12 from framework import VppTestCase, VppTestRunner, running_extended_tests
13 from ipfix import IPFIX, Set, Template, Data, IPFIXDecoder
14 from scapy.all import bind_layers, Packet, ByteEnumField, ShortField, \
15 IPField, IntField, LongField, XByteField, FlagsField, FieldLenField, \
17 from scapy.data import IP_PROTOS
18 from scapy.layers.inet import IP, TCP, UDP, ICMP
19 from scapy.layers.inet import IPerror, TCPerror, UDPerror, ICMPerror
20 from scapy.layers.inet6 import ICMPv6DestUnreach, IPerror6, IPv6ExtHdrFragment
21 from scapy.layers.inet6 import IPv6, ICMPv6EchoRequest, ICMPv6EchoReply, \
22 ICMPv6ND_NS, ICMPv6ND_NA, ICMPv6NDOptDstLLAddr, fragment6
23 from scapy.layers.l2 import Ether, ARP, GRE
24 from scapy.packet import Raw
25 from syslog_rfc5424_parser import SyslogMessage, ParseError
26 from syslog_rfc5424_parser.constants import SyslogSeverity
27 from util import ip4_range
28 from util import ppc, ppp
29 from vpp_acl import AclRule, VppAcl, VppAclInterface
30 from vpp_ip_route import VppIpRoute, VppRoutePath
31 from vpp_neighbor import VppNeighbor
32 from vpp_papi import VppEnum
35 # NAT HA protocol event data
38 fields_desc = [ByteEnumField("event_type", None,
39 {1: "add", 2: "del", 3: "refresh"}),
40 ByteEnumField("protocol", None,
41 {0: "other", 1: "udp", 2: "tcp", 3: "icmp"}),
42 ShortField("flags", 0),
43 IPField("in_addr", None),
44 IPField("out_addr", None),
45 ShortField("in_port", None),
46 ShortField("out_port", None),
47 IPField("eh_addr", None),
48 IPField("ehn_addr", None),
49 ShortField("eh_port", None),
50 ShortField("ehn_port", None),
51 IntField("fib_index", None),
52 IntField("total_pkts", 0),
53 LongField("total_bytes", 0)]
55 def extract_padding(self, s):
59 # NAT HA protocol header
60 class HANATStateSync(Packet):
61 name = "HA NAT state sync"
62 fields_desc = [XByteField("version", 1),
63 FlagsField("flags", 0, 8, ['ACK']),
64 FieldLenField("count", None, count_of="events"),
65 IntField("sequence_number", 1),
66 IntField("thread_index", 0),
67 PacketListField("events", [], Event,
68 count_from=lambda pkt: pkt.count)]
71 class MethodHolder(VppTestCase):
72 """ NAT create capture and verify method holder """
75 def config_flags(self):
76 return VppEnum.vl_api_nat_config_flags_t
79 def SYSLOG_SEVERITY(self):
80 return VppEnum.vl_api_syslog_severity_t
82 def clear_nat44(self):
84 Clear NAT44 configuration.
86 if hasattr(self, 'pg7') and hasattr(self, 'pg8'):
87 if self.pg7.has_ip4_config:
88 self.pg7.unconfig_ip4()
90 self.vapi.nat44_forwarding_enable_disable(enable=0)
92 interfaces = self.vapi.nat44_interface_addr_dump()
93 for intf in interfaces:
94 self.vapi.nat44_add_del_interface_addr(
96 sw_if_index=intf.sw_if_index,
99 self.vapi.nat_ipfix_enable_disable(domain_id=self.ipfix_domain_id,
100 src_port=self.ipfix_src_port,
102 self.ipfix_src_port = 4739
103 self.ipfix_domain_id = 1
105 self.vapi.syslog_set_filter(
106 self.SYSLOG_SEVERITY.SYSLOG_API_SEVERITY_EMERG)
108 self.vapi.nat_ha_set_listener(ip_address='0.0.0.0', port=0,
110 self.vapi.nat_ha_set_failover(ip_address='0.0.0.0', port=0,
111 session_refresh_interval=10)
113 interfaces = self.vapi.nat44_interface_dump()
114 for intf in interfaces:
115 if intf.flags & self.config_flags.NAT_IS_INSIDE and \
116 intf.flags & self.config_flags.NAT_IS_OUTSIDE:
117 self.vapi.nat44_interface_add_del_feature(
118 sw_if_index=intf.sw_if_index)
119 self.vapi.nat44_interface_add_del_feature(
120 sw_if_index=intf.sw_if_index,
123 interfaces = self.vapi.nat44_interface_output_feature_dump()
124 for intf in interfaces:
125 self.vapi.nat44_interface_add_del_output_feature(
128 sw_if_index=intf.sw_if_index)
129 static_mappings = self.vapi.nat44_static_mapping_dump()
130 for sm in static_mappings:
131 self.vapi.nat44_add_del_static_mapping(
133 local_ip_address=sm.local_ip_address,
134 external_ip_address=sm.external_ip_address,
135 external_sw_if_index=sm.external_sw_if_index,
136 local_port=sm.local_port,
137 external_port=sm.external_port,
139 protocol=sm.protocol,
140 flags=sm.flags, tag=sm.tag)
142 lb_static_mappings = self.vapi.nat44_lb_static_mapping_dump()
143 for lb_sm in lb_static_mappings:
144 self.vapi.nat44_add_del_lb_static_mapping(
147 external_addr=lb_sm.external_addr,
148 external_port=lb_sm.external_port,
149 protocol=lb_sm.protocol,
150 local_num=0, locals=[],
153 identity_mappings = self.vapi.nat44_identity_mapping_dump()
154 for id_m in identity_mappings:
155 self.vapi.nat44_add_del_identity_mapping(
156 ip_address=id_m.ip_address,
157 sw_if_index=id_m.sw_if_index,
161 protocol=id_m.protocol)
163 addresses = self.vapi.nat44_address_dump()
164 for addr in addresses:
165 self.vapi.nat44_add_del_address_range(
166 first_ip_address=addr.ip_address,
167 last_ip_address=addr.ip_address,
168 vrf_id=0xFFFFFFFF, flags=addr.flags)
170 self.verify_no_nat44_user()
171 self.vapi.nat_set_timeouts(udp=300, tcp_established=7440,
172 tcp_transitory=240, icmp=60)
173 self.vapi.nat_set_addr_and_port_alloc_alg()
174 self.vapi.nat_set_mss_clamping(enable=0, mss_value=1500)
176 def nat44_add_static_mapping(self, local_ip, external_ip='0.0.0.0',
177 local_port=0, external_port=0, vrf_id=0,
178 is_add=1, external_sw_if_index=0xFFFFFFFF,
179 proto=0, tag="", flags=0):
181 Add/delete NAT44 static mapping
183 :param local_ip: Local IP address
184 :param external_ip: External IP address
185 :param local_port: Local port number (Optional)
186 :param external_port: External port number (Optional)
187 :param vrf_id: VRF ID (Default 0)
188 :param is_add: 1 if add, 0 if delete (Default add)
189 :param external_sw_if_index: External interface instead of IP address
190 :param proto: IP protocol (Mandatory if port specified)
191 :param tag: Opaque string tag
192 :param flags: NAT configuration flags
195 if not (local_port and external_port):
196 flags |= self.config_flags.NAT_IS_ADDR_ONLY
198 self.vapi.nat44_add_del_static_mapping(
200 local_ip_address=local_ip,
201 external_ip_address=external_ip,
202 external_sw_if_index=external_sw_if_index,
203 local_port=local_port,
204 external_port=external_port,
205 vrf_id=vrf_id, protocol=proto,
209 def nat44_add_address(self, ip, is_add=1, vrf_id=0xFFFFFFFF, twice_nat=0):
211 Add/delete NAT44 address
213 :param ip: IP address
214 :param is_add: 1 if add, 0 if delete (Default add)
215 :param twice_nat: twice NAT address for external hosts
217 flags = self.config_flags.NAT_IS_TWICE_NAT if twice_nat else 0
218 self.vapi.nat44_add_del_address_range(first_ip_address=ip,
224 def create_stream_in(self, in_if, out_if, dst_ip=None, ttl=64):
226 Create packet stream for inside network
228 :param in_if: Inside interface
229 :param out_if: Outside interface
230 :param dst_ip: Destination address
231 :param ttl: TTL of generated packets
234 dst_ip = out_if.remote_ip4
238 p = (Ether(dst=in_if.local_mac, src=in_if.remote_mac) /
239 IP(src=in_if.remote_ip4, dst=dst_ip, ttl=ttl) /
240 TCP(sport=self.tcp_port_in, dport=20))
244 p = (Ether(dst=in_if.local_mac, src=in_if.remote_mac) /
245 IP(src=in_if.remote_ip4, dst=dst_ip, ttl=ttl) /
246 UDP(sport=self.udp_port_in, dport=20))
250 p = (Ether(dst=in_if.local_mac, src=in_if.remote_mac) /
251 IP(src=in_if.remote_ip4, dst=dst_ip, ttl=ttl) /
252 ICMP(id=self.icmp_id_in, type='echo-request'))
257 def compose_ip6(self, ip4, pref, plen):
259 Compose IPv4-embedded IPv6 addresses
261 :param ip4: IPv4 address
262 :param pref: IPv6 prefix
263 :param plen: IPv6 prefix length
264 :returns: IPv4-embedded IPv6 addresses
266 pref_n = list(socket.inet_pton(socket.AF_INET6, pref))
267 ip4_n = list(socket.inet_pton(socket.AF_INET, ip4))
282 pref_n[10] = ip4_n[3]
286 pref_n[10] = ip4_n[2]
287 pref_n[11] = ip4_n[3]
290 pref_n[10] = ip4_n[1]
291 pref_n[11] = ip4_n[2]
292 pref_n[12] = ip4_n[3]
294 pref_n[12] = ip4_n[0]
295 pref_n[13] = ip4_n[1]
296 pref_n[14] = ip4_n[2]
297 pref_n[15] = ip4_n[3]
298 packed_pref_n = b''.join([scapy.compat.chb(x) for x in pref_n])
299 return socket.inet_ntop(socket.AF_INET6, packed_pref_n)
301 def extract_ip4(self, ip6, plen):
303 Extract IPv4 address embedded in IPv6 addresses
305 :param ip6: IPv6 address
306 :param plen: IPv6 prefix length
307 :returns: extracted IPv4 address
309 ip6_n = list(socket.inet_pton(socket.AF_INET6, ip6))
341 return socket.inet_ntop(socket.AF_INET, ''.join(ip4_n))
343 def create_stream_in_ip6(self, in_if, out_if, hlim=64, pref=None, plen=0):
345 Create IPv6 packet stream for inside network
347 :param in_if: Inside interface
348 :param out_if: Outside interface
349 :param ttl: Hop Limit of generated packets
350 :param pref: NAT64 prefix
351 :param plen: NAT64 prefix length
355 dst = ''.join(['64:ff9b::', out_if.remote_ip4])
357 dst = self.compose_ip6(out_if.remote_ip4, pref, plen)
360 p = (Ether(dst=in_if.local_mac, src=in_if.remote_mac) /
361 IPv6(src=in_if.remote_ip6, dst=dst, hlim=hlim) /
362 TCP(sport=self.tcp_port_in, dport=20))
366 p = (Ether(dst=in_if.local_mac, src=in_if.remote_mac) /
367 IPv6(src=in_if.remote_ip6, dst=dst, hlim=hlim) /
368 UDP(sport=self.udp_port_in, dport=20))
372 p = (Ether(dst=in_if.local_mac, src=in_if.remote_mac) /
373 IPv6(src=in_if.remote_ip6, dst=dst, hlim=hlim) /
374 ICMPv6EchoRequest(id=self.icmp_id_in))
379 def create_stream_out(self, out_if, dst_ip=None, ttl=64,
380 use_inside_ports=False):
382 Create packet stream for outside network
384 :param out_if: Outside interface
385 :param dst_ip: Destination IP address (Default use global NAT address)
386 :param ttl: TTL of generated packets
387 :param use_inside_ports: Use inside NAT ports as destination ports
388 instead of outside ports
391 dst_ip = self.nat_addr
392 if not use_inside_ports:
393 tcp_port = self.tcp_port_out
394 udp_port = self.udp_port_out
395 icmp_id = self.icmp_id_out
397 tcp_port = self.tcp_port_in
398 udp_port = self.udp_port_in
399 icmp_id = self.icmp_id_in
402 p = (Ether(dst=out_if.local_mac, src=out_if.remote_mac) /
403 IP(src=out_if.remote_ip4, dst=dst_ip, ttl=ttl) /
404 TCP(dport=tcp_port, sport=20))
408 p = (Ether(dst=out_if.local_mac, src=out_if.remote_mac) /
409 IP(src=out_if.remote_ip4, dst=dst_ip, ttl=ttl) /
410 UDP(dport=udp_port, sport=20))
414 p = (Ether(dst=out_if.local_mac, src=out_if.remote_mac) /
415 IP(src=out_if.remote_ip4, dst=dst_ip, ttl=ttl) /
416 ICMP(id=icmp_id, type='echo-reply'))
421 def create_stream_out_ip6(self, out_if, src_ip, dst_ip, hl=64):
423 Create packet stream for outside network
425 :param out_if: Outside interface
426 :param dst_ip: Destination IP address (Default use global NAT address)
427 :param hl: HL of generated packets
431 p = (Ether(dst=out_if.local_mac, src=out_if.remote_mac) /
432 IPv6(src=src_ip, dst=dst_ip, hlim=hl) /
433 TCP(dport=self.tcp_port_out, sport=20))
437 p = (Ether(dst=out_if.local_mac, src=out_if.remote_mac) /
438 IPv6(src=src_ip, dst=dst_ip, hlim=hl) /
439 UDP(dport=self.udp_port_out, sport=20))
443 p = (Ether(dst=out_if.local_mac, src=out_if.remote_mac) /
444 IPv6(src=src_ip, dst=dst_ip, hlim=hl) /
445 ICMPv6EchoReply(id=self.icmp_id_out))
450 def verify_capture_out(self, capture, nat_ip=None, same_port=False,
451 dst_ip=None, is_ip6=False, ignore_port=False):
453 Verify captured packets on outside network
455 :param capture: Captured packets
456 :param nat_ip: Translated IP address (Default use global NAT address)
457 :param same_port: Source port number is not translated (Default False)
458 :param dst_ip: Destination IP address (Default do not verify)
459 :param is_ip6: If L3 protocol is IPv6 (Default False)
463 ICMP46 = ICMPv6EchoRequest
468 nat_ip = self.nat_addr
469 for packet in capture:
472 self.assert_packet_checksums_valid(packet)
473 self.assertEqual(packet[IP46].src, nat_ip)
474 if dst_ip is not None:
475 self.assertEqual(packet[IP46].dst, dst_ip)
476 if packet.haslayer(TCP):
480 packet[TCP].sport, self.tcp_port_in)
483 packet[TCP].sport, self.tcp_port_in)
484 self.tcp_port_out = packet[TCP].sport
485 self.assert_packet_checksums_valid(packet)
486 elif packet.haslayer(UDP):
490 packet[UDP].sport, self.udp_port_in)
493 packet[UDP].sport, self.udp_port_in)
494 self.udp_port_out = packet[UDP].sport
499 packet[ICMP46].id, self.icmp_id_in)
502 packet[ICMP46].id, self.icmp_id_in)
503 self.icmp_id_out = packet[ICMP46].id
504 self.assert_packet_checksums_valid(packet)
506 self.logger.error(ppp("Unexpected or invalid packet "
507 "(outside network):", packet))
510 def verify_capture_out_ip6(self, capture, nat_ip, same_port=False,
513 Verify captured packets on outside network
515 :param capture: Captured packets
516 :param nat_ip: Translated IP address
517 :param same_port: Source port number is not translated (Default False)
518 :param dst_ip: Destination IP address (Default do not verify)
520 return self.verify_capture_out(capture, nat_ip, same_port, dst_ip,
523 def verify_capture_in(self, capture, in_if):
525 Verify captured packets on inside network
527 :param capture: Captured packets
528 :param in_if: Inside interface
530 for packet in capture:
532 self.assert_packet_checksums_valid(packet)
533 self.assertEqual(packet[IP].dst, in_if.remote_ip4)
534 if packet.haslayer(TCP):
535 self.assertEqual(packet[TCP].dport, self.tcp_port_in)
536 elif packet.haslayer(UDP):
537 self.assertEqual(packet[UDP].dport, self.udp_port_in)
539 self.assertEqual(packet[ICMP].id, self.icmp_id_in)
541 self.logger.error(ppp("Unexpected or invalid packet "
542 "(inside network):", packet))
545 def verify_capture_in_ip6(self, capture, src_ip, dst_ip):
547 Verify captured IPv6 packets on inside network
549 :param capture: Captured packets
550 :param src_ip: Source IP
551 :param dst_ip: Destination IP address
553 for packet in capture:
555 self.assertEqual(packet[IPv6].src, src_ip)
556 self.assertEqual(packet[IPv6].dst, dst_ip)
557 self.assert_packet_checksums_valid(packet)
558 if packet.haslayer(TCP):
559 self.assertEqual(packet[TCP].dport, self.tcp_port_in)
560 elif packet.haslayer(UDP):
561 self.assertEqual(packet[UDP].dport, self.udp_port_in)
563 self.assertEqual(packet[ICMPv6EchoReply].id,
566 self.logger.error(ppp("Unexpected or invalid packet "
567 "(inside network):", packet))
570 def verify_capture_no_translation(self, capture, ingress_if, egress_if):
572 Verify captured packet that don't have to be translated
574 :param capture: Captured packets
575 :param ingress_if: Ingress interface
576 :param egress_if: Egress interface
578 for packet in capture:
580 self.assertEqual(packet[IP].src, ingress_if.remote_ip4)
581 self.assertEqual(packet[IP].dst, egress_if.remote_ip4)
582 if packet.haslayer(TCP):
583 self.assertEqual(packet[TCP].sport, self.tcp_port_in)
584 elif packet.haslayer(UDP):
585 self.assertEqual(packet[UDP].sport, self.udp_port_in)
587 self.assertEqual(packet[ICMP].id, self.icmp_id_in)
589 self.logger.error(ppp("Unexpected or invalid packet "
590 "(inside network):", packet))
593 def verify_capture_out_with_icmp_errors(self, capture, src_ip=None,
596 Verify captured packets with ICMP errors on outside network
598 :param capture: Captured packets
599 :param src_ip: Translated IP address or IP address of VPP
600 (Default use global NAT address)
601 :param icmp_type: Type of error ICMP packet
602 we are expecting (Default 11)
605 src_ip = self.nat_addr
606 for packet in capture:
608 self.assertEqual(packet[IP].src, src_ip)
609 self.assertEqual(packet.haslayer(ICMP), 1)
611 self.assertEqual(icmp.type, icmp_type)
612 self.assertTrue(icmp.haslayer(IPerror))
613 inner_ip = icmp[IPerror]
614 if inner_ip.haslayer(TCPerror):
615 self.assertEqual(inner_ip[TCPerror].dport,
617 elif inner_ip.haslayer(UDPerror):
618 self.assertEqual(inner_ip[UDPerror].dport,
621 self.assertEqual(inner_ip[ICMPerror].id, self.icmp_id_out)
623 self.logger.error(ppp("Unexpected or invalid packet "
624 "(outside network):", packet))
627 def verify_capture_in_with_icmp_errors(self, capture, in_if, icmp_type=11):
629 Verify captured packets with ICMP errors on inside network
631 :param capture: Captured packets
632 :param in_if: Inside interface
633 :param icmp_type: Type of error ICMP packet
634 we are expecting (Default 11)
636 for packet in capture:
638 self.assertEqual(packet[IP].dst, in_if.remote_ip4)
639 self.assertEqual(packet.haslayer(ICMP), 1)
641 self.assertEqual(icmp.type, icmp_type)
642 self.assertTrue(icmp.haslayer(IPerror))
643 inner_ip = icmp[IPerror]
644 if inner_ip.haslayer(TCPerror):
645 self.assertEqual(inner_ip[TCPerror].sport,
647 elif inner_ip.haslayer(UDPerror):
648 self.assertEqual(inner_ip[UDPerror].sport,
651 self.assertEqual(inner_ip[ICMPerror].id, self.icmp_id_in)
653 self.logger.error(ppp("Unexpected or invalid packet "
654 "(inside network):", packet))
657 def create_stream_frag(self, src_if, dst, sport, dport, data,
658 proto=IP_PROTOS.tcp, echo_reply=False):
660 Create fragmented packet stream
662 :param src_if: Source interface
663 :param dst: Destination IPv4 address
664 :param sport: Source port
665 :param dport: Destination port
666 :param data: Payload data
667 :param proto: protocol (TCP, UDP, ICMP)
668 :param echo_reply: use echo_reply if protocol is ICMP
671 if proto == IP_PROTOS.tcp:
672 p = (IP(src=src_if.remote_ip4, dst=dst) /
673 TCP(sport=sport, dport=dport) /
675 p = p.__class__(scapy.compat.raw(p))
676 chksum = p[TCP].chksum
677 proto_header = TCP(sport=sport, dport=dport, chksum=chksum)
678 elif proto == IP_PROTOS.udp:
679 proto_header = UDP(sport=sport, dport=dport)
680 elif proto == IP_PROTOS.icmp:
682 proto_header = ICMP(id=sport, type='echo-request')
684 proto_header = ICMP(id=sport, type='echo-reply')
686 raise Exception("Unsupported protocol")
687 id = random.randint(0, 65535)
689 if proto == IP_PROTOS.tcp:
692 raw = Raw(data[0:16])
693 p = (Ether(src=src_if.remote_mac, dst=src_if.local_mac) /
694 IP(src=src_if.remote_ip4, dst=dst, flags="MF", frag=0, id=id) /
698 if proto == IP_PROTOS.tcp:
699 raw = Raw(data[4:20])
701 raw = Raw(data[16:32])
702 p = (Ether(src=src_if.remote_mac, dst=src_if.local_mac) /
703 IP(src=src_if.remote_ip4, dst=dst, flags="MF", frag=3, id=id,
707 if proto == IP_PROTOS.tcp:
711 p = (Ether(src=src_if.remote_mac, dst=src_if.local_mac) /
712 IP(src=src_if.remote_ip4, dst=dst, frag=5, proto=proto,
718 def create_stream_frag_ip6(self, src_if, dst, sport, dport, data,
719 pref=None, plen=0, frag_size=128):
721 Create fragmented packet stream
723 :param src_if: Source interface
724 :param dst: Destination IPv4 address
725 :param sport: Source TCP port
726 :param dport: Destination TCP port
727 :param data: Payload data
728 :param pref: NAT64 prefix
729 :param plen: NAT64 prefix length
730 :param fragsize: size of fragments
734 dst_ip6 = ''.join(['64:ff9b::', dst])
736 dst_ip6 = self.compose_ip6(dst, pref, plen)
738 p = (Ether(dst=src_if.local_mac, src=src_if.remote_mac) /
739 IPv6(src=src_if.remote_ip6, dst=dst_ip6) /
740 IPv6ExtHdrFragment(id=random.randint(0, 65535)) /
741 TCP(sport=sport, dport=dport) /
744 return fragment6(p, frag_size)
746 def reass_frags_and_verify(self, frags, src, dst):
748 Reassemble and verify fragmented packet
750 :param frags: Captured fragments
751 :param src: Source IPv4 address to verify
752 :param dst: Destination IPv4 address to verify
754 :returns: Reassembled IPv4 packet
758 self.assertEqual(p[IP].src, src)
759 self.assertEqual(p[IP].dst, dst)
760 self.assert_ip_checksum_valid(p)
761 buffer.seek(p[IP].frag * 8)
762 buffer.write(bytes(p[IP].payload))
763 ip = IP(src=frags[0][IP].src, dst=frags[0][IP].dst,
764 proto=frags[0][IP].proto)
765 if ip.proto == IP_PROTOS.tcp:
766 p = (ip / TCP(buffer.getvalue()))
767 self.logger.debug(ppp("Reassembled:", p))
768 self.assert_tcp_checksum_valid(p)
769 elif ip.proto == IP_PROTOS.udp:
770 p = (ip / UDP(buffer.getvalue()[:8]) /
771 Raw(buffer.getvalue()[8:]))
772 elif ip.proto == IP_PROTOS.icmp:
773 p = (ip / ICMP(buffer.getvalue()))
776 def reass_frags_and_verify_ip6(self, frags, src, dst):
778 Reassemble and verify fragmented packet
780 :param frags: Captured fragments
781 :param src: Source IPv6 address to verify
782 :param dst: Destination IPv6 address to verify
784 :returns: Reassembled IPv6 packet
788 self.assertEqual(p[IPv6].src, src)
789 self.assertEqual(p[IPv6].dst, dst)
790 buffer.seek(p[IPv6ExtHdrFragment].offset * 8)
791 buffer.write(bytes(p[IPv6ExtHdrFragment].payload))
792 ip = IPv6(src=frags[0][IPv6].src, dst=frags[0][IPv6].dst,
793 nh=frags[0][IPv6ExtHdrFragment].nh)
794 if ip.nh == IP_PROTOS.tcp:
795 p = (ip / TCP(buffer.getvalue()))
796 elif ip.nh == IP_PROTOS.udp:
797 p = (ip / UDP(buffer.getvalue()))
798 self.logger.debug(ppp("Reassembled:", p))
799 self.assert_packet_checksums_valid(p)
802 def initiate_tcp_session(self, in_if, out_if):
804 Initiates TCP session
806 :param in_if: Inside interface
807 :param out_if: Outside interface
811 p = (Ether(src=in_if.remote_mac, dst=in_if.local_mac) /
812 IP(src=in_if.remote_ip4, dst=out_if.remote_ip4) /
813 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
816 self.pg_enable_capture(self.pg_interfaces)
818 capture = out_if.get_capture(1)
820 self.tcp_port_out = p[TCP].sport
822 # SYN + ACK packet out->in
823 p = (Ether(src=out_if.remote_mac, dst=out_if.local_mac) /
824 IP(src=out_if.remote_ip4, dst=self.nat_addr) /
825 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
828 self.pg_enable_capture(self.pg_interfaces)
833 p = (Ether(src=in_if.remote_mac, dst=in_if.local_mac) /
834 IP(src=in_if.remote_ip4, dst=out_if.remote_ip4) /
835 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
838 self.pg_enable_capture(self.pg_interfaces)
840 out_if.get_capture(1)
843 self.logger.error("TCP 3 way handshake failed")
846 def verify_ipfix_nat44_ses(self, data):
848 Verify IPFIX NAT44 session create/delete event
850 :param data: Decoded IPFIX data records
852 nat44_ses_create_num = 0
853 nat44_ses_delete_num = 0
854 self.assertEqual(6, len(data))
857 self.assertIn(scapy.compat.orb(record[230]), [4, 5])
858 if scapy.compat.orb(record[230]) == 4:
859 nat44_ses_create_num += 1
861 nat44_ses_delete_num += 1
863 self.assertEqual(self.pg0.remote_ip4,
864 str(ipaddress.IPv4Address(record[8])))
865 # postNATSourceIPv4Address
866 self.assertEqual(socket.inet_pton(socket.AF_INET, self.nat_addr),
869 self.assertEqual(struct.pack("!I", 0), record[234])
870 # protocolIdentifier/sourceTransportPort
871 # /postNAPTSourceTransportPort
872 if IP_PROTOS.icmp == scapy.compat.orb(record[4]):
873 self.assertEqual(struct.pack("!H", self.icmp_id_in), record[7])
874 self.assertEqual(struct.pack("!H", self.icmp_id_out),
876 elif IP_PROTOS.tcp == scapy.compat.orb(record[4]):
877 self.assertEqual(struct.pack("!H", self.tcp_port_in),
879 self.assertEqual(struct.pack("!H", self.tcp_port_out),
881 elif IP_PROTOS.udp == scapy.compat.orb(record[4]):
882 self.assertEqual(struct.pack("!H", self.udp_port_in),
884 self.assertEqual(struct.pack("!H", self.udp_port_out),
887 self.fail("Invalid protocol")
888 self.assertEqual(3, nat44_ses_create_num)
889 self.assertEqual(3, nat44_ses_delete_num)
891 def verify_ipfix_addr_exhausted(self, data):
893 Verify IPFIX NAT addresses event
895 :param data: Decoded IPFIX data records
897 self.assertEqual(1, len(data))
900 self.assertEqual(scapy.compat.orb(record[230]), 3)
902 self.assertEqual(struct.pack("!I", 0), record[283])
904 def verify_ipfix_max_sessions(self, data, limit):
906 Verify IPFIX maximum session entries exceeded event
908 :param data: Decoded IPFIX data records
909 :param limit: Number of maximum session entries that can be created.
911 self.assertEqual(1, len(data))
914 self.assertEqual(scapy.compat.orb(record[230]), 13)
915 # natQuotaExceededEvent
916 self.assertEqual(struct.pack("I", 1), record[466])
918 self.assertEqual(struct.pack("I", limit), record[471])
920 def verify_ipfix_max_bibs(self, data, limit):
922 Verify IPFIX maximum BIB entries exceeded event
924 :param data: Decoded IPFIX data records
925 :param limit: Number of maximum BIB entries that can be created.
927 self.assertEqual(1, len(data))
930 self.assertEqual(scapy.compat.orb(record[230]), 13)
931 # natQuotaExceededEvent
932 self.assertEqual(struct.pack("I", 2), record[466])
934 self.assertEqual(struct.pack("I", limit), record[472])
936 def verify_ipfix_bib(self, data, is_create, src_addr):
938 Verify IPFIX NAT64 BIB create and delete events
940 :param data: Decoded IPFIX data records
941 :param is_create: Create event if nonzero value otherwise delete event
942 :param src_addr: IPv6 source address
944 self.assertEqual(1, len(data))
948 self.assertEqual(scapy.compat.orb(record[230]), 10)
950 self.assertEqual(scapy.compat.orb(record[230]), 11)
952 self.assertEqual(src_addr, str(ipaddress.IPv6Address(record[27])))
953 # postNATSourceIPv4Address
954 self.assertEqual(self.nat_addr_n, record[225])
956 self.assertEqual(IP_PROTOS.tcp, scapy.compat.orb(record[4]))
958 self.assertEqual(struct.pack("!I", 0), record[234])
959 # sourceTransportPort
960 self.assertEqual(struct.pack("!H", self.tcp_port_in), record[7])
961 # postNAPTSourceTransportPort
962 self.assertEqual(struct.pack("!H", self.tcp_port_out), record[227])
964 def verify_ipfix_nat64_ses(self, data, is_create, src_addr, dst_addr,
967 Verify IPFIX NAT64 session create and delete events
969 :param data: Decoded IPFIX data records
970 :param is_create: Create event if nonzero value otherwise delete event
971 :param src_addr: IPv6 source address
972 :param dst_addr: IPv4 destination address
973 :param dst_port: destination TCP port
975 self.assertEqual(1, len(data))
979 self.assertEqual(scapy.compat.orb(record[230]), 6)
981 self.assertEqual(scapy.compat.orb(record[230]), 7)
983 self.assertEqual(src_addr, str(ipaddress.IPv6Address(record[27])))
984 # destinationIPv6Address
985 self.assertEqual(socket.inet_pton(socket.AF_INET6,
986 self.compose_ip6(dst_addr,
990 # postNATSourceIPv4Address
991 self.assertEqual(self.nat_addr_n, record[225])
992 # postNATDestinationIPv4Address
993 self.assertEqual(socket.inet_pton(socket.AF_INET, dst_addr),
996 self.assertEqual(IP_PROTOS.tcp, scapy.compat.orb(record[4]))
998 self.assertEqual(struct.pack("!I", 0), record[234])
999 # sourceTransportPort
1000 self.assertEqual(struct.pack("!H", self.tcp_port_in), record[7])
1001 # postNAPTSourceTransportPort
1002 self.assertEqual(struct.pack("!H", self.tcp_port_out), record[227])
1003 # destinationTransportPort
1004 self.assertEqual(struct.pack("!H", dst_port), record[11])
1005 # postNAPTDestinationTransportPort
1006 self.assertEqual(struct.pack("!H", dst_port), record[228])
1008 def verify_no_nat44_user(self):
1009 """ Verify that there is no NAT44 user """
1010 users = self.vapi.nat44_user_dump()
1011 self.assertEqual(len(users), 0)
1012 users = self.statistics.get_counter('/nat44/total-users')
1013 self.assertEqual(users[0][0], 0)
1014 sessions = self.statistics.get_counter('/nat44/total-sessions')
1015 self.assertEqual(sessions[0][0], 0)
1017 def verify_ipfix_max_entries_per_user(self, data, limit, src_addr):
1019 Verify IPFIX maximum entries per user exceeded event
1021 :param data: Decoded IPFIX data records
1022 :param limit: Number of maximum entries per user
1023 :param src_addr: IPv4 source address
1025 self.assertEqual(1, len(data))
1028 self.assertEqual(scapy.compat.orb(record[230]), 13)
1029 # natQuotaExceededEvent
1030 self.assertEqual(struct.pack("I", 3), record[466])
1032 self.assertEqual(struct.pack("I", limit), record[473])
1034 self.assertEqual(socket.inet_pton(socket.AF_INET, src_addr), record[8])
1036 def verify_syslog_apmap(self, data, is_add=True):
1037 message = data.decode('utf-8')
1039 message = SyslogMessage.parse(message)
1040 except ParseError as e:
1041 self.logger.error(e)
1044 self.assertEqual(message.severity, SyslogSeverity.info)
1045 self.assertEqual(message.appname, 'NAT')
1046 self.assertEqual(message.msgid, 'APMADD' if is_add else 'APMDEL')
1047 sd_params = message.sd.get('napmap')
1048 self.assertTrue(sd_params is not None)
1049 self.assertEqual(sd_params.get('IATYP'), 'IPv4')
1050 self.assertEqual(sd_params.get('ISADDR'), self.pg0.remote_ip4)
1051 self.assertEqual(sd_params.get('ISPORT'), "%d" % self.tcp_port_in)
1052 self.assertEqual(sd_params.get('XATYP'), 'IPv4')
1053 self.assertEqual(sd_params.get('XSADDR'), self.nat_addr)
1054 self.assertEqual(sd_params.get('XSPORT'), "%d" % self.tcp_port_out)
1055 self.assertEqual(sd_params.get('PROTO'), "%d" % IP_PROTOS.tcp)
1056 self.assertTrue(sd_params.get('SSUBIX') is not None)
1057 self.assertEqual(sd_params.get('SVLAN'), '0')
1059 def verify_syslog_sess(self, data, is_add=True, is_ip6=False):
1060 message = data.decode('utf-8')
1062 message = SyslogMessage.parse(message)
1063 except ParseError as e:
1064 self.logger.error(e)
1067 self.assertEqual(message.severity, SyslogSeverity.info)
1068 self.assertEqual(message.appname, 'NAT')
1069 self.assertEqual(message.msgid, 'SADD' if is_add else 'SDEL')
1070 sd_params = message.sd.get('nsess')
1071 self.assertTrue(sd_params is not None)
1073 self.assertEqual(sd_params.get('IATYP'), 'IPv6')
1074 self.assertEqual(sd_params.get('ISADDR'), self.pg0.remote_ip6)
1076 self.assertEqual(sd_params.get('IATYP'), 'IPv4')
1077 self.assertEqual(sd_params.get('ISADDR'), self.pg0.remote_ip4)
1078 self.assertTrue(sd_params.get('SSUBIX') is not None)
1079 self.assertEqual(sd_params.get('ISPORT'), "%d" % self.tcp_port_in)
1080 self.assertEqual(sd_params.get('XATYP'), 'IPv4')
1081 self.assertEqual(sd_params.get('XSADDR'), self.nat_addr)
1082 self.assertEqual(sd_params.get('XSPORT'), "%d" % self.tcp_port_out)
1083 self.assertEqual(sd_params.get('PROTO'), "%d" % IP_PROTOS.tcp)
1084 self.assertEqual(sd_params.get('SVLAN'), '0')
1085 self.assertEqual(sd_params.get('XDADDR'), self.pg1.remote_ip4)
1086 self.assertEqual(sd_params.get('XDPORT'),
1087 "%d" % self.tcp_external_port)
1089 def verify_mss_value(self, pkt, mss):
1091 Verify TCP MSS value
1096 if not pkt.haslayer(IP) or not pkt.haslayer(TCP):
1097 raise TypeError("Not a TCP/IP packet")
1099 for option in pkt[TCP].options:
1100 if option[0] == 'MSS':
1101 self.assertEqual(option[1], mss)
1102 self.assert_tcp_checksum_valid(pkt)
1105 def proto2layer(proto):
1106 if proto == IP_PROTOS.tcp:
1108 elif proto == IP_PROTOS.udp:
1110 elif proto == IP_PROTOS.icmp:
1113 raise Exception("Unsupported protocol")
1115 def frag_in_order(self, proto=IP_PROTOS.tcp, dont_translate=False,
1117 layer = self.proto2layer(proto)
1119 if proto == IP_PROTOS.tcp:
1120 data = b"A" * 4 + b"B" * 16 + b"C" * 3
1122 data = b"A" * 16 + b"B" * 16 + b"C" * 3
1123 self.port_in = random.randint(1025, 65535)
1126 pkts = self.create_stream_frag(self.pg0, self.pg1.remote_ip4,
1127 self.port_in, 20, data, proto)
1128 self.pg0.add_stream(pkts)
1129 self.pg_enable_capture(self.pg_interfaces)
1131 frags = self.pg1.get_capture(len(pkts))
1132 if not dont_translate:
1133 p = self.reass_frags_and_verify(frags,
1135 self.pg1.remote_ip4)
1137 p = self.reass_frags_and_verify(frags,
1138 self.pg0.remote_ip4,
1139 self.pg1.remote_ip4)
1140 if proto != IP_PROTOS.icmp:
1141 if not dont_translate:
1142 self.assertEqual(p[layer].dport, 20)
1144 self.assertNotEqual(p[layer].sport, self.port_in)
1146 self.assertEqual(p[layer].sport, self.port_in)
1149 if not dont_translate:
1150 self.assertNotEqual(p[layer].id, self.port_in)
1152 self.assertEqual(p[layer].id, self.port_in)
1153 self.assertEqual(data, p[Raw].load)
1156 if not dont_translate:
1157 dst_addr = self.nat_addr
1159 dst_addr = self.pg0.remote_ip4
1160 if proto != IP_PROTOS.icmp:
1162 dport = p[layer].sport
1166 pkts = self.create_stream_frag(self.pg1, dst_addr, sport, dport, data,
1167 proto, echo_reply=True)
1168 self.pg1.add_stream(pkts)
1169 self.pg_enable_capture(self.pg_interfaces)
1171 frags = self.pg0.get_capture(len(pkts))
1172 p = self.reass_frags_and_verify(frags,
1173 self.pg1.remote_ip4,
1174 self.pg0.remote_ip4)
1175 if proto != IP_PROTOS.icmp:
1176 self.assertEqual(p[layer].sport, 20)
1177 self.assertEqual(p[layer].dport, self.port_in)
1179 self.assertEqual(p[layer].id, self.port_in)
1180 self.assertEqual(data, p[Raw].load)
1182 def frag_in_order_in_plus_out(self, proto=IP_PROTOS.tcp):
1183 layer = self.proto2layer(proto)
1185 if proto == IP_PROTOS.tcp:
1186 data = b"A" * 4 + b"B" * 16 + b"C" * 3
1188 data = b"A" * 16 + b"B" * 16 + b"C" * 3
1189 self.port_in = random.randint(1025, 65535)
1193 pkts = self.create_stream_frag(self.pg0, self.server_out_addr,
1194 self.port_in, self.server_out_port,
1196 self.pg0.add_stream(pkts)
1197 self.pg_enable_capture(self.pg_interfaces)
1199 frags = self.pg1.get_capture(len(pkts))
1200 p = self.reass_frags_and_verify(frags,
1201 self.pg0.remote_ip4,
1202 self.server_in_addr)
1203 if proto != IP_PROTOS.icmp:
1204 self.assertEqual(p[layer].sport, self.port_in)
1205 self.assertEqual(p[layer].dport, self.server_in_port)
1207 self.assertEqual(p[layer].id, self.port_in)
1208 self.assertEqual(data, p[Raw].load)
1211 if proto != IP_PROTOS.icmp:
1212 pkts = self.create_stream_frag(self.pg1, self.pg0.remote_ip4,
1213 self.server_in_port,
1214 p[layer].sport, data, proto)
1216 pkts = self.create_stream_frag(self.pg1, self.pg0.remote_ip4,
1217 p[layer].id, 0, data, proto,
1219 self.pg1.add_stream(pkts)
1220 self.pg_enable_capture(self.pg_interfaces)
1222 frags = self.pg0.get_capture(len(pkts))
1223 p = self.reass_frags_and_verify(frags,
1224 self.server_out_addr,
1225 self.pg0.remote_ip4)
1226 if proto != IP_PROTOS.icmp:
1227 self.assertEqual(p[layer].sport, self.server_out_port)
1228 self.assertEqual(p[layer].dport, self.port_in)
1230 self.assertEqual(p[layer].id, self.port_in)
1231 self.assertEqual(data, p[Raw].load)
1233 def reass_hairpinning(self, proto=IP_PROTOS.tcp, ignore_port=False):
1234 layer = self.proto2layer(proto)
1236 if proto == IP_PROTOS.tcp:
1237 data = b"A" * 4 + b"B" * 16 + b"C" * 3
1239 data = b"A" * 16 + b"B" * 16 + b"C" * 3
1241 # send packet from host to server
1242 pkts = self.create_stream_frag(self.pg0,
1245 self.server_out_port,
1248 self.pg0.add_stream(pkts)
1249 self.pg_enable_capture(self.pg_interfaces)
1251 frags = self.pg0.get_capture(len(pkts))
1252 p = self.reass_frags_and_verify(frags,
1255 if proto != IP_PROTOS.icmp:
1257 self.assertNotEqual(p[layer].sport, self.host_in_port)
1258 self.assertEqual(p[layer].dport, self.server_in_port)
1261 self.assertNotEqual(p[layer].id, self.host_in_port)
1262 self.assertEqual(data, p[Raw].load)
1264 def frag_out_of_order(self, proto=IP_PROTOS.tcp, dont_translate=False,
1266 layer = self.proto2layer(proto)
1268 if proto == IP_PROTOS.tcp:
1269 data = b"A" * 4 + b"B" * 16 + b"C" * 3
1271 data = b"A" * 16 + b"B" * 16 + b"C" * 3
1272 self.port_in = random.randint(1025, 65535)
1276 pkts = self.create_stream_frag(self.pg0, self.pg1.remote_ip4,
1277 self.port_in, 20, data, proto)
1279 self.pg0.add_stream(pkts)
1280 self.pg_enable_capture(self.pg_interfaces)
1282 frags = self.pg1.get_capture(len(pkts))
1283 if not dont_translate:
1284 p = self.reass_frags_and_verify(frags,
1286 self.pg1.remote_ip4)
1288 p = self.reass_frags_and_verify(frags,
1289 self.pg0.remote_ip4,
1290 self.pg1.remote_ip4)
1291 if proto != IP_PROTOS.icmp:
1292 if not dont_translate:
1293 self.assertEqual(p[layer].dport, 20)
1295 self.assertNotEqual(p[layer].sport, self.port_in)
1297 self.assertEqual(p[layer].sport, self.port_in)
1300 if not dont_translate:
1301 self.assertNotEqual(p[layer].id, self.port_in)
1303 self.assertEqual(p[layer].id, self.port_in)
1304 self.assertEqual(data, p[Raw].load)
1307 if not dont_translate:
1308 dst_addr = self.nat_addr
1310 dst_addr = self.pg0.remote_ip4
1311 if proto != IP_PROTOS.icmp:
1313 dport = p[layer].sport
1317 pkts = self.create_stream_frag(self.pg1, dst_addr, sport, dport,
1318 data, proto, echo_reply=True)
1320 self.pg1.add_stream(pkts)
1321 self.pg_enable_capture(self.pg_interfaces)
1323 frags = self.pg0.get_capture(len(pkts))
1324 p = self.reass_frags_and_verify(frags,
1325 self.pg1.remote_ip4,
1326 self.pg0.remote_ip4)
1327 if proto != IP_PROTOS.icmp:
1328 self.assertEqual(p[layer].sport, 20)
1329 self.assertEqual(p[layer].dport, self.port_in)
1331 self.assertEqual(p[layer].id, self.port_in)
1332 self.assertEqual(data, p[Raw].load)
1334 def frag_out_of_order_in_plus_out(self, proto=IP_PROTOS.tcp):
1335 layer = self.proto2layer(proto)
1337 if proto == IP_PROTOS.tcp:
1338 data = b"A" * 4 + b"B" * 16 + b"C" * 3
1340 data = b"A" * 16 + b"B" * 16 + b"C" * 3
1341 self.port_in = random.randint(1025, 65535)
1345 pkts = self.create_stream_frag(self.pg0, self.server_out_addr,
1346 self.port_in, self.server_out_port,
1349 self.pg0.add_stream(pkts)
1350 self.pg_enable_capture(self.pg_interfaces)
1352 frags = self.pg1.get_capture(len(pkts))
1353 p = self.reass_frags_and_verify(frags,
1354 self.pg0.remote_ip4,
1355 self.server_in_addr)
1356 if proto != IP_PROTOS.icmp:
1357 self.assertEqual(p[layer].dport, self.server_in_port)
1358 self.assertEqual(p[layer].sport, self.port_in)
1359 self.assertEqual(p[layer].dport, self.server_in_port)
1361 self.assertEqual(p[layer].id, self.port_in)
1362 self.assertEqual(data, p[Raw].load)
1365 if proto != IP_PROTOS.icmp:
1366 pkts = self.create_stream_frag(self.pg1, self.pg0.remote_ip4,
1367 self.server_in_port,
1368 p[layer].sport, data, proto)
1370 pkts = self.create_stream_frag(self.pg1, self.pg0.remote_ip4,
1371 p[layer].id, 0, data, proto,
1374 self.pg1.add_stream(pkts)
1375 self.pg_enable_capture(self.pg_interfaces)
1377 frags = self.pg0.get_capture(len(pkts))
1378 p = self.reass_frags_and_verify(frags,
1379 self.server_out_addr,
1380 self.pg0.remote_ip4)
1381 if proto != IP_PROTOS.icmp:
1382 self.assertEqual(p[layer].sport, self.server_out_port)
1383 self.assertEqual(p[layer].dport, self.port_in)
1385 self.assertEqual(p[layer].id, self.port_in)
1386 self.assertEqual(data, p[Raw].load)
1389 class TestNAT44(MethodHolder):
1390 """ NAT44 Test Cases """
1392 max_translations = 10240
1396 def setUpConstants(cls):
1397 super(TestNAT44, 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 setUpClass(cls):
1407 super(TestNAT44, cls).setUpClass()
1408 cls.vapi.cli("set log class nat level debug")
1410 cls.tcp_port_in = 6303
1411 cls.tcp_port_out = 6303
1412 cls.udp_port_in = 6304
1413 cls.udp_port_out = 6304
1414 cls.icmp_id_in = 6305
1415 cls.icmp_id_out = 6305
1416 cls.nat_addr = '10.0.0.3'
1417 cls.ipfix_src_port = 4739
1418 cls.ipfix_domain_id = 1
1419 cls.tcp_external_port = 80
1420 cls.udp_external_port = 69
1422 cls.create_pg_interfaces(range(10))
1423 cls.interfaces = list(cls.pg_interfaces[0:4])
1425 for i in cls.interfaces:
1430 cls.pg0.generate_remote_hosts(3)
1431 cls.pg0.configure_ipv4_neighbors()
1433 cls.pg1.generate_remote_hosts(1)
1434 cls.pg1.configure_ipv4_neighbors()
1436 cls.overlapping_interfaces = list(list(cls.pg_interfaces[4:7]))
1437 cls.vapi.ip_table_add_del(is_add=1, table={'table_id': 10})
1438 cls.vapi.ip_table_add_del(is_add=1, table={'table_id': 20})
1440 cls.pg4._local_ip4 = "172.16.255.1"
1441 cls.pg4._remote_hosts[0]._ip4 = "172.16.255.2"
1442 cls.pg4.set_table_ip4(10)
1443 cls.pg5._local_ip4 = "172.17.255.3"
1444 cls.pg5._remote_hosts[0]._ip4 = "172.17.255.4"
1445 cls.pg5.set_table_ip4(10)
1446 cls.pg6._local_ip4 = "172.16.255.1"
1447 cls.pg6._remote_hosts[0]._ip4 = "172.16.255.2"
1448 cls.pg6.set_table_ip4(20)
1449 for i in cls.overlapping_interfaces:
1457 cls.pg9.generate_remote_hosts(2)
1458 cls.pg9.config_ip4()
1459 cls.vapi.sw_interface_add_del_address(
1460 sw_if_index=cls.pg9.sw_if_index,
1461 prefix="10.0.0.1/24")
1464 cls.pg9.resolve_arp()
1465 cls.pg9._remote_hosts[1]._ip4 = cls.pg9._remote_hosts[0]._ip4
1466 cls.pg4._remote_ip4 = cls.pg9._remote_hosts[0]._ip4 = "10.0.0.2"
1467 cls.pg9.resolve_arp()
1470 def tearDownClass(cls):
1471 super(TestNAT44, cls).tearDownClass()
1473 def test_clear_sessions(self):
1474 """ NAT44 session clearing test """
1476 self.nat44_add_address(self.nat_addr)
1477 flags = self.config_flags.NAT_IS_INSIDE
1478 self.vapi.nat44_interface_add_del_feature(
1479 sw_if_index=self.pg0.sw_if_index,
1480 flags=flags, is_add=1)
1481 self.vapi.nat44_interface_add_del_feature(
1482 sw_if_index=self.pg1.sw_if_index,
1485 nat_config = self.vapi.nat_show_config()
1486 self.assertEqual(0, nat_config.endpoint_dependent)
1488 pkts = self.create_stream_in(self.pg0, self.pg1)
1489 self.pg0.add_stream(pkts)
1490 self.pg_enable_capture(self.pg_interfaces)
1492 capture = self.pg1.get_capture(len(pkts))
1493 self.verify_capture_out(capture)
1495 sessions = self.statistics.get_counter('/nat44/total-sessions')
1496 self.assertTrue(sessions[0][0] > 0)
1497 self.logger.info("sessions before clearing: %s" % sessions[0][0])
1499 self.vapi.cli("clear nat44 sessions")
1501 sessions = self.statistics.get_counter('/nat44/total-sessions')
1502 self.assertEqual(sessions[0][0], 0)
1503 self.logger.info("sessions after clearing: %s" % sessions[0][0])
1505 def test_dynamic(self):
1506 """ NAT44 dynamic translation test """
1507 self.nat44_add_address(self.nat_addr)
1508 flags = self.config_flags.NAT_IS_INSIDE
1509 self.vapi.nat44_interface_add_del_feature(
1510 sw_if_index=self.pg0.sw_if_index,
1511 flags=flags, is_add=1)
1512 self.vapi.nat44_interface_add_del_feature(
1513 sw_if_index=self.pg1.sw_if_index,
1517 tcpn = self.statistics.get_err_counter(
1518 '/err/nat44-in2out-slowpath/TCP packets')
1519 udpn = self.statistics.get_err_counter(
1520 '/err/nat44-in2out-slowpath/UDP packets')
1521 icmpn = self.statistics.get_err_counter(
1522 '/err/nat44-in2out-slowpath/ICMP packets')
1523 totaln = self.statistics.get_err_counter(
1524 '/err/nat44-in2out-slowpath/good in2out packets processed')
1526 pkts = self.create_stream_in(self.pg0, self.pg1)
1527 self.pg0.add_stream(pkts)
1528 self.pg_enable_capture(self.pg_interfaces)
1530 capture = self.pg1.get_capture(len(pkts))
1531 self.verify_capture_out(capture)
1533 err = self.statistics.get_err_counter(
1534 '/err/nat44-in2out-slowpath/TCP packets')
1535 self.assertEqual(err - tcpn, 2)
1536 err = self.statistics.get_err_counter(
1537 '/err/nat44-in2out-slowpath/UDP packets')
1538 self.assertEqual(err - udpn, 1)
1539 err = self.statistics.get_err_counter(
1540 '/err/nat44-in2out-slowpath/ICMP packets')
1541 self.assertEqual(err - icmpn, 1)
1542 err = self.statistics.get_err_counter(
1543 '/err/nat44-in2out-slowpath/good in2out packets processed')
1544 self.assertEqual(err - totaln, 4)
1547 tcpn = self.statistics.get_err_counter('/err/nat44-out2in/TCP packets')
1548 udpn = self.statistics.get_err_counter('/err/nat44-out2in/UDP packets')
1549 icmpn = self.statistics.get_err_counter(
1550 '/err/nat44-out2in/ICMP packets')
1551 totaln = self.statistics.get_err_counter(
1552 '/err/nat44-out2in/good out2in packets processed')
1554 pkts = self.create_stream_out(self.pg1)
1555 self.pg1.add_stream(pkts)
1556 self.pg_enable_capture(self.pg_interfaces)
1558 capture = self.pg0.get_capture(len(pkts))
1559 self.verify_capture_in(capture, self.pg0)
1561 err = self.statistics.get_err_counter('/err/nat44-out2in/TCP packets')
1562 self.assertEqual(err - tcpn, 2)
1563 err = self.statistics.get_err_counter('/err/nat44-out2in/UDP packets')
1564 self.assertEqual(err - udpn, 1)
1565 err = self.statistics.get_err_counter('/err/nat44-out2in/ICMP packets')
1566 self.assertEqual(err - icmpn, 1)
1567 err = self.statistics.get_err_counter(
1568 '/err/nat44-out2in/good out2in packets processed')
1569 self.assertEqual(err - totaln, 4)
1571 users = self.statistics.get_counter('/nat44/total-users')
1572 self.assertEqual(users[0][0], 1)
1573 sessions = self.statistics.get_counter('/nat44/total-sessions')
1574 self.assertEqual(sessions[0][0], 3)
1576 def test_dynamic_icmp_errors_in2out_ttl_1(self):
1577 """ NAT44 handling of client packets with TTL=1 """
1579 self.nat44_add_address(self.nat_addr)
1580 flags = self.config_flags.NAT_IS_INSIDE
1581 self.vapi.nat44_interface_add_del_feature(
1582 sw_if_index=self.pg0.sw_if_index,
1583 flags=flags, is_add=1)
1584 self.vapi.nat44_interface_add_del_feature(
1585 sw_if_index=self.pg1.sw_if_index,
1588 # Client side - generate traffic
1589 pkts = self.create_stream_in(self.pg0, self.pg1, ttl=1)
1590 self.pg0.add_stream(pkts)
1591 self.pg_enable_capture(self.pg_interfaces)
1594 # Client side - verify ICMP type 11 packets
1595 capture = self.pg0.get_capture(len(pkts))
1596 self.verify_capture_in_with_icmp_errors(capture, self.pg0)
1598 def test_dynamic_icmp_errors_out2in_ttl_1(self):
1599 """ NAT44 handling of server packets with TTL=1 """
1601 self.nat44_add_address(self.nat_addr)
1602 flags = self.config_flags.NAT_IS_INSIDE
1603 self.vapi.nat44_interface_add_del_feature(
1604 sw_if_index=self.pg0.sw_if_index,
1605 flags=flags, is_add=1)
1606 self.vapi.nat44_interface_add_del_feature(
1607 sw_if_index=self.pg1.sw_if_index,
1610 # Client side - create sessions
1611 pkts = self.create_stream_in(self.pg0, self.pg1)
1612 self.pg0.add_stream(pkts)
1613 self.pg_enable_capture(self.pg_interfaces)
1616 # Server side - generate traffic
1617 capture = self.pg1.get_capture(len(pkts))
1618 self.verify_capture_out(capture)
1619 pkts = self.create_stream_out(self.pg1, ttl=1)
1620 self.pg1.add_stream(pkts)
1621 self.pg_enable_capture(self.pg_interfaces)
1624 # Server side - verify ICMP type 11 packets
1625 capture = self.pg1.get_capture(len(pkts))
1626 self.verify_capture_out_with_icmp_errors(capture,
1627 src_ip=self.pg1.local_ip4)
1629 def test_dynamic_icmp_errors_in2out_ttl_2(self):
1630 """ NAT44 handling of error responses to client packets with TTL=2 """
1632 self.nat44_add_address(self.nat_addr)
1633 flags = self.config_flags.NAT_IS_INSIDE
1634 self.vapi.nat44_interface_add_del_feature(
1635 sw_if_index=self.pg0.sw_if_index,
1636 flags=flags, is_add=1)
1637 self.vapi.nat44_interface_add_del_feature(
1638 sw_if_index=self.pg1.sw_if_index,
1641 # Client side - generate traffic
1642 pkts = self.create_stream_in(self.pg0, self.pg1, ttl=2)
1643 self.pg0.add_stream(pkts)
1644 self.pg_enable_capture(self.pg_interfaces)
1647 # Server side - simulate ICMP type 11 response
1648 capture = self.pg1.get_capture(len(pkts))
1649 pkts = [Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
1650 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
1651 ICMP(type=11) / packet[IP] for packet in capture]
1652 self.pg1.add_stream(pkts)
1653 self.pg_enable_capture(self.pg_interfaces)
1656 # Client side - verify ICMP type 11 packets
1657 capture = self.pg0.get_capture(len(pkts))
1658 self.verify_capture_in_with_icmp_errors(capture, self.pg0)
1660 def test_dynamic_icmp_errors_out2in_ttl_2(self):
1661 """ NAT44 handling of error responses to server packets with TTL=2 """
1663 self.nat44_add_address(self.nat_addr)
1664 flags = self.config_flags.NAT_IS_INSIDE
1665 self.vapi.nat44_interface_add_del_feature(
1666 sw_if_index=self.pg0.sw_if_index,
1667 flags=flags, is_add=1)
1668 self.vapi.nat44_interface_add_del_feature(
1669 sw_if_index=self.pg1.sw_if_index,
1672 # Client side - create sessions
1673 pkts = self.create_stream_in(self.pg0, self.pg1)
1674 self.pg0.add_stream(pkts)
1675 self.pg_enable_capture(self.pg_interfaces)
1678 # Server side - generate traffic
1679 capture = self.pg1.get_capture(len(pkts))
1680 self.verify_capture_out(capture)
1681 pkts = self.create_stream_out(self.pg1, ttl=2)
1682 self.pg1.add_stream(pkts)
1683 self.pg_enable_capture(self.pg_interfaces)
1686 # Client side - simulate ICMP type 11 response
1687 capture = self.pg0.get_capture(len(pkts))
1688 pkts = [Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
1689 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
1690 ICMP(type=11) / packet[IP] for packet in capture]
1691 self.pg0.add_stream(pkts)
1692 self.pg_enable_capture(self.pg_interfaces)
1695 # Server side - verify ICMP type 11 packets
1696 capture = self.pg1.get_capture(len(pkts))
1697 self.verify_capture_out_with_icmp_errors(capture)
1699 def test_ping_out_interface_from_outside(self):
1700 """ Ping NAT44 out interface from outside network """
1702 self.nat44_add_address(self.nat_addr)
1703 flags = self.config_flags.NAT_IS_INSIDE
1704 self.vapi.nat44_interface_add_del_feature(
1705 sw_if_index=self.pg0.sw_if_index,
1706 flags=flags, is_add=1)
1707 self.vapi.nat44_interface_add_del_feature(
1708 sw_if_index=self.pg1.sw_if_index,
1711 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
1712 IP(src=self.pg1.remote_ip4, dst=self.pg1.local_ip4) /
1713 ICMP(id=self.icmp_id_out, type='echo-request'))
1715 self.pg1.add_stream(pkts)
1716 self.pg_enable_capture(self.pg_interfaces)
1718 capture = self.pg1.get_capture(len(pkts))
1721 self.assertEqual(packet[IP].src, self.pg1.local_ip4)
1722 self.assertEqual(packet[IP].dst, self.pg1.remote_ip4)
1723 self.assertEqual(packet[ICMP].id, self.icmp_id_in)
1724 self.assertEqual(packet[ICMP].type, 0) # echo reply
1726 self.logger.error(ppp("Unexpected or invalid packet "
1727 "(outside network):", packet))
1730 def test_ping_internal_host_from_outside(self):
1731 """ Ping internal host from outside network """
1733 self.nat44_add_static_mapping(self.pg0.remote_ip4, self.nat_addr)
1734 flags = self.config_flags.NAT_IS_INSIDE
1735 self.vapi.nat44_interface_add_del_feature(
1736 sw_if_index=self.pg0.sw_if_index,
1737 flags=flags, is_add=1)
1738 self.vapi.nat44_interface_add_del_feature(
1739 sw_if_index=self.pg1.sw_if_index,
1743 pkt = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
1744 IP(src=self.pg1.remote_ip4, dst=self.nat_addr, ttl=64) /
1745 ICMP(id=self.icmp_id_out, type='echo-request'))
1746 self.pg1.add_stream(pkt)
1747 self.pg_enable_capture(self.pg_interfaces)
1749 capture = self.pg0.get_capture(1)
1750 self.verify_capture_in(capture, self.pg0)
1751 self.assert_equal(capture[0][IP].proto, IP_PROTOS.icmp)
1754 pkt = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
1755 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4, ttl=64) /
1756 ICMP(id=self.icmp_id_in, type='echo-reply'))
1757 self.pg0.add_stream(pkt)
1758 self.pg_enable_capture(self.pg_interfaces)
1760 capture = self.pg1.get_capture(1)
1761 self.verify_capture_out(capture, same_port=True)
1762 self.assert_equal(capture[0][IP].proto, IP_PROTOS.icmp)
1764 def test_forwarding(self):
1765 """ NAT44 forwarding test """
1767 flags = self.config_flags.NAT_IS_INSIDE
1768 self.vapi.nat44_interface_add_del_feature(
1769 sw_if_index=self.pg0.sw_if_index,
1770 flags=flags, is_add=1)
1771 self.vapi.nat44_interface_add_del_feature(
1772 sw_if_index=self.pg1.sw_if_index,
1774 self.vapi.nat44_forwarding_enable_disable(enable=1)
1776 real_ip = self.pg0.remote_ip4
1777 alias_ip = self.nat_addr
1778 flags = self.config_flags.NAT_IS_ADDR_ONLY
1779 self.vapi.nat44_add_del_static_mapping(is_add=1,
1780 local_ip_address=real_ip,
1781 external_ip_address=alias_ip,
1782 external_sw_if_index=0xFFFFFFFF,
1786 # static mapping match
1788 pkts = self.create_stream_out(self.pg1)
1789 self.pg1.add_stream(pkts)
1790 self.pg_enable_capture(self.pg_interfaces)
1792 capture = self.pg0.get_capture(len(pkts))
1793 self.verify_capture_in(capture, self.pg0)
1795 pkts = self.create_stream_in(self.pg0, self.pg1)
1796 self.pg0.add_stream(pkts)
1797 self.pg_enable_capture(self.pg_interfaces)
1799 capture = self.pg1.get_capture(len(pkts))
1800 self.verify_capture_out(capture, same_port=True)
1802 # no static mapping match
1804 host0 = self.pg0.remote_hosts[0]
1805 self.pg0.remote_hosts[0] = self.pg0.remote_hosts[1]
1807 pkts = self.create_stream_out(self.pg1,
1808 dst_ip=self.pg0.remote_ip4,
1809 use_inside_ports=True)
1810 self.pg1.add_stream(pkts)
1811 self.pg_enable_capture(self.pg_interfaces)
1813 capture = self.pg0.get_capture(len(pkts))
1814 self.verify_capture_in(capture, self.pg0)
1816 pkts = self.create_stream_in(self.pg0, self.pg1)
1817 self.pg0.add_stream(pkts)
1818 self.pg_enable_capture(self.pg_interfaces)
1820 capture = self.pg1.get_capture(len(pkts))
1821 self.verify_capture_out(capture, nat_ip=self.pg0.remote_ip4,
1824 self.pg0.remote_hosts[0] = host0
1827 self.vapi.nat44_forwarding_enable_disable(enable=0)
1828 flags = self.config_flags.NAT_IS_ADDR_ONLY
1829 self.vapi.nat44_add_del_static_mapping(
1831 local_ip_address=real_ip,
1832 external_ip_address=alias_ip,
1833 external_sw_if_index=0xFFFFFFFF,
1836 def test_static_in(self):
1837 """ 1:1 NAT initialized from inside network """
1839 nat_ip = "10.0.0.10"
1840 self.tcp_port_out = 6303
1841 self.udp_port_out = 6304
1842 self.icmp_id_out = 6305
1844 self.nat44_add_static_mapping(self.pg0.remote_ip4, nat_ip)
1845 flags = self.config_flags.NAT_IS_INSIDE
1846 self.vapi.nat44_interface_add_del_feature(
1847 sw_if_index=self.pg0.sw_if_index,
1848 flags=flags, is_add=1)
1849 self.vapi.nat44_interface_add_del_feature(
1850 sw_if_index=self.pg1.sw_if_index,
1852 sm = self.vapi.nat44_static_mapping_dump()
1853 self.assertEqual(len(sm), 1)
1854 self.assertEqual(sm[0].tag, '')
1855 self.assertEqual(sm[0].protocol, 0)
1856 self.assertEqual(sm[0].local_port, 0)
1857 self.assertEqual(sm[0].external_port, 0)
1860 pkts = self.create_stream_in(self.pg0, self.pg1)
1861 self.pg0.add_stream(pkts)
1862 self.pg_enable_capture(self.pg_interfaces)
1864 capture = self.pg1.get_capture(len(pkts))
1865 self.verify_capture_out(capture, nat_ip, True)
1868 pkts = self.create_stream_out(self.pg1, nat_ip)
1869 self.pg1.add_stream(pkts)
1870 self.pg_enable_capture(self.pg_interfaces)
1872 capture = self.pg0.get_capture(len(pkts))
1873 self.verify_capture_in(capture, self.pg0)
1875 def test_static_out(self):
1876 """ 1:1 NAT initialized from outside network """
1878 nat_ip = "10.0.0.20"
1879 self.tcp_port_out = 6303
1880 self.udp_port_out = 6304
1881 self.icmp_id_out = 6305
1884 self.nat44_add_static_mapping(self.pg0.remote_ip4, nat_ip, tag=tag)
1885 flags = self.config_flags.NAT_IS_INSIDE
1886 self.vapi.nat44_interface_add_del_feature(
1887 sw_if_index=self.pg0.sw_if_index,
1888 flags=flags, is_add=1)
1889 self.vapi.nat44_interface_add_del_feature(
1890 sw_if_index=self.pg1.sw_if_index,
1892 sm = self.vapi.nat44_static_mapping_dump()
1893 self.assertEqual(len(sm), 1)
1894 self.assertEqual(sm[0].tag, tag)
1897 pkts = self.create_stream_out(self.pg1, nat_ip)
1898 self.pg1.add_stream(pkts)
1899 self.pg_enable_capture(self.pg_interfaces)
1901 capture = self.pg0.get_capture(len(pkts))
1902 self.verify_capture_in(capture, self.pg0)
1905 pkts = self.create_stream_in(self.pg0, self.pg1)
1906 self.pg0.add_stream(pkts)
1907 self.pg_enable_capture(self.pg_interfaces)
1909 capture = self.pg1.get_capture(len(pkts))
1910 self.verify_capture_out(capture, nat_ip, True)
1912 def test_static_with_port_in(self):
1913 """ 1:1 NAPT initialized from inside network """
1915 self.tcp_port_out = 3606
1916 self.udp_port_out = 3607
1917 self.icmp_id_out = 3608
1919 self.nat44_add_address(self.nat_addr)
1920 self.nat44_add_static_mapping(self.pg0.remote_ip4, self.nat_addr,
1921 self.tcp_port_in, self.tcp_port_out,
1922 proto=IP_PROTOS.tcp)
1923 self.nat44_add_static_mapping(self.pg0.remote_ip4, self.nat_addr,
1924 self.udp_port_in, self.udp_port_out,
1925 proto=IP_PROTOS.udp)
1926 self.nat44_add_static_mapping(self.pg0.remote_ip4, self.nat_addr,
1927 self.icmp_id_in, self.icmp_id_out,
1928 proto=IP_PROTOS.icmp)
1929 flags = self.config_flags.NAT_IS_INSIDE
1930 self.vapi.nat44_interface_add_del_feature(
1931 sw_if_index=self.pg0.sw_if_index,
1932 flags=flags, is_add=1)
1933 self.vapi.nat44_interface_add_del_feature(
1934 sw_if_index=self.pg1.sw_if_index,
1938 pkts = self.create_stream_in(self.pg0, self.pg1)
1939 self.pg0.add_stream(pkts)
1940 self.pg_enable_capture(self.pg_interfaces)
1942 capture = self.pg1.get_capture(len(pkts))
1943 self.verify_capture_out(capture)
1946 pkts = self.create_stream_out(self.pg1)
1947 self.pg1.add_stream(pkts)
1948 self.pg_enable_capture(self.pg_interfaces)
1950 capture = self.pg0.get_capture(len(pkts))
1951 self.verify_capture_in(capture, self.pg0)
1953 def test_static_with_port_out(self):
1954 """ 1:1 NAPT initialized from outside network """
1956 self.tcp_port_out = 30606
1957 self.udp_port_out = 30607
1958 self.icmp_id_out = 30608
1960 self.nat44_add_address(self.nat_addr)
1961 self.nat44_add_static_mapping(self.pg0.remote_ip4, self.nat_addr,
1962 self.tcp_port_in, self.tcp_port_out,
1963 proto=IP_PROTOS.tcp)
1964 self.nat44_add_static_mapping(self.pg0.remote_ip4, self.nat_addr,
1965 self.udp_port_in, self.udp_port_out,
1966 proto=IP_PROTOS.udp)
1967 self.nat44_add_static_mapping(self.pg0.remote_ip4, self.nat_addr,
1968 self.icmp_id_in, self.icmp_id_out,
1969 proto=IP_PROTOS.icmp)
1970 flags = self.config_flags.NAT_IS_INSIDE
1971 self.vapi.nat44_interface_add_del_feature(
1972 sw_if_index=self.pg0.sw_if_index,
1973 flags=flags, is_add=1)
1974 self.vapi.nat44_interface_add_del_feature(
1975 sw_if_index=self.pg1.sw_if_index,
1979 pkts = self.create_stream_out(self.pg1)
1980 self.pg1.add_stream(pkts)
1981 self.pg_enable_capture(self.pg_interfaces)
1983 capture = self.pg0.get_capture(len(pkts))
1984 self.verify_capture_in(capture, self.pg0)
1987 pkts = self.create_stream_in(self.pg0, self.pg1)
1988 self.pg0.add_stream(pkts)
1989 self.pg_enable_capture(self.pg_interfaces)
1991 capture = self.pg1.get_capture(len(pkts))
1992 self.verify_capture_out(capture)
1994 def test_static_vrf_aware(self):
1995 """ 1:1 NAT VRF awareness """
1997 nat_ip1 = "10.0.0.30"
1998 nat_ip2 = "10.0.0.40"
1999 self.tcp_port_out = 6303
2000 self.udp_port_out = 6304
2001 self.icmp_id_out = 6305
2003 self.nat44_add_static_mapping(self.pg4.remote_ip4, nat_ip1,
2005 self.nat44_add_static_mapping(self.pg0.remote_ip4, nat_ip2,
2007 flags = self.config_flags.NAT_IS_INSIDE
2008 self.vapi.nat44_interface_add_del_feature(
2009 sw_if_index=self.pg3.sw_if_index,
2011 self.vapi.nat44_interface_add_del_feature(
2012 sw_if_index=self.pg0.sw_if_index,
2013 flags=flags, is_add=1)
2014 self.vapi.nat44_interface_add_del_feature(
2015 sw_if_index=self.pg4.sw_if_index,
2016 flags=flags, is_add=1)
2018 # inside interface VRF match NAT44 static mapping VRF
2019 pkts = self.create_stream_in(self.pg4, self.pg3)
2020 self.pg4.add_stream(pkts)
2021 self.pg_enable_capture(self.pg_interfaces)
2023 capture = self.pg3.get_capture(len(pkts))
2024 self.verify_capture_out(capture, nat_ip1, True)
2026 # inside interface VRF don't match NAT44 static mapping VRF (packets
2028 pkts = self.create_stream_in(self.pg0, self.pg3)
2029 self.pg0.add_stream(pkts)
2030 self.pg_enable_capture(self.pg_interfaces)
2032 self.pg3.assert_nothing_captured()
2034 def test_dynamic_to_static(self):
2035 """ Switch from dynamic translation to 1:1NAT """
2036 nat_ip = "10.0.0.10"
2037 self.tcp_port_out = 6303
2038 self.udp_port_out = 6304
2039 self.icmp_id_out = 6305
2041 self.nat44_add_address(self.nat_addr)
2042 flags = self.config_flags.NAT_IS_INSIDE
2043 self.vapi.nat44_interface_add_del_feature(
2044 sw_if_index=self.pg0.sw_if_index,
2045 flags=flags, is_add=1)
2046 self.vapi.nat44_interface_add_del_feature(
2047 sw_if_index=self.pg1.sw_if_index,
2051 pkts = self.create_stream_in(self.pg0, self.pg1)
2052 self.pg0.add_stream(pkts)
2053 self.pg_enable_capture(self.pg_interfaces)
2055 capture = self.pg1.get_capture(len(pkts))
2056 self.verify_capture_out(capture)
2059 self.nat44_add_static_mapping(self.pg0.remote_ip4, nat_ip)
2060 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4, 0)
2061 self.assertEqual(len(sessions), 0)
2062 pkts = self.create_stream_in(self.pg0, self.pg1)
2063 self.pg0.add_stream(pkts)
2064 self.pg_enable_capture(self.pg_interfaces)
2066 capture = self.pg1.get_capture(len(pkts))
2067 self.verify_capture_out(capture, nat_ip, True)
2069 def test_identity_nat(self):
2070 """ Identity NAT """
2071 flags = self.config_flags.NAT_IS_ADDR_ONLY
2072 self.vapi.nat44_add_del_identity_mapping(
2073 ip_address=self.pg0.remote_ip4, sw_if_index=0xFFFFFFFF,
2074 flags=flags, is_add=1)
2075 flags = self.config_flags.NAT_IS_INSIDE
2076 self.vapi.nat44_interface_add_del_feature(
2077 sw_if_index=self.pg0.sw_if_index,
2078 flags=flags, is_add=1)
2079 self.vapi.nat44_interface_add_del_feature(
2080 sw_if_index=self.pg1.sw_if_index,
2083 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
2084 IP(src=self.pg1.remote_ip4, dst=self.pg0.remote_ip4) /
2085 TCP(sport=12345, dport=56789))
2086 self.pg1.add_stream(p)
2087 self.pg_enable_capture(self.pg_interfaces)
2089 capture = self.pg0.get_capture(1)
2094 self.assertEqual(ip.dst, self.pg0.remote_ip4)
2095 self.assertEqual(ip.src, self.pg1.remote_ip4)
2096 self.assertEqual(tcp.dport, 56789)
2097 self.assertEqual(tcp.sport, 12345)
2098 self.assert_packet_checksums_valid(p)
2100 self.logger.error(ppp("Unexpected or invalid packet:", p))
2103 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4, 0)
2104 self.assertEqual(len(sessions), 0)
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, vrf_id=1, is_add=1)
2109 identity_mappings = self.vapi.nat44_identity_mapping_dump()
2110 self.assertEqual(len(identity_mappings), 2)
2112 def test_multiple_inside_interfaces(self):
2113 """ NAT44 multiple non-overlapping address space inside interfaces """
2115 self.nat44_add_address(self.nat_addr)
2116 flags = self.config_flags.NAT_IS_INSIDE
2117 self.vapi.nat44_interface_add_del_feature(
2118 sw_if_index=self.pg0.sw_if_index,
2119 flags=flags, is_add=1)
2120 self.vapi.nat44_interface_add_del_feature(
2121 sw_if_index=self.pg1.sw_if_index,
2122 flags=flags, is_add=1)
2123 self.vapi.nat44_interface_add_del_feature(
2124 sw_if_index=self.pg3.sw_if_index,
2127 # between two NAT44 inside interfaces (no translation)
2128 pkts = self.create_stream_in(self.pg0, self.pg1)
2129 self.pg0.add_stream(pkts)
2130 self.pg_enable_capture(self.pg_interfaces)
2132 capture = self.pg1.get_capture(len(pkts))
2133 self.verify_capture_no_translation(capture, self.pg0, self.pg1)
2135 # from NAT44 inside to interface without NAT44 feature (no translation)
2136 pkts = self.create_stream_in(self.pg0, self.pg2)
2137 self.pg0.add_stream(pkts)
2138 self.pg_enable_capture(self.pg_interfaces)
2140 capture = self.pg2.get_capture(len(pkts))
2141 self.verify_capture_no_translation(capture, self.pg0, self.pg2)
2143 # in2out 1st interface
2144 pkts = self.create_stream_in(self.pg0, self.pg3)
2145 self.pg0.add_stream(pkts)
2146 self.pg_enable_capture(self.pg_interfaces)
2148 capture = self.pg3.get_capture(len(pkts))
2149 self.verify_capture_out(capture)
2151 # out2in 1st interface
2152 pkts = self.create_stream_out(self.pg3)
2153 self.pg3.add_stream(pkts)
2154 self.pg_enable_capture(self.pg_interfaces)
2156 capture = self.pg0.get_capture(len(pkts))
2157 self.verify_capture_in(capture, self.pg0)
2159 # in2out 2nd interface
2160 pkts = self.create_stream_in(self.pg1, self.pg3)
2161 self.pg1.add_stream(pkts)
2162 self.pg_enable_capture(self.pg_interfaces)
2164 capture = self.pg3.get_capture(len(pkts))
2165 self.verify_capture_out(capture)
2167 # out2in 2nd interface
2168 pkts = self.create_stream_out(self.pg3)
2169 self.pg3.add_stream(pkts)
2170 self.pg_enable_capture(self.pg_interfaces)
2172 capture = self.pg1.get_capture(len(pkts))
2173 self.verify_capture_in(capture, self.pg1)
2175 def test_inside_overlapping_interfaces(self):
2176 """ NAT44 multiple inside interfaces with overlapping address space """
2178 static_nat_ip = "10.0.0.10"
2179 self.nat44_add_address(self.nat_addr)
2180 flags = self.config_flags.NAT_IS_INSIDE
2181 self.vapi.nat44_interface_add_del_feature(
2182 sw_if_index=self.pg3.sw_if_index,
2184 self.vapi.nat44_interface_add_del_feature(
2185 sw_if_index=self.pg4.sw_if_index,
2186 flags=flags, is_add=1)
2187 self.vapi.nat44_interface_add_del_feature(
2188 sw_if_index=self.pg5.sw_if_index,
2189 flags=flags, is_add=1)
2190 self.vapi.nat44_interface_add_del_feature(
2191 sw_if_index=self.pg6.sw_if_index,
2192 flags=flags, is_add=1)
2193 self.nat44_add_static_mapping(self.pg6.remote_ip4, static_nat_ip,
2196 # between NAT44 inside interfaces with same VRF (no translation)
2197 pkts = self.create_stream_in(self.pg4, self.pg5)
2198 self.pg4.add_stream(pkts)
2199 self.pg_enable_capture(self.pg_interfaces)
2201 capture = self.pg5.get_capture(len(pkts))
2202 self.verify_capture_no_translation(capture, self.pg4, self.pg5)
2204 # between NAT44 inside interfaces with different VRF (hairpinning)
2205 p = (Ether(src=self.pg4.remote_mac, dst=self.pg4.local_mac) /
2206 IP(src=self.pg4.remote_ip4, dst=static_nat_ip) /
2207 TCP(sport=1234, dport=5678))
2208 self.pg4.add_stream(p)
2209 self.pg_enable_capture(self.pg_interfaces)
2211 capture = self.pg6.get_capture(1)
2216 self.assertEqual(ip.src, self.nat_addr)
2217 self.assertEqual(ip.dst, self.pg6.remote_ip4)
2218 self.assertNotEqual(tcp.sport, 1234)
2219 self.assertEqual(tcp.dport, 5678)
2221 self.logger.error(ppp("Unexpected or invalid packet:", p))
2224 # in2out 1st interface
2225 pkts = self.create_stream_in(self.pg4, self.pg3)
2226 self.pg4.add_stream(pkts)
2227 self.pg_enable_capture(self.pg_interfaces)
2229 capture = self.pg3.get_capture(len(pkts))
2230 self.verify_capture_out(capture)
2232 # out2in 1st interface
2233 pkts = self.create_stream_out(self.pg3)
2234 self.pg3.add_stream(pkts)
2235 self.pg_enable_capture(self.pg_interfaces)
2237 capture = self.pg4.get_capture(len(pkts))
2238 self.verify_capture_in(capture, self.pg4)
2240 # in2out 2nd interface
2241 pkts = self.create_stream_in(self.pg5, self.pg3)
2242 self.pg5.add_stream(pkts)
2243 self.pg_enable_capture(self.pg_interfaces)
2245 capture = self.pg3.get_capture(len(pkts))
2246 self.verify_capture_out(capture)
2248 # out2in 2nd interface
2249 pkts = self.create_stream_out(self.pg3)
2250 self.pg3.add_stream(pkts)
2251 self.pg_enable_capture(self.pg_interfaces)
2253 capture = self.pg5.get_capture(len(pkts))
2254 self.verify_capture_in(capture, self.pg5)
2257 addresses = self.vapi.nat44_address_dump()
2258 self.assertEqual(len(addresses), 1)
2259 sessions = self.vapi.nat44_user_session_dump(self.pg5.remote_ip4, 10)
2260 self.assertEqual(len(sessions), 3)
2261 for session in sessions:
2262 self.assertFalse(session.flags & self.config_flags.NAT_IS_STATIC)
2263 self.assertEqual(str(session.inside_ip_address),
2264 self.pg5.remote_ip4)
2265 self.assertEqual(session.outside_ip_address,
2266 addresses[0].ip_address)
2267 self.assertEqual(sessions[0].protocol, IP_PROTOS.tcp)
2268 self.assertEqual(sessions[1].protocol, IP_PROTOS.udp)
2269 self.assertEqual(sessions[2].protocol, IP_PROTOS.icmp)
2270 self.assertEqual(sessions[0].inside_port, self.tcp_port_in)
2271 self.assertEqual(sessions[1].inside_port, self.udp_port_in)
2272 self.assertEqual(sessions[2].inside_port, self.icmp_id_in)
2273 self.assertEqual(sessions[0].outside_port, self.tcp_port_out)
2274 self.assertEqual(sessions[1].outside_port, self.udp_port_out)
2275 self.assertEqual(sessions[2].outside_port, self.icmp_id_out)
2277 # in2out 3rd interface
2278 pkts = self.create_stream_in(self.pg6, self.pg3)
2279 self.pg6.add_stream(pkts)
2280 self.pg_enable_capture(self.pg_interfaces)
2282 capture = self.pg3.get_capture(len(pkts))
2283 self.verify_capture_out(capture, static_nat_ip, True)
2285 # out2in 3rd interface
2286 pkts = self.create_stream_out(self.pg3, static_nat_ip)
2287 self.pg3.add_stream(pkts)
2288 self.pg_enable_capture(self.pg_interfaces)
2290 capture = self.pg6.get_capture(len(pkts))
2291 self.verify_capture_in(capture, self.pg6)
2293 # general user and session dump verifications
2294 users = self.vapi.nat44_user_dump()
2295 self.assertGreaterEqual(len(users), 3)
2296 addresses = self.vapi.nat44_address_dump()
2297 self.assertEqual(len(addresses), 1)
2299 sessions = self.vapi.nat44_user_session_dump(user.ip_address,
2301 for session in sessions:
2302 self.assertEqual(user.ip_address, session.inside_ip_address)
2303 self.assertTrue(session.total_bytes > session.total_pkts > 0)
2304 self.assertTrue(session.protocol in
2305 [IP_PROTOS.tcp, IP_PROTOS.udp,
2307 self.assertFalse(session.flags &
2308 self.config_flags.NAT_IS_EXT_HOST_VALID)
2311 sessions = self.vapi.nat44_user_session_dump(self.pg4.remote_ip4, 10)
2312 self.assertGreaterEqual(len(sessions), 4)
2313 for session in sessions:
2314 self.assertFalse(session.flags & self.config_flags.NAT_IS_STATIC)
2315 self.assertEqual(str(session.inside_ip_address),
2316 self.pg4.remote_ip4)
2317 self.assertEqual(session.outside_ip_address,
2318 addresses[0].ip_address)
2321 sessions = self.vapi.nat44_user_session_dump(self.pg6.remote_ip4, 20)
2322 self.assertGreaterEqual(len(sessions), 3)
2323 for session in sessions:
2324 self.assertTrue(session.flags & self.config_flags.NAT_IS_STATIC)
2325 self.assertEqual(str(session.inside_ip_address),
2326 self.pg6.remote_ip4)
2327 self.assertEqual(str(session.outside_ip_address),
2329 self.assertTrue(session.inside_port in
2330 [self.tcp_port_in, self.udp_port_in,
2333 def test_hairpinning(self):
2334 """ NAT44 hairpinning - 1:1 NAPT """
2336 host = self.pg0.remote_hosts[0]
2337 server = self.pg0.remote_hosts[1]
2340 server_in_port = 5678
2341 server_out_port = 8765
2343 self.nat44_add_address(self.nat_addr)
2344 flags = self.config_flags.NAT_IS_INSIDE
2345 self.vapi.nat44_interface_add_del_feature(
2346 sw_if_index=self.pg0.sw_if_index,
2347 flags=flags, is_add=1)
2348 self.vapi.nat44_interface_add_del_feature(
2349 sw_if_index=self.pg1.sw_if_index,
2352 # add static mapping for server
2353 self.nat44_add_static_mapping(server.ip4, self.nat_addr,
2354 server_in_port, server_out_port,
2355 proto=IP_PROTOS.tcp)
2357 # send packet from host to server
2358 p = (Ether(src=host.mac, dst=self.pg0.local_mac) /
2359 IP(src=host.ip4, dst=self.nat_addr) /
2360 TCP(sport=host_in_port, dport=server_out_port))
2361 self.pg0.add_stream(p)
2362 self.pg_enable_capture(self.pg_interfaces)
2364 capture = self.pg0.get_capture(1)
2369 self.assertEqual(ip.src, self.nat_addr)
2370 self.assertEqual(ip.dst, server.ip4)
2371 self.assertNotEqual(tcp.sport, host_in_port)
2372 self.assertEqual(tcp.dport, server_in_port)
2373 self.assert_packet_checksums_valid(p)
2374 host_out_port = tcp.sport
2376 self.logger.error(ppp("Unexpected or invalid packet:", p))
2379 # send reply from server to host
2380 p = (Ether(src=server.mac, dst=self.pg0.local_mac) /
2381 IP(src=server.ip4, dst=self.nat_addr) /
2382 TCP(sport=server_in_port, dport=host_out_port))
2383 self.pg0.add_stream(p)
2384 self.pg_enable_capture(self.pg_interfaces)
2386 capture = self.pg0.get_capture(1)
2391 self.assertEqual(ip.src, self.nat_addr)
2392 self.assertEqual(ip.dst, host.ip4)
2393 self.assertEqual(tcp.sport, server_out_port)
2394 self.assertEqual(tcp.dport, host_in_port)
2395 self.assert_packet_checksums_valid(p)
2397 self.logger.error(ppp("Unexpected or invalid packet:", p))
2400 def test_hairpinning2(self):
2401 """ NAT44 hairpinning - 1:1 NAT"""
2403 server1_nat_ip = "10.0.0.10"
2404 server2_nat_ip = "10.0.0.11"
2405 host = self.pg0.remote_hosts[0]
2406 server1 = self.pg0.remote_hosts[1]
2407 server2 = self.pg0.remote_hosts[2]
2408 server_tcp_port = 22
2409 server_udp_port = 20
2411 self.nat44_add_address(self.nat_addr)
2412 flags = self.config_flags.NAT_IS_INSIDE
2413 self.vapi.nat44_interface_add_del_feature(
2414 sw_if_index=self.pg0.sw_if_index,
2415 flags=flags, is_add=1)
2416 self.vapi.nat44_interface_add_del_feature(
2417 sw_if_index=self.pg1.sw_if_index,
2420 # add static mapping for servers
2421 self.nat44_add_static_mapping(server1.ip4, server1_nat_ip)
2422 self.nat44_add_static_mapping(server2.ip4, server2_nat_ip)
2426 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2427 IP(src=host.ip4, dst=server1_nat_ip) /
2428 TCP(sport=self.tcp_port_in, dport=server_tcp_port))
2430 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2431 IP(src=host.ip4, dst=server1_nat_ip) /
2432 UDP(sport=self.udp_port_in, dport=server_udp_port))
2434 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2435 IP(src=host.ip4, dst=server1_nat_ip) /
2436 ICMP(id=self.icmp_id_in, type='echo-request'))
2438 self.pg0.add_stream(pkts)
2439 self.pg_enable_capture(self.pg_interfaces)
2441 capture = self.pg0.get_capture(len(pkts))
2442 for packet in capture:
2444 self.assertEqual(packet[IP].src, self.nat_addr)
2445 self.assertEqual(packet[IP].dst, server1.ip4)
2446 if packet.haslayer(TCP):
2447 self.assertNotEqual(packet[TCP].sport, self.tcp_port_in)
2448 self.assertEqual(packet[TCP].dport, server_tcp_port)
2449 self.tcp_port_out = packet[TCP].sport
2450 self.assert_packet_checksums_valid(packet)
2451 elif packet.haslayer(UDP):
2452 self.assertNotEqual(packet[UDP].sport, self.udp_port_in)
2453 self.assertEqual(packet[UDP].dport, server_udp_port)
2454 self.udp_port_out = packet[UDP].sport
2456 self.assertNotEqual(packet[ICMP].id, self.icmp_id_in)
2457 self.icmp_id_out = packet[ICMP].id
2459 self.logger.error(ppp("Unexpected or invalid packet:", packet))
2464 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2465 IP(src=server1.ip4, dst=self.nat_addr) /
2466 TCP(sport=server_tcp_port, dport=self.tcp_port_out))
2468 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2469 IP(src=server1.ip4, dst=self.nat_addr) /
2470 UDP(sport=server_udp_port, dport=self.udp_port_out))
2472 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2473 IP(src=server1.ip4, dst=self.nat_addr) /
2474 ICMP(id=self.icmp_id_out, type='echo-reply'))
2476 self.pg0.add_stream(pkts)
2477 self.pg_enable_capture(self.pg_interfaces)
2479 capture = self.pg0.get_capture(len(pkts))
2480 for packet in capture:
2482 self.assertEqual(packet[IP].src, server1_nat_ip)
2483 self.assertEqual(packet[IP].dst, host.ip4)
2484 if packet.haslayer(TCP):
2485 self.assertEqual(packet[TCP].dport, self.tcp_port_in)
2486 self.assertEqual(packet[TCP].sport, server_tcp_port)
2487 self.assert_packet_checksums_valid(packet)
2488 elif packet.haslayer(UDP):
2489 self.assertEqual(packet[UDP].dport, self.udp_port_in)
2490 self.assertEqual(packet[UDP].sport, server_udp_port)
2492 self.assertEqual(packet[ICMP].id, self.icmp_id_in)
2494 self.logger.error(ppp("Unexpected or invalid packet:", packet))
2497 # server2 to server1
2499 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2500 IP(src=server2.ip4, dst=server1_nat_ip) /
2501 TCP(sport=self.tcp_port_in, dport=server_tcp_port))
2503 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2504 IP(src=server2.ip4, dst=server1_nat_ip) /
2505 UDP(sport=self.udp_port_in, dport=server_udp_port))
2507 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2508 IP(src=server2.ip4, dst=server1_nat_ip) /
2509 ICMP(id=self.icmp_id_in, type='echo-request'))
2511 self.pg0.add_stream(pkts)
2512 self.pg_enable_capture(self.pg_interfaces)
2514 capture = self.pg0.get_capture(len(pkts))
2515 for packet in capture:
2517 self.assertEqual(packet[IP].src, server2_nat_ip)
2518 self.assertEqual(packet[IP].dst, server1.ip4)
2519 if packet.haslayer(TCP):
2520 self.assertEqual(packet[TCP].sport, self.tcp_port_in)
2521 self.assertEqual(packet[TCP].dport, server_tcp_port)
2522 self.tcp_port_out = packet[TCP].sport
2523 self.assert_packet_checksums_valid(packet)
2524 elif packet.haslayer(UDP):
2525 self.assertEqual(packet[UDP].sport, self.udp_port_in)
2526 self.assertEqual(packet[UDP].dport, server_udp_port)
2527 self.udp_port_out = packet[UDP].sport
2529 self.assertEqual(packet[ICMP].id, self.icmp_id_in)
2530 self.icmp_id_out = packet[ICMP].id
2532 self.logger.error(ppp("Unexpected or invalid packet:", packet))
2535 # server1 to server2
2537 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2538 IP(src=server1.ip4, dst=server2_nat_ip) /
2539 TCP(sport=server_tcp_port, dport=self.tcp_port_out))
2541 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2542 IP(src=server1.ip4, dst=server2_nat_ip) /
2543 UDP(sport=server_udp_port, dport=self.udp_port_out))
2545 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2546 IP(src=server1.ip4, dst=server2_nat_ip) /
2547 ICMP(id=self.icmp_id_out, type='echo-reply'))
2549 self.pg0.add_stream(pkts)
2550 self.pg_enable_capture(self.pg_interfaces)
2552 capture = self.pg0.get_capture(len(pkts))
2553 for packet in capture:
2555 self.assertEqual(packet[IP].src, server1_nat_ip)
2556 self.assertEqual(packet[IP].dst, server2.ip4)
2557 if packet.haslayer(TCP):
2558 self.assertEqual(packet[TCP].dport, self.tcp_port_in)
2559 self.assertEqual(packet[TCP].sport, server_tcp_port)
2560 self.assert_packet_checksums_valid(packet)
2561 elif packet.haslayer(UDP):
2562 self.assertEqual(packet[UDP].dport, self.udp_port_in)
2563 self.assertEqual(packet[UDP].sport, server_udp_port)
2565 self.assertEqual(packet[ICMP].id, self.icmp_id_in)
2567 self.logger.error(ppp("Unexpected or invalid packet:", packet))
2570 def test_interface_addr(self):
2571 """ Acquire NAT44 addresses from interface """
2572 self.vapi.nat44_add_del_interface_addr(
2574 sw_if_index=self.pg7.sw_if_index)
2576 # no address in NAT pool
2577 addresses = self.vapi.nat44_address_dump()
2578 self.assertEqual(0, len(addresses))
2580 # configure interface address and check NAT address pool
2581 self.pg7.config_ip4()
2582 addresses = self.vapi.nat44_address_dump()
2583 self.assertEqual(1, len(addresses))
2584 self.assertEqual(str(addresses[0].ip_address), self.pg7.local_ip4)
2586 # remove interface address and check NAT address pool
2587 self.pg7.unconfig_ip4()
2588 addresses = self.vapi.nat44_address_dump()
2589 self.assertEqual(0, len(addresses))
2591 def test_interface_addr_static_mapping(self):
2592 """ Static mapping with addresses from interface """
2595 self.vapi.nat44_add_del_interface_addr(
2597 sw_if_index=self.pg7.sw_if_index)
2598 self.nat44_add_static_mapping(
2600 external_sw_if_index=self.pg7.sw_if_index,
2603 # static mappings with external interface
2604 static_mappings = self.vapi.nat44_static_mapping_dump()
2605 self.assertEqual(1, len(static_mappings))
2606 self.assertEqual(self.pg7.sw_if_index,
2607 static_mappings[0].external_sw_if_index)
2608 self.assertEqual(static_mappings[0].tag, tag)
2610 # configure interface address and check static mappings
2611 self.pg7.config_ip4()
2612 static_mappings = self.vapi.nat44_static_mapping_dump()
2613 self.assertEqual(2, len(static_mappings))
2615 for sm in static_mappings:
2616 if sm.external_sw_if_index == 0xFFFFFFFF:
2617 self.assertEqual(str(sm.external_ip_address),
2619 self.assertEqual(sm.tag, tag)
2621 self.assertTrue(resolved)
2623 # remove interface address and check static mappings
2624 self.pg7.unconfig_ip4()
2625 static_mappings = self.vapi.nat44_static_mapping_dump()
2626 self.assertEqual(1, len(static_mappings))
2627 self.assertEqual(self.pg7.sw_if_index,
2628 static_mappings[0].external_sw_if_index)
2629 self.assertEqual(static_mappings[0].tag, tag)
2631 # configure interface address again and check static mappings
2632 self.pg7.config_ip4()
2633 static_mappings = self.vapi.nat44_static_mapping_dump()
2634 self.assertEqual(2, len(static_mappings))
2636 for sm in static_mappings:
2637 if sm.external_sw_if_index == 0xFFFFFFFF:
2638 self.assertEqual(str(sm.external_ip_address),
2640 self.assertEqual(sm.tag, tag)
2642 self.assertTrue(resolved)
2644 # remove static mapping
2645 self.nat44_add_static_mapping(
2647 external_sw_if_index=self.pg7.sw_if_index,
2650 static_mappings = self.vapi.nat44_static_mapping_dump()
2651 self.assertEqual(0, len(static_mappings))
2653 def test_interface_addr_identity_nat(self):
2654 """ Identity NAT with addresses from interface """
2657 self.vapi.nat44_add_del_interface_addr(
2659 sw_if_index=self.pg7.sw_if_index)
2660 self.vapi.nat44_add_del_identity_mapping(
2662 sw_if_index=self.pg7.sw_if_index,
2664 protocol=IP_PROTOS.tcp,
2667 # identity mappings with external interface
2668 identity_mappings = self.vapi.nat44_identity_mapping_dump()
2669 self.assertEqual(1, len(identity_mappings))
2670 self.assertEqual(self.pg7.sw_if_index,
2671 identity_mappings[0].sw_if_index)
2673 # configure interface address and check identity mappings
2674 self.pg7.config_ip4()
2675 identity_mappings = self.vapi.nat44_identity_mapping_dump()
2677 self.assertEqual(2, len(identity_mappings))
2678 for sm in identity_mappings:
2679 if sm.sw_if_index == 0xFFFFFFFF:
2680 self.assertEqual(str(identity_mappings[0].ip_address),
2682 self.assertEqual(port, identity_mappings[0].port)
2683 self.assertEqual(IP_PROTOS.tcp, identity_mappings[0].protocol)
2685 self.assertTrue(resolved)
2687 # remove interface address and check identity mappings
2688 self.pg7.unconfig_ip4()
2689 identity_mappings = self.vapi.nat44_identity_mapping_dump()
2690 self.assertEqual(1, len(identity_mappings))
2691 self.assertEqual(self.pg7.sw_if_index,
2692 identity_mappings[0].sw_if_index)
2694 def test_ipfix_nat44_sess(self):
2695 """ IPFIX logging NAT44 session created/deleted """
2696 self.ipfix_domain_id = 10
2697 self.ipfix_src_port = 20202
2698 collector_port = 30303
2699 bind_layers(UDP, IPFIX, dport=30303)
2700 self.nat44_add_address(self.nat_addr)
2701 flags = self.config_flags.NAT_IS_INSIDE
2702 self.vapi.nat44_interface_add_del_feature(
2703 sw_if_index=self.pg0.sw_if_index,
2704 flags=flags, is_add=1)
2705 self.vapi.nat44_interface_add_del_feature(
2706 sw_if_index=self.pg1.sw_if_index,
2708 self.vapi.set_ipfix_exporter(collector_address=self.pg3.remote_ip4,
2709 src_address=self.pg3.local_ip4,
2711 template_interval=10,
2712 collector_port=collector_port)
2713 self.vapi.nat_ipfix_enable_disable(domain_id=self.ipfix_domain_id,
2714 src_port=self.ipfix_src_port,
2717 pkts = self.create_stream_in(self.pg0, self.pg1)
2718 self.pg0.add_stream(pkts)
2719 self.pg_enable_capture(self.pg_interfaces)
2721 capture = self.pg1.get_capture(len(pkts))
2722 self.verify_capture_out(capture)
2723 self.nat44_add_address(self.nat_addr, is_add=0)
2724 self.vapi.ipfix_flush()
2725 capture = self.pg3.get_capture(7)
2726 ipfix = IPFIXDecoder()
2727 # first load template
2729 self.assertTrue(p.haslayer(IPFIX))
2730 self.assertEqual(p[IP].src, self.pg3.local_ip4)
2731 self.assertEqual(p[IP].dst, self.pg3.remote_ip4)
2732 self.assertEqual(p[UDP].sport, self.ipfix_src_port)
2733 self.assertEqual(p[UDP].dport, collector_port)
2734 self.assertEqual(p[IPFIX].observationDomainID,
2735 self.ipfix_domain_id)
2736 if p.haslayer(Template):
2737 ipfix.add_template(p.getlayer(Template))
2738 # verify events in data set
2740 if p.haslayer(Data):
2741 data = ipfix.decode_data_set(p.getlayer(Set))
2742 self.verify_ipfix_nat44_ses(data)
2744 def test_ipfix_addr_exhausted(self):
2745 """ IPFIX logging NAT addresses exhausted """
2746 flags = self.config_flags.NAT_IS_INSIDE
2747 self.vapi.nat44_interface_add_del_feature(
2748 sw_if_index=self.pg0.sw_if_index,
2749 flags=flags, is_add=1)
2750 self.vapi.nat44_interface_add_del_feature(
2751 sw_if_index=self.pg1.sw_if_index,
2753 self.vapi.set_ipfix_exporter(collector_address=self.pg3.remote_ip4,
2754 src_address=self.pg3.local_ip4,
2756 template_interval=10)
2757 self.vapi.nat_ipfix_enable_disable(domain_id=self.ipfix_domain_id,
2758 src_port=self.ipfix_src_port,
2761 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
2762 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
2764 self.pg0.add_stream(p)
2765 self.pg_enable_capture(self.pg_interfaces)
2767 self.pg1.assert_nothing_captured()
2769 self.vapi.ipfix_flush()
2770 capture = self.pg3.get_capture(7)
2771 ipfix = IPFIXDecoder()
2772 # first load template
2774 self.assertTrue(p.haslayer(IPFIX))
2775 self.assertEqual(p[IP].src, self.pg3.local_ip4)
2776 self.assertEqual(p[IP].dst, self.pg3.remote_ip4)
2777 self.assertEqual(p[UDP].sport, self.ipfix_src_port)
2778 self.assertEqual(p[UDP].dport, 4739)
2779 self.assertEqual(p[IPFIX].observationDomainID,
2780 self.ipfix_domain_id)
2781 if p.haslayer(Template):
2782 ipfix.add_template(p.getlayer(Template))
2783 # verify events in data set
2785 if p.haslayer(Data):
2786 data = ipfix.decode_data_set(p.getlayer(Set))
2787 self.verify_ipfix_addr_exhausted(data)
2789 @unittest.skipUnless(running_extended_tests, "part of extended tests")
2790 def test_ipfix_max_sessions(self):
2791 """ IPFIX logging maximum session entries exceeded """
2792 self.nat44_add_address(self.nat_addr)
2793 flags = self.config_flags.NAT_IS_INSIDE
2794 self.vapi.nat44_interface_add_del_feature(
2795 sw_if_index=self.pg0.sw_if_index,
2796 flags=flags, is_add=1)
2797 self.vapi.nat44_interface_add_del_feature(
2798 sw_if_index=self.pg1.sw_if_index,
2801 max_sessions = self.max_translations
2804 for i in range(0, max_sessions):
2805 src = "10.10.%u.%u" % ((i & 0xFF00) >> 8, i & 0xFF)
2806 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2807 IP(src=src, dst=self.pg1.remote_ip4) /
2810 self.pg0.add_stream(pkts)
2811 self.pg_enable_capture(self.pg_interfaces)
2814 self.pg1.get_capture(max_sessions)
2815 self.vapi.set_ipfix_exporter(collector_address=self.pg3.remote_ip4,
2816 src_address=self.pg3.local_ip4,
2818 template_interval=10)
2819 self.vapi.nat_ipfix_enable_disable(domain_id=self.ipfix_domain_id,
2820 src_port=self.ipfix_src_port,
2823 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2824 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
2826 self.pg0.add_stream(p)
2827 self.pg_enable_capture(self.pg_interfaces)
2829 self.pg1.assert_nothing_captured()
2831 self.vapi.ipfix_flush()
2832 capture = self.pg3.get_capture(7)
2833 ipfix = IPFIXDecoder()
2834 # first load template
2836 self.assertTrue(p.haslayer(IPFIX))
2837 self.assertEqual(p[IP].src, self.pg3.local_ip4)
2838 self.assertEqual(p[IP].dst, self.pg3.remote_ip4)
2839 self.assertEqual(p[UDP].sport, self.ipfix_src_port)
2840 self.assertEqual(p[UDP].dport, 4739)
2841 self.assertEqual(p[IPFIX].observationDomainID,
2842 self.ipfix_domain_id)
2843 if p.haslayer(Template):
2844 ipfix.add_template(p.getlayer(Template))
2845 # verify events in data set
2847 if p.haslayer(Data):
2848 data = ipfix.decode_data_set(p.getlayer(Set))
2849 self.verify_ipfix_max_sessions(data, max_sessions)
2851 def test_syslog_apmap(self):
2852 """ Test syslog address and port mapping creation and deletion """
2853 self.vapi.syslog_set_filter(
2854 self.SYSLOG_SEVERITY.SYSLOG_API_SEVERITY_INFO)
2855 self.vapi.syslog_set_sender(self.pg3.local_ip4, self.pg3.remote_ip4)
2856 self.nat44_add_address(self.nat_addr)
2857 flags = self.config_flags.NAT_IS_INSIDE
2858 self.vapi.nat44_interface_add_del_feature(
2859 sw_if_index=self.pg0.sw_if_index,
2860 flags=flags, is_add=1)
2861 self.vapi.nat44_interface_add_del_feature(
2862 sw_if_index=self.pg1.sw_if_index,
2865 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2866 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
2867 TCP(sport=self.tcp_port_in, dport=20))
2868 self.pg0.add_stream(p)
2869 self.pg_enable_capture(self.pg_interfaces)
2871 capture = self.pg1.get_capture(1)
2872 self.tcp_port_out = capture[0][TCP].sport
2873 capture = self.pg3.get_capture(1)
2874 self.verify_syslog_apmap(capture[0][Raw].load)
2876 self.pg_enable_capture(self.pg_interfaces)
2878 self.nat44_add_address(self.nat_addr, is_add=0)
2879 capture = self.pg3.get_capture(1)
2880 self.verify_syslog_apmap(capture[0][Raw].load, False)
2882 def test_pool_addr_fib(self):
2883 """ NAT44 add pool addresses to FIB """
2884 static_addr = '10.0.0.10'
2885 self.nat44_add_address(self.nat_addr)
2886 flags = self.config_flags.NAT_IS_INSIDE
2887 self.vapi.nat44_interface_add_del_feature(
2888 sw_if_index=self.pg0.sw_if_index,
2889 flags=flags, is_add=1)
2890 self.vapi.nat44_interface_add_del_feature(
2891 sw_if_index=self.pg1.sw_if_index,
2893 self.nat44_add_static_mapping(self.pg0.remote_ip4, static_addr)
2896 p = (Ether(src=self.pg1.remote_mac, dst='ff:ff:ff:ff:ff:ff') /
2897 ARP(op=ARP.who_has, pdst=self.nat_addr,
2898 psrc=self.pg1.remote_ip4, hwsrc=self.pg1.remote_mac))
2899 self.pg1.add_stream(p)
2900 self.pg_enable_capture(self.pg_interfaces)
2902 capture = self.pg1.get_capture(1)
2903 self.assertTrue(capture[0].haslayer(ARP))
2904 self.assertTrue(capture[0][ARP].op, ARP.is_at)
2907 p = (Ether(src=self.pg1.remote_mac, dst='ff:ff:ff:ff:ff:ff') /
2908 ARP(op=ARP.who_has, pdst=static_addr,
2909 psrc=self.pg1.remote_ip4, hwsrc=self.pg1.remote_mac))
2910 self.pg1.add_stream(p)
2911 self.pg_enable_capture(self.pg_interfaces)
2913 capture = self.pg1.get_capture(1)
2914 self.assertTrue(capture[0].haslayer(ARP))
2915 self.assertTrue(capture[0][ARP].op, ARP.is_at)
2917 # send ARP to non-NAT44 interface
2918 p = (Ether(src=self.pg2.remote_mac, dst='ff:ff:ff:ff:ff:ff') /
2919 ARP(op=ARP.who_has, pdst=self.nat_addr,
2920 psrc=self.pg2.remote_ip4, hwsrc=self.pg2.remote_mac))
2921 self.pg2.add_stream(p)
2922 self.pg_enable_capture(self.pg_interfaces)
2924 self.pg1.assert_nothing_captured()
2926 # remove addresses and verify
2927 self.nat44_add_address(self.nat_addr, is_add=0)
2928 self.nat44_add_static_mapping(self.pg0.remote_ip4, static_addr,
2931 p = (Ether(src=self.pg1.remote_mac, dst='ff:ff:ff:ff:ff:ff') /
2932 ARP(op=ARP.who_has, pdst=self.nat_addr,
2933 psrc=self.pg1.remote_ip4, hwsrc=self.pg1.remote_mac))
2934 self.pg1.add_stream(p)
2935 self.pg_enable_capture(self.pg_interfaces)
2937 self.pg1.assert_nothing_captured()
2939 p = (Ether(src=self.pg1.remote_mac, dst='ff:ff:ff:ff:ff:ff') /
2940 ARP(op=ARP.who_has, pdst=static_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 self.pg1.assert_nothing_captured()
2947 def test_vrf_mode(self):
2948 """ NAT44 tenant VRF aware address pool mode """
2952 nat_ip1 = "10.0.0.10"
2953 nat_ip2 = "10.0.0.11"
2955 self.pg0.unconfig_ip4()
2956 self.pg1.unconfig_ip4()
2957 self.vapi.ip_table_add_del(is_add=1, table={'table_id': vrf_id1})
2958 self.vapi.ip_table_add_del(is_add=1, table={'table_id': vrf_id2})
2959 self.pg0.set_table_ip4(vrf_id1)
2960 self.pg1.set_table_ip4(vrf_id2)
2961 self.pg0.config_ip4()
2962 self.pg1.config_ip4()
2963 self.pg0.resolve_arp()
2964 self.pg1.resolve_arp()
2966 self.nat44_add_address(nat_ip1, vrf_id=vrf_id1)
2967 self.nat44_add_address(nat_ip2, vrf_id=vrf_id2)
2968 flags = self.config_flags.NAT_IS_INSIDE
2969 self.vapi.nat44_interface_add_del_feature(
2970 sw_if_index=self.pg0.sw_if_index,
2971 flags=flags, is_add=1)
2972 self.vapi.nat44_interface_add_del_feature(
2973 sw_if_index=self.pg1.sw_if_index,
2974 flags=flags, is_add=1)
2975 self.vapi.nat44_interface_add_del_feature(
2976 sw_if_index=self.pg2.sw_if_index,
2981 pkts = self.create_stream_in(self.pg0, self.pg2)
2982 self.pg0.add_stream(pkts)
2983 self.pg_enable_capture(self.pg_interfaces)
2985 capture = self.pg2.get_capture(len(pkts))
2986 self.verify_capture_out(capture, nat_ip1)
2989 pkts = self.create_stream_in(self.pg1, self.pg2)
2990 self.pg1.add_stream(pkts)
2991 self.pg_enable_capture(self.pg_interfaces)
2993 capture = self.pg2.get_capture(len(pkts))
2994 self.verify_capture_out(capture, nat_ip2)
2997 self.pg0.unconfig_ip4()
2998 self.pg1.unconfig_ip4()
2999 self.pg0.set_table_ip4(0)
3000 self.pg1.set_table_ip4(0)
3001 self.pg0.config_ip4()
3002 self.pg1.config_ip4()
3003 self.pg0.resolve_arp()
3004 self.pg1.resolve_arp()
3005 self.vapi.ip_table_add_del(is_add=0, table={'table_id': vrf_id1})
3006 self.vapi.ip_table_add_del(is_add=0, table={'table_id': vrf_id2})
3008 def test_vrf_feature_independent(self):
3009 """ NAT44 tenant VRF independent address pool mode """
3011 nat_ip1 = "10.0.0.10"
3012 nat_ip2 = "10.0.0.11"
3014 self.nat44_add_address(nat_ip1)
3015 self.nat44_add_address(nat_ip2, vrf_id=99)
3016 flags = self.config_flags.NAT_IS_INSIDE
3017 self.vapi.nat44_interface_add_del_feature(
3018 sw_if_index=self.pg0.sw_if_index,
3019 flags=flags, is_add=1)
3020 self.vapi.nat44_interface_add_del_feature(
3021 sw_if_index=self.pg1.sw_if_index,
3022 flags=flags, is_add=1)
3023 self.vapi.nat44_interface_add_del_feature(
3024 sw_if_index=self.pg2.sw_if_index,
3028 pkts = self.create_stream_in(self.pg0, self.pg2)
3029 self.pg0.add_stream(pkts)
3030 self.pg_enable_capture(self.pg_interfaces)
3032 capture = self.pg2.get_capture(len(pkts))
3033 self.verify_capture_out(capture, nat_ip1)
3036 pkts = self.create_stream_in(self.pg1, self.pg2)
3037 self.pg1.add_stream(pkts)
3038 self.pg_enable_capture(self.pg_interfaces)
3040 capture = self.pg2.get_capture(len(pkts))
3041 self.verify_capture_out(capture, nat_ip1)
3043 def create_routes_and_neigbors(self):
3044 r1 = VppIpRoute(self, self.pg7.remote_ip4, 32,
3045 [VppRoutePath(self.pg7.remote_ip4,
3046 self.pg7.sw_if_index)])
3047 r2 = VppIpRoute(self, self.pg8.remote_ip4, 32,
3048 [VppRoutePath(self.pg8.remote_ip4,
3049 self.pg8.sw_if_index)])
3053 n1 = VppNeighbor(self,
3054 self.pg7.sw_if_index,
3055 self.pg7.remote_mac,
3056 self.pg7.remote_ip4,
3058 n2 = VppNeighbor(self,
3059 self.pg8.sw_if_index,
3060 self.pg8.remote_mac,
3061 self.pg8.remote_ip4,
3066 def test_dynamic_ipless_interfaces(self):
3067 """ NAT44 interfaces without configured IP address """
3068 self.create_routes_and_neigbors()
3069 self.nat44_add_address(self.nat_addr)
3070 flags = self.config_flags.NAT_IS_INSIDE
3071 self.vapi.nat44_interface_add_del_feature(
3072 sw_if_index=self.pg7.sw_if_index,
3073 flags=flags, is_add=1)
3074 self.vapi.nat44_interface_add_del_feature(
3075 sw_if_index=self.pg8.sw_if_index,
3079 pkts = self.create_stream_in(self.pg7, self.pg8)
3080 self.pg7.add_stream(pkts)
3081 self.pg_enable_capture(self.pg_interfaces)
3083 capture = self.pg8.get_capture(len(pkts))
3084 self.verify_capture_out(capture)
3087 pkts = self.create_stream_out(self.pg8, self.nat_addr)
3088 self.pg8.add_stream(pkts)
3089 self.pg_enable_capture(self.pg_interfaces)
3091 capture = self.pg7.get_capture(len(pkts))
3092 self.verify_capture_in(capture, self.pg7)
3094 def test_static_ipless_interfaces(self):
3095 """ NAT44 interfaces without configured IP address - 1:1 NAT """
3097 self.create_routes_and_neigbors()
3098 self.nat44_add_static_mapping(self.pg7.remote_ip4, self.nat_addr)
3099 flags = self.config_flags.NAT_IS_INSIDE
3100 self.vapi.nat44_interface_add_del_feature(
3101 sw_if_index=self.pg7.sw_if_index,
3102 flags=flags, is_add=1)
3103 self.vapi.nat44_interface_add_del_feature(
3104 sw_if_index=self.pg8.sw_if_index,
3108 pkts = self.create_stream_out(self.pg8)
3109 self.pg8.add_stream(pkts)
3110 self.pg_enable_capture(self.pg_interfaces)
3112 capture = self.pg7.get_capture(len(pkts))
3113 self.verify_capture_in(capture, self.pg7)
3116 pkts = self.create_stream_in(self.pg7, self.pg8)
3117 self.pg7.add_stream(pkts)
3118 self.pg_enable_capture(self.pg_interfaces)
3120 capture = self.pg8.get_capture(len(pkts))
3121 self.verify_capture_out(capture, self.nat_addr, True)
3123 def test_static_with_port_ipless_interfaces(self):
3124 """ NAT44 interfaces without configured IP address - 1:1 NAPT """
3126 self.tcp_port_out = 30606
3127 self.udp_port_out = 30607
3128 self.icmp_id_out = 30608
3130 self.create_routes_and_neigbors()
3131 self.nat44_add_address(self.nat_addr)
3132 self.nat44_add_static_mapping(self.pg7.remote_ip4, self.nat_addr,
3133 self.tcp_port_in, self.tcp_port_out,
3134 proto=IP_PROTOS.tcp)
3135 self.nat44_add_static_mapping(self.pg7.remote_ip4, self.nat_addr,
3136 self.udp_port_in, self.udp_port_out,
3137 proto=IP_PROTOS.udp)
3138 self.nat44_add_static_mapping(self.pg7.remote_ip4, self.nat_addr,
3139 self.icmp_id_in, self.icmp_id_out,
3140 proto=IP_PROTOS.icmp)
3141 flags = self.config_flags.NAT_IS_INSIDE
3142 self.vapi.nat44_interface_add_del_feature(
3143 sw_if_index=self.pg7.sw_if_index,
3144 flags=flags, is_add=1)
3145 self.vapi.nat44_interface_add_del_feature(
3146 sw_if_index=self.pg8.sw_if_index,
3150 pkts = self.create_stream_out(self.pg8)
3151 self.pg8.add_stream(pkts)
3152 self.pg_enable_capture(self.pg_interfaces)
3154 capture = self.pg7.get_capture(len(pkts))
3155 self.verify_capture_in(capture, self.pg7)
3158 pkts = self.create_stream_in(self.pg7, self.pg8)
3159 self.pg7.add_stream(pkts)
3160 self.pg_enable_capture(self.pg_interfaces)
3162 capture = self.pg8.get_capture(len(pkts))
3163 self.verify_capture_out(capture)
3165 def test_static_unknown_proto(self):
3166 """ 1:1 NAT translate packet with unknown protocol """
3167 nat_ip = "10.0.0.10"
3168 self.nat44_add_static_mapping(self.pg0.remote_ip4, nat_ip)
3169 flags = self.config_flags.NAT_IS_INSIDE
3170 self.vapi.nat44_interface_add_del_feature(
3171 sw_if_index=self.pg0.sw_if_index,
3172 flags=flags, is_add=1)
3173 self.vapi.nat44_interface_add_del_feature(
3174 sw_if_index=self.pg1.sw_if_index,
3178 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
3179 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
3181 IP(src=self.pg2.remote_ip4, dst=self.pg3.remote_ip4) /
3182 TCP(sport=1234, dport=1234))
3183 self.pg0.add_stream(p)
3184 self.pg_enable_capture(self.pg_interfaces)
3186 p = self.pg1.get_capture(1)
3189 self.assertEqual(packet[IP].src, nat_ip)
3190 self.assertEqual(packet[IP].dst, self.pg1.remote_ip4)
3191 self.assertEqual(packet.haslayer(GRE), 1)
3192 self.assert_packet_checksums_valid(packet)
3194 self.logger.error(ppp("Unexpected or invalid packet:", packet))
3198 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
3199 IP(src=self.pg1.remote_ip4, dst=nat_ip) /
3201 IP(src=self.pg3.remote_ip4, dst=self.pg2.remote_ip4) /
3202 TCP(sport=1234, dport=1234))
3203 self.pg1.add_stream(p)
3204 self.pg_enable_capture(self.pg_interfaces)
3206 p = self.pg0.get_capture(1)
3209 self.assertEqual(packet[IP].src, self.pg1.remote_ip4)
3210 self.assertEqual(packet[IP].dst, self.pg0.remote_ip4)
3211 self.assertEqual(packet.haslayer(GRE), 1)
3212 self.assert_packet_checksums_valid(packet)
3214 self.logger.error(ppp("Unexpected or invalid packet:", packet))
3217 def test_hairpinning_static_unknown_proto(self):
3218 """ 1:1 NAT translate packet with unknown protocol - hairpinning """
3220 host = self.pg0.remote_hosts[0]
3221 server = self.pg0.remote_hosts[1]
3223 host_nat_ip = "10.0.0.10"
3224 server_nat_ip = "10.0.0.11"
3226 self.nat44_add_static_mapping(host.ip4, host_nat_ip)
3227 self.nat44_add_static_mapping(server.ip4, server_nat_ip)
3228 flags = self.config_flags.NAT_IS_INSIDE
3229 self.vapi.nat44_interface_add_del_feature(
3230 sw_if_index=self.pg0.sw_if_index,
3231 flags=flags, is_add=1)
3232 self.vapi.nat44_interface_add_del_feature(
3233 sw_if_index=self.pg1.sw_if_index,
3237 p = (Ether(dst=self.pg0.local_mac, src=host.mac) /
3238 IP(src=host.ip4, dst=server_nat_ip) /
3240 IP(src=self.pg2.remote_ip4, dst=self.pg3.remote_ip4) /
3241 TCP(sport=1234, dport=1234))
3242 self.pg0.add_stream(p)
3243 self.pg_enable_capture(self.pg_interfaces)
3245 p = self.pg0.get_capture(1)
3248 self.assertEqual(packet[IP].src, host_nat_ip)
3249 self.assertEqual(packet[IP].dst, server.ip4)
3250 self.assertEqual(packet.haslayer(GRE), 1)
3251 self.assert_packet_checksums_valid(packet)
3253 self.logger.error(ppp("Unexpected or invalid packet:", packet))
3257 p = (Ether(dst=self.pg0.local_mac, src=server.mac) /
3258 IP(src=server.ip4, dst=host_nat_ip) /
3260 IP(src=self.pg3.remote_ip4, dst=self.pg2.remote_ip4) /
3261 TCP(sport=1234, dport=1234))
3262 self.pg0.add_stream(p)
3263 self.pg_enable_capture(self.pg_interfaces)
3265 p = self.pg0.get_capture(1)
3268 self.assertEqual(packet[IP].src, server_nat_ip)
3269 self.assertEqual(packet[IP].dst, host.ip4)
3270 self.assertEqual(packet.haslayer(GRE), 1)
3271 self.assert_packet_checksums_valid(packet)
3273 self.logger.error(ppp("Unexpected or invalid packet:", packet))
3276 def test_output_feature(self):
3277 """ NAT44 interface output feature (in2out postrouting) """
3278 self.nat44_add_address(self.nat_addr)
3279 flags = self.config_flags.NAT_IS_INSIDE
3280 self.vapi.nat44_interface_add_del_output_feature(
3281 is_add=1, flags=flags,
3282 sw_if_index=self.pg0.sw_if_index)
3283 self.vapi.nat44_interface_add_del_output_feature(
3284 is_add=1, flags=flags,
3285 sw_if_index=self.pg1.sw_if_index)
3286 self.vapi.nat44_interface_add_del_output_feature(
3288 sw_if_index=self.pg3.sw_if_index)
3291 pkts = self.create_stream_in(self.pg0, self.pg3)
3292 self.pg0.add_stream(pkts)
3293 self.pg_enable_capture(self.pg_interfaces)
3295 capture = self.pg3.get_capture(len(pkts))
3296 self.verify_capture_out(capture)
3299 pkts = self.create_stream_out(self.pg3)
3300 self.pg3.add_stream(pkts)
3301 self.pg_enable_capture(self.pg_interfaces)
3303 capture = self.pg0.get_capture(len(pkts))
3304 self.verify_capture_in(capture, self.pg0)
3306 # from non-NAT interface to NAT inside interface
3307 pkts = self.create_stream_in(self.pg2, self.pg0)
3308 self.pg2.add_stream(pkts)
3309 self.pg_enable_capture(self.pg_interfaces)
3311 capture = self.pg0.get_capture(len(pkts))
3312 self.verify_capture_no_translation(capture, self.pg2, self.pg0)
3314 def test_output_feature_vrf_aware(self):
3315 """ NAT44 interface output feature VRF aware (in2out postrouting) """
3316 nat_ip_vrf10 = "10.0.0.10"
3317 nat_ip_vrf20 = "10.0.0.20"
3319 r1 = VppIpRoute(self, self.pg3.remote_ip4, 32,
3320 [VppRoutePath(self.pg3.remote_ip4,
3321 self.pg3.sw_if_index)],
3323 r2 = VppIpRoute(self, self.pg3.remote_ip4, 32,
3324 [VppRoutePath(self.pg3.remote_ip4,
3325 self.pg3.sw_if_index)],
3330 self.nat44_add_address(nat_ip_vrf10, vrf_id=10)
3331 self.nat44_add_address(nat_ip_vrf20, vrf_id=20)
3332 flags = self.config_flags.NAT_IS_INSIDE
3333 self.vapi.nat44_interface_add_del_output_feature(
3334 is_add=1, flags=flags,
3335 sw_if_index=self.pg4.sw_if_index)
3336 self.vapi.nat44_interface_add_del_output_feature(
3337 is_add=1, flags=flags,
3338 sw_if_index=self.pg6.sw_if_index)
3339 self.vapi.nat44_interface_add_del_output_feature(
3341 sw_if_index=self.pg3.sw_if_index)
3344 pkts = self.create_stream_in(self.pg4, self.pg3)
3345 self.pg4.add_stream(pkts)
3346 self.pg_enable_capture(self.pg_interfaces)
3348 capture = self.pg3.get_capture(len(pkts))
3349 self.verify_capture_out(capture, nat_ip=nat_ip_vrf10)
3352 pkts = self.create_stream_out(self.pg3, dst_ip=nat_ip_vrf10)
3353 self.pg3.add_stream(pkts)
3354 self.pg_enable_capture(self.pg_interfaces)
3356 capture = self.pg4.get_capture(len(pkts))
3357 self.verify_capture_in(capture, self.pg4)
3360 pkts = self.create_stream_in(self.pg6, self.pg3)
3361 self.pg6.add_stream(pkts)
3362 self.pg_enable_capture(self.pg_interfaces)
3364 capture = self.pg3.get_capture(len(pkts))
3365 self.verify_capture_out(capture, nat_ip=nat_ip_vrf20)
3368 pkts = self.create_stream_out(self.pg3, dst_ip=nat_ip_vrf20)
3369 self.pg3.add_stream(pkts)
3370 self.pg_enable_capture(self.pg_interfaces)
3372 capture = self.pg6.get_capture(len(pkts))
3373 self.verify_capture_in(capture, self.pg6)
3375 def test_output_feature_hairpinning(self):
3376 """ NAT44 interface output feature hairpinning (in2out postrouting) """
3377 host = self.pg0.remote_hosts[0]
3378 server = self.pg0.remote_hosts[1]
3381 server_in_port = 5678
3382 server_out_port = 8765
3384 self.nat44_add_address(self.nat_addr)
3385 flags = self.config_flags.NAT_IS_INSIDE
3386 self.vapi.nat44_interface_add_del_output_feature(
3387 is_add=1, flags=flags,
3388 sw_if_index=self.pg0.sw_if_index)
3389 self.vapi.nat44_interface_add_del_output_feature(
3391 sw_if_index=self.pg1.sw_if_index)
3393 # add static mapping for server
3394 self.nat44_add_static_mapping(server.ip4, self.nat_addr,
3395 server_in_port, server_out_port,
3396 proto=IP_PROTOS.tcp)
3398 # send packet from host to server
3399 p = (Ether(src=host.mac, dst=self.pg0.local_mac) /
3400 IP(src=host.ip4, dst=self.nat_addr) /
3401 TCP(sport=host_in_port, dport=server_out_port))
3402 self.pg0.add_stream(p)
3403 self.pg_enable_capture(self.pg_interfaces)
3405 capture = self.pg0.get_capture(1)
3410 self.assertEqual(ip.src, self.nat_addr)
3411 self.assertEqual(ip.dst, server.ip4)
3412 self.assertNotEqual(tcp.sport, host_in_port)
3413 self.assertEqual(tcp.dport, server_in_port)
3414 self.assert_packet_checksums_valid(p)
3415 host_out_port = tcp.sport
3417 self.logger.error(ppp("Unexpected or invalid packet:", p))
3420 # send reply from server to host
3421 p = (Ether(src=server.mac, dst=self.pg0.local_mac) /
3422 IP(src=server.ip4, dst=self.nat_addr) /
3423 TCP(sport=server_in_port, dport=host_out_port))
3424 self.pg0.add_stream(p)
3425 self.pg_enable_capture(self.pg_interfaces)
3427 capture = self.pg0.get_capture(1)
3432 self.assertEqual(ip.src, self.nat_addr)
3433 self.assertEqual(ip.dst, host.ip4)
3434 self.assertEqual(tcp.sport, server_out_port)
3435 self.assertEqual(tcp.dport, host_in_port)
3436 self.assert_packet_checksums_valid(p)
3438 self.logger.error(ppp("Unexpected or invalid packet:", p))
3441 def test_one_armed_nat44(self):
3442 """ One armed NAT44 """
3443 remote_host = self.pg9.remote_hosts[0]
3444 local_host = self.pg9.remote_hosts[1]
3447 self.nat44_add_address(self.nat_addr)
3448 flags = self.config_flags.NAT_IS_INSIDE
3449 self.vapi.nat44_interface_add_del_feature(
3450 sw_if_index=self.pg9.sw_if_index,
3452 self.vapi.nat44_interface_add_del_feature(
3453 sw_if_index=self.pg9.sw_if_index,
3454 flags=flags, is_add=1)
3457 p = (Ether(src=self.pg9.remote_mac, dst=self.pg9.local_mac) /
3458 IP(src=local_host.ip4, dst=remote_host.ip4) /
3459 TCP(sport=12345, dport=80))
3460 self.pg9.add_stream(p)
3461 self.pg_enable_capture(self.pg_interfaces)
3463 capture = self.pg9.get_capture(1)
3468 self.assertEqual(ip.src, self.nat_addr)
3469 self.assertEqual(ip.dst, remote_host.ip4)
3470 self.assertNotEqual(tcp.sport, 12345)
3471 external_port = tcp.sport
3472 self.assertEqual(tcp.dport, 80)
3473 self.assert_packet_checksums_valid(p)
3475 self.logger.error(ppp("Unexpected or invalid packet:", p))
3479 p = (Ether(src=self.pg9.remote_mac, dst=self.pg9.local_mac) /
3480 IP(src=remote_host.ip4, dst=self.nat_addr) /
3481 TCP(sport=80, dport=external_port))
3482 self.pg9.add_stream(p)
3483 self.pg_enable_capture(self.pg_interfaces)
3485 capture = self.pg9.get_capture(1)
3490 self.assertEqual(ip.src, remote_host.ip4)
3491 self.assertEqual(ip.dst, local_host.ip4)
3492 self.assertEqual(tcp.sport, 80)
3493 self.assertEqual(tcp.dport, 12345)
3494 self.assert_packet_checksums_valid(p)
3496 self.logger.error(ppp("Unexpected or invalid packet:", p))
3499 err = self.statistics.get_err_counter(
3500 '/err/nat44-classify/next in2out')
3501 self.assertEqual(err, 1)
3502 err = self.statistics.get_err_counter(
3503 '/err/nat44-classify/next out2in')
3504 self.assertEqual(err, 1)
3506 def test_del_session(self):
3507 """ Delete NAT44 session """
3508 self.nat44_add_address(self.nat_addr)
3509 flags = self.config_flags.NAT_IS_INSIDE
3510 self.vapi.nat44_interface_add_del_feature(
3511 sw_if_index=self.pg0.sw_if_index,
3512 flags=flags, is_add=1)
3513 self.vapi.nat44_interface_add_del_feature(
3514 sw_if_index=self.pg1.sw_if_index,
3517 pkts = self.create_stream_in(self.pg0, self.pg1)
3518 self.pg0.add_stream(pkts)
3519 self.pg_enable_capture(self.pg_interfaces)
3521 self.pg1.get_capture(len(pkts))
3523 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4, 0)
3524 nsessions = len(sessions)
3526 self.vapi.nat44_del_session(address=sessions[0].inside_ip_address,
3527 port=sessions[0].inside_port,
3528 protocol=sessions[0].protocol,
3529 flags=self.config_flags.NAT_IS_INSIDE)
3530 self.vapi.nat44_del_session(address=sessions[1].outside_ip_address,
3531 port=sessions[1].outside_port,
3532 protocol=sessions[1].protocol)
3534 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4, 0)
3535 self.assertEqual(nsessions - len(sessions), 2)
3537 self.vapi.nat44_del_session(address=sessions[0].inside_ip_address,
3538 port=sessions[0].inside_port,
3539 protocol=sessions[0].protocol,
3540 flags=self.config_flags.NAT_IS_INSIDE)
3542 self.verify_no_nat44_user()
3544 def test_frag_in_order(self):
3545 """ NAT44 translate fragments arriving in order """
3547 self.nat44_add_address(self.nat_addr)
3548 flags = self.config_flags.NAT_IS_INSIDE
3549 self.vapi.nat44_interface_add_del_feature(
3550 sw_if_index=self.pg0.sw_if_index,
3551 flags=flags, is_add=1)
3552 self.vapi.nat44_interface_add_del_feature(
3553 sw_if_index=self.pg1.sw_if_index,
3556 self.frag_in_order(proto=IP_PROTOS.tcp)
3557 self.frag_in_order(proto=IP_PROTOS.udp)
3558 self.frag_in_order(proto=IP_PROTOS.icmp)
3560 def test_frag_forwarding(self):
3561 """ NAT44 forwarding fragment test """
3562 self.vapi.nat44_add_del_interface_addr(
3564 sw_if_index=self.pg1.sw_if_index)
3565 flags = self.config_flags.NAT_IS_INSIDE
3566 self.vapi.nat44_interface_add_del_feature(
3567 sw_if_index=self.pg0.sw_if_index,
3568 flags=flags, is_add=1)
3569 self.vapi.nat44_interface_add_del_feature(
3570 sw_if_index=self.pg1.sw_if_index,
3572 self.vapi.nat44_forwarding_enable_disable(enable=1)
3574 data = b"A" * 16 + b"B" * 16 + b"C" * 3
3575 pkts = self.create_stream_frag(self.pg1,
3576 self.pg0.remote_ip4,
3580 proto=IP_PROTOS.udp)
3581 self.pg1.add_stream(pkts)
3582 self.pg_enable_capture(self.pg_interfaces)
3584 frags = self.pg0.get_capture(len(pkts))
3585 p = self.reass_frags_and_verify(frags,
3586 self.pg1.remote_ip4,
3587 self.pg0.remote_ip4)
3588 self.assertEqual(p[UDP].sport, 4789)
3589 self.assertEqual(p[UDP].dport, 4789)
3590 self.assertEqual(data, p[Raw].load)
3592 def test_reass_hairpinning(self):
3593 """ NAT44 fragments hairpinning """
3595 self.server = self.pg0.remote_hosts[1]
3596 self.host_in_port = random.randint(1025, 65535)
3597 self.server_in_port = random.randint(1025, 65535)
3598 self.server_out_port = random.randint(1025, 65535)
3600 self.nat44_add_address(self.nat_addr)
3601 flags = self.config_flags.NAT_IS_INSIDE
3602 self.vapi.nat44_interface_add_del_feature(
3603 sw_if_index=self.pg0.sw_if_index,
3604 flags=flags, is_add=1)
3605 self.vapi.nat44_interface_add_del_feature(
3606 sw_if_index=self.pg1.sw_if_index,
3608 # add static mapping for server
3609 self.nat44_add_static_mapping(self.server.ip4, self.nat_addr,
3610 self.server_in_port,
3611 self.server_out_port,
3612 proto=IP_PROTOS.tcp)
3613 self.nat44_add_static_mapping(self.server.ip4, self.nat_addr,
3614 self.server_in_port,
3615 self.server_out_port,
3616 proto=IP_PROTOS.udp)
3617 self.nat44_add_static_mapping(self.server.ip4, self.nat_addr)
3619 self.reass_hairpinning(proto=IP_PROTOS.tcp)
3620 self.reass_hairpinning(proto=IP_PROTOS.udp)
3621 self.reass_hairpinning(proto=IP_PROTOS.icmp)
3623 def test_frag_out_of_order(self):
3624 """ NAT44 translate fragments arriving out of order """
3626 self.nat44_add_address(self.nat_addr)
3627 flags = self.config_flags.NAT_IS_INSIDE
3628 self.vapi.nat44_interface_add_del_feature(
3629 sw_if_index=self.pg0.sw_if_index,
3630 flags=flags, is_add=1)
3631 self.vapi.nat44_interface_add_del_feature(
3632 sw_if_index=self.pg1.sw_if_index,
3635 self.frag_out_of_order(proto=IP_PROTOS.tcp)
3636 self.frag_out_of_order(proto=IP_PROTOS.udp)
3637 self.frag_out_of_order(proto=IP_PROTOS.icmp)
3639 def test_port_restricted(self):
3640 """ Port restricted NAT44 (MAP-E CE) """
3641 self.nat44_add_address(self.nat_addr)
3642 flags = self.config_flags.NAT_IS_INSIDE
3643 self.vapi.nat44_interface_add_del_feature(
3644 sw_if_index=self.pg0.sw_if_index,
3645 flags=flags, is_add=1)
3646 self.vapi.nat44_interface_add_del_feature(
3647 sw_if_index=self.pg1.sw_if_index,
3649 self.vapi.nat_set_addr_and_port_alloc_alg(alg=1,
3654 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
3655 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
3656 TCP(sport=4567, dport=22))
3657 self.pg0.add_stream(p)
3658 self.pg_enable_capture(self.pg_interfaces)
3660 capture = self.pg1.get_capture(1)
3665 self.assertEqual(ip.dst, self.pg1.remote_ip4)
3666 self.assertEqual(ip.src, self.nat_addr)
3667 self.assertEqual(tcp.dport, 22)
3668 self.assertNotEqual(tcp.sport, 4567)
3669 self.assertEqual((tcp.sport >> 6) & 63, 10)
3670 self.assert_packet_checksums_valid(p)
3672 self.logger.error(ppp("Unexpected or invalid packet:", p))
3675 def test_port_range(self):
3676 """ External address port range """
3677 self.nat44_add_address(self.nat_addr)
3678 flags = self.config_flags.NAT_IS_INSIDE
3679 self.vapi.nat44_interface_add_del_feature(
3680 sw_if_index=self.pg0.sw_if_index,
3681 flags=flags, is_add=1)
3682 self.vapi.nat44_interface_add_del_feature(
3683 sw_if_index=self.pg1.sw_if_index,
3685 self.vapi.nat_set_addr_and_port_alloc_alg(alg=2,
3690 for port in range(0, 5):
3691 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
3692 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
3693 TCP(sport=1125 + port))
3695 self.pg0.add_stream(pkts)
3696 self.pg_enable_capture(self.pg_interfaces)
3698 capture = self.pg1.get_capture(3)
3701 self.assertGreaterEqual(tcp.sport, 1025)
3702 self.assertLessEqual(tcp.sport, 1027)
3704 def test_multiple_outside_vrf(self):
3705 """ Multiple outside VRF """
3709 self.pg1.unconfig_ip4()
3710 self.pg2.unconfig_ip4()
3711 self.vapi.ip_table_add_del(is_add=1, table={'table_id': vrf_id1})
3712 self.vapi.ip_table_add_del(is_add=1, table={'table_id': vrf_id2})
3713 self.pg1.set_table_ip4(vrf_id1)
3714 self.pg2.set_table_ip4(vrf_id2)
3715 self.pg1.config_ip4()
3716 self.pg2.config_ip4()
3717 self.pg1.resolve_arp()
3718 self.pg2.resolve_arp()
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.nat44_interface_add_del_feature(
3729 sw_if_index=self.pg2.sw_if_index,
3734 pkts = self.create_stream_in(self.pg0, self.pg1)
3735 self.pg0.add_stream(pkts)
3736 self.pg_enable_capture(self.pg_interfaces)
3738 capture = self.pg1.get_capture(len(pkts))
3739 self.verify_capture_out(capture, self.nat_addr)
3741 pkts = self.create_stream_out(self.pg1, self.nat_addr)
3742 self.pg1.add_stream(pkts)
3743 self.pg_enable_capture(self.pg_interfaces)
3745 capture = self.pg0.get_capture(len(pkts))
3746 self.verify_capture_in(capture, self.pg0)
3748 self.tcp_port_in = 60303
3749 self.udp_port_in = 60304
3750 self.icmp_id_in = 60305
3753 pkts = self.create_stream_in(self.pg0, self.pg2)
3754 self.pg0.add_stream(pkts)
3755 self.pg_enable_capture(self.pg_interfaces)
3757 capture = self.pg2.get_capture(len(pkts))
3758 self.verify_capture_out(capture, self.nat_addr)
3760 pkts = self.create_stream_out(self.pg2, self.nat_addr)
3761 self.pg2.add_stream(pkts)
3762 self.pg_enable_capture(self.pg_interfaces)
3764 capture = self.pg0.get_capture(len(pkts))
3765 self.verify_capture_in(capture, self.pg0)
3768 self.nat44_add_address(self.nat_addr, is_add=0)
3769 self.pg1.unconfig_ip4()
3770 self.pg2.unconfig_ip4()
3771 self.pg1.set_table_ip4(0)
3772 self.pg2.set_table_ip4(0)
3773 self.pg1.config_ip4()
3774 self.pg2.config_ip4()
3775 self.pg1.resolve_arp()
3776 self.pg2.resolve_arp()
3778 @unittest.skipUnless(running_extended_tests, "part of extended tests")
3779 def test_session_timeout(self):
3780 """ NAT44 session timeouts """
3781 self.nat44_add_address(self.nat_addr)
3782 flags = self.config_flags.NAT_IS_INSIDE
3783 self.vapi.nat44_interface_add_del_feature(
3784 sw_if_index=self.pg0.sw_if_index,
3785 flags=flags, is_add=1)
3786 self.vapi.nat44_interface_add_del_feature(
3787 sw_if_index=self.pg1.sw_if_index,
3789 self.vapi.nat_set_timeouts(udp=5, tcp_established=7440,
3790 tcp_transitory=240, icmp=60)
3794 for i in range(0, max_sessions):
3795 src = "10.10.%u.%u" % ((i & 0xFF00) >> 8, i & 0xFF)
3796 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
3797 IP(src=src, dst=self.pg1.remote_ip4) /
3798 UDP(sport=1025, dport=53))
3800 self.pg0.add_stream(pkts)
3801 self.pg_enable_capture(self.pg_interfaces)
3803 self.pg1.get_capture(max_sessions)
3808 for i in range(0, max_sessions):
3809 src = "10.10.%u.%u" % ((i & 0xFF00) >> 8, i & 0xFF)
3810 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
3811 IP(src=src, dst=self.pg1.remote_ip4) /
3812 UDP(sport=1026, dport=53))
3814 self.pg0.add_stream(pkts)
3815 self.pg_enable_capture(self.pg_interfaces)
3817 self.pg1.get_capture(max_sessions)
3820 users = self.vapi.nat44_user_dump()
3822 nsessions = nsessions + user.nsessions
3823 self.assertLess(nsessions, 2 * max_sessions)
3825 def test_mss_clamping(self):
3826 """ TCP MSS clamping """
3827 self.nat44_add_address(self.nat_addr)
3828 flags = self.config_flags.NAT_IS_INSIDE
3829 self.vapi.nat44_interface_add_del_feature(
3830 sw_if_index=self.pg0.sw_if_index,
3831 flags=flags, is_add=1)
3832 self.vapi.nat44_interface_add_del_feature(
3833 sw_if_index=self.pg1.sw_if_index,
3836 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
3837 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
3838 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
3839 flags="S", options=[('MSS', 1400)]))
3841 self.vapi.nat_set_mss_clamping(enable=1, mss_value=1000)
3842 self.pg0.add_stream(p)
3843 self.pg_enable_capture(self.pg_interfaces)
3845 capture = self.pg1.get_capture(1)
3846 # Negotiated MSS value greater than configured - changed
3847 self.verify_mss_value(capture[0], 1000)
3849 self.vapi.nat_set_mss_clamping(enable=0, mss_value=1500)
3850 self.pg0.add_stream(p)
3851 self.pg_enable_capture(self.pg_interfaces)
3853 capture = self.pg1.get_capture(1)
3854 # MSS clamping disabled - negotiated MSS unchanged
3855 self.verify_mss_value(capture[0], 1400)
3857 self.vapi.nat_set_mss_clamping(enable=1, mss_value=1500)
3858 self.pg0.add_stream(p)
3859 self.pg_enable_capture(self.pg_interfaces)
3861 capture = self.pg1.get_capture(1)
3862 # Negotiated MSS value smaller than configured - unchanged
3863 self.verify_mss_value(capture[0], 1400)
3865 @unittest.skipUnless(running_extended_tests, "part of extended tests")
3866 def test_ha_send(self):
3867 """ Send HA session synchronization events (active) """
3868 self.nat44_add_address(self.nat_addr)
3869 flags = self.config_flags.NAT_IS_INSIDE
3870 self.vapi.nat44_interface_add_del_feature(
3871 sw_if_index=self.pg0.sw_if_index,
3872 flags=flags, is_add=1)
3873 self.vapi.nat44_interface_add_del_feature(
3874 sw_if_index=self.pg1.sw_if_index,
3876 self.vapi.nat_ha_set_listener(ip_address=self.pg3.local_ip4,
3879 self.vapi.nat_ha_set_failover(ip_address=self.pg3.remote_ip4,
3880 port=12346, session_refresh_interval=10)
3881 bind_layers(UDP, HANATStateSync, sport=12345)
3884 pkts = self.create_stream_in(self.pg0, self.pg1)
3885 self.pg0.add_stream(pkts)
3886 self.pg_enable_capture(self.pg_interfaces)
3888 capture = self.pg1.get_capture(len(pkts))
3889 self.verify_capture_out(capture)
3890 # active send HA events
3891 self.vapi.nat_ha_flush()
3892 stats = self.statistics.get_counter('/nat44/ha/add-event-send')
3893 self.assertEqual(stats[0][0], 3)
3894 capture = self.pg3.get_capture(1)
3896 self.assert_packet_checksums_valid(p)
3900 hanat = p[HANATStateSync]
3902 self.logger.error(ppp("Invalid packet:", p))
3905 self.assertEqual(ip.src, self.pg3.local_ip4)
3906 self.assertEqual(ip.dst, self.pg3.remote_ip4)
3907 self.assertEqual(udp.sport, 12345)
3908 self.assertEqual(udp.dport, 12346)
3909 self.assertEqual(hanat.version, 1)
3910 self.assertEqual(hanat.thread_index, 0)
3911 self.assertEqual(hanat.count, 3)
3912 seq = hanat.sequence_number
3913 for event in hanat.events:
3914 self.assertEqual(event.event_type, 1)
3915 self.assertEqual(event.in_addr, self.pg0.remote_ip4)
3916 self.assertEqual(event.out_addr, self.nat_addr)
3917 self.assertEqual(event.fib_index, 0)
3919 # ACK received events
3920 ack = (Ether(dst=self.pg3.local_mac, src=self.pg3.remote_mac) /
3921 IP(src=self.pg3.remote_ip4, dst=self.pg3.local_ip4) /
3922 UDP(sport=12346, dport=12345) /
3923 HANATStateSync(sequence_number=seq, flags='ACK'))
3924 self.pg3.add_stream(ack)
3926 stats = self.statistics.get_counter('/nat44/ha/ack-recv')
3927 self.assertEqual(stats[0][0], 1)
3929 # delete one session
3930 self.pg_enable_capture(self.pg_interfaces)
3931 self.vapi.nat44_del_session(address=self.pg0.remote_ip4,
3932 port=self.tcp_port_in,
3933 protocol=IP_PROTOS.tcp,
3934 flags=self.config_flags.NAT_IS_INSIDE)
3935 self.vapi.nat_ha_flush()
3936 stats = self.statistics.get_counter('/nat44/ha/del-event-send')
3937 self.assertEqual(stats[0][0], 1)
3938 capture = self.pg3.get_capture(1)
3941 hanat = p[HANATStateSync]
3943 self.logger.error(ppp("Invalid packet:", p))
3946 self.assertGreater(hanat.sequence_number, seq)
3948 # do not send ACK, active retry send HA event again
3949 self.pg_enable_capture(self.pg_interfaces)
3951 stats = self.statistics.get_counter('/nat44/ha/retry-count')
3952 self.assertEqual(stats[0][0], 3)
3953 stats = self.statistics.get_counter('/nat44/ha/missed-count')
3954 self.assertEqual(stats[0][0], 1)
3955 capture = self.pg3.get_capture(3)
3956 for packet in capture:
3957 self.assertEqual(packet, p)
3959 # session counters refresh
3960 pkts = self.create_stream_out(self.pg1)
3961 self.pg1.add_stream(pkts)
3962 self.pg_enable_capture(self.pg_interfaces)
3964 self.pg0.get_capture(2)
3965 self.vapi.nat_ha_flush()
3966 stats = self.statistics.get_counter('/nat44/ha/refresh-event-send')
3967 self.assertEqual(stats[0][0], 2)
3968 capture = self.pg3.get_capture(1)
3970 self.assert_packet_checksums_valid(p)
3974 hanat = p[HANATStateSync]
3976 self.logger.error(ppp("Invalid packet:", p))
3979 self.assertEqual(ip.src, self.pg3.local_ip4)
3980 self.assertEqual(ip.dst, self.pg3.remote_ip4)
3981 self.assertEqual(udp.sport, 12345)
3982 self.assertEqual(udp.dport, 12346)
3983 self.assertEqual(hanat.version, 1)
3984 self.assertEqual(hanat.count, 2)
3985 seq = hanat.sequence_number
3986 for event in hanat.events:
3987 self.assertEqual(event.event_type, 3)
3988 self.assertEqual(event.out_addr, self.nat_addr)
3989 self.assertEqual(event.fib_index, 0)
3990 self.assertEqual(event.total_pkts, 2)
3991 self.assertGreater(event.total_bytes, 0)
3993 ack = (Ether(dst=self.pg3.local_mac, src=self.pg3.remote_mac) /
3994 IP(src=self.pg3.remote_ip4, dst=self.pg3.local_ip4) /
3995 UDP(sport=12346, dport=12345) /
3996 HANATStateSync(sequence_number=seq, flags='ACK'))
3997 self.pg3.add_stream(ack)
3999 stats = self.statistics.get_counter('/nat44/ha/ack-recv')
4000 self.assertEqual(stats[0][0], 2)
4002 def test_ha_recv(self):
4003 """ Receive HA session synchronization events (passive) """
4004 self.nat44_add_address(self.nat_addr)
4005 flags = self.config_flags.NAT_IS_INSIDE
4006 self.vapi.nat44_interface_add_del_feature(
4007 sw_if_index=self.pg0.sw_if_index,
4008 flags=flags, is_add=1)
4009 self.vapi.nat44_interface_add_del_feature(
4010 sw_if_index=self.pg1.sw_if_index,
4012 self.vapi.nat_ha_set_listener(ip_address=self.pg3.local_ip4,
4015 bind_layers(UDP, HANATStateSync, sport=12345)
4017 self.tcp_port_out = random.randint(1025, 65535)
4018 self.udp_port_out = random.randint(1025, 65535)
4020 # send HA session add events to failover/passive
4021 p = (Ether(dst=self.pg3.local_mac, src=self.pg3.remote_mac) /
4022 IP(src=self.pg3.remote_ip4, dst=self.pg3.local_ip4) /
4023 UDP(sport=12346, dport=12345) /
4024 HANATStateSync(sequence_number=1, events=[
4025 Event(event_type='add', protocol='tcp',
4026 in_addr=self.pg0.remote_ip4, out_addr=self.nat_addr,
4027 in_port=self.tcp_port_in, out_port=self.tcp_port_out,
4028 eh_addr=self.pg1.remote_ip4,
4029 ehn_addr=self.pg1.remote_ip4,
4030 eh_port=self.tcp_external_port,
4031 ehn_port=self.tcp_external_port, fib_index=0),
4032 Event(event_type='add', protocol='udp',
4033 in_addr=self.pg0.remote_ip4, out_addr=self.nat_addr,
4034 in_port=self.udp_port_in, out_port=self.udp_port_out,
4035 eh_addr=self.pg1.remote_ip4,
4036 ehn_addr=self.pg1.remote_ip4,
4037 eh_port=self.udp_external_port,
4038 ehn_port=self.udp_external_port, fib_index=0)]))
4040 self.pg3.add_stream(p)
4041 self.pg_enable_capture(self.pg_interfaces)
4044 capture = self.pg3.get_capture(1)
4047 hanat = p[HANATStateSync]
4049 self.logger.error(ppp("Invalid packet:", p))
4052 self.assertEqual(hanat.sequence_number, 1)
4053 self.assertEqual(hanat.flags, 'ACK')
4054 self.assertEqual(hanat.version, 1)
4055 self.assertEqual(hanat.thread_index, 0)
4056 stats = self.statistics.get_counter('/nat44/ha/ack-send')
4057 self.assertEqual(stats[0][0], 1)
4058 stats = self.statistics.get_counter('/nat44/ha/add-event-recv')
4059 self.assertEqual(stats[0][0], 2)
4060 users = self.statistics.get_counter('/nat44/total-users')
4061 self.assertEqual(users[0][0], 1)
4062 sessions = self.statistics.get_counter('/nat44/total-sessions')
4063 self.assertEqual(sessions[0][0], 2)
4064 users = self.vapi.nat44_user_dump()
4065 self.assertEqual(len(users), 1)
4066 self.assertEqual(str(users[0].ip_address),
4067 self.pg0.remote_ip4)
4068 # there should be 2 sessions created by HA
4069 sessions = self.vapi.nat44_user_session_dump(users[0].ip_address,
4071 self.assertEqual(len(sessions), 2)
4072 for session in sessions:
4073 self.assertEqual(str(session.inside_ip_address),
4074 self.pg0.remote_ip4)
4075 self.assertEqual(str(session.outside_ip_address),
4077 self.assertIn(session.inside_port,
4078 [self.tcp_port_in, self.udp_port_in])
4079 self.assertIn(session.outside_port,
4080 [self.tcp_port_out, self.udp_port_out])
4081 self.assertIn(session.protocol, [IP_PROTOS.tcp, IP_PROTOS.udp])
4083 # send HA session delete event to failover/passive
4084 p = (Ether(dst=self.pg3.local_mac, src=self.pg3.remote_mac) /
4085 IP(src=self.pg3.remote_ip4, dst=self.pg3.local_ip4) /
4086 UDP(sport=12346, dport=12345) /
4087 HANATStateSync(sequence_number=2, events=[
4088 Event(event_type='del', protocol='udp',
4089 in_addr=self.pg0.remote_ip4, out_addr=self.nat_addr,
4090 in_port=self.udp_port_in, out_port=self.udp_port_out,
4091 eh_addr=self.pg1.remote_ip4,
4092 ehn_addr=self.pg1.remote_ip4,
4093 eh_port=self.udp_external_port,
4094 ehn_port=self.udp_external_port, fib_index=0)]))
4096 self.pg3.add_stream(p)
4097 self.pg_enable_capture(self.pg_interfaces)
4100 capture = self.pg3.get_capture(1)
4103 hanat = p[HANATStateSync]
4105 self.logger.error(ppp("Invalid packet:", p))
4108 self.assertEqual(hanat.sequence_number, 2)
4109 self.assertEqual(hanat.flags, 'ACK')
4110 self.assertEqual(hanat.version, 1)
4111 users = self.vapi.nat44_user_dump()
4112 self.assertEqual(len(users), 1)
4113 self.assertEqual(str(users[0].ip_address),
4114 self.pg0.remote_ip4)
4115 # now we should have only 1 session, 1 deleted by HA
4116 sessions = self.vapi.nat44_user_session_dump(users[0].ip_address,
4118 self.assertEqual(len(sessions), 1)
4119 stats = self.statistics.get_counter('/nat44/ha/del-event-recv')
4120 self.assertEqual(stats[0][0], 1)
4122 stats = self.statistics.get_err_counter('/err/nat-ha/pkts-processed')
4123 self.assertEqual(stats, 2)
4125 # send HA session refresh event to failover/passive
4126 p = (Ether(dst=self.pg3.local_mac, src=self.pg3.remote_mac) /
4127 IP(src=self.pg3.remote_ip4, dst=self.pg3.local_ip4) /
4128 UDP(sport=12346, dport=12345) /
4129 HANATStateSync(sequence_number=3, events=[
4130 Event(event_type='refresh', protocol='tcp',
4131 in_addr=self.pg0.remote_ip4, out_addr=self.nat_addr,
4132 in_port=self.tcp_port_in, out_port=self.tcp_port_out,
4133 eh_addr=self.pg1.remote_ip4,
4134 ehn_addr=self.pg1.remote_ip4,
4135 eh_port=self.tcp_external_port,
4136 ehn_port=self.tcp_external_port, fib_index=0,
4137 total_bytes=1024, total_pkts=2)]))
4138 self.pg3.add_stream(p)
4139 self.pg_enable_capture(self.pg_interfaces)
4142 capture = self.pg3.get_capture(1)
4145 hanat = p[HANATStateSync]
4147 self.logger.error(ppp("Invalid packet:", p))
4150 self.assertEqual(hanat.sequence_number, 3)
4151 self.assertEqual(hanat.flags, 'ACK')
4152 self.assertEqual(hanat.version, 1)
4153 users = self.vapi.nat44_user_dump()
4154 self.assertEqual(len(users), 1)
4155 self.assertEqual(str(users[0].ip_address),
4156 self.pg0.remote_ip4)
4157 sessions = self.vapi.nat44_user_session_dump(users[0].ip_address,
4159 self.assertEqual(len(sessions), 1)
4160 session = sessions[0]
4161 self.assertEqual(session.total_bytes, 1024)
4162 self.assertEqual(session.total_pkts, 2)
4163 stats = self.statistics.get_counter('/nat44/ha/refresh-event-recv')
4164 self.assertEqual(stats[0][0], 1)
4166 stats = self.statistics.get_err_counter('/err/nat-ha/pkts-processed')
4167 self.assertEqual(stats, 3)
4169 # send packet to test session created by HA
4170 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
4171 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
4172 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out))
4173 self.pg1.add_stream(p)
4174 self.pg_enable_capture(self.pg_interfaces)
4176 capture = self.pg0.get_capture(1)
4182 self.logger.error(ppp("Invalid packet:", p))
4185 self.assertEqual(ip.src, self.pg1.remote_ip4)
4186 self.assertEqual(ip.dst, self.pg0.remote_ip4)
4187 self.assertEqual(tcp.sport, self.tcp_external_port)
4188 self.assertEqual(tcp.dport, self.tcp_port_in)
4191 super(TestNAT44, self).tearDown()
4193 self.vapi.cli("clear logging")
4195 def show_commands_at_teardown(self):
4196 self.logger.info(self.vapi.cli("show nat44 addresses"))
4197 self.logger.info(self.vapi.cli("show nat44 interfaces"))
4198 self.logger.info(self.vapi.cli("show nat44 static mappings"))
4199 self.logger.info(self.vapi.cli("show nat44 interface address"))
4200 self.logger.info(self.vapi.cli("show nat44 sessions detail"))
4201 self.logger.info(self.vapi.cli("show nat44 hash tables detail"))
4202 self.logger.info(self.vapi.cli("show nat timeouts"))
4204 self.vapi.cli("show nat addr-port-assignment-alg"))
4205 self.logger.info(self.vapi.cli("show nat ha"))
4208 class TestNAT44EndpointDependent2(MethodHolder):
4209 """ Endpoint-Dependent mapping and filtering test cases """
4212 def setUpConstants(cls):
4213 super(TestNAT44EndpointDependent2, cls).setUpConstants()
4214 cls.vpp_cmdline.extend(["nat", "{", "endpoint-dependent", "}"])
4217 def tearDownClass(cls):
4218 super(TestNAT44EndpointDependent2, cls).tearDownClass()
4221 super(TestNAT44EndpointDependent2, self).tearDown()
4224 def create_and_add_ip4_table(cls, i, table_id):
4225 cls.vapi.ip_table_add_del(is_add=1, table={'table_id': table_id})
4226 i.set_table_ip4(table_id)
4229 def setUpClass(cls):
4230 super(TestNAT44EndpointDependent2, cls).setUpClass()
4232 cls.create_pg_interfaces(range(3))
4233 cls.interfaces = list(cls.pg_interfaces)
4235 cls.create_and_add_ip4_table(cls.pg1, 10)
4237 for i in cls.interfaces:
4242 i.generate_remote_hosts(1)
4243 i.configure_ipv4_neighbors()
4246 super(TestNAT44EndpointDependent2, self).setUp()
4248 nat_config = self.vapi.nat_show_config()
4249 self.assertEqual(1, nat_config.endpoint_dependent)
4251 def nat_add_inside_interface(self, i):
4252 self.vapi.nat44_interface_add_del_feature(
4253 flags=self.config_flags.NAT_IS_INSIDE,
4254 sw_if_index=i.sw_if_index, is_add=1)
4256 def nat_add_outside_interface(self, i):
4257 self.vapi.nat44_interface_add_del_feature(
4258 flags=self.config_flags.NAT_IS_OUTSIDE,
4259 sw_if_index=i.sw_if_index, is_add=1)
4261 def nat_add_interface_address(self, i):
4262 self.nat_addr = i.local_ip4
4263 self.vapi.nat44_add_del_interface_addr(
4264 sw_if_index=i.sw_if_index, is_add=1)
4266 def nat_add_address(self, address, vrf_id=0xFFFFFFFF):
4267 self.nat_addr = address
4268 self.nat44_add_address(address, vrf_id=vrf_id)
4270 def cli(self, command):
4271 result = self.vapi.cli(command)
4272 self.logger.info(result)
4275 def show_configuration(self):
4276 self.cli("show interface")
4277 self.cli("show interface address")
4278 self.cli("show nat44 addresses")
4279 self.cli("show nat44 interfaces")
4281 def create_tcp_stream(self, in_if, out_if, count):
4283 Create tcp packet stream
4285 :param in_if: Inside interface
4286 :param out_if: Outside interface
4287 :param count: count of packets to generate
4292 for i in range(count):
4293 p = (Ether(dst=in_if.local_mac, src=in_if.remote_mac) /
4294 IP(src=in_if.remote_ip4, dst=out_if.remote_ip4, ttl=64) /
4295 TCP(sport=port + i, dport=20))
4300 def test_session_limit_per_vrf(self):
4303 inside_vrf10 = self.pg1
4308 # 2 interfaces pg0, pg1 (vrf10, limit 1 tcp session)
4309 # non existing vrf_id makes process core dump
4310 self.vapi.nat44_set_session_limit(session_limit=limit, vrf_id=10)
4312 self.nat_add_inside_interface(inside)
4313 self.nat_add_inside_interface(inside_vrf10)
4314 self.nat_add_outside_interface(outside)
4317 self.nat_add_interface_address(outside)
4319 # BUG: causing core dump - when bad vrf_id is specified
4320 # self.nat44_add_address(outside.local_ip4, vrf_id=20)
4322 self.show_configuration()
4324 stream = self.create_tcp_stream(inside_vrf10, outside, limit * 2)
4325 inside_vrf10.add_stream(stream)
4327 self.pg_enable_capture(self.pg_interfaces)
4330 capture = outside.get_capture(limit)
4332 stream = self.create_tcp_stream(inside, outside, limit * 2)
4333 inside.add_stream(stream)
4335 self.pg_enable_capture(self.pg_interfaces)
4338 capture = outside.get_capture(len(stream))
4341 class TestNAT44EndpointDependent(MethodHolder):
4342 """ Endpoint-Dependent mapping and filtering test cases """
4345 def setUpConstants(cls):
4346 super(TestNAT44EndpointDependent, cls).setUpConstants()
4347 cls.vpp_cmdline.extend(["nat", "{", "endpoint-dependent", "}"])
4350 def setUpClass(cls):
4351 super(TestNAT44EndpointDependent, cls).setUpClass()
4352 cls.vapi.cli("set log class nat level debug")
4354 cls.tcp_port_in = 6303
4355 cls.tcp_port_out = 6303
4356 cls.udp_port_in = 6304
4357 cls.udp_port_out = 6304
4358 cls.icmp_id_in = 6305
4359 cls.icmp_id_out = 6305
4360 cls.nat_addr = '10.0.0.3'
4361 cls.ipfix_src_port = 4739
4362 cls.ipfix_domain_id = 1
4363 cls.tcp_external_port = 80
4365 cls.create_pg_interfaces(range(9))
4366 cls.interfaces = list(cls.pg_interfaces[0:3])
4368 for i in cls.interfaces:
4373 cls.pg0.generate_remote_hosts(3)
4374 cls.pg0.configure_ipv4_neighbors()
4378 cls.pg4.generate_remote_hosts(2)
4379 cls.pg4.config_ip4()
4380 cls.vapi.sw_interface_add_del_address(
4381 sw_if_index=cls.pg4.sw_if_index,
4382 prefix="10.0.0.1/24")
4385 cls.pg4.resolve_arp()
4386 cls.pg4._remote_hosts[1]._ip4 = cls.pg4._remote_hosts[0]._ip4
4387 cls.pg4.resolve_arp()
4389 zero_ip4 = socket.inet_pton(socket.AF_INET, "0.0.0.0")
4390 cls.vapi.ip_table_add_del(is_add=1, table={'table_id': 1})
4392 cls.pg5._local_ip4 = "10.1.1.1"
4393 cls.pg5._remote_hosts[0]._ip4 = "10.1.1.2"
4394 cls.pg5.set_table_ip4(1)
4395 cls.pg5.config_ip4()
4397 r1 = VppIpRoute(cls, cls.pg5.remote_ip4, 32,
4398 [VppRoutePath("0.0.0.0",
4399 cls.pg5.sw_if_index)],
4404 cls.pg6._local_ip4 = "10.1.2.1"
4405 cls.pg6._remote_hosts[0]._ip4 = "10.1.2.2"
4406 cls.pg6.set_table_ip4(1)
4407 cls.pg6.config_ip4()
4410 r2 = VppIpRoute(cls, cls.pg6.remote_ip4, 32,
4411 [VppRoutePath("0.0.0.0",
4412 cls.pg6.sw_if_index)],
4415 r3 = VppIpRoute(cls, cls.pg6.remote_ip4, 16,
4416 [VppRoutePath("0.0.0.0",
4421 r4 = VppIpRoute(cls, "0.0.0.0", 0,
4422 [VppRoutePath("0.0.0.0", 0xffffffff,
4426 r5 = VppIpRoute(cls, "0.0.0.0", 0,
4427 [VppRoutePath(cls.pg1.local_ip4,
4428 cls.pg1.sw_if_index)],
4435 cls.pg5.resolve_arp()
4436 cls.pg6.resolve_arp()
4439 cls.pg7.config_ip4()
4440 cls.pg7.resolve_arp()
4441 cls.pg7.generate_remote_hosts(3)
4442 cls.pg7.configure_ipv4_neighbors()
4445 cls.pg8.config_ip4()
4446 cls.pg8.resolve_arp()
4449 super(TestNAT44EndpointDependent, self).setUp()
4450 self.vapi.nat_set_timeouts(
4451 udp=300, tcp_established=7440, tcp_transitory=240, icmp=60)
4454 def tearDownClass(cls):
4455 super(TestNAT44EndpointDependent, cls).tearDownClass()
4457 def test_frag_in_order(self):
4458 """ NAT44 translate fragments arriving in order """
4459 self.nat44_add_address(self.nat_addr)
4460 flags = self.config_flags.NAT_IS_INSIDE
4461 self.vapi.nat44_interface_add_del_feature(
4462 sw_if_index=self.pg0.sw_if_index,
4463 flags=flags, is_add=1)
4464 self.vapi.nat44_interface_add_del_feature(
4465 sw_if_index=self.pg1.sw_if_index,
4467 self.frag_in_order(proto=IP_PROTOS.tcp, ignore_port=True)
4468 self.frag_in_order(proto=IP_PROTOS.udp, ignore_port=True)
4469 self.frag_in_order(proto=IP_PROTOS.icmp, ignore_port=True)
4471 def test_frag_in_order_dont_translate(self):
4472 """ NAT44 don't translate fragments arriving in order """
4473 flags = self.config_flags.NAT_IS_INSIDE
4474 self.vapi.nat44_interface_add_del_feature(
4475 sw_if_index=self.pg0.sw_if_index,
4476 flags=flags, is_add=1)
4477 self.vapi.nat44_interface_add_del_feature(
4478 sw_if_index=self.pg1.sw_if_index,
4480 self.vapi.nat44_forwarding_enable_disable(enable=True)
4481 self.frag_in_order(proto=IP_PROTOS.tcp, dont_translate=True)
4483 def test_frag_out_of_order(self):
4484 """ NAT44 translate fragments arriving out of order """
4485 self.nat44_add_address(self.nat_addr)
4486 flags = self.config_flags.NAT_IS_INSIDE
4487 self.vapi.nat44_interface_add_del_feature(
4488 sw_if_index=self.pg0.sw_if_index,
4489 flags=flags, is_add=1)
4490 self.vapi.nat44_interface_add_del_feature(
4491 sw_if_index=self.pg1.sw_if_index,
4493 self.frag_out_of_order(proto=IP_PROTOS.tcp, ignore_port=True)
4494 self.frag_out_of_order(proto=IP_PROTOS.udp, ignore_port=True)
4495 self.frag_out_of_order(proto=IP_PROTOS.icmp, ignore_port=True)
4497 def test_frag_out_of_order_dont_translate(self):
4498 """ NAT44 don't translate fragments arriving out of order """
4499 flags = self.config_flags.NAT_IS_INSIDE
4500 self.vapi.nat44_interface_add_del_feature(
4501 sw_if_index=self.pg0.sw_if_index,
4502 flags=flags, is_add=1)
4503 self.vapi.nat44_interface_add_del_feature(
4504 sw_if_index=self.pg1.sw_if_index,
4506 self.vapi.nat44_forwarding_enable_disable(enable=True)
4507 self.frag_out_of_order(proto=IP_PROTOS.tcp, dont_translate=True)
4509 def test_frag_in_order_in_plus_out(self):
4510 """ in+out interface fragments in order """
4511 flags = self.config_flags.NAT_IS_INSIDE
4512 self.vapi.nat44_interface_add_del_feature(
4513 sw_if_index=self.pg0.sw_if_index,
4515 self.vapi.nat44_interface_add_del_feature(
4516 sw_if_index=self.pg0.sw_if_index,
4517 flags=flags, is_add=1)
4518 self.vapi.nat44_interface_add_del_feature(
4519 sw_if_index=self.pg1.sw_if_index,
4521 self.vapi.nat44_interface_add_del_feature(
4522 sw_if_index=self.pg1.sw_if_index,
4523 flags=flags, is_add=1)
4525 self.server = self.pg1.remote_hosts[0]
4527 self.server_in_addr = self.server.ip4
4528 self.server_out_addr = '11.11.11.11'
4529 self.server_in_port = random.randint(1025, 65535)
4530 self.server_out_port = random.randint(1025, 65535)
4532 self.nat44_add_address(self.server_out_addr)
4534 # add static mappings for server
4535 self.nat44_add_static_mapping(self.server_in_addr,
4536 self.server_out_addr,
4537 self.server_in_port,
4538 self.server_out_port,
4539 proto=IP_PROTOS.tcp)
4540 self.nat44_add_static_mapping(self.server_in_addr,
4541 self.server_out_addr,
4542 self.server_in_port,
4543 self.server_out_port,
4544 proto=IP_PROTOS.udp)
4545 self.nat44_add_static_mapping(self.server_in_addr,
4546 self.server_out_addr,
4547 proto=IP_PROTOS.icmp)
4549 self.frag_in_order_in_plus_out(proto=IP_PROTOS.tcp)
4550 self.frag_in_order_in_plus_out(proto=IP_PROTOS.udp)
4551 self.frag_in_order_in_plus_out(proto=IP_PROTOS.icmp)
4553 def test_frag_out_of_order_in_plus_out(self):
4554 """ in+out interface fragments out of order """
4555 flags = self.config_flags.NAT_IS_INSIDE
4556 self.vapi.nat44_interface_add_del_feature(
4557 sw_if_index=self.pg0.sw_if_index,
4559 self.vapi.nat44_interface_add_del_feature(
4560 sw_if_index=self.pg0.sw_if_index,
4561 flags=flags, is_add=1)
4562 self.vapi.nat44_interface_add_del_feature(
4563 sw_if_index=self.pg1.sw_if_index,
4565 self.vapi.nat44_interface_add_del_feature(
4566 sw_if_index=self.pg1.sw_if_index,
4567 flags=flags, is_add=1)
4569 self.server = self.pg1.remote_hosts[0]
4571 self.server_in_addr = self.server.ip4
4572 self.server_out_addr = '11.11.11.11'
4573 self.server_in_port = random.randint(1025, 65535)
4574 self.server_out_port = random.randint(1025, 65535)
4576 self.nat44_add_address(self.server_out_addr)
4578 # add static mappings for server
4579 self.nat44_add_static_mapping(self.server_in_addr,
4580 self.server_out_addr,
4581 self.server_in_port,
4582 self.server_out_port,
4583 proto=IP_PROTOS.tcp)
4584 self.nat44_add_static_mapping(self.server_in_addr,
4585 self.server_out_addr,
4586 self.server_in_port,
4587 self.server_out_port,
4588 proto=IP_PROTOS.udp)
4589 self.nat44_add_static_mapping(self.server_in_addr,
4590 self.server_out_addr,
4591 proto=IP_PROTOS.icmp)
4593 self.frag_out_of_order_in_plus_out(proto=IP_PROTOS.tcp)
4594 self.frag_out_of_order_in_plus_out(proto=IP_PROTOS.udp)
4595 self.frag_out_of_order_in_plus_out(proto=IP_PROTOS.icmp)
4597 def test_reass_hairpinning(self):
4598 """ NAT44 fragments hairpinning """
4599 self.server = self.pg0.remote_hosts[1]
4600 self.host_in_port = random.randint(1025, 65535)
4601 self.server_in_port = random.randint(1025, 65535)
4602 self.server_out_port = random.randint(1025, 65535)
4604 self.nat44_add_address(self.nat_addr)
4605 flags = self.config_flags.NAT_IS_INSIDE
4606 self.vapi.nat44_interface_add_del_feature(
4607 sw_if_index=self.pg0.sw_if_index,
4608 flags=flags, is_add=1)
4609 self.vapi.nat44_interface_add_del_feature(
4610 sw_if_index=self.pg1.sw_if_index,
4612 # add static mapping for server
4613 self.nat44_add_static_mapping(self.server.ip4, self.nat_addr,
4614 self.server_in_port,
4615 self.server_out_port,
4616 proto=IP_PROTOS.tcp)
4617 self.nat44_add_static_mapping(self.server.ip4, self.nat_addr,
4618 self.server_in_port,
4619 self.server_out_port,
4620 proto=IP_PROTOS.udp)
4621 self.nat44_add_static_mapping(self.server.ip4, self.nat_addr)
4623 self.reass_hairpinning(proto=IP_PROTOS.tcp, ignore_port=True)
4624 self.reass_hairpinning(proto=IP_PROTOS.udp, ignore_port=True)
4625 self.reass_hairpinning(proto=IP_PROTOS.icmp, ignore_port=True)
4627 def test_clear_sessions(self):
4628 """ NAT44 ED session clearing test """
4630 self.nat44_add_address(self.nat_addr)
4631 flags = self.config_flags.NAT_IS_INSIDE
4632 self.vapi.nat44_interface_add_del_feature(
4633 sw_if_index=self.pg0.sw_if_index,
4634 flags=flags, is_add=1)
4635 self.vapi.nat44_interface_add_del_feature(
4636 sw_if_index=self.pg1.sw_if_index,
4639 nat_config = self.vapi.nat_show_config()
4640 self.assertEqual(1, nat_config.endpoint_dependent)
4642 pkts = self.create_stream_in(self.pg0, self.pg1)
4643 self.pg0.add_stream(pkts)
4644 self.pg_enable_capture(self.pg_interfaces)
4646 capture = self.pg1.get_capture(len(pkts))
4647 self.verify_capture_out(capture, ignore_port=True)
4649 sessions = self.statistics.get_counter('/nat44/total-sessions')
4650 self.assertTrue(sessions[0][0] > 0)
4651 self.logger.info("sessions before clearing: %s" % sessions[0][0])
4653 # just for testing purposes
4654 self.logger.info(self.vapi.cli("show nat44 summary"))
4656 self.vapi.cli("clear nat44 sessions")
4658 self.logger.info(self.vapi.cli("show nat44 summary"))
4660 sessions = self.statistics.get_counter('/nat44/total-sessions')
4661 self.assertEqual(sessions[0][0], 0)
4662 self.logger.info("sessions after clearing: %s" % sessions[0][0])
4664 def test_dynamic(self):
4665 """ NAT44 dynamic translation test """
4667 self.nat44_add_address(self.nat_addr)
4668 flags = self.config_flags.NAT_IS_INSIDE
4669 self.vapi.nat44_interface_add_del_feature(
4670 sw_if_index=self.pg0.sw_if_index,
4671 flags=flags, is_add=1)
4672 self.vapi.nat44_interface_add_del_feature(
4673 sw_if_index=self.pg1.sw_if_index,
4676 nat_config = self.vapi.nat_show_config()
4677 self.assertEqual(1, nat_config.endpoint_dependent)
4680 tcpn = self.statistics.get_err_counter(
4681 '/err/nat44-ed-in2out-slowpath/TCP packets')
4682 udpn = self.statistics.get_err_counter(
4683 '/err/nat44-ed-in2out-slowpath/UDP packets')
4684 icmpn = self.statistics.get_err_counter(
4685 '/err/nat44-ed-in2out-slowpath/ICMP packets')
4686 totaln = self.statistics.get_err_counter(
4687 '/err/nat44-ed-in2out-slowpath/good in2out packets processed')
4689 pkts = self.create_stream_in(self.pg0, self.pg1)
4690 self.pg0.add_stream(pkts)
4691 self.pg_enable_capture(self.pg_interfaces)
4693 capture = self.pg1.get_capture(len(pkts))
4694 self.verify_capture_out(capture, ignore_port=True)
4696 err = self.statistics.get_err_counter(
4697 '/err/nat44-ed-in2out-slowpath/TCP packets')
4698 self.assertEqual(err - tcpn, 2)
4699 err = self.statistics.get_err_counter(
4700 '/err/nat44-ed-in2out-slowpath/UDP packets')
4701 self.assertEqual(err - udpn, 1)
4702 err = self.statistics.get_err_counter(
4703 '/err/nat44-ed-in2out-slowpath/ICMP packets')
4704 self.assertEqual(err - icmpn, 1)
4705 err = self.statistics.get_err_counter(
4706 '/err/nat44-ed-in2out-slowpath/good in2out packets processed')
4707 self.assertEqual(err - totaln, 4)
4710 tcpn = self.statistics.get_err_counter(
4711 '/err/nat44-ed-out2in/TCP packets')
4712 udpn = self.statistics.get_err_counter(
4713 '/err/nat44-ed-out2in/UDP packets')
4714 icmpn = self.statistics.get_err_counter(
4715 '/err/nat44-ed-out2in-slowpath/ICMP packets')
4716 totaln = self.statistics.get_err_counter(
4717 '/err/nat44-ed-out2in/good out2in packets processed')
4719 pkts = self.create_stream_out(self.pg1)
4720 self.pg1.add_stream(pkts)
4721 self.pg_enable_capture(self.pg_interfaces)
4723 capture = self.pg0.get_capture(len(pkts))
4724 self.verify_capture_in(capture, self.pg0)
4726 err = self.statistics.get_err_counter(
4727 '/err/nat44-ed-out2in/TCP packets')
4728 self.assertEqual(err - tcpn, 2)
4729 err = self.statistics.get_err_counter(
4730 '/err/nat44-ed-out2in/UDP packets')
4731 self.assertEqual(err - udpn, 1)
4732 err = self.statistics.get_err_counter(
4733 '/err/nat44-ed-out2in-slowpath/ICMP packets')
4734 self.assertEqual(err - icmpn, 1)
4735 err = self.statistics.get_err_counter(
4736 '/err/nat44-ed-out2in/good out2in packets processed')
4737 self.assertEqual(err - totaln, 3)
4739 sessions = self.statistics.get_counter('/nat44/total-sessions')
4740 self.assertEqual(sessions[0][0], 3)
4742 def test_dynamic_out_of_ports(self):
4743 """ NAT44 dynamic translation test: out of ports """
4745 flags = self.config_flags.NAT_IS_INSIDE
4746 self.vapi.nat44_interface_add_del_feature(
4747 sw_if_index=self.pg0.sw_if_index,
4748 flags=flags, is_add=1)
4749 self.vapi.nat44_interface_add_del_feature(
4750 sw_if_index=self.pg1.sw_if_index,
4753 nat_config = self.vapi.nat_show_config()
4754 self.assertEqual(1, nat_config.endpoint_dependent)
4756 # in2out and no NAT addresses added
4757 err_old = self.statistics.get_err_counter(
4758 '/err/nat44-ed-in2out-slowpath/out of ports')
4760 pkts = self.create_stream_in(self.pg0, self.pg1)
4761 self.pg0.add_stream(pkts)
4762 self.pg_enable_capture(self.pg_interfaces)
4764 self.pg1.get_capture(0, timeout=1)
4766 err_new = self.statistics.get_err_counter(
4767 '/err/nat44-ed-in2out-slowpath/out of ports')
4769 self.assertEqual(err_new - err_old, len(pkts))
4771 # in2out after NAT addresses added
4772 self.nat44_add_address(self.nat_addr)
4774 err_old = self.statistics.get_err_counter(
4775 '/err/nat44-ed-in2out-slowpath/out of ports')
4777 pkts = self.create_stream_in(self.pg0, self.pg1)
4778 self.pg0.add_stream(pkts)
4779 self.pg_enable_capture(self.pg_interfaces)
4781 capture = self.pg1.get_capture(len(pkts))
4782 self.verify_capture_out(capture, ignore_port=True)
4784 err_new = self.statistics.get_err_counter(
4785 '/err/nat44-ed-in2out-slowpath/out of ports')
4787 self.assertEqual(err_new, err_old)
4789 def test_dynamic_output_feature_vrf(self):
4790 """ NAT44 dynamic translation test: output-feature, VRF"""
4792 # other then default (0)
4795 self.nat44_add_address(self.nat_addr)
4796 flags = self.config_flags.NAT_IS_INSIDE
4797 self.vapi.nat44_interface_add_del_output_feature(
4798 sw_if_index=self.pg7.sw_if_index,
4799 flags=flags, is_add=1)
4800 self.vapi.nat44_interface_add_del_output_feature(
4801 sw_if_index=self.pg8.sw_if_index,
4805 self.vapi.ip_table_add_del(is_add=1,
4806 table={'table_id': new_vrf_id})
4808 self.pg7.unconfig_ip4()
4809 self.pg7.set_table_ip4(new_vrf_id)
4810 self.pg7.config_ip4()
4811 self.pg7.resolve_arp()
4813 self.pg8.unconfig_ip4()
4814 self.pg8.set_table_ip4(new_vrf_id)
4815 self.pg8.config_ip4()
4816 self.pg8.resolve_arp()
4818 nat_config = self.vapi.nat_show_config()
4819 self.assertEqual(1, nat_config.endpoint_dependent)
4822 tcpn = self.statistics.get_err_counter(
4823 '/err/nat44-ed-in2out-slowpath/TCP packets')
4824 udpn = self.statistics.get_err_counter(
4825 '/err/nat44-ed-in2out-slowpath/UDP packets')
4826 icmpn = self.statistics.get_err_counter(
4827 '/err/nat44-ed-in2out-slowpath/ICMP packets')
4828 totaln = self.statistics.get_err_counter(
4829 '/err/nat44-ed-in2out-slowpath/good in2out packets processed')
4831 pkts = self.create_stream_in(self.pg7, self.pg8)
4832 self.pg7.add_stream(pkts)
4833 self.pg_enable_capture(self.pg_interfaces)
4835 capture = self.pg8.get_capture(len(pkts))
4836 self.verify_capture_out(capture, ignore_port=True)
4838 err = self.statistics.get_err_counter(
4839 '/err/nat44-ed-in2out-slowpath/TCP packets')
4840 self.assertEqual(err - tcpn, 2)
4841 err = self.statistics.get_err_counter(
4842 '/err/nat44-ed-in2out-slowpath/UDP packets')
4843 self.assertEqual(err - udpn, 1)
4844 err = self.statistics.get_err_counter(
4845 '/err/nat44-ed-in2out-slowpath/ICMP packets')
4846 self.assertEqual(err - icmpn, 1)
4847 err = self.statistics.get_err_counter(
4848 '/err/nat44-ed-in2out-slowpath/good in2out packets processed')
4849 self.assertEqual(err - totaln, 4)
4852 tcpn = self.statistics.get_err_counter(
4853 '/err/nat44-ed-out2in/TCP packets')
4854 udpn = self.statistics.get_err_counter(
4855 '/err/nat44-ed-out2in/UDP packets')
4856 icmpn = self.statistics.get_err_counter(
4857 '/err/nat44-ed-out2in-slowpath/ICMP packets')
4858 totaln = self.statistics.get_err_counter(
4859 '/err/nat44-ed-out2in/good out2in packets processed')
4861 pkts = self.create_stream_out(self.pg8)
4862 self.pg8.add_stream(pkts)
4863 self.pg_enable_capture(self.pg_interfaces)
4865 capture = self.pg7.get_capture(len(pkts))
4866 self.verify_capture_in(capture, self.pg7)
4868 err = self.statistics.get_err_counter(
4869 '/err/nat44-ed-out2in/TCP packets')
4870 self.assertEqual(err - tcpn, 2)
4871 err = self.statistics.get_err_counter(
4872 '/err/nat44-ed-out2in/UDP packets')
4873 self.assertEqual(err - udpn, 1)
4874 err = self.statistics.get_err_counter(
4875 '/err/nat44-ed-out2in-slowpath/ICMP packets')
4876 self.assertEqual(err - icmpn, 1)
4877 err = self.statistics.get_err_counter(
4878 '/err/nat44-ed-out2in/good out2in packets processed')
4879 self.assertEqual(err - totaln, 3)
4881 sessions = self.statistics.get_counter('/nat44/total-sessions')
4882 self.assertEqual(sessions[0][0], 3)
4885 self.pg7.unconfig_ip4()
4886 self.pg7.set_table_ip4(1)
4887 self.pg7.config_ip4()
4888 self.pg7.resolve_arp()
4890 self.pg8.unconfig_ip4()
4891 self.pg8.set_table_ip4(1)
4892 self.pg8.config_ip4()
4893 self.pg8.resolve_arp()
4895 self.vapi.ip_table_add_del(is_add=0,
4896 table={'table_id': new_vrf_id})
4898 def test_forwarding(self):
4899 """ NAT44 forwarding test """
4901 flags = self.config_flags.NAT_IS_INSIDE
4902 self.vapi.nat44_interface_add_del_feature(
4903 sw_if_index=self.pg0.sw_if_index,
4904 flags=flags, is_add=1)
4905 self.vapi.nat44_interface_add_del_feature(
4906 sw_if_index=self.pg1.sw_if_index,
4908 self.vapi.nat44_forwarding_enable_disable(enable=1)
4910 real_ip = self.pg0.remote_ip4
4911 alias_ip = self.nat_addr
4912 flags = self.config_flags.NAT_IS_ADDR_ONLY
4913 self.vapi.nat44_add_del_static_mapping(is_add=1,
4914 local_ip_address=real_ip,
4915 external_ip_address=alias_ip,
4916 external_sw_if_index=0xFFFFFFFF,
4920 # in2out - static mapping match
4922 pkts = self.create_stream_out(self.pg1)
4923 self.pg1.add_stream(pkts)
4924 self.pg_enable_capture(self.pg_interfaces)
4926 capture = self.pg0.get_capture(len(pkts))
4927 self.verify_capture_in(capture, self.pg0)
4929 pkts = self.create_stream_in(self.pg0, self.pg1)
4930 self.pg0.add_stream(pkts)
4931 self.pg_enable_capture(self.pg_interfaces)
4933 capture = self.pg1.get_capture(len(pkts))
4934 self.verify_capture_out(capture, same_port=True)
4936 # in2out - no static mapping match
4938 host0 = self.pg0.remote_hosts[0]
4939 self.pg0.remote_hosts[0] = self.pg0.remote_hosts[1]
4941 pkts = self.create_stream_out(self.pg1,
4942 dst_ip=self.pg0.remote_ip4,
4943 use_inside_ports=True)
4944 self.pg1.add_stream(pkts)
4945 self.pg_enable_capture(self.pg_interfaces)
4947 capture = self.pg0.get_capture(len(pkts))
4948 self.verify_capture_in(capture, self.pg0)
4950 pkts = self.create_stream_in(self.pg0, self.pg1)
4951 self.pg0.add_stream(pkts)
4952 self.pg_enable_capture(self.pg_interfaces)
4954 capture = self.pg1.get_capture(len(pkts))
4955 self.verify_capture_out(capture, nat_ip=self.pg0.remote_ip4,
4958 self.pg0.remote_hosts[0] = host0
4960 user = self.pg0.remote_hosts[1]
4961 sessions = self.vapi.nat44_user_session_dump(user.ip4, 0)
4962 self.assertEqual(len(sessions), 3)
4963 self.assertTrue(sessions[0].flags &
4964 self.config_flags.NAT_IS_EXT_HOST_VALID)
4965 self.vapi.nat44_del_session(
4966 address=sessions[0].inside_ip_address,
4967 port=sessions[0].inside_port,
4968 protocol=sessions[0].protocol,
4969 flags=(self.config_flags.NAT_IS_INSIDE |
4970 self.config_flags.NAT_IS_EXT_HOST_VALID),
4971 ext_host_address=sessions[0].ext_host_address,
4972 ext_host_port=sessions[0].ext_host_port)
4973 sessions = self.vapi.nat44_user_session_dump(user.ip4, 0)
4974 self.assertEqual(len(sessions), 2)
4977 self.vapi.nat44_forwarding_enable_disable(enable=0)
4978 flags = self.config_flags.NAT_IS_ADDR_ONLY
4979 self.vapi.nat44_add_del_static_mapping(
4981 local_ip_address=real_ip,
4982 external_ip_address=alias_ip,
4983 external_sw_if_index=0xFFFFFFFF,
4986 def test_static_lb(self):
4987 """ NAT44 local service load balancing """
4988 external_addr_n = self.nat_addr
4991 server1 = self.pg0.remote_hosts[0]
4992 server2 = self.pg0.remote_hosts[1]
4994 locals = [{'addr': server1.ip4,
4998 {'addr': server2.ip4,
5003 self.nat44_add_address(self.nat_addr)
5004 self.vapi.nat44_add_del_lb_static_mapping(
5006 external_addr=external_addr_n,
5007 external_port=external_port,
5008 protocol=IP_PROTOS.tcp,
5009 local_num=len(locals),
5011 flags = self.config_flags.NAT_IS_INSIDE
5012 self.vapi.nat44_interface_add_del_feature(
5013 sw_if_index=self.pg0.sw_if_index,
5014 flags=flags, is_add=1)
5015 self.vapi.nat44_interface_add_del_feature(
5016 sw_if_index=self.pg1.sw_if_index,
5019 # from client to service
5020 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
5021 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
5022 TCP(sport=12345, dport=external_port))
5023 self.pg1.add_stream(p)
5024 self.pg_enable_capture(self.pg_interfaces)
5026 capture = self.pg0.get_capture(1)
5032 self.assertIn(ip.dst, [server1.ip4, server2.ip4])
5033 if ip.dst == server1.ip4:
5037 self.assertEqual(tcp.dport, local_port)
5038 self.assert_packet_checksums_valid(p)
5040 self.logger.error(ppp("Unexpected or invalid packet:", p))
5043 # from service back to client
5044 p = (Ether(src=server.mac, dst=self.pg0.local_mac) /
5045 IP(src=server.ip4, dst=self.pg1.remote_ip4) /
5046 TCP(sport=local_port, dport=12345))
5047 self.pg0.add_stream(p)
5048 self.pg_enable_capture(self.pg_interfaces)
5050 capture = self.pg1.get_capture(1)
5055 self.assertEqual(ip.src, self.nat_addr)
5056 self.assertEqual(tcp.sport, external_port)
5057 self.assert_packet_checksums_valid(p)
5059 self.logger.error(ppp("Unexpected or invalid packet:", p))
5062 sessions = self.vapi.nat44_user_session_dump(server.ip4, 0)
5063 self.assertEqual(len(sessions), 1)
5064 self.assertTrue(sessions[0].flags &
5065 self.config_flags.NAT_IS_EXT_HOST_VALID)
5066 self.vapi.nat44_del_session(
5067 address=sessions[0].inside_ip_address,
5068 port=sessions[0].inside_port,
5069 protocol=sessions[0].protocol,
5070 flags=(self.config_flags.NAT_IS_INSIDE |
5071 self.config_flags.NAT_IS_EXT_HOST_VALID),
5072 ext_host_address=sessions[0].ext_host_address,
5073 ext_host_port=sessions[0].ext_host_port)
5074 sessions = self.vapi.nat44_user_session_dump(server.ip4, 0)
5075 self.assertEqual(len(sessions), 0)
5077 @unittest.skipUnless(running_extended_tests, "part of extended tests")
5078 def test_static_lb_multi_clients(self):
5079 """ NAT44 local service load balancing - multiple clients"""
5081 external_addr = self.nat_addr
5084 server1 = self.pg0.remote_hosts[0]
5085 server2 = self.pg0.remote_hosts[1]
5086 server3 = self.pg0.remote_hosts[2]
5088 locals = [{'addr': server1.ip4,
5092 {'addr': server2.ip4,
5097 self.nat44_add_address(self.nat_addr)
5098 self.vapi.nat44_add_del_lb_static_mapping(is_add=1,
5099 external_addr=external_addr,
5100 external_port=external_port,
5101 protocol=IP_PROTOS.tcp,
5102 local_num=len(locals),
5104 flags = self.config_flags.NAT_IS_INSIDE
5105 self.vapi.nat44_interface_add_del_feature(
5106 sw_if_index=self.pg0.sw_if_index,
5107 flags=flags, is_add=1)
5108 self.vapi.nat44_interface_add_del_feature(
5109 sw_if_index=self.pg1.sw_if_index,
5114 clients = ip4_range(self.pg1.remote_ip4, 10, 50)
5116 for client in clients:
5117 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
5118 IP(src=client, dst=self.nat_addr) /
5119 TCP(sport=12345, dport=external_port))
5121 self.pg1.add_stream(pkts)
5122 self.pg_enable_capture(self.pg_interfaces)
5124 capture = self.pg0.get_capture(len(pkts))
5126 if p[IP].dst == server1.ip4:
5130 self.assertGreater(server1_n, server2_n)
5133 'addr': server3.ip4,
5140 self.vapi.nat44_lb_static_mapping_add_del_local(
5142 external_addr=external_addr,
5143 external_port=external_port,
5145 protocol=IP_PROTOS.tcp)
5149 clients = ip4_range(self.pg1.remote_ip4, 60, 110)
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=12346, dport=external_port))
5156 self.assertGreater(len(pkts), 0)
5157 self.pg1.add_stream(pkts)
5158 self.pg_enable_capture(self.pg_interfaces)
5160 capture = self.pg0.get_capture(len(pkts))
5162 if p[IP].dst == server1.ip4:
5164 elif p[IP].dst == server2.ip4:
5168 self.assertGreater(server1_n, 0)
5169 self.assertGreater(server2_n, 0)
5170 self.assertGreater(server3_n, 0)
5173 'addr': server2.ip4,
5179 # remove one back-end
5180 self.vapi.nat44_lb_static_mapping_add_del_local(
5182 external_addr=external_addr,
5183 external_port=external_port,
5185 protocol=IP_PROTOS.tcp)
5189 self.pg1.add_stream(pkts)
5190 self.pg_enable_capture(self.pg_interfaces)
5192 capture = self.pg0.get_capture(len(pkts))
5194 if p[IP].dst == server1.ip4:
5196 elif p[IP].dst == server2.ip4:
5200 self.assertGreater(server1_n, 0)
5201 self.assertEqual(server2_n, 0)
5202 self.assertGreater(server3_n, 0)
5204 def test_static_lb_2(self):
5205 """ NAT44 local service load balancing (asymmetrical rule) """
5206 external_addr = self.nat_addr
5209 server1 = self.pg0.remote_hosts[0]
5210 server2 = self.pg0.remote_hosts[1]
5212 locals = [{'addr': server1.ip4,
5216 {'addr': server2.ip4,
5221 self.vapi.nat44_forwarding_enable_disable(enable=1)
5222 flags = self.config_flags.NAT_IS_OUT2IN_ONLY
5223 self.vapi.nat44_add_del_lb_static_mapping(is_add=1, flags=flags,
5224 external_addr=external_addr,
5225 external_port=external_port,
5226 protocol=IP_PROTOS.tcp,
5227 local_num=len(locals),
5229 flags = self.config_flags.NAT_IS_INSIDE
5230 self.vapi.nat44_interface_add_del_feature(
5231 sw_if_index=self.pg0.sw_if_index,
5232 flags=flags, is_add=1)
5233 self.vapi.nat44_interface_add_del_feature(
5234 sw_if_index=self.pg1.sw_if_index,
5237 # from client to service
5238 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
5239 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
5240 TCP(sport=12345, dport=external_port))
5241 self.pg1.add_stream(p)
5242 self.pg_enable_capture(self.pg_interfaces)
5244 capture = self.pg0.get_capture(1)
5250 self.assertIn(ip.dst, [server1.ip4, server2.ip4])
5251 if ip.dst == server1.ip4:
5255 self.assertEqual(tcp.dport, local_port)
5256 self.assert_packet_checksums_valid(p)
5258 self.logger.error(ppp("Unexpected or invalid packet:", p))
5261 # from service back to client
5262 p = (Ether(src=server.mac, dst=self.pg0.local_mac) /
5263 IP(src=server.ip4, dst=self.pg1.remote_ip4) /
5264 TCP(sport=local_port, dport=12345))
5265 self.pg0.add_stream(p)
5266 self.pg_enable_capture(self.pg_interfaces)
5268 capture = self.pg1.get_capture(1)
5273 self.assertEqual(ip.src, self.nat_addr)
5274 self.assertEqual(tcp.sport, external_port)
5275 self.assert_packet_checksums_valid(p)
5277 self.logger.error(ppp("Unexpected or invalid packet:", p))
5280 # from client to server (no translation)
5281 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
5282 IP(src=self.pg1.remote_ip4, dst=server1.ip4) /
5283 TCP(sport=12346, dport=local_port))
5284 self.pg1.add_stream(p)
5285 self.pg_enable_capture(self.pg_interfaces)
5287 capture = self.pg0.get_capture(1)
5293 self.assertEqual(ip.dst, server1.ip4)
5294 self.assertEqual(tcp.dport, local_port)
5295 self.assert_packet_checksums_valid(p)
5297 self.logger.error(ppp("Unexpected or invalid packet:", p))
5300 # from service back to client (no translation)
5301 p = (Ether(src=server1.mac, dst=self.pg0.local_mac) /
5302 IP(src=server1.ip4, dst=self.pg1.remote_ip4) /
5303 TCP(sport=local_port, dport=12346))
5304 self.pg0.add_stream(p)
5305 self.pg_enable_capture(self.pg_interfaces)
5307 capture = self.pg1.get_capture(1)
5312 self.assertEqual(ip.src, server1.ip4)
5313 self.assertEqual(tcp.sport, local_port)
5314 self.assert_packet_checksums_valid(p)
5316 self.logger.error(ppp("Unexpected or invalid packet:", p))
5319 def test_lb_affinity(self):
5320 """ NAT44 local service load balancing affinity """
5321 external_addr = self.nat_addr
5324 server1 = self.pg0.remote_hosts[0]
5325 server2 = self.pg0.remote_hosts[1]
5327 locals = [{'addr': server1.ip4,
5331 {'addr': server2.ip4,
5336 self.nat44_add_address(self.nat_addr)
5337 self.vapi.nat44_add_del_lb_static_mapping(is_add=1,
5338 external_addr=external_addr,
5339 external_port=external_port,
5340 protocol=IP_PROTOS.tcp,
5342 local_num=len(locals),
5344 flags = self.config_flags.NAT_IS_INSIDE
5345 self.vapi.nat44_interface_add_del_feature(
5346 sw_if_index=self.pg0.sw_if_index,
5347 flags=flags, is_add=1)
5348 self.vapi.nat44_interface_add_del_feature(
5349 sw_if_index=self.pg1.sw_if_index,
5352 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
5353 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
5354 TCP(sport=1025, dport=external_port))
5355 self.pg1.add_stream(p)
5356 self.pg_enable_capture(self.pg_interfaces)
5358 capture = self.pg0.get_capture(1)
5359 backend = capture[0][IP].dst
5361 sessions = self.vapi.nat44_user_session_dump(backend, 0)
5362 self.assertEqual(len(sessions), 1)
5363 self.assertTrue(sessions[0].flags &
5364 self.config_flags.NAT_IS_EXT_HOST_VALID)
5365 self.vapi.nat44_del_session(
5366 address=sessions[0].inside_ip_address,
5367 port=sessions[0].inside_port,
5368 protocol=sessions[0].protocol,
5369 flags=(self.config_flags.NAT_IS_INSIDE |
5370 self.config_flags.NAT_IS_EXT_HOST_VALID),
5371 ext_host_address=sessions[0].ext_host_address,
5372 ext_host_port=sessions[0].ext_host_port)
5375 for port in range(1030, 1100):
5376 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
5377 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
5378 TCP(sport=port, dport=external_port))
5380 self.pg1.add_stream(pkts)
5381 self.pg_enable_capture(self.pg_interfaces)
5383 capture = self.pg0.get_capture(len(pkts))
5385 self.assertEqual(p[IP].dst, backend)
5387 def test_unknown_proto(self):
5388 """ NAT44 translate packet with unknown protocol """
5389 self.nat44_add_address(self.nat_addr)
5390 flags = self.config_flags.NAT_IS_INSIDE
5391 self.vapi.nat44_interface_add_del_feature(
5392 sw_if_index=self.pg0.sw_if_index,
5393 flags=flags, is_add=1)
5394 self.vapi.nat44_interface_add_del_feature(
5395 sw_if_index=self.pg1.sw_if_index,
5399 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
5400 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
5401 TCP(sport=self.tcp_port_in, dport=20))
5402 self.pg0.add_stream(p)
5403 self.pg_enable_capture(self.pg_interfaces)
5405 p = self.pg1.get_capture(1)
5407 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
5408 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
5410 IP(src=self.pg2.remote_ip4, dst=self.pg2.remote_ip4) /
5411 TCP(sport=1234, dport=1234))
5412 self.pg0.add_stream(p)
5413 self.pg_enable_capture(self.pg_interfaces)
5415 p = self.pg1.get_capture(1)
5418 self.assertEqual(packet[IP].src, self.nat_addr)
5419 self.assertEqual(packet[IP].dst, self.pg1.remote_ip4)
5420 self.assertEqual(packet.haslayer(GRE), 1)
5421 self.assert_packet_checksums_valid(packet)
5423 self.logger.error(ppp("Unexpected or invalid packet:", packet))
5427 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
5428 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
5430 IP(src=self.pg2.remote_ip4, dst=self.pg2.remote_ip4) /
5431 TCP(sport=1234, dport=1234))
5432 self.pg1.add_stream(p)
5433 self.pg_enable_capture(self.pg_interfaces)
5435 p = self.pg0.get_capture(1)
5438 self.assertEqual(packet[IP].src, self.pg1.remote_ip4)
5439 self.assertEqual(packet[IP].dst, self.pg0.remote_ip4)
5440 self.assertEqual(packet.haslayer(GRE), 1)
5441 self.assert_packet_checksums_valid(packet)
5443 self.logger.error(ppp("Unexpected or invalid packet:", packet))
5446 def test_hairpinning_unknown_proto(self):
5447 """ NAT44 translate packet with unknown protocol - hairpinning """
5448 host = self.pg0.remote_hosts[0]
5449 server = self.pg0.remote_hosts[1]
5451 server_out_port = 8765
5452 server_nat_ip = "10.0.0.11"
5454 self.nat44_add_address(self.nat_addr)
5455 flags = self.config_flags.NAT_IS_INSIDE
5456 self.vapi.nat44_interface_add_del_feature(
5457 sw_if_index=self.pg0.sw_if_index,
5458 flags=flags, is_add=1)
5459 self.vapi.nat44_interface_add_del_feature(
5460 sw_if_index=self.pg1.sw_if_index,
5463 # add static mapping for server
5464 self.nat44_add_static_mapping(server.ip4, server_nat_ip)
5467 p = (Ether(src=host.mac, dst=self.pg0.local_mac) /
5468 IP(src=host.ip4, dst=server_nat_ip) /
5469 TCP(sport=host_in_port, dport=server_out_port))
5470 self.pg0.add_stream(p)
5471 self.pg_enable_capture(self.pg_interfaces)
5473 self.pg0.get_capture(1)
5475 p = (Ether(dst=self.pg0.local_mac, src=host.mac) /
5476 IP(src=host.ip4, dst=server_nat_ip) /
5478 IP(src=self.pg2.remote_ip4, dst=self.pg2.remote_ip4) /
5479 TCP(sport=1234, dport=1234))
5480 self.pg0.add_stream(p)
5481 self.pg_enable_capture(self.pg_interfaces)
5483 p = self.pg0.get_capture(1)
5486 self.assertEqual(packet[IP].src, self.nat_addr)
5487 self.assertEqual(packet[IP].dst, server.ip4)
5488 self.assertEqual(packet.haslayer(GRE), 1)
5489 self.assert_packet_checksums_valid(packet)
5491 self.logger.error(ppp("Unexpected or invalid packet:", packet))
5495 p = (Ether(dst=self.pg0.local_mac, src=server.mac) /
5496 IP(src=server.ip4, dst=self.nat_addr) /
5498 IP(src=self.pg2.remote_ip4, dst=self.pg2.remote_ip4) /
5499 TCP(sport=1234, dport=1234))
5500 self.pg0.add_stream(p)
5501 self.pg_enable_capture(self.pg_interfaces)
5503 p = self.pg0.get_capture(1)
5506 self.assertEqual(packet[IP].src, server_nat_ip)
5507 self.assertEqual(packet[IP].dst, host.ip4)
5508 self.assertEqual(packet.haslayer(GRE), 1)
5509 self.assert_packet_checksums_valid(packet)
5511 self.logger.error(ppp("Unexpected or invalid packet:", packet))
5514 def test_output_feature_and_service(self):
5515 """ NAT44 interface output feature and services """
5516 external_addr = '1.2.3.4'
5520 self.vapi.nat44_forwarding_enable_disable(enable=1)
5521 self.nat44_add_address(self.nat_addr)
5522 flags = self.config_flags.NAT_IS_ADDR_ONLY
5523 self.vapi.nat44_add_del_identity_mapping(
5524 ip_address=self.pg1.remote_ip4, sw_if_index=0xFFFFFFFF,
5525 flags=flags, is_add=1)
5526 flags = self.config_flags.NAT_IS_OUT2IN_ONLY
5527 self.nat44_add_static_mapping(self.pg0.remote_ip4, external_addr,
5528 local_port, external_port,
5529 proto=IP_PROTOS.tcp, flags=flags)
5530 flags = self.config_flags.NAT_IS_INSIDE
5531 self.vapi.nat44_interface_add_del_feature(
5532 sw_if_index=self.pg0.sw_if_index,
5534 self.vapi.nat44_interface_add_del_feature(
5535 sw_if_index=self.pg0.sw_if_index,
5536 flags=flags, is_add=1)
5537 self.vapi.nat44_interface_add_del_output_feature(
5539 sw_if_index=self.pg1.sw_if_index)
5541 # from client to service
5542 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
5543 IP(src=self.pg1.remote_ip4, dst=external_addr) /
5544 TCP(sport=12345, dport=external_port))
5545 self.pg1.add_stream(p)
5546 self.pg_enable_capture(self.pg_interfaces)
5548 capture = self.pg0.get_capture(1)
5553 self.assertEqual(ip.dst, self.pg0.remote_ip4)
5554 self.assertEqual(tcp.dport, local_port)
5555 self.assert_packet_checksums_valid(p)
5557 self.logger.error(ppp("Unexpected or invalid packet:", p))
5560 # from service back to client
5561 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5562 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
5563 TCP(sport=local_port, dport=12345))
5564 self.pg0.add_stream(p)
5565 self.pg_enable_capture(self.pg_interfaces)
5567 capture = self.pg1.get_capture(1)
5572 self.assertEqual(ip.src, external_addr)
5573 self.assertEqual(tcp.sport, external_port)
5574 self.assert_packet_checksums_valid(p)
5576 self.logger.error(ppp("Unexpected or invalid packet:", p))
5579 # from local network host to external network
5580 pkts = self.create_stream_in(self.pg0, self.pg1)
5581 self.pg0.add_stream(pkts)
5582 self.pg_enable_capture(self.pg_interfaces)
5584 capture = self.pg1.get_capture(len(pkts))
5585 self.verify_capture_out(capture, ignore_port=True)
5586 pkts = self.create_stream_in(self.pg0, self.pg1)
5587 self.pg0.add_stream(pkts)
5588 self.pg_enable_capture(self.pg_interfaces)
5590 capture = self.pg1.get_capture(len(pkts))
5591 self.verify_capture_out(capture, ignore_port=True)
5593 # from external network back to local network host
5594 pkts = self.create_stream_out(self.pg1)
5595 self.pg1.add_stream(pkts)
5596 self.pg_enable_capture(self.pg_interfaces)
5598 capture = self.pg0.get_capture(len(pkts))
5599 self.verify_capture_in(capture, self.pg0)
5601 def test_output_feature_and_service2(self):
5602 """ NAT44 interface output feature and service host direct access """
5603 self.vapi.nat44_forwarding_enable_disable(enable=1)
5604 self.nat44_add_address(self.nat_addr)
5605 self.vapi.nat44_interface_add_del_output_feature(
5607 sw_if_index=self.pg1.sw_if_index)
5609 # session initiated from service host - translate
5610 pkts = self.create_stream_in(self.pg0, self.pg1)
5611 self.pg0.add_stream(pkts)
5612 self.pg_enable_capture(self.pg_interfaces)
5614 capture = self.pg1.get_capture(len(pkts))
5615 self.verify_capture_out(capture, ignore_port=True)
5617 pkts = self.create_stream_out(self.pg1)
5618 self.pg1.add_stream(pkts)
5619 self.pg_enable_capture(self.pg_interfaces)
5621 capture = self.pg0.get_capture(len(pkts))
5622 self.verify_capture_in(capture, self.pg0)
5624 # session initiated from remote host - do not translate
5625 self.tcp_port_in = 60303
5626 self.udp_port_in = 60304
5627 self.icmp_id_in = 60305
5628 pkts = self.create_stream_out(self.pg1,
5629 self.pg0.remote_ip4,
5630 use_inside_ports=True)
5631 self.pg1.add_stream(pkts)
5632 self.pg_enable_capture(self.pg_interfaces)
5634 capture = self.pg0.get_capture(len(pkts))
5635 self.verify_capture_in(capture, self.pg0)
5637 pkts = self.create_stream_in(self.pg0, self.pg1)
5638 self.pg0.add_stream(pkts)
5639 self.pg_enable_capture(self.pg_interfaces)
5641 capture = self.pg1.get_capture(len(pkts))
5642 self.verify_capture_out(capture, nat_ip=self.pg0.remote_ip4,
5645 def test_output_feature_and_service3(self):
5646 """ NAT44 interface output feature and DST NAT """
5647 external_addr = '1.2.3.4'
5651 self.vapi.nat44_forwarding_enable_disable(enable=1)
5652 self.nat44_add_address(self.nat_addr)
5653 flags = self.config_flags.NAT_IS_OUT2IN_ONLY
5654 self.nat44_add_static_mapping(self.pg1.remote_ip4, external_addr,
5655 local_port, external_port,
5656 proto=IP_PROTOS.tcp, flags=flags)
5657 flags = self.config_flags.NAT_IS_INSIDE
5658 self.vapi.nat44_interface_add_del_feature(
5659 sw_if_index=self.pg0.sw_if_index,
5661 self.vapi.nat44_interface_add_del_feature(
5662 sw_if_index=self.pg0.sw_if_index,
5663 flags=flags, is_add=1)
5664 self.vapi.nat44_interface_add_del_output_feature(
5666 sw_if_index=self.pg1.sw_if_index)
5668 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5669 IP(src=self.pg0.remote_ip4, dst=external_addr) /
5670 TCP(sport=12345, dport=external_port))
5671 self.pg0.add_stream(p)
5672 self.pg_enable_capture(self.pg_interfaces)
5674 capture = self.pg1.get_capture(1)
5679 self.assertEqual(ip.src, self.pg0.remote_ip4)
5680 self.assertEqual(tcp.sport, 12345)
5681 self.assertEqual(ip.dst, self.pg1.remote_ip4)
5682 self.assertEqual(tcp.dport, local_port)
5683 self.assert_packet_checksums_valid(p)
5685 self.logger.error(ppp("Unexpected or invalid packet:", p))
5688 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
5689 IP(src=self.pg1.remote_ip4, dst=self.pg0.remote_ip4) /
5690 TCP(sport=local_port, dport=12345))
5691 self.pg1.add_stream(p)
5692 self.pg_enable_capture(self.pg_interfaces)
5694 capture = self.pg0.get_capture(1)
5699 self.assertEqual(ip.src, external_addr)
5700 self.assertEqual(tcp.sport, external_port)
5701 self.assertEqual(ip.dst, self.pg0.remote_ip4)
5702 self.assertEqual(tcp.dport, 12345)
5703 self.assert_packet_checksums_valid(p)
5705 self.logger.error(ppp("Unexpected or invalid packet:", p))
5708 def test_next_src_nat(self):
5709 """ On way back forward packet to nat44-in2out node. """
5710 twice_nat_addr = '10.0.1.3'
5713 post_twice_nat_port = 0
5715 self.vapi.nat44_forwarding_enable_disable(enable=1)
5716 self.nat44_add_address(twice_nat_addr, twice_nat=1)
5717 flags = (self.config_flags.NAT_IS_OUT2IN_ONLY |
5718 self.config_flags.NAT_IS_SELF_TWICE_NAT)
5719 self.nat44_add_static_mapping(self.pg6.remote_ip4, self.pg1.remote_ip4,
5720 local_port, external_port,
5721 proto=IP_PROTOS.tcp, vrf_id=1,
5723 self.vapi.nat44_interface_add_del_feature(
5724 sw_if_index=self.pg6.sw_if_index,
5727 p = (Ether(src=self.pg6.remote_mac, dst=self.pg6.local_mac) /
5728 IP(src=self.pg6.remote_ip4, dst=self.pg1.remote_ip4) /
5729 TCP(sport=12345, dport=external_port))
5730 self.pg6.add_stream(p)
5731 self.pg_enable_capture(self.pg_interfaces)
5733 capture = self.pg6.get_capture(1)
5738 self.assertEqual(ip.src, twice_nat_addr)
5739 self.assertNotEqual(tcp.sport, 12345)
5740 post_twice_nat_port = tcp.sport
5741 self.assertEqual(ip.dst, self.pg6.remote_ip4)
5742 self.assertEqual(tcp.dport, local_port)
5743 self.assert_packet_checksums_valid(p)
5745 self.logger.error(ppp("Unexpected or invalid packet:", p))
5748 p = (Ether(src=self.pg6.remote_mac, dst=self.pg6.local_mac) /
5749 IP(src=self.pg6.remote_ip4, dst=twice_nat_addr) /
5750 TCP(sport=local_port, dport=post_twice_nat_port))
5751 self.pg6.add_stream(p)
5752 self.pg_enable_capture(self.pg_interfaces)
5754 capture = self.pg6.get_capture(1)
5759 self.assertEqual(ip.src, self.pg1.remote_ip4)
5760 self.assertEqual(tcp.sport, external_port)
5761 self.assertEqual(ip.dst, self.pg6.remote_ip4)
5762 self.assertEqual(tcp.dport, 12345)
5763 self.assert_packet_checksums_valid(p)
5765 self.logger.error(ppp("Unexpected or invalid packet:", p))
5768 def twice_nat_common(self, self_twice_nat=False, same_pg=False, lb=False,
5770 twice_nat_addr = '10.0.1.3'
5778 port_in1 = port_in + 1
5779 port_in2 = port_in + 2
5784 server1 = self.pg0.remote_hosts[0]
5785 server2 = self.pg0.remote_hosts[1]
5797 eh_translate = ((not self_twice_nat) or (not lb and same_pg) or
5800 self.nat44_add_address(self.nat_addr)
5801 self.nat44_add_address(twice_nat_addr, twice_nat=1)
5805 flags |= self.config_flags.NAT_IS_SELF_TWICE_NAT
5807 flags |= self.config_flags.NAT_IS_TWICE_NAT
5810 self.nat44_add_static_mapping(pg0.remote_ip4, self.nat_addr,
5812 proto=IP_PROTOS.tcp,
5815 locals = [{'addr': server1.ip4,
5819 {'addr': server2.ip4,
5823 out_addr = self.nat_addr
5825 self.vapi.nat44_add_del_lb_static_mapping(is_add=1, flags=flags,
5826 external_addr=out_addr,
5827 external_port=port_out,
5828 protocol=IP_PROTOS.tcp,
5829 local_num=len(locals),
5831 flags = self.config_flags.NAT_IS_INSIDE
5832 self.vapi.nat44_interface_add_del_feature(
5833 sw_if_index=pg0.sw_if_index,
5834 flags=flags, is_add=1)
5835 self.vapi.nat44_interface_add_del_feature(
5836 sw_if_index=pg1.sw_if_index,
5843 assert client_id is not None
5845 client = self.pg0.remote_hosts[0]
5846 elif client_id == 2:
5847 client = self.pg0.remote_hosts[1]
5849 client = pg1.remote_hosts[0]
5850 p = (Ether(src=pg1.remote_mac, dst=pg1.local_mac) /
5851 IP(src=client.ip4, dst=self.nat_addr) /
5852 TCP(sport=eh_port_out, dport=port_out))
5854 self.pg_enable_capture(self.pg_interfaces)
5856 capture = pg0.get_capture(1)
5862 if ip.dst == server1.ip4:
5868 self.assertEqual(ip.dst, server.ip4)
5870 self.assertIn(tcp.dport, [port_in1, port_in2])
5872 self.assertEqual(tcp.dport, port_in)
5874 self.assertEqual(ip.src, twice_nat_addr)
5875 self.assertNotEqual(tcp.sport, eh_port_out)
5877 self.assertEqual(ip.src, client.ip4)
5878 self.assertEqual(tcp.sport, eh_port_out)
5880 eh_port_in = tcp.sport
5881 saved_port_in = tcp.dport
5882 self.assert_packet_checksums_valid(p)
5884 self.logger.error(ppp("Unexpected or invalid packet:", p))
5887 p = (Ether(src=server.mac, dst=pg0.local_mac) /
5888 IP(src=server.ip4, dst=eh_addr_in) /
5889 TCP(sport=saved_port_in, dport=eh_port_in))
5891 self.pg_enable_capture(self.pg_interfaces)
5893 capture = pg1.get_capture(1)
5898 self.assertEqual(ip.dst, client.ip4)
5899 self.assertEqual(ip.src, self.nat_addr)
5900 self.assertEqual(tcp.dport, eh_port_out)
5901 self.assertEqual(tcp.sport, port_out)
5902 self.assert_packet_checksums_valid(p)
5904 self.logger.error(ppp("Unexpected or invalid packet:", p))
5908 sessions = self.vapi.nat44_user_session_dump(server.ip4, 0)
5909 self.assertEqual(len(sessions), 1)
5910 self.assertTrue(sessions[0].flags &
5911 self.config_flags.NAT_IS_EXT_HOST_VALID)
5912 self.assertTrue(sessions[0].flags &
5913 self.config_flags.NAT_IS_TWICE_NAT)
5914 self.logger.info(self.vapi.cli("show nat44 sessions detail"))
5915 self.vapi.nat44_del_session(
5916 address=sessions[0].inside_ip_address,
5917 port=sessions[0].inside_port,
5918 protocol=sessions[0].protocol,
5919 flags=(self.config_flags.NAT_IS_INSIDE |
5920 self.config_flags.NAT_IS_EXT_HOST_VALID),
5921 ext_host_address=sessions[0].ext_host_nat_address,
5922 ext_host_port=sessions[0].ext_host_nat_port)
5923 sessions = self.vapi.nat44_user_session_dump(server.ip4, 0)
5924 self.assertEqual(len(sessions), 0)
5926 def test_twice_nat(self):
5928 self.twice_nat_common()
5930 def test_self_twice_nat_positive(self):
5931 """ Self Twice NAT44 (positive test) """
5932 self.twice_nat_common(self_twice_nat=True, same_pg=True)
5934 def test_self_twice_nat_negative(self):
5935 """ Self Twice NAT44 (negative test) """
5936 self.twice_nat_common(self_twice_nat=True)
5938 def test_twice_nat_lb(self):
5939 """ Twice NAT44 local service load balancing """
5940 self.twice_nat_common(lb=True)
5942 def test_self_twice_nat_lb_positive(self):
5943 """ Self Twice NAT44 local service load balancing (positive test) """
5944 self.twice_nat_common(lb=True, self_twice_nat=True, same_pg=True,
5947 def test_self_twice_nat_lb_negative(self):
5948 """ Self Twice NAT44 local service load balancing (negative test) """
5949 self.twice_nat_common(lb=True, self_twice_nat=True, same_pg=True,
5952 def test_twice_nat_interface_addr(self):
5953 """ Acquire twice NAT44 addresses from interface """
5954 flags = self.config_flags.NAT_IS_TWICE_NAT
5955 self.vapi.nat44_add_del_interface_addr(
5957 sw_if_index=self.pg3.sw_if_index,
5960 # no address in NAT pool
5961 adresses = self.vapi.nat44_address_dump()
5962 self.assertEqual(0, len(adresses))
5964 # configure interface address and check NAT address pool
5965 self.pg3.config_ip4()
5966 adresses = self.vapi.nat44_address_dump()
5967 self.assertEqual(1, len(adresses))
5968 self.assertEqual(str(adresses[0].ip_address),
5970 self.assertEqual(adresses[0].flags, flags)
5972 # remove interface address and check NAT address pool
5973 self.pg3.unconfig_ip4()
5974 adresses = self.vapi.nat44_address_dump()
5975 self.assertEqual(0, len(adresses))
5977 def test_tcp_close(self):
5978 """ Close TCP session from inside network - output feature """
5979 self.vapi.nat44_forwarding_enable_disable(enable=1)
5980 self.nat44_add_address(self.pg1.local_ip4)
5981 twice_nat_addr = '10.0.1.3'
5982 service_ip = '192.168.16.150'
5983 self.nat44_add_address(twice_nat_addr, twice_nat=1)
5984 flags = self.config_flags.NAT_IS_INSIDE
5985 self.vapi.nat44_interface_add_del_feature(
5986 sw_if_index=self.pg0.sw_if_index,
5988 self.vapi.nat44_interface_add_del_feature(
5989 sw_if_index=self.pg0.sw_if_index,
5990 flags=flags, is_add=1)
5991 self.vapi.nat44_interface_add_del_output_feature(
5993 sw_if_index=self.pg1.sw_if_index)
5994 flags = (self.config_flags.NAT_IS_OUT2IN_ONLY |
5995 self.config_flags.NAT_IS_TWICE_NAT)
5996 self.nat44_add_static_mapping(self.pg0.remote_ip4,
6000 proto=IP_PROTOS.tcp,
6002 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4, 0)
6003 start_sessnum = len(sessions)
6005 # SYN packet out->in
6006 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
6007 IP(src=self.pg1.remote_ip4, dst=service_ip) /
6008 TCP(sport=33898, dport=80, flags="S"))
6009 self.pg1.add_stream(p)
6010 self.pg_enable_capture(self.pg_interfaces)
6012 capture = self.pg0.get_capture(1)
6014 tcp_port = p[TCP].sport
6016 # SYN + ACK packet in->out
6017 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6018 IP(src=self.pg0.remote_ip4, dst=twice_nat_addr) /
6019 TCP(sport=80, dport=tcp_port, flags="SA"))
6020 self.pg0.add_stream(p)
6021 self.pg_enable_capture(self.pg_interfaces)
6023 self.pg1.get_capture(1)
6025 # ACK packet out->in
6026 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
6027 IP(src=self.pg1.remote_ip4, dst=service_ip) /
6028 TCP(sport=33898, dport=80, flags="A"))
6029 self.pg1.add_stream(p)
6030 self.pg_enable_capture(self.pg_interfaces)
6032 self.pg0.get_capture(1)
6034 # FIN packet in -> out
6035 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6036 IP(src=self.pg0.remote_ip4, dst=twice_nat_addr) /
6037 TCP(sport=80, dport=tcp_port, flags="FA", seq=100, ack=300))
6038 self.pg0.add_stream(p)
6039 self.pg_enable_capture(self.pg_interfaces)
6041 self.pg1.get_capture(1)
6043 # FIN+ACK packet out -> in
6044 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
6045 IP(src=self.pg1.remote_ip4, dst=service_ip) /
6046 TCP(sport=33898, dport=80, flags="FA", seq=300, ack=101))
6047 self.pg1.add_stream(p)
6048 self.pg_enable_capture(self.pg_interfaces)
6050 self.pg0.get_capture(1)
6052 # ACK packet in -> out
6053 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6054 IP(src=self.pg0.remote_ip4, dst=twice_nat_addr) /
6055 TCP(sport=80, dport=tcp_port, flags="A", seq=101, ack=301))
6056 self.pg0.add_stream(p)
6057 self.pg_enable_capture(self.pg_interfaces)
6059 self.pg1.get_capture(1)
6061 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4,
6063 self.assertEqual(len(sessions) - start_sessnum, 0)
6065 def test_tcp_session_close_in(self):
6066 """ Close TCP session from inside network """
6067 self.tcp_port_out = 10505
6068 self.nat44_add_address(self.nat_addr)
6069 flags = self.config_flags.NAT_IS_TWICE_NAT
6070 self.nat44_add_static_mapping(self.pg0.remote_ip4,
6074 proto=IP_PROTOS.tcp,
6076 flags = self.config_flags.NAT_IS_INSIDE
6077 self.vapi.nat44_interface_add_del_feature(
6078 sw_if_index=self.pg0.sw_if_index,
6079 flags=flags, is_add=1)
6080 self.vapi.nat44_interface_add_del_feature(
6081 sw_if_index=self.pg1.sw_if_index,
6084 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4, 0)
6085 start_sessnum = len(sessions)
6087 self.vapi.nat_set_timeouts(udp=300, tcp_established=7440,
6088 tcp_transitory=2, icmp=5)
6090 self.initiate_tcp_session(self.pg0, self.pg1)
6092 # FIN packet in -> out
6093 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6094 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6095 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
6096 flags="FA", seq=100, ack=300))
6097 self.pg0.add_stream(p)
6098 self.pg_enable_capture(self.pg_interfaces)
6100 self.pg1.get_capture(1)
6104 # ACK packet out -> in
6105 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
6106 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
6107 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
6108 flags="A", seq=300, ack=101))
6111 # FIN packet out -> in
6112 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
6113 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
6114 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
6115 flags="FA", seq=300, ack=101))
6118 self.pg1.add_stream(pkts)
6119 self.pg_enable_capture(self.pg_interfaces)
6121 self.pg0.get_capture(2)
6123 # ACK packet in -> out
6124 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6125 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6126 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
6127 flags="A", seq=101, ack=301))
6128 self.pg0.add_stream(p)
6129 self.pg_enable_capture(self.pg_interfaces)
6131 self.pg1.get_capture(1)
6133 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4, 0)
6134 self.assertEqual(len(sessions) - start_sessnum, 1)
6136 stats = self.statistics.get_counter(
6137 '/err/nat44-ed-out2in/drops due to TCP in transitory timeout')
6138 out2in_drops = stats[0]
6139 stats = self.statistics.get_counter(
6140 '/err/nat44-ed-in2out/drops due to TCP in transitory timeout')
6141 in2out_drops = stats[0]
6143 # extra FIN packet out -> in - this should be dropped
6144 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
6145 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
6146 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
6147 flags="FA", seq=300, ack=101))
6149 self.pg1.add_stream(p)
6150 self.pg_enable_capture(self.pg_interfaces)
6152 self.pg0.assert_nothing_captured()
6154 # extra ACK packet in -> out - this should be dropped
6155 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6156 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6157 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
6158 flags="A", seq=101, ack=301))
6159 self.pg0.add_stream(p)
6160 self.pg_enable_capture(self.pg_interfaces)
6162 self.pg1.assert_nothing_captured()
6164 stats = self.statistics.get_counter(
6165 '/err/nat44-ed-out2in/drops due to TCP in transitory timeout')
6166 self.assertEqual(stats[0] - out2in_drops, 1)
6167 stats = self.statistics.get_counter(
6168 '/err/nat44-ed-in2out/drops due to TCP in transitory timeout')
6169 self.assertEqual(stats[0] - in2out_drops, 1)
6172 # extra ACK packet in -> out - this will cause session to be wiped
6173 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6174 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6175 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
6176 flags="A", seq=101, ack=301))
6177 self.pg0.add_stream(p)
6178 self.pg_enable_capture(self.pg_interfaces)
6180 self.pg1.assert_nothing_captured()
6181 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4, 0)
6182 self.assertEqual(len(sessions) - start_sessnum, 0)
6184 def test_tcp_session_close_out(self):
6185 """ Close TCP session from outside network """
6186 self.tcp_port_out = 10505
6187 self.nat44_add_address(self.nat_addr)
6188 flags = self.config_flags.NAT_IS_TWICE_NAT
6189 self.nat44_add_static_mapping(self.pg0.remote_ip4,
6193 proto=IP_PROTOS.tcp,
6195 flags = self.config_flags.NAT_IS_INSIDE
6196 self.vapi.nat44_interface_add_del_feature(
6197 sw_if_index=self.pg0.sw_if_index,
6198 flags=flags, is_add=1)
6199 self.vapi.nat44_interface_add_del_feature(
6200 sw_if_index=self.pg1.sw_if_index,
6203 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4, 0)
6204 start_sessnum = len(sessions)
6206 self.vapi.nat_set_timeouts(udp=300, tcp_established=7440,
6207 tcp_transitory=2, icmp=5)
6209 self.initiate_tcp_session(self.pg0, self.pg1)
6211 # FIN packet out -> in
6212 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
6213 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
6214 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
6215 flags="FA", seq=100, ack=300))
6216 self.pg1.add_stream(p)
6217 self.pg_enable_capture(self.pg_interfaces)
6219 self.pg0.get_capture(1)
6221 # FIN+ACK packet in -> out
6222 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6223 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6224 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
6225 flags="FA", seq=300, ack=101))
6227 self.pg0.add_stream(p)
6228 self.pg_enable_capture(self.pg_interfaces)
6230 self.pg1.get_capture(1)
6232 # ACK packet out -> in
6233 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
6234 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
6235 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
6236 flags="A", seq=101, ack=301))
6237 self.pg1.add_stream(p)
6238 self.pg_enable_capture(self.pg_interfaces)
6240 self.pg0.get_capture(1)
6242 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4, 0)
6243 self.assertEqual(len(sessions) - start_sessnum, 1)
6245 stats = self.statistics.get_counter(
6246 '/err/nat44-ed-out2in/drops due to TCP in transitory timeout')
6247 out2in_drops = stats[0]
6248 stats = self.statistics.get_counter(
6249 '/err/nat44-ed-in2out/drops due to TCP in transitory timeout')
6250 in2out_drops = stats[0]
6252 # extra FIN packet out -> in - this should be dropped
6253 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
6254 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
6255 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
6256 flags="FA", seq=300, ack=101))
6258 self.pg1.add_stream(p)
6259 self.pg_enable_capture(self.pg_interfaces)
6261 self.pg0.assert_nothing_captured()
6263 # extra ACK packet in -> out - this should be dropped
6264 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6265 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6266 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
6267 flags="A", seq=101, ack=301))
6268 self.pg0.add_stream(p)
6269 self.pg_enable_capture(self.pg_interfaces)
6271 self.pg1.assert_nothing_captured()
6273 stats = self.statistics.get_counter(
6274 '/err/nat44-ed-out2in/drops due to TCP in transitory timeout')
6275 self.assertEqual(stats[0] - out2in_drops, 1)
6276 stats = self.statistics.get_counter(
6277 '/err/nat44-ed-in2out/drops due to TCP in transitory timeout')
6278 self.assertEqual(stats[0] - in2out_drops, 1)
6281 # extra ACK packet in -> out - this will cause session to be wiped
6282 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6283 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6284 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
6285 flags="A", seq=101, ack=301))
6286 self.pg0.add_stream(p)
6287 self.pg_enable_capture(self.pg_interfaces)
6289 self.pg1.assert_nothing_captured()
6290 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4, 0)
6291 self.assertEqual(len(sessions) - start_sessnum, 0)
6293 def test_tcp_session_close_simultaneous(self):
6294 """ Close TCP session from inside network """
6295 self.tcp_port_out = 10505
6296 self.nat44_add_address(self.nat_addr)
6297 flags = self.config_flags.NAT_IS_TWICE_NAT
6298 self.nat44_add_static_mapping(self.pg0.remote_ip4,
6302 proto=IP_PROTOS.tcp,
6304 flags = self.config_flags.NAT_IS_INSIDE
6305 self.vapi.nat44_interface_add_del_feature(
6306 sw_if_index=self.pg0.sw_if_index,
6307 flags=flags, is_add=1)
6308 self.vapi.nat44_interface_add_del_feature(
6309 sw_if_index=self.pg1.sw_if_index,
6312 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4, 0)
6313 start_sessnum = len(sessions)
6315 self.vapi.nat_set_timeouts(udp=300, tcp_established=7440,
6316 tcp_transitory=2, icmp=5)
6318 self.initiate_tcp_session(self.pg0, self.pg1)
6320 # FIN packet in -> out
6321 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6322 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6323 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
6324 flags="FA", seq=100, ack=300))
6325 self.pg0.add_stream(p)
6326 self.pg_enable_capture(self.pg_interfaces)
6328 self.pg1.get_capture(1)
6330 # FIN packet out -> in
6331 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
6332 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
6333 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
6334 flags="FA", seq=300, ack=100))
6335 self.pg1.add_stream(p)
6336 self.pg_enable_capture(self.pg_interfaces)
6338 self.pg0.get_capture(1)
6340 # ACK packet in -> out
6341 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6342 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6343 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
6344 flags="A", seq=101, ack=301))
6345 self.pg0.add_stream(p)
6346 self.pg_enable_capture(self.pg_interfaces)
6348 self.pg1.get_capture(1)
6350 # ACK packet out -> in
6351 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
6352 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
6353 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
6354 flags="A", seq=301, ack=101))
6355 self.pg1.add_stream(p)
6356 self.pg_enable_capture(self.pg_interfaces)
6358 self.pg0.get_capture(1)
6360 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4, 0)
6361 self.assertEqual(len(sessions) - start_sessnum, 1)
6363 stats = self.statistics.get_counter(
6364 '/err/nat44-ed-out2in/drops due to TCP in transitory timeout')
6365 out2in_drops = stats[0]
6366 stats = self.statistics.get_counter(
6367 '/err/nat44-ed-in2out/drops due to TCP in transitory timeout')
6368 in2out_drops = stats[0]
6370 # extra FIN packet out -> in - this should be dropped
6371 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
6372 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
6373 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
6374 flags="FA", seq=300, ack=101))
6376 self.pg1.add_stream(p)
6377 self.pg_enable_capture(self.pg_interfaces)
6379 self.pg0.assert_nothing_captured()
6381 # extra ACK packet in -> out - this should be dropped
6382 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6383 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6384 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
6385 flags="A", seq=101, ack=301))
6386 self.pg0.add_stream(p)
6387 self.pg_enable_capture(self.pg_interfaces)
6389 self.pg1.assert_nothing_captured()
6391 stats = self.statistics.get_counter(
6392 '/err/nat44-ed-out2in/drops due to TCP in transitory timeout')
6393 self.assertEqual(stats[0] - out2in_drops, 1)
6394 stats = self.statistics.get_counter(
6395 '/err/nat44-ed-in2out/drops due to TCP in transitory timeout')
6396 self.assertEqual(stats[0] - in2out_drops, 1)
6399 # extra ACK packet in -> out - this will cause session to be wiped
6400 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6401 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6402 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
6403 flags="A", seq=101, ack=301))
6404 self.pg0.add_stream(p)
6405 self.pg_enable_capture(self.pg_interfaces)
6407 self.pg1.assert_nothing_captured()
6408 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4, 0)
6409 self.assertEqual(len(sessions) - start_sessnum, 0)
6411 def test_one_armed_nat44_static(self):
6412 """ One armed NAT44 and 1:1 NAPT asymmetrical rule """
6413 remote_host = self.pg4.remote_hosts[0]
6414 local_host = self.pg4.remote_hosts[1]
6419 self.vapi.nat44_forwarding_enable_disable(enable=1)
6420 self.nat44_add_address(self.nat_addr, twice_nat=1)
6421 flags = (self.config_flags.NAT_IS_OUT2IN_ONLY |
6422 self.config_flags.NAT_IS_TWICE_NAT)
6423 self.nat44_add_static_mapping(local_host.ip4, self.nat_addr,
6424 local_port, external_port,
6425 proto=IP_PROTOS.tcp, flags=flags)
6426 flags = self.config_flags.NAT_IS_INSIDE
6427 self.vapi.nat44_interface_add_del_feature(
6428 sw_if_index=self.pg4.sw_if_index,
6430 self.vapi.nat44_interface_add_del_feature(
6431 sw_if_index=self.pg4.sw_if_index,
6432 flags=flags, is_add=1)
6434 # from client to service
6435 p = (Ether(src=self.pg4.remote_mac, dst=self.pg4.local_mac) /
6436 IP(src=remote_host.ip4, dst=self.nat_addr) /
6437 TCP(sport=12345, dport=external_port))
6438 self.pg4.add_stream(p)
6439 self.pg_enable_capture(self.pg_interfaces)
6441 capture = self.pg4.get_capture(1)
6446 self.assertEqual(ip.dst, local_host.ip4)
6447 self.assertEqual(ip.src, self.nat_addr)
6448 self.assertEqual(tcp.dport, local_port)
6449 self.assertNotEqual(tcp.sport, 12345)
6450 eh_port_in = tcp.sport
6451 self.assert_packet_checksums_valid(p)
6453 self.logger.error(ppp("Unexpected or invalid packet:", p))
6456 # from service back to client
6457 p = (Ether(src=self.pg4.remote_mac, dst=self.pg4.local_mac) /
6458 IP(src=local_host.ip4, dst=self.nat_addr) /
6459 TCP(sport=local_port, dport=eh_port_in))
6460 self.pg4.add_stream(p)
6461 self.pg_enable_capture(self.pg_interfaces)
6463 capture = self.pg4.get_capture(1)
6468 self.assertEqual(ip.src, self.nat_addr)
6469 self.assertEqual(ip.dst, remote_host.ip4)
6470 self.assertEqual(tcp.sport, external_port)
6471 self.assertEqual(tcp.dport, 12345)
6472 self.assert_packet_checksums_valid(p)
6474 self.logger.error(ppp("Unexpected or invalid packet:", p))
6477 def test_static_with_port_out2(self):
6478 """ 1:1 NAPT asymmetrical rule """
6483 self.vapi.nat44_forwarding_enable_disable(enable=1)
6484 flags = self.config_flags.NAT_IS_OUT2IN_ONLY
6485 self.nat44_add_static_mapping(self.pg0.remote_ip4, self.nat_addr,
6486 local_port, external_port,
6487 proto=IP_PROTOS.tcp, flags=flags)
6488 flags = self.config_flags.NAT_IS_INSIDE
6489 self.vapi.nat44_interface_add_del_feature(
6490 sw_if_index=self.pg0.sw_if_index,
6491 flags=flags, is_add=1)
6492 self.vapi.nat44_interface_add_del_feature(
6493 sw_if_index=self.pg1.sw_if_index,
6496 # from client to service
6497 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
6498 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
6499 TCP(sport=12345, dport=external_port))
6500 self.pg1.add_stream(p)
6501 self.pg_enable_capture(self.pg_interfaces)
6503 capture = self.pg0.get_capture(1)
6508 self.assertEqual(ip.dst, self.pg0.remote_ip4)
6509 self.assertEqual(tcp.dport, local_port)
6510 self.assert_packet_checksums_valid(p)
6512 self.logger.error(ppp("Unexpected or invalid packet:", p))
6516 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
6517 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6518 ICMP(type=11) / capture[0][IP])
6519 self.pg0.add_stream(p)
6520 self.pg_enable_capture(self.pg_interfaces)
6522 capture = self.pg1.get_capture(1)
6525 self.assertEqual(p[IP].src, self.nat_addr)
6527 self.assertEqual(inner.dst, self.nat_addr)
6528 self.assertEqual(inner[TCPerror].dport, external_port)
6530 self.logger.error(ppp("Unexpected or invalid packet:", p))
6533 # from service back to client
6534 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6535 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6536 TCP(sport=local_port, dport=12345))
6537 self.pg0.add_stream(p)
6538 self.pg_enable_capture(self.pg_interfaces)
6540 capture = self.pg1.get_capture(1)
6545 self.assertEqual(ip.src, self.nat_addr)
6546 self.assertEqual(tcp.sport, external_port)
6547 self.assert_packet_checksums_valid(p)
6549 self.logger.error(ppp("Unexpected or invalid packet:", p))
6553 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
6554 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
6555 ICMP(type=11) / capture[0][IP])
6556 self.pg1.add_stream(p)
6557 self.pg_enable_capture(self.pg_interfaces)
6559 capture = self.pg0.get_capture(1)
6562 self.assertEqual(p[IP].dst, self.pg0.remote_ip4)
6564 self.assertEqual(inner.src, self.pg0.remote_ip4)
6565 self.assertEqual(inner[TCPerror].sport, local_port)
6567 self.logger.error(ppp("Unexpected or invalid packet:", p))
6570 # from client to server (no translation)
6571 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
6572 IP(src=self.pg1.remote_ip4, dst=self.pg0.remote_ip4) /
6573 TCP(sport=12346, dport=local_port))
6574 self.pg1.add_stream(p)
6575 self.pg_enable_capture(self.pg_interfaces)
6577 capture = self.pg0.get_capture(1)
6582 self.assertEqual(ip.dst, self.pg0.remote_ip4)
6583 self.assertEqual(tcp.dport, local_port)
6584 self.assert_packet_checksums_valid(p)
6586 self.logger.error(ppp("Unexpected or invalid packet:", p))
6589 # from service back to client (no translation)
6590 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6591 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6592 TCP(sport=local_port, dport=12346))
6593 self.pg0.add_stream(p)
6594 self.pg_enable_capture(self.pg_interfaces)
6596 capture = self.pg1.get_capture(1)
6601 self.assertEqual(ip.src, self.pg0.remote_ip4)
6602 self.assertEqual(tcp.sport, local_port)
6603 self.assert_packet_checksums_valid(p)
6605 self.logger.error(ppp("Unexpected or invalid packet:", p))
6608 def test_output_feature(self):
6609 """ NAT44 interface output feature (in2out postrouting) """
6610 self.vapi.nat44_forwarding_enable_disable(enable=1)
6611 self.nat44_add_address(self.nat_addr)
6612 self.vapi.nat44_interface_add_del_feature(
6613 sw_if_index=self.pg0.sw_if_index,
6615 self.vapi.nat44_interface_add_del_output_feature(
6617 sw_if_index=self.pg1.sw_if_index)
6620 pkts = self.create_stream_in(self.pg0, self.pg1)
6621 self.pg0.add_stream(pkts)
6622 self.pg_enable_capture(self.pg_interfaces)
6624 capture = self.pg1.get_capture(len(pkts))
6625 self.verify_capture_out(capture, ignore_port=True)
6628 pkts = self.create_stream_out(self.pg1)
6629 self.pg1.add_stream(pkts)
6630 self.pg_enable_capture(self.pg_interfaces)
6632 capture = self.pg0.get_capture(len(pkts))
6633 self.verify_capture_in(capture, self.pg0)
6635 def test_output_feature_stateful_acl(self):
6636 """ NAT44 endpoint-dependent output feature works with stateful ACL """
6637 self.nat44_add_address(self.nat_addr)
6638 self.vapi.nat44_interface_add_del_output_feature(
6639 sw_if_index=self.pg0.sw_if_index,
6640 flags=self.config_flags.NAT_IS_INSIDE,
6642 self.vapi.nat44_interface_add_del_output_feature(
6643 sw_if_index=self.pg1.sw_if_index,
6644 flags=self.config_flags.NAT_IS_OUTSIDE,
6647 # First ensure that the NAT is working sans ACL
6649 # send packets out2in, no sessions yet so packets should drop
6650 pkts_out2in = self.create_stream_out(self.pg1)
6651 self.send_and_assert_no_replies(self.pg1, pkts_out2in)
6653 # send packets into inside intf, ensure received via outside intf
6654 pkts_in2out = self.create_stream_in(self.pg0, self.pg1)
6655 capture = self.send_and_expect(self.pg0, pkts_in2out, self.pg1,
6657 self.verify_capture_out(capture, ignore_port=True)
6659 # send out2in again, with sessions created it should work now
6660 pkts_out2in = self.create_stream_out(self.pg1)
6661 capture = self.send_and_expect(self.pg1, pkts_out2in, self.pg0,
6663 self.verify_capture_in(capture, self.pg0)
6665 # Create an ACL blocking everything
6666 out2in_deny_rule = AclRule(is_permit=0)
6667 out2in_acl = VppAcl(self, rules=[out2in_deny_rule])
6668 out2in_acl.add_vpp_config()
6670 # create an ACL to permit/reflect everything
6671 in2out_reflect_rule = AclRule(is_permit=2)
6672 in2out_acl = VppAcl(self, rules=[in2out_reflect_rule])
6673 in2out_acl.add_vpp_config()
6675 # apply as input acl on interface and confirm it blocks everything
6676 acl_if = VppAclInterface(self, sw_if_index=self.pg1.sw_if_index,
6677 n_input=1, acls=[out2in_acl])
6678 acl_if.add_vpp_config()
6679 self.send_and_assert_no_replies(self.pg1, pkts_out2in)
6682 acl_if.acls = [out2in_acl, in2out_acl]
6683 acl_if.add_vpp_config()
6684 # send in2out to generate ACL state (NAT state was created earlier)
6685 capture = self.send_and_expect(self.pg0, pkts_in2out, self.pg1,
6687 self.verify_capture_out(capture, ignore_port=True)
6689 # send out2in again. ACL state exists so it should work now.
6690 # TCP packets with the syn flag set also need the ack flag
6691 for p in pkts_out2in:
6692 if p.haslayer(TCP) and p[TCP].flags & 0x02:
6693 p[TCP].flags |= 0x10
6694 capture = self.send_and_expect(self.pg1, pkts_out2in, self.pg0,
6696 self.verify_capture_in(capture, self.pg0)
6697 self.logger.info(self.vapi.cli("show trace"))
6699 def test_multiple_vrf(self):
6700 """ Multiple VRF setup """
6701 external_addr = '1.2.3.4'
6706 self.vapi.nat44_forwarding_enable_disable(enable=1)
6707 self.nat44_add_address(self.nat_addr)
6708 flags = self.config_flags.NAT_IS_INSIDE
6709 self.vapi.nat44_interface_add_del_feature(
6710 sw_if_index=self.pg0.sw_if_index,
6712 self.vapi.nat44_interface_add_del_feature(
6713 sw_if_index=self.pg0.sw_if_index,
6714 flags=flags, is_add=1)
6715 self.vapi.nat44_interface_add_del_output_feature(
6717 sw_if_index=self.pg1.sw_if_index)
6718 self.vapi.nat44_interface_add_del_feature(
6719 sw_if_index=self.pg5.sw_if_index,
6721 self.vapi.nat44_interface_add_del_feature(
6722 sw_if_index=self.pg5.sw_if_index,
6723 flags=flags, is_add=1)
6724 self.vapi.nat44_interface_add_del_feature(
6725 sw_if_index=self.pg6.sw_if_index,
6727 flags = self.config_flags.NAT_IS_OUT2IN_ONLY
6728 self.nat44_add_static_mapping(self.pg5.remote_ip4, external_addr,
6729 local_port, external_port, vrf_id=1,
6730 proto=IP_PROTOS.tcp, flags=flags)
6731 self.nat44_add_static_mapping(
6732 self.pg0.remote_ip4,
6733 external_sw_if_index=self.pg0.sw_if_index,
6734 local_port=local_port,
6736 external_port=external_port,
6737 proto=IP_PROTOS.tcp,
6741 # from client to service (both VRF1)
6742 p = (Ether(src=self.pg6.remote_mac, dst=self.pg6.local_mac) /
6743 IP(src=self.pg6.remote_ip4, dst=external_addr) /
6744 TCP(sport=12345, dport=external_port))
6745 self.pg6.add_stream(p)
6746 self.pg_enable_capture(self.pg_interfaces)
6748 capture = self.pg5.get_capture(1)
6753 self.assertEqual(ip.dst, self.pg5.remote_ip4)
6754 self.assertEqual(tcp.dport, local_port)
6755 self.assert_packet_checksums_valid(p)
6757 self.logger.error(ppp("Unexpected or invalid packet:", p))
6760 # from service back to client (both VRF1)
6761 p = (Ether(src=self.pg5.remote_mac, dst=self.pg5.local_mac) /
6762 IP(src=self.pg5.remote_ip4, dst=self.pg6.remote_ip4) /
6763 TCP(sport=local_port, dport=12345))
6764 self.pg5.add_stream(p)
6765 self.pg_enable_capture(self.pg_interfaces)
6767 capture = self.pg6.get_capture(1)
6772 self.assertEqual(ip.src, external_addr)
6773 self.assertEqual(tcp.sport, external_port)
6774 self.assert_packet_checksums_valid(p)
6776 self.logger.error(ppp("Unexpected or invalid packet:", p))
6779 # dynamic NAT from VRF1 to VRF0 (output-feature)
6780 p = (Ether(src=self.pg5.remote_mac, dst=self.pg5.local_mac) /
6781 IP(src=self.pg5.remote_ip4, dst=self.pg1.remote_ip4) /
6782 TCP(sport=2345, dport=22))
6783 self.pg5.add_stream(p)
6784 self.pg_enable_capture(self.pg_interfaces)
6786 capture = self.pg1.get_capture(1)
6791 self.assertEqual(ip.src, self.nat_addr)
6792 self.assert_packet_checksums_valid(p)
6795 self.logger.error(ppp("Unexpected or invalid packet:", p))
6798 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
6799 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
6800 TCP(sport=22, dport=port))
6801 self.pg1.add_stream(p)
6802 self.pg_enable_capture(self.pg_interfaces)
6804 capture = self.pg5.get_capture(1)
6809 self.assertEqual(ip.dst, self.pg5.remote_ip4)
6810 self.assertEqual(tcp.dport, 2345)
6811 self.assert_packet_checksums_valid(p)
6813 self.logger.error(ppp("Unexpected or invalid packet:", p))
6816 # from client VRF1 to service VRF0
6817 p = (Ether(src=self.pg6.remote_mac, dst=self.pg6.local_mac) /
6818 IP(src=self.pg6.remote_ip4, dst=self.pg0.local_ip4) /
6819 TCP(sport=12346, dport=external_port))
6820 self.pg6.add_stream(p)
6821 self.pg_enable_capture(self.pg_interfaces)
6823 capture = self.pg0.get_capture(1)
6828 self.assertEqual(ip.dst, self.pg0.remote_ip4)
6829 self.assertEqual(tcp.dport, local_port)
6830 self.assert_packet_checksums_valid(p)
6832 self.logger.error(ppp("Unexpected or invalid packet:", p))
6835 # from service VRF0 back to client VRF1
6836 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6837 IP(src=self.pg0.remote_ip4, dst=self.pg6.remote_ip4) /
6838 TCP(sport=local_port, dport=12346))
6839 self.pg0.add_stream(p)
6840 self.pg_enable_capture(self.pg_interfaces)
6842 capture = self.pg6.get_capture(1)
6847 self.assertEqual(ip.src, self.pg0.local_ip4)
6848 self.assertEqual(tcp.sport, external_port)
6849 self.assert_packet_checksums_valid(p)
6851 self.logger.error(ppp("Unexpected or invalid packet:", p))
6854 # from client VRF0 to service VRF1
6855 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6856 IP(src=self.pg0.remote_ip4, dst=external_addr) /
6857 TCP(sport=12347, dport=external_port))
6858 self.pg0.add_stream(p)
6859 self.pg_enable_capture(self.pg_interfaces)
6861 capture = self.pg5.get_capture(1)
6866 self.assertEqual(ip.dst, self.pg5.remote_ip4)
6867 self.assertEqual(tcp.dport, local_port)
6868 self.assert_packet_checksums_valid(p)
6870 self.logger.error(ppp("Unexpected or invalid packet:", p))
6873 # from service VRF1 back to client VRF0
6874 p = (Ether(src=self.pg5.remote_mac, dst=self.pg5.local_mac) /
6875 IP(src=self.pg5.remote_ip4, dst=self.pg0.remote_ip4) /
6876 TCP(sport=local_port, dport=12347))
6877 self.pg5.add_stream(p)
6878 self.pg_enable_capture(self.pg_interfaces)
6880 capture = self.pg0.get_capture(1)
6885 self.assertEqual(ip.src, external_addr)
6886 self.assertEqual(tcp.sport, external_port)
6887 self.assert_packet_checksums_valid(p)
6889 self.logger.error(ppp("Unexpected or invalid packet:", p))
6892 # from client to server (both VRF1, no translation)
6893 p = (Ether(src=self.pg6.remote_mac, dst=self.pg6.local_mac) /
6894 IP(src=self.pg6.remote_ip4, dst=self.pg5.remote_ip4) /
6895 TCP(sport=12348, dport=local_port))
6896 self.pg6.add_stream(p)
6897 self.pg_enable_capture(self.pg_interfaces)
6899 capture = self.pg5.get_capture(1)
6904 self.assertEqual(ip.dst, self.pg5.remote_ip4)
6905 self.assertEqual(tcp.dport, local_port)
6906 self.assert_packet_checksums_valid(p)
6908 self.logger.error(ppp("Unexpected or invalid packet:", p))
6911 # from server back to client (both VRF1, no translation)
6912 p = (Ether(src=self.pg5.remote_mac, dst=self.pg5.local_mac) /
6913 IP(src=self.pg5.remote_ip4, dst=self.pg6.remote_ip4) /
6914 TCP(sport=local_port, dport=12348))
6915 self.pg5.add_stream(p)
6916 self.pg_enable_capture(self.pg_interfaces)
6918 capture = self.pg6.get_capture(1)
6923 self.assertEqual(ip.src, self.pg5.remote_ip4)
6924 self.assertEqual(tcp.sport, local_port)
6925 self.assert_packet_checksums_valid(p)
6927 self.logger.error(ppp("Unexpected or invalid packet:", p))
6930 # from client VRF1 to server VRF0 (no translation)
6931 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6932 IP(src=self.pg0.remote_ip4, dst=self.pg6.remote_ip4) /
6933 TCP(sport=local_port, dport=12349))
6934 self.pg0.add_stream(p)
6935 self.pg_enable_capture(self.pg_interfaces)
6937 capture = self.pg6.get_capture(1)
6942 self.assertEqual(ip.src, self.pg0.remote_ip4)
6943 self.assertEqual(tcp.sport, local_port)
6944 self.assert_packet_checksums_valid(p)
6946 self.logger.error(ppp("Unexpected or invalid packet:", p))
6949 # from server VRF0 back to client VRF1 (no translation)
6950 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6951 IP(src=self.pg0.remote_ip4, dst=self.pg6.remote_ip4) /
6952 TCP(sport=local_port, dport=12349))
6953 self.pg0.add_stream(p)
6954 self.pg_enable_capture(self.pg_interfaces)
6956 capture = self.pg6.get_capture(1)
6961 self.assertEqual(ip.src, self.pg0.remote_ip4)
6962 self.assertEqual(tcp.sport, local_port)
6963 self.assert_packet_checksums_valid(p)
6965 self.logger.error(ppp("Unexpected or invalid packet:", p))
6968 # from client VRF0 to server VRF1 (no translation)
6969 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6970 IP(src=self.pg0.remote_ip4, dst=self.pg5.remote_ip4) /
6971 TCP(sport=12344, dport=local_port))
6972 self.pg0.add_stream(p)
6973 self.pg_enable_capture(self.pg_interfaces)
6975 capture = self.pg5.get_capture(1)
6980 self.assertEqual(ip.dst, self.pg5.remote_ip4)
6981 self.assertEqual(tcp.dport, local_port)
6982 self.assert_packet_checksums_valid(p)
6984 self.logger.error(ppp("Unexpected or invalid packet:", p))
6987 # from server VRF1 back to client VRF0 (no translation)
6988 p = (Ether(src=self.pg5.remote_mac, dst=self.pg5.local_mac) /
6989 IP(src=self.pg5.remote_ip4, dst=self.pg0.remote_ip4) /
6990 TCP(sport=local_port, dport=12344))
6991 self.pg5.add_stream(p)
6992 self.pg_enable_capture(self.pg_interfaces)
6994 capture = self.pg0.get_capture(1)
6999 self.assertEqual(ip.src, self.pg5.remote_ip4)
7000 self.assertEqual(tcp.sport, local_port)
7001 self.assert_packet_checksums_valid(p)
7003 self.logger.error(ppp("Unexpected or invalid packet:", p))
7006 @unittest.skipUnless(running_extended_tests, "part of extended tests")
7007 def test_session_timeout(self):
7008 """ NAT44 session timeouts """
7009 self.nat44_add_address(self.nat_addr)
7010 flags = self.config_flags.NAT_IS_INSIDE
7011 self.vapi.nat44_interface_add_del_feature(
7012 sw_if_index=self.pg0.sw_if_index,
7013 flags=flags, is_add=1)
7014 self.vapi.nat44_interface_add_del_feature(
7015 sw_if_index=self.pg1.sw_if_index,
7017 self.vapi.nat_set_timeouts(udp=300, tcp_established=7440,
7018 tcp_transitory=240, icmp=5)
7022 for i in range(0, max_sessions):
7023 src = "10.10.%u.%u" % ((i & 0xFF00) >> 8, i & 0xFF)
7024 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
7025 IP(src=src, dst=self.pg1.remote_ip4) /
7026 ICMP(id=1025, type='echo-request'))
7028 self.pg0.add_stream(pkts)
7029 self.pg_enable_capture(self.pg_interfaces)
7031 self.pg1.get_capture(max_sessions)
7036 for i in range(0, max_sessions):
7037 src = "10.11.%u.%u" % ((i & 0xFF00) >> 8, i & 0xFF)
7038 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
7039 IP(src=src, dst=self.pg1.remote_ip4) /
7040 ICMP(id=1026, type='echo-request'))
7042 self.pg0.add_stream(pkts)
7043 self.pg_enable_capture(self.pg_interfaces)
7045 self.pg1.get_capture(max_sessions)
7048 users = self.vapi.nat44_user_dump()
7050 nsessions = nsessions + user.nsessions
7051 self.assertLess(nsessions, 2 * max_sessions)
7053 @unittest.skipUnless(running_extended_tests, "part of extended tests")
7054 def test_session_rst_timeout(self):
7055 """ NAT44 session RST timeouts """
7056 self.nat44_add_address(self.nat_addr)
7057 flags = self.config_flags.NAT_IS_INSIDE
7058 self.vapi.nat44_interface_add_del_feature(
7059 sw_if_index=self.pg0.sw_if_index,
7060 flags=flags, is_add=1)
7061 self.vapi.nat44_interface_add_del_feature(
7062 sw_if_index=self.pg1.sw_if_index,
7064 self.vapi.nat_set_timeouts(udp=300, tcp_established=7440,
7065 tcp_transitory=5, icmp=60)
7067 self.initiate_tcp_session(self.pg0, self.pg1)
7068 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
7069 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
7070 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
7072 self.pg0.add_stream(p)
7073 self.pg_enable_capture(self.pg_interfaces)
7075 self.pg1.get_capture(1)
7079 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
7080 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
7081 TCP(sport=self.tcp_port_in + 1, dport=self.tcp_external_port + 1,
7083 self.pg0.add_stream(p)
7084 self.pg_enable_capture(self.pg_interfaces)
7086 self.pg1.get_capture(1)
7088 def test_syslog_sess(self):
7089 """ Test syslog session creation and deletion """
7090 self.vapi.syslog_set_filter(
7091 self.SYSLOG_SEVERITY.SYSLOG_API_SEVERITY_INFO)
7092 self.vapi.syslog_set_sender(self.pg2.local_ip4, self.pg2.remote_ip4)
7093 self.nat44_add_address(self.nat_addr)
7094 flags = self.config_flags.NAT_IS_INSIDE
7095 self.vapi.nat44_interface_add_del_feature(
7096 sw_if_index=self.pg0.sw_if_index,
7097 flags=flags, is_add=1)
7098 self.vapi.nat44_interface_add_del_feature(
7099 sw_if_index=self.pg1.sw_if_index,
7102 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
7103 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
7104 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port))
7105 self.pg0.add_stream(p)
7106 self.pg_enable_capture(self.pg_interfaces)
7108 capture = self.pg1.get_capture(1)
7109 self.tcp_port_out = capture[0][TCP].sport
7110 capture = self.pg2.get_capture(1)
7111 self.verify_syslog_sess(capture[0][Raw].load)
7113 self.pg_enable_capture(self.pg_interfaces)
7115 self.nat44_add_address(self.nat_addr, is_add=0)
7116 capture = self.pg2.get_capture(1)
7117 self.verify_syslog_sess(capture[0][Raw].load, False)
7119 def test_ed_users_dump(self):
7120 """ API test - nat44_user_dump """
7121 flags = self.config_flags.NAT_IS_INSIDE
7122 self.vapi.nat44_interface_add_del_feature(
7123 sw_if_index=self.pg0.sw_if_index,
7124 flags=flags, is_add=1)
7125 self.vapi.nat44_interface_add_del_feature(
7126 sw_if_index=self.pg1.sw_if_index,
7128 self.vapi.nat44_forwarding_enable_disable(enable=1)
7130 real_ip = self.pg0.remote_ip4
7131 alias_ip = self.nat_addr
7132 flags = self.config_flags.NAT_IS_ADDR_ONLY
7133 self.vapi.nat44_add_del_static_mapping(is_add=1,
7134 local_ip_address=real_ip,
7135 external_ip_address=alias_ip,
7136 external_sw_if_index=0xFFFFFFFF,
7139 users = self.vapi.nat44_user_dump()
7140 self.assertEqual(len(users), 0)
7142 # in2out - static mapping match
7144 pkts = self.create_stream_out(self.pg1)
7145 self.pg1.add_stream(pkts)
7146 self.pg_enable_capture(self.pg_interfaces)
7148 capture = self.pg0.get_capture(len(pkts))
7149 self.verify_capture_in(capture, self.pg0)
7151 pkts = self.create_stream_in(self.pg0, self.pg1)
7152 self.pg0.add_stream(pkts)
7153 self.pg_enable_capture(self.pg_interfaces)
7155 capture = self.pg1.get_capture(len(pkts))
7156 self.verify_capture_out(capture, same_port=True)
7158 users = self.vapi.nat44_user_dump()
7159 self.assertEqual(len(users), 1)
7160 static_user = users[0]
7161 self.assertEqual(static_user.nstaticsessions, 3)
7162 self.assertEqual(static_user.nsessions, 0)
7164 # in2out - no static mapping match
7166 host0 = self.pg0.remote_hosts[0]
7167 self.pg0.remote_hosts[0] = self.pg0.remote_hosts[1]
7169 pkts = self.create_stream_out(self.pg1,
7170 dst_ip=self.pg0.remote_ip4,
7171 use_inside_ports=True)
7172 self.pg1.add_stream(pkts)
7173 self.pg_enable_capture(self.pg_interfaces)
7175 capture = self.pg0.get_capture(len(pkts))
7176 self.verify_capture_in(capture, self.pg0)
7178 pkts = self.create_stream_in(self.pg0, self.pg1)
7179 self.pg0.add_stream(pkts)
7180 self.pg_enable_capture(self.pg_interfaces)
7182 capture = self.pg1.get_capture(len(pkts))
7183 self.verify_capture_out(capture, nat_ip=self.pg0.remote_ip4,
7186 self.pg0.remote_hosts[0] = host0
7188 users = self.vapi.nat44_user_dump()
7189 self.assertEqual(len(users), 2)
7190 if str(users[0].ip_address) == self.pg0.remote_hosts[0].ip4:
7191 non_static_user = users[1]
7192 static_user = users[0]
7194 non_static_user = users[0]
7195 static_user = users[1]
7196 self.assertEqual(static_user.nstaticsessions, 3)
7197 self.assertEqual(static_user.nsessions, 0)
7198 self.assertEqual(non_static_user.nstaticsessions, 0)
7199 self.assertEqual(non_static_user.nsessions, 3)
7201 users = self.vapi.nat44_user_dump()
7202 self.assertEqual(len(users), 2)
7203 if str(users[0].ip_address) == self.pg0.remote_hosts[0].ip4:
7204 non_static_user = users[1]
7205 static_user = users[0]
7207 non_static_user = users[0]
7208 static_user = users[1]
7209 self.assertEqual(static_user.nstaticsessions, 3)
7210 self.assertEqual(static_user.nsessions, 0)
7211 self.assertEqual(non_static_user.nstaticsessions, 0)
7212 self.assertEqual(non_static_user.nsessions, 3)
7215 self.vapi.nat44_forwarding_enable_disable(enable=0)
7216 flags = self.config_flags.NAT_IS_ADDR_ONLY
7217 self.vapi.nat44_add_del_static_mapping(
7219 local_ip_address=real_ip,
7220 external_ip_address=alias_ip,
7221 external_sw_if_index=0xFFFFFFFF,
7225 super(TestNAT44EndpointDependent, self).tearDown()
7226 if not self.vpp_dead:
7228 self.vapi.cli("clear logging")
7230 def show_commands_at_teardown(self):
7231 self.logger.info(self.vapi.cli("show nat44 addresses"))
7232 self.logger.info(self.vapi.cli("show nat44 interfaces"))
7233 self.logger.info(self.vapi.cli("show nat44 static mappings"))
7234 self.logger.info(self.vapi.cli("show nat44 interface address"))
7235 self.logger.info(self.vapi.cli("show nat44 sessions detail"))
7236 self.logger.info(self.vapi.cli("show nat44 hash tables detail"))
7237 self.logger.info(self.vapi.cli("show nat timeouts"))
7240 class TestNAT44EndpointDependent3(MethodHolder):
7241 """ Endpoint-Dependent mapping and filtering extra test cases """
7243 max_translations = 50
7246 def setUpConstants(cls):
7247 super(TestNAT44EndpointDependent3, cls).setUpConstants()
7248 cls.vpp_cmdline.extend([
7249 "nat", "{", "endpoint-dependent",
7250 "max translations per thread %d" % cls.max_translations,
7255 def setUpClass(cls):
7256 super(TestNAT44EndpointDependent3, cls).setUpClass()
7257 cls.vapi.cli("set log class nat level debug")
7259 cls.nat_addr = '10.0.0.3'
7261 cls.create_pg_interfaces(range(2))
7263 for i in cls.pg_interfaces:
7269 super(TestNAT44EndpointDependent3, self).setUp()
7270 self.vapi.nat_set_timeouts(
7271 udp=1, tcp_established=7440, tcp_transitory=30, icmp=1)
7272 self.nat44_add_address(self.nat_addr)
7273 flags = self.config_flags.NAT_IS_INSIDE
7274 self.vapi.nat44_interface_add_del_feature(
7275 sw_if_index=self.pg0.sw_if_index, flags=flags, is_add=1)
7276 self.vapi.nat44_interface_add_del_feature(
7277 sw_if_index=self.pg1.sw_if_index, is_add=1)
7280 def tearDownClass(cls):
7281 super(TestNAT44EndpointDependent3, cls).tearDownClass()
7283 def init_tcp_session(self, in_if, out_if, sport, ext_dport):
7284 # SYN packet in->out
7285 p = (Ether(src=in_if.remote_mac, dst=in_if.local_mac) /
7286 IP(src=in_if.remote_ip4, dst=out_if.remote_ip4) /
7287 TCP(sport=sport, dport=ext_dport, flags="S"))
7289 self.pg_enable_capture(self.pg_interfaces)
7291 capture = out_if.get_capture(1)
7293 tcp_port_out = p[TCP].sport
7295 # SYN + ACK packet out->in
7296 p = (Ether(src=out_if.remote_mac, dst=out_if.local_mac) /
7297 IP(src=out_if.remote_ip4, dst=self.nat_addr) /
7298 TCP(sport=ext_dport, dport=tcp_port_out, flags="SA"))
7299 out_if.add_stream(p)
7300 self.pg_enable_capture(self.pg_interfaces)
7302 in_if.get_capture(1)
7304 # ACK packet in->out
7305 p = (Ether(src=in_if.remote_mac, dst=in_if.local_mac) /
7306 IP(src=in_if.remote_ip4, dst=out_if.remote_ip4) /
7307 TCP(sport=sport, dport=ext_dport, flags="A"))
7309 self.pg_enable_capture(self.pg_interfaces)
7311 out_if.get_capture(1)
7315 def test_lru_cleanup(self):
7316 """ LRU cleanup algorithm """
7317 tcp_port_out = self.init_tcp_session(self.pg0, self.pg1, 2000, 80)
7319 for i in range(0, self.max_translations - 1):
7320 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
7321 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4, ttl=64) /
7322 UDP(sport=7000+i, dport=80))
7325 self.pg0.add_stream(pkts)
7326 self.pg_enable_capture(self.pg_interfaces)
7328 self.pg1.get_capture(len(pkts))
7329 self.sleep(1.5, "wait for timeouts")
7332 for i in range(0, self.max_translations - 1):
7333 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
7334 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4, ttl=64) /
7335 ICMP(id=8000+i, type='echo-request'))
7338 self.pg0.add_stream(pkts)
7339 self.pg_enable_capture(self.pg_interfaces)
7341 self.pg1.get_capture(len(pkts))
7344 class TestNAT44Out2InDPO(MethodHolder):
7345 """ NAT44 Test Cases using out2in DPO """
7348 def setUpConstants(cls):
7349 super(TestNAT44Out2InDPO, cls).setUpConstants()
7350 cls.vpp_cmdline.extend(["nat", "{", "out2in dpo", "}"])
7353 def setUpClass(cls):
7354 super(TestNAT44Out2InDPO, cls).setUpClass()
7355 cls.vapi.cli("set log class nat level debug")
7357 cls.tcp_port_in = 6303
7358 cls.tcp_port_out = 6303
7359 cls.udp_port_in = 6304
7360 cls.udp_port_out = 6304
7361 cls.icmp_id_in = 6305
7362 cls.icmp_id_out = 6305
7363 cls.nat_addr = '10.0.0.3'
7364 cls.dst_ip4 = '192.168.70.1'
7366 cls.create_pg_interfaces(range(2))
7369 cls.pg0.config_ip4()
7370 cls.pg0.resolve_arp()
7373 cls.pg1.config_ip6()
7374 cls.pg1.resolve_ndp()
7376 r1 = VppIpRoute(cls, "::", 0,
7377 [VppRoutePath(cls.pg1.remote_ip6,
7378 cls.pg1.sw_if_index)],
7383 def tearDownClass(cls):
7384 super(TestNAT44Out2InDPO, cls).tearDownClass()
7386 def configure_xlat(self):
7387 self.dst_ip6_pfx = '1:2:3::'
7388 self.dst_ip6_pfx_n = socket.inet_pton(socket.AF_INET6,
7390 self.dst_ip6_pfx_len = 96
7391 self.src_ip6_pfx = '4:5:6::'
7392 self.src_ip6_pfx_n = socket.inet_pton(socket.AF_INET6,
7394 self.src_ip6_pfx_len = 96
7395 self.vapi.map_add_domain(self.dst_ip6_pfx_n, self.dst_ip6_pfx_len,
7396 self.src_ip6_pfx_n, self.src_ip6_pfx_len,
7397 '\x00\x00\x00\x00', 0)
7399 @unittest.skip('Temporary disabled')
7400 def test_464xlat_ce(self):
7401 """ Test 464XLAT CE with NAT44 """
7403 nat_config = self.vapi.nat_show_config()
7404 self.assertEqual(1, nat_config.out2in_dpo)
7406 self.configure_xlat()
7408 flags = self.config_flags.NAT_IS_INSIDE
7409 self.vapi.nat44_interface_add_del_feature(
7410 sw_if_index=self.pg0.sw_if_index,
7411 flags=flags, is_add=1)
7412 self.vapi.nat44_add_del_address_range(first_ip_address=self.nat_addr_n,
7413 last_ip_address=self.nat_addr_n,
7414 vrf_id=0xFFFFFFFF, is_add=1)
7416 out_src_ip6 = self.compose_ip6(self.dst_ip4, self.dst_ip6_pfx,
7417 self.dst_ip6_pfx_len)
7418 out_dst_ip6 = self.compose_ip6(self.nat_addr, self.src_ip6_pfx,
7419 self.src_ip6_pfx_len)
7422 pkts = self.create_stream_in(self.pg0, self.pg1, self.dst_ip4)
7423 self.pg0.add_stream(pkts)
7424 self.pg_enable_capture(self.pg_interfaces)
7426 capture = self.pg1.get_capture(len(pkts))
7427 self.verify_capture_out_ip6(capture, nat_ip=out_dst_ip6,
7430 pkts = self.create_stream_out_ip6(self.pg1, out_src_ip6,
7432 self.pg1.add_stream(pkts)
7433 self.pg_enable_capture(self.pg_interfaces)
7435 capture = self.pg0.get_capture(len(pkts))
7436 self.verify_capture_in(capture, self.pg0)
7438 self.vapi.nat44_interface_add_del_feature(
7439 sw_if_index=self.pg0.sw_if_index,
7441 self.vapi.nat44_add_del_address_range(
7442 first_ip_address=self.nat_addr_n,
7443 last_ip_address=self.nat_addr_n,
7446 @unittest.skip('Temporary disabled')
7447 def test_464xlat_ce_no_nat(self):
7448 """ Test 464XLAT CE without NAT44 """
7450 self.configure_xlat()
7452 out_src_ip6 = self.compose_ip6(self.dst_ip4, self.dst_ip6_pfx,
7453 self.dst_ip6_pfx_len)
7454 out_dst_ip6 = self.compose_ip6(self.pg0.remote_ip4, self.src_ip6_pfx,
7455 self.src_ip6_pfx_len)
7457 pkts = self.create_stream_in(self.pg0, self.pg1, self.dst_ip4)
7458 self.pg0.add_stream(pkts)
7459 self.pg_enable_capture(self.pg_interfaces)
7461 capture = self.pg1.get_capture(len(pkts))
7462 self.verify_capture_out_ip6(capture, dst_ip=out_src_ip6,
7463 nat_ip=out_dst_ip6, same_port=True)
7465 pkts = self.create_stream_out_ip6(self.pg1, out_src_ip6, out_dst_ip6)
7466 self.pg1.add_stream(pkts)
7467 self.pg_enable_capture(self.pg_interfaces)
7469 capture = self.pg0.get_capture(len(pkts))
7470 self.verify_capture_in(capture, self.pg0)
7473 class TestDeterministicNAT(MethodHolder):
7474 """ Deterministic NAT Test Cases """
7477 def setUpConstants(cls):
7478 super(TestDeterministicNAT, cls).setUpConstants()
7479 cls.vpp_cmdline.extend(["nat", "{", "deterministic", "}"])
7482 def setUpClass(cls):
7483 super(TestDeterministicNAT, cls).setUpClass()
7484 cls.vapi.cli("set log class nat level debug")
7486 cls.tcp_port_in = 6303
7487 cls.tcp_external_port = 6303
7488 cls.udp_port_in = 6304
7489 cls.udp_external_port = 6304
7490 cls.icmp_id_in = 6305
7491 cls.nat_addr = '10.0.0.3'
7493 cls.create_pg_interfaces(range(3))
7494 cls.interfaces = list(cls.pg_interfaces)
7496 for i in cls.interfaces:
7501 cls.pg0.generate_remote_hosts(2)
7502 cls.pg0.configure_ipv4_neighbors()
7505 def tearDownClass(cls):
7506 super(TestDeterministicNAT, cls).tearDownClass()
7508 def create_stream_in(self, in_if, out_if, ttl=64):
7510 Create packet stream for inside network
7512 :param in_if: Inside interface
7513 :param out_if: Outside interface
7514 :param ttl: TTL of generated packets
7518 p = (Ether(dst=in_if.local_mac, src=in_if.remote_mac) /
7519 IP(src=in_if.remote_ip4, dst=out_if.remote_ip4, ttl=ttl) /
7520 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port))
7524 p = (Ether(dst=in_if.local_mac, src=in_if.remote_mac) /
7525 IP(src=in_if.remote_ip4, dst=out_if.remote_ip4, ttl=ttl) /
7526 UDP(sport=self.udp_port_in, dport=self.udp_external_port))
7530 p = (Ether(dst=in_if.local_mac, src=in_if.remote_mac) /
7531 IP(src=in_if.remote_ip4, dst=out_if.remote_ip4, ttl=ttl) /
7532 ICMP(id=self.icmp_id_in, type='echo-request'))
7537 def create_stream_out(self, out_if, dst_ip=None, ttl=64):
7539 Create packet stream for outside network
7541 :param out_if: Outside interface
7542 :param dst_ip: Destination IP address (Default use global NAT address)
7543 :param ttl: TTL of generated packets
7546 dst_ip = self.nat_addr
7549 p = (Ether(dst=out_if.local_mac, src=out_if.remote_mac) /
7550 IP(src=out_if.remote_ip4, dst=dst_ip, ttl=ttl) /
7551 TCP(dport=self.tcp_port_out, sport=self.tcp_external_port))
7555 p = (Ether(dst=out_if.local_mac, src=out_if.remote_mac) /
7556 IP(src=out_if.remote_ip4, dst=dst_ip, ttl=ttl) /
7557 UDP(dport=self.udp_port_out, sport=self.udp_external_port))
7561 p = (Ether(dst=out_if.local_mac, src=out_if.remote_mac) /
7562 IP(src=out_if.remote_ip4, dst=dst_ip, ttl=ttl) /
7563 ICMP(id=self.icmp_external_id, type='echo-reply'))
7568 def verify_capture_out(self, capture, nat_ip=None):
7570 Verify captured packets on outside network
7572 :param capture: Captured packets
7573 :param nat_ip: Translated IP address (Default use global NAT address)
7574 :param same_port: Source port number is not translated (Default False)
7577 nat_ip = self.nat_addr
7578 for packet in capture:
7580 self.assertEqual(packet[IP].src, nat_ip)
7581 if packet.haslayer(TCP):
7582 self.tcp_port_out = packet[TCP].sport
7583 elif packet.haslayer(UDP):
7584 self.udp_port_out = packet[UDP].sport
7586 self.icmp_external_id = packet[ICMP].id
7588 self.logger.error(ppp("Unexpected or invalid packet "
7589 "(outside network):", packet))
7592 def test_deterministic_mode(self):
7593 """ NAT plugin run deterministic mode """
7594 in_addr = '172.16.255.0'
7595 out_addr = '172.17.255.50'
7596 in_addr_t = '172.16.255.20'
7600 nat_config = self.vapi.nat_show_config()
7601 self.assertEqual(1, nat_config.deterministic)
7603 self.vapi.nat_det_add_del_map(is_add=1, in_addr=in_addr,
7604 in_plen=in_plen, out_addr=out_addr,
7607 rep1 = self.vapi.nat_det_forward(in_addr_t)
7608 self.assertEqual(str(rep1.out_addr), out_addr)
7609 rep2 = self.vapi.nat_det_reverse(rep1.out_port_hi, out_addr)
7611 self.assertEqual(str(rep2.in_addr), in_addr_t)
7613 deterministic_mappings = self.vapi.nat_det_map_dump()
7614 self.assertEqual(len(deterministic_mappings), 1)
7615 dsm = deterministic_mappings[0]
7616 self.assertEqual(in_addr, str(dsm.in_addr))
7617 self.assertEqual(in_plen, dsm.in_plen)
7618 self.assertEqual(out_addr, str(dsm.out_addr))
7619 self.assertEqual(out_plen, dsm.out_plen)
7621 self.clear_nat_det()
7622 deterministic_mappings = self.vapi.nat_det_map_dump()
7623 self.assertEqual(len(deterministic_mappings), 0)
7625 def test_set_timeouts(self):
7626 """ Set deterministic NAT timeouts """
7627 timeouts_before = self.vapi.nat_get_timeouts()
7629 self.vapi.nat_set_timeouts(
7630 udp=timeouts_before.udp + 10,
7631 tcp_established=timeouts_before.tcp_established + 10,
7632 tcp_transitory=timeouts_before.tcp_transitory + 10,
7633 icmp=timeouts_before.icmp + 10)
7635 timeouts_after = self.vapi.nat_get_timeouts()
7637 self.assertNotEqual(timeouts_before.udp, timeouts_after.udp)
7638 self.assertNotEqual(timeouts_before.icmp, timeouts_after.icmp)
7639 self.assertNotEqual(timeouts_before.tcp_established,
7640 timeouts_after.tcp_established)
7641 self.assertNotEqual(timeouts_before.tcp_transitory,
7642 timeouts_after.tcp_transitory)
7644 def test_det_in(self):
7645 """ Deterministic NAT translation test (TCP, UDP, ICMP) """
7647 nat_ip = "10.0.0.10"
7649 self.vapi.nat_det_add_del_map(is_add=1, in_addr=self.pg0.remote_ip4,
7651 out_addr=socket.inet_aton(nat_ip),
7654 flags = self.config_flags.NAT_IS_INSIDE
7655 self.vapi.nat44_interface_add_del_feature(
7656 sw_if_index=self.pg0.sw_if_index,
7657 flags=flags, is_add=1)
7658 self.vapi.nat44_interface_add_del_feature(
7659 sw_if_index=self.pg1.sw_if_index,
7663 pkts = self.create_stream_in(self.pg0, self.pg1)
7664 self.pg0.add_stream(pkts)
7665 self.pg_enable_capture(self.pg_interfaces)
7667 capture = self.pg1.get_capture(len(pkts))
7668 self.verify_capture_out(capture, nat_ip)
7671 pkts = self.create_stream_out(self.pg1, nat_ip)
7672 self.pg1.add_stream(pkts)
7673 self.pg_enable_capture(self.pg_interfaces)
7675 capture = self.pg0.get_capture(len(pkts))
7676 self.verify_capture_in(capture, self.pg0)
7679 sessions = self.vapi.nat_det_session_dump(self.pg0.remote_ip4)
7680 self.assertEqual(len(sessions), 3)
7684 self.assertEqual(str(s.ext_addr), self.pg1.remote_ip4)
7685 self.assertEqual(s.in_port, self.tcp_port_in)
7686 self.assertEqual(s.out_port, self.tcp_port_out)
7687 self.assertEqual(s.ext_port, self.tcp_external_port)
7691 self.assertEqual(str(s.ext_addr), self.pg1.remote_ip4)
7692 self.assertEqual(s.in_port, self.udp_port_in)
7693 self.assertEqual(s.out_port, self.udp_port_out)
7694 self.assertEqual(s.ext_port, self.udp_external_port)
7698 self.assertEqual(str(s.ext_addr), self.pg1.remote_ip4)
7699 self.assertEqual(s.in_port, self.icmp_id_in)
7700 self.assertEqual(s.out_port, self.icmp_external_id)
7702 def test_multiple_users(self):
7703 """ Deterministic NAT multiple users """
7705 nat_ip = "10.0.0.10"
7707 external_port = 6303
7709 host0 = self.pg0.remote_hosts[0]
7710 host1 = self.pg0.remote_hosts[1]
7712 self.vapi.nat_det_add_del_map(is_add=1, in_addr=host0.ip4, in_plen=24,
7713 out_addr=socket.inet_aton(nat_ip),
7715 flags = self.config_flags.NAT_IS_INSIDE
7716 self.vapi.nat44_interface_add_del_feature(
7717 sw_if_index=self.pg0.sw_if_index,
7718 flags=flags, is_add=1)
7719 self.vapi.nat44_interface_add_del_feature(
7720 sw_if_index=self.pg1.sw_if_index,
7724 p = (Ether(src=host0.mac, dst=self.pg0.local_mac) /
7725 IP(src=host0.ip4, dst=self.pg1.remote_ip4) /
7726 TCP(sport=port_in, dport=external_port))
7727 self.pg0.add_stream(p)
7728 self.pg_enable_capture(self.pg_interfaces)
7730 capture = self.pg1.get_capture(1)
7735 self.assertEqual(ip.src, nat_ip)
7736 self.assertEqual(ip.dst, self.pg1.remote_ip4)
7737 self.assertEqual(tcp.dport, external_port)
7738 port_out0 = tcp.sport
7740 self.logger.error(ppp("Unexpected or invalid packet:", p))
7744 p = (Ether(src=host1.mac, dst=self.pg0.local_mac) /
7745 IP(src=host1.ip4, dst=self.pg1.remote_ip4) /
7746 TCP(sport=port_in, dport=external_port))
7747 self.pg0.add_stream(p)
7748 self.pg_enable_capture(self.pg_interfaces)
7750 capture = self.pg1.get_capture(1)
7755 self.assertEqual(ip.src, nat_ip)
7756 self.assertEqual(ip.dst, self.pg1.remote_ip4)
7757 self.assertEqual(tcp.dport, external_port)
7758 port_out1 = tcp.sport
7760 self.logger.error(ppp("Unexpected or invalid packet:", p))
7763 dms = self.vapi.nat_det_map_dump()
7764 self.assertEqual(1, len(dms))
7765 self.assertEqual(2, dms[0].ses_num)
7768 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
7769 IP(src=self.pg1.remote_ip4, dst=nat_ip) /
7770 TCP(sport=external_port, dport=port_out0))
7771 self.pg1.add_stream(p)
7772 self.pg_enable_capture(self.pg_interfaces)
7774 capture = self.pg0.get_capture(1)
7779 self.assertEqual(ip.src, self.pg1.remote_ip4)
7780 self.assertEqual(ip.dst, host0.ip4)
7781 self.assertEqual(tcp.dport, port_in)
7782 self.assertEqual(tcp.sport, external_port)
7784 self.logger.error(ppp("Unexpected or invalid packet:", p))
7788 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
7789 IP(src=self.pg1.remote_ip4, dst=nat_ip) /
7790 TCP(sport=external_port, dport=port_out1))
7791 self.pg1.add_stream(p)
7792 self.pg_enable_capture(self.pg_interfaces)
7794 capture = self.pg0.get_capture(1)
7799 self.assertEqual(ip.src, self.pg1.remote_ip4)
7800 self.assertEqual(ip.dst, host1.ip4)
7801 self.assertEqual(tcp.dport, port_in)
7802 self.assertEqual(tcp.sport, external_port)
7804 self.logger.error(ppp("Unexpected or invalid packet", p))
7807 # session close api test
7808 self.vapi.nat_det_close_session_out(socket.inet_aton(nat_ip),
7810 self.pg1.remote_ip4,
7812 dms = self.vapi.nat_det_map_dump()
7813 self.assertEqual(dms[0].ses_num, 1)
7815 self.vapi.nat_det_close_session_in(host0.ip4,
7817 self.pg1.remote_ip4,
7819 dms = self.vapi.nat_det_map_dump()
7820 self.assertEqual(dms[0].ses_num, 0)
7822 def test_tcp_session_close_detection_in(self):
7823 """ Deterministic NAT TCP session close from inside network """
7824 self.vapi.nat_det_add_del_map(is_add=1, in_addr=self.pg0.remote_ip4,
7826 out_addr=socket.inet_aton(self.nat_addr),
7828 flags = self.config_flags.NAT_IS_INSIDE
7829 self.vapi.nat44_interface_add_del_feature(
7830 sw_if_index=self.pg0.sw_if_index,
7831 flags=flags, is_add=1)
7832 self.vapi.nat44_interface_add_del_feature(
7833 sw_if_index=self.pg1.sw_if_index,
7836 self.initiate_tcp_session(self.pg0, self.pg1)
7838 # close the session from inside
7840 # FIN packet in -> out
7841 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
7842 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
7843 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
7845 self.pg0.add_stream(p)
7846 self.pg_enable_capture(self.pg_interfaces)
7848 self.pg1.get_capture(1)
7852 # ACK packet out -> in
7853 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
7854 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
7855 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
7859 # FIN packet out -> in
7860 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
7861 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
7862 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
7866 self.pg1.add_stream(pkts)
7867 self.pg_enable_capture(self.pg_interfaces)
7869 self.pg0.get_capture(2)
7871 # ACK packet in -> out
7872 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
7873 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
7874 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
7876 self.pg0.add_stream(p)
7877 self.pg_enable_capture(self.pg_interfaces)
7879 self.pg1.get_capture(1)
7881 # Check if deterministic NAT44 closed the session
7882 dms = self.vapi.nat_det_map_dump()
7883 self.assertEqual(0, dms[0].ses_num)
7885 self.logger.error("TCP session termination failed")
7888 def test_tcp_session_close_detection_out(self):
7889 """ Deterministic NAT TCP session close from outside network """
7890 self.vapi.nat_det_add_del_map(is_add=1, in_addr=self.pg0.remote_ip4,
7892 out_addr=socket.inet_aton(self.nat_addr),
7894 flags = self.config_flags.NAT_IS_INSIDE
7895 self.vapi.nat44_interface_add_del_feature(
7896 sw_if_index=self.pg0.sw_if_index,
7897 flags=flags, is_add=1)
7898 self.vapi.nat44_interface_add_del_feature(
7899 sw_if_index=self.pg1.sw_if_index,
7902 self.initiate_tcp_session(self.pg0, self.pg1)
7904 # close the session from outside
7906 # FIN packet out -> in
7907 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
7908 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
7909 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
7911 self.pg1.add_stream(p)
7912 self.pg_enable_capture(self.pg_interfaces)
7914 self.pg0.get_capture(1)
7918 # ACK packet in -> out
7919 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
7920 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
7921 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
7925 # ACK packet in -> out
7926 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
7927 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
7928 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
7932 self.pg0.add_stream(pkts)
7933 self.pg_enable_capture(self.pg_interfaces)
7935 self.pg1.get_capture(2)
7937 # ACK packet out -> in
7938 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
7939 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
7940 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
7942 self.pg1.add_stream(p)
7943 self.pg_enable_capture(self.pg_interfaces)
7945 self.pg0.get_capture(1)
7947 # Check if deterministic NAT44 closed the session
7948 dms = self.vapi.nat_det_map_dump()
7949 self.assertEqual(0, dms[0].ses_num)
7951 self.logger.error("TCP session termination failed")
7954 @unittest.skipUnless(running_extended_tests, "part of extended tests")
7955 def test_session_timeout(self):
7956 """ Deterministic NAT session timeouts """
7957 self.vapi.nat_det_add_del_map(is_add=1, in_addr=self.pg0.remote_ip4,
7959 out_addr=socket.inet_aton(self.nat_addr),
7961 flags = self.config_flags.NAT_IS_INSIDE
7962 self.vapi.nat44_interface_add_del_feature(
7963 sw_if_index=self.pg0.sw_if_index,
7964 flags=flags, is_add=1)
7965 self.vapi.nat44_interface_add_del_feature(
7966 sw_if_index=self.pg1.sw_if_index,
7969 self.initiate_tcp_session(self.pg0, self.pg1)
7970 self.vapi.nat_set_timeouts(udp=5, tcp_established=5, tcp_transitory=5,
7972 pkts = self.create_stream_in(self.pg0, self.pg1)
7973 self.pg0.add_stream(pkts)
7974 self.pg_enable_capture(self.pg_interfaces)
7976 capture = self.pg1.get_capture(len(pkts))
7979 dms = self.vapi.nat_det_map_dump()
7980 self.assertEqual(0, dms[0].ses_num)
7982 @unittest.skipUnless(running_extended_tests, "part of extended tests")
7983 def test_session_limit_per_user(self):
7984 """ Deterministic NAT maximum sessions per user limit """
7985 self.vapi.nat_det_add_del_map(is_add=1, in_addr=self.pg0.remote_ip4,
7987 out_addr=socket.inet_aton(self.nat_addr),
7989 flags = self.config_flags.NAT_IS_INSIDE
7990 self.vapi.nat44_interface_add_del_feature(
7991 sw_if_index=self.pg0.sw_if_index,
7992 flags=flags, is_add=1)
7993 self.vapi.nat44_interface_add_del_feature(
7994 sw_if_index=self.pg1.sw_if_index,
7996 self.vapi.set_ipfix_exporter(collector_address=self.pg2.remote_ip4,
7997 src_address=self.pg2.local_ip4,
7999 template_interval=10)
8000 self.vapi.nat_ipfix_enable_disable(domain_id=1, src_port=4739,
8004 for port in range(1025, 2025):
8005 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
8006 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
8007 UDP(sport=port, dport=port))
8010 self.pg0.add_stream(pkts)
8011 self.pg_enable_capture(self.pg_interfaces)
8013 capture = self.pg1.get_capture(len(pkts))
8015 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
8016 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
8017 UDP(sport=3001, dport=3002))
8018 self.pg0.add_stream(p)
8019 self.pg_enable_capture(self.pg_interfaces)
8021 capture = self.pg1.assert_nothing_captured()
8023 # verify ICMP error packet
8024 capture = self.pg0.get_capture(1)
8026 self.assertTrue(p.haslayer(ICMP))
8028 self.assertEqual(icmp.type, 3)
8029 self.assertEqual(icmp.code, 1)
8030 self.assertTrue(icmp.haslayer(IPerror))
8031 inner_ip = icmp[IPerror]
8032 self.assertEqual(inner_ip[UDPerror].sport, 3001)
8033 self.assertEqual(inner_ip[UDPerror].dport, 3002)
8035 dms = self.vapi.nat_det_map_dump()
8037 self.assertEqual(1000, dms[0].ses_num)
8039 # verify IPFIX logging
8040 self.vapi.ipfix_flush()
8042 capture = self.pg2.get_capture(2)
8043 ipfix = IPFIXDecoder()
8044 # first load template
8046 self.assertTrue(p.haslayer(IPFIX))
8047 if p.haslayer(Template):
8048 ipfix.add_template(p.getlayer(Template))
8049 # verify events in data set
8051 if p.haslayer(Data):
8052 data = ipfix.decode_data_set(p.getlayer(Set))
8053 self.verify_ipfix_max_entries_per_user(data,
8055 self.pg0.remote_ip4)
8057 def clear_nat_det(self):
8059 Clear deterministic NAT configuration.
8061 self.vapi.nat_ipfix_enable_disable(domain_id=1, src_port=4739,
8063 self.vapi.nat_set_timeouts(udp=300, tcp_established=7440,
8064 tcp_transitory=240, icmp=60)
8065 deterministic_mappings = self.vapi.nat_det_map_dump()
8066 for dsm in deterministic_mappings:
8067 self.vapi.nat_det_add_del_map(is_add=0, in_addr=dsm.in_addr,
8068 in_plen=dsm.in_plen,
8069 out_addr=dsm.out_addr,
8070 out_plen=dsm.out_plen)
8072 interfaces = self.vapi.nat44_interface_dump()
8073 for intf in interfaces:
8074 self.vapi.nat44_interface_add_del_feature(
8075 sw_if_index=intf.sw_if_index,
8079 super(TestDeterministicNAT, self).tearDown()
8080 if not self.vpp_dead:
8081 self.clear_nat_det()
8083 def show_commands_at_teardown(self):
8084 self.logger.info(self.vapi.cli("show nat44 interfaces"))
8085 self.logger.info(self.vapi.cli("show nat timeouts"))
8087 self.vapi.cli("show nat44 deterministic mappings"))
8089 self.vapi.cli("show nat44 deterministic sessions"))
8092 class TestNAT64(MethodHolder):
8093 """ NAT64 Test Cases """
8096 def setUpConstants(cls):
8097 super(TestNAT64, cls).setUpConstants()
8098 cls.vpp_cmdline.extend(["nat", "{", "nat64 bib hash buckets 128",
8099 "nat64 st hash buckets 256", "}"])
8102 def setUpClass(cls):
8103 super(TestNAT64, cls).setUpClass()
8105 cls.tcp_port_in = 6303
8106 cls.tcp_port_out = 6303
8107 cls.udp_port_in = 6304
8108 cls.udp_port_out = 6304
8109 cls.icmp_id_in = 6305
8110 cls.icmp_id_out = 6305
8111 cls.tcp_external_port = 80
8112 cls.nat_addr = '10.0.0.3'
8113 cls.nat_addr_n = socket.inet_pton(socket.AF_INET, cls.nat_addr)
8115 cls.vrf1_nat_addr = '10.0.10.3'
8116 cls.ipfix_src_port = 4739
8117 cls.ipfix_domain_id = 1
8119 cls.create_pg_interfaces(range(6))
8120 cls.ip6_interfaces = list(cls.pg_interfaces[0:1])
8121 cls.ip6_interfaces.append(cls.pg_interfaces[2])
8122 cls.ip4_interfaces = list(cls.pg_interfaces[1:2])
8124 cls.vapi.ip_table_add_del(is_add=1,
8125 table={'table_id': cls.vrf1_id,
8128 cls.pg_interfaces[2].set_table_ip6(cls.vrf1_id)
8130 cls.pg0.generate_remote_hosts(2)
8132 for i in cls.ip6_interfaces:
8135 i.configure_ipv6_neighbors()
8137 for i in cls.ip4_interfaces:
8143 cls.pg3.config_ip4()
8144 cls.pg3.resolve_arp()
8145 cls.pg3.config_ip6()
8146 cls.pg3.configure_ipv6_neighbors()
8149 cls.pg5.config_ip6()
8152 def tearDownClass(cls):
8153 super(TestNAT64, cls).tearDownClass()
8155 def test_nat64_inside_interface_handles_neighbor_advertisement(self):
8156 """ NAT64 inside interface handles Neighbor Advertisement """
8158 flags = self.config_flags.NAT_IS_INSIDE
8159 self.vapi.nat64_add_del_interface(is_add=1, flags=flags,
8160 sw_if_index=self.pg5.sw_if_index)
8163 ping = (Ether(dst=self.pg5.local_mac, src=self.pg5.remote_mac) /
8164 IPv6(src=self.pg5.remote_ip6, dst=self.pg5.local_ip6) /
8165 ICMPv6EchoRequest())
8167 self.pg5.add_stream(pkts)
8168 self.pg_enable_capture(self.pg_interfaces)
8171 # Wait for Neighbor Solicitation
8172 capture = self.pg5.get_capture(len(pkts))
8175 self.assertEqual(packet[IPv6].src, self.pg5.local_ip6)
8176 self.assertEqual(packet.haslayer(ICMPv6ND_NS), 1)
8177 tgt = packet[ICMPv6ND_NS].tgt
8179 self.logger.error(ppp("Unexpected or invalid packet:", packet))
8182 # Send Neighbor Advertisement
8183 p = (Ether(dst=self.pg5.local_mac, src=self.pg5.remote_mac) /
8184 IPv6(src=self.pg5.remote_ip6, dst=self.pg5.local_ip6) /
8185 ICMPv6ND_NA(tgt=tgt) /
8186 ICMPv6NDOptDstLLAddr(lladdr=self.pg5.remote_mac))
8188 self.pg5.add_stream(pkts)
8189 self.pg_enable_capture(self.pg_interfaces)
8192 # Try to send ping again
8194 self.pg5.add_stream(pkts)
8195 self.pg_enable_capture(self.pg_interfaces)
8198 # Wait for ping reply
8199 capture = self.pg5.get_capture(len(pkts))
8202 self.assertEqual(packet[IPv6].src, self.pg5.local_ip6)
8203 self.assertEqual(packet[IPv6].dst, self.pg5.remote_ip6)
8204 self.assertEqual(packet.haslayer(ICMPv6EchoReply), 1)
8206 self.logger.error(ppp("Unexpected or invalid packet:", packet))
8209 def test_pool(self):
8210 """ Add/delete address to NAT64 pool """
8211 nat_addr = '1.2.3.4'
8213 self.vapi.nat64_add_del_pool_addr_range(start_addr=nat_addr,
8215 vrf_id=0xFFFFFFFF, is_add=1)
8217 addresses = self.vapi.nat64_pool_addr_dump()
8218 self.assertEqual(len(addresses), 1)
8219 self.assertEqual(str(addresses[0].address), nat_addr)
8221 self.vapi.nat64_add_del_pool_addr_range(start_addr=nat_addr,
8223 vrf_id=0xFFFFFFFF, is_add=0)
8225 addresses = self.vapi.nat64_pool_addr_dump()
8226 self.assertEqual(len(addresses), 0)
8228 def test_interface(self):
8229 """ Enable/disable NAT64 feature on the interface """
8230 flags = self.config_flags.NAT_IS_INSIDE
8231 self.vapi.nat64_add_del_interface(is_add=1, flags=flags,
8232 sw_if_index=self.pg0.sw_if_index)
8233 self.vapi.nat64_add_del_interface(is_add=1, flags=0,
8234 sw_if_index=self.pg1.sw_if_index)
8236 interfaces = self.vapi.nat64_interface_dump()
8237 self.assertEqual(len(interfaces), 2)
8240 for intf in interfaces:
8241 if intf.sw_if_index == self.pg0.sw_if_index:
8242 self.assertEqual(intf.flags, self.config_flags.NAT_IS_INSIDE)
8244 elif intf.sw_if_index == self.pg1.sw_if_index:
8245 self.assertEqual(intf.flags, self.config_flags.NAT_IS_OUTSIDE)
8247 self.assertTrue(pg0_found)
8248 self.assertTrue(pg1_found)
8250 features = self.vapi.cli("show interface features pg0")
8251 self.assertIn('nat64-in2out', features)
8252 features = self.vapi.cli("show interface features pg1")
8253 self.assertIn('nat64-out2in', features)
8255 self.vapi.nat64_add_del_interface(is_add=0, flags=flags,
8256 sw_if_index=self.pg0.sw_if_index)
8257 self.vapi.nat64_add_del_interface(is_add=0, flags=flags,
8258 sw_if_index=self.pg1.sw_if_index)
8260 interfaces = self.vapi.nat64_interface_dump()
8261 self.assertEqual(len(interfaces), 0)
8263 def test_static_bib(self):
8264 """ Add/delete static BIB entry """
8265 in_addr = '2001:db8:85a3::8a2e:370:7334'
8266 out_addr = '10.1.1.3'
8269 proto = IP_PROTOS.tcp
8271 self.vapi.nat64_add_del_static_bib(i_addr=in_addr, o_addr=out_addr,
8272 i_port=in_port, o_port=out_port,
8273 proto=proto, vrf_id=0, is_add=1)
8274 bib = self.vapi.nat64_bib_dump(proto=IP_PROTOS.tcp)
8277 if bibe.flags & self.config_flags.NAT_IS_STATIC:
8279 self.assertEqual(str(bibe.i_addr), in_addr)
8280 self.assertEqual(str(bibe.o_addr), out_addr)
8281 self.assertEqual(bibe.i_port, in_port)
8282 self.assertEqual(bibe.o_port, out_port)
8283 self.assertEqual(static_bib_num, 1)
8284 bibs = self.statistics.get_counter('/nat64/total-bibs')
8285 self.assertEqual(bibs[0][0], 1)
8287 self.vapi.nat64_add_del_static_bib(i_addr=in_addr, o_addr=out_addr,
8288 i_port=in_port, o_port=out_port,
8289 proto=proto, vrf_id=0, is_add=0)
8290 bib = self.vapi.nat64_bib_dump(proto=IP_PROTOS.tcp)
8293 if bibe.flags & self.config_flags.NAT_IS_STATIC:
8295 self.assertEqual(static_bib_num, 0)
8296 bibs = self.statistics.get_counter('/nat64/total-bibs')
8297 self.assertEqual(bibs[0][0], 0)
8299 def test_set_timeouts(self):
8300 """ Set NAT64 timeouts """
8301 # verify default values
8302 timeouts = self.vapi.nat_get_timeouts()
8303 self.assertEqual(timeouts.udp, 300)
8304 self.assertEqual(timeouts.icmp, 60)
8305 self.assertEqual(timeouts.tcp_transitory, 240)
8306 self.assertEqual(timeouts.tcp_established, 7440)
8308 # set and verify custom values
8309 self.vapi.nat_set_timeouts(udp=200, tcp_established=7450,
8310 tcp_transitory=250, icmp=30)
8311 timeouts = self.vapi.nat_get_timeouts()
8312 self.assertEqual(timeouts.udp, 200)
8313 self.assertEqual(timeouts.icmp, 30)
8314 self.assertEqual(timeouts.tcp_transitory, 250)
8315 self.assertEqual(timeouts.tcp_established, 7450)
8317 def test_dynamic(self):
8318 """ NAT64 dynamic translation test """
8319 self.tcp_port_in = 6303
8320 self.udp_port_in = 6304
8321 self.icmp_id_in = 6305
8323 ses_num_start = self.nat64_get_ses_num()
8325 self.vapi.nat64_add_del_pool_addr_range(start_addr=self.nat_addr,
8326 end_addr=self.nat_addr,
8329 flags = self.config_flags.NAT_IS_INSIDE
8330 self.vapi.nat64_add_del_interface(is_add=1, flags=flags,
8331 sw_if_index=self.pg0.sw_if_index)
8332 self.vapi.nat64_add_del_interface(is_add=1, flags=0,
8333 sw_if_index=self.pg1.sw_if_index)
8336 tcpn = self.statistics.get_err_counter('/err/nat64-in2out/TCP packets')
8337 udpn = self.statistics.get_err_counter('/err/nat64-in2out/UDP packets')
8338 icmpn = self.statistics.get_err_counter(
8339 '/err/nat64-in2out/ICMP packets')
8340 totaln = self.statistics.get_err_counter(
8341 '/err/nat64-in2out/good in2out packets processed')
8343 pkts = self.create_stream_in_ip6(self.pg0, self.pg1)
8344 self.pg0.add_stream(pkts)
8345 self.pg_enable_capture(self.pg_interfaces)
8347 capture = self.pg1.get_capture(len(pkts))
8348 self.verify_capture_out(capture, nat_ip=self.nat_addr,
8349 dst_ip=self.pg1.remote_ip4)
8351 err = self.statistics.get_err_counter('/err/nat64-in2out/TCP packets')
8352 self.assertEqual(err - tcpn, 1)
8353 err = self.statistics.get_err_counter('/err/nat64-in2out/UDP packets')
8354 self.assertEqual(err - udpn, 1)
8355 err = self.statistics.get_err_counter('/err/nat64-in2out/ICMP packets')
8356 self.assertEqual(err - icmpn, 1)
8357 err = self.statistics.get_err_counter(
8358 '/err/nat64-in2out/good in2out packets processed')
8359 self.assertEqual(err - totaln, 3)
8362 tcpn = self.statistics.get_err_counter('/err/nat64-out2in/TCP packets')
8363 udpn = self.statistics.get_err_counter('/err/nat64-out2in/UDP packets')
8364 icmpn = self.statistics.get_err_counter(
8365 '/err/nat64-out2in/ICMP packets')
8366 totaln = self.statistics.get_err_counter(
8367 '/err/nat64-out2in/good out2in packets processed')
8369 pkts = self.create_stream_out(self.pg1, dst_ip=self.nat_addr)
8370 self.pg1.add_stream(pkts)
8371 self.pg_enable_capture(self.pg_interfaces)
8373 capture = self.pg0.get_capture(len(pkts))
8374 ip = IPv6(src=''.join(['64:ff9b::', self.pg1.remote_ip4]))
8375 self.verify_capture_in_ip6(capture, ip[IPv6].src, self.pg0.remote_ip6)
8377 err = self.statistics.get_err_counter('/err/nat64-out2in/TCP packets')
8378 self.assertEqual(err - tcpn, 2)
8379 err = self.statistics.get_err_counter('/err/nat64-out2in/UDP packets')
8380 self.assertEqual(err - udpn, 1)
8381 err = self.statistics.get_err_counter('/err/nat64-out2in/ICMP packets')
8382 self.assertEqual(err - icmpn, 1)
8383 err = self.statistics.get_err_counter(
8384 '/err/nat64-out2in/good out2in packets processed')
8385 self.assertEqual(err - totaln, 4)
8387 bibs = self.statistics.get_counter('/nat64/total-bibs')
8388 self.assertEqual(bibs[0][0], 3)
8389 sessions = self.statistics.get_counter('/nat64/total-sessions')
8390 self.assertEqual(sessions[0][0], 3)
8393 pkts = self.create_stream_in_ip6(self.pg0, self.pg1)
8394 self.pg0.add_stream(pkts)
8395 self.pg_enable_capture(self.pg_interfaces)
8397 capture = self.pg1.get_capture(len(pkts))
8398 self.verify_capture_out(capture, nat_ip=self.nat_addr,
8399 dst_ip=self.pg1.remote_ip4)
8402 pkts = self.create_stream_out(self.pg1, dst_ip=self.nat_addr)
8403 self.pg1.add_stream(pkts)
8404 self.pg_enable_capture(self.pg_interfaces)
8406 capture = self.pg0.get_capture(len(pkts))
8407 self.verify_capture_in_ip6(capture, ip[IPv6].src, self.pg0.remote_ip6)
8409 ses_num_end = self.nat64_get_ses_num()
8411 self.assertEqual(ses_num_end - ses_num_start, 3)
8413 # tenant with specific VRF
8414 self.vapi.nat64_add_del_pool_addr_range(start_addr=self.vrf1_nat_addr,
8415 end_addr=self.vrf1_nat_addr,
8416 vrf_id=self.vrf1_id, is_add=1)
8417 flags = self.config_flags.NAT_IS_INSIDE
8418 self.vapi.nat64_add_del_interface(is_add=1, flags=flags,
8419 sw_if_index=self.pg2.sw_if_index)
8421 pkts = self.create_stream_in_ip6(self.pg2, self.pg1)
8422 self.pg2.add_stream(pkts)
8423 self.pg_enable_capture(self.pg_interfaces)
8425 capture = self.pg1.get_capture(len(pkts))
8426 self.verify_capture_out(capture, nat_ip=self.vrf1_nat_addr,
8427 dst_ip=self.pg1.remote_ip4)
8429 pkts = self.create_stream_out(self.pg1, dst_ip=self.vrf1_nat_addr)
8430 self.pg1.add_stream(pkts)
8431 self.pg_enable_capture(self.pg_interfaces)
8433 capture = self.pg2.get_capture(len(pkts))
8434 self.verify_capture_in_ip6(capture, ip[IPv6].src, self.pg2.remote_ip6)
8436 def test_static(self):
8437 """ NAT64 static translation test """
8438 self.tcp_port_in = 60303
8439 self.udp_port_in = 60304
8440 self.icmp_id_in = 60305
8441 self.tcp_port_out = 60303
8442 self.udp_port_out = 60304
8443 self.icmp_id_out = 60305
8445 ses_num_start = self.nat64_get_ses_num()
8447 self.vapi.nat64_add_del_pool_addr_range(start_addr=self.nat_addr,
8448 end_addr=self.nat_addr,
8451 flags = self.config_flags.NAT_IS_INSIDE
8452 self.vapi.nat64_add_del_interface(is_add=1, flags=flags,
8453 sw_if_index=self.pg0.sw_if_index)
8454 self.vapi.nat64_add_del_interface(is_add=1, flags=0,
8455 sw_if_index=self.pg1.sw_if_index)
8457 self.vapi.nat64_add_del_static_bib(i_addr=self.pg0.remote_ip6,
8458 o_addr=self.nat_addr,
8459 i_port=self.tcp_port_in,
8460 o_port=self.tcp_port_out,
8461 proto=IP_PROTOS.tcp, vrf_id=0,
8463 self.vapi.nat64_add_del_static_bib(i_addr=self.pg0.remote_ip6,
8464 o_addr=self.nat_addr,
8465 i_port=self.udp_port_in,
8466 o_port=self.udp_port_out,
8467 proto=IP_PROTOS.udp, vrf_id=0,
8469 self.vapi.nat64_add_del_static_bib(i_addr=self.pg0.remote_ip6,
8470 o_addr=self.nat_addr,
8471 i_port=self.icmp_id_in,
8472 o_port=self.icmp_id_out,
8473 proto=IP_PROTOS.icmp, vrf_id=0,
8477 pkts = self.create_stream_in_ip6(self.pg0, self.pg1)
8478 self.pg0.add_stream(pkts)
8479 self.pg_enable_capture(self.pg_interfaces)
8481 capture = self.pg1.get_capture(len(pkts))
8482 self.verify_capture_out(capture, nat_ip=self.nat_addr,
8483 dst_ip=self.pg1.remote_ip4, same_port=True)
8486 pkts = self.create_stream_out(self.pg1, dst_ip=self.nat_addr)
8487 self.pg1.add_stream(pkts)
8488 self.pg_enable_capture(self.pg_interfaces)
8490 capture = self.pg0.get_capture(len(pkts))
8491 ip = IPv6(src=''.join(['64:ff9b::', self.pg1.remote_ip4]))
8492 self.verify_capture_in_ip6(capture, ip[IPv6].src, self.pg0.remote_ip6)
8494 ses_num_end = self.nat64_get_ses_num()
8496 self.assertEqual(ses_num_end - ses_num_start, 3)
8498 @unittest.skipUnless(running_extended_tests, "part of extended tests")
8499 def test_session_timeout(self):
8500 """ NAT64 session timeout """
8501 self.icmp_id_in = 1234
8502 self.vapi.nat64_add_del_pool_addr_range(start_addr=self.nat_addr,
8503 end_addr=self.nat_addr,
8506 flags = self.config_flags.NAT_IS_INSIDE
8507 self.vapi.nat64_add_del_interface(is_add=1, flags=flags,
8508 sw_if_index=self.pg0.sw_if_index)
8509 self.vapi.nat64_add_del_interface(is_add=1, flags=0,
8510 sw_if_index=self.pg1.sw_if_index)
8511 self.vapi.nat_set_timeouts(udp=300, tcp_established=5,
8515 pkts = self.create_stream_in_ip6(self.pg0, self.pg1)
8516 self.pg0.add_stream(pkts)
8517 self.pg_enable_capture(self.pg_interfaces)
8519 capture = self.pg1.get_capture(len(pkts))
8521 ses_num_before_timeout = self.nat64_get_ses_num()
8525 # ICMP and TCP session after timeout
8526 ses_num_after_timeout = self.nat64_get_ses_num()
8527 self.assertEqual(ses_num_before_timeout - ses_num_after_timeout, 2)
8529 def test_icmp_error(self):
8530 """ NAT64 ICMP Error message translation """
8531 self.tcp_port_in = 6303
8532 self.udp_port_in = 6304
8533 self.icmp_id_in = 6305
8535 self.vapi.nat64_add_del_pool_addr_range(start_addr=self.nat_addr,
8536 end_addr=self.nat_addr,
8539 flags = self.config_flags.NAT_IS_INSIDE
8540 self.vapi.nat64_add_del_interface(is_add=1, flags=flags,
8541 sw_if_index=self.pg0.sw_if_index)
8542 self.vapi.nat64_add_del_interface(is_add=1, flags=0,
8543 sw_if_index=self.pg1.sw_if_index)
8545 # send some packets to create sessions
8546 pkts = self.create_stream_in_ip6(self.pg0, self.pg1)
8547 self.pg0.add_stream(pkts)
8548 self.pg_enable_capture(self.pg_interfaces)
8550 capture_ip4 = self.pg1.get_capture(len(pkts))
8551 self.verify_capture_out(capture_ip4,
8552 nat_ip=self.nat_addr,
8553 dst_ip=self.pg1.remote_ip4)
8555 pkts = self.create_stream_out(self.pg1, dst_ip=self.nat_addr)
8556 self.pg1.add_stream(pkts)
8557 self.pg_enable_capture(self.pg_interfaces)
8559 capture_ip6 = self.pg0.get_capture(len(pkts))
8560 ip = IPv6(src=''.join(['64:ff9b::', self.pg1.remote_ip4]))
8561 self.verify_capture_in_ip6(capture_ip6, ip[IPv6].src,
8562 self.pg0.remote_ip6)
8565 pkts = [Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
8566 IPv6(src=self.pg0.remote_ip6, dst=ip[IPv6].src) /
8567 ICMPv6DestUnreach(code=1) /
8568 packet[IPv6] for packet in capture_ip6]
8569 self.pg0.add_stream(pkts)
8570 self.pg_enable_capture(self.pg_interfaces)
8572 capture = self.pg1.get_capture(len(pkts))
8573 for packet in capture:
8575 self.assertEqual(packet[IP].src, self.nat_addr)
8576 self.assertEqual(packet[IP].dst, self.pg1.remote_ip4)
8577 self.assertEqual(packet[ICMP].type, 3)
8578 self.assertEqual(packet[ICMP].code, 13)
8579 inner = packet[IPerror]
8580 self.assertEqual(inner.src, self.pg1.remote_ip4)
8581 self.assertEqual(inner.dst, self.nat_addr)
8582 self.assert_packet_checksums_valid(packet)
8583 if inner.haslayer(TCPerror):
8584 self.assertEqual(inner[TCPerror].dport, self.tcp_port_out)
8585 elif inner.haslayer(UDPerror):
8586 self.assertEqual(inner[UDPerror].dport, self.udp_port_out)
8588 self.assertEqual(inner[ICMPerror].id, self.icmp_id_out)
8590 self.logger.error(ppp("Unexpected or invalid packet:", packet))
8594 pkts = [Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
8595 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
8596 ICMP(type=3, code=13) /
8597 packet[IP] for packet in capture_ip4]
8598 self.pg1.add_stream(pkts)
8599 self.pg_enable_capture(self.pg_interfaces)
8601 capture = self.pg0.get_capture(len(pkts))
8602 for packet in capture:
8604 self.assertEqual(packet[IPv6].src, ip.src)
8605 self.assertEqual(packet[IPv6].dst, self.pg0.remote_ip6)
8606 icmp = packet[ICMPv6DestUnreach]
8607 self.assertEqual(icmp.code, 1)
8608 inner = icmp[IPerror6]
8609 self.assertEqual(inner.src, self.pg0.remote_ip6)
8610 self.assertEqual(inner.dst, ip.src)
8611 self.assert_icmpv6_checksum_valid(packet)
8612 if inner.haslayer(TCPerror):
8613 self.assertEqual(inner[TCPerror].sport, self.tcp_port_in)
8614 elif inner.haslayer(UDPerror):
8615 self.assertEqual(inner[UDPerror].sport, self.udp_port_in)
8617 self.assertEqual(inner[ICMPv6EchoRequest].id,
8620 self.logger.error(ppp("Unexpected or invalid packet:", packet))
8623 def test_hairpinning(self):
8624 """ NAT64 hairpinning """
8626 client = self.pg0.remote_hosts[0]
8627 server = self.pg0.remote_hosts[1]
8628 server_tcp_in_port = 22
8629 server_tcp_out_port = 4022
8630 server_udp_in_port = 23
8631 server_udp_out_port = 4023
8632 client_tcp_in_port = 1234
8633 client_udp_in_port = 1235
8634 client_tcp_out_port = 0
8635 client_udp_out_port = 0
8636 ip = IPv6(src=''.join(['64:ff9b::', self.nat_addr]))
8637 nat_addr_ip6 = ip.src
8639 self.vapi.nat64_add_del_pool_addr_range(start_addr=self.nat_addr,
8640 end_addr=self.nat_addr,
8643 flags = self.config_flags.NAT_IS_INSIDE
8644 self.vapi.nat64_add_del_interface(is_add=1, flags=flags,
8645 sw_if_index=self.pg0.sw_if_index)
8646 self.vapi.nat64_add_del_interface(is_add=1, flags=0,
8647 sw_if_index=self.pg1.sw_if_index)
8649 self.vapi.nat64_add_del_static_bib(i_addr=server.ip6n,
8650 o_addr=self.nat_addr,
8651 i_port=server_tcp_in_port,
8652 o_port=server_tcp_out_port,
8653 proto=IP_PROTOS.tcp, vrf_id=0,
8655 self.vapi.nat64_add_del_static_bib(i_addr=server.ip6n,
8656 o_addr=self.nat_addr,
8657 i_port=server_udp_in_port,
8658 o_port=server_udp_out_port,
8659 proto=IP_PROTOS.udp, vrf_id=0,
8664 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
8665 IPv6(src=client.ip6, dst=nat_addr_ip6) /
8666 TCP(sport=client_tcp_in_port, dport=server_tcp_out_port))
8668 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
8669 IPv6(src=client.ip6, dst=nat_addr_ip6) /
8670 UDP(sport=client_udp_in_port, dport=server_udp_out_port))
8672 self.pg0.add_stream(pkts)
8673 self.pg_enable_capture(self.pg_interfaces)
8675 capture = self.pg0.get_capture(len(pkts))
8676 for packet in capture:
8678 self.assertEqual(packet[IPv6].src, nat_addr_ip6)
8679 self.assertEqual(packet[IPv6].dst, server.ip6)
8680 self.assert_packet_checksums_valid(packet)
8681 if packet.haslayer(TCP):
8682 self.assertNotEqual(packet[TCP].sport, client_tcp_in_port)
8683 self.assertEqual(packet[TCP].dport, server_tcp_in_port)
8684 client_tcp_out_port = packet[TCP].sport
8686 self.assertNotEqual(packet[UDP].sport, client_udp_in_port)
8687 self.assertEqual(packet[UDP].dport, server_udp_in_port)
8688 client_udp_out_port = packet[UDP].sport
8690 self.logger.error(ppp("Unexpected or invalid packet:", packet))
8695 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
8696 IPv6(src=server.ip6, dst=nat_addr_ip6) /
8697 TCP(sport=server_tcp_in_port, dport=client_tcp_out_port))
8699 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
8700 IPv6(src=server.ip6, dst=nat_addr_ip6) /
8701 UDP(sport=server_udp_in_port, dport=client_udp_out_port))
8703 self.pg0.add_stream(pkts)
8704 self.pg_enable_capture(self.pg_interfaces)
8706 capture = self.pg0.get_capture(len(pkts))
8707 for packet in capture:
8709 self.assertEqual(packet[IPv6].src, nat_addr_ip6)
8710 self.assertEqual(packet[IPv6].dst, client.ip6)
8711 self.assert_packet_checksums_valid(packet)
8712 if packet.haslayer(TCP):
8713 self.assertEqual(packet[TCP].sport, server_tcp_out_port)
8714 self.assertEqual(packet[TCP].dport, client_tcp_in_port)
8716 self.assertEqual(packet[UDP].sport, server_udp_out_port)
8717 self.assertEqual(packet[UDP].dport, client_udp_in_port)
8719 self.logger.error(ppp("Unexpected or invalid packet:", packet))
8724 pkts = [Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
8725 IPv6(src=client.ip6, dst=nat_addr_ip6) /
8726 ICMPv6DestUnreach(code=1) /
8727 packet[IPv6] for packet in capture]
8728 self.pg0.add_stream(pkts)
8729 self.pg_enable_capture(self.pg_interfaces)
8731 capture = self.pg0.get_capture(len(pkts))
8732 for packet in capture:
8734 self.assertEqual(packet[IPv6].src, nat_addr_ip6)
8735 self.assertEqual(packet[IPv6].dst, server.ip6)
8736 icmp = packet[ICMPv6DestUnreach]
8737 self.assertEqual(icmp.code, 1)
8738 inner = icmp[IPerror6]
8739 self.assertEqual(inner.src, server.ip6)
8740 self.assertEqual(inner.dst, nat_addr_ip6)
8741 self.assert_packet_checksums_valid(packet)
8742 if inner.haslayer(TCPerror):
8743 self.assertEqual(inner[TCPerror].sport, server_tcp_in_port)
8744 self.assertEqual(inner[TCPerror].dport,
8745 client_tcp_out_port)
8747 self.assertEqual(inner[UDPerror].sport, server_udp_in_port)
8748 self.assertEqual(inner[UDPerror].dport,
8749 client_udp_out_port)
8751 self.logger.error(ppp("Unexpected or invalid packet:", packet))
8754 def test_prefix(self):
8755 """ NAT64 Network-Specific Prefix """
8757 self.vapi.nat64_add_del_pool_addr_range(start_addr=self.nat_addr,
8758 end_addr=self.nat_addr,
8761 flags = self.config_flags.NAT_IS_INSIDE
8762 self.vapi.nat64_add_del_interface(is_add=1, flags=flags,
8763 sw_if_index=self.pg0.sw_if_index)
8764 self.vapi.nat64_add_del_interface(is_add=1, flags=0,
8765 sw_if_index=self.pg1.sw_if_index)
8766 self.vapi.nat64_add_del_pool_addr_range(start_addr=self.vrf1_nat_addr,
8767 end_addr=self.vrf1_nat_addr,
8768 vrf_id=self.vrf1_id, is_add=1)
8769 self.vapi.nat64_add_del_interface(is_add=1, flags=flags,
8770 sw_if_index=self.pg2.sw_if_index)
8773 global_pref64 = "2001:db8::"
8774 global_pref64_len = 32
8775 global_pref64_str = "{}/{}".format(global_pref64, global_pref64_len)
8776 self.vapi.nat64_add_del_prefix(prefix=global_pref64_str, vrf_id=0,
8779 prefix = self.vapi.nat64_prefix_dump()
8780 self.assertEqual(len(prefix), 1)
8781 self.assertEqual(str(prefix[0].prefix), global_pref64_str)
8782 self.assertEqual(prefix[0].vrf_id, 0)
8784 # Add tenant specific prefix
8785 vrf1_pref64 = "2001:db8:122:300::"
8786 vrf1_pref64_len = 56
8787 vrf1_pref64_str = "{}/{}".format(vrf1_pref64, vrf1_pref64_len)
8788 self.vapi.nat64_add_del_prefix(prefix=vrf1_pref64_str,
8789 vrf_id=self.vrf1_id, is_add=1)
8791 prefix = self.vapi.nat64_prefix_dump()
8792 self.assertEqual(len(prefix), 2)
8795 pkts = self.create_stream_in_ip6(self.pg0,
8798 plen=global_pref64_len)
8799 self.pg0.add_stream(pkts)
8800 self.pg_enable_capture(self.pg_interfaces)
8802 capture = self.pg1.get_capture(len(pkts))
8803 self.verify_capture_out(capture, nat_ip=self.nat_addr,
8804 dst_ip=self.pg1.remote_ip4)
8806 pkts = self.create_stream_out(self.pg1, dst_ip=self.nat_addr)
8807 self.pg1.add_stream(pkts)
8808 self.pg_enable_capture(self.pg_interfaces)
8810 capture = self.pg0.get_capture(len(pkts))
8811 dst_ip = self.compose_ip6(self.pg1.remote_ip4,
8814 self.verify_capture_in_ip6(capture, dst_ip, self.pg0.remote_ip6)
8816 # Tenant specific prefix
8817 pkts = self.create_stream_in_ip6(self.pg2,
8820 plen=vrf1_pref64_len)
8821 self.pg2.add_stream(pkts)
8822 self.pg_enable_capture(self.pg_interfaces)
8824 capture = self.pg1.get_capture(len(pkts))
8825 self.verify_capture_out(capture, nat_ip=self.vrf1_nat_addr,
8826 dst_ip=self.pg1.remote_ip4)
8828 pkts = self.create_stream_out(self.pg1, dst_ip=self.vrf1_nat_addr)
8829 self.pg1.add_stream(pkts)
8830 self.pg_enable_capture(self.pg_interfaces)
8832 capture = self.pg2.get_capture(len(pkts))
8833 dst_ip = self.compose_ip6(self.pg1.remote_ip4,
8836 self.verify_capture_in_ip6(capture, dst_ip, self.pg2.remote_ip6)
8838 def test_unknown_proto(self):
8839 """ NAT64 translate packet with unknown protocol """
8841 self.vapi.nat64_add_del_pool_addr_range(start_addr=self.nat_addr,
8842 end_addr=self.nat_addr,
8845 flags = self.config_flags.NAT_IS_INSIDE
8846 self.vapi.nat64_add_del_interface(is_add=1, flags=flags,
8847 sw_if_index=self.pg0.sw_if_index)
8848 self.vapi.nat64_add_del_interface(is_add=1, flags=0,
8849 sw_if_index=self.pg1.sw_if_index)
8850 remote_ip6 = self.compose_ip6(self.pg1.remote_ip4, '64:ff9b::', 96)
8853 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
8854 IPv6(src=self.pg0.remote_ip6, dst=remote_ip6) /
8855 TCP(sport=self.tcp_port_in, dport=20))
8856 self.pg0.add_stream(p)
8857 self.pg_enable_capture(self.pg_interfaces)
8859 p = self.pg1.get_capture(1)
8861 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
8862 IPv6(src=self.pg0.remote_ip6, dst=remote_ip6, nh=47) /
8864 IP(src=self.pg2.local_ip4, dst=self.pg2.remote_ip4) /
8865 TCP(sport=1234, dport=1234))
8866 self.pg0.add_stream(p)
8867 self.pg_enable_capture(self.pg_interfaces)
8869 p = self.pg1.get_capture(1)
8872 self.assertEqual(packet[IP].src, self.nat_addr)
8873 self.assertEqual(packet[IP].dst, self.pg1.remote_ip4)
8874 self.assertEqual(packet.haslayer(GRE), 1)
8875 self.assert_packet_checksums_valid(packet)
8877 self.logger.error(ppp("Unexpected or invalid packet:", packet))
8881 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
8882 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
8884 IP(src=self.pg2.remote_ip4, dst=self.pg2.local_ip4) /
8885 TCP(sport=1234, dport=1234))
8886 self.pg1.add_stream(p)
8887 self.pg_enable_capture(self.pg_interfaces)
8889 p = self.pg0.get_capture(1)
8892 self.assertEqual(packet[IPv6].src, remote_ip6)
8893 self.assertEqual(packet[IPv6].dst, self.pg0.remote_ip6)
8894 self.assertEqual(packet[IPv6].nh, 47)
8896 self.logger.error(ppp("Unexpected or invalid packet:", packet))
8899 def test_hairpinning_unknown_proto(self):
8900 """ NAT64 translate packet with unknown protocol - hairpinning """
8902 client = self.pg0.remote_hosts[0]
8903 server = self.pg0.remote_hosts[1]
8904 server_tcp_in_port = 22
8905 server_tcp_out_port = 4022
8906 client_tcp_in_port = 1234
8907 client_tcp_out_port = 1235
8908 server_nat_ip = "10.0.0.100"
8909 client_nat_ip = "10.0.0.110"
8910 server_nat_ip6 = self.compose_ip6(server_nat_ip, '64:ff9b::', 96)
8911 client_nat_ip6 = self.compose_ip6(client_nat_ip, '64:ff9b::', 96)
8913 self.vapi.nat64_add_del_pool_addr_range(start_addr=server_nat_ip,
8914 end_addr=client_nat_ip,
8917 flags = self.config_flags.NAT_IS_INSIDE
8918 self.vapi.nat64_add_del_interface(is_add=1, flags=flags,
8919 sw_if_index=self.pg0.sw_if_index)
8920 self.vapi.nat64_add_del_interface(is_add=1, flags=0,
8921 sw_if_index=self.pg1.sw_if_index)
8923 self.vapi.nat64_add_del_static_bib(i_addr=server.ip6n,
8924 o_addr=server_nat_ip,
8925 i_port=server_tcp_in_port,
8926 o_port=server_tcp_out_port,
8927 proto=IP_PROTOS.tcp, vrf_id=0,
8930 self.vapi.nat64_add_del_static_bib(i_addr=server.ip6n,
8931 o_addr=server_nat_ip, i_port=0,
8933 proto=IP_PROTOS.gre, vrf_id=0,
8936 self.vapi.nat64_add_del_static_bib(i_addr=client.ip6n,
8937 o_addr=client_nat_ip,
8938 i_port=client_tcp_in_port,
8939 o_port=client_tcp_out_port,
8940 proto=IP_PROTOS.tcp, vrf_id=0,
8944 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
8945 IPv6(src=client.ip6, dst=server_nat_ip6) /
8946 TCP(sport=client_tcp_in_port, dport=server_tcp_out_port))
8947 self.pg0.add_stream(p)
8948 self.pg_enable_capture(self.pg_interfaces)
8950 p = self.pg0.get_capture(1)
8952 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
8953 IPv6(src=client.ip6, dst=server_nat_ip6, nh=IP_PROTOS.gre) /
8955 IP(src=self.pg2.local_ip4, dst=self.pg2.remote_ip4) /
8956 TCP(sport=1234, dport=1234))
8957 self.pg0.add_stream(p)
8958 self.pg_enable_capture(self.pg_interfaces)
8960 p = self.pg0.get_capture(1)
8963 self.assertEqual(packet[IPv6].src, client_nat_ip6)
8964 self.assertEqual(packet[IPv6].dst, server.ip6)
8965 self.assertEqual(packet[IPv6].nh, IP_PROTOS.gre)
8967 self.logger.error(ppp("Unexpected or invalid packet:", packet))
8971 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
8972 IPv6(src=server.ip6, dst=client_nat_ip6, nh=IP_PROTOS.gre) /
8974 IP(src=self.pg2.remote_ip4, dst=self.pg2.local_ip4) /
8975 TCP(sport=1234, dport=1234))
8976 self.pg0.add_stream(p)
8977 self.pg_enable_capture(self.pg_interfaces)
8979 p = self.pg0.get_capture(1)
8982 self.assertEqual(packet[IPv6].src, server_nat_ip6)
8983 self.assertEqual(packet[IPv6].dst, client.ip6)
8984 self.assertEqual(packet[IPv6].nh, IP_PROTOS.gre)
8986 self.logger.error(ppp("Unexpected or invalid packet:", packet))
8989 def test_one_armed_nat64(self):
8990 """ One armed NAT64 """
8992 remote_host_ip6 = self.compose_ip6(self.pg3.remote_ip4,
8996 self.vapi.nat64_add_del_pool_addr_range(start_addr=self.nat_addr,
8997 end_addr=self.nat_addr,
9000 flags = self.config_flags.NAT_IS_INSIDE
9001 self.vapi.nat64_add_del_interface(is_add=1, flags=flags,
9002 sw_if_index=self.pg3.sw_if_index)
9003 self.vapi.nat64_add_del_interface(is_add=1, flags=0,
9004 sw_if_index=self.pg3.sw_if_index)
9007 p = (Ether(src=self.pg3.remote_mac, dst=self.pg3.local_mac) /
9008 IPv6(src=self.pg3.remote_ip6, dst=remote_host_ip6) /
9009 TCP(sport=12345, dport=80))
9010 self.pg3.add_stream(p)
9011 self.pg_enable_capture(self.pg_interfaces)
9013 capture = self.pg3.get_capture(1)
9018 self.assertEqual(ip.src, self.nat_addr)
9019 self.assertEqual(ip.dst, self.pg3.remote_ip4)
9020 self.assertNotEqual(tcp.sport, 12345)
9021 external_port = tcp.sport
9022 self.assertEqual(tcp.dport, 80)
9023 self.assert_packet_checksums_valid(p)
9025 self.logger.error(ppp("Unexpected or invalid packet:", p))
9029 p = (Ether(src=self.pg3.remote_mac, dst=self.pg3.local_mac) /
9030 IP(src=self.pg3.remote_ip4, dst=self.nat_addr) /
9031 TCP(sport=80, dport=external_port))
9032 self.pg3.add_stream(p)
9033 self.pg_enable_capture(self.pg_interfaces)
9035 capture = self.pg3.get_capture(1)
9040 self.assertEqual(ip.src, remote_host_ip6)
9041 self.assertEqual(ip.dst, self.pg3.remote_ip6)
9042 self.assertEqual(tcp.sport, 80)
9043 self.assertEqual(tcp.dport, 12345)
9044 self.assert_packet_checksums_valid(p)
9046 self.logger.error(ppp("Unexpected or invalid packet:", p))
9049 def test_frag_in_order(self):
9050 """ NAT64 translate fragments arriving in order """
9051 self.tcp_port_in = random.randint(1025, 65535)
9053 self.vapi.nat64_add_del_pool_addr_range(start_addr=self.nat_addr,
9054 end_addr=self.nat_addr,
9057 flags = self.config_flags.NAT_IS_INSIDE
9058 self.vapi.nat64_add_del_interface(is_add=1, flags=flags,
9059 sw_if_index=self.pg0.sw_if_index)
9060 self.vapi.nat64_add_del_interface(is_add=1, flags=0,
9061 sw_if_index=self.pg1.sw_if_index)
9065 pkts = self.create_stream_frag_ip6(self.pg0, self.pg1.remote_ip4,
9066 self.tcp_port_in, 20, data)
9067 self.pg0.add_stream(pkts)
9068 self.pg_enable_capture(self.pg_interfaces)
9070 frags = self.pg1.get_capture(len(pkts))
9071 p = self.reass_frags_and_verify(frags,
9073 self.pg1.remote_ip4)
9074 self.assertEqual(p[TCP].dport, 20)
9075 self.assertNotEqual(p[TCP].sport, self.tcp_port_in)
9076 self.tcp_port_out = p[TCP].sport
9077 self.assertEqual(data, p[Raw].load)
9080 data = b"A" * 4 + b"b" * 16 + b"C" * 3
9081 pkts = self.create_stream_frag(self.pg1,
9086 self.pg1.add_stream(pkts)
9087 self.pg_enable_capture(self.pg_interfaces)
9089 frags = self.pg0.get_capture(len(pkts))
9090 self.logger.debug(ppc("Captured:", frags))
9091 src = self.compose_ip6(self.pg1.remote_ip4, '64:ff9b::', 96)
9092 p = self.reass_frags_and_verify_ip6(frags, src, self.pg0.remote_ip6)
9093 self.assertEqual(p[TCP].sport, 20)
9094 self.assertEqual(p[TCP].dport, self.tcp_port_in)
9095 self.assertEqual(data, p[Raw].load)
9097 def test_reass_hairpinning(self):
9098 """ NAT64 fragments hairpinning """
9100 server = self.pg0.remote_hosts[1]
9101 server_in_port = random.randint(1025, 65535)
9102 server_out_port = random.randint(1025, 65535)
9103 client_in_port = random.randint(1025, 65535)
9104 ip = IPv6(src=''.join(['64:ff9b::', self.nat_addr]))
9105 nat_addr_ip6 = ip.src
9107 self.vapi.nat64_add_del_pool_addr_range(start_addr=self.nat_addr,
9108 end_addr=self.nat_addr,
9111 flags = self.config_flags.NAT_IS_INSIDE
9112 self.vapi.nat64_add_del_interface(is_add=1, flags=flags,
9113 sw_if_index=self.pg0.sw_if_index)
9114 self.vapi.nat64_add_del_interface(is_add=1, flags=0,
9115 sw_if_index=self.pg1.sw_if_index)
9117 # add static BIB entry for server
9118 self.vapi.nat64_add_del_static_bib(i_addr=server.ip6n,
9119 o_addr=self.nat_addr,
9120 i_port=server_in_port,
9121 o_port=server_out_port,
9122 proto=IP_PROTOS.tcp, vrf_id=0,
9125 # send packet from host to server
9126 pkts = self.create_stream_frag_ip6(self.pg0,
9131 self.pg0.add_stream(pkts)
9132 self.pg_enable_capture(self.pg_interfaces)
9134 frags = self.pg0.get_capture(len(pkts))
9135 self.logger.debug(ppc("Captured:", frags))
9136 p = self.reass_frags_and_verify_ip6(frags, nat_addr_ip6, server.ip6)
9137 self.assertNotEqual(p[TCP].sport, client_in_port)
9138 self.assertEqual(p[TCP].dport, server_in_port)
9139 self.assertEqual(data, p[Raw].load)
9141 def test_frag_out_of_order(self):
9142 """ NAT64 translate fragments arriving out of order """
9143 self.tcp_port_in = random.randint(1025, 65535)
9145 self.vapi.nat64_add_del_pool_addr_range(start_addr=self.nat_addr,
9146 end_addr=self.nat_addr,
9149 flags = self.config_flags.NAT_IS_INSIDE
9150 self.vapi.nat64_add_del_interface(is_add=1, flags=flags,
9151 sw_if_index=self.pg0.sw_if_index)
9152 self.vapi.nat64_add_del_interface(is_add=1, flags=0,
9153 sw_if_index=self.pg1.sw_if_index)
9157 pkts = self.create_stream_frag_ip6(self.pg0, self.pg1.remote_ip4,
9158 self.tcp_port_in, 20, data)
9160 self.pg0.add_stream(pkts)
9161 self.pg_enable_capture(self.pg_interfaces)
9163 frags = self.pg1.get_capture(len(pkts))
9164 p = self.reass_frags_and_verify(frags,
9166 self.pg1.remote_ip4)
9167 self.assertEqual(p[TCP].dport, 20)
9168 self.assertNotEqual(p[TCP].sport, self.tcp_port_in)
9169 self.tcp_port_out = p[TCP].sport
9170 self.assertEqual(data, p[Raw].load)
9173 data = b"A" * 4 + b"B" * 16 + b"C" * 3
9174 pkts = self.create_stream_frag(self.pg1,
9180 self.pg1.add_stream(pkts)
9181 self.pg_enable_capture(self.pg_interfaces)
9183 frags = self.pg0.get_capture(len(pkts))
9184 src = self.compose_ip6(self.pg1.remote_ip4, '64:ff9b::', 96)
9185 p = self.reass_frags_and_verify_ip6(frags, src, self.pg0.remote_ip6)
9186 self.assertEqual(p[TCP].sport, 20)
9187 self.assertEqual(p[TCP].dport, self.tcp_port_in)
9188 self.assertEqual(data, p[Raw].load)
9190 def test_interface_addr(self):
9191 """ Acquire NAT64 pool addresses from interface """
9192 self.vapi.nat64_add_del_interface_addr(
9194 sw_if_index=self.pg4.sw_if_index)
9196 # no address in NAT64 pool
9197 addresses = self.vapi.nat44_address_dump()
9198 self.assertEqual(0, len(addresses))
9200 # configure interface address and check NAT64 address pool
9201 self.pg4.config_ip4()
9202 addresses = self.vapi.nat64_pool_addr_dump()
9203 self.assertEqual(len(addresses), 1)
9205 self.assertEqual(str(addresses[0].address),
9208 # remove interface address and check NAT64 address pool
9209 self.pg4.unconfig_ip4()
9210 addresses = self.vapi.nat64_pool_addr_dump()
9211 self.assertEqual(0, len(addresses))
9213 @unittest.skipUnless(running_extended_tests, "part of extended tests")
9214 def test_ipfix_max_bibs_sessions(self):
9215 """ IPFIX logging maximum session and BIB entries exceeded """
9218 remote_host_ip6 = self.compose_ip6(self.pg1.remote_ip4,
9222 self.vapi.nat64_add_del_pool_addr_range(start_addr=self.nat_addr,
9223 end_addr=self.nat_addr,
9226 flags = self.config_flags.NAT_IS_INSIDE
9227 self.vapi.nat64_add_del_interface(is_add=1, flags=flags,
9228 sw_if_index=self.pg0.sw_if_index)
9229 self.vapi.nat64_add_del_interface(is_add=1, flags=0,
9230 sw_if_index=self.pg1.sw_if_index)
9234 for i in range(0, max_bibs):
9235 src = "fd01:aa::%x" % (i)
9236 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
9237 IPv6(src=src, dst=remote_host_ip6) /
9238 TCP(sport=12345, dport=80))
9240 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
9241 IPv6(src=src, dst=remote_host_ip6) /
9242 TCP(sport=12345, dport=22))
9244 self.pg0.add_stream(pkts)
9245 self.pg_enable_capture(self.pg_interfaces)
9247 self.pg1.get_capture(max_sessions)
9249 self.vapi.set_ipfix_exporter(collector_address=self.pg3.remote_ip4,
9250 src_address=self.pg3.local_ip4,
9252 template_interval=10)
9253 self.vapi.nat_ipfix_enable_disable(domain_id=self.ipfix_domain_id,
9254 src_port=self.ipfix_src_port,
9257 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
9258 IPv6(src=src, dst=remote_host_ip6) /
9259 TCP(sport=12345, dport=25))
9260 self.pg0.add_stream(p)
9261 self.pg_enable_capture(self.pg_interfaces)
9263 self.pg1.assert_nothing_captured()
9265 self.vapi.ipfix_flush()
9266 capture = self.pg3.get_capture(7)
9267 ipfix = IPFIXDecoder()
9268 # first load template
9270 self.assertTrue(p.haslayer(IPFIX))
9271 self.assertEqual(p[IP].src, self.pg3.local_ip4)
9272 self.assertEqual(p[IP].dst, self.pg3.remote_ip4)
9273 self.assertEqual(p[UDP].sport, self.ipfix_src_port)
9274 self.assertEqual(p[UDP].dport, 4739)
9275 self.assertEqual(p[IPFIX].observationDomainID,
9276 self.ipfix_domain_id)
9277 if p.haslayer(Template):
9278 ipfix.add_template(p.getlayer(Template))
9279 # verify events in data set
9281 if p.haslayer(Data):
9282 data = ipfix.decode_data_set(p.getlayer(Set))
9283 self.verify_ipfix_max_sessions(data, max_sessions)
9285 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
9286 IPv6(src=self.pg0.remote_ip6, dst=remote_host_ip6) /
9287 TCP(sport=12345, dport=80))
9288 self.pg0.add_stream(p)
9289 self.pg_enable_capture(self.pg_interfaces)
9291 self.pg1.assert_nothing_captured()
9293 self.vapi.ipfix_flush()
9294 capture = self.pg3.get_capture(1)
9295 # verify events in data set
9297 self.assertTrue(p.haslayer(IPFIX))
9298 self.assertEqual(p[IP].src, self.pg3.local_ip4)
9299 self.assertEqual(p[IP].dst, self.pg3.remote_ip4)
9300 self.assertEqual(p[UDP].sport, self.ipfix_src_port)
9301 self.assertEqual(p[UDP].dport, 4739)
9302 self.assertEqual(p[IPFIX].observationDomainID,
9303 self.ipfix_domain_id)
9304 if p.haslayer(Data):
9305 data = ipfix.decode_data_set(p.getlayer(Set))
9306 self.verify_ipfix_max_bibs(data, max_bibs)
9308 def test_ipfix_bib_ses(self):
9309 """ IPFIX logging NAT64 BIB/session create and delete events """
9310 self.tcp_port_in = random.randint(1025, 65535)
9311 remote_host_ip6 = self.compose_ip6(self.pg1.remote_ip4,
9315 self.vapi.nat64_add_del_pool_addr_range(start_addr=self.nat_addr,
9316 end_addr=self.nat_addr,
9319 flags = self.config_flags.NAT_IS_INSIDE
9320 self.vapi.nat64_add_del_interface(is_add=1, flags=flags,
9321 sw_if_index=self.pg0.sw_if_index)
9322 self.vapi.nat64_add_del_interface(is_add=1, flags=0,
9323 sw_if_index=self.pg1.sw_if_index)
9324 self.vapi.set_ipfix_exporter(collector_address=self.pg3.remote_ip4,
9325 src_address=self.pg3.local_ip4,
9327 template_interval=10)
9328 self.vapi.nat_ipfix_enable_disable(domain_id=self.ipfix_domain_id,
9329 src_port=self.ipfix_src_port,
9333 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
9334 IPv6(src=self.pg0.remote_ip6, dst=remote_host_ip6) /
9335 TCP(sport=self.tcp_port_in, dport=25))
9336 self.pg0.add_stream(p)
9337 self.pg_enable_capture(self.pg_interfaces)
9339 p = self.pg1.get_capture(1)
9340 self.tcp_port_out = p[0][TCP].sport
9341 self.vapi.ipfix_flush()
9342 capture = self.pg3.get_capture(8)
9343 ipfix = IPFIXDecoder()
9344 # first load template
9346 self.assertTrue(p.haslayer(IPFIX))
9347 self.assertEqual(p[IP].src, self.pg3.local_ip4)
9348 self.assertEqual(p[IP].dst, self.pg3.remote_ip4)
9349 self.assertEqual(p[UDP].sport, self.ipfix_src_port)
9350 self.assertEqual(p[UDP].dport, 4739)
9351 self.assertEqual(p[IPFIX].observationDomainID,
9352 self.ipfix_domain_id)
9353 if p.haslayer(Template):
9354 ipfix.add_template(p.getlayer(Template))
9355 # verify events in data set
9357 if p.haslayer(Data):
9358 data = ipfix.decode_data_set(p.getlayer(Set))
9359 if scapy.compat.orb(data[0][230]) == 10:
9360 self.verify_ipfix_bib(data, 1, self.pg0.remote_ip6)
9361 elif scapy.compat.orb(data[0][230]) == 6:
9362 self.verify_ipfix_nat64_ses(data,
9364 self.pg0.remote_ip6,
9365 self.pg1.remote_ip4,
9368 self.logger.error(ppp("Unexpected or invalid packet: ", p))
9371 self.pg_enable_capture(self.pg_interfaces)
9372 self.vapi.nat64_add_del_pool_addr_range(start_addr=self.nat_addr,
9373 end_addr=self.nat_addr,
9376 self.vapi.ipfix_flush()
9377 capture = self.pg3.get_capture(2)
9378 # verify events in data set
9380 self.assertTrue(p.haslayer(IPFIX))
9381 self.assertEqual(p[IP].src, self.pg3.local_ip4)
9382 self.assertEqual(p[IP].dst, self.pg3.remote_ip4)
9383 self.assertEqual(p[UDP].sport, self.ipfix_src_port)
9384 self.assertEqual(p[UDP].dport, 4739)
9385 self.assertEqual(p[IPFIX].observationDomainID,
9386 self.ipfix_domain_id)
9387 if p.haslayer(Data):
9388 data = ipfix.decode_data_set(p.getlayer(Set))
9389 if scapy.compat.orb(data[0][230]) == 11:
9390 self.verify_ipfix_bib(data, 0, self.pg0.remote_ip6)
9391 elif scapy.compat.orb(data[0][230]) == 7:
9392 self.verify_ipfix_nat64_ses(data,
9394 self.pg0.remote_ip6,
9395 self.pg1.remote_ip4,
9398 self.logger.error(ppp("Unexpected or invalid packet: ", p))
9400 def test_syslog_sess(self):
9401 """ Test syslog session creation and deletion """
9402 self.tcp_port_in = random.randint(1025, 65535)
9403 remote_host_ip6 = self.compose_ip6(self.pg1.remote_ip4,
9407 self.vapi.nat64_add_del_pool_addr_range(start_addr=self.nat_addr,
9408 end_addr=self.nat_addr,
9411 flags = self.config_flags.NAT_IS_INSIDE
9412 self.vapi.nat64_add_del_interface(is_add=1, flags=flags,
9413 sw_if_index=self.pg0.sw_if_index)
9414 self.vapi.nat64_add_del_interface(is_add=1, flags=0,
9415 sw_if_index=self.pg1.sw_if_index)
9416 self.vapi.syslog_set_filter(
9417 self.SYSLOG_SEVERITY.SYSLOG_API_SEVERITY_INFO)
9418 self.vapi.syslog_set_sender(self.pg3.local_ip4, self.pg3.remote_ip4)
9420 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
9421 IPv6(src=self.pg0.remote_ip6, dst=remote_host_ip6) /
9422 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port))
9423 self.pg0.add_stream(p)
9424 self.pg_enable_capture(self.pg_interfaces)
9426 p = self.pg1.get_capture(1)
9427 self.tcp_port_out = p[0][TCP].sport
9428 capture = self.pg3.get_capture(1)
9429 self.verify_syslog_sess(capture[0][Raw].load, is_ip6=True)
9431 self.pg_enable_capture(self.pg_interfaces)
9433 self.vapi.nat64_add_del_pool_addr_range(start_addr=self.nat_addr,
9434 end_addr=self.nat_addr,
9437 capture = self.pg3.get_capture(1)
9438 self.verify_syslog_sess(capture[0][Raw].load, False, True)
9440 def nat64_get_ses_num(self):
9442 Return number of active NAT64 sessions.
9444 st = self.vapi.nat64_st_dump(proto=255)
9447 def clear_nat64(self):
9449 Clear NAT64 configuration.
9451 self.vapi.nat_ipfix_enable_disable(domain_id=self.ipfix_domain_id,
9452 src_port=self.ipfix_src_port,
9454 self.ipfix_src_port = 4739
9455 self.ipfix_domain_id = 1
9457 self.vapi.syslog_set_filter(
9458 self.SYSLOG_SEVERITY.SYSLOG_API_SEVERITY_EMERG)
9460 self.vapi.nat_set_timeouts(udp=300, tcp_established=7440,
9461 tcp_transitory=240, icmp=60)
9463 interfaces = self.vapi.nat64_interface_dump()
9464 for intf in interfaces:
9465 self.vapi.nat64_add_del_interface(is_add=0, flags=intf.flags,
9466 sw_if_index=intf.sw_if_index)
9468 bib = self.vapi.nat64_bib_dump(proto=255)
9470 if bibe.flags & self.config_flags.NAT_IS_STATIC:
9471 self.vapi.nat64_add_del_static_bib(i_addr=bibe.i_addr,
9479 adresses = self.vapi.nat64_pool_addr_dump()
9480 for addr in adresses:
9481 self.vapi.nat64_add_del_pool_addr_range(start_addr=addr.address,
9482 end_addr=addr.address,
9486 prefixes = self.vapi.nat64_prefix_dump()
9487 for prefix in prefixes:
9488 self.vapi.nat64_add_del_prefix(prefix=str(prefix.prefix),
9489 vrf_id=prefix.vrf_id, is_add=0)
9491 bibs = self.statistics.get_counter('/nat64/total-bibs')
9492 self.assertEqual(bibs[0][0], 0)
9493 sessions = self.statistics.get_counter('/nat64/total-sessions')
9494 self.assertEqual(sessions[0][0], 0)
9497 super(TestNAT64, self).tearDown()
9498 if not self.vpp_dead:
9501 def show_commands_at_teardown(self):
9502 self.logger.info(self.vapi.cli("show nat64 pool"))
9503 self.logger.info(self.vapi.cli("show nat64 interfaces"))
9504 self.logger.info(self.vapi.cli("show nat64 prefix"))
9505 self.logger.info(self.vapi.cli("show nat64 bib all"))
9506 self.logger.info(self.vapi.cli("show nat64 session table all"))
9509 if __name__ == '__main__':
9510 unittest.main(testRunner=VppTestRunner)