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_counter('/nat44/in2out/slowpath/tcp')[0]
1518 udpn = self.statistics.get_counter('/nat44/in2out/slowpath/udp')[0]
1519 icmpn = self.statistics.get_counter('/nat44/in2out/slowpath/icmp')[0]
1520 drops = self.statistics.get_counter('/nat44/in2out/slowpath/drops')[0]
1522 pkts = self.create_stream_in(self.pg0, self.pg1)
1523 self.pg0.add_stream(pkts)
1524 self.pg_enable_capture(self.pg_interfaces)
1526 capture = self.pg1.get_capture(len(pkts))
1527 self.verify_capture_out(capture)
1529 if_idx = self.pg0.sw_if_index
1530 cnt = self.statistics.get_counter('/nat44/in2out/slowpath/tcp')[0]
1531 self.assertEqual(cnt[if_idx] - tcpn[if_idx], 2)
1532 cnt = self.statistics.get_counter('/nat44/in2out/slowpath/udp')[0]
1533 self.assertEqual(cnt[if_idx] - udpn[if_idx], 1)
1534 cnt = self.statistics.get_counter('/nat44/in2out/slowpath/icmp')[0]
1535 self.assertEqual(cnt[if_idx] - icmpn[if_idx], 1)
1536 cnt = self.statistics.get_counter('/nat44/in2out/slowpath/drops')[0]
1537 self.assertEqual(cnt[if_idx] - drops[if_idx], 0)
1540 tcpn = self.statistics.get_counter('/nat44/out2in/slowpath/tcp')[0]
1541 udpn = self.statistics.get_counter('/nat44/out2in/slowpath/udp')[0]
1542 icmpn = self.statistics.get_counter('/nat44/out2in/slowpath/icmp')[0]
1543 drops = self.statistics.get_counter('/nat44/out2in/slowpath/drops')[0]
1545 pkts = self.create_stream_out(self.pg1)
1546 self.pg1.add_stream(pkts)
1547 self.pg_enable_capture(self.pg_interfaces)
1549 capture = self.pg0.get_capture(len(pkts))
1550 self.verify_capture_in(capture, self.pg0)
1552 if_idx = self.pg1.sw_if_index
1553 cnt = self.statistics.get_counter('/nat44/out2in/slowpath/tcp')[0]
1554 self.assertEqual(cnt[if_idx] - tcpn[if_idx], 2)
1555 cnt = self.statistics.get_counter('/nat44/out2in/slowpath/udp')[0]
1556 self.assertEqual(cnt[if_idx] - udpn[if_idx], 1)
1557 cnt = self.statistics.get_counter('/nat44/out2in/slowpath/icmp')[0]
1558 self.assertEqual(cnt[if_idx] - icmpn[if_idx], 1)
1559 cnt = self.statistics.get_counter('/nat44/out2in/slowpath/drops')[0]
1560 self.assertEqual(cnt[if_idx] - drops[if_idx], 0)
1562 users = self.statistics.get_counter('/nat44/total-users')
1563 self.assertEqual(users[0][0], 1)
1564 sessions = self.statistics.get_counter('/nat44/total-sessions')
1565 self.assertEqual(sessions[0][0], 3)
1567 def test_dynamic_icmp_errors_in2out_ttl_1(self):
1568 """ NAT44 handling of client packets with TTL=1 """
1570 self.nat44_add_address(self.nat_addr)
1571 flags = self.config_flags.NAT_IS_INSIDE
1572 self.vapi.nat44_interface_add_del_feature(
1573 sw_if_index=self.pg0.sw_if_index,
1574 flags=flags, is_add=1)
1575 self.vapi.nat44_interface_add_del_feature(
1576 sw_if_index=self.pg1.sw_if_index,
1579 # Client side - generate traffic
1580 pkts = self.create_stream_in(self.pg0, self.pg1, ttl=1)
1581 self.pg0.add_stream(pkts)
1582 self.pg_enable_capture(self.pg_interfaces)
1585 # Client side - verify ICMP type 11 packets
1586 capture = self.pg0.get_capture(len(pkts))
1587 self.verify_capture_in_with_icmp_errors(capture, self.pg0)
1589 def test_dynamic_icmp_errors_out2in_ttl_1(self):
1590 """ NAT44 handling of server packets with TTL=1 """
1592 self.nat44_add_address(self.nat_addr)
1593 flags = self.config_flags.NAT_IS_INSIDE
1594 self.vapi.nat44_interface_add_del_feature(
1595 sw_if_index=self.pg0.sw_if_index,
1596 flags=flags, is_add=1)
1597 self.vapi.nat44_interface_add_del_feature(
1598 sw_if_index=self.pg1.sw_if_index,
1601 # Client side - create sessions
1602 pkts = self.create_stream_in(self.pg0, self.pg1)
1603 self.pg0.add_stream(pkts)
1604 self.pg_enable_capture(self.pg_interfaces)
1607 # Server side - generate traffic
1608 capture = self.pg1.get_capture(len(pkts))
1609 self.verify_capture_out(capture)
1610 pkts = self.create_stream_out(self.pg1, ttl=1)
1611 self.pg1.add_stream(pkts)
1612 self.pg_enable_capture(self.pg_interfaces)
1615 # Server side - verify ICMP type 11 packets
1616 capture = self.pg1.get_capture(len(pkts))
1617 self.verify_capture_out_with_icmp_errors(capture,
1618 src_ip=self.pg1.local_ip4)
1620 def test_dynamic_icmp_errors_in2out_ttl_2(self):
1621 """ NAT44 handling of error responses to client packets with TTL=2 """
1623 self.nat44_add_address(self.nat_addr)
1624 flags = self.config_flags.NAT_IS_INSIDE
1625 self.vapi.nat44_interface_add_del_feature(
1626 sw_if_index=self.pg0.sw_if_index,
1627 flags=flags, is_add=1)
1628 self.vapi.nat44_interface_add_del_feature(
1629 sw_if_index=self.pg1.sw_if_index,
1632 # Client side - generate traffic
1633 pkts = self.create_stream_in(self.pg0, self.pg1, ttl=2)
1634 self.pg0.add_stream(pkts)
1635 self.pg_enable_capture(self.pg_interfaces)
1638 # Server side - simulate ICMP type 11 response
1639 capture = self.pg1.get_capture(len(pkts))
1640 pkts = [Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
1641 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
1642 ICMP(type=11) / packet[IP] for packet in capture]
1643 self.pg1.add_stream(pkts)
1644 self.pg_enable_capture(self.pg_interfaces)
1647 # Client side - verify ICMP type 11 packets
1648 capture = self.pg0.get_capture(len(pkts))
1649 self.verify_capture_in_with_icmp_errors(capture, self.pg0)
1651 def test_dynamic_icmp_errors_out2in_ttl_2(self):
1652 """ NAT44 handling of error responses to server packets with TTL=2 """
1654 self.nat44_add_address(self.nat_addr)
1655 flags = self.config_flags.NAT_IS_INSIDE
1656 self.vapi.nat44_interface_add_del_feature(
1657 sw_if_index=self.pg0.sw_if_index,
1658 flags=flags, is_add=1)
1659 self.vapi.nat44_interface_add_del_feature(
1660 sw_if_index=self.pg1.sw_if_index,
1663 # Client side - create sessions
1664 pkts = self.create_stream_in(self.pg0, self.pg1)
1665 self.pg0.add_stream(pkts)
1666 self.pg_enable_capture(self.pg_interfaces)
1669 # Server side - generate traffic
1670 capture = self.pg1.get_capture(len(pkts))
1671 self.verify_capture_out(capture)
1672 pkts = self.create_stream_out(self.pg1, ttl=2)
1673 self.pg1.add_stream(pkts)
1674 self.pg_enable_capture(self.pg_interfaces)
1677 # Client side - simulate ICMP type 11 response
1678 capture = self.pg0.get_capture(len(pkts))
1679 pkts = [Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
1680 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
1681 ICMP(type=11) / packet[IP] for packet in capture]
1682 self.pg0.add_stream(pkts)
1683 self.pg_enable_capture(self.pg_interfaces)
1686 # Server side - verify ICMP type 11 packets
1687 capture = self.pg1.get_capture(len(pkts))
1688 self.verify_capture_out_with_icmp_errors(capture)
1690 def test_ping_out_interface_from_outside(self):
1691 """ Ping NAT44 out interface from outside network """
1693 self.nat44_add_address(self.nat_addr)
1694 flags = self.config_flags.NAT_IS_INSIDE
1695 self.vapi.nat44_interface_add_del_feature(
1696 sw_if_index=self.pg0.sw_if_index,
1697 flags=flags, is_add=1)
1698 self.vapi.nat44_interface_add_del_feature(
1699 sw_if_index=self.pg1.sw_if_index,
1702 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
1703 IP(src=self.pg1.remote_ip4, dst=self.pg1.local_ip4) /
1704 ICMP(id=self.icmp_id_out, type='echo-request'))
1706 self.pg1.add_stream(pkts)
1707 self.pg_enable_capture(self.pg_interfaces)
1709 capture = self.pg1.get_capture(len(pkts))
1712 self.assertEqual(packet[IP].src, self.pg1.local_ip4)
1713 self.assertEqual(packet[IP].dst, self.pg1.remote_ip4)
1714 self.assertEqual(packet[ICMP].id, self.icmp_id_in)
1715 self.assertEqual(packet[ICMP].type, 0) # echo reply
1717 self.logger.error(ppp("Unexpected or invalid packet "
1718 "(outside network):", packet))
1721 def test_ping_internal_host_from_outside(self):
1722 """ Ping internal host from outside network """
1724 self.nat44_add_static_mapping(self.pg0.remote_ip4, self.nat_addr)
1725 flags = self.config_flags.NAT_IS_INSIDE
1726 self.vapi.nat44_interface_add_del_feature(
1727 sw_if_index=self.pg0.sw_if_index,
1728 flags=flags, is_add=1)
1729 self.vapi.nat44_interface_add_del_feature(
1730 sw_if_index=self.pg1.sw_if_index,
1734 pkt = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
1735 IP(src=self.pg1.remote_ip4, dst=self.nat_addr, ttl=64) /
1736 ICMP(id=self.icmp_id_out, type='echo-request'))
1737 self.pg1.add_stream(pkt)
1738 self.pg_enable_capture(self.pg_interfaces)
1740 capture = self.pg0.get_capture(1)
1741 self.verify_capture_in(capture, self.pg0)
1742 self.assert_equal(capture[0][IP].proto, IP_PROTOS.icmp)
1745 pkt = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
1746 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4, ttl=64) /
1747 ICMP(id=self.icmp_id_in, type='echo-reply'))
1748 self.pg0.add_stream(pkt)
1749 self.pg_enable_capture(self.pg_interfaces)
1751 capture = self.pg1.get_capture(1)
1752 self.verify_capture_out(capture, same_port=True)
1753 self.assert_equal(capture[0][IP].proto, IP_PROTOS.icmp)
1755 def test_forwarding(self):
1756 """ NAT44 forwarding test """
1758 flags = self.config_flags.NAT_IS_INSIDE
1759 self.vapi.nat44_interface_add_del_feature(
1760 sw_if_index=self.pg0.sw_if_index,
1761 flags=flags, is_add=1)
1762 self.vapi.nat44_interface_add_del_feature(
1763 sw_if_index=self.pg1.sw_if_index,
1765 self.vapi.nat44_forwarding_enable_disable(enable=1)
1767 real_ip = self.pg0.remote_ip4
1768 alias_ip = self.nat_addr
1769 flags = self.config_flags.NAT_IS_ADDR_ONLY
1770 self.vapi.nat44_add_del_static_mapping(is_add=1,
1771 local_ip_address=real_ip,
1772 external_ip_address=alias_ip,
1773 external_sw_if_index=0xFFFFFFFF,
1777 # static mapping match
1779 pkts = self.create_stream_out(self.pg1)
1780 self.pg1.add_stream(pkts)
1781 self.pg_enable_capture(self.pg_interfaces)
1783 capture = self.pg0.get_capture(len(pkts))
1784 self.verify_capture_in(capture, self.pg0)
1786 pkts = self.create_stream_in(self.pg0, self.pg1)
1787 self.pg0.add_stream(pkts)
1788 self.pg_enable_capture(self.pg_interfaces)
1790 capture = self.pg1.get_capture(len(pkts))
1791 self.verify_capture_out(capture, same_port=True)
1793 # no static mapping match
1795 host0 = self.pg0.remote_hosts[0]
1796 self.pg0.remote_hosts[0] = self.pg0.remote_hosts[1]
1798 pkts = self.create_stream_out(self.pg1,
1799 dst_ip=self.pg0.remote_ip4,
1800 use_inside_ports=True)
1801 self.pg1.add_stream(pkts)
1802 self.pg_enable_capture(self.pg_interfaces)
1804 capture = self.pg0.get_capture(len(pkts))
1805 self.verify_capture_in(capture, self.pg0)
1807 pkts = self.create_stream_in(self.pg0, self.pg1)
1808 self.pg0.add_stream(pkts)
1809 self.pg_enable_capture(self.pg_interfaces)
1811 capture = self.pg1.get_capture(len(pkts))
1812 self.verify_capture_out(capture, nat_ip=self.pg0.remote_ip4,
1815 self.pg0.remote_hosts[0] = host0
1818 self.vapi.nat44_forwarding_enable_disable(enable=0)
1819 flags = self.config_flags.NAT_IS_ADDR_ONLY
1820 self.vapi.nat44_add_del_static_mapping(
1822 local_ip_address=real_ip,
1823 external_ip_address=alias_ip,
1824 external_sw_if_index=0xFFFFFFFF,
1827 def test_static_in(self):
1828 """ 1:1 NAT initialized from inside network """
1830 nat_ip = "10.0.0.10"
1831 self.tcp_port_out = 6303
1832 self.udp_port_out = 6304
1833 self.icmp_id_out = 6305
1835 self.nat44_add_static_mapping(self.pg0.remote_ip4, nat_ip)
1836 flags = self.config_flags.NAT_IS_INSIDE
1837 self.vapi.nat44_interface_add_del_feature(
1838 sw_if_index=self.pg0.sw_if_index,
1839 flags=flags, is_add=1)
1840 self.vapi.nat44_interface_add_del_feature(
1841 sw_if_index=self.pg1.sw_if_index,
1843 sm = self.vapi.nat44_static_mapping_dump()
1844 self.assertEqual(len(sm), 1)
1845 self.assertEqual(sm[0].tag, '')
1846 self.assertEqual(sm[0].protocol, 0)
1847 self.assertEqual(sm[0].local_port, 0)
1848 self.assertEqual(sm[0].external_port, 0)
1851 pkts = self.create_stream_in(self.pg0, self.pg1)
1852 self.pg0.add_stream(pkts)
1853 self.pg_enable_capture(self.pg_interfaces)
1855 capture = self.pg1.get_capture(len(pkts))
1856 self.verify_capture_out(capture, nat_ip, True)
1859 pkts = self.create_stream_out(self.pg1, nat_ip)
1860 self.pg1.add_stream(pkts)
1861 self.pg_enable_capture(self.pg_interfaces)
1863 capture = self.pg0.get_capture(len(pkts))
1864 self.verify_capture_in(capture, self.pg0)
1866 def test_static_out(self):
1867 """ 1:1 NAT initialized from outside network """
1869 nat_ip = "10.0.0.20"
1870 self.tcp_port_out = 6303
1871 self.udp_port_out = 6304
1872 self.icmp_id_out = 6305
1875 self.nat44_add_static_mapping(self.pg0.remote_ip4, nat_ip, tag=tag)
1876 flags = self.config_flags.NAT_IS_INSIDE
1877 self.vapi.nat44_interface_add_del_feature(
1878 sw_if_index=self.pg0.sw_if_index,
1879 flags=flags, is_add=1)
1880 self.vapi.nat44_interface_add_del_feature(
1881 sw_if_index=self.pg1.sw_if_index,
1883 sm = self.vapi.nat44_static_mapping_dump()
1884 self.assertEqual(len(sm), 1)
1885 self.assertEqual(sm[0].tag, tag)
1888 pkts = self.create_stream_out(self.pg1, nat_ip)
1889 self.pg1.add_stream(pkts)
1890 self.pg_enable_capture(self.pg_interfaces)
1892 capture = self.pg0.get_capture(len(pkts))
1893 self.verify_capture_in(capture, self.pg0)
1896 pkts = self.create_stream_in(self.pg0, self.pg1)
1897 self.pg0.add_stream(pkts)
1898 self.pg_enable_capture(self.pg_interfaces)
1900 capture = self.pg1.get_capture(len(pkts))
1901 self.verify_capture_out(capture, nat_ip, True)
1903 def test_static_with_port_in(self):
1904 """ 1:1 NAPT initialized from inside network """
1906 self.tcp_port_out = 3606
1907 self.udp_port_out = 3607
1908 self.icmp_id_out = 3608
1910 self.nat44_add_address(self.nat_addr)
1911 self.nat44_add_static_mapping(self.pg0.remote_ip4, self.nat_addr,
1912 self.tcp_port_in, self.tcp_port_out,
1913 proto=IP_PROTOS.tcp)
1914 self.nat44_add_static_mapping(self.pg0.remote_ip4, self.nat_addr,
1915 self.udp_port_in, self.udp_port_out,
1916 proto=IP_PROTOS.udp)
1917 self.nat44_add_static_mapping(self.pg0.remote_ip4, self.nat_addr,
1918 self.icmp_id_in, self.icmp_id_out,
1919 proto=IP_PROTOS.icmp)
1920 flags = self.config_flags.NAT_IS_INSIDE
1921 self.vapi.nat44_interface_add_del_feature(
1922 sw_if_index=self.pg0.sw_if_index,
1923 flags=flags, is_add=1)
1924 self.vapi.nat44_interface_add_del_feature(
1925 sw_if_index=self.pg1.sw_if_index,
1929 pkts = self.create_stream_in(self.pg0, self.pg1)
1930 self.pg0.add_stream(pkts)
1931 self.pg_enable_capture(self.pg_interfaces)
1933 capture = self.pg1.get_capture(len(pkts))
1934 self.verify_capture_out(capture)
1937 pkts = self.create_stream_out(self.pg1)
1938 self.pg1.add_stream(pkts)
1939 self.pg_enable_capture(self.pg_interfaces)
1941 capture = self.pg0.get_capture(len(pkts))
1942 self.verify_capture_in(capture, self.pg0)
1944 def test_static_with_port_out(self):
1945 """ 1:1 NAPT initialized from outside network """
1947 self.tcp_port_out = 30606
1948 self.udp_port_out = 30607
1949 self.icmp_id_out = 30608
1951 self.nat44_add_address(self.nat_addr)
1952 self.nat44_add_static_mapping(self.pg0.remote_ip4, self.nat_addr,
1953 self.tcp_port_in, self.tcp_port_out,
1954 proto=IP_PROTOS.tcp)
1955 self.nat44_add_static_mapping(self.pg0.remote_ip4, self.nat_addr,
1956 self.udp_port_in, self.udp_port_out,
1957 proto=IP_PROTOS.udp)
1958 self.nat44_add_static_mapping(self.pg0.remote_ip4, self.nat_addr,
1959 self.icmp_id_in, self.icmp_id_out,
1960 proto=IP_PROTOS.icmp)
1961 flags = self.config_flags.NAT_IS_INSIDE
1962 self.vapi.nat44_interface_add_del_feature(
1963 sw_if_index=self.pg0.sw_if_index,
1964 flags=flags, is_add=1)
1965 self.vapi.nat44_interface_add_del_feature(
1966 sw_if_index=self.pg1.sw_if_index,
1970 pkts = self.create_stream_out(self.pg1)
1971 self.pg1.add_stream(pkts)
1972 self.pg_enable_capture(self.pg_interfaces)
1974 capture = self.pg0.get_capture(len(pkts))
1975 self.verify_capture_in(capture, self.pg0)
1978 pkts = self.create_stream_in(self.pg0, self.pg1)
1979 self.pg0.add_stream(pkts)
1980 self.pg_enable_capture(self.pg_interfaces)
1982 capture = self.pg1.get_capture(len(pkts))
1983 self.verify_capture_out(capture)
1985 def test_static_vrf_aware(self):
1986 """ 1:1 NAT VRF awareness """
1988 nat_ip1 = "10.0.0.30"
1989 nat_ip2 = "10.0.0.40"
1990 self.tcp_port_out = 6303
1991 self.udp_port_out = 6304
1992 self.icmp_id_out = 6305
1994 self.nat44_add_static_mapping(self.pg4.remote_ip4, nat_ip1,
1996 self.nat44_add_static_mapping(self.pg0.remote_ip4, nat_ip2,
1998 flags = self.config_flags.NAT_IS_INSIDE
1999 self.vapi.nat44_interface_add_del_feature(
2000 sw_if_index=self.pg3.sw_if_index,
2002 self.vapi.nat44_interface_add_del_feature(
2003 sw_if_index=self.pg0.sw_if_index,
2004 flags=flags, is_add=1)
2005 self.vapi.nat44_interface_add_del_feature(
2006 sw_if_index=self.pg4.sw_if_index,
2007 flags=flags, is_add=1)
2009 # inside interface VRF match NAT44 static mapping VRF
2010 pkts = self.create_stream_in(self.pg4, self.pg3)
2011 self.pg4.add_stream(pkts)
2012 self.pg_enable_capture(self.pg_interfaces)
2014 capture = self.pg3.get_capture(len(pkts))
2015 self.verify_capture_out(capture, nat_ip1, True)
2017 # inside interface VRF don't match NAT44 static mapping VRF (packets
2019 pkts = self.create_stream_in(self.pg0, self.pg3)
2020 self.pg0.add_stream(pkts)
2021 self.pg_enable_capture(self.pg_interfaces)
2023 self.pg3.assert_nothing_captured()
2025 def test_dynamic_to_static(self):
2026 """ Switch from dynamic translation to 1:1NAT """
2027 nat_ip = "10.0.0.10"
2028 self.tcp_port_out = 6303
2029 self.udp_port_out = 6304
2030 self.icmp_id_out = 6305
2032 self.nat44_add_address(self.nat_addr)
2033 flags = self.config_flags.NAT_IS_INSIDE
2034 self.vapi.nat44_interface_add_del_feature(
2035 sw_if_index=self.pg0.sw_if_index,
2036 flags=flags, is_add=1)
2037 self.vapi.nat44_interface_add_del_feature(
2038 sw_if_index=self.pg1.sw_if_index,
2042 pkts = self.create_stream_in(self.pg0, self.pg1)
2043 self.pg0.add_stream(pkts)
2044 self.pg_enable_capture(self.pg_interfaces)
2046 capture = self.pg1.get_capture(len(pkts))
2047 self.verify_capture_out(capture)
2050 self.nat44_add_static_mapping(self.pg0.remote_ip4, nat_ip)
2051 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4, 0)
2052 self.assertEqual(len(sessions), 0)
2053 pkts = self.create_stream_in(self.pg0, self.pg1)
2054 self.pg0.add_stream(pkts)
2055 self.pg_enable_capture(self.pg_interfaces)
2057 capture = self.pg1.get_capture(len(pkts))
2058 self.verify_capture_out(capture, nat_ip, True)
2060 def test_identity_nat(self):
2061 """ Identity NAT """
2062 flags = self.config_flags.NAT_IS_ADDR_ONLY
2063 self.vapi.nat44_add_del_identity_mapping(
2064 ip_address=self.pg0.remote_ip4, sw_if_index=0xFFFFFFFF,
2065 flags=flags, is_add=1)
2066 flags = self.config_flags.NAT_IS_INSIDE
2067 self.vapi.nat44_interface_add_del_feature(
2068 sw_if_index=self.pg0.sw_if_index,
2069 flags=flags, is_add=1)
2070 self.vapi.nat44_interface_add_del_feature(
2071 sw_if_index=self.pg1.sw_if_index,
2074 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
2075 IP(src=self.pg1.remote_ip4, dst=self.pg0.remote_ip4) /
2076 TCP(sport=12345, dport=56789))
2077 self.pg1.add_stream(p)
2078 self.pg_enable_capture(self.pg_interfaces)
2080 capture = self.pg0.get_capture(1)
2085 self.assertEqual(ip.dst, self.pg0.remote_ip4)
2086 self.assertEqual(ip.src, self.pg1.remote_ip4)
2087 self.assertEqual(tcp.dport, 56789)
2088 self.assertEqual(tcp.sport, 12345)
2089 self.assert_packet_checksums_valid(p)
2091 self.logger.error(ppp("Unexpected or invalid packet:", p))
2094 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4, 0)
2095 self.assertEqual(len(sessions), 0)
2096 flags = self.config_flags.NAT_IS_ADDR_ONLY
2097 self.vapi.nat44_add_del_identity_mapping(
2098 ip_address=self.pg0.remote_ip4, sw_if_index=0xFFFFFFFF,
2099 flags=flags, vrf_id=1, is_add=1)
2100 identity_mappings = self.vapi.nat44_identity_mapping_dump()
2101 self.assertEqual(len(identity_mappings), 2)
2103 def test_multiple_inside_interfaces(self):
2104 """ NAT44 multiple non-overlapping address space inside interfaces """
2106 self.nat44_add_address(self.nat_addr)
2107 flags = self.config_flags.NAT_IS_INSIDE
2108 self.vapi.nat44_interface_add_del_feature(
2109 sw_if_index=self.pg0.sw_if_index,
2110 flags=flags, is_add=1)
2111 self.vapi.nat44_interface_add_del_feature(
2112 sw_if_index=self.pg1.sw_if_index,
2113 flags=flags, is_add=1)
2114 self.vapi.nat44_interface_add_del_feature(
2115 sw_if_index=self.pg3.sw_if_index,
2118 # between two NAT44 inside interfaces (no translation)
2119 pkts = self.create_stream_in(self.pg0, self.pg1)
2120 self.pg0.add_stream(pkts)
2121 self.pg_enable_capture(self.pg_interfaces)
2123 capture = self.pg1.get_capture(len(pkts))
2124 self.verify_capture_no_translation(capture, self.pg0, self.pg1)
2126 # from NAT44 inside to interface without NAT44 feature (no translation)
2127 pkts = self.create_stream_in(self.pg0, self.pg2)
2128 self.pg0.add_stream(pkts)
2129 self.pg_enable_capture(self.pg_interfaces)
2131 capture = self.pg2.get_capture(len(pkts))
2132 self.verify_capture_no_translation(capture, self.pg0, self.pg2)
2134 # in2out 1st interface
2135 pkts = self.create_stream_in(self.pg0, self.pg3)
2136 self.pg0.add_stream(pkts)
2137 self.pg_enable_capture(self.pg_interfaces)
2139 capture = self.pg3.get_capture(len(pkts))
2140 self.verify_capture_out(capture)
2142 # out2in 1st interface
2143 pkts = self.create_stream_out(self.pg3)
2144 self.pg3.add_stream(pkts)
2145 self.pg_enable_capture(self.pg_interfaces)
2147 capture = self.pg0.get_capture(len(pkts))
2148 self.verify_capture_in(capture, self.pg0)
2150 # in2out 2nd interface
2151 pkts = self.create_stream_in(self.pg1, self.pg3)
2152 self.pg1.add_stream(pkts)
2153 self.pg_enable_capture(self.pg_interfaces)
2155 capture = self.pg3.get_capture(len(pkts))
2156 self.verify_capture_out(capture)
2158 # out2in 2nd interface
2159 pkts = self.create_stream_out(self.pg3)
2160 self.pg3.add_stream(pkts)
2161 self.pg_enable_capture(self.pg_interfaces)
2163 capture = self.pg1.get_capture(len(pkts))
2164 self.verify_capture_in(capture, self.pg1)
2166 def test_inside_overlapping_interfaces(self):
2167 """ NAT44 multiple inside interfaces with overlapping address space """
2169 static_nat_ip = "10.0.0.10"
2170 self.nat44_add_address(self.nat_addr)
2171 flags = self.config_flags.NAT_IS_INSIDE
2172 self.vapi.nat44_interface_add_del_feature(
2173 sw_if_index=self.pg3.sw_if_index,
2175 self.vapi.nat44_interface_add_del_feature(
2176 sw_if_index=self.pg4.sw_if_index,
2177 flags=flags, is_add=1)
2178 self.vapi.nat44_interface_add_del_feature(
2179 sw_if_index=self.pg5.sw_if_index,
2180 flags=flags, is_add=1)
2181 self.vapi.nat44_interface_add_del_feature(
2182 sw_if_index=self.pg6.sw_if_index,
2183 flags=flags, is_add=1)
2184 self.nat44_add_static_mapping(self.pg6.remote_ip4, static_nat_ip,
2187 # between NAT44 inside interfaces with same VRF (no translation)
2188 pkts = self.create_stream_in(self.pg4, self.pg5)
2189 self.pg4.add_stream(pkts)
2190 self.pg_enable_capture(self.pg_interfaces)
2192 capture = self.pg5.get_capture(len(pkts))
2193 self.verify_capture_no_translation(capture, self.pg4, self.pg5)
2195 # between NAT44 inside interfaces with different VRF (hairpinning)
2196 p = (Ether(src=self.pg4.remote_mac, dst=self.pg4.local_mac) /
2197 IP(src=self.pg4.remote_ip4, dst=static_nat_ip) /
2198 TCP(sport=1234, dport=5678))
2199 self.pg4.add_stream(p)
2200 self.pg_enable_capture(self.pg_interfaces)
2202 capture = self.pg6.get_capture(1)
2207 self.assertEqual(ip.src, self.nat_addr)
2208 self.assertEqual(ip.dst, self.pg6.remote_ip4)
2209 self.assertNotEqual(tcp.sport, 1234)
2210 self.assertEqual(tcp.dport, 5678)
2212 self.logger.error(ppp("Unexpected or invalid packet:", p))
2215 # in2out 1st interface
2216 pkts = self.create_stream_in(self.pg4, self.pg3)
2217 self.pg4.add_stream(pkts)
2218 self.pg_enable_capture(self.pg_interfaces)
2220 capture = self.pg3.get_capture(len(pkts))
2221 self.verify_capture_out(capture)
2223 # out2in 1st interface
2224 pkts = self.create_stream_out(self.pg3)
2225 self.pg3.add_stream(pkts)
2226 self.pg_enable_capture(self.pg_interfaces)
2228 capture = self.pg4.get_capture(len(pkts))
2229 self.verify_capture_in(capture, self.pg4)
2231 # in2out 2nd interface
2232 pkts = self.create_stream_in(self.pg5, self.pg3)
2233 self.pg5.add_stream(pkts)
2234 self.pg_enable_capture(self.pg_interfaces)
2236 capture = self.pg3.get_capture(len(pkts))
2237 self.verify_capture_out(capture)
2239 # out2in 2nd interface
2240 pkts = self.create_stream_out(self.pg3)
2241 self.pg3.add_stream(pkts)
2242 self.pg_enable_capture(self.pg_interfaces)
2244 capture = self.pg5.get_capture(len(pkts))
2245 self.verify_capture_in(capture, self.pg5)
2248 addresses = self.vapi.nat44_address_dump()
2249 self.assertEqual(len(addresses), 1)
2250 sessions = self.vapi.nat44_user_session_dump(self.pg5.remote_ip4, 10)
2251 self.assertEqual(len(sessions), 3)
2252 for session in sessions:
2253 self.assertFalse(session.flags & self.config_flags.NAT_IS_STATIC)
2254 self.assertEqual(str(session.inside_ip_address),
2255 self.pg5.remote_ip4)
2256 self.assertEqual(session.outside_ip_address,
2257 addresses[0].ip_address)
2258 self.assertEqual(sessions[0].protocol, IP_PROTOS.tcp)
2259 self.assertEqual(sessions[1].protocol, IP_PROTOS.udp)
2260 self.assertEqual(sessions[2].protocol, IP_PROTOS.icmp)
2261 self.assertEqual(sessions[0].inside_port, self.tcp_port_in)
2262 self.assertEqual(sessions[1].inside_port, self.udp_port_in)
2263 self.assertEqual(sessions[2].inside_port, self.icmp_id_in)
2264 self.assertEqual(sessions[0].outside_port, self.tcp_port_out)
2265 self.assertEqual(sessions[1].outside_port, self.udp_port_out)
2266 self.assertEqual(sessions[2].outside_port, self.icmp_id_out)
2268 # in2out 3rd interface
2269 pkts = self.create_stream_in(self.pg6, self.pg3)
2270 self.pg6.add_stream(pkts)
2271 self.pg_enable_capture(self.pg_interfaces)
2273 capture = self.pg3.get_capture(len(pkts))
2274 self.verify_capture_out(capture, static_nat_ip, True)
2276 # out2in 3rd interface
2277 pkts = self.create_stream_out(self.pg3, static_nat_ip)
2278 self.pg3.add_stream(pkts)
2279 self.pg_enable_capture(self.pg_interfaces)
2281 capture = self.pg6.get_capture(len(pkts))
2282 self.verify_capture_in(capture, self.pg6)
2284 # general user and session dump verifications
2285 users = self.vapi.nat44_user_dump()
2286 self.assertGreaterEqual(len(users), 3)
2287 addresses = self.vapi.nat44_address_dump()
2288 self.assertEqual(len(addresses), 1)
2290 sessions = self.vapi.nat44_user_session_dump(user.ip_address,
2292 for session in sessions:
2293 self.assertEqual(user.ip_address, session.inside_ip_address)
2294 self.assertTrue(session.total_bytes > session.total_pkts > 0)
2295 self.assertTrue(session.protocol in
2296 [IP_PROTOS.tcp, IP_PROTOS.udp,
2298 self.assertFalse(session.flags &
2299 self.config_flags.NAT_IS_EXT_HOST_VALID)
2302 sessions = self.vapi.nat44_user_session_dump(self.pg4.remote_ip4, 10)
2303 self.assertGreaterEqual(len(sessions), 4)
2304 for session in sessions:
2305 self.assertFalse(session.flags & self.config_flags.NAT_IS_STATIC)
2306 self.assertEqual(str(session.inside_ip_address),
2307 self.pg4.remote_ip4)
2308 self.assertEqual(session.outside_ip_address,
2309 addresses[0].ip_address)
2312 sessions = self.vapi.nat44_user_session_dump(self.pg6.remote_ip4, 20)
2313 self.assertGreaterEqual(len(sessions), 3)
2314 for session in sessions:
2315 self.assertTrue(session.flags & self.config_flags.NAT_IS_STATIC)
2316 self.assertEqual(str(session.inside_ip_address),
2317 self.pg6.remote_ip4)
2318 self.assertEqual(str(session.outside_ip_address),
2320 self.assertTrue(session.inside_port in
2321 [self.tcp_port_in, self.udp_port_in,
2324 def test_hairpinning(self):
2325 """ NAT44 hairpinning - 1:1 NAPT """
2327 host = self.pg0.remote_hosts[0]
2328 server = self.pg0.remote_hosts[1]
2331 server_in_port = 5678
2332 server_out_port = 8765
2334 self.nat44_add_address(self.nat_addr)
2335 flags = self.config_flags.NAT_IS_INSIDE
2336 self.vapi.nat44_interface_add_del_feature(
2337 sw_if_index=self.pg0.sw_if_index,
2338 flags=flags, is_add=1)
2339 self.vapi.nat44_interface_add_del_feature(
2340 sw_if_index=self.pg1.sw_if_index,
2343 # add static mapping for server
2344 self.nat44_add_static_mapping(server.ip4, self.nat_addr,
2345 server_in_port, server_out_port,
2346 proto=IP_PROTOS.tcp)
2348 cnt = self.statistics.get_counter('/nat44/hairpinning')[0]
2349 # send packet from host to server
2350 p = (Ether(src=host.mac, dst=self.pg0.local_mac) /
2351 IP(src=host.ip4, dst=self.nat_addr) /
2352 TCP(sport=host_in_port, dport=server_out_port))
2353 self.pg0.add_stream(p)
2354 self.pg_enable_capture(self.pg_interfaces)
2356 capture = self.pg0.get_capture(1)
2361 self.assertEqual(ip.src, self.nat_addr)
2362 self.assertEqual(ip.dst, server.ip4)
2363 self.assertNotEqual(tcp.sport, host_in_port)
2364 self.assertEqual(tcp.dport, server_in_port)
2365 self.assert_packet_checksums_valid(p)
2366 host_out_port = tcp.sport
2368 self.logger.error(ppp("Unexpected or invalid packet:", p))
2371 after = self.statistics.get_counter('/nat44/hairpinning')[0]
2372 if_idx = self.pg0.sw_if_index
2373 self.assertEqual(after[if_idx] - cnt[if_idx], 1)
2375 # send reply from server to host
2376 p = (Ether(src=server.mac, dst=self.pg0.local_mac) /
2377 IP(src=server.ip4, dst=self.nat_addr) /
2378 TCP(sport=server_in_port, dport=host_out_port))
2379 self.pg0.add_stream(p)
2380 self.pg_enable_capture(self.pg_interfaces)
2382 capture = self.pg0.get_capture(1)
2387 self.assertEqual(ip.src, self.nat_addr)
2388 self.assertEqual(ip.dst, host.ip4)
2389 self.assertEqual(tcp.sport, server_out_port)
2390 self.assertEqual(tcp.dport, host_in_port)
2391 self.assert_packet_checksums_valid(p)
2393 self.logger.error(ppp("Unexpected or invalid packet:", p))
2396 after = self.statistics.get_counter('/nat44/hairpinning')[0]
2397 if_idx = self.pg0.sw_if_index
2398 self.assertEqual(after[if_idx] - cnt[if_idx], 2)
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_counter('/nat44/ed/in2out/slowpath/tcp')[0]
4681 udpn = self.statistics.get_counter('/nat44/ed/in2out/slowpath/udp')[0]
4682 icmpn = self.statistics.get_counter(
4683 '/nat44/ed/in2out/slowpath/icmp')[0]
4684 drops = self.statistics.get_counter(
4685 '/nat44/ed/in2out/slowpath/drops')[0]
4687 pkts = self.create_stream_in(self.pg0, self.pg1)
4688 self.pg0.add_stream(pkts)
4689 self.pg_enable_capture(self.pg_interfaces)
4691 capture = self.pg1.get_capture(len(pkts))
4692 self.verify_capture_out(capture, ignore_port=True)
4694 if_idx = self.pg0.sw_if_index
4695 cnt = self.statistics.get_counter('/nat44/ed/in2out/slowpath/tcp')[0]
4696 self.assertEqual(cnt[if_idx] - tcpn[if_idx], 2)
4697 cnt = self.statistics.get_counter('/nat44/ed/in2out/slowpath/udp')[0]
4698 self.assertEqual(cnt[if_idx] - udpn[if_idx], 1)
4699 cnt = self.statistics.get_counter('/nat44/ed/in2out/slowpath/icmp')[0]
4700 self.assertEqual(cnt[if_idx] - icmpn[if_idx], 1)
4701 cnt = self.statistics.get_counter('/nat44/ed/in2out/slowpath/drops')[0]
4702 self.assertEqual(cnt[if_idx] - drops[if_idx], 0)
4705 tcpn = self.statistics.get_counter('/nat44/ed/out2in/fastpath/tcp')[0]
4706 udpn = self.statistics.get_counter('/nat44/ed/out2in/fastpath/udp')[0]
4707 icmpn = self.statistics.get_counter(
4708 '/nat44/ed/out2in/slowpath/icmp')[0]
4709 drops = self.statistics.get_counter(
4710 '/nat44/ed/out2in/fastpath/drops')[0]
4712 pkts = self.create_stream_out(self.pg1)
4713 self.pg1.add_stream(pkts)
4714 self.pg_enable_capture(self.pg_interfaces)
4716 capture = self.pg0.get_capture(len(pkts))
4717 self.verify_capture_in(capture, self.pg0)
4719 if_idx = self.pg1.sw_if_index
4720 cnt = self.statistics.get_counter('/nat44/ed/out2in/fastpath/tcp')[0]
4721 self.assertEqual(cnt[if_idx] - tcpn[if_idx], 2)
4722 cnt = self.statistics.get_counter('/nat44/ed/out2in/fastpath/udp')[0]
4723 self.assertEqual(cnt[if_idx] - udpn[if_idx], 1)
4724 cnt = self.statistics.get_counter('/nat44/ed/out2in/slowpath/icmp')[0]
4725 self.assertEqual(cnt[if_idx] - icmpn[if_idx], 1)
4726 cnt = self.statistics.get_counter('/nat44/ed/out2in/fastpath/drops')[0]
4727 self.assertEqual(cnt[if_idx] - drops[if_idx], 0)
4729 sessions = self.statistics.get_counter('/nat44/total-sessions')
4730 self.assertEqual(sessions[0][0], 3)
4732 def test_dynamic_out_of_ports(self):
4733 """ NAT44 dynamic translation test: out of ports """
4735 flags = self.config_flags.NAT_IS_INSIDE
4736 self.vapi.nat44_interface_add_del_feature(
4737 sw_if_index=self.pg0.sw_if_index,
4738 flags=flags, is_add=1)
4739 self.vapi.nat44_interface_add_del_feature(
4740 sw_if_index=self.pg1.sw_if_index,
4743 nat_config = self.vapi.nat_show_config()
4744 self.assertEqual(1, nat_config.endpoint_dependent)
4746 # in2out and no NAT addresses added
4747 err_old = self.statistics.get_err_counter(
4748 '/err/nat44-ed-in2out-slowpath/out of ports')
4750 pkts = self.create_stream_in(self.pg0, self.pg1)
4751 self.pg0.add_stream(pkts)
4752 self.pg_enable_capture(self.pg_interfaces)
4754 self.pg1.get_capture(0, timeout=1)
4756 err_new = self.statistics.get_err_counter(
4757 '/err/nat44-ed-in2out-slowpath/out of ports')
4759 self.assertEqual(err_new - err_old, len(pkts))
4761 # in2out after NAT addresses added
4762 self.nat44_add_address(self.nat_addr)
4764 err_old = self.statistics.get_err_counter(
4765 '/err/nat44-ed-in2out-slowpath/out of ports')
4767 pkts = self.create_stream_in(self.pg0, self.pg1)
4768 self.pg0.add_stream(pkts)
4769 self.pg_enable_capture(self.pg_interfaces)
4771 capture = self.pg1.get_capture(len(pkts))
4772 self.verify_capture_out(capture, ignore_port=True)
4774 err_new = self.statistics.get_err_counter(
4775 '/err/nat44-ed-in2out-slowpath/out of ports')
4777 self.assertEqual(err_new, err_old)
4779 def test_dynamic_output_feature_vrf(self):
4780 """ NAT44 dynamic translation test: output-feature, VRF"""
4782 # other then default (0)
4785 self.nat44_add_address(self.nat_addr)
4786 flags = self.config_flags.NAT_IS_INSIDE
4787 self.vapi.nat44_interface_add_del_output_feature(
4788 sw_if_index=self.pg7.sw_if_index,
4789 flags=flags, is_add=1)
4790 self.vapi.nat44_interface_add_del_output_feature(
4791 sw_if_index=self.pg8.sw_if_index,
4795 self.vapi.ip_table_add_del(is_add=1,
4796 table={'table_id': new_vrf_id})
4798 self.pg7.unconfig_ip4()
4799 self.pg7.set_table_ip4(new_vrf_id)
4800 self.pg7.config_ip4()
4801 self.pg7.resolve_arp()
4803 self.pg8.unconfig_ip4()
4804 self.pg8.set_table_ip4(new_vrf_id)
4805 self.pg8.config_ip4()
4806 self.pg8.resolve_arp()
4808 nat_config = self.vapi.nat_show_config()
4809 self.assertEqual(1, nat_config.endpoint_dependent)
4812 tcpn = self.statistics.get_counter(
4813 '/nat44/ed/in2out/slowpath/tcp')[0]
4814 udpn = self.statistics.get_counter(
4815 '/nat44/ed/in2out/slowpath/udp')[0]
4816 icmpn = self.statistics.get_counter(
4817 '/nat44/ed/in2out/slowpath/icmp')[0]
4818 drops = self.statistics.get_counter(
4819 '/nat44/ed/in2out/slowpath/drops')[0]
4821 pkts = self.create_stream_in(self.pg7, self.pg8)
4822 self.pg7.add_stream(pkts)
4823 self.pg_enable_capture(self.pg_interfaces)
4825 capture = self.pg8.get_capture(len(pkts))
4826 self.verify_capture_out(capture, ignore_port=True)
4828 if_idx = self.pg7.sw_if_index
4829 cnt = self.statistics.get_counter(
4830 '/nat44/ed/in2out/slowpath/tcp')[0]
4831 self.assertEqual(cnt[if_idx] - tcpn[if_idx], 2)
4832 cnt = self.statistics.get_counter(
4833 '/nat44/ed/in2out/slowpath/udp')[0]
4834 self.assertEqual(cnt[if_idx] - udpn[if_idx], 1)
4835 cnt = self.statistics.get_counter(
4836 '/nat44/ed/in2out/slowpath/icmp')[0]
4837 self.assertEqual(cnt[if_idx] - icmpn[if_idx], 1)
4838 cnt = self.statistics.get_counter(
4839 '/nat44/ed/in2out/slowpath/drops')[0]
4840 self.assertEqual(cnt[if_idx] - drops[if_idx], 0)
4843 tcpn = self.statistics.get_counter(
4844 '/nat44/ed/out2in/fastpath/tcp')[0]
4845 udpn = self.statistics.get_counter(
4846 '/nat44/ed/out2in/fastpath/udp')[0]
4847 icmpn = self.statistics.get_counter(
4848 '/nat44/ed/out2in/slowpath/icmp')[0]
4849 drops = self.statistics.get_counter(
4850 '/nat44/ed/out2in/fastpath/drops')[0]
4852 pkts = self.create_stream_out(self.pg8)
4853 self.pg8.add_stream(pkts)
4854 self.pg_enable_capture(self.pg_interfaces)
4856 capture = self.pg7.get_capture(len(pkts))
4857 self.verify_capture_in(capture, self.pg7)
4859 if_idx = self.pg8.sw_if_index
4860 cnt = self.statistics.get_counter(
4861 '/nat44/ed/out2in/fastpath/tcp')[0]
4862 self.assertEqual(cnt[if_idx] - tcpn[if_idx], 2)
4863 cnt = self.statistics.get_counter(
4864 '/nat44/ed/out2in/fastpath/udp')[0]
4865 self.assertEqual(cnt[if_idx] - udpn[if_idx], 1)
4866 cnt = self.statistics.get_counter(
4867 '/nat44/ed/out2in/slowpath/icmp')[0]
4868 self.assertEqual(cnt[if_idx] - icmpn[if_idx], 1)
4869 cnt = self.statistics.get_counter(
4870 '/nat44/ed/out2in/fastpath/drops')[0]
4871 self.assertEqual(cnt[if_idx] - drops[if_idx], 0)
4873 sessions = self.statistics.get_counter('/nat44/total-sessions')
4874 self.assertEqual(sessions[0][0], 3)
4877 self.pg7.unconfig_ip4()
4878 self.pg7.set_table_ip4(1)
4879 self.pg7.config_ip4()
4880 self.pg7.resolve_arp()
4882 self.pg8.unconfig_ip4()
4883 self.pg8.set_table_ip4(1)
4884 self.pg8.config_ip4()
4885 self.pg8.resolve_arp()
4887 self.vapi.ip_table_add_del(is_add=0,
4888 table={'table_id': new_vrf_id})
4890 def test_forwarding(self):
4891 """ NAT44 forwarding test """
4893 flags = self.config_flags.NAT_IS_INSIDE
4894 self.vapi.nat44_interface_add_del_feature(
4895 sw_if_index=self.pg0.sw_if_index,
4896 flags=flags, is_add=1)
4897 self.vapi.nat44_interface_add_del_feature(
4898 sw_if_index=self.pg1.sw_if_index,
4900 self.vapi.nat44_forwarding_enable_disable(enable=1)
4902 real_ip = self.pg0.remote_ip4
4903 alias_ip = self.nat_addr
4904 flags = self.config_flags.NAT_IS_ADDR_ONLY
4905 self.vapi.nat44_add_del_static_mapping(is_add=1,
4906 local_ip_address=real_ip,
4907 external_ip_address=alias_ip,
4908 external_sw_if_index=0xFFFFFFFF,
4912 # in2out - static mapping match
4914 pkts = self.create_stream_out(self.pg1)
4915 self.pg1.add_stream(pkts)
4916 self.pg_enable_capture(self.pg_interfaces)
4918 capture = self.pg0.get_capture(len(pkts))
4919 self.verify_capture_in(capture, self.pg0)
4921 pkts = self.create_stream_in(self.pg0, self.pg1)
4922 self.pg0.add_stream(pkts)
4923 self.pg_enable_capture(self.pg_interfaces)
4925 capture = self.pg1.get_capture(len(pkts))
4926 self.verify_capture_out(capture, same_port=True)
4928 # in2out - no static mapping match
4930 host0 = self.pg0.remote_hosts[0]
4931 self.pg0.remote_hosts[0] = self.pg0.remote_hosts[1]
4933 pkts = self.create_stream_out(self.pg1,
4934 dst_ip=self.pg0.remote_ip4,
4935 use_inside_ports=True)
4936 self.pg1.add_stream(pkts)
4937 self.pg_enable_capture(self.pg_interfaces)
4939 capture = self.pg0.get_capture(len(pkts))
4940 self.verify_capture_in(capture, self.pg0)
4942 pkts = self.create_stream_in(self.pg0, self.pg1)
4943 self.pg0.add_stream(pkts)
4944 self.pg_enable_capture(self.pg_interfaces)
4946 capture = self.pg1.get_capture(len(pkts))
4947 self.verify_capture_out(capture, nat_ip=self.pg0.remote_ip4,
4950 self.pg0.remote_hosts[0] = host0
4952 user = self.pg0.remote_hosts[1]
4953 sessions = self.vapi.nat44_user_session_dump(user.ip4, 0)
4954 self.assertEqual(len(sessions), 3)
4955 self.assertTrue(sessions[0].flags &
4956 self.config_flags.NAT_IS_EXT_HOST_VALID)
4957 self.vapi.nat44_del_session(
4958 address=sessions[0].inside_ip_address,
4959 port=sessions[0].inside_port,
4960 protocol=sessions[0].protocol,
4961 flags=(self.config_flags.NAT_IS_INSIDE |
4962 self.config_flags.NAT_IS_EXT_HOST_VALID),
4963 ext_host_address=sessions[0].ext_host_address,
4964 ext_host_port=sessions[0].ext_host_port)
4965 sessions = self.vapi.nat44_user_session_dump(user.ip4, 0)
4966 self.assertEqual(len(sessions), 2)
4969 self.vapi.nat44_forwarding_enable_disable(enable=0)
4970 flags = self.config_flags.NAT_IS_ADDR_ONLY
4971 self.vapi.nat44_add_del_static_mapping(
4973 local_ip_address=real_ip,
4974 external_ip_address=alias_ip,
4975 external_sw_if_index=0xFFFFFFFF,
4978 def test_static_lb(self):
4979 """ NAT44 local service load balancing """
4980 external_addr_n = self.nat_addr
4983 server1 = self.pg0.remote_hosts[0]
4984 server2 = self.pg0.remote_hosts[1]
4986 locals = [{'addr': server1.ip4,
4990 {'addr': server2.ip4,
4995 self.nat44_add_address(self.nat_addr)
4996 self.vapi.nat44_add_del_lb_static_mapping(
4998 external_addr=external_addr_n,
4999 external_port=external_port,
5000 protocol=IP_PROTOS.tcp,
5001 local_num=len(locals),
5003 flags = self.config_flags.NAT_IS_INSIDE
5004 self.vapi.nat44_interface_add_del_feature(
5005 sw_if_index=self.pg0.sw_if_index,
5006 flags=flags, is_add=1)
5007 self.vapi.nat44_interface_add_del_feature(
5008 sw_if_index=self.pg1.sw_if_index,
5011 # from client to service
5012 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
5013 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
5014 TCP(sport=12345, dport=external_port))
5015 self.pg1.add_stream(p)
5016 self.pg_enable_capture(self.pg_interfaces)
5018 capture = self.pg0.get_capture(1)
5024 self.assertIn(ip.dst, [server1.ip4, server2.ip4])
5025 if ip.dst == server1.ip4:
5029 self.assertEqual(tcp.dport, local_port)
5030 self.assert_packet_checksums_valid(p)
5032 self.logger.error(ppp("Unexpected or invalid packet:", p))
5035 # from service back to client
5036 p = (Ether(src=server.mac, dst=self.pg0.local_mac) /
5037 IP(src=server.ip4, dst=self.pg1.remote_ip4) /
5038 TCP(sport=local_port, dport=12345))
5039 self.pg0.add_stream(p)
5040 self.pg_enable_capture(self.pg_interfaces)
5042 capture = self.pg1.get_capture(1)
5047 self.assertEqual(ip.src, self.nat_addr)
5048 self.assertEqual(tcp.sport, external_port)
5049 self.assert_packet_checksums_valid(p)
5051 self.logger.error(ppp("Unexpected or invalid packet:", p))
5054 sessions = self.vapi.nat44_user_session_dump(server.ip4, 0)
5055 self.assertEqual(len(sessions), 1)
5056 self.assertTrue(sessions[0].flags &
5057 self.config_flags.NAT_IS_EXT_HOST_VALID)
5058 self.vapi.nat44_del_session(
5059 address=sessions[0].inside_ip_address,
5060 port=sessions[0].inside_port,
5061 protocol=sessions[0].protocol,
5062 flags=(self.config_flags.NAT_IS_INSIDE |
5063 self.config_flags.NAT_IS_EXT_HOST_VALID),
5064 ext_host_address=sessions[0].ext_host_address,
5065 ext_host_port=sessions[0].ext_host_port)
5066 sessions = self.vapi.nat44_user_session_dump(server.ip4, 0)
5067 self.assertEqual(len(sessions), 0)
5069 @unittest.skipUnless(running_extended_tests, "part of extended tests")
5070 def test_static_lb_multi_clients(self):
5071 """ NAT44 local service load balancing - multiple clients"""
5073 external_addr = self.nat_addr
5076 server1 = self.pg0.remote_hosts[0]
5077 server2 = self.pg0.remote_hosts[1]
5078 server3 = self.pg0.remote_hosts[2]
5080 locals = [{'addr': server1.ip4,
5084 {'addr': server2.ip4,
5089 self.nat44_add_address(self.nat_addr)
5090 self.vapi.nat44_add_del_lb_static_mapping(is_add=1,
5091 external_addr=external_addr,
5092 external_port=external_port,
5093 protocol=IP_PROTOS.tcp,
5094 local_num=len(locals),
5096 flags = self.config_flags.NAT_IS_INSIDE
5097 self.vapi.nat44_interface_add_del_feature(
5098 sw_if_index=self.pg0.sw_if_index,
5099 flags=flags, is_add=1)
5100 self.vapi.nat44_interface_add_del_feature(
5101 sw_if_index=self.pg1.sw_if_index,
5106 clients = ip4_range(self.pg1.remote_ip4, 10, 50)
5108 for client in clients:
5109 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
5110 IP(src=client, dst=self.nat_addr) /
5111 TCP(sport=12345, dport=external_port))
5113 self.pg1.add_stream(pkts)
5114 self.pg_enable_capture(self.pg_interfaces)
5116 capture = self.pg0.get_capture(len(pkts))
5118 if p[IP].dst == server1.ip4:
5122 self.assertGreater(server1_n, server2_n)
5125 'addr': server3.ip4,
5132 self.vapi.nat44_lb_static_mapping_add_del_local(
5134 external_addr=external_addr,
5135 external_port=external_port,
5137 protocol=IP_PROTOS.tcp)
5141 clients = ip4_range(self.pg1.remote_ip4, 60, 110)
5143 for client in clients:
5144 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
5145 IP(src=client, dst=self.nat_addr) /
5146 TCP(sport=12346, dport=external_port))
5148 self.assertGreater(len(pkts), 0)
5149 self.pg1.add_stream(pkts)
5150 self.pg_enable_capture(self.pg_interfaces)
5152 capture = self.pg0.get_capture(len(pkts))
5154 if p[IP].dst == server1.ip4:
5156 elif p[IP].dst == server2.ip4:
5160 self.assertGreater(server1_n, 0)
5161 self.assertGreater(server2_n, 0)
5162 self.assertGreater(server3_n, 0)
5165 'addr': server2.ip4,
5171 # remove one back-end
5172 self.vapi.nat44_lb_static_mapping_add_del_local(
5174 external_addr=external_addr,
5175 external_port=external_port,
5177 protocol=IP_PROTOS.tcp)
5181 self.pg1.add_stream(pkts)
5182 self.pg_enable_capture(self.pg_interfaces)
5184 capture = self.pg0.get_capture(len(pkts))
5186 if p[IP].dst == server1.ip4:
5188 elif p[IP].dst == server2.ip4:
5192 self.assertGreater(server1_n, 0)
5193 self.assertEqual(server2_n, 0)
5194 self.assertGreater(server3_n, 0)
5196 def test_static_lb_2(self):
5197 """ NAT44 local service load balancing (asymmetrical rule) """
5198 external_addr = self.nat_addr
5201 server1 = self.pg0.remote_hosts[0]
5202 server2 = self.pg0.remote_hosts[1]
5204 locals = [{'addr': server1.ip4,
5208 {'addr': server2.ip4,
5213 self.vapi.nat44_forwarding_enable_disable(enable=1)
5214 flags = self.config_flags.NAT_IS_OUT2IN_ONLY
5215 self.vapi.nat44_add_del_lb_static_mapping(is_add=1, flags=flags,
5216 external_addr=external_addr,
5217 external_port=external_port,
5218 protocol=IP_PROTOS.tcp,
5219 local_num=len(locals),
5221 flags = self.config_flags.NAT_IS_INSIDE
5222 self.vapi.nat44_interface_add_del_feature(
5223 sw_if_index=self.pg0.sw_if_index,
5224 flags=flags, is_add=1)
5225 self.vapi.nat44_interface_add_del_feature(
5226 sw_if_index=self.pg1.sw_if_index,
5229 # from client to service
5230 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
5231 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
5232 TCP(sport=12345, dport=external_port))
5233 self.pg1.add_stream(p)
5234 self.pg_enable_capture(self.pg_interfaces)
5236 capture = self.pg0.get_capture(1)
5242 self.assertIn(ip.dst, [server1.ip4, server2.ip4])
5243 if ip.dst == server1.ip4:
5247 self.assertEqual(tcp.dport, local_port)
5248 self.assert_packet_checksums_valid(p)
5250 self.logger.error(ppp("Unexpected or invalid packet:", p))
5253 # from service back to client
5254 p = (Ether(src=server.mac, dst=self.pg0.local_mac) /
5255 IP(src=server.ip4, dst=self.pg1.remote_ip4) /
5256 TCP(sport=local_port, dport=12345))
5257 self.pg0.add_stream(p)
5258 self.pg_enable_capture(self.pg_interfaces)
5260 capture = self.pg1.get_capture(1)
5265 self.assertEqual(ip.src, self.nat_addr)
5266 self.assertEqual(tcp.sport, external_port)
5267 self.assert_packet_checksums_valid(p)
5269 self.logger.error(ppp("Unexpected or invalid packet:", p))
5272 # from client to server (no translation)
5273 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
5274 IP(src=self.pg1.remote_ip4, dst=server1.ip4) /
5275 TCP(sport=12346, dport=local_port))
5276 self.pg1.add_stream(p)
5277 self.pg_enable_capture(self.pg_interfaces)
5279 capture = self.pg0.get_capture(1)
5285 self.assertEqual(ip.dst, server1.ip4)
5286 self.assertEqual(tcp.dport, local_port)
5287 self.assert_packet_checksums_valid(p)
5289 self.logger.error(ppp("Unexpected or invalid packet:", p))
5292 # from service back to client (no translation)
5293 p = (Ether(src=server1.mac, dst=self.pg0.local_mac) /
5294 IP(src=server1.ip4, dst=self.pg1.remote_ip4) /
5295 TCP(sport=local_port, dport=12346))
5296 self.pg0.add_stream(p)
5297 self.pg_enable_capture(self.pg_interfaces)
5299 capture = self.pg1.get_capture(1)
5304 self.assertEqual(ip.src, server1.ip4)
5305 self.assertEqual(tcp.sport, local_port)
5306 self.assert_packet_checksums_valid(p)
5308 self.logger.error(ppp("Unexpected or invalid packet:", p))
5311 def test_lb_affinity(self):
5312 """ NAT44 local service load balancing affinity """
5313 external_addr = self.nat_addr
5316 server1 = self.pg0.remote_hosts[0]
5317 server2 = self.pg0.remote_hosts[1]
5319 locals = [{'addr': server1.ip4,
5323 {'addr': server2.ip4,
5328 self.nat44_add_address(self.nat_addr)
5329 self.vapi.nat44_add_del_lb_static_mapping(is_add=1,
5330 external_addr=external_addr,
5331 external_port=external_port,
5332 protocol=IP_PROTOS.tcp,
5334 local_num=len(locals),
5336 flags = self.config_flags.NAT_IS_INSIDE
5337 self.vapi.nat44_interface_add_del_feature(
5338 sw_if_index=self.pg0.sw_if_index,
5339 flags=flags, is_add=1)
5340 self.vapi.nat44_interface_add_del_feature(
5341 sw_if_index=self.pg1.sw_if_index,
5344 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
5345 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
5346 TCP(sport=1025, dport=external_port))
5347 self.pg1.add_stream(p)
5348 self.pg_enable_capture(self.pg_interfaces)
5350 capture = self.pg0.get_capture(1)
5351 backend = capture[0][IP].dst
5353 sessions = self.vapi.nat44_user_session_dump(backend, 0)
5354 self.assertEqual(len(sessions), 1)
5355 self.assertTrue(sessions[0].flags &
5356 self.config_flags.NAT_IS_EXT_HOST_VALID)
5357 self.vapi.nat44_del_session(
5358 address=sessions[0].inside_ip_address,
5359 port=sessions[0].inside_port,
5360 protocol=sessions[0].protocol,
5361 flags=(self.config_flags.NAT_IS_INSIDE |
5362 self.config_flags.NAT_IS_EXT_HOST_VALID),
5363 ext_host_address=sessions[0].ext_host_address,
5364 ext_host_port=sessions[0].ext_host_port)
5367 for port in range(1030, 1100):
5368 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
5369 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
5370 TCP(sport=port, dport=external_port))
5372 self.pg1.add_stream(pkts)
5373 self.pg_enable_capture(self.pg_interfaces)
5375 capture = self.pg0.get_capture(len(pkts))
5377 self.assertEqual(p[IP].dst, backend)
5379 def test_unknown_proto(self):
5380 """ NAT44 translate packet with unknown protocol """
5381 self.nat44_add_address(self.nat_addr)
5382 flags = self.config_flags.NAT_IS_INSIDE
5383 self.vapi.nat44_interface_add_del_feature(
5384 sw_if_index=self.pg0.sw_if_index,
5385 flags=flags, is_add=1)
5386 self.vapi.nat44_interface_add_del_feature(
5387 sw_if_index=self.pg1.sw_if_index,
5391 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
5392 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
5393 TCP(sport=self.tcp_port_in, dport=20))
5394 self.pg0.add_stream(p)
5395 self.pg_enable_capture(self.pg_interfaces)
5397 p = self.pg1.get_capture(1)
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) /
5402 IP(src=self.pg2.remote_ip4, dst=self.pg2.remote_ip4) /
5403 TCP(sport=1234, dport=1234))
5404 self.pg0.add_stream(p)
5405 self.pg_enable_capture(self.pg_interfaces)
5407 p = self.pg1.get_capture(1)
5410 self.assertEqual(packet[IP].src, self.nat_addr)
5411 self.assertEqual(packet[IP].dst, self.pg1.remote_ip4)
5412 self.assertEqual(packet.haslayer(GRE), 1)
5413 self.assert_packet_checksums_valid(packet)
5415 self.logger.error(ppp("Unexpected or invalid packet:", packet))
5419 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
5420 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
5422 IP(src=self.pg2.remote_ip4, dst=self.pg2.remote_ip4) /
5423 TCP(sport=1234, dport=1234))
5424 self.pg1.add_stream(p)
5425 self.pg_enable_capture(self.pg_interfaces)
5427 p = self.pg0.get_capture(1)
5430 self.assertEqual(packet[IP].src, self.pg1.remote_ip4)
5431 self.assertEqual(packet[IP].dst, self.pg0.remote_ip4)
5432 self.assertEqual(packet.haslayer(GRE), 1)
5433 self.assert_packet_checksums_valid(packet)
5435 self.logger.error(ppp("Unexpected or invalid packet:", packet))
5438 def test_hairpinning_unknown_proto(self):
5439 """ NAT44 translate packet with unknown protocol - hairpinning """
5440 host = self.pg0.remote_hosts[0]
5441 server = self.pg0.remote_hosts[1]
5443 server_out_port = 8765
5444 server_nat_ip = "10.0.0.11"
5446 self.nat44_add_address(self.nat_addr)
5447 flags = self.config_flags.NAT_IS_INSIDE
5448 self.vapi.nat44_interface_add_del_feature(
5449 sw_if_index=self.pg0.sw_if_index,
5450 flags=flags, is_add=1)
5451 self.vapi.nat44_interface_add_del_feature(
5452 sw_if_index=self.pg1.sw_if_index,
5455 # add static mapping for server
5456 self.nat44_add_static_mapping(server.ip4, server_nat_ip)
5459 p = (Ether(src=host.mac, dst=self.pg0.local_mac) /
5460 IP(src=host.ip4, dst=server_nat_ip) /
5461 TCP(sport=host_in_port, dport=server_out_port))
5462 self.pg0.add_stream(p)
5463 self.pg_enable_capture(self.pg_interfaces)
5465 self.pg0.get_capture(1)
5467 p = (Ether(dst=self.pg0.local_mac, src=host.mac) /
5468 IP(src=host.ip4, dst=server_nat_ip) /
5470 IP(src=self.pg2.remote_ip4, dst=self.pg2.remote_ip4) /
5471 TCP(sport=1234, dport=1234))
5472 self.pg0.add_stream(p)
5473 self.pg_enable_capture(self.pg_interfaces)
5475 p = self.pg0.get_capture(1)
5478 self.assertEqual(packet[IP].src, self.nat_addr)
5479 self.assertEqual(packet[IP].dst, server.ip4)
5480 self.assertEqual(packet.haslayer(GRE), 1)
5481 self.assert_packet_checksums_valid(packet)
5483 self.logger.error(ppp("Unexpected or invalid packet:", packet))
5487 p = (Ether(dst=self.pg0.local_mac, src=server.mac) /
5488 IP(src=server.ip4, dst=self.nat_addr) /
5490 IP(src=self.pg2.remote_ip4, dst=self.pg2.remote_ip4) /
5491 TCP(sport=1234, dport=1234))
5492 self.pg0.add_stream(p)
5493 self.pg_enable_capture(self.pg_interfaces)
5495 p = self.pg0.get_capture(1)
5498 self.assertEqual(packet[IP].src, server_nat_ip)
5499 self.assertEqual(packet[IP].dst, host.ip4)
5500 self.assertEqual(packet.haslayer(GRE), 1)
5501 self.assert_packet_checksums_valid(packet)
5503 self.logger.error(ppp("Unexpected or invalid packet:", packet))
5506 def test_output_feature_and_service(self):
5507 """ NAT44 interface output feature and services """
5508 external_addr = '1.2.3.4'
5512 self.vapi.nat44_forwarding_enable_disable(enable=1)
5513 self.nat44_add_address(self.nat_addr)
5514 flags = self.config_flags.NAT_IS_ADDR_ONLY
5515 self.vapi.nat44_add_del_identity_mapping(
5516 ip_address=self.pg1.remote_ip4, sw_if_index=0xFFFFFFFF,
5517 flags=flags, is_add=1)
5518 flags = self.config_flags.NAT_IS_OUT2IN_ONLY
5519 self.nat44_add_static_mapping(self.pg0.remote_ip4, external_addr,
5520 local_port, external_port,
5521 proto=IP_PROTOS.tcp, flags=flags)
5522 flags = self.config_flags.NAT_IS_INSIDE
5523 self.vapi.nat44_interface_add_del_feature(
5524 sw_if_index=self.pg0.sw_if_index,
5526 self.vapi.nat44_interface_add_del_feature(
5527 sw_if_index=self.pg0.sw_if_index,
5528 flags=flags, is_add=1)
5529 self.vapi.nat44_interface_add_del_output_feature(
5531 sw_if_index=self.pg1.sw_if_index)
5533 # from client to service
5534 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
5535 IP(src=self.pg1.remote_ip4, dst=external_addr) /
5536 TCP(sport=12345, dport=external_port))
5537 self.pg1.add_stream(p)
5538 self.pg_enable_capture(self.pg_interfaces)
5540 capture = self.pg0.get_capture(1)
5545 self.assertEqual(ip.dst, self.pg0.remote_ip4)
5546 self.assertEqual(tcp.dport, local_port)
5547 self.assert_packet_checksums_valid(p)
5549 self.logger.error(ppp("Unexpected or invalid packet:", p))
5552 # from service back to client
5553 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5554 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
5555 TCP(sport=local_port, dport=12345))
5556 self.pg0.add_stream(p)
5557 self.pg_enable_capture(self.pg_interfaces)
5559 capture = self.pg1.get_capture(1)
5564 self.assertEqual(ip.src, external_addr)
5565 self.assertEqual(tcp.sport, external_port)
5566 self.assert_packet_checksums_valid(p)
5568 self.logger.error(ppp("Unexpected or invalid packet:", p))
5571 # from local network host to external network
5572 pkts = self.create_stream_in(self.pg0, self.pg1)
5573 self.pg0.add_stream(pkts)
5574 self.pg_enable_capture(self.pg_interfaces)
5576 capture = self.pg1.get_capture(len(pkts))
5577 self.verify_capture_out(capture, ignore_port=True)
5578 pkts = self.create_stream_in(self.pg0, self.pg1)
5579 self.pg0.add_stream(pkts)
5580 self.pg_enable_capture(self.pg_interfaces)
5582 capture = self.pg1.get_capture(len(pkts))
5583 self.verify_capture_out(capture, ignore_port=True)
5585 # from external network back to local network host
5586 pkts = self.create_stream_out(self.pg1)
5587 self.pg1.add_stream(pkts)
5588 self.pg_enable_capture(self.pg_interfaces)
5590 capture = self.pg0.get_capture(len(pkts))
5591 self.verify_capture_in(capture, self.pg0)
5593 def test_output_feature_and_service2(self):
5594 """ NAT44 interface output feature and service host direct access """
5595 self.vapi.nat44_forwarding_enable_disable(enable=1)
5596 self.nat44_add_address(self.nat_addr)
5597 self.vapi.nat44_interface_add_del_output_feature(
5599 sw_if_index=self.pg1.sw_if_index)
5601 # session initiated from service host - translate
5602 pkts = self.create_stream_in(self.pg0, self.pg1)
5603 self.pg0.add_stream(pkts)
5604 self.pg_enable_capture(self.pg_interfaces)
5606 capture = self.pg1.get_capture(len(pkts))
5607 self.verify_capture_out(capture, ignore_port=True)
5609 pkts = self.create_stream_out(self.pg1)
5610 self.pg1.add_stream(pkts)
5611 self.pg_enable_capture(self.pg_interfaces)
5613 capture = self.pg0.get_capture(len(pkts))
5614 self.verify_capture_in(capture, self.pg0)
5616 # session initiated from remote host - do not translate
5617 self.tcp_port_in = 60303
5618 self.udp_port_in = 60304
5619 self.icmp_id_in = 60305
5620 pkts = self.create_stream_out(self.pg1,
5621 self.pg0.remote_ip4,
5622 use_inside_ports=True)
5623 self.pg1.add_stream(pkts)
5624 self.pg_enable_capture(self.pg_interfaces)
5626 capture = self.pg0.get_capture(len(pkts))
5627 self.verify_capture_in(capture, self.pg0)
5629 pkts = self.create_stream_in(self.pg0, self.pg1)
5630 self.pg0.add_stream(pkts)
5631 self.pg_enable_capture(self.pg_interfaces)
5633 capture = self.pg1.get_capture(len(pkts))
5634 self.verify_capture_out(capture, nat_ip=self.pg0.remote_ip4,
5637 def test_output_feature_and_service3(self):
5638 """ NAT44 interface output feature and DST NAT """
5639 external_addr = '1.2.3.4'
5643 self.vapi.nat44_forwarding_enable_disable(enable=1)
5644 self.nat44_add_address(self.nat_addr)
5645 flags = self.config_flags.NAT_IS_OUT2IN_ONLY
5646 self.nat44_add_static_mapping(self.pg1.remote_ip4, external_addr,
5647 local_port, external_port,
5648 proto=IP_PROTOS.tcp, flags=flags)
5649 flags = self.config_flags.NAT_IS_INSIDE
5650 self.vapi.nat44_interface_add_del_feature(
5651 sw_if_index=self.pg0.sw_if_index,
5653 self.vapi.nat44_interface_add_del_feature(
5654 sw_if_index=self.pg0.sw_if_index,
5655 flags=flags, is_add=1)
5656 self.vapi.nat44_interface_add_del_output_feature(
5658 sw_if_index=self.pg1.sw_if_index)
5660 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5661 IP(src=self.pg0.remote_ip4, dst=external_addr) /
5662 TCP(sport=12345, dport=external_port))
5663 self.pg0.add_stream(p)
5664 self.pg_enable_capture(self.pg_interfaces)
5666 capture = self.pg1.get_capture(1)
5671 self.assertEqual(ip.src, self.pg0.remote_ip4)
5672 self.assertEqual(tcp.sport, 12345)
5673 self.assertEqual(ip.dst, self.pg1.remote_ip4)
5674 self.assertEqual(tcp.dport, local_port)
5675 self.assert_packet_checksums_valid(p)
5677 self.logger.error(ppp("Unexpected or invalid packet:", p))
5680 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
5681 IP(src=self.pg1.remote_ip4, dst=self.pg0.remote_ip4) /
5682 TCP(sport=local_port, dport=12345))
5683 self.pg1.add_stream(p)
5684 self.pg_enable_capture(self.pg_interfaces)
5686 capture = self.pg0.get_capture(1)
5691 self.assertEqual(ip.src, external_addr)
5692 self.assertEqual(tcp.sport, external_port)
5693 self.assertEqual(ip.dst, self.pg0.remote_ip4)
5694 self.assertEqual(tcp.dport, 12345)
5695 self.assert_packet_checksums_valid(p)
5697 self.logger.error(ppp("Unexpected or invalid packet:", p))
5700 def test_next_src_nat(self):
5701 """ On way back forward packet to nat44-in2out node. """
5702 twice_nat_addr = '10.0.1.3'
5705 post_twice_nat_port = 0
5707 self.vapi.nat44_forwarding_enable_disable(enable=1)
5708 self.nat44_add_address(twice_nat_addr, twice_nat=1)
5709 flags = (self.config_flags.NAT_IS_OUT2IN_ONLY |
5710 self.config_flags.NAT_IS_SELF_TWICE_NAT)
5711 self.nat44_add_static_mapping(self.pg6.remote_ip4, self.pg1.remote_ip4,
5712 local_port, external_port,
5713 proto=IP_PROTOS.tcp, vrf_id=1,
5715 self.vapi.nat44_interface_add_del_feature(
5716 sw_if_index=self.pg6.sw_if_index,
5719 p = (Ether(src=self.pg6.remote_mac, dst=self.pg6.local_mac) /
5720 IP(src=self.pg6.remote_ip4, dst=self.pg1.remote_ip4) /
5721 TCP(sport=12345, dport=external_port))
5722 self.pg6.add_stream(p)
5723 self.pg_enable_capture(self.pg_interfaces)
5725 capture = self.pg6.get_capture(1)
5730 self.assertEqual(ip.src, twice_nat_addr)
5731 self.assertNotEqual(tcp.sport, 12345)
5732 post_twice_nat_port = tcp.sport
5733 self.assertEqual(ip.dst, self.pg6.remote_ip4)
5734 self.assertEqual(tcp.dport, local_port)
5735 self.assert_packet_checksums_valid(p)
5737 self.logger.error(ppp("Unexpected or invalid packet:", p))
5740 p = (Ether(src=self.pg6.remote_mac, dst=self.pg6.local_mac) /
5741 IP(src=self.pg6.remote_ip4, dst=twice_nat_addr) /
5742 TCP(sport=local_port, dport=post_twice_nat_port))
5743 self.pg6.add_stream(p)
5744 self.pg_enable_capture(self.pg_interfaces)
5746 capture = self.pg6.get_capture(1)
5751 self.assertEqual(ip.src, self.pg1.remote_ip4)
5752 self.assertEqual(tcp.sport, external_port)
5753 self.assertEqual(ip.dst, self.pg6.remote_ip4)
5754 self.assertEqual(tcp.dport, 12345)
5755 self.assert_packet_checksums_valid(p)
5757 self.logger.error(ppp("Unexpected or invalid packet:", p))
5760 def twice_nat_common(self, self_twice_nat=False, same_pg=False, lb=False,
5762 twice_nat_addr = '10.0.1.3'
5770 port_in1 = port_in + 1
5771 port_in2 = port_in + 2
5776 server1 = self.pg0.remote_hosts[0]
5777 server2 = self.pg0.remote_hosts[1]
5789 eh_translate = ((not self_twice_nat) or (not lb and same_pg) or
5792 self.nat44_add_address(self.nat_addr)
5793 self.nat44_add_address(twice_nat_addr, twice_nat=1)
5797 flags |= self.config_flags.NAT_IS_SELF_TWICE_NAT
5799 flags |= self.config_flags.NAT_IS_TWICE_NAT
5802 self.nat44_add_static_mapping(pg0.remote_ip4, self.nat_addr,
5804 proto=IP_PROTOS.tcp,
5807 locals = [{'addr': server1.ip4,
5811 {'addr': server2.ip4,
5815 out_addr = self.nat_addr
5817 self.vapi.nat44_add_del_lb_static_mapping(is_add=1, flags=flags,
5818 external_addr=out_addr,
5819 external_port=port_out,
5820 protocol=IP_PROTOS.tcp,
5821 local_num=len(locals),
5823 flags = self.config_flags.NAT_IS_INSIDE
5824 self.vapi.nat44_interface_add_del_feature(
5825 sw_if_index=pg0.sw_if_index,
5826 flags=flags, is_add=1)
5827 self.vapi.nat44_interface_add_del_feature(
5828 sw_if_index=pg1.sw_if_index,
5835 assert client_id is not None
5837 client = self.pg0.remote_hosts[0]
5838 elif client_id == 2:
5839 client = self.pg0.remote_hosts[1]
5841 client = pg1.remote_hosts[0]
5842 p = (Ether(src=pg1.remote_mac, dst=pg1.local_mac) /
5843 IP(src=client.ip4, dst=self.nat_addr) /
5844 TCP(sport=eh_port_out, dport=port_out))
5846 self.pg_enable_capture(self.pg_interfaces)
5848 capture = pg0.get_capture(1)
5854 if ip.dst == server1.ip4:
5860 self.assertEqual(ip.dst, server.ip4)
5862 self.assertIn(tcp.dport, [port_in1, port_in2])
5864 self.assertEqual(tcp.dport, port_in)
5866 self.assertEqual(ip.src, twice_nat_addr)
5867 self.assertNotEqual(tcp.sport, eh_port_out)
5869 self.assertEqual(ip.src, client.ip4)
5870 self.assertEqual(tcp.sport, eh_port_out)
5872 eh_port_in = tcp.sport
5873 saved_port_in = tcp.dport
5874 self.assert_packet_checksums_valid(p)
5876 self.logger.error(ppp("Unexpected or invalid packet:", p))
5879 p = (Ether(src=server.mac, dst=pg0.local_mac) /
5880 IP(src=server.ip4, dst=eh_addr_in) /
5881 TCP(sport=saved_port_in, dport=eh_port_in))
5883 self.pg_enable_capture(self.pg_interfaces)
5885 capture = pg1.get_capture(1)
5890 self.assertEqual(ip.dst, client.ip4)
5891 self.assertEqual(ip.src, self.nat_addr)
5892 self.assertEqual(tcp.dport, eh_port_out)
5893 self.assertEqual(tcp.sport, port_out)
5894 self.assert_packet_checksums_valid(p)
5896 self.logger.error(ppp("Unexpected or invalid packet:", p))
5900 sessions = self.vapi.nat44_user_session_dump(server.ip4, 0)
5901 self.assertEqual(len(sessions), 1)
5902 self.assertTrue(sessions[0].flags &
5903 self.config_flags.NAT_IS_EXT_HOST_VALID)
5904 self.assertTrue(sessions[0].flags &
5905 self.config_flags.NAT_IS_TWICE_NAT)
5906 self.logger.info(self.vapi.cli("show nat44 sessions detail"))
5907 self.vapi.nat44_del_session(
5908 address=sessions[0].inside_ip_address,
5909 port=sessions[0].inside_port,
5910 protocol=sessions[0].protocol,
5911 flags=(self.config_flags.NAT_IS_INSIDE |
5912 self.config_flags.NAT_IS_EXT_HOST_VALID),
5913 ext_host_address=sessions[0].ext_host_nat_address,
5914 ext_host_port=sessions[0].ext_host_nat_port)
5915 sessions = self.vapi.nat44_user_session_dump(server.ip4, 0)
5916 self.assertEqual(len(sessions), 0)
5918 def test_twice_nat(self):
5920 self.twice_nat_common()
5922 def test_self_twice_nat_positive(self):
5923 """ Self Twice NAT44 (positive test) """
5924 self.twice_nat_common(self_twice_nat=True, same_pg=True)
5926 def test_self_twice_nat_negative(self):
5927 """ Self Twice NAT44 (negative test) """
5928 self.twice_nat_common(self_twice_nat=True)
5930 def test_twice_nat_lb(self):
5931 """ Twice NAT44 local service load balancing """
5932 self.twice_nat_common(lb=True)
5934 def test_self_twice_nat_lb_positive(self):
5935 """ Self Twice NAT44 local service load balancing (positive test) """
5936 self.twice_nat_common(lb=True, self_twice_nat=True, same_pg=True,
5939 def test_self_twice_nat_lb_negative(self):
5940 """ Self Twice NAT44 local service load balancing (negative test) """
5941 self.twice_nat_common(lb=True, self_twice_nat=True, same_pg=True,
5944 def test_twice_nat_interface_addr(self):
5945 """ Acquire twice NAT44 addresses from interface """
5946 flags = self.config_flags.NAT_IS_TWICE_NAT
5947 self.vapi.nat44_add_del_interface_addr(
5949 sw_if_index=self.pg3.sw_if_index,
5952 # no address in NAT pool
5953 adresses = self.vapi.nat44_address_dump()
5954 self.assertEqual(0, len(adresses))
5956 # configure interface address and check NAT address pool
5957 self.pg3.config_ip4()
5958 adresses = self.vapi.nat44_address_dump()
5959 self.assertEqual(1, len(adresses))
5960 self.assertEqual(str(adresses[0].ip_address),
5962 self.assertEqual(adresses[0].flags, flags)
5964 # remove interface address and check NAT address pool
5965 self.pg3.unconfig_ip4()
5966 adresses = self.vapi.nat44_address_dump()
5967 self.assertEqual(0, len(adresses))
5969 def test_tcp_close(self):
5970 """ Close TCP session from inside network - output feature """
5971 self.vapi.nat44_forwarding_enable_disable(enable=1)
5972 self.nat44_add_address(self.pg1.local_ip4)
5973 twice_nat_addr = '10.0.1.3'
5974 service_ip = '192.168.16.150'
5975 self.nat44_add_address(twice_nat_addr, twice_nat=1)
5976 flags = self.config_flags.NAT_IS_INSIDE
5977 self.vapi.nat44_interface_add_del_feature(
5978 sw_if_index=self.pg0.sw_if_index,
5980 self.vapi.nat44_interface_add_del_feature(
5981 sw_if_index=self.pg0.sw_if_index,
5982 flags=flags, is_add=1)
5983 self.vapi.nat44_interface_add_del_output_feature(
5985 sw_if_index=self.pg1.sw_if_index)
5986 flags = (self.config_flags.NAT_IS_OUT2IN_ONLY |
5987 self.config_flags.NAT_IS_TWICE_NAT)
5988 self.nat44_add_static_mapping(self.pg0.remote_ip4,
5992 proto=IP_PROTOS.tcp,
5994 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4, 0)
5995 start_sessnum = len(sessions)
5997 # SYN packet out->in
5998 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
5999 IP(src=self.pg1.remote_ip4, dst=service_ip) /
6000 TCP(sport=33898, dport=80, flags="S"))
6001 self.pg1.add_stream(p)
6002 self.pg_enable_capture(self.pg_interfaces)
6004 capture = self.pg0.get_capture(1)
6006 tcp_port = p[TCP].sport
6008 # SYN + ACK packet in->out
6009 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6010 IP(src=self.pg0.remote_ip4, dst=twice_nat_addr) /
6011 TCP(sport=80, dport=tcp_port, flags="SA"))
6012 self.pg0.add_stream(p)
6013 self.pg_enable_capture(self.pg_interfaces)
6015 self.pg1.get_capture(1)
6017 # ACK packet out->in
6018 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
6019 IP(src=self.pg1.remote_ip4, dst=service_ip) /
6020 TCP(sport=33898, dport=80, flags="A"))
6021 self.pg1.add_stream(p)
6022 self.pg_enable_capture(self.pg_interfaces)
6024 self.pg0.get_capture(1)
6026 # FIN packet in -> out
6027 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6028 IP(src=self.pg0.remote_ip4, dst=twice_nat_addr) /
6029 TCP(sport=80, dport=tcp_port, flags="FA", seq=100, ack=300))
6030 self.pg0.add_stream(p)
6031 self.pg_enable_capture(self.pg_interfaces)
6033 self.pg1.get_capture(1)
6035 # FIN+ACK packet out -> in
6036 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
6037 IP(src=self.pg1.remote_ip4, dst=service_ip) /
6038 TCP(sport=33898, dport=80, flags="FA", seq=300, ack=101))
6039 self.pg1.add_stream(p)
6040 self.pg_enable_capture(self.pg_interfaces)
6042 self.pg0.get_capture(1)
6044 # ACK packet in -> out
6045 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6046 IP(src=self.pg0.remote_ip4, dst=twice_nat_addr) /
6047 TCP(sport=80, dport=tcp_port, flags="A", seq=101, ack=301))
6048 self.pg0.add_stream(p)
6049 self.pg_enable_capture(self.pg_interfaces)
6051 self.pg1.get_capture(1)
6053 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4,
6055 self.assertEqual(len(sessions) - start_sessnum, 0)
6057 def test_tcp_session_close_in(self):
6058 """ Close TCP session from inside network """
6059 self.tcp_port_out = 10505
6060 self.nat44_add_address(self.nat_addr)
6061 flags = self.config_flags.NAT_IS_TWICE_NAT
6062 self.nat44_add_static_mapping(self.pg0.remote_ip4,
6066 proto=IP_PROTOS.tcp,
6068 flags = self.config_flags.NAT_IS_INSIDE
6069 self.vapi.nat44_interface_add_del_feature(
6070 sw_if_index=self.pg0.sw_if_index,
6071 flags=flags, is_add=1)
6072 self.vapi.nat44_interface_add_del_feature(
6073 sw_if_index=self.pg1.sw_if_index,
6076 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4, 0)
6077 start_sessnum = len(sessions)
6079 self.vapi.nat_set_timeouts(udp=300, tcp_established=7440,
6080 tcp_transitory=2, icmp=5)
6082 self.initiate_tcp_session(self.pg0, self.pg1)
6084 # FIN packet in -> out
6085 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6086 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6087 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
6088 flags="FA", seq=100, ack=300))
6089 self.pg0.add_stream(p)
6090 self.pg_enable_capture(self.pg_interfaces)
6092 self.pg1.get_capture(1)
6096 # ACK packet out -> in
6097 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
6098 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
6099 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
6100 flags="A", seq=300, ack=101))
6103 # FIN packet out -> in
6104 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
6105 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
6106 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
6107 flags="FA", seq=300, ack=101))
6110 self.pg1.add_stream(pkts)
6111 self.pg_enable_capture(self.pg_interfaces)
6113 self.pg0.get_capture(2)
6115 # ACK packet in -> out
6116 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6117 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6118 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
6119 flags="A", seq=101, ack=301))
6120 self.pg0.add_stream(p)
6121 self.pg_enable_capture(self.pg_interfaces)
6123 self.pg1.get_capture(1)
6125 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4, 0)
6126 self.assertEqual(len(sessions) - start_sessnum, 1)
6128 stats = self.statistics.get_counter(
6129 '/err/nat44-ed-out2in/drops due to TCP in transitory timeout')
6130 out2in_drops = stats[0]
6131 stats = self.statistics.get_counter(
6132 '/err/nat44-ed-in2out/drops due to TCP in transitory timeout')
6133 in2out_drops = stats[0]
6135 # extra FIN packet out -> in - this should be dropped
6136 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
6137 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
6138 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
6139 flags="FA", seq=300, ack=101))
6141 self.pg1.add_stream(p)
6142 self.pg_enable_capture(self.pg_interfaces)
6144 self.pg0.assert_nothing_captured()
6146 # extra ACK packet in -> out - this should be dropped
6147 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6148 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6149 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
6150 flags="A", seq=101, ack=301))
6151 self.pg0.add_stream(p)
6152 self.pg_enable_capture(self.pg_interfaces)
6154 self.pg1.assert_nothing_captured()
6156 stats = self.statistics.get_counter(
6157 '/err/nat44-ed-out2in/drops due to TCP in transitory timeout')
6158 self.assertEqual(stats[0] - out2in_drops, 1)
6159 stats = self.statistics.get_counter(
6160 '/err/nat44-ed-in2out/drops due to TCP in transitory timeout')
6161 self.assertEqual(stats[0] - in2out_drops, 1)
6164 # extra ACK packet in -> out - this will cause session to be wiped
6165 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6166 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6167 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
6168 flags="A", seq=101, ack=301))
6169 self.pg0.add_stream(p)
6170 self.pg_enable_capture(self.pg_interfaces)
6172 self.pg1.assert_nothing_captured()
6173 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4, 0)
6174 self.assertEqual(len(sessions) - start_sessnum, 0)
6176 def test_tcp_session_close_out(self):
6177 """ Close TCP session from outside network """
6178 self.tcp_port_out = 10505
6179 self.nat44_add_address(self.nat_addr)
6180 flags = self.config_flags.NAT_IS_TWICE_NAT
6181 self.nat44_add_static_mapping(self.pg0.remote_ip4,
6185 proto=IP_PROTOS.tcp,
6187 flags = self.config_flags.NAT_IS_INSIDE
6188 self.vapi.nat44_interface_add_del_feature(
6189 sw_if_index=self.pg0.sw_if_index,
6190 flags=flags, is_add=1)
6191 self.vapi.nat44_interface_add_del_feature(
6192 sw_if_index=self.pg1.sw_if_index,
6195 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4, 0)
6196 start_sessnum = len(sessions)
6198 self.vapi.nat_set_timeouts(udp=300, tcp_established=7440,
6199 tcp_transitory=2, icmp=5)
6201 self.initiate_tcp_session(self.pg0, self.pg1)
6203 # FIN packet out -> in
6204 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
6205 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
6206 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
6207 flags="FA", seq=100, ack=300))
6208 self.pg1.add_stream(p)
6209 self.pg_enable_capture(self.pg_interfaces)
6211 self.pg0.get_capture(1)
6213 # FIN+ACK packet in -> out
6214 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6215 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6216 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
6217 flags="FA", seq=300, ack=101))
6219 self.pg0.add_stream(p)
6220 self.pg_enable_capture(self.pg_interfaces)
6222 self.pg1.get_capture(1)
6224 # ACK packet out -> in
6225 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
6226 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
6227 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
6228 flags="A", seq=101, ack=301))
6229 self.pg1.add_stream(p)
6230 self.pg_enable_capture(self.pg_interfaces)
6232 self.pg0.get_capture(1)
6234 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4, 0)
6235 self.assertEqual(len(sessions) - start_sessnum, 1)
6237 stats = self.statistics.get_counter(
6238 '/err/nat44-ed-out2in/drops due to TCP in transitory timeout')
6239 out2in_drops = stats[0]
6240 stats = self.statistics.get_counter(
6241 '/err/nat44-ed-in2out/drops due to TCP in transitory timeout')
6242 in2out_drops = stats[0]
6244 # extra FIN packet out -> in - this should be dropped
6245 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
6246 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
6247 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
6248 flags="FA", seq=300, ack=101))
6250 self.pg1.add_stream(p)
6251 self.pg_enable_capture(self.pg_interfaces)
6253 self.pg0.assert_nothing_captured()
6255 # extra ACK packet in -> out - this should be dropped
6256 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6257 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6258 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
6259 flags="A", seq=101, ack=301))
6260 self.pg0.add_stream(p)
6261 self.pg_enable_capture(self.pg_interfaces)
6263 self.pg1.assert_nothing_captured()
6265 stats = self.statistics.get_counter(
6266 '/err/nat44-ed-out2in/drops due to TCP in transitory timeout')
6267 self.assertEqual(stats[0] - out2in_drops, 1)
6268 stats = self.statistics.get_counter(
6269 '/err/nat44-ed-in2out/drops due to TCP in transitory timeout')
6270 self.assertEqual(stats[0] - in2out_drops, 1)
6273 # extra ACK packet in -> out - this will cause session to be wiped
6274 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6275 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6276 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
6277 flags="A", seq=101, ack=301))
6278 self.pg0.add_stream(p)
6279 self.pg_enable_capture(self.pg_interfaces)
6281 self.pg1.assert_nothing_captured()
6282 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4, 0)
6283 self.assertEqual(len(sessions) - start_sessnum, 0)
6285 def test_tcp_session_close_simultaneous(self):
6286 """ Close TCP session from inside network """
6287 self.tcp_port_out = 10505
6288 self.nat44_add_address(self.nat_addr)
6289 flags = self.config_flags.NAT_IS_TWICE_NAT
6290 self.nat44_add_static_mapping(self.pg0.remote_ip4,
6294 proto=IP_PROTOS.tcp,
6296 flags = self.config_flags.NAT_IS_INSIDE
6297 self.vapi.nat44_interface_add_del_feature(
6298 sw_if_index=self.pg0.sw_if_index,
6299 flags=flags, is_add=1)
6300 self.vapi.nat44_interface_add_del_feature(
6301 sw_if_index=self.pg1.sw_if_index,
6304 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4, 0)
6305 start_sessnum = len(sessions)
6307 self.vapi.nat_set_timeouts(udp=300, tcp_established=7440,
6308 tcp_transitory=2, icmp=5)
6310 self.initiate_tcp_session(self.pg0, self.pg1)
6312 # FIN packet in -> out
6313 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6314 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6315 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
6316 flags="FA", seq=100, ack=300))
6317 self.pg0.add_stream(p)
6318 self.pg_enable_capture(self.pg_interfaces)
6320 self.pg1.get_capture(1)
6322 # FIN packet out -> in
6323 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
6324 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
6325 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
6326 flags="FA", seq=300, ack=100))
6327 self.pg1.add_stream(p)
6328 self.pg_enable_capture(self.pg_interfaces)
6330 self.pg0.get_capture(1)
6332 # ACK packet in -> out
6333 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6334 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6335 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
6336 flags="A", seq=101, ack=301))
6337 self.pg0.add_stream(p)
6338 self.pg_enable_capture(self.pg_interfaces)
6340 self.pg1.get_capture(1)
6342 # ACK packet out -> in
6343 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
6344 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
6345 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
6346 flags="A", seq=301, ack=101))
6347 self.pg1.add_stream(p)
6348 self.pg_enable_capture(self.pg_interfaces)
6350 self.pg0.get_capture(1)
6352 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4, 0)
6353 self.assertEqual(len(sessions) - start_sessnum, 1)
6355 stats = self.statistics.get_counter(
6356 '/err/nat44-ed-out2in/drops due to TCP in transitory timeout')
6357 out2in_drops = stats[0]
6358 stats = self.statistics.get_counter(
6359 '/err/nat44-ed-in2out/drops due to TCP in transitory timeout')
6360 in2out_drops = stats[0]
6362 # extra FIN packet out -> in - this should be dropped
6363 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
6364 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
6365 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
6366 flags="FA", seq=300, ack=101))
6368 self.pg1.add_stream(p)
6369 self.pg_enable_capture(self.pg_interfaces)
6371 self.pg0.assert_nothing_captured()
6373 # extra ACK packet in -> out - this should be dropped
6374 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6375 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6376 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
6377 flags="A", seq=101, ack=301))
6378 self.pg0.add_stream(p)
6379 self.pg_enable_capture(self.pg_interfaces)
6381 self.pg1.assert_nothing_captured()
6383 stats = self.statistics.get_counter(
6384 '/err/nat44-ed-out2in/drops due to TCP in transitory timeout')
6385 self.assertEqual(stats[0] - out2in_drops, 1)
6386 stats = self.statistics.get_counter(
6387 '/err/nat44-ed-in2out/drops due to TCP in transitory timeout')
6388 self.assertEqual(stats[0] - in2out_drops, 1)
6391 # extra ACK packet in -> out - this will cause session to be wiped
6392 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6393 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6394 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
6395 flags="A", seq=101, ack=301))
6396 self.pg0.add_stream(p)
6397 self.pg_enable_capture(self.pg_interfaces)
6399 self.pg1.assert_nothing_captured()
6400 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4, 0)
6401 self.assertEqual(len(sessions) - start_sessnum, 0)
6403 def test_one_armed_nat44_static(self):
6404 """ One armed NAT44 and 1:1 NAPT asymmetrical rule """
6405 remote_host = self.pg4.remote_hosts[0]
6406 local_host = self.pg4.remote_hosts[1]
6411 self.vapi.nat44_forwarding_enable_disable(enable=1)
6412 self.nat44_add_address(self.nat_addr, twice_nat=1)
6413 flags = (self.config_flags.NAT_IS_OUT2IN_ONLY |
6414 self.config_flags.NAT_IS_TWICE_NAT)
6415 self.nat44_add_static_mapping(local_host.ip4, self.nat_addr,
6416 local_port, external_port,
6417 proto=IP_PROTOS.tcp, flags=flags)
6418 flags = self.config_flags.NAT_IS_INSIDE
6419 self.vapi.nat44_interface_add_del_feature(
6420 sw_if_index=self.pg4.sw_if_index,
6422 self.vapi.nat44_interface_add_del_feature(
6423 sw_if_index=self.pg4.sw_if_index,
6424 flags=flags, is_add=1)
6426 # from client to service
6427 p = (Ether(src=self.pg4.remote_mac, dst=self.pg4.local_mac) /
6428 IP(src=remote_host.ip4, dst=self.nat_addr) /
6429 TCP(sport=12345, dport=external_port))
6430 self.pg4.add_stream(p)
6431 self.pg_enable_capture(self.pg_interfaces)
6433 capture = self.pg4.get_capture(1)
6438 self.assertEqual(ip.dst, local_host.ip4)
6439 self.assertEqual(ip.src, self.nat_addr)
6440 self.assertEqual(tcp.dport, local_port)
6441 self.assertNotEqual(tcp.sport, 12345)
6442 eh_port_in = tcp.sport
6443 self.assert_packet_checksums_valid(p)
6445 self.logger.error(ppp("Unexpected or invalid packet:", p))
6448 # from service back to client
6449 p = (Ether(src=self.pg4.remote_mac, dst=self.pg4.local_mac) /
6450 IP(src=local_host.ip4, dst=self.nat_addr) /
6451 TCP(sport=local_port, dport=eh_port_in))
6452 self.pg4.add_stream(p)
6453 self.pg_enable_capture(self.pg_interfaces)
6455 capture = self.pg4.get_capture(1)
6460 self.assertEqual(ip.src, self.nat_addr)
6461 self.assertEqual(ip.dst, remote_host.ip4)
6462 self.assertEqual(tcp.sport, external_port)
6463 self.assertEqual(tcp.dport, 12345)
6464 self.assert_packet_checksums_valid(p)
6466 self.logger.error(ppp("Unexpected or invalid packet:", p))
6469 def test_static_with_port_out2(self):
6470 """ 1:1 NAPT asymmetrical rule """
6475 self.vapi.nat44_forwarding_enable_disable(enable=1)
6476 flags = self.config_flags.NAT_IS_OUT2IN_ONLY
6477 self.nat44_add_static_mapping(self.pg0.remote_ip4, self.nat_addr,
6478 local_port, external_port,
6479 proto=IP_PROTOS.tcp, flags=flags)
6480 flags = self.config_flags.NAT_IS_INSIDE
6481 self.vapi.nat44_interface_add_del_feature(
6482 sw_if_index=self.pg0.sw_if_index,
6483 flags=flags, is_add=1)
6484 self.vapi.nat44_interface_add_del_feature(
6485 sw_if_index=self.pg1.sw_if_index,
6488 # from client to service
6489 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
6490 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
6491 TCP(sport=12345, dport=external_port))
6492 self.pg1.add_stream(p)
6493 self.pg_enable_capture(self.pg_interfaces)
6495 capture = self.pg0.get_capture(1)
6500 self.assertEqual(ip.dst, self.pg0.remote_ip4)
6501 self.assertEqual(tcp.dport, local_port)
6502 self.assert_packet_checksums_valid(p)
6504 self.logger.error(ppp("Unexpected or invalid packet:", p))
6508 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
6509 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6510 ICMP(type=11) / capture[0][IP])
6511 self.pg0.add_stream(p)
6512 self.pg_enable_capture(self.pg_interfaces)
6514 capture = self.pg1.get_capture(1)
6517 self.assertEqual(p[IP].src, self.nat_addr)
6519 self.assertEqual(inner.dst, self.nat_addr)
6520 self.assertEqual(inner[TCPerror].dport, external_port)
6522 self.logger.error(ppp("Unexpected or invalid packet:", p))
6525 # from service back to client
6526 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6527 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6528 TCP(sport=local_port, dport=12345))
6529 self.pg0.add_stream(p)
6530 self.pg_enable_capture(self.pg_interfaces)
6532 capture = self.pg1.get_capture(1)
6537 self.assertEqual(ip.src, self.nat_addr)
6538 self.assertEqual(tcp.sport, external_port)
6539 self.assert_packet_checksums_valid(p)
6541 self.logger.error(ppp("Unexpected or invalid packet:", p))
6545 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
6546 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
6547 ICMP(type=11) / capture[0][IP])
6548 self.pg1.add_stream(p)
6549 self.pg_enable_capture(self.pg_interfaces)
6551 capture = self.pg0.get_capture(1)
6554 self.assertEqual(p[IP].dst, self.pg0.remote_ip4)
6556 self.assertEqual(inner.src, self.pg0.remote_ip4)
6557 self.assertEqual(inner[TCPerror].sport, local_port)
6559 self.logger.error(ppp("Unexpected or invalid packet:", p))
6562 # from client to server (no translation)
6563 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
6564 IP(src=self.pg1.remote_ip4, dst=self.pg0.remote_ip4) /
6565 TCP(sport=12346, dport=local_port))
6566 self.pg1.add_stream(p)
6567 self.pg_enable_capture(self.pg_interfaces)
6569 capture = self.pg0.get_capture(1)
6574 self.assertEqual(ip.dst, self.pg0.remote_ip4)
6575 self.assertEqual(tcp.dport, local_port)
6576 self.assert_packet_checksums_valid(p)
6578 self.logger.error(ppp("Unexpected or invalid packet:", p))
6581 # from service back to client (no translation)
6582 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6583 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6584 TCP(sport=local_port, dport=12346))
6585 self.pg0.add_stream(p)
6586 self.pg_enable_capture(self.pg_interfaces)
6588 capture = self.pg1.get_capture(1)
6593 self.assertEqual(ip.src, self.pg0.remote_ip4)
6594 self.assertEqual(tcp.sport, local_port)
6595 self.assert_packet_checksums_valid(p)
6597 self.logger.error(ppp("Unexpected or invalid packet:", p))
6600 def test_output_feature(self):
6601 """ NAT44 interface output feature (in2out postrouting) """
6602 self.vapi.nat44_forwarding_enable_disable(enable=1)
6603 self.nat44_add_address(self.nat_addr)
6604 self.vapi.nat44_interface_add_del_feature(
6605 sw_if_index=self.pg0.sw_if_index,
6607 self.vapi.nat44_interface_add_del_output_feature(
6609 sw_if_index=self.pg1.sw_if_index)
6612 pkts = self.create_stream_in(self.pg0, self.pg1)
6613 self.pg0.add_stream(pkts)
6614 self.pg_enable_capture(self.pg_interfaces)
6616 capture = self.pg1.get_capture(len(pkts))
6617 self.verify_capture_out(capture, ignore_port=True)
6620 pkts = self.create_stream_out(self.pg1)
6621 self.pg1.add_stream(pkts)
6622 self.pg_enable_capture(self.pg_interfaces)
6624 capture = self.pg0.get_capture(len(pkts))
6625 self.verify_capture_in(capture, self.pg0)
6627 def test_output_feature_stateful_acl(self):
6628 """ NAT44 endpoint-dependent output feature works with stateful ACL """
6629 self.nat44_add_address(self.nat_addr)
6630 self.vapi.nat44_interface_add_del_output_feature(
6631 sw_if_index=self.pg0.sw_if_index,
6632 flags=self.config_flags.NAT_IS_INSIDE,
6634 self.vapi.nat44_interface_add_del_output_feature(
6635 sw_if_index=self.pg1.sw_if_index,
6636 flags=self.config_flags.NAT_IS_OUTSIDE,
6639 # First ensure that the NAT is working sans ACL
6641 # send packets out2in, no sessions yet so packets should drop
6642 pkts_out2in = self.create_stream_out(self.pg1)
6643 self.send_and_assert_no_replies(self.pg1, pkts_out2in)
6645 # send packets into inside intf, ensure received via outside intf
6646 pkts_in2out = self.create_stream_in(self.pg0, self.pg1)
6647 capture = self.send_and_expect(self.pg0, pkts_in2out, self.pg1,
6649 self.verify_capture_out(capture, ignore_port=True)
6651 # send out2in again, with sessions created it should work now
6652 pkts_out2in = self.create_stream_out(self.pg1)
6653 capture = self.send_and_expect(self.pg1, pkts_out2in, self.pg0,
6655 self.verify_capture_in(capture, self.pg0)
6657 # Create an ACL blocking everything
6658 out2in_deny_rule = AclRule(is_permit=0)
6659 out2in_acl = VppAcl(self, rules=[out2in_deny_rule])
6660 out2in_acl.add_vpp_config()
6662 # create an ACL to permit/reflect everything
6663 in2out_reflect_rule = AclRule(is_permit=2)
6664 in2out_acl = VppAcl(self, rules=[in2out_reflect_rule])
6665 in2out_acl.add_vpp_config()
6667 # apply as input acl on interface and confirm it blocks everything
6668 acl_if = VppAclInterface(self, sw_if_index=self.pg1.sw_if_index,
6669 n_input=1, acls=[out2in_acl])
6670 acl_if.add_vpp_config()
6671 self.send_and_assert_no_replies(self.pg1, pkts_out2in)
6674 acl_if.acls = [out2in_acl, in2out_acl]
6675 acl_if.add_vpp_config()
6676 # send in2out to generate ACL state (NAT state was created earlier)
6677 capture = self.send_and_expect(self.pg0, pkts_in2out, self.pg1,
6679 self.verify_capture_out(capture, ignore_port=True)
6681 # send out2in again. ACL state exists so it should work now.
6682 # TCP packets with the syn flag set also need the ack flag
6683 for p in pkts_out2in:
6684 if p.haslayer(TCP) and p[TCP].flags & 0x02:
6685 p[TCP].flags |= 0x10
6686 capture = self.send_and_expect(self.pg1, pkts_out2in, self.pg0,
6688 self.verify_capture_in(capture, self.pg0)
6689 self.logger.info(self.vapi.cli("show trace"))
6691 def test_multiple_vrf(self):
6692 """ Multiple VRF setup """
6693 external_addr = '1.2.3.4'
6698 self.vapi.nat44_forwarding_enable_disable(enable=1)
6699 self.nat44_add_address(self.nat_addr)
6700 flags = self.config_flags.NAT_IS_INSIDE
6701 self.vapi.nat44_interface_add_del_feature(
6702 sw_if_index=self.pg0.sw_if_index,
6704 self.vapi.nat44_interface_add_del_feature(
6705 sw_if_index=self.pg0.sw_if_index,
6706 is_add=1, flags=flags)
6707 self.vapi.nat44_interface_add_del_output_feature(
6708 sw_if_index=self.pg1.sw_if_index,
6710 self.vapi.nat44_interface_add_del_feature(
6711 sw_if_index=self.pg5.sw_if_index,
6713 self.vapi.nat44_interface_add_del_feature(
6714 sw_if_index=self.pg5.sw_if_index,
6715 is_add=1, flags=flags)
6716 self.vapi.nat44_interface_add_del_feature(
6717 sw_if_index=self.pg6.sw_if_index,
6719 flags = self.config_flags.NAT_IS_OUT2IN_ONLY
6720 self.nat44_add_static_mapping(self.pg5.remote_ip4, external_addr,
6721 local_port, external_port, vrf_id=1,
6722 proto=IP_PROTOS.tcp, flags=flags)
6723 self.nat44_add_static_mapping(
6724 self.pg0.remote_ip4,
6725 external_sw_if_index=self.pg0.sw_if_index,
6726 local_port=local_port,
6728 external_port=external_port,
6729 proto=IP_PROTOS.tcp,
6733 # from client to service (both VRF1)
6734 p = (Ether(src=self.pg6.remote_mac, dst=self.pg6.local_mac) /
6735 IP(src=self.pg6.remote_ip4, dst=external_addr) /
6736 TCP(sport=12345, dport=external_port))
6737 self.pg6.add_stream(p)
6738 self.pg_enable_capture(self.pg_interfaces)
6740 capture = self.pg5.get_capture(1)
6745 self.assertEqual(ip.dst, self.pg5.remote_ip4)
6746 self.assertEqual(tcp.dport, local_port)
6747 self.assert_packet_checksums_valid(p)
6749 self.logger.error(ppp("Unexpected or invalid packet:", p))
6752 # from service back to client (both VRF1)
6753 p = (Ether(src=self.pg5.remote_mac, dst=self.pg5.local_mac) /
6754 IP(src=self.pg5.remote_ip4, dst=self.pg6.remote_ip4) /
6755 TCP(sport=local_port, dport=12345))
6756 self.pg5.add_stream(p)
6757 self.pg_enable_capture(self.pg_interfaces)
6759 capture = self.pg6.get_capture(1)
6764 self.assertEqual(ip.src, external_addr)
6765 self.assertEqual(tcp.sport, external_port)
6766 self.assert_packet_checksums_valid(p)
6768 self.logger.error(ppp("Unexpected or invalid packet:", p))
6771 # dynamic NAT from VRF1 to VRF0 (output-feature)
6772 p = (Ether(src=self.pg5.remote_mac, dst=self.pg5.local_mac) /
6773 IP(src=self.pg5.remote_ip4, dst=self.pg1.remote_ip4) /
6774 TCP(sport=2345, dport=22))
6775 self.pg5.add_stream(p)
6776 self.pg_enable_capture(self.pg_interfaces)
6778 capture = self.pg1.get_capture(1)
6783 self.assertEqual(ip.src, self.nat_addr)
6784 self.assert_packet_checksums_valid(p)
6787 self.logger.error(ppp("Unexpected or invalid packet:", p))
6790 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
6791 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
6792 TCP(sport=22, dport=port))
6793 self.pg1.add_stream(p)
6794 self.pg_enable_capture(self.pg_interfaces)
6796 capture = self.pg5.get_capture(1)
6801 self.assertEqual(ip.dst, self.pg5.remote_ip4)
6802 self.assertEqual(tcp.dport, 2345)
6803 self.assert_packet_checksums_valid(p)
6805 self.logger.error(ppp("Unexpected or invalid packet:", p))
6808 # from client VRF1 to service VRF0
6809 p = (Ether(src=self.pg6.remote_mac, dst=self.pg6.local_mac) /
6810 IP(src=self.pg6.remote_ip4, dst=self.pg0.local_ip4) /
6811 TCP(sport=12346, dport=external_port))
6812 self.pg6.add_stream(p)
6813 self.pg_enable_capture(self.pg_interfaces)
6815 capture = self.pg0.get_capture(1)
6820 self.assertEqual(ip.dst, self.pg0.remote_ip4)
6821 self.assertEqual(tcp.dport, local_port)
6822 self.assert_packet_checksums_valid(p)
6824 self.logger.error(ppp("Unexpected or invalid packet:", p))
6827 # from service VRF0 back to client VRF1
6828 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6829 IP(src=self.pg0.remote_ip4, dst=self.pg6.remote_ip4) /
6830 TCP(sport=local_port, dport=12346))
6831 self.pg0.add_stream(p)
6832 self.pg_enable_capture(self.pg_interfaces)
6834 capture = self.pg6.get_capture(1)
6839 self.assertEqual(ip.src, self.pg0.local_ip4)
6840 self.assertEqual(tcp.sport, external_port)
6841 self.assert_packet_checksums_valid(p)
6843 self.logger.error(ppp("Unexpected or invalid packet:", p))
6846 # from client VRF0 to service VRF1
6847 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6848 IP(src=self.pg0.remote_ip4, dst=external_addr) /
6849 TCP(sport=12347, dport=external_port))
6850 self.pg0.add_stream(p)
6851 self.pg_enable_capture(self.pg_interfaces)
6853 capture = self.pg5.get_capture(1)
6858 self.assertEqual(ip.dst, self.pg5.remote_ip4)
6859 self.assertEqual(tcp.dport, local_port)
6860 self.assert_packet_checksums_valid(p)
6862 self.logger.error(ppp("Unexpected or invalid packet:", p))
6865 # from service VRF1 back to client VRF0
6866 p = (Ether(src=self.pg5.remote_mac, dst=self.pg5.local_mac) /
6867 IP(src=self.pg5.remote_ip4, dst=self.pg0.remote_ip4) /
6868 TCP(sport=local_port, dport=12347))
6869 self.pg5.add_stream(p)
6870 self.pg_enable_capture(self.pg_interfaces)
6872 capture = self.pg0.get_capture(1)
6877 self.assertEqual(ip.src, external_addr)
6878 self.assertEqual(tcp.sport, external_port)
6879 self.assert_packet_checksums_valid(p)
6881 self.logger.error(ppp("Unexpected or invalid packet:", p))
6884 # from client to server (both VRF1, no translation)
6885 p = (Ether(src=self.pg6.remote_mac, dst=self.pg6.local_mac) /
6886 IP(src=self.pg6.remote_ip4, dst=self.pg5.remote_ip4) /
6887 TCP(sport=12348, dport=local_port))
6888 self.pg6.add_stream(p)
6889 self.pg_enable_capture(self.pg_interfaces)
6891 capture = self.pg5.get_capture(1)
6896 self.assertEqual(ip.dst, self.pg5.remote_ip4)
6897 self.assertEqual(tcp.dport, local_port)
6898 self.assert_packet_checksums_valid(p)
6900 self.logger.error(ppp("Unexpected or invalid packet:", p))
6903 # from server back to client (both VRF1, no translation)
6904 p = (Ether(src=self.pg5.remote_mac, dst=self.pg5.local_mac) /
6905 IP(src=self.pg5.remote_ip4, dst=self.pg6.remote_ip4) /
6906 TCP(sport=local_port, dport=12348))
6907 self.pg5.add_stream(p)
6908 self.pg_enable_capture(self.pg_interfaces)
6910 capture = self.pg6.get_capture(1)
6915 self.assertEqual(ip.src, self.pg5.remote_ip4)
6916 self.assertEqual(tcp.sport, local_port)
6917 self.assert_packet_checksums_valid(p)
6919 self.logger.error(ppp("Unexpected or invalid packet:", p))
6922 # from client VRF1 to server VRF0 (no translation)
6923 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6924 IP(src=self.pg0.remote_ip4, dst=self.pg6.remote_ip4) /
6925 TCP(sport=local_port, dport=12349))
6926 self.pg0.add_stream(p)
6927 self.pg_enable_capture(self.pg_interfaces)
6929 capture = self.pg6.get_capture(1)
6934 self.assertEqual(ip.src, self.pg0.remote_ip4)
6935 self.assertEqual(tcp.sport, local_port)
6936 self.assert_packet_checksums_valid(p)
6938 self.logger.error(ppp("Unexpected or invalid packet:", p))
6941 # from server VRF0 back to client VRF1 (no translation)
6942 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6943 IP(src=self.pg0.remote_ip4, dst=self.pg6.remote_ip4) /
6944 TCP(sport=local_port, dport=12349))
6945 self.pg0.add_stream(p)
6946 self.pg_enable_capture(self.pg_interfaces)
6948 capture = self.pg6.get_capture(1)
6953 self.assertEqual(ip.src, self.pg0.remote_ip4)
6954 self.assertEqual(tcp.sport, local_port)
6955 self.assert_packet_checksums_valid(p)
6957 self.logger.error(ppp("Unexpected or invalid packet:", p))
6960 # from client VRF0 to server VRF1 (no translation)
6961 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6962 IP(src=self.pg0.remote_ip4, dst=self.pg5.remote_ip4) /
6963 TCP(sport=12344, dport=local_port))
6964 self.pg0.add_stream(p)
6965 self.pg_enable_capture(self.pg_interfaces)
6967 capture = self.pg5.get_capture(1)
6972 self.assertEqual(ip.dst, self.pg5.remote_ip4)
6973 self.assertEqual(tcp.dport, local_port)
6974 self.assert_packet_checksums_valid(p)
6976 self.logger.error(ppp("Unexpected or invalid packet:", p))
6979 # from server VRF1 back to client VRF0 (no translation)
6980 p = (Ether(src=self.pg5.remote_mac, dst=self.pg5.local_mac) /
6981 IP(src=self.pg5.remote_ip4, dst=self.pg0.remote_ip4) /
6982 TCP(sport=local_port, dport=12344))
6983 self.pg5.add_stream(p)
6984 self.pg_enable_capture(self.pg_interfaces)
6986 capture = self.pg0.get_capture(1)
6991 self.assertEqual(ip.src, self.pg5.remote_ip4)
6992 self.assertEqual(tcp.sport, local_port)
6993 self.assert_packet_checksums_valid(p)
6995 self.logger.error(ppp("Unexpected or invalid packet:", p))
6998 @unittest.skipUnless(running_extended_tests, "part of extended tests")
6999 def test_session_timeout(self):
7000 """ NAT44 session timeouts """
7001 self.nat44_add_address(self.nat_addr)
7002 flags = self.config_flags.NAT_IS_INSIDE
7003 self.vapi.nat44_interface_add_del_feature(
7004 sw_if_index=self.pg0.sw_if_index,
7005 flags=flags, is_add=1)
7006 self.vapi.nat44_interface_add_del_feature(
7007 sw_if_index=self.pg1.sw_if_index,
7009 self.vapi.nat_set_timeouts(udp=300, tcp_established=7440,
7010 tcp_transitory=240, icmp=5)
7014 for i in range(0, max_sessions):
7015 src = "10.10.%u.%u" % ((i & 0xFF00) >> 8, i & 0xFF)
7016 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
7017 IP(src=src, dst=self.pg1.remote_ip4) /
7018 ICMP(id=1025, type='echo-request'))
7020 self.pg0.add_stream(pkts)
7021 self.pg_enable_capture(self.pg_interfaces)
7023 self.pg1.get_capture(max_sessions)
7028 for i in range(0, max_sessions):
7029 src = "10.11.%u.%u" % ((i & 0xFF00) >> 8, i & 0xFF)
7030 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
7031 IP(src=src, dst=self.pg1.remote_ip4) /
7032 ICMP(id=1026, type='echo-request'))
7034 self.pg0.add_stream(pkts)
7035 self.pg_enable_capture(self.pg_interfaces)
7037 self.pg1.get_capture(max_sessions)
7040 users = self.vapi.nat44_user_dump()
7042 nsessions = nsessions + user.nsessions
7043 self.assertLess(nsessions, 2 * max_sessions)
7045 @unittest.skipUnless(running_extended_tests, "part of extended tests")
7046 def test_session_rst_timeout(self):
7047 """ NAT44 session RST timeouts """
7048 self.nat44_add_address(self.nat_addr)
7049 flags = self.config_flags.NAT_IS_INSIDE
7050 self.vapi.nat44_interface_add_del_feature(
7051 sw_if_index=self.pg0.sw_if_index,
7052 flags=flags, is_add=1)
7053 self.vapi.nat44_interface_add_del_feature(
7054 sw_if_index=self.pg1.sw_if_index,
7056 self.vapi.nat_set_timeouts(udp=300, tcp_established=7440,
7057 tcp_transitory=5, icmp=60)
7059 self.initiate_tcp_session(self.pg0, self.pg1)
7060 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
7061 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
7062 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
7064 self.pg0.add_stream(p)
7065 self.pg_enable_capture(self.pg_interfaces)
7067 self.pg1.get_capture(1)
7071 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
7072 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
7073 TCP(sport=self.tcp_port_in + 1, dport=self.tcp_external_port + 1,
7075 self.pg0.add_stream(p)
7076 self.pg_enable_capture(self.pg_interfaces)
7078 self.pg1.get_capture(1)
7080 def test_syslog_sess(self):
7081 """ Test syslog session creation and deletion """
7082 self.vapi.syslog_set_filter(
7083 self.SYSLOG_SEVERITY.SYSLOG_API_SEVERITY_INFO)
7084 self.vapi.syslog_set_sender(self.pg2.local_ip4, self.pg2.remote_ip4)
7085 self.nat44_add_address(self.nat_addr)
7086 flags = self.config_flags.NAT_IS_INSIDE
7087 self.vapi.nat44_interface_add_del_feature(
7088 sw_if_index=self.pg0.sw_if_index,
7089 flags=flags, is_add=1)
7090 self.vapi.nat44_interface_add_del_feature(
7091 sw_if_index=self.pg1.sw_if_index,
7094 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
7095 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
7096 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port))
7097 self.pg0.add_stream(p)
7098 self.pg_enable_capture(self.pg_interfaces)
7100 capture = self.pg1.get_capture(1)
7101 self.tcp_port_out = capture[0][TCP].sport
7102 capture = self.pg2.get_capture(1)
7103 self.verify_syslog_sess(capture[0][Raw].load)
7105 self.pg_enable_capture(self.pg_interfaces)
7107 self.nat44_add_address(self.nat_addr, is_add=0)
7108 capture = self.pg2.get_capture(1)
7109 self.verify_syslog_sess(capture[0][Raw].load, False)
7111 def test_ed_users_dump(self):
7112 """ API test - nat44_user_dump """
7113 flags = self.config_flags.NAT_IS_INSIDE
7114 self.vapi.nat44_interface_add_del_feature(
7115 sw_if_index=self.pg0.sw_if_index,
7116 flags=flags, is_add=1)
7117 self.vapi.nat44_interface_add_del_feature(
7118 sw_if_index=self.pg1.sw_if_index,
7120 self.vapi.nat44_forwarding_enable_disable(enable=1)
7122 real_ip = self.pg0.remote_ip4
7123 alias_ip = self.nat_addr
7124 flags = self.config_flags.NAT_IS_ADDR_ONLY
7125 self.vapi.nat44_add_del_static_mapping(is_add=1,
7126 local_ip_address=real_ip,
7127 external_ip_address=alias_ip,
7128 external_sw_if_index=0xFFFFFFFF,
7131 users = self.vapi.nat44_user_dump()
7132 self.assertEqual(len(users), 0)
7134 # in2out - static mapping match
7136 pkts = self.create_stream_out(self.pg1)
7137 self.pg1.add_stream(pkts)
7138 self.pg_enable_capture(self.pg_interfaces)
7140 capture = self.pg0.get_capture(len(pkts))
7141 self.verify_capture_in(capture, self.pg0)
7143 pkts = self.create_stream_in(self.pg0, self.pg1)
7144 self.pg0.add_stream(pkts)
7145 self.pg_enable_capture(self.pg_interfaces)
7147 capture = self.pg1.get_capture(len(pkts))
7148 self.verify_capture_out(capture, same_port=True)
7150 users = self.vapi.nat44_user_dump()
7151 self.assertEqual(len(users), 1)
7152 static_user = users[0]
7153 self.assertEqual(static_user.nstaticsessions, 3)
7154 self.assertEqual(static_user.nsessions, 0)
7156 # in2out - no static mapping match
7158 host0 = self.pg0.remote_hosts[0]
7159 self.pg0.remote_hosts[0] = self.pg0.remote_hosts[1]
7161 pkts = self.create_stream_out(self.pg1,
7162 dst_ip=self.pg0.remote_ip4,
7163 use_inside_ports=True)
7164 self.pg1.add_stream(pkts)
7165 self.pg_enable_capture(self.pg_interfaces)
7167 capture = self.pg0.get_capture(len(pkts))
7168 self.verify_capture_in(capture, self.pg0)
7170 pkts = self.create_stream_in(self.pg0, self.pg1)
7171 self.pg0.add_stream(pkts)
7172 self.pg_enable_capture(self.pg_interfaces)
7174 capture = self.pg1.get_capture(len(pkts))
7175 self.verify_capture_out(capture, nat_ip=self.pg0.remote_ip4,
7178 self.pg0.remote_hosts[0] = host0
7180 users = self.vapi.nat44_user_dump()
7181 self.assertEqual(len(users), 2)
7182 if str(users[0].ip_address) == self.pg0.remote_hosts[0].ip4:
7183 non_static_user = users[1]
7184 static_user = users[0]
7186 non_static_user = users[0]
7187 static_user = users[1]
7188 self.assertEqual(static_user.nstaticsessions, 3)
7189 self.assertEqual(static_user.nsessions, 0)
7190 self.assertEqual(non_static_user.nstaticsessions, 0)
7191 self.assertEqual(non_static_user.nsessions, 3)
7193 users = self.vapi.nat44_user_dump()
7194 self.assertEqual(len(users), 2)
7195 if str(users[0].ip_address) == self.pg0.remote_hosts[0].ip4:
7196 non_static_user = users[1]
7197 static_user = users[0]
7199 non_static_user = users[0]
7200 static_user = users[1]
7201 self.assertEqual(static_user.nstaticsessions, 3)
7202 self.assertEqual(static_user.nsessions, 0)
7203 self.assertEqual(non_static_user.nstaticsessions, 0)
7204 self.assertEqual(non_static_user.nsessions, 3)
7207 self.vapi.nat44_forwarding_enable_disable(enable=0)
7208 flags = self.config_flags.NAT_IS_ADDR_ONLY
7209 self.vapi.nat44_add_del_static_mapping(
7211 local_ip_address=real_ip,
7212 external_ip_address=alias_ip,
7213 external_sw_if_index=0xFFFFFFFF,
7217 super(TestNAT44EndpointDependent, self).tearDown()
7218 if not self.vpp_dead:
7220 self.vapi.cli("clear logging")
7222 def show_commands_at_teardown(self):
7223 self.logger.info(self.vapi.cli("show errors"))
7224 self.logger.info(self.vapi.cli("show nat44 addresses"))
7225 self.logger.info(self.vapi.cli("show nat44 interfaces"))
7226 self.logger.info(self.vapi.cli("show nat44 static mappings"))
7227 self.logger.info(self.vapi.cli("show nat44 interface address"))
7228 self.logger.info(self.vapi.cli("show nat44 sessions detail"))
7229 self.logger.info(self.vapi.cli("show nat44 hash tables detail"))
7230 self.logger.info(self.vapi.cli("show nat timeouts"))
7231 self.logger.info(self.vapi.cli("debug nat44 fib registration"))
7234 class TestNAT44EndpointDependent3(MethodHolder):
7235 """ Endpoint-Dependent mapping and filtering extra test cases """
7237 max_translations = 50
7240 def setUpConstants(cls):
7241 super(TestNAT44EndpointDependent3, cls).setUpConstants()
7242 cls.vpp_cmdline.extend([
7243 "nat", "{", "endpoint-dependent",
7244 "max translations per thread %d" % cls.max_translations,
7249 def setUpClass(cls):
7250 super(TestNAT44EndpointDependent3, cls).setUpClass()
7251 cls.vapi.cli("set log class nat level debug")
7253 cls.nat_addr = '10.0.0.3'
7255 cls.create_pg_interfaces(range(2))
7257 for i in cls.pg_interfaces:
7263 super(TestNAT44EndpointDependent3, self).setUp()
7264 self.vapi.nat_set_timeouts(
7265 udp=1, tcp_established=7440, tcp_transitory=30, icmp=1)
7266 self.nat44_add_address(self.nat_addr)
7267 flags = self.config_flags.NAT_IS_INSIDE
7268 self.vapi.nat44_interface_add_del_feature(
7269 sw_if_index=self.pg0.sw_if_index, flags=flags, is_add=1)
7270 self.vapi.nat44_interface_add_del_feature(
7271 sw_if_index=self.pg1.sw_if_index, is_add=1)
7274 def tearDownClass(cls):
7275 super(TestNAT44EndpointDependent3, cls).tearDownClass()
7277 def init_tcp_session(self, in_if, out_if, sport, ext_dport):
7278 # SYN packet in->out
7279 p = (Ether(src=in_if.remote_mac, dst=in_if.local_mac) /
7280 IP(src=in_if.remote_ip4, dst=out_if.remote_ip4) /
7281 TCP(sport=sport, dport=ext_dport, flags="S"))
7283 self.pg_enable_capture(self.pg_interfaces)
7285 capture = out_if.get_capture(1)
7287 tcp_port_out = p[TCP].sport
7289 # SYN + ACK packet out->in
7290 p = (Ether(src=out_if.remote_mac, dst=out_if.local_mac) /
7291 IP(src=out_if.remote_ip4, dst=self.nat_addr) /
7292 TCP(sport=ext_dport, dport=tcp_port_out, flags="SA"))
7293 out_if.add_stream(p)
7294 self.pg_enable_capture(self.pg_interfaces)
7296 in_if.get_capture(1)
7298 # ACK packet in->out
7299 p = (Ether(src=in_if.remote_mac, dst=in_if.local_mac) /
7300 IP(src=in_if.remote_ip4, dst=out_if.remote_ip4) /
7301 TCP(sport=sport, dport=ext_dport, flags="A"))
7303 self.pg_enable_capture(self.pg_interfaces)
7305 out_if.get_capture(1)
7309 def test_lru_cleanup(self):
7310 """ LRU cleanup algorithm """
7311 tcp_port_out = self.init_tcp_session(self.pg0, self.pg1, 2000, 80)
7313 for i in range(0, self.max_translations - 1):
7314 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
7315 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4, ttl=64) /
7316 UDP(sport=7000+i, dport=80))
7319 self.pg0.add_stream(pkts)
7320 self.pg_enable_capture(self.pg_interfaces)
7322 self.pg1.get_capture(len(pkts))
7323 self.sleep(1.5, "wait for timeouts")
7326 for i in range(0, self.max_translations - 1):
7327 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
7328 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4, ttl=64) /
7329 ICMP(id=8000+i, type='echo-request'))
7332 self.pg0.add_stream(pkts)
7333 self.pg_enable_capture(self.pg_interfaces)
7335 self.pg1.get_capture(len(pkts))
7338 class TestNAT44Out2InDPO(MethodHolder):
7339 """ NAT44 Test Cases using out2in DPO """
7342 def setUpConstants(cls):
7343 super(TestNAT44Out2InDPO, cls).setUpConstants()
7344 cls.vpp_cmdline.extend(["nat", "{", "out2in dpo", "}"])
7347 def setUpClass(cls):
7348 super(TestNAT44Out2InDPO, cls).setUpClass()
7349 cls.vapi.cli("set log class nat level debug")
7351 cls.tcp_port_in = 6303
7352 cls.tcp_port_out = 6303
7353 cls.udp_port_in = 6304
7354 cls.udp_port_out = 6304
7355 cls.icmp_id_in = 6305
7356 cls.icmp_id_out = 6305
7357 cls.nat_addr = '10.0.0.3'
7358 cls.dst_ip4 = '192.168.70.1'
7360 cls.create_pg_interfaces(range(2))
7363 cls.pg0.config_ip4()
7364 cls.pg0.resolve_arp()
7367 cls.pg1.config_ip6()
7368 cls.pg1.resolve_ndp()
7370 r1 = VppIpRoute(cls, "::", 0,
7371 [VppRoutePath(cls.pg1.remote_ip6,
7372 cls.pg1.sw_if_index)],
7377 def tearDownClass(cls):
7378 super(TestNAT44Out2InDPO, cls).tearDownClass()
7380 def configure_xlat(self):
7381 self.dst_ip6_pfx = '1:2:3::'
7382 self.dst_ip6_pfx_n = socket.inet_pton(socket.AF_INET6,
7384 self.dst_ip6_pfx_len = 96
7385 self.src_ip6_pfx = '4:5:6::'
7386 self.src_ip6_pfx_n = socket.inet_pton(socket.AF_INET6,
7388 self.src_ip6_pfx_len = 96
7389 self.vapi.map_add_domain(self.dst_ip6_pfx_n, self.dst_ip6_pfx_len,
7390 self.src_ip6_pfx_n, self.src_ip6_pfx_len,
7391 '\x00\x00\x00\x00', 0)
7393 @unittest.skip('Temporary disabled')
7394 def test_464xlat_ce(self):
7395 """ Test 464XLAT CE with NAT44 """
7397 nat_config = self.vapi.nat_show_config()
7398 self.assertEqual(1, nat_config.out2in_dpo)
7400 self.configure_xlat()
7402 flags = self.config_flags.NAT_IS_INSIDE
7403 self.vapi.nat44_interface_add_del_feature(
7404 sw_if_index=self.pg0.sw_if_index,
7405 flags=flags, is_add=1)
7406 self.vapi.nat44_add_del_address_range(first_ip_address=self.nat_addr_n,
7407 last_ip_address=self.nat_addr_n,
7408 vrf_id=0xFFFFFFFF, is_add=1)
7410 out_src_ip6 = self.compose_ip6(self.dst_ip4, self.dst_ip6_pfx,
7411 self.dst_ip6_pfx_len)
7412 out_dst_ip6 = self.compose_ip6(self.nat_addr, self.src_ip6_pfx,
7413 self.src_ip6_pfx_len)
7416 pkts = self.create_stream_in(self.pg0, self.pg1, self.dst_ip4)
7417 self.pg0.add_stream(pkts)
7418 self.pg_enable_capture(self.pg_interfaces)
7420 capture = self.pg1.get_capture(len(pkts))
7421 self.verify_capture_out_ip6(capture, nat_ip=out_dst_ip6,
7424 pkts = self.create_stream_out_ip6(self.pg1, out_src_ip6,
7426 self.pg1.add_stream(pkts)
7427 self.pg_enable_capture(self.pg_interfaces)
7429 capture = self.pg0.get_capture(len(pkts))
7430 self.verify_capture_in(capture, self.pg0)
7432 self.vapi.nat44_interface_add_del_feature(
7433 sw_if_index=self.pg0.sw_if_index,
7435 self.vapi.nat44_add_del_address_range(
7436 first_ip_address=self.nat_addr_n,
7437 last_ip_address=self.nat_addr_n,
7440 @unittest.skip('Temporary disabled')
7441 def test_464xlat_ce_no_nat(self):
7442 """ Test 464XLAT CE without NAT44 """
7444 self.configure_xlat()
7446 out_src_ip6 = self.compose_ip6(self.dst_ip4, self.dst_ip6_pfx,
7447 self.dst_ip6_pfx_len)
7448 out_dst_ip6 = self.compose_ip6(self.pg0.remote_ip4, self.src_ip6_pfx,
7449 self.src_ip6_pfx_len)
7451 pkts = self.create_stream_in(self.pg0, self.pg1, self.dst_ip4)
7452 self.pg0.add_stream(pkts)
7453 self.pg_enable_capture(self.pg_interfaces)
7455 capture = self.pg1.get_capture(len(pkts))
7456 self.verify_capture_out_ip6(capture, dst_ip=out_src_ip6,
7457 nat_ip=out_dst_ip6, same_port=True)
7459 pkts = self.create_stream_out_ip6(self.pg1, out_src_ip6, out_dst_ip6)
7460 self.pg1.add_stream(pkts)
7461 self.pg_enable_capture(self.pg_interfaces)
7463 capture = self.pg0.get_capture(len(pkts))
7464 self.verify_capture_in(capture, self.pg0)
7467 class TestNAT64(MethodHolder):
7468 """ NAT64 Test Cases """
7471 def setUpConstants(cls):
7472 super(TestNAT64, cls).setUpConstants()
7473 cls.vpp_cmdline.extend(["nat", "{", "nat64 bib hash buckets 128",
7474 "nat64 st hash buckets 256", "}"])
7477 def setUpClass(cls):
7478 super(TestNAT64, cls).setUpClass()
7480 cls.tcp_port_in = 6303
7481 cls.tcp_port_out = 6303
7482 cls.udp_port_in = 6304
7483 cls.udp_port_out = 6304
7484 cls.icmp_id_in = 6305
7485 cls.icmp_id_out = 6305
7486 cls.tcp_external_port = 80
7487 cls.nat_addr = '10.0.0.3'
7488 cls.nat_addr_n = socket.inet_pton(socket.AF_INET, cls.nat_addr)
7490 cls.vrf1_nat_addr = '10.0.10.3'
7491 cls.ipfix_src_port = 4739
7492 cls.ipfix_domain_id = 1
7494 cls.create_pg_interfaces(range(6))
7495 cls.ip6_interfaces = list(cls.pg_interfaces[0:1])
7496 cls.ip6_interfaces.append(cls.pg_interfaces[2])
7497 cls.ip4_interfaces = list(cls.pg_interfaces[1:2])
7499 cls.vapi.ip_table_add_del(is_add=1,
7500 table={'table_id': cls.vrf1_id,
7503 cls.pg_interfaces[2].set_table_ip6(cls.vrf1_id)
7505 cls.pg0.generate_remote_hosts(2)
7507 for i in cls.ip6_interfaces:
7510 i.configure_ipv6_neighbors()
7512 for i in cls.ip4_interfaces:
7518 cls.pg3.config_ip4()
7519 cls.pg3.resolve_arp()
7520 cls.pg3.config_ip6()
7521 cls.pg3.configure_ipv6_neighbors()
7524 cls.pg5.config_ip6()
7527 def tearDownClass(cls):
7528 super(TestNAT64, cls).tearDownClass()
7530 def test_nat64_inside_interface_handles_neighbor_advertisement(self):
7531 """ NAT64 inside interface handles Neighbor Advertisement """
7533 flags = self.config_flags.NAT_IS_INSIDE
7534 self.vapi.nat64_add_del_interface(is_add=1, flags=flags,
7535 sw_if_index=self.pg5.sw_if_index)
7538 ping = (Ether(dst=self.pg5.local_mac, src=self.pg5.remote_mac) /
7539 IPv6(src=self.pg5.remote_ip6, dst=self.pg5.local_ip6) /
7540 ICMPv6EchoRequest())
7542 self.pg5.add_stream(pkts)
7543 self.pg_enable_capture(self.pg_interfaces)
7546 # Wait for Neighbor Solicitation
7547 capture = self.pg5.get_capture(len(pkts))
7550 self.assertEqual(packet[IPv6].src, self.pg5.local_ip6)
7551 self.assertEqual(packet.haslayer(ICMPv6ND_NS), 1)
7552 tgt = packet[ICMPv6ND_NS].tgt
7554 self.logger.error(ppp("Unexpected or invalid packet:", packet))
7557 # Send Neighbor Advertisement
7558 p = (Ether(dst=self.pg5.local_mac, src=self.pg5.remote_mac) /
7559 IPv6(src=self.pg5.remote_ip6, dst=self.pg5.local_ip6) /
7560 ICMPv6ND_NA(tgt=tgt) /
7561 ICMPv6NDOptDstLLAddr(lladdr=self.pg5.remote_mac))
7563 self.pg5.add_stream(pkts)
7564 self.pg_enable_capture(self.pg_interfaces)
7567 # Try to send ping again
7569 self.pg5.add_stream(pkts)
7570 self.pg_enable_capture(self.pg_interfaces)
7573 # Wait for ping reply
7574 capture = self.pg5.get_capture(len(pkts))
7577 self.assertEqual(packet[IPv6].src, self.pg5.local_ip6)
7578 self.assertEqual(packet[IPv6].dst, self.pg5.remote_ip6)
7579 self.assertEqual(packet.haslayer(ICMPv6EchoReply), 1)
7581 self.logger.error(ppp("Unexpected or invalid packet:", packet))
7584 def test_pool(self):
7585 """ Add/delete address to NAT64 pool """
7586 nat_addr = '1.2.3.4'
7588 self.vapi.nat64_add_del_pool_addr_range(start_addr=nat_addr,
7590 vrf_id=0xFFFFFFFF, is_add=1)
7592 addresses = self.vapi.nat64_pool_addr_dump()
7593 self.assertEqual(len(addresses), 1)
7594 self.assertEqual(str(addresses[0].address), nat_addr)
7596 self.vapi.nat64_add_del_pool_addr_range(start_addr=nat_addr,
7598 vrf_id=0xFFFFFFFF, is_add=0)
7600 addresses = self.vapi.nat64_pool_addr_dump()
7601 self.assertEqual(len(addresses), 0)
7603 def test_interface(self):
7604 """ Enable/disable NAT64 feature on the interface """
7605 flags = self.config_flags.NAT_IS_INSIDE
7606 self.vapi.nat64_add_del_interface(is_add=1, flags=flags,
7607 sw_if_index=self.pg0.sw_if_index)
7608 self.vapi.nat64_add_del_interface(is_add=1, flags=0,
7609 sw_if_index=self.pg1.sw_if_index)
7611 interfaces = self.vapi.nat64_interface_dump()
7612 self.assertEqual(len(interfaces), 2)
7615 for intf in interfaces:
7616 if intf.sw_if_index == self.pg0.sw_if_index:
7617 self.assertEqual(intf.flags, self.config_flags.NAT_IS_INSIDE)
7619 elif intf.sw_if_index == self.pg1.sw_if_index:
7620 self.assertEqual(intf.flags, self.config_flags.NAT_IS_OUTSIDE)
7622 self.assertTrue(pg0_found)
7623 self.assertTrue(pg1_found)
7625 features = self.vapi.cli("show interface features pg0")
7626 self.assertIn('nat64-in2out', features)
7627 features = self.vapi.cli("show interface features pg1")
7628 self.assertIn('nat64-out2in', features)
7630 self.vapi.nat64_add_del_interface(is_add=0, flags=flags,
7631 sw_if_index=self.pg0.sw_if_index)
7632 self.vapi.nat64_add_del_interface(is_add=0, flags=flags,
7633 sw_if_index=self.pg1.sw_if_index)
7635 interfaces = self.vapi.nat64_interface_dump()
7636 self.assertEqual(len(interfaces), 0)
7638 def test_static_bib(self):
7639 """ Add/delete static BIB entry """
7640 in_addr = '2001:db8:85a3::8a2e:370:7334'
7641 out_addr = '10.1.1.3'
7644 proto = IP_PROTOS.tcp
7646 self.vapi.nat64_add_del_static_bib(i_addr=in_addr, o_addr=out_addr,
7647 i_port=in_port, o_port=out_port,
7648 proto=proto, vrf_id=0, is_add=1)
7649 bib = self.vapi.nat64_bib_dump(proto=IP_PROTOS.tcp)
7652 if bibe.flags & self.config_flags.NAT_IS_STATIC:
7654 self.assertEqual(str(bibe.i_addr), in_addr)
7655 self.assertEqual(str(bibe.o_addr), out_addr)
7656 self.assertEqual(bibe.i_port, in_port)
7657 self.assertEqual(bibe.o_port, out_port)
7658 self.assertEqual(static_bib_num, 1)
7659 bibs = self.statistics.get_counter('/nat64/total-bibs')
7660 self.assertEqual(bibs[0][0], 1)
7662 self.vapi.nat64_add_del_static_bib(i_addr=in_addr, o_addr=out_addr,
7663 i_port=in_port, o_port=out_port,
7664 proto=proto, vrf_id=0, is_add=0)
7665 bib = self.vapi.nat64_bib_dump(proto=IP_PROTOS.tcp)
7668 if bibe.flags & self.config_flags.NAT_IS_STATIC:
7670 self.assertEqual(static_bib_num, 0)
7671 bibs = self.statistics.get_counter('/nat64/total-bibs')
7672 self.assertEqual(bibs[0][0], 0)
7674 def test_set_timeouts(self):
7675 """ Set NAT64 timeouts """
7676 # verify default values
7677 timeouts = self.vapi.nat_get_timeouts()
7678 self.assertEqual(timeouts.udp, 300)
7679 self.assertEqual(timeouts.icmp, 60)
7680 self.assertEqual(timeouts.tcp_transitory, 240)
7681 self.assertEqual(timeouts.tcp_established, 7440)
7683 # set and verify custom values
7684 self.vapi.nat_set_timeouts(udp=200, tcp_established=7450,
7685 tcp_transitory=250, icmp=30)
7686 timeouts = self.vapi.nat_get_timeouts()
7687 self.assertEqual(timeouts.udp, 200)
7688 self.assertEqual(timeouts.icmp, 30)
7689 self.assertEqual(timeouts.tcp_transitory, 250)
7690 self.assertEqual(timeouts.tcp_established, 7450)
7692 def test_dynamic(self):
7693 """ NAT64 dynamic translation test """
7694 self.tcp_port_in = 6303
7695 self.udp_port_in = 6304
7696 self.icmp_id_in = 6305
7698 ses_num_start = self.nat64_get_ses_num()
7700 self.vapi.nat64_add_del_pool_addr_range(start_addr=self.nat_addr,
7701 end_addr=self.nat_addr,
7704 flags = self.config_flags.NAT_IS_INSIDE
7705 self.vapi.nat64_add_del_interface(is_add=1, flags=flags,
7706 sw_if_index=self.pg0.sw_if_index)
7707 self.vapi.nat64_add_del_interface(is_add=1, flags=0,
7708 sw_if_index=self.pg1.sw_if_index)
7711 tcpn = self.statistics.get_counter('/nat64/in2out/tcp')[0]
7712 udpn = self.statistics.get_counter('/nat64/in2out/udp')[0]
7713 icmpn = self.statistics.get_counter('/nat64/in2out/icmp')[0]
7714 drops = self.statistics.get_counter('/nat64/in2out/drops')[0]
7716 pkts = self.create_stream_in_ip6(self.pg0, self.pg1)
7717 self.pg0.add_stream(pkts)
7718 self.pg_enable_capture(self.pg_interfaces)
7720 capture = self.pg1.get_capture(len(pkts))
7721 self.verify_capture_out(capture, nat_ip=self.nat_addr,
7722 dst_ip=self.pg1.remote_ip4)
7724 if_idx = self.pg0.sw_if_index
7725 cnt = self.statistics.get_counter('/nat64/in2out/tcp')[0]
7726 self.assertEqual(cnt[if_idx] - tcpn[if_idx], 1)
7727 cnt = self.statistics.get_counter('/nat64/in2out/udp')[0]
7728 self.assertEqual(cnt[if_idx] - udpn[if_idx], 1)
7729 cnt = self.statistics.get_counter('/nat64/in2out/icmp')[0]
7730 self.assertEqual(cnt[if_idx] - icmpn[if_idx], 1)
7731 cnt = self.statistics.get_counter('/nat64/in2out/drops')[0]
7732 self.assertEqual(cnt[if_idx] - drops[if_idx], 0)
7735 tcpn = self.statistics.get_counter('/nat64/out2in/tcp')[0]
7736 udpn = self.statistics.get_counter('/nat64/out2in/udp')[0]
7737 icmpn = self.statistics.get_counter('/nat64/out2in/icmp')[0]
7738 drops = self.statistics.get_counter('/nat64/out2in/drops')[0]
7740 pkts = self.create_stream_out(self.pg1, dst_ip=self.nat_addr)
7741 self.pg1.add_stream(pkts)
7742 self.pg_enable_capture(self.pg_interfaces)
7744 capture = self.pg0.get_capture(len(pkts))
7745 ip = IPv6(src=''.join(['64:ff9b::', self.pg1.remote_ip4]))
7746 self.verify_capture_in_ip6(capture, ip[IPv6].src, self.pg0.remote_ip6)
7748 if_idx = self.pg1.sw_if_index
7749 cnt = self.statistics.get_counter('/nat64/out2in/tcp')[0]
7750 self.assertEqual(cnt[if_idx] - tcpn[if_idx], 2)
7751 cnt = self.statistics.get_counter('/nat64/out2in/udp')[0]
7752 self.assertEqual(cnt[if_idx] - udpn[if_idx], 1)
7753 cnt = self.statistics.get_counter('/nat64/out2in/icmp')[0]
7754 self.assertEqual(cnt[if_idx] - icmpn[if_idx], 1)
7755 cnt = self.statistics.get_counter('/nat64/out2in/drops')[0]
7756 self.assertEqual(cnt[if_idx] - drops[if_idx], 0)
7758 bibs = self.statistics.get_counter('/nat64/total-bibs')
7759 self.assertEqual(bibs[0][0], 3)
7760 sessions = self.statistics.get_counter('/nat64/total-sessions')
7761 self.assertEqual(sessions[0][0], 3)
7764 pkts = self.create_stream_in_ip6(self.pg0, self.pg1)
7765 self.pg0.add_stream(pkts)
7766 self.pg_enable_capture(self.pg_interfaces)
7768 capture = self.pg1.get_capture(len(pkts))
7769 self.verify_capture_out(capture, nat_ip=self.nat_addr,
7770 dst_ip=self.pg1.remote_ip4)
7773 pkts = self.create_stream_out(self.pg1, dst_ip=self.nat_addr)
7774 self.pg1.add_stream(pkts)
7775 self.pg_enable_capture(self.pg_interfaces)
7777 capture = self.pg0.get_capture(len(pkts))
7778 self.verify_capture_in_ip6(capture, ip[IPv6].src, self.pg0.remote_ip6)
7780 ses_num_end = self.nat64_get_ses_num()
7782 self.assertEqual(ses_num_end - ses_num_start, 3)
7784 # tenant with specific VRF
7785 self.vapi.nat64_add_del_pool_addr_range(start_addr=self.vrf1_nat_addr,
7786 end_addr=self.vrf1_nat_addr,
7787 vrf_id=self.vrf1_id, is_add=1)
7788 flags = self.config_flags.NAT_IS_INSIDE
7789 self.vapi.nat64_add_del_interface(is_add=1, flags=flags,
7790 sw_if_index=self.pg2.sw_if_index)
7792 pkts = self.create_stream_in_ip6(self.pg2, self.pg1)
7793 self.pg2.add_stream(pkts)
7794 self.pg_enable_capture(self.pg_interfaces)
7796 capture = self.pg1.get_capture(len(pkts))
7797 self.verify_capture_out(capture, nat_ip=self.vrf1_nat_addr,
7798 dst_ip=self.pg1.remote_ip4)
7800 pkts = self.create_stream_out(self.pg1, dst_ip=self.vrf1_nat_addr)
7801 self.pg1.add_stream(pkts)
7802 self.pg_enable_capture(self.pg_interfaces)
7804 capture = self.pg2.get_capture(len(pkts))
7805 self.verify_capture_in_ip6(capture, ip[IPv6].src, self.pg2.remote_ip6)
7807 def test_static(self):
7808 """ NAT64 static translation test """
7809 self.tcp_port_in = 60303
7810 self.udp_port_in = 60304
7811 self.icmp_id_in = 60305
7812 self.tcp_port_out = 60303
7813 self.udp_port_out = 60304
7814 self.icmp_id_out = 60305
7816 ses_num_start = self.nat64_get_ses_num()
7818 self.vapi.nat64_add_del_pool_addr_range(start_addr=self.nat_addr,
7819 end_addr=self.nat_addr,
7822 flags = self.config_flags.NAT_IS_INSIDE
7823 self.vapi.nat64_add_del_interface(is_add=1, flags=flags,
7824 sw_if_index=self.pg0.sw_if_index)
7825 self.vapi.nat64_add_del_interface(is_add=1, flags=0,
7826 sw_if_index=self.pg1.sw_if_index)
7828 self.vapi.nat64_add_del_static_bib(i_addr=self.pg0.remote_ip6,
7829 o_addr=self.nat_addr,
7830 i_port=self.tcp_port_in,
7831 o_port=self.tcp_port_out,
7832 proto=IP_PROTOS.tcp, vrf_id=0,
7834 self.vapi.nat64_add_del_static_bib(i_addr=self.pg0.remote_ip6,
7835 o_addr=self.nat_addr,
7836 i_port=self.udp_port_in,
7837 o_port=self.udp_port_out,
7838 proto=IP_PROTOS.udp, vrf_id=0,
7840 self.vapi.nat64_add_del_static_bib(i_addr=self.pg0.remote_ip6,
7841 o_addr=self.nat_addr,
7842 i_port=self.icmp_id_in,
7843 o_port=self.icmp_id_out,
7844 proto=IP_PROTOS.icmp, vrf_id=0,
7848 pkts = self.create_stream_in_ip6(self.pg0, self.pg1)
7849 self.pg0.add_stream(pkts)
7850 self.pg_enable_capture(self.pg_interfaces)
7852 capture = self.pg1.get_capture(len(pkts))
7853 self.verify_capture_out(capture, nat_ip=self.nat_addr,
7854 dst_ip=self.pg1.remote_ip4, same_port=True)
7857 pkts = self.create_stream_out(self.pg1, dst_ip=self.nat_addr)
7858 self.pg1.add_stream(pkts)
7859 self.pg_enable_capture(self.pg_interfaces)
7861 capture = self.pg0.get_capture(len(pkts))
7862 ip = IPv6(src=''.join(['64:ff9b::', self.pg1.remote_ip4]))
7863 self.verify_capture_in_ip6(capture, ip[IPv6].src, self.pg0.remote_ip6)
7865 ses_num_end = self.nat64_get_ses_num()
7867 self.assertEqual(ses_num_end - ses_num_start, 3)
7869 @unittest.skipUnless(running_extended_tests, "part of extended tests")
7870 def test_session_timeout(self):
7871 """ NAT64 session timeout """
7872 self.icmp_id_in = 1234
7873 self.vapi.nat64_add_del_pool_addr_range(start_addr=self.nat_addr,
7874 end_addr=self.nat_addr,
7877 flags = self.config_flags.NAT_IS_INSIDE
7878 self.vapi.nat64_add_del_interface(is_add=1, flags=flags,
7879 sw_if_index=self.pg0.sw_if_index)
7880 self.vapi.nat64_add_del_interface(is_add=1, flags=0,
7881 sw_if_index=self.pg1.sw_if_index)
7882 self.vapi.nat_set_timeouts(udp=300, tcp_established=5,
7886 pkts = self.create_stream_in_ip6(self.pg0, self.pg1)
7887 self.pg0.add_stream(pkts)
7888 self.pg_enable_capture(self.pg_interfaces)
7890 capture = self.pg1.get_capture(len(pkts))
7892 ses_num_before_timeout = self.nat64_get_ses_num()
7896 # ICMP and TCP session after timeout
7897 ses_num_after_timeout = self.nat64_get_ses_num()
7898 self.assertEqual(ses_num_before_timeout - ses_num_after_timeout, 2)
7900 def test_icmp_error(self):
7901 """ NAT64 ICMP Error message translation """
7902 self.tcp_port_in = 6303
7903 self.udp_port_in = 6304
7904 self.icmp_id_in = 6305
7906 self.vapi.nat64_add_del_pool_addr_range(start_addr=self.nat_addr,
7907 end_addr=self.nat_addr,
7910 flags = self.config_flags.NAT_IS_INSIDE
7911 self.vapi.nat64_add_del_interface(is_add=1, flags=flags,
7912 sw_if_index=self.pg0.sw_if_index)
7913 self.vapi.nat64_add_del_interface(is_add=1, flags=0,
7914 sw_if_index=self.pg1.sw_if_index)
7916 # send some packets to create sessions
7917 pkts = self.create_stream_in_ip6(self.pg0, self.pg1)
7918 self.pg0.add_stream(pkts)
7919 self.pg_enable_capture(self.pg_interfaces)
7921 capture_ip4 = self.pg1.get_capture(len(pkts))
7922 self.verify_capture_out(capture_ip4,
7923 nat_ip=self.nat_addr,
7924 dst_ip=self.pg1.remote_ip4)
7926 pkts = self.create_stream_out(self.pg1, dst_ip=self.nat_addr)
7927 self.pg1.add_stream(pkts)
7928 self.pg_enable_capture(self.pg_interfaces)
7930 capture_ip6 = self.pg0.get_capture(len(pkts))
7931 ip = IPv6(src=''.join(['64:ff9b::', self.pg1.remote_ip4]))
7932 self.verify_capture_in_ip6(capture_ip6, ip[IPv6].src,
7933 self.pg0.remote_ip6)
7936 pkts = [Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
7937 IPv6(src=self.pg0.remote_ip6, dst=ip[IPv6].src) /
7938 ICMPv6DestUnreach(code=1) /
7939 packet[IPv6] for packet in capture_ip6]
7940 self.pg0.add_stream(pkts)
7941 self.pg_enable_capture(self.pg_interfaces)
7943 capture = self.pg1.get_capture(len(pkts))
7944 for packet in capture:
7946 self.assertEqual(packet[IP].src, self.nat_addr)
7947 self.assertEqual(packet[IP].dst, self.pg1.remote_ip4)
7948 self.assertEqual(packet[ICMP].type, 3)
7949 self.assertEqual(packet[ICMP].code, 13)
7950 inner = packet[IPerror]
7951 self.assertEqual(inner.src, self.pg1.remote_ip4)
7952 self.assertEqual(inner.dst, self.nat_addr)
7953 self.assert_packet_checksums_valid(packet)
7954 if inner.haslayer(TCPerror):
7955 self.assertEqual(inner[TCPerror].dport, self.tcp_port_out)
7956 elif inner.haslayer(UDPerror):
7957 self.assertEqual(inner[UDPerror].dport, self.udp_port_out)
7959 self.assertEqual(inner[ICMPerror].id, self.icmp_id_out)
7961 self.logger.error(ppp("Unexpected or invalid packet:", packet))
7965 pkts = [Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
7966 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
7967 ICMP(type=3, code=13) /
7968 packet[IP] for packet in capture_ip4]
7969 self.pg1.add_stream(pkts)
7970 self.pg_enable_capture(self.pg_interfaces)
7972 capture = self.pg0.get_capture(len(pkts))
7973 for packet in capture:
7975 self.assertEqual(packet[IPv6].src, ip.src)
7976 self.assertEqual(packet[IPv6].dst, self.pg0.remote_ip6)
7977 icmp = packet[ICMPv6DestUnreach]
7978 self.assertEqual(icmp.code, 1)
7979 inner = icmp[IPerror6]
7980 self.assertEqual(inner.src, self.pg0.remote_ip6)
7981 self.assertEqual(inner.dst, ip.src)
7982 self.assert_icmpv6_checksum_valid(packet)
7983 if inner.haslayer(TCPerror):
7984 self.assertEqual(inner[TCPerror].sport, self.tcp_port_in)
7985 elif inner.haslayer(UDPerror):
7986 self.assertEqual(inner[UDPerror].sport, self.udp_port_in)
7988 self.assertEqual(inner[ICMPv6EchoRequest].id,
7991 self.logger.error(ppp("Unexpected or invalid packet:", packet))
7994 def test_hairpinning(self):
7995 """ NAT64 hairpinning """
7997 client = self.pg0.remote_hosts[0]
7998 server = self.pg0.remote_hosts[1]
7999 server_tcp_in_port = 22
8000 server_tcp_out_port = 4022
8001 server_udp_in_port = 23
8002 server_udp_out_port = 4023
8003 client_tcp_in_port = 1234
8004 client_udp_in_port = 1235
8005 client_tcp_out_port = 0
8006 client_udp_out_port = 0
8007 ip = IPv6(src=''.join(['64:ff9b::', self.nat_addr]))
8008 nat_addr_ip6 = ip.src
8010 self.vapi.nat64_add_del_pool_addr_range(start_addr=self.nat_addr,
8011 end_addr=self.nat_addr,
8014 flags = self.config_flags.NAT_IS_INSIDE
8015 self.vapi.nat64_add_del_interface(is_add=1, flags=flags,
8016 sw_if_index=self.pg0.sw_if_index)
8017 self.vapi.nat64_add_del_interface(is_add=1, flags=0,
8018 sw_if_index=self.pg1.sw_if_index)
8020 self.vapi.nat64_add_del_static_bib(i_addr=server.ip6n,
8021 o_addr=self.nat_addr,
8022 i_port=server_tcp_in_port,
8023 o_port=server_tcp_out_port,
8024 proto=IP_PROTOS.tcp, vrf_id=0,
8026 self.vapi.nat64_add_del_static_bib(i_addr=server.ip6n,
8027 o_addr=self.nat_addr,
8028 i_port=server_udp_in_port,
8029 o_port=server_udp_out_port,
8030 proto=IP_PROTOS.udp, vrf_id=0,
8035 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
8036 IPv6(src=client.ip6, dst=nat_addr_ip6) /
8037 TCP(sport=client_tcp_in_port, dport=server_tcp_out_port))
8039 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
8040 IPv6(src=client.ip6, dst=nat_addr_ip6) /
8041 UDP(sport=client_udp_in_port, dport=server_udp_out_port))
8043 self.pg0.add_stream(pkts)
8044 self.pg_enable_capture(self.pg_interfaces)
8046 capture = self.pg0.get_capture(len(pkts))
8047 for packet in capture:
8049 self.assertEqual(packet[IPv6].src, nat_addr_ip6)
8050 self.assertEqual(packet[IPv6].dst, server.ip6)
8051 self.assert_packet_checksums_valid(packet)
8052 if packet.haslayer(TCP):
8053 self.assertNotEqual(packet[TCP].sport, client_tcp_in_port)
8054 self.assertEqual(packet[TCP].dport, server_tcp_in_port)
8055 client_tcp_out_port = packet[TCP].sport
8057 self.assertNotEqual(packet[UDP].sport, client_udp_in_port)
8058 self.assertEqual(packet[UDP].dport, server_udp_in_port)
8059 client_udp_out_port = packet[UDP].sport
8061 self.logger.error(ppp("Unexpected or invalid packet:", packet))
8066 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
8067 IPv6(src=server.ip6, dst=nat_addr_ip6) /
8068 TCP(sport=server_tcp_in_port, dport=client_tcp_out_port))
8070 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
8071 IPv6(src=server.ip6, dst=nat_addr_ip6) /
8072 UDP(sport=server_udp_in_port, dport=client_udp_out_port))
8074 self.pg0.add_stream(pkts)
8075 self.pg_enable_capture(self.pg_interfaces)
8077 capture = self.pg0.get_capture(len(pkts))
8078 for packet in capture:
8080 self.assertEqual(packet[IPv6].src, nat_addr_ip6)
8081 self.assertEqual(packet[IPv6].dst, client.ip6)
8082 self.assert_packet_checksums_valid(packet)
8083 if packet.haslayer(TCP):
8084 self.assertEqual(packet[TCP].sport, server_tcp_out_port)
8085 self.assertEqual(packet[TCP].dport, client_tcp_in_port)
8087 self.assertEqual(packet[UDP].sport, server_udp_out_port)
8088 self.assertEqual(packet[UDP].dport, client_udp_in_port)
8090 self.logger.error(ppp("Unexpected or invalid packet:", packet))
8095 pkts = [Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
8096 IPv6(src=client.ip6, dst=nat_addr_ip6) /
8097 ICMPv6DestUnreach(code=1) /
8098 packet[IPv6] for packet in capture]
8099 self.pg0.add_stream(pkts)
8100 self.pg_enable_capture(self.pg_interfaces)
8102 capture = self.pg0.get_capture(len(pkts))
8103 for packet in capture:
8105 self.assertEqual(packet[IPv6].src, nat_addr_ip6)
8106 self.assertEqual(packet[IPv6].dst, server.ip6)
8107 icmp = packet[ICMPv6DestUnreach]
8108 self.assertEqual(icmp.code, 1)
8109 inner = icmp[IPerror6]
8110 self.assertEqual(inner.src, server.ip6)
8111 self.assertEqual(inner.dst, nat_addr_ip6)
8112 self.assert_packet_checksums_valid(packet)
8113 if inner.haslayer(TCPerror):
8114 self.assertEqual(inner[TCPerror].sport, server_tcp_in_port)
8115 self.assertEqual(inner[TCPerror].dport,
8116 client_tcp_out_port)
8118 self.assertEqual(inner[UDPerror].sport, server_udp_in_port)
8119 self.assertEqual(inner[UDPerror].dport,
8120 client_udp_out_port)
8122 self.logger.error(ppp("Unexpected or invalid packet:", packet))
8125 def test_prefix(self):
8126 """ NAT64 Network-Specific Prefix """
8128 self.vapi.nat64_add_del_pool_addr_range(start_addr=self.nat_addr,
8129 end_addr=self.nat_addr,
8132 flags = self.config_flags.NAT_IS_INSIDE
8133 self.vapi.nat64_add_del_interface(is_add=1, flags=flags,
8134 sw_if_index=self.pg0.sw_if_index)
8135 self.vapi.nat64_add_del_interface(is_add=1, flags=0,
8136 sw_if_index=self.pg1.sw_if_index)
8137 self.vapi.nat64_add_del_pool_addr_range(start_addr=self.vrf1_nat_addr,
8138 end_addr=self.vrf1_nat_addr,
8139 vrf_id=self.vrf1_id, is_add=1)
8140 self.vapi.nat64_add_del_interface(is_add=1, flags=flags,
8141 sw_if_index=self.pg2.sw_if_index)
8144 global_pref64 = "2001:db8::"
8145 global_pref64_len = 32
8146 global_pref64_str = "{}/{}".format(global_pref64, global_pref64_len)
8147 self.vapi.nat64_add_del_prefix(prefix=global_pref64_str, vrf_id=0,
8150 prefix = self.vapi.nat64_prefix_dump()
8151 self.assertEqual(len(prefix), 1)
8152 self.assertEqual(str(prefix[0].prefix), global_pref64_str)
8153 self.assertEqual(prefix[0].vrf_id, 0)
8155 # Add tenant specific prefix
8156 vrf1_pref64 = "2001:db8:122:300::"
8157 vrf1_pref64_len = 56
8158 vrf1_pref64_str = "{}/{}".format(vrf1_pref64, vrf1_pref64_len)
8159 self.vapi.nat64_add_del_prefix(prefix=vrf1_pref64_str,
8160 vrf_id=self.vrf1_id, is_add=1)
8162 prefix = self.vapi.nat64_prefix_dump()
8163 self.assertEqual(len(prefix), 2)
8166 pkts = self.create_stream_in_ip6(self.pg0,
8169 plen=global_pref64_len)
8170 self.pg0.add_stream(pkts)
8171 self.pg_enable_capture(self.pg_interfaces)
8173 capture = self.pg1.get_capture(len(pkts))
8174 self.verify_capture_out(capture, nat_ip=self.nat_addr,
8175 dst_ip=self.pg1.remote_ip4)
8177 pkts = self.create_stream_out(self.pg1, dst_ip=self.nat_addr)
8178 self.pg1.add_stream(pkts)
8179 self.pg_enable_capture(self.pg_interfaces)
8181 capture = self.pg0.get_capture(len(pkts))
8182 dst_ip = self.compose_ip6(self.pg1.remote_ip4,
8185 self.verify_capture_in_ip6(capture, dst_ip, self.pg0.remote_ip6)
8187 # Tenant specific prefix
8188 pkts = self.create_stream_in_ip6(self.pg2,
8191 plen=vrf1_pref64_len)
8192 self.pg2.add_stream(pkts)
8193 self.pg_enable_capture(self.pg_interfaces)
8195 capture = self.pg1.get_capture(len(pkts))
8196 self.verify_capture_out(capture, nat_ip=self.vrf1_nat_addr,
8197 dst_ip=self.pg1.remote_ip4)
8199 pkts = self.create_stream_out(self.pg1, dst_ip=self.vrf1_nat_addr)
8200 self.pg1.add_stream(pkts)
8201 self.pg_enable_capture(self.pg_interfaces)
8203 capture = self.pg2.get_capture(len(pkts))
8204 dst_ip = self.compose_ip6(self.pg1.remote_ip4,
8207 self.verify_capture_in_ip6(capture, dst_ip, self.pg2.remote_ip6)
8209 def test_unknown_proto(self):
8210 """ NAT64 translate packet with unknown protocol """
8212 self.vapi.nat64_add_del_pool_addr_range(start_addr=self.nat_addr,
8213 end_addr=self.nat_addr,
8216 flags = self.config_flags.NAT_IS_INSIDE
8217 self.vapi.nat64_add_del_interface(is_add=1, flags=flags,
8218 sw_if_index=self.pg0.sw_if_index)
8219 self.vapi.nat64_add_del_interface(is_add=1, flags=0,
8220 sw_if_index=self.pg1.sw_if_index)
8221 remote_ip6 = self.compose_ip6(self.pg1.remote_ip4, '64:ff9b::', 96)
8224 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
8225 IPv6(src=self.pg0.remote_ip6, dst=remote_ip6) /
8226 TCP(sport=self.tcp_port_in, dport=20))
8227 self.pg0.add_stream(p)
8228 self.pg_enable_capture(self.pg_interfaces)
8230 p = self.pg1.get_capture(1)
8232 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
8233 IPv6(src=self.pg0.remote_ip6, dst=remote_ip6, nh=47) /
8235 IP(src=self.pg2.local_ip4, dst=self.pg2.remote_ip4) /
8236 TCP(sport=1234, dport=1234))
8237 self.pg0.add_stream(p)
8238 self.pg_enable_capture(self.pg_interfaces)
8240 p = self.pg1.get_capture(1)
8243 self.assertEqual(packet[IP].src, self.nat_addr)
8244 self.assertEqual(packet[IP].dst, self.pg1.remote_ip4)
8245 self.assertEqual(packet.haslayer(GRE), 1)
8246 self.assert_packet_checksums_valid(packet)
8248 self.logger.error(ppp("Unexpected or invalid packet:", packet))
8252 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
8253 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
8255 IP(src=self.pg2.remote_ip4, dst=self.pg2.local_ip4) /
8256 TCP(sport=1234, dport=1234))
8257 self.pg1.add_stream(p)
8258 self.pg_enable_capture(self.pg_interfaces)
8260 p = self.pg0.get_capture(1)
8263 self.assertEqual(packet[IPv6].src, remote_ip6)
8264 self.assertEqual(packet[IPv6].dst, self.pg0.remote_ip6)
8265 self.assertEqual(packet[IPv6].nh, 47)
8267 self.logger.error(ppp("Unexpected or invalid packet:", packet))
8270 def test_hairpinning_unknown_proto(self):
8271 """ NAT64 translate packet with unknown protocol - hairpinning """
8273 client = self.pg0.remote_hosts[0]
8274 server = self.pg0.remote_hosts[1]
8275 server_tcp_in_port = 22
8276 server_tcp_out_port = 4022
8277 client_tcp_in_port = 1234
8278 client_tcp_out_port = 1235
8279 server_nat_ip = "10.0.0.100"
8280 client_nat_ip = "10.0.0.110"
8281 server_nat_ip6 = self.compose_ip6(server_nat_ip, '64:ff9b::', 96)
8282 client_nat_ip6 = self.compose_ip6(client_nat_ip, '64:ff9b::', 96)
8284 self.vapi.nat64_add_del_pool_addr_range(start_addr=server_nat_ip,
8285 end_addr=client_nat_ip,
8288 flags = self.config_flags.NAT_IS_INSIDE
8289 self.vapi.nat64_add_del_interface(is_add=1, flags=flags,
8290 sw_if_index=self.pg0.sw_if_index)
8291 self.vapi.nat64_add_del_interface(is_add=1, flags=0,
8292 sw_if_index=self.pg1.sw_if_index)
8294 self.vapi.nat64_add_del_static_bib(i_addr=server.ip6n,
8295 o_addr=server_nat_ip,
8296 i_port=server_tcp_in_port,
8297 o_port=server_tcp_out_port,
8298 proto=IP_PROTOS.tcp, vrf_id=0,
8301 self.vapi.nat64_add_del_static_bib(i_addr=server.ip6n,
8302 o_addr=server_nat_ip, i_port=0,
8304 proto=IP_PROTOS.gre, vrf_id=0,
8307 self.vapi.nat64_add_del_static_bib(i_addr=client.ip6n,
8308 o_addr=client_nat_ip,
8309 i_port=client_tcp_in_port,
8310 o_port=client_tcp_out_port,
8311 proto=IP_PROTOS.tcp, vrf_id=0,
8315 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
8316 IPv6(src=client.ip6, dst=server_nat_ip6) /
8317 TCP(sport=client_tcp_in_port, dport=server_tcp_out_port))
8318 self.pg0.add_stream(p)
8319 self.pg_enable_capture(self.pg_interfaces)
8321 p = self.pg0.get_capture(1)
8323 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
8324 IPv6(src=client.ip6, dst=server_nat_ip6, nh=IP_PROTOS.gre) /
8326 IP(src=self.pg2.local_ip4, dst=self.pg2.remote_ip4) /
8327 TCP(sport=1234, dport=1234))
8328 self.pg0.add_stream(p)
8329 self.pg_enable_capture(self.pg_interfaces)
8331 p = self.pg0.get_capture(1)
8334 self.assertEqual(packet[IPv6].src, client_nat_ip6)
8335 self.assertEqual(packet[IPv6].dst, server.ip6)
8336 self.assertEqual(packet[IPv6].nh, IP_PROTOS.gre)
8338 self.logger.error(ppp("Unexpected or invalid packet:", packet))
8342 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
8343 IPv6(src=server.ip6, dst=client_nat_ip6, nh=IP_PROTOS.gre) /
8345 IP(src=self.pg2.remote_ip4, dst=self.pg2.local_ip4) /
8346 TCP(sport=1234, dport=1234))
8347 self.pg0.add_stream(p)
8348 self.pg_enable_capture(self.pg_interfaces)
8350 p = self.pg0.get_capture(1)
8353 self.assertEqual(packet[IPv6].src, server_nat_ip6)
8354 self.assertEqual(packet[IPv6].dst, client.ip6)
8355 self.assertEqual(packet[IPv6].nh, IP_PROTOS.gre)
8357 self.logger.error(ppp("Unexpected or invalid packet:", packet))
8360 def test_one_armed_nat64(self):
8361 """ One armed NAT64 """
8363 remote_host_ip6 = self.compose_ip6(self.pg3.remote_ip4,
8367 self.vapi.nat64_add_del_pool_addr_range(start_addr=self.nat_addr,
8368 end_addr=self.nat_addr,
8371 flags = self.config_flags.NAT_IS_INSIDE
8372 self.vapi.nat64_add_del_interface(is_add=1, flags=flags,
8373 sw_if_index=self.pg3.sw_if_index)
8374 self.vapi.nat64_add_del_interface(is_add=1, flags=0,
8375 sw_if_index=self.pg3.sw_if_index)
8378 p = (Ether(src=self.pg3.remote_mac, dst=self.pg3.local_mac) /
8379 IPv6(src=self.pg3.remote_ip6, dst=remote_host_ip6) /
8380 TCP(sport=12345, dport=80))
8381 self.pg3.add_stream(p)
8382 self.pg_enable_capture(self.pg_interfaces)
8384 capture = self.pg3.get_capture(1)
8389 self.assertEqual(ip.src, self.nat_addr)
8390 self.assertEqual(ip.dst, self.pg3.remote_ip4)
8391 self.assertNotEqual(tcp.sport, 12345)
8392 external_port = tcp.sport
8393 self.assertEqual(tcp.dport, 80)
8394 self.assert_packet_checksums_valid(p)
8396 self.logger.error(ppp("Unexpected or invalid packet:", p))
8400 p = (Ether(src=self.pg3.remote_mac, dst=self.pg3.local_mac) /
8401 IP(src=self.pg3.remote_ip4, dst=self.nat_addr) /
8402 TCP(sport=80, dport=external_port))
8403 self.pg3.add_stream(p)
8404 self.pg_enable_capture(self.pg_interfaces)
8406 capture = self.pg3.get_capture(1)
8411 self.assertEqual(ip.src, remote_host_ip6)
8412 self.assertEqual(ip.dst, self.pg3.remote_ip6)
8413 self.assertEqual(tcp.sport, 80)
8414 self.assertEqual(tcp.dport, 12345)
8415 self.assert_packet_checksums_valid(p)
8417 self.logger.error(ppp("Unexpected or invalid packet:", p))
8420 def test_frag_in_order(self):
8421 """ NAT64 translate fragments arriving in order """
8422 self.tcp_port_in = random.randint(1025, 65535)
8424 self.vapi.nat64_add_del_pool_addr_range(start_addr=self.nat_addr,
8425 end_addr=self.nat_addr,
8428 flags = self.config_flags.NAT_IS_INSIDE
8429 self.vapi.nat64_add_del_interface(is_add=1, flags=flags,
8430 sw_if_index=self.pg0.sw_if_index)
8431 self.vapi.nat64_add_del_interface(is_add=1, flags=0,
8432 sw_if_index=self.pg1.sw_if_index)
8436 pkts = self.create_stream_frag_ip6(self.pg0, self.pg1.remote_ip4,
8437 self.tcp_port_in, 20, data)
8438 self.pg0.add_stream(pkts)
8439 self.pg_enable_capture(self.pg_interfaces)
8441 frags = self.pg1.get_capture(len(pkts))
8442 p = self.reass_frags_and_verify(frags,
8444 self.pg1.remote_ip4)
8445 self.assertEqual(p[TCP].dport, 20)
8446 self.assertNotEqual(p[TCP].sport, self.tcp_port_in)
8447 self.tcp_port_out = p[TCP].sport
8448 self.assertEqual(data, p[Raw].load)
8451 data = b"A" * 4 + b"b" * 16 + b"C" * 3
8452 pkts = self.create_stream_frag(self.pg1,
8457 self.pg1.add_stream(pkts)
8458 self.pg_enable_capture(self.pg_interfaces)
8460 frags = self.pg0.get_capture(len(pkts))
8461 self.logger.debug(ppc("Captured:", frags))
8462 src = self.compose_ip6(self.pg1.remote_ip4, '64:ff9b::', 96)
8463 p = self.reass_frags_and_verify_ip6(frags, src, self.pg0.remote_ip6)
8464 self.assertEqual(p[TCP].sport, 20)
8465 self.assertEqual(p[TCP].dport, self.tcp_port_in)
8466 self.assertEqual(data, p[Raw].load)
8468 def test_reass_hairpinning(self):
8469 """ NAT64 fragments hairpinning """
8471 server = self.pg0.remote_hosts[1]
8472 server_in_port = random.randint(1025, 65535)
8473 server_out_port = random.randint(1025, 65535)
8474 client_in_port = random.randint(1025, 65535)
8475 ip = IPv6(src=''.join(['64:ff9b::', self.nat_addr]))
8476 nat_addr_ip6 = ip.src
8478 self.vapi.nat64_add_del_pool_addr_range(start_addr=self.nat_addr,
8479 end_addr=self.nat_addr,
8482 flags = self.config_flags.NAT_IS_INSIDE
8483 self.vapi.nat64_add_del_interface(is_add=1, flags=flags,
8484 sw_if_index=self.pg0.sw_if_index)
8485 self.vapi.nat64_add_del_interface(is_add=1, flags=0,
8486 sw_if_index=self.pg1.sw_if_index)
8488 # add static BIB entry for server
8489 self.vapi.nat64_add_del_static_bib(i_addr=server.ip6n,
8490 o_addr=self.nat_addr,
8491 i_port=server_in_port,
8492 o_port=server_out_port,
8493 proto=IP_PROTOS.tcp, vrf_id=0,
8496 # send packet from host to server
8497 pkts = self.create_stream_frag_ip6(self.pg0,
8502 self.pg0.add_stream(pkts)
8503 self.pg_enable_capture(self.pg_interfaces)
8505 frags = self.pg0.get_capture(len(pkts))
8506 self.logger.debug(ppc("Captured:", frags))
8507 p = self.reass_frags_and_verify_ip6(frags, nat_addr_ip6, server.ip6)
8508 self.assertNotEqual(p[TCP].sport, client_in_port)
8509 self.assertEqual(p[TCP].dport, server_in_port)
8510 self.assertEqual(data, p[Raw].load)
8512 def test_frag_out_of_order(self):
8513 """ NAT64 translate fragments arriving out of order """
8514 self.tcp_port_in = random.randint(1025, 65535)
8516 self.vapi.nat64_add_del_pool_addr_range(start_addr=self.nat_addr,
8517 end_addr=self.nat_addr,
8520 flags = self.config_flags.NAT_IS_INSIDE
8521 self.vapi.nat64_add_del_interface(is_add=1, flags=flags,
8522 sw_if_index=self.pg0.sw_if_index)
8523 self.vapi.nat64_add_del_interface(is_add=1, flags=0,
8524 sw_if_index=self.pg1.sw_if_index)
8528 pkts = self.create_stream_frag_ip6(self.pg0, self.pg1.remote_ip4,
8529 self.tcp_port_in, 20, data)
8531 self.pg0.add_stream(pkts)
8532 self.pg_enable_capture(self.pg_interfaces)
8534 frags = self.pg1.get_capture(len(pkts))
8535 p = self.reass_frags_and_verify(frags,
8537 self.pg1.remote_ip4)
8538 self.assertEqual(p[TCP].dport, 20)
8539 self.assertNotEqual(p[TCP].sport, self.tcp_port_in)
8540 self.tcp_port_out = p[TCP].sport
8541 self.assertEqual(data, p[Raw].load)
8544 data = b"A" * 4 + b"B" * 16 + b"C" * 3
8545 pkts = self.create_stream_frag(self.pg1,
8551 self.pg1.add_stream(pkts)
8552 self.pg_enable_capture(self.pg_interfaces)
8554 frags = self.pg0.get_capture(len(pkts))
8555 src = self.compose_ip6(self.pg1.remote_ip4, '64:ff9b::', 96)
8556 p = self.reass_frags_and_verify_ip6(frags, src, self.pg0.remote_ip6)
8557 self.assertEqual(p[TCP].sport, 20)
8558 self.assertEqual(p[TCP].dport, self.tcp_port_in)
8559 self.assertEqual(data, p[Raw].load)
8561 def test_interface_addr(self):
8562 """ Acquire NAT64 pool addresses from interface """
8563 self.vapi.nat64_add_del_interface_addr(
8565 sw_if_index=self.pg4.sw_if_index)
8567 # no address in NAT64 pool
8568 addresses = self.vapi.nat44_address_dump()
8569 self.assertEqual(0, len(addresses))
8571 # configure interface address and check NAT64 address pool
8572 self.pg4.config_ip4()
8573 addresses = self.vapi.nat64_pool_addr_dump()
8574 self.assertEqual(len(addresses), 1)
8576 self.assertEqual(str(addresses[0].address),
8579 # remove interface address and check NAT64 address pool
8580 self.pg4.unconfig_ip4()
8581 addresses = self.vapi.nat64_pool_addr_dump()
8582 self.assertEqual(0, len(addresses))
8584 @unittest.skipUnless(running_extended_tests, "part of extended tests")
8585 def test_ipfix_max_bibs_sessions(self):
8586 """ IPFIX logging maximum session and BIB entries exceeded """
8589 remote_host_ip6 = self.compose_ip6(self.pg1.remote_ip4,
8593 self.vapi.nat64_add_del_pool_addr_range(start_addr=self.nat_addr,
8594 end_addr=self.nat_addr,
8597 flags = self.config_flags.NAT_IS_INSIDE
8598 self.vapi.nat64_add_del_interface(is_add=1, flags=flags,
8599 sw_if_index=self.pg0.sw_if_index)
8600 self.vapi.nat64_add_del_interface(is_add=1, flags=0,
8601 sw_if_index=self.pg1.sw_if_index)
8605 for i in range(0, max_bibs):
8606 src = "fd01:aa::%x" % (i)
8607 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
8608 IPv6(src=src, dst=remote_host_ip6) /
8609 TCP(sport=12345, dport=80))
8611 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
8612 IPv6(src=src, dst=remote_host_ip6) /
8613 TCP(sport=12345, dport=22))
8615 self.pg0.add_stream(pkts)
8616 self.pg_enable_capture(self.pg_interfaces)
8618 self.pg1.get_capture(max_sessions)
8620 self.vapi.set_ipfix_exporter(collector_address=self.pg3.remote_ip4,
8621 src_address=self.pg3.local_ip4,
8623 template_interval=10)
8624 self.vapi.nat_ipfix_enable_disable(domain_id=self.ipfix_domain_id,
8625 src_port=self.ipfix_src_port,
8628 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
8629 IPv6(src=src, dst=remote_host_ip6) /
8630 TCP(sport=12345, dport=25))
8631 self.pg0.add_stream(p)
8632 self.pg_enable_capture(self.pg_interfaces)
8634 self.pg1.assert_nothing_captured()
8636 self.vapi.ipfix_flush()
8637 capture = self.pg3.get_capture(7)
8638 ipfix = IPFIXDecoder()
8639 # first load template
8641 self.assertTrue(p.haslayer(IPFIX))
8642 self.assertEqual(p[IP].src, self.pg3.local_ip4)
8643 self.assertEqual(p[IP].dst, self.pg3.remote_ip4)
8644 self.assertEqual(p[UDP].sport, self.ipfix_src_port)
8645 self.assertEqual(p[UDP].dport, 4739)
8646 self.assertEqual(p[IPFIX].observationDomainID,
8647 self.ipfix_domain_id)
8648 if p.haslayer(Template):
8649 ipfix.add_template(p.getlayer(Template))
8650 # verify events in data set
8652 if p.haslayer(Data):
8653 data = ipfix.decode_data_set(p.getlayer(Set))
8654 self.verify_ipfix_max_sessions(data, max_sessions)
8656 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
8657 IPv6(src=self.pg0.remote_ip6, dst=remote_host_ip6) /
8658 TCP(sport=12345, dport=80))
8659 self.pg0.add_stream(p)
8660 self.pg_enable_capture(self.pg_interfaces)
8662 self.pg1.assert_nothing_captured()
8664 self.vapi.ipfix_flush()
8665 capture = self.pg3.get_capture(1)
8666 # verify events in data set
8668 self.assertTrue(p.haslayer(IPFIX))
8669 self.assertEqual(p[IP].src, self.pg3.local_ip4)
8670 self.assertEqual(p[IP].dst, self.pg3.remote_ip4)
8671 self.assertEqual(p[UDP].sport, self.ipfix_src_port)
8672 self.assertEqual(p[UDP].dport, 4739)
8673 self.assertEqual(p[IPFIX].observationDomainID,
8674 self.ipfix_domain_id)
8675 if p.haslayer(Data):
8676 data = ipfix.decode_data_set(p.getlayer(Set))
8677 self.verify_ipfix_max_bibs(data, max_bibs)
8679 def test_ipfix_bib_ses(self):
8680 """ IPFIX logging NAT64 BIB/session create and delete events """
8681 self.tcp_port_in = random.randint(1025, 65535)
8682 remote_host_ip6 = self.compose_ip6(self.pg1.remote_ip4,
8686 self.vapi.nat64_add_del_pool_addr_range(start_addr=self.nat_addr,
8687 end_addr=self.nat_addr,
8690 flags = self.config_flags.NAT_IS_INSIDE
8691 self.vapi.nat64_add_del_interface(is_add=1, flags=flags,
8692 sw_if_index=self.pg0.sw_if_index)
8693 self.vapi.nat64_add_del_interface(is_add=1, flags=0,
8694 sw_if_index=self.pg1.sw_if_index)
8695 self.vapi.set_ipfix_exporter(collector_address=self.pg3.remote_ip4,
8696 src_address=self.pg3.local_ip4,
8698 template_interval=10)
8699 self.vapi.nat_ipfix_enable_disable(domain_id=self.ipfix_domain_id,
8700 src_port=self.ipfix_src_port,
8704 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
8705 IPv6(src=self.pg0.remote_ip6, dst=remote_host_ip6) /
8706 TCP(sport=self.tcp_port_in, dport=25))
8707 self.pg0.add_stream(p)
8708 self.pg_enable_capture(self.pg_interfaces)
8710 p = self.pg1.get_capture(1)
8711 self.tcp_port_out = p[0][TCP].sport
8712 self.vapi.ipfix_flush()
8713 capture = self.pg3.get_capture(8)
8714 ipfix = IPFIXDecoder()
8715 # first load template
8717 self.assertTrue(p.haslayer(IPFIX))
8718 self.assertEqual(p[IP].src, self.pg3.local_ip4)
8719 self.assertEqual(p[IP].dst, self.pg3.remote_ip4)
8720 self.assertEqual(p[UDP].sport, self.ipfix_src_port)
8721 self.assertEqual(p[UDP].dport, 4739)
8722 self.assertEqual(p[IPFIX].observationDomainID,
8723 self.ipfix_domain_id)
8724 if p.haslayer(Template):
8725 ipfix.add_template(p.getlayer(Template))
8726 # verify events in data set
8728 if p.haslayer(Data):
8729 data = ipfix.decode_data_set(p.getlayer(Set))
8730 if scapy.compat.orb(data[0][230]) == 10:
8731 self.verify_ipfix_bib(data, 1, self.pg0.remote_ip6)
8732 elif scapy.compat.orb(data[0][230]) == 6:
8733 self.verify_ipfix_nat64_ses(data,
8735 self.pg0.remote_ip6,
8736 self.pg1.remote_ip4,
8739 self.logger.error(ppp("Unexpected or invalid packet: ", p))
8742 self.pg_enable_capture(self.pg_interfaces)
8743 self.vapi.nat64_add_del_pool_addr_range(start_addr=self.nat_addr,
8744 end_addr=self.nat_addr,
8747 self.vapi.ipfix_flush()
8748 capture = self.pg3.get_capture(2)
8749 # verify events in data set
8751 self.assertTrue(p.haslayer(IPFIX))
8752 self.assertEqual(p[IP].src, self.pg3.local_ip4)
8753 self.assertEqual(p[IP].dst, self.pg3.remote_ip4)
8754 self.assertEqual(p[UDP].sport, self.ipfix_src_port)
8755 self.assertEqual(p[UDP].dport, 4739)
8756 self.assertEqual(p[IPFIX].observationDomainID,
8757 self.ipfix_domain_id)
8758 if p.haslayer(Data):
8759 data = ipfix.decode_data_set(p.getlayer(Set))
8760 if scapy.compat.orb(data[0][230]) == 11:
8761 self.verify_ipfix_bib(data, 0, self.pg0.remote_ip6)
8762 elif scapy.compat.orb(data[0][230]) == 7:
8763 self.verify_ipfix_nat64_ses(data,
8765 self.pg0.remote_ip6,
8766 self.pg1.remote_ip4,
8769 self.logger.error(ppp("Unexpected or invalid packet: ", p))
8771 def test_syslog_sess(self):
8772 """ Test syslog session creation and deletion """
8773 self.tcp_port_in = random.randint(1025, 65535)
8774 remote_host_ip6 = self.compose_ip6(self.pg1.remote_ip4,
8778 self.vapi.nat64_add_del_pool_addr_range(start_addr=self.nat_addr,
8779 end_addr=self.nat_addr,
8782 flags = self.config_flags.NAT_IS_INSIDE
8783 self.vapi.nat64_add_del_interface(is_add=1, flags=flags,
8784 sw_if_index=self.pg0.sw_if_index)
8785 self.vapi.nat64_add_del_interface(is_add=1, flags=0,
8786 sw_if_index=self.pg1.sw_if_index)
8787 self.vapi.syslog_set_filter(
8788 self.SYSLOG_SEVERITY.SYSLOG_API_SEVERITY_INFO)
8789 self.vapi.syslog_set_sender(self.pg3.local_ip4, self.pg3.remote_ip4)
8791 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
8792 IPv6(src=self.pg0.remote_ip6, dst=remote_host_ip6) /
8793 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port))
8794 self.pg0.add_stream(p)
8795 self.pg_enable_capture(self.pg_interfaces)
8797 p = self.pg1.get_capture(1)
8798 self.tcp_port_out = p[0][TCP].sport
8799 capture = self.pg3.get_capture(1)
8800 self.verify_syslog_sess(capture[0][Raw].load, is_ip6=True)
8802 self.pg_enable_capture(self.pg_interfaces)
8804 self.vapi.nat64_add_del_pool_addr_range(start_addr=self.nat_addr,
8805 end_addr=self.nat_addr,
8808 capture = self.pg3.get_capture(1)
8809 self.verify_syslog_sess(capture[0][Raw].load, False, True)
8811 def nat64_get_ses_num(self):
8813 Return number of active NAT64 sessions.
8815 st = self.vapi.nat64_st_dump(proto=255)
8818 def clear_nat64(self):
8820 Clear NAT64 configuration.
8822 self.vapi.nat_ipfix_enable_disable(domain_id=self.ipfix_domain_id,
8823 src_port=self.ipfix_src_port,
8825 self.ipfix_src_port = 4739
8826 self.ipfix_domain_id = 1
8828 self.vapi.syslog_set_filter(
8829 self.SYSLOG_SEVERITY.SYSLOG_API_SEVERITY_EMERG)
8831 self.vapi.nat_set_timeouts(udp=300, tcp_established=7440,
8832 tcp_transitory=240, icmp=60)
8834 interfaces = self.vapi.nat64_interface_dump()
8835 for intf in interfaces:
8836 self.vapi.nat64_add_del_interface(is_add=0, flags=intf.flags,
8837 sw_if_index=intf.sw_if_index)
8839 bib = self.vapi.nat64_bib_dump(proto=255)
8841 if bibe.flags & self.config_flags.NAT_IS_STATIC:
8842 self.vapi.nat64_add_del_static_bib(i_addr=bibe.i_addr,
8850 adresses = self.vapi.nat64_pool_addr_dump()
8851 for addr in adresses:
8852 self.vapi.nat64_add_del_pool_addr_range(start_addr=addr.address,
8853 end_addr=addr.address,
8857 prefixes = self.vapi.nat64_prefix_dump()
8858 for prefix in prefixes:
8859 self.vapi.nat64_add_del_prefix(prefix=str(prefix.prefix),
8860 vrf_id=prefix.vrf_id, is_add=0)
8862 bibs = self.statistics.get_counter('/nat64/total-bibs')
8863 self.assertEqual(bibs[0][0], 0)
8864 sessions = self.statistics.get_counter('/nat64/total-sessions')
8865 self.assertEqual(sessions[0][0], 0)
8868 super(TestNAT64, self).tearDown()
8869 if not self.vpp_dead:
8872 def show_commands_at_teardown(self):
8873 self.logger.info(self.vapi.cli("show nat64 pool"))
8874 self.logger.info(self.vapi.cli("show nat64 interfaces"))
8875 self.logger.info(self.vapi.cli("show nat64 prefix"))
8876 self.logger.info(self.vapi.cli("show nat64 bib all"))
8877 self.logger.info(self.vapi.cli("show nat64 session table all"))
8880 if __name__ == '__main__':
8881 unittest.main(testRunner=VppTestRunner)