8 from framework import VppTestCase, VppTestRunner, running_extended_tests
11 from scapy.layers.inet import IP, TCP, UDP, ICMP
12 from scapy.layers.inet import IPerror, TCPerror, UDPerror, ICMPerror
13 from scapy.layers.inet6 import IPv6, ICMPv6EchoRequest, ICMPv6EchoReply, \
14 ICMPv6ND_NS, ICMPv6ND_NA, ICMPv6NDOptDstLLAddr, fragment6
15 from scapy.layers.inet6 import ICMPv6DestUnreach, IPerror6, IPv6ExtHdrFragment
16 from scapy.layers.l2 import Ether, ARP, GRE
17 from scapy.data import IP_PROTOS
18 from scapy.packet import bind_layers, Raw
20 from ipfix import IPFIX, Set, Template, Data, IPFIXDecoder
21 from time import sleep
22 from util import ip4_range
23 from vpp_papi import mac_pton
24 from syslog_rfc5424_parser import SyslogMessage, ParseError
25 from syslog_rfc5424_parser.constants import SyslogFacility, SyslogSeverity
26 from io import BytesIO
27 from vpp_papi import VppEnum
28 from vpp_ip_route import VppIpRoute, VppRoutePath, FibPathType
29 from vpp_neighbor import VppNeighbor
30 from vpp_ip import VppIpAddress, VppIpPrefix
31 from scapy.all import bind_layers, Packet, ByteEnumField, ShortField, \
32 IPField, IntField, LongField, XByteField, FlagsField, FieldLenField, \
34 from ipaddress import IPv6Network
37 # NAT HA protocol event data
40 fields_desc = [ByteEnumField("event_type", None,
41 {1: "add", 2: "del", 3: "refresh"}),
42 ByteEnumField("protocol", None,
43 {0: "udp", 1: "tcp", 2: "icmp"}),
44 ShortField("flags", 0),
45 IPField("in_addr", None),
46 IPField("out_addr", None),
47 ShortField("in_port", None),
48 ShortField("out_port", None),
49 IPField("eh_addr", None),
50 IPField("ehn_addr", None),
51 ShortField("eh_port", None),
52 ShortField("ehn_port", None),
53 IntField("fib_index", None),
54 IntField("total_pkts", 0),
55 LongField("total_bytes", 0)]
57 def extract_padding(self, s):
61 # NAT HA protocol header
62 class HANATStateSync(Packet):
63 name = "HA NAT state sync"
64 fields_desc = [XByteField("version", 1),
65 FlagsField("flags", 0, 8, ['ACK']),
66 FieldLenField("count", None, count_of="events"),
67 IntField("sequence_number", 1),
68 IntField("thread_index", 0),
69 PacketListField("events", [], Event,
70 count_from=lambda pkt: pkt.count)]
73 class MethodHolder(VppTestCase):
74 """ NAT create capture and verify method holder """
77 def config_flags(self):
78 return VppEnum.vl_api_nat_config_flags_t
81 def SYSLOG_SEVERITY(self):
82 return VppEnum.vl_api_syslog_severity_t
84 def clear_nat44(self):
86 Clear NAT44 configuration.
88 if hasattr(self, 'pg7') and hasattr(self, 'pg8'):
89 if self.pg7.has_ip4_config:
90 self.pg7.unconfig_ip4()
92 self.vapi.nat44_forwarding_enable_disable(enable=0)
94 interfaces = self.vapi.nat44_interface_addr_dump()
95 for intf in interfaces:
96 self.vapi.nat44_add_del_interface_addr(
98 sw_if_index=intf.sw_if_index,
101 self.vapi.nat_ipfix_enable_disable(domain_id=self.ipfix_domain_id,
102 src_port=self.ipfix_src_port,
104 self.ipfix_src_port = 4739
105 self.ipfix_domain_id = 1
107 self.vapi.syslog_set_filter(
108 self.SYSLOG_SEVERITY.SYSLOG_API_SEVERITY_EMERG)
110 self.vapi.nat_ha_set_listener(ip_address='0.0.0.0', port=0,
112 self.vapi.nat_ha_set_failover(ip_address='0.0.0.0', port=0,
113 session_refresh_interval=10)
115 interfaces = self.vapi.nat44_interface_dump()
116 for intf in interfaces:
117 if intf.flags & self.config_flags.NAT_IS_INSIDE and \
118 intf.flags & self.config_flags.NAT_IS_OUTSIDE:
119 self.vapi.nat44_interface_add_del_feature(
120 sw_if_index=intf.sw_if_index)
121 self.vapi.nat44_interface_add_del_feature(
122 sw_if_index=intf.sw_if_index,
125 interfaces = self.vapi.nat44_interface_output_feature_dump()
126 for intf in interfaces:
127 self.vapi.nat44_interface_add_del_output_feature(
130 sw_if_index=intf.sw_if_index)
131 static_mappings = self.vapi.nat44_static_mapping_dump()
132 for sm in static_mappings:
133 self.vapi.nat44_add_del_static_mapping(
135 local_ip_address=sm.local_ip_address,
136 external_ip_address=sm.external_ip_address,
137 external_sw_if_index=sm.external_sw_if_index,
138 local_port=sm.local_port,
139 external_port=sm.external_port,
141 protocol=sm.protocol,
142 flags=sm.flags, tag=sm.tag)
144 lb_static_mappings = self.vapi.nat44_lb_static_mapping_dump()
145 for lb_sm in lb_static_mappings:
146 self.vapi.nat44_add_del_lb_static_mapping(
149 external_addr=lb_sm.external_addr,
150 external_port=lb_sm.external_port,
151 protocol=lb_sm.protocol,
152 local_num=0, locals=[],
155 identity_mappings = self.vapi.nat44_identity_mapping_dump()
156 for id_m in identity_mappings:
157 self.vapi.nat44_add_del_identity_mapping(
158 ip_address=id_m.ip_address,
159 sw_if_index=id_m.sw_if_index,
163 protocol=id_m.protocol)
165 addresses = self.vapi.nat44_address_dump()
166 for addr in addresses:
167 self.vapi.nat44_add_del_address_range(
168 first_ip_address=addr.ip_address,
169 last_ip_address=addr.ip_address,
170 vrf_id=0xFFFFFFFF, flags=addr.flags)
172 self.vapi.nat_set_reass(timeout=2, max_reass=1024, max_frag=5,
174 self.vapi.nat_set_reass(timeout=2, max_reass=1024, max_frag=5,
175 drop_frag=0, is_ip6=1)
176 self.verify_no_nat44_user()
177 self.vapi.nat_set_timeouts(udp=300, tcp_established=7440,
178 tcp_transitory=240, icmp=60)
179 self.vapi.nat_set_addr_and_port_alloc_alg()
180 self.vapi.nat_set_mss_clamping(enable=0, mss_value=1500)
182 def nat44_add_static_mapping(self, local_ip, external_ip='0.0.0.0',
183 local_port=0, external_port=0, vrf_id=0,
184 is_add=1, external_sw_if_index=0xFFFFFFFF,
185 proto=0, tag="", flags=0):
187 Add/delete NAT44 static mapping
189 :param local_ip: Local IP address
190 :param external_ip: External IP address
191 :param local_port: Local port number (Optional)
192 :param external_port: External port number (Optional)
193 :param vrf_id: VRF ID (Default 0)
194 :param is_add: 1 if add, 0 if delete (Default add)
195 :param external_sw_if_index: External interface instead of IP address
196 :param proto: IP protocol (Mandatory if port specified)
197 :param tag: Opaque string tag
198 :param flags: NAT configuration flags
201 if not (local_port and external_port):
202 flags |= self.config_flags.NAT_IS_ADDR_ONLY
204 self.vapi.nat44_add_del_static_mapping(
206 local_ip_address=local_ip,
207 external_ip_address=external_ip,
208 external_sw_if_index=external_sw_if_index,
209 local_port=local_port,
210 external_port=external_port,
211 vrf_id=vrf_id, protocol=proto,
215 def nat44_add_address(self, ip, is_add=1, vrf_id=0xFFFFFFFF, twice_nat=0):
217 Add/delete NAT44 address
219 :param ip: IP address
220 :param is_add: 1 if add, 0 if delete (Default add)
221 :param twice_nat: twice NAT address for external hosts
223 flags = self.config_flags.NAT_IS_TWICE_NAT if twice_nat else 0
224 self.vapi.nat44_add_del_address_range(first_ip_address=ip,
230 def create_stream_in(self, in_if, out_if, dst_ip=None, ttl=64):
232 Create packet stream for inside network
234 :param in_if: Inside interface
235 :param out_if: Outside interface
236 :param dst_ip: Destination address
237 :param ttl: TTL of generated packets
240 dst_ip = out_if.remote_ip4
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 TCP(sport=self.tcp_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 UDP(sport=self.udp_port_in, dport=20))
256 p = (Ether(dst=in_if.local_mac, src=in_if.remote_mac) /
257 IP(src=in_if.remote_ip4, dst=dst_ip, ttl=ttl) /
258 ICMP(id=self.icmp_id_in, type='echo-request'))
263 def compose_ip6(self, ip4, pref, plen):
265 Compose IPv4-embedded IPv6 addresses
267 :param ip4: IPv4 address
268 :param pref: IPv6 prefix
269 :param plen: IPv6 prefix length
270 :returns: IPv4-embedded IPv6 addresses
272 pref_n = list(socket.inet_pton(socket.AF_INET6, pref))
273 ip4_n = list(socket.inet_pton(socket.AF_INET, ip4))
288 pref_n[10] = ip4_n[3]
292 pref_n[10] = ip4_n[2]
293 pref_n[11] = ip4_n[3]
296 pref_n[10] = ip4_n[1]
297 pref_n[11] = ip4_n[2]
298 pref_n[12] = ip4_n[3]
300 pref_n[12] = ip4_n[0]
301 pref_n[13] = ip4_n[1]
302 pref_n[14] = ip4_n[2]
303 pref_n[15] = ip4_n[3]
304 packed_pref_n = b''.join([scapy.compat.chb(x) for x in pref_n])
305 return socket.inet_ntop(socket.AF_INET6, packed_pref_n)
307 def extract_ip4(self, ip6, plen):
309 Extract IPv4 address embedded in IPv6 addresses
311 :param ip6: IPv6 address
312 :param plen: IPv6 prefix length
313 :returns: extracted IPv4 address
315 ip6_n = list(socket.inet_pton(socket.AF_INET6, ip6))
347 return socket.inet_ntop(socket.AF_INET, ''.join(ip4_n))
349 def create_stream_in_ip6(self, in_if, out_if, hlim=64, pref=None, plen=0):
351 Create IPv6 packet stream for inside network
353 :param in_if: Inside interface
354 :param out_if: Outside interface
355 :param ttl: Hop Limit of generated packets
356 :param pref: NAT64 prefix
357 :param plen: NAT64 prefix length
361 dst = ''.join(['64:ff9b::', out_if.remote_ip4])
363 dst = self.compose_ip6(out_if.remote_ip4, pref, plen)
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 TCP(sport=self.tcp_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 UDP(sport=self.udp_port_in, dport=20))
378 p = (Ether(dst=in_if.local_mac, src=in_if.remote_mac) /
379 IPv6(src=in_if.remote_ip6, dst=dst, hlim=hlim) /
380 ICMPv6EchoRequest(id=self.icmp_id_in))
385 def create_stream_out(self, out_if, dst_ip=None, ttl=64,
386 use_inside_ports=False):
388 Create packet stream for outside network
390 :param out_if: Outside interface
391 :param dst_ip: Destination IP address (Default use global NAT address)
392 :param ttl: TTL of generated packets
393 :param use_inside_ports: Use inside NAT ports as destination ports
394 instead of outside ports
397 dst_ip = self.nat_addr
398 if not use_inside_ports:
399 tcp_port = self.tcp_port_out
400 udp_port = self.udp_port_out
401 icmp_id = self.icmp_id_out
403 tcp_port = self.tcp_port_in
404 udp_port = self.udp_port_in
405 icmp_id = self.icmp_id_in
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 TCP(dport=tcp_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 UDP(dport=udp_port, sport=20))
420 p = (Ether(dst=out_if.local_mac, src=out_if.remote_mac) /
421 IP(src=out_if.remote_ip4, dst=dst_ip, ttl=ttl) /
422 ICMP(id=icmp_id, type='echo-reply'))
427 def create_stream_out_ip6(self, out_if, src_ip, dst_ip, hl=64):
429 Create packet stream for outside network
431 :param out_if: Outside interface
432 :param dst_ip: Destination IP address (Default use global NAT address)
433 :param hl: HL of generated packets
437 p = (Ether(dst=out_if.local_mac, src=out_if.remote_mac) /
438 IPv6(src=src_ip, dst=dst_ip, hlim=hl) /
439 TCP(dport=self.tcp_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 UDP(dport=self.udp_port_out, sport=20))
449 p = (Ether(dst=out_if.local_mac, src=out_if.remote_mac) /
450 IPv6(src=src_ip, dst=dst_ip, hlim=hl) /
451 ICMPv6EchoReply(id=self.icmp_id_out))
456 def verify_capture_out(self, capture, nat_ip=None, same_port=False,
457 dst_ip=None, is_ip6=False):
459 Verify captured packets on outside network
461 :param capture: Captured packets
462 :param nat_ip: Translated IP address (Default use global NAT address)
463 :param same_port: Source port number is not translated (Default False)
464 :param dst_ip: Destination IP address (Default do not verify)
465 :param is_ip6: If L3 protocol is IPv6 (Default False)
469 ICMP46 = ICMPv6EchoRequest
474 nat_ip = self.nat_addr
475 for packet in capture:
478 self.assert_packet_checksums_valid(packet)
479 self.assertEqual(packet[IP46].src, nat_ip)
480 if dst_ip is not None:
481 self.assertEqual(packet[IP46].dst, dst_ip)
482 if packet.haslayer(TCP):
484 self.assertEqual(packet[TCP].sport, self.tcp_port_in)
487 packet[TCP].sport, self.tcp_port_in)
488 self.tcp_port_out = packet[TCP].sport
489 self.assert_packet_checksums_valid(packet)
490 elif packet.haslayer(UDP):
492 self.assertEqual(packet[UDP].sport, self.udp_port_in)
495 packet[UDP].sport, self.udp_port_in)
496 self.udp_port_out = packet[UDP].sport
499 self.assertEqual(packet[ICMP46].id, self.icmp_id_in)
501 self.assertNotEqual(packet[ICMP46].id, self.icmp_id_in)
502 self.icmp_id_out = packet[ICMP46].id
503 self.assert_packet_checksums_valid(packet)
505 self.logger.error(ppp("Unexpected or invalid packet "
506 "(outside network):", packet))
509 def verify_capture_out_ip6(self, capture, nat_ip, same_port=False,
512 Verify captured packets on outside network
514 :param capture: Captured packets
515 :param nat_ip: Translated IP address
516 :param same_port: Source port number is not translated (Default False)
517 :param dst_ip: Destination IP address (Default do not verify)
519 return self.verify_capture_out(capture, nat_ip, same_port, dst_ip,
522 def verify_capture_in(self, capture, in_if):
524 Verify captured packets on inside network
526 :param capture: Captured packets
527 :param in_if: Inside interface
529 for packet in capture:
531 self.assert_packet_checksums_valid(packet)
532 self.assertEqual(packet[IP].dst, in_if.remote_ip4)
533 if packet.haslayer(TCP):
534 self.assertEqual(packet[TCP].dport, self.tcp_port_in)
535 elif packet.haslayer(UDP):
536 self.assertEqual(packet[UDP].dport, self.udp_port_in)
538 self.assertEqual(packet[ICMP].id, self.icmp_id_in)
540 self.logger.error(ppp("Unexpected or invalid packet "
541 "(inside network):", packet))
544 def verify_capture_in_ip6(self, capture, src_ip, dst_ip):
546 Verify captured IPv6 packets on inside network
548 :param capture: Captured packets
549 :param src_ip: Source IP
550 :param dst_ip: Destination IP address
552 for packet in capture:
554 self.assertEqual(packet[IPv6].src, src_ip)
555 self.assertEqual(packet[IPv6].dst, dst_ip)
556 self.assert_packet_checksums_valid(packet)
557 if packet.haslayer(TCP):
558 self.assertEqual(packet[TCP].dport, self.tcp_port_in)
559 elif packet.haslayer(UDP):
560 self.assertEqual(packet[UDP].dport, self.udp_port_in)
562 self.assertEqual(packet[ICMPv6EchoReply].id,
565 self.logger.error(ppp("Unexpected or invalid packet "
566 "(inside network):", packet))
569 def verify_capture_no_translation(self, capture, ingress_if, egress_if):
571 Verify captured packet that don't have to be translated
573 :param capture: Captured packets
574 :param ingress_if: Ingress interface
575 :param egress_if: Egress interface
577 for packet in capture:
579 self.assertEqual(packet[IP].src, ingress_if.remote_ip4)
580 self.assertEqual(packet[IP].dst, egress_if.remote_ip4)
581 if packet.haslayer(TCP):
582 self.assertEqual(packet[TCP].sport, self.tcp_port_in)
583 elif packet.haslayer(UDP):
584 self.assertEqual(packet[UDP].sport, self.udp_port_in)
586 self.assertEqual(packet[ICMP].id, self.icmp_id_in)
588 self.logger.error(ppp("Unexpected or invalid packet "
589 "(inside network):", packet))
592 def verify_capture_out_with_icmp_errors(self, capture, src_ip=None,
595 Verify captured packets with ICMP errors on outside network
597 :param capture: Captured packets
598 :param src_ip: Translated IP address or IP address of VPP
599 (Default use global NAT address)
600 :param icmp_type: Type of error ICMP packet
601 we are expecting (Default 11)
604 src_ip = self.nat_addr
605 for packet in capture:
607 self.assertEqual(packet[IP].src, src_ip)
608 self.assertEqual(packet.haslayer(ICMP), 1)
610 self.assertEqual(icmp.type, icmp_type)
611 self.assertTrue(icmp.haslayer(IPerror))
612 inner_ip = icmp[IPerror]
613 if inner_ip.haslayer(TCPerror):
614 self.assertEqual(inner_ip[TCPerror].dport,
616 elif inner_ip.haslayer(UDPerror):
617 self.assertEqual(inner_ip[UDPerror].dport,
620 self.assertEqual(inner_ip[ICMPerror].id, self.icmp_id_out)
622 self.logger.error(ppp("Unexpected or invalid packet "
623 "(outside network):", packet))
626 def verify_capture_in_with_icmp_errors(self, capture, in_if, icmp_type=11):
628 Verify captured packets with ICMP errors on inside network
630 :param capture: Captured packets
631 :param in_if: Inside interface
632 :param icmp_type: Type of error ICMP packet
633 we are expecting (Default 11)
635 for packet in capture:
637 self.assertEqual(packet[IP].dst, in_if.remote_ip4)
638 self.assertEqual(packet.haslayer(ICMP), 1)
640 self.assertEqual(icmp.type, icmp_type)
641 self.assertTrue(icmp.haslayer(IPerror))
642 inner_ip = icmp[IPerror]
643 if inner_ip.haslayer(TCPerror):
644 self.assertEqual(inner_ip[TCPerror].sport,
646 elif inner_ip.haslayer(UDPerror):
647 self.assertEqual(inner_ip[UDPerror].sport,
650 self.assertEqual(inner_ip[ICMPerror].id, self.icmp_id_in)
652 self.logger.error(ppp("Unexpected or invalid packet "
653 "(inside network):", packet))
656 def create_stream_frag(self, src_if, dst, sport, dport, data,
657 proto=IP_PROTOS.tcp, echo_reply=False):
659 Create fragmented packet stream
661 :param src_if: Source interface
662 :param dst: Destination IPv4 address
663 :param sport: Source port
664 :param dport: Destination port
665 :param data: Payload data
666 :param proto: protocol (TCP, UDP, ICMP)
667 :param echo_reply: use echo_reply if protocol is ICMP
670 if proto == IP_PROTOS.tcp:
671 p = (IP(src=src_if.remote_ip4, dst=dst) /
672 TCP(sport=sport, dport=dport) /
674 p = p.__class__(scapy.compat.raw(p))
675 chksum = p[TCP].chksum
676 proto_header = TCP(sport=sport, dport=dport, chksum=chksum)
677 elif proto == IP_PROTOS.udp:
678 proto_header = UDP(sport=sport, dport=dport)
679 elif proto == IP_PROTOS.icmp:
681 proto_header = ICMP(id=sport, type='echo-request')
683 proto_header = ICMP(id=sport, type='echo-reply')
685 raise Exception("Unsupported protocol")
686 id = random.randint(0, 65535)
688 if proto == IP_PROTOS.tcp:
691 raw = Raw(data[0:16])
692 p = (Ether(src=src_if.remote_mac, dst=src_if.local_mac) /
693 IP(src=src_if.remote_ip4, dst=dst, flags="MF", frag=0, id=id) /
697 if proto == IP_PROTOS.tcp:
698 raw = Raw(data[4:20])
700 raw = Raw(data[16:32])
701 p = (Ether(src=src_if.remote_mac, dst=src_if.local_mac) /
702 IP(src=src_if.remote_ip4, dst=dst, flags="MF", frag=3, id=id,
706 if proto == IP_PROTOS.tcp:
710 p = (Ether(src=src_if.remote_mac, dst=src_if.local_mac) /
711 IP(src=src_if.remote_ip4, dst=dst, frag=5, proto=proto,
717 def create_stream_frag_ip6(self, src_if, dst, sport, dport, data,
718 pref=None, plen=0, frag_size=128):
720 Create fragmented packet stream
722 :param src_if: Source interface
723 :param dst: Destination IPv4 address
724 :param sport: Source TCP port
725 :param dport: Destination TCP port
726 :param data: Payload data
727 :param pref: NAT64 prefix
728 :param plen: NAT64 prefix length
729 :param fragsize: size of fragments
733 dst_ip6 = ''.join(['64:ff9b::', dst])
735 dst_ip6 = self.compose_ip6(dst, pref, plen)
737 p = (Ether(dst=src_if.local_mac, src=src_if.remote_mac) /
738 IPv6(src=src_if.remote_ip6, dst=dst_ip6) /
739 IPv6ExtHdrFragment(id=random.randint(0, 65535)) /
740 TCP(sport=sport, dport=dport) /
743 return fragment6(p, frag_size)
745 def reass_frags_and_verify(self, frags, src, dst):
747 Reassemble and verify fragmented packet
749 :param frags: Captured fragments
750 :param src: Source IPv4 address to verify
751 :param dst: Destination IPv4 address to verify
753 :returns: Reassembled IPv4 packet
757 self.assertEqual(p[IP].src, src)
758 self.assertEqual(p[IP].dst, dst)
759 self.assert_ip_checksum_valid(p)
760 buffer.seek(p[IP].frag * 8)
761 buffer.write(bytes(p[IP].payload))
762 ip = IP(src=frags[0][IP].src, dst=frags[0][IP].dst,
763 proto=frags[0][IP].proto)
764 if ip.proto == IP_PROTOS.tcp:
765 p = (ip / TCP(buffer.getvalue()))
766 self.assert_tcp_checksum_valid(p)
767 elif ip.proto == IP_PROTOS.udp:
768 p = (ip / UDP(buffer.getvalue()[:8]) /
769 Raw(buffer.getvalue()[8:]))
770 elif ip.proto == IP_PROTOS.icmp:
771 p = (ip / ICMP(buffer.getvalue()))
774 def reass_frags_and_verify_ip6(self, frags, src, dst):
776 Reassemble and verify fragmented packet
778 :param frags: Captured fragments
779 :param src: Source IPv6 address to verify
780 :param dst: Destination IPv6 address to verify
782 :returns: Reassembled IPv6 packet
786 self.assertEqual(p[IPv6].src, src)
787 self.assertEqual(p[IPv6].dst, dst)
788 buffer.seek(p[IPv6ExtHdrFragment].offset * 8)
789 buffer.write(bytes(p[IPv6ExtHdrFragment].payload))
790 ip = IPv6(src=frags[0][IPv6].src, dst=frags[0][IPv6].dst,
791 nh=frags[0][IPv6ExtHdrFragment].nh)
792 if ip.nh == IP_PROTOS.tcp:
793 p = (ip / TCP(buffer.getvalue()))
794 elif ip.nh == IP_PROTOS.udp:
795 p = (ip / UDP(buffer.getvalue()))
796 self.assert_packet_checksums_valid(p)
799 def initiate_tcp_session(self, in_if, out_if):
801 Initiates TCP session
803 :param in_if: Inside interface
804 :param out_if: Outside interface
808 p = (Ether(src=in_if.remote_mac, dst=in_if.local_mac) /
809 IP(src=in_if.remote_ip4, dst=out_if.remote_ip4) /
810 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
813 self.pg_enable_capture(self.pg_interfaces)
815 capture = out_if.get_capture(1)
817 self.tcp_port_out = p[TCP].sport
819 # SYN + ACK packet out->in
820 p = (Ether(src=out_if.remote_mac, dst=out_if.local_mac) /
821 IP(src=out_if.remote_ip4, dst=self.nat_addr) /
822 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
825 self.pg_enable_capture(self.pg_interfaces)
830 p = (Ether(src=in_if.remote_mac, dst=in_if.local_mac) /
831 IP(src=in_if.remote_ip4, dst=out_if.remote_ip4) /
832 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
835 self.pg_enable_capture(self.pg_interfaces)
837 out_if.get_capture(1)
840 self.logger.error("TCP 3 way handshake failed")
843 def verify_ipfix_nat44_ses(self, data):
845 Verify IPFIX NAT44 session create/delete event
847 :param data: Decoded IPFIX data records
849 nat44_ses_create_num = 0
850 nat44_ses_delete_num = 0
851 self.assertEqual(6, len(data))
854 self.assertIn(scapy.compat.orb(record[230]), [4, 5])
855 if scapy.compat.orb(record[230]) == 4:
856 nat44_ses_create_num += 1
858 nat44_ses_delete_num += 1
860 self.assertEqual(self.pg0.remote_ip4n, record[8])
861 # postNATSourceIPv4Address
862 self.assertEqual(socket.inet_pton(socket.AF_INET, self.nat_addr),
865 self.assertEqual(struct.pack("!I", 0), record[234])
866 # protocolIdentifier/sourceTransportPort
867 # /postNAPTSourceTransportPort
868 if IP_PROTOS.icmp == scapy.compat.orb(record[4]):
869 self.assertEqual(struct.pack("!H", self.icmp_id_in), record[7])
870 self.assertEqual(struct.pack("!H", self.icmp_id_out),
872 elif IP_PROTOS.tcp == scapy.compat.orb(record[4]):
873 self.assertEqual(struct.pack("!H", self.tcp_port_in),
875 self.assertEqual(struct.pack("!H", self.tcp_port_out),
877 elif IP_PROTOS.udp == scapy.compat.orb(record[4]):
878 self.assertEqual(struct.pack("!H", self.udp_port_in),
880 self.assertEqual(struct.pack("!H", self.udp_port_out),
883 self.fail("Invalid protocol")
884 self.assertEqual(3, nat44_ses_create_num)
885 self.assertEqual(3, nat44_ses_delete_num)
887 def verify_ipfix_addr_exhausted(self, data):
889 Verify IPFIX NAT addresses event
891 :param data: Decoded IPFIX data records
893 self.assertEqual(1, len(data))
896 self.assertEqual(scapy.compat.orb(record[230]), 3)
898 self.assertEqual(struct.pack("!I", 0), record[283])
900 def verify_ipfix_max_sessions(self, data, limit):
902 Verify IPFIX maximum session entries exceeded event
904 :param data: Decoded IPFIX data records
905 :param limit: Number of maximum session entries that can be created.
907 self.assertEqual(1, len(data))
910 self.assertEqual(scapy.compat.orb(record[230]), 13)
911 # natQuotaExceededEvent
912 self.assertEqual(struct.pack("I", 1), record[466])
914 self.assertEqual(struct.pack("I", limit), record[471])
916 def verify_ipfix_max_bibs(self, data, limit):
918 Verify IPFIX maximum BIB entries exceeded event
920 :param data: Decoded IPFIX data records
921 :param limit: Number of maximum BIB entries that can be created.
923 self.assertEqual(1, len(data))
926 self.assertEqual(scapy.compat.orb(record[230]), 13)
927 # natQuotaExceededEvent
928 self.assertEqual(struct.pack("I", 2), record[466])
930 self.assertEqual(struct.pack("I", limit), record[472])
932 def verify_ipfix_max_fragments_ip6(self, data, limit, src_addr):
934 Verify IPFIX maximum IPv6 fragments pending reassembly exceeded event
936 :param data: Decoded IPFIX data records
937 :param limit: Number of maximum fragments pending reassembly
938 :param src_addr: IPv6 source address
940 self.assertEqual(1, len(data))
943 self.assertEqual(scapy.compat.orb(record[230]), 13)
944 # natQuotaExceededEvent
945 self.assertEqual(struct.pack("I", 5), record[466])
946 # maxFragmentsPendingReassembly
947 self.assertEqual(struct.pack("I", limit), record[475])
949 self.assertEqual(src_addr, record[27])
951 def verify_ipfix_max_fragments_ip4(self, data, limit, src_addr):
953 Verify IPFIX maximum IPv4 fragments pending reassembly exceeded event
955 :param data: Decoded IPFIX data records
956 :param limit: Number of maximum fragments pending reassembly
957 :param src_addr: IPv4 source address
959 self.assertEqual(1, len(data))
962 self.assertEqual(scapy.compat.orb(record[230]), 13)
963 # natQuotaExceededEvent
964 self.assertEqual(struct.pack("I", 5), record[466])
965 # maxFragmentsPendingReassembly
966 self.assertEqual(struct.pack("I", limit), record[475])
968 self.assertEqual(src_addr, record[8])
970 def verify_ipfix_bib(self, data, is_create, src_addr):
972 Verify IPFIX NAT64 BIB create and delete events
974 :param data: Decoded IPFIX data records
975 :param is_create: Create event if nonzero value otherwise delete event
976 :param src_addr: IPv6 source address
978 self.assertEqual(1, len(data))
982 self.assertEqual(scapy.compat.orb(record[230]), 10)
984 self.assertEqual(scapy.compat.orb(record[230]), 11)
986 self.assertEqual(src_addr, record[27])
987 # postNATSourceIPv4Address
988 self.assertEqual(self.nat_addr_n, record[225])
990 self.assertEqual(IP_PROTOS.tcp, scapy.compat.orb(record[4]))
992 self.assertEqual(struct.pack("!I", 0), record[234])
993 # sourceTransportPort
994 self.assertEqual(struct.pack("!H", self.tcp_port_in), record[7])
995 # postNAPTSourceTransportPort
996 self.assertEqual(struct.pack("!H", self.tcp_port_out), record[227])
998 def verify_ipfix_nat64_ses(self, data, is_create, src_addr, dst_addr,
1001 Verify IPFIX NAT64 session create and delete events
1003 :param data: Decoded IPFIX data records
1004 :param is_create: Create event if nonzero value otherwise delete event
1005 :param src_addr: IPv6 source address
1006 :param dst_addr: IPv4 destination address
1007 :param dst_port: destination TCP port
1009 self.assertEqual(1, len(data))
1013 self.assertEqual(scapy.compat.orb(record[230]), 6)
1015 self.assertEqual(scapy.compat.orb(record[230]), 7)
1017 self.assertEqual(src_addr, record[27])
1018 # destinationIPv6Address
1019 self.assertEqual(socket.inet_pton(socket.AF_INET6,
1020 self.compose_ip6(dst_addr,
1024 # postNATSourceIPv4Address
1025 self.assertEqual(self.nat_addr_n, record[225])
1026 # postNATDestinationIPv4Address
1027 self.assertEqual(socket.inet_pton(socket.AF_INET, dst_addr),
1029 # protocolIdentifier
1030 self.assertEqual(IP_PROTOS.tcp, scapy.compat.orb(record[4]))
1032 self.assertEqual(struct.pack("!I", 0), record[234])
1033 # sourceTransportPort
1034 self.assertEqual(struct.pack("!H", self.tcp_port_in), record[7])
1035 # postNAPTSourceTransportPort
1036 self.assertEqual(struct.pack("!H", self.tcp_port_out), record[227])
1037 # destinationTransportPort
1038 self.assertEqual(struct.pack("!H", dst_port), record[11])
1039 # postNAPTDestinationTransportPort
1040 self.assertEqual(struct.pack("!H", dst_port), record[228])
1042 def verify_no_nat44_user(self):
1043 """ Verify that there is no NAT44 user """
1044 users = self.vapi.nat44_user_dump()
1045 self.assertEqual(len(users), 0)
1046 users = self.statistics.get_counter('/nat44/total-users')
1047 self.assertEqual(users[0][0], 0)
1048 sessions = self.statistics.get_counter('/nat44/total-sessions')
1049 self.assertEqual(sessions[0][0], 0)
1051 def verify_ipfix_max_entries_per_user(self, data, limit, src_addr):
1053 Verify IPFIX maximum entries per user exceeded event
1055 :param data: Decoded IPFIX data records
1056 :param limit: Number of maximum entries per user
1057 :param src_addr: IPv4 source address
1059 self.assertEqual(1, len(data))
1062 self.assertEqual(scapy.compat.orb(record[230]), 13)
1063 # natQuotaExceededEvent
1064 self.assertEqual(struct.pack("I", 3), record[466])
1066 self.assertEqual(struct.pack("I", limit), record[473])
1068 self.assertEqual(src_addr, record[8])
1070 def verify_syslog_apmap(self, data, is_add=True):
1071 message = data.decode('utf-8')
1073 message = SyslogMessage.parse(message)
1074 except ParseError as e:
1075 self.logger.error(e)
1078 self.assertEqual(message.severity, SyslogSeverity.info)
1079 self.assertEqual(message.appname, 'NAT')
1080 self.assertEqual(message.msgid, 'APMADD' if is_add else 'APMDEL')
1081 sd_params = message.sd.get('napmap')
1082 self.assertTrue(sd_params is not None)
1083 self.assertEqual(sd_params.get('IATYP'), 'IPv4')
1084 self.assertEqual(sd_params.get('ISADDR'), self.pg0.remote_ip4)
1085 self.assertEqual(sd_params.get('ISPORT'), "%d" % self.tcp_port_in)
1086 self.assertEqual(sd_params.get('XATYP'), 'IPv4')
1087 self.assertEqual(sd_params.get('XSADDR'), self.nat_addr)
1088 self.assertEqual(sd_params.get('XSPORT'), "%d" % self.tcp_port_out)
1089 self.assertEqual(sd_params.get('PROTO'), "%d" % IP_PROTOS.tcp)
1090 self.assertTrue(sd_params.get('SSUBIX') is not None)
1091 self.assertEqual(sd_params.get('SVLAN'), '0')
1093 def verify_syslog_sess(self, data, is_add=True, is_ip6=False):
1094 message = data.decode('utf-8')
1096 message = SyslogMessage.parse(message)
1097 except ParseError as e:
1098 self.logger.error(e)
1101 self.assertEqual(message.severity, SyslogSeverity.info)
1102 self.assertEqual(message.appname, 'NAT')
1103 self.assertEqual(message.msgid, 'SADD' if is_add else 'SDEL')
1104 sd_params = message.sd.get('nsess')
1105 self.assertTrue(sd_params is not None)
1107 self.assertEqual(sd_params.get('IATYP'), 'IPv6')
1108 self.assertEqual(sd_params.get('ISADDR'), self.pg0.remote_ip6)
1110 self.assertEqual(sd_params.get('IATYP'), 'IPv4')
1111 self.assertEqual(sd_params.get('ISADDR'), self.pg0.remote_ip4)
1112 self.assertTrue(sd_params.get('SSUBIX') is not None)
1113 self.assertEqual(sd_params.get('ISPORT'), "%d" % self.tcp_port_in)
1114 self.assertEqual(sd_params.get('XATYP'), 'IPv4')
1115 self.assertEqual(sd_params.get('XSADDR'), self.nat_addr)
1116 self.assertEqual(sd_params.get('XSPORT'), "%d" % self.tcp_port_out)
1117 self.assertEqual(sd_params.get('PROTO'), "%d" % IP_PROTOS.tcp)
1118 self.assertEqual(sd_params.get('SVLAN'), '0')
1119 self.assertEqual(sd_params.get('XDADDR'), self.pg1.remote_ip4)
1120 self.assertEqual(sd_params.get('XDPORT'),
1121 "%d" % self.tcp_external_port)
1123 def verify_mss_value(self, pkt, mss):
1125 Verify TCP MSS value
1130 if not pkt.haslayer(IP) or not pkt.haslayer(TCP):
1131 raise TypeError("Not a TCP/IP packet")
1133 for option in pkt[TCP].options:
1134 if option[0] == 'MSS':
1135 self.assertEqual(option[1], mss)
1136 self.assert_tcp_checksum_valid(pkt)
1139 def proto2layer(proto):
1140 if proto == IP_PROTOS.tcp:
1142 elif proto == IP_PROTOS.udp:
1144 elif proto == IP_PROTOS.icmp:
1147 raise Exception("Unsupported protocol")
1149 def frag_in_order(self, proto=IP_PROTOS.tcp, dont_translate=False):
1150 layer = self.proto2layer(proto)
1152 if proto == IP_PROTOS.tcp:
1153 data = b"A" * 4 + b"B" * 16 + b"C" * 3
1155 data = b"A" * 16 + b"B" * 16 + b"C" * 3
1156 self.port_in = random.randint(1025, 65535)
1158 reass = self.vapi.nat_reass_dump()
1159 reass_n_start = len(reass)
1162 pkts = self.create_stream_frag(self.pg0,
1163 self.pg1.remote_ip4,
1168 self.pg0.add_stream(pkts)
1169 self.pg_enable_capture(self.pg_interfaces)
1171 frags = self.pg1.get_capture(len(pkts))
1172 if not dont_translate:
1173 p = self.reass_frags_and_verify(frags,
1175 self.pg1.remote_ip4)
1177 p = self.reass_frags_and_verify(frags,
1178 self.pg0.remote_ip4,
1179 self.pg1.remote_ip4)
1180 if proto != IP_PROTOS.icmp:
1181 if not dont_translate:
1182 self.assertEqual(p[layer].dport, 20)
1183 self.assertNotEqual(p[layer].sport, self.port_in)
1185 self.assertEqual(p[layer].sport, self.port_in)
1187 if not dont_translate:
1188 self.assertNotEqual(p[layer].id, self.port_in)
1190 self.assertEqual(p[layer].id, self.port_in)
1191 self.assertEqual(data, p[Raw].load)
1194 if not dont_translate:
1195 dst_addr = self.nat_addr
1197 dst_addr = self.pg0.remote_ip4
1198 if proto != IP_PROTOS.icmp:
1200 dport = p[layer].sport
1204 pkts = self.create_stream_frag(self.pg1,
1211 self.pg1.add_stream(pkts)
1212 self.pg_enable_capture(self.pg_interfaces)
1214 frags = self.pg0.get_capture(len(pkts))
1215 p = self.reass_frags_and_verify(frags,
1216 self.pg1.remote_ip4,
1217 self.pg0.remote_ip4)
1218 if proto != IP_PROTOS.icmp:
1219 self.assertEqual(p[layer].sport, 20)
1220 self.assertEqual(p[layer].dport, self.port_in)
1222 self.assertEqual(p[layer].id, self.port_in)
1223 self.assertEqual(data, p[Raw].load)
1225 reass = self.vapi.nat_reass_dump()
1226 reass_n_end = len(reass)
1228 self.assertEqual(reass_n_end - reass_n_start, 2)
1230 def frag_in_order_in_plus_out(self, proto=IP_PROTOS.tcp):
1231 layer = self.proto2layer(proto)
1233 if proto == IP_PROTOS.tcp:
1234 data = b"A" * 4 + b"B" * 16 + b"C" * 3
1236 data = b"A" * 16 + b"B" * 16 + b"C" * 3
1237 self.port_in = random.randint(1025, 65535)
1240 reass = self.vapi.nat_reass_dump()
1241 reass_n_start = len(reass)
1244 pkts = self.create_stream_frag(self.pg0,
1245 self.server_out_addr,
1247 self.server_out_port,
1250 self.pg0.add_stream(pkts)
1251 self.pg_enable_capture(self.pg_interfaces)
1253 frags = self.pg1.get_capture(len(pkts))
1254 p = self.reass_frags_and_verify(frags,
1255 self.pg0.remote_ip4,
1256 self.server_in_addr)
1257 if proto != IP_PROTOS.icmp:
1258 self.assertEqual(p[layer].sport, self.port_in)
1259 self.assertEqual(p[layer].dport, self.server_in_port)
1261 self.assertEqual(p[layer].id, self.port_in)
1262 self.assertEqual(data, p[Raw].load)
1265 if proto != IP_PROTOS.icmp:
1266 pkts = self.create_stream_frag(self.pg1,
1267 self.pg0.remote_ip4,
1268 self.server_in_port,
1273 pkts = self.create_stream_frag(self.pg1,
1274 self.pg0.remote_ip4,
1280 self.pg1.add_stream(pkts)
1281 self.pg_enable_capture(self.pg_interfaces)
1283 frags = self.pg0.get_capture(len(pkts))
1284 p = self.reass_frags_and_verify(frags,
1285 self.server_out_addr,
1286 self.pg0.remote_ip4)
1287 if proto != IP_PROTOS.icmp:
1288 self.assertEqual(p[layer].sport, self.server_out_port)
1289 self.assertEqual(p[layer].dport, self.port_in)
1291 self.assertEqual(p[layer].id, self.port_in)
1292 self.assertEqual(data, p[Raw].load)
1294 reass = self.vapi.nat_reass_dump()
1295 reass_n_end = len(reass)
1297 self.assertEqual(reass_n_end - reass_n_start, 2)
1299 def reass_hairpinning(self, proto=IP_PROTOS.tcp):
1300 layer = self.proto2layer(proto)
1302 if proto == IP_PROTOS.tcp:
1303 data = b"A" * 4 + b"B" * 16 + b"C" * 3
1305 data = b"A" * 16 + b"B" * 16 + b"C" * 3
1307 # send packet from host to server
1308 pkts = self.create_stream_frag(self.pg0,
1311 self.server_out_port,
1314 self.pg0.add_stream(pkts)
1315 self.pg_enable_capture(self.pg_interfaces)
1317 frags = self.pg0.get_capture(len(pkts))
1318 p = self.reass_frags_and_verify(frags,
1321 if proto != IP_PROTOS.icmp:
1322 self.assertNotEqual(p[layer].sport, self.host_in_port)
1323 self.assertEqual(p[layer].dport, self.server_in_port)
1325 self.assertNotEqual(p[layer].id, self.host_in_port)
1326 self.assertEqual(data, p[Raw].load)
1328 def frag_out_of_order(self, proto=IP_PROTOS.tcp, dont_translate=False):
1329 layer = self.proto2layer(proto)
1331 if proto == IP_PROTOS.tcp:
1332 data = b"A" * 4 + b"B" * 16 + b"C" * 3
1334 data = b"A" * 16 + b"B" * 16 + b"C" * 3
1335 self.port_in = random.randint(1025, 65535)
1339 pkts = self.create_stream_frag(self.pg0,
1340 self.pg1.remote_ip4,
1346 self.pg0.add_stream(pkts)
1347 self.pg_enable_capture(self.pg_interfaces)
1349 frags = self.pg1.get_capture(len(pkts))
1350 if not dont_translate:
1351 p = self.reass_frags_and_verify(frags,
1353 self.pg1.remote_ip4)
1355 p = self.reass_frags_and_verify(frags,
1356 self.pg0.remote_ip4,
1357 self.pg1.remote_ip4)
1358 if proto != IP_PROTOS.icmp:
1359 if not dont_translate:
1360 self.assertEqual(p[layer].dport, 20)
1361 self.assertNotEqual(p[layer].sport, self.port_in)
1363 self.assertEqual(p[layer].sport, self.port_in)
1365 if not dont_translate:
1366 self.assertNotEqual(p[layer].id, self.port_in)
1368 self.assertEqual(p[layer].id, self.port_in)
1369 self.assertEqual(data, p[Raw].load)
1372 if not dont_translate:
1373 dst_addr = self.nat_addr
1375 dst_addr = self.pg0.remote_ip4
1376 if proto != IP_PROTOS.icmp:
1378 dport = p[layer].sport
1382 pkts = self.create_stream_frag(self.pg1,
1390 self.pg1.add_stream(pkts)
1391 self.pg_enable_capture(self.pg_interfaces)
1393 frags = self.pg0.get_capture(len(pkts))
1394 p = self.reass_frags_and_verify(frags,
1395 self.pg1.remote_ip4,
1396 self.pg0.remote_ip4)
1397 if proto != IP_PROTOS.icmp:
1398 self.assertEqual(p[layer].sport, 20)
1399 self.assertEqual(p[layer].dport, self.port_in)
1401 self.assertEqual(p[layer].id, self.port_in)
1402 self.assertEqual(data, p[Raw].load)
1404 def frag_out_of_order_in_plus_out(self, proto=IP_PROTOS.tcp):
1405 layer = self.proto2layer(proto)
1407 if proto == IP_PROTOS.tcp:
1408 data = b"A" * 4 + b"B" * 16 + b"C" * 3
1410 data = b"A" * 16 + b"B" * 16 + b"C" * 3
1411 self.port_in = random.randint(1025, 65535)
1415 pkts = self.create_stream_frag(self.pg0,
1416 self.server_out_addr,
1418 self.server_out_port,
1422 self.pg0.add_stream(pkts)
1423 self.pg_enable_capture(self.pg_interfaces)
1425 frags = self.pg1.get_capture(len(pkts))
1426 p = self.reass_frags_and_verify(frags,
1427 self.pg0.remote_ip4,
1428 self.server_in_addr)
1429 if proto != IP_PROTOS.icmp:
1430 self.assertEqual(p[layer].dport, self.server_in_port)
1431 self.assertEqual(p[layer].sport, self.port_in)
1432 self.assertEqual(p[layer].dport, self.server_in_port)
1434 self.assertEqual(p[layer].id, self.port_in)
1435 self.assertEqual(data, p[Raw].load)
1438 if proto != IP_PROTOS.icmp:
1439 pkts = self.create_stream_frag(self.pg1,
1440 self.pg0.remote_ip4,
1441 self.server_in_port,
1446 pkts = self.create_stream_frag(self.pg1,
1447 self.pg0.remote_ip4,
1454 self.pg1.add_stream(pkts)
1455 self.pg_enable_capture(self.pg_interfaces)
1457 frags = self.pg0.get_capture(len(pkts))
1458 p = self.reass_frags_and_verify(frags,
1459 self.server_out_addr,
1460 self.pg0.remote_ip4)
1461 if proto != IP_PROTOS.icmp:
1462 self.assertEqual(p[layer].sport, self.server_out_port)
1463 self.assertEqual(p[layer].dport, self.port_in)
1465 self.assertEqual(p[layer].id, self.port_in)
1466 self.assertEqual(data, p[Raw].load)
1469 class TestNAT44(MethodHolder):
1470 """ NAT44 Test Cases """
1473 def setUpClass(cls):
1474 super(TestNAT44, cls).setUpClass()
1475 cls.vapi.cli("set log class nat level debug")
1478 cls.tcp_port_in = 6303
1479 cls.tcp_port_out = 6303
1480 cls.udp_port_in = 6304
1481 cls.udp_port_out = 6304
1482 cls.icmp_id_in = 6305
1483 cls.icmp_id_out = 6305
1484 cls.nat_addr = '10.0.0.3'
1485 cls.ipfix_src_port = 4739
1486 cls.ipfix_domain_id = 1
1487 cls.tcp_external_port = 80
1488 cls.udp_external_port = 69
1490 cls.create_pg_interfaces(range(10))
1491 cls.interfaces = list(cls.pg_interfaces[0:4])
1493 for i in cls.interfaces:
1498 cls.pg0.generate_remote_hosts(3)
1499 cls.pg0.configure_ipv4_neighbors()
1501 cls.pg1.generate_remote_hosts(1)
1502 cls.pg1.configure_ipv4_neighbors()
1504 cls.overlapping_interfaces = list(list(cls.pg_interfaces[4:7]))
1505 cls.vapi.ip_table_add_del(is_add=1, table_id=10)
1506 cls.vapi.ip_table_add_del(is_add=1, table_id=20)
1508 cls.pg4._local_ip4 = VppIpPrefix("172.16.255.1",
1509 cls.pg4.local_ip4_prefix.len)
1510 cls.pg4._remote_hosts[0]._ip4 = "172.16.255.2"
1511 cls.pg4.set_table_ip4(10)
1512 cls.pg5._local_ip4 = VppIpPrefix("172.17.255.3",
1513 cls.pg5.local_ip4_prefix.len)
1514 cls.pg5._remote_hosts[0]._ip4 = "172.17.255.4"
1515 cls.pg5.set_table_ip4(10)
1516 cls.pg6._local_ip4 = VppIpPrefix("172.16.255.1",
1517 cls.pg6.local_ip4_prefix.len)
1518 cls.pg6._remote_hosts[0]._ip4 = "172.16.255.2"
1519 cls.pg6.set_table_ip4(20)
1520 for i in cls.overlapping_interfaces:
1528 cls.pg9.generate_remote_hosts(2)
1529 cls.pg9.config_ip4()
1530 cls.vapi.sw_interface_add_del_address(
1531 sw_if_index=cls.pg9.sw_if_index,
1532 prefix=VppIpPrefix("10.0.0.1", 24).encode())
1535 cls.pg9.resolve_arp()
1536 cls.pg9._remote_hosts[1]._ip4 = cls.pg9._remote_hosts[0]._ip4
1537 cls.pg4._remote_ip4 = cls.pg9._remote_hosts[0]._ip4 = "10.0.0.2"
1538 cls.pg9.resolve_arp()
1541 super(TestNAT44, cls).tearDownClass()
1545 def tearDownClass(cls):
1546 super(TestNAT44, cls).tearDownClass()
1548 def test_dynamic(self):
1549 """ NAT44 dynamic translation test """
1550 self.nat44_add_address(self.nat_addr)
1551 flags = self.config_flags.NAT_IS_INSIDE
1552 self.vapi.nat44_interface_add_del_feature(
1553 sw_if_index=self.pg0.sw_if_index,
1554 flags=flags, is_add=1)
1555 self.vapi.nat44_interface_add_del_feature(
1556 sw_if_index=self.pg1.sw_if_index,
1560 tcpn = self.statistics.get_err_counter(
1561 '/err/nat44-in2out-slowpath/TCP packets')
1562 udpn = self.statistics.get_err_counter(
1563 '/err/nat44-in2out-slowpath/UDP packets')
1564 icmpn = self.statistics.get_err_counter(
1565 '/err/nat44-in2out-slowpath/ICMP packets')
1566 totaln = self.statistics.get_err_counter(
1567 '/err/nat44-in2out-slowpath/good in2out packets processed')
1569 pkts = self.create_stream_in(self.pg0, self.pg1)
1570 self.pg0.add_stream(pkts)
1571 self.pg_enable_capture(self.pg_interfaces)
1573 capture = self.pg1.get_capture(len(pkts))
1574 self.verify_capture_out(capture)
1576 err = self.statistics.get_err_counter(
1577 '/err/nat44-in2out-slowpath/TCP packets')
1578 self.assertEqual(err - tcpn, 1)
1579 err = self.statistics.get_err_counter(
1580 '/err/nat44-in2out-slowpath/UDP packets')
1581 self.assertEqual(err - udpn, 1)
1582 err = self.statistics.get_err_counter(
1583 '/err/nat44-in2out-slowpath/ICMP packets')
1584 self.assertEqual(err - icmpn, 1)
1585 err = self.statistics.get_err_counter(
1586 '/err/nat44-in2out-slowpath/good in2out packets processed')
1587 self.assertEqual(err - totaln, 3)
1590 tcpn = self.statistics.get_err_counter('/err/nat44-out2in/TCP packets')
1591 udpn = self.statistics.get_err_counter('/err/nat44-out2in/UDP packets')
1592 icmpn = self.statistics.get_err_counter(
1593 '/err/nat44-out2in/ICMP packets')
1594 totaln = self.statistics.get_err_counter(
1595 '/err/nat44-out2in/good out2in packets processed')
1597 pkts = self.create_stream_out(self.pg1)
1598 self.pg1.add_stream(pkts)
1599 self.pg_enable_capture(self.pg_interfaces)
1601 capture = self.pg0.get_capture(len(pkts))
1602 self.verify_capture_in(capture, self.pg0)
1604 err = self.statistics.get_err_counter('/err/nat44-out2in/TCP packets')
1605 self.assertEqual(err - tcpn, 1)
1606 err = self.statistics.get_err_counter('/err/nat44-out2in/UDP packets')
1607 self.assertEqual(err - udpn, 1)
1608 err = self.statistics.get_err_counter('/err/nat44-out2in/ICMP packets')
1609 self.assertEqual(err - icmpn, 1)
1610 err = self.statistics.get_err_counter(
1611 '/err/nat44-out2in/good out2in packets processed')
1612 self.assertEqual(err - totaln, 3)
1614 users = self.statistics.get_counter('/nat44/total-users')
1615 self.assertEqual(users[0][0], 1)
1616 sessions = self.statistics.get_counter('/nat44/total-sessions')
1617 self.assertEqual(sessions[0][0], 3)
1619 def test_dynamic_icmp_errors_in2out_ttl_1(self):
1620 """ NAT44 handling of client packets with TTL=1 """
1622 self.nat44_add_address(self.nat_addr)
1623 flags = self.config_flags.NAT_IS_INSIDE
1624 self.vapi.nat44_interface_add_del_feature(
1625 sw_if_index=self.pg0.sw_if_index,
1626 flags=flags, is_add=1)
1627 self.vapi.nat44_interface_add_del_feature(
1628 sw_if_index=self.pg1.sw_if_index,
1631 # Client side - generate traffic
1632 pkts = self.create_stream_in(self.pg0, self.pg1, ttl=1)
1633 self.pg0.add_stream(pkts)
1634 self.pg_enable_capture(self.pg_interfaces)
1637 # Client side - verify ICMP type 11 packets
1638 capture = self.pg0.get_capture(len(pkts))
1639 self.verify_capture_in_with_icmp_errors(capture, self.pg0)
1641 def test_dynamic_icmp_errors_out2in_ttl_1(self):
1642 """ NAT44 handling of server packets with TTL=1 """
1644 self.nat44_add_address(self.nat_addr)
1645 flags = self.config_flags.NAT_IS_INSIDE
1646 self.vapi.nat44_interface_add_del_feature(
1647 sw_if_index=self.pg0.sw_if_index,
1648 flags=flags, is_add=1)
1649 self.vapi.nat44_interface_add_del_feature(
1650 sw_if_index=self.pg1.sw_if_index,
1653 # Client side - create sessions
1654 pkts = self.create_stream_in(self.pg0, self.pg1)
1655 self.pg0.add_stream(pkts)
1656 self.pg_enable_capture(self.pg_interfaces)
1659 # Server side - generate traffic
1660 capture = self.pg1.get_capture(len(pkts))
1661 self.verify_capture_out(capture)
1662 pkts = self.create_stream_out(self.pg1, ttl=1)
1663 self.pg1.add_stream(pkts)
1664 self.pg_enable_capture(self.pg_interfaces)
1667 # Server side - verify ICMP type 11 packets
1668 capture = self.pg1.get_capture(len(pkts))
1669 self.verify_capture_out_with_icmp_errors(capture,
1670 src_ip=self.pg1.local_ip4)
1672 def test_dynamic_icmp_errors_in2out_ttl_2(self):
1673 """ NAT44 handling of error responses to client packets with TTL=2 """
1675 self.nat44_add_address(self.nat_addr)
1676 flags = self.config_flags.NAT_IS_INSIDE
1677 self.vapi.nat44_interface_add_del_feature(
1678 sw_if_index=self.pg0.sw_if_index,
1679 flags=flags, is_add=1)
1680 self.vapi.nat44_interface_add_del_feature(
1681 sw_if_index=self.pg1.sw_if_index,
1684 # Client side - generate traffic
1685 pkts = self.create_stream_in(self.pg0, self.pg1, ttl=2)
1686 self.pg0.add_stream(pkts)
1687 self.pg_enable_capture(self.pg_interfaces)
1690 # Server side - simulate ICMP type 11 response
1691 capture = self.pg1.get_capture(len(pkts))
1692 pkts = [Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
1693 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
1694 ICMP(type=11) / packet[IP] for packet in capture]
1695 self.pg1.add_stream(pkts)
1696 self.pg_enable_capture(self.pg_interfaces)
1699 # Client side - verify ICMP type 11 packets
1700 capture = self.pg0.get_capture(len(pkts))
1701 self.verify_capture_in_with_icmp_errors(capture, self.pg0)
1703 def test_dynamic_icmp_errors_out2in_ttl_2(self):
1704 """ NAT44 handling of error responses to server packets with TTL=2 """
1706 self.nat44_add_address(self.nat_addr)
1707 flags = self.config_flags.NAT_IS_INSIDE
1708 self.vapi.nat44_interface_add_del_feature(
1709 sw_if_index=self.pg0.sw_if_index,
1710 flags=flags, is_add=1)
1711 self.vapi.nat44_interface_add_del_feature(
1712 sw_if_index=self.pg1.sw_if_index,
1715 # Client side - create sessions
1716 pkts = self.create_stream_in(self.pg0, self.pg1)
1717 self.pg0.add_stream(pkts)
1718 self.pg_enable_capture(self.pg_interfaces)
1721 # Server side - generate traffic
1722 capture = self.pg1.get_capture(len(pkts))
1723 self.verify_capture_out(capture)
1724 pkts = self.create_stream_out(self.pg1, ttl=2)
1725 self.pg1.add_stream(pkts)
1726 self.pg_enable_capture(self.pg_interfaces)
1729 # Client side - simulate ICMP type 11 response
1730 capture = self.pg0.get_capture(len(pkts))
1731 pkts = [Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
1732 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
1733 ICMP(type=11) / packet[IP] for packet in capture]
1734 self.pg0.add_stream(pkts)
1735 self.pg_enable_capture(self.pg_interfaces)
1738 # Server side - verify ICMP type 11 packets
1739 capture = self.pg1.get_capture(len(pkts))
1740 self.verify_capture_out_with_icmp_errors(capture)
1742 def test_ping_out_interface_from_outside(self):
1743 """ Ping NAT44 out interface from outside network """
1745 self.nat44_add_address(self.nat_addr)
1746 flags = self.config_flags.NAT_IS_INSIDE
1747 self.vapi.nat44_interface_add_del_feature(
1748 sw_if_index=self.pg0.sw_if_index,
1749 flags=flags, is_add=1)
1750 self.vapi.nat44_interface_add_del_feature(
1751 sw_if_index=self.pg1.sw_if_index,
1754 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
1755 IP(src=self.pg1.remote_ip4, dst=self.pg1.local_ip4) /
1756 ICMP(id=self.icmp_id_out, type='echo-request'))
1758 self.pg1.add_stream(pkts)
1759 self.pg_enable_capture(self.pg_interfaces)
1761 capture = self.pg1.get_capture(len(pkts))
1764 self.assertEqual(packet[IP].src, self.pg1.local_ip4)
1765 self.assertEqual(packet[IP].dst, self.pg1.remote_ip4)
1766 self.assertEqual(packet[ICMP].id, self.icmp_id_in)
1767 self.assertEqual(packet[ICMP].type, 0) # echo reply
1769 self.logger.error(ppp("Unexpected or invalid packet "
1770 "(outside network):", packet))
1773 def test_ping_internal_host_from_outside(self):
1774 """ Ping internal host from outside network """
1776 self.nat44_add_static_mapping(self.pg0.remote_ip4, self.nat_addr)
1777 flags = self.config_flags.NAT_IS_INSIDE
1778 self.vapi.nat44_interface_add_del_feature(
1779 sw_if_index=self.pg0.sw_if_index,
1780 flags=flags, is_add=1)
1781 self.vapi.nat44_interface_add_del_feature(
1782 sw_if_index=self.pg1.sw_if_index,
1786 pkt = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
1787 IP(src=self.pg1.remote_ip4, dst=self.nat_addr, ttl=64) /
1788 ICMP(id=self.icmp_id_out, type='echo-request'))
1789 self.pg1.add_stream(pkt)
1790 self.pg_enable_capture(self.pg_interfaces)
1792 capture = self.pg0.get_capture(1)
1793 self.verify_capture_in(capture, self.pg0)
1794 self.assert_equal(capture[0][IP].proto, IP_PROTOS.icmp)
1797 pkt = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
1798 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4, ttl=64) /
1799 ICMP(id=self.icmp_id_in, type='echo-reply'))
1800 self.pg0.add_stream(pkt)
1801 self.pg_enable_capture(self.pg_interfaces)
1803 capture = self.pg1.get_capture(1)
1804 self.verify_capture_out(capture, same_port=True)
1805 self.assert_equal(capture[0][IP].proto, IP_PROTOS.icmp)
1807 def test_forwarding(self):
1808 """ NAT44 forwarding test """
1810 flags = self.config_flags.NAT_IS_INSIDE
1811 self.vapi.nat44_interface_add_del_feature(
1812 sw_if_index=self.pg0.sw_if_index,
1813 flags=flags, is_add=1)
1814 self.vapi.nat44_interface_add_del_feature(
1815 sw_if_index=self.pg1.sw_if_index,
1817 self.vapi.nat44_forwarding_enable_disable(enable=1)
1819 real_ip = self.pg0.remote_ip4n
1820 alias_ip = self.nat_addr
1821 flags = self.config_flags.NAT_IS_ADDR_ONLY
1822 self.vapi.nat44_add_del_static_mapping(is_add=1,
1823 local_ip_address=real_ip,
1824 external_ip_address=alias_ip,
1825 external_sw_if_index=0xFFFFFFFF,
1829 # static mapping match
1831 pkts = self.create_stream_out(self.pg1)
1832 self.pg1.add_stream(pkts)
1833 self.pg_enable_capture(self.pg_interfaces)
1835 capture = self.pg0.get_capture(len(pkts))
1836 self.verify_capture_in(capture, self.pg0)
1838 pkts = self.create_stream_in(self.pg0, self.pg1)
1839 self.pg0.add_stream(pkts)
1840 self.pg_enable_capture(self.pg_interfaces)
1842 capture = self.pg1.get_capture(len(pkts))
1843 self.verify_capture_out(capture, same_port=True)
1845 # no static mapping match
1847 host0 = self.pg0.remote_hosts[0]
1848 self.pg0.remote_hosts[0] = self.pg0.remote_hosts[1]
1850 pkts = self.create_stream_out(self.pg1,
1851 dst_ip=self.pg0.remote_ip4,
1852 use_inside_ports=True)
1853 self.pg1.add_stream(pkts)
1854 self.pg_enable_capture(self.pg_interfaces)
1856 capture = self.pg0.get_capture(len(pkts))
1857 self.verify_capture_in(capture, self.pg0)
1859 pkts = self.create_stream_in(self.pg0, self.pg1)
1860 self.pg0.add_stream(pkts)
1861 self.pg_enable_capture(self.pg_interfaces)
1863 capture = self.pg1.get_capture(len(pkts))
1864 self.verify_capture_out(capture, nat_ip=self.pg0.remote_ip4,
1867 self.pg0.remote_hosts[0] = host0
1870 self.vapi.nat44_forwarding_enable_disable(enable=0)
1871 flags = self.config_flags.NAT_IS_ADDR_ONLY
1872 self.vapi.nat44_add_del_static_mapping(
1874 local_ip_address=real_ip,
1875 external_ip_address=alias_ip,
1876 external_sw_if_index=0xFFFFFFFF,
1879 def test_static_in(self):
1880 """ 1:1 NAT initialized from inside network """
1882 nat_ip = "10.0.0.10"
1883 self.tcp_port_out = 6303
1884 self.udp_port_out = 6304
1885 self.icmp_id_out = 6305
1887 self.nat44_add_static_mapping(self.pg0.remote_ip4, nat_ip)
1888 flags = self.config_flags.NAT_IS_INSIDE
1889 self.vapi.nat44_interface_add_del_feature(
1890 sw_if_index=self.pg0.sw_if_index,
1891 flags=flags, is_add=1)
1892 self.vapi.nat44_interface_add_del_feature(
1893 sw_if_index=self.pg1.sw_if_index,
1895 sm = self.vapi.nat44_static_mapping_dump()
1896 self.assertEqual(len(sm), 1)
1897 self.assertEqual((sm[0].tag).split(b'\0', 1)[0], b'')
1898 self.assertEqual(sm[0].protocol, 0)
1899 self.assertEqual(sm[0].local_port, 0)
1900 self.assertEqual(sm[0].external_port, 0)
1903 pkts = self.create_stream_in(self.pg0, self.pg1)
1904 self.pg0.add_stream(pkts)
1905 self.pg_enable_capture(self.pg_interfaces)
1907 capture = self.pg1.get_capture(len(pkts))
1908 self.verify_capture_out(capture, nat_ip, True)
1911 pkts = self.create_stream_out(self.pg1, nat_ip)
1912 self.pg1.add_stream(pkts)
1913 self.pg_enable_capture(self.pg_interfaces)
1915 capture = self.pg0.get_capture(len(pkts))
1916 self.verify_capture_in(capture, self.pg0)
1918 def test_static_out(self):
1919 """ 1:1 NAT initialized from outside network """
1921 nat_ip = "10.0.0.20"
1922 self.tcp_port_out = 6303
1923 self.udp_port_out = 6304
1924 self.icmp_id_out = 6305
1927 self.nat44_add_static_mapping(self.pg0.remote_ip4, nat_ip, tag=tag)
1928 flags = self.config_flags.NAT_IS_INSIDE
1929 self.vapi.nat44_interface_add_del_feature(
1930 sw_if_index=self.pg0.sw_if_index,
1931 flags=flags, is_add=1)
1932 self.vapi.nat44_interface_add_del_feature(
1933 sw_if_index=self.pg1.sw_if_index,
1935 sm = self.vapi.nat44_static_mapping_dump()
1936 self.assertEqual(len(sm), 1)
1937 self.assertEqual((sm[0].tag).split(b'\0', 1)[0], tag)
1940 pkts = self.create_stream_out(self.pg1, nat_ip)
1941 self.pg1.add_stream(pkts)
1942 self.pg_enable_capture(self.pg_interfaces)
1944 capture = self.pg0.get_capture(len(pkts))
1945 self.verify_capture_in(capture, self.pg0)
1948 pkts = self.create_stream_in(self.pg0, self.pg1)
1949 self.pg0.add_stream(pkts)
1950 self.pg_enable_capture(self.pg_interfaces)
1952 capture = self.pg1.get_capture(len(pkts))
1953 self.verify_capture_out(capture, nat_ip, True)
1955 def test_static_with_port_in(self):
1956 """ 1:1 NAPT initialized from inside network """
1958 self.tcp_port_out = 3606
1959 self.udp_port_out = 3607
1960 self.icmp_id_out = 3608
1962 self.nat44_add_address(self.nat_addr)
1963 self.nat44_add_static_mapping(self.pg0.remote_ip4, self.nat_addr,
1964 self.tcp_port_in, self.tcp_port_out,
1965 proto=IP_PROTOS.tcp)
1966 self.nat44_add_static_mapping(self.pg0.remote_ip4, self.nat_addr,
1967 self.udp_port_in, self.udp_port_out,
1968 proto=IP_PROTOS.udp)
1969 self.nat44_add_static_mapping(self.pg0.remote_ip4, self.nat_addr,
1970 self.icmp_id_in, self.icmp_id_out,
1971 proto=IP_PROTOS.icmp)
1972 flags = self.config_flags.NAT_IS_INSIDE
1973 self.vapi.nat44_interface_add_del_feature(
1974 sw_if_index=self.pg0.sw_if_index,
1975 flags=flags, is_add=1)
1976 self.vapi.nat44_interface_add_del_feature(
1977 sw_if_index=self.pg1.sw_if_index,
1981 pkts = self.create_stream_in(self.pg0, self.pg1)
1982 self.pg0.add_stream(pkts)
1983 self.pg_enable_capture(self.pg_interfaces)
1985 capture = self.pg1.get_capture(len(pkts))
1986 self.verify_capture_out(capture)
1989 pkts = self.create_stream_out(self.pg1)
1990 self.pg1.add_stream(pkts)
1991 self.pg_enable_capture(self.pg_interfaces)
1993 capture = self.pg0.get_capture(len(pkts))
1994 self.verify_capture_in(capture, self.pg0)
1996 def test_static_with_port_out(self):
1997 """ 1:1 NAPT initialized from outside network """
1999 self.tcp_port_out = 30606
2000 self.udp_port_out = 30607
2001 self.icmp_id_out = 30608
2003 self.nat44_add_address(self.nat_addr)
2004 self.nat44_add_static_mapping(self.pg0.remote_ip4, self.nat_addr,
2005 self.tcp_port_in, self.tcp_port_out,
2006 proto=IP_PROTOS.tcp)
2007 self.nat44_add_static_mapping(self.pg0.remote_ip4, self.nat_addr,
2008 self.udp_port_in, self.udp_port_out,
2009 proto=IP_PROTOS.udp)
2010 self.nat44_add_static_mapping(self.pg0.remote_ip4, self.nat_addr,
2011 self.icmp_id_in, self.icmp_id_out,
2012 proto=IP_PROTOS.icmp)
2013 flags = self.config_flags.NAT_IS_INSIDE
2014 self.vapi.nat44_interface_add_del_feature(
2015 sw_if_index=self.pg0.sw_if_index,
2016 flags=flags, is_add=1)
2017 self.vapi.nat44_interface_add_del_feature(
2018 sw_if_index=self.pg1.sw_if_index,
2022 pkts = self.create_stream_out(self.pg1)
2023 self.pg1.add_stream(pkts)
2024 self.pg_enable_capture(self.pg_interfaces)
2026 capture = self.pg0.get_capture(len(pkts))
2027 self.verify_capture_in(capture, self.pg0)
2030 pkts = self.create_stream_in(self.pg0, self.pg1)
2031 self.pg0.add_stream(pkts)
2032 self.pg_enable_capture(self.pg_interfaces)
2034 capture = self.pg1.get_capture(len(pkts))
2035 self.verify_capture_out(capture)
2037 def test_static_vrf_aware(self):
2038 """ 1:1 NAT VRF awareness """
2040 nat_ip1 = "10.0.0.30"
2041 nat_ip2 = "10.0.0.40"
2042 self.tcp_port_out = 6303
2043 self.udp_port_out = 6304
2044 self.icmp_id_out = 6305
2046 self.nat44_add_static_mapping(self.pg4.remote_ip4, nat_ip1,
2048 self.nat44_add_static_mapping(self.pg0.remote_ip4, nat_ip2,
2050 flags = self.config_flags.NAT_IS_INSIDE
2051 self.vapi.nat44_interface_add_del_feature(
2052 sw_if_index=self.pg3.sw_if_index,
2054 self.vapi.nat44_interface_add_del_feature(
2055 sw_if_index=self.pg0.sw_if_index,
2056 flags=flags, is_add=1)
2057 self.vapi.nat44_interface_add_del_feature(
2058 sw_if_index=self.pg4.sw_if_index,
2059 flags=flags, is_add=1)
2061 # inside interface VRF match NAT44 static mapping VRF
2062 pkts = self.create_stream_in(self.pg4, self.pg3)
2063 self.pg4.add_stream(pkts)
2064 self.pg_enable_capture(self.pg_interfaces)
2066 capture = self.pg3.get_capture(len(pkts))
2067 self.verify_capture_out(capture, nat_ip1, True)
2069 # inside interface VRF don't match NAT44 static mapping VRF (packets
2071 pkts = self.create_stream_in(self.pg0, self.pg3)
2072 self.pg0.add_stream(pkts)
2073 self.pg_enable_capture(self.pg_interfaces)
2075 self.pg3.assert_nothing_captured()
2077 def test_dynamic_to_static(self):
2078 """ Switch from dynamic translation to 1:1NAT """
2079 nat_ip = "10.0.0.10"
2080 self.tcp_port_out = 6303
2081 self.udp_port_out = 6304
2082 self.icmp_id_out = 6305
2084 self.nat44_add_address(self.nat_addr)
2085 flags = self.config_flags.NAT_IS_INSIDE
2086 self.vapi.nat44_interface_add_del_feature(
2087 sw_if_index=self.pg0.sw_if_index,
2088 flags=flags, is_add=1)
2089 self.vapi.nat44_interface_add_del_feature(
2090 sw_if_index=self.pg1.sw_if_index,
2094 pkts = self.create_stream_in(self.pg0, self.pg1)
2095 self.pg0.add_stream(pkts)
2096 self.pg_enable_capture(self.pg_interfaces)
2098 capture = self.pg1.get_capture(len(pkts))
2099 self.verify_capture_out(capture)
2102 self.nat44_add_static_mapping(self.pg0.remote_ip4, nat_ip)
2103 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4n, 0)
2104 self.assertEqual(len(sessions), 0)
2105 pkts = self.create_stream_in(self.pg0, self.pg1)
2106 self.pg0.add_stream(pkts)
2107 self.pg_enable_capture(self.pg_interfaces)
2109 capture = self.pg1.get_capture(len(pkts))
2110 self.verify_capture_out(capture, nat_ip, True)
2112 def test_identity_nat(self):
2113 """ Identity NAT """
2114 flags = self.config_flags.NAT_IS_ADDR_ONLY
2115 self.vapi.nat44_add_del_identity_mapping(
2116 ip_address=self.pg0.remote_ip4n, sw_if_index=0xFFFFFFFF,
2117 flags=flags, is_add=1)
2118 flags = self.config_flags.NAT_IS_INSIDE
2119 self.vapi.nat44_interface_add_del_feature(
2120 sw_if_index=self.pg0.sw_if_index,
2121 flags=flags, is_add=1)
2122 self.vapi.nat44_interface_add_del_feature(
2123 sw_if_index=self.pg1.sw_if_index,
2126 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
2127 IP(src=self.pg1.remote_ip4, dst=self.pg0.remote_ip4) /
2128 TCP(sport=12345, dport=56789))
2129 self.pg1.add_stream(p)
2130 self.pg_enable_capture(self.pg_interfaces)
2132 capture = self.pg0.get_capture(1)
2137 self.assertEqual(ip.dst, self.pg0.remote_ip4)
2138 self.assertEqual(ip.src, self.pg1.remote_ip4)
2139 self.assertEqual(tcp.dport, 56789)
2140 self.assertEqual(tcp.sport, 12345)
2141 self.assert_packet_checksums_valid(p)
2143 self.logger.error(ppp("Unexpected or invalid packet:", p))
2146 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4n, 0)
2147 self.assertEqual(len(sessions), 0)
2148 flags = self.config_flags.NAT_IS_ADDR_ONLY
2149 self.vapi.nat44_add_del_identity_mapping(
2150 ip_address=self.pg0.remote_ip4n, sw_if_index=0xFFFFFFFF,
2151 flags=flags, vrf_id=1, is_add=1)
2152 identity_mappings = self.vapi.nat44_identity_mapping_dump()
2153 self.assertEqual(len(identity_mappings), 2)
2155 def test_multiple_inside_interfaces(self):
2156 """ NAT44 multiple non-overlapping address space inside interfaces """
2158 self.nat44_add_address(self.nat_addr)
2159 flags = self.config_flags.NAT_IS_INSIDE
2160 self.vapi.nat44_interface_add_del_feature(
2161 sw_if_index=self.pg0.sw_if_index,
2162 flags=flags, is_add=1)
2163 self.vapi.nat44_interface_add_del_feature(
2164 sw_if_index=self.pg1.sw_if_index,
2165 flags=flags, is_add=1)
2166 self.vapi.nat44_interface_add_del_feature(
2167 sw_if_index=self.pg3.sw_if_index,
2170 # between two NAT44 inside interfaces (no translation)
2171 pkts = self.create_stream_in(self.pg0, self.pg1)
2172 self.pg0.add_stream(pkts)
2173 self.pg_enable_capture(self.pg_interfaces)
2175 capture = self.pg1.get_capture(len(pkts))
2176 self.verify_capture_no_translation(capture, self.pg0, self.pg1)
2178 # from NAT44 inside to interface without NAT44 feature (no translation)
2179 pkts = self.create_stream_in(self.pg0, self.pg2)
2180 self.pg0.add_stream(pkts)
2181 self.pg_enable_capture(self.pg_interfaces)
2183 capture = self.pg2.get_capture(len(pkts))
2184 self.verify_capture_no_translation(capture, self.pg0, self.pg2)
2186 # in2out 1st interface
2187 pkts = self.create_stream_in(self.pg0, self.pg3)
2188 self.pg0.add_stream(pkts)
2189 self.pg_enable_capture(self.pg_interfaces)
2191 capture = self.pg3.get_capture(len(pkts))
2192 self.verify_capture_out(capture)
2194 # out2in 1st interface
2195 pkts = self.create_stream_out(self.pg3)
2196 self.pg3.add_stream(pkts)
2197 self.pg_enable_capture(self.pg_interfaces)
2199 capture = self.pg0.get_capture(len(pkts))
2200 self.verify_capture_in(capture, self.pg0)
2202 # in2out 2nd interface
2203 pkts = self.create_stream_in(self.pg1, self.pg3)
2204 self.pg1.add_stream(pkts)
2205 self.pg_enable_capture(self.pg_interfaces)
2207 capture = self.pg3.get_capture(len(pkts))
2208 self.verify_capture_out(capture)
2210 # out2in 2nd interface
2211 pkts = self.create_stream_out(self.pg3)
2212 self.pg3.add_stream(pkts)
2213 self.pg_enable_capture(self.pg_interfaces)
2215 capture = self.pg1.get_capture(len(pkts))
2216 self.verify_capture_in(capture, self.pg1)
2218 def test_inside_overlapping_interfaces(self):
2219 """ NAT44 multiple inside interfaces with overlapping address space """
2221 static_nat_ip = "10.0.0.10"
2222 self.nat44_add_address(self.nat_addr)
2223 flags = self.config_flags.NAT_IS_INSIDE
2224 self.vapi.nat44_interface_add_del_feature(
2225 sw_if_index=self.pg3.sw_if_index,
2227 self.vapi.nat44_interface_add_del_feature(
2228 sw_if_index=self.pg4.sw_if_index,
2229 flags=flags, is_add=1)
2230 self.vapi.nat44_interface_add_del_feature(
2231 sw_if_index=self.pg5.sw_if_index,
2232 flags=flags, is_add=1)
2233 self.vapi.nat44_interface_add_del_feature(
2234 sw_if_index=self.pg6.sw_if_index,
2235 flags=flags, is_add=1)
2236 self.nat44_add_static_mapping(self.pg6.remote_ip4, static_nat_ip,
2239 # between NAT44 inside interfaces with same VRF (no translation)
2240 pkts = self.create_stream_in(self.pg4, self.pg5)
2241 self.pg4.add_stream(pkts)
2242 self.pg_enable_capture(self.pg_interfaces)
2244 capture = self.pg5.get_capture(len(pkts))
2245 self.verify_capture_no_translation(capture, self.pg4, self.pg5)
2247 # between NAT44 inside interfaces with different VRF (hairpinning)
2248 p = (Ether(src=self.pg4.remote_mac, dst=self.pg4.local_mac) /
2249 IP(src=self.pg4.remote_ip4, dst=static_nat_ip) /
2250 TCP(sport=1234, dport=5678))
2251 self.pg4.add_stream(p)
2252 self.pg_enable_capture(self.pg_interfaces)
2254 capture = self.pg6.get_capture(1)
2259 self.assertEqual(ip.src, self.nat_addr)
2260 self.assertEqual(ip.dst, self.pg6.remote_ip4)
2261 self.assertNotEqual(tcp.sport, 1234)
2262 self.assertEqual(tcp.dport, 5678)
2264 self.logger.error(ppp("Unexpected or invalid packet:", p))
2267 # in2out 1st interface
2268 pkts = self.create_stream_in(self.pg4, self.pg3)
2269 self.pg4.add_stream(pkts)
2270 self.pg_enable_capture(self.pg_interfaces)
2272 capture = self.pg3.get_capture(len(pkts))
2273 self.verify_capture_out(capture)
2275 # out2in 1st interface
2276 pkts = self.create_stream_out(self.pg3)
2277 self.pg3.add_stream(pkts)
2278 self.pg_enable_capture(self.pg_interfaces)
2280 capture = self.pg4.get_capture(len(pkts))
2281 self.verify_capture_in(capture, self.pg4)
2283 # in2out 2nd interface
2284 pkts = self.create_stream_in(self.pg5, self.pg3)
2285 self.pg5.add_stream(pkts)
2286 self.pg_enable_capture(self.pg_interfaces)
2288 capture = self.pg3.get_capture(len(pkts))
2289 self.verify_capture_out(capture)
2291 # out2in 2nd interface
2292 pkts = self.create_stream_out(self.pg3)
2293 self.pg3.add_stream(pkts)
2294 self.pg_enable_capture(self.pg_interfaces)
2296 capture = self.pg5.get_capture(len(pkts))
2297 self.verify_capture_in(capture, self.pg5)
2300 addresses = self.vapi.nat44_address_dump()
2301 self.assertEqual(len(addresses), 1)
2302 sessions = self.vapi.nat44_user_session_dump(self.pg5.remote_ip4n, 10)
2303 self.assertEqual(len(sessions), 3)
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.pg5.remote_ip4)
2308 self.assertEqual(session.outside_ip_address,
2309 addresses[0].ip_address)
2310 self.assertEqual(sessions[0].protocol, IP_PROTOS.tcp)
2311 self.assertEqual(sessions[1].protocol, IP_PROTOS.udp)
2312 self.assertEqual(sessions[2].protocol, IP_PROTOS.icmp)
2313 self.assertEqual(sessions[0].inside_port, self.tcp_port_in)
2314 self.assertEqual(sessions[1].inside_port, self.udp_port_in)
2315 self.assertEqual(sessions[2].inside_port, self.icmp_id_in)
2316 self.assertEqual(sessions[0].outside_port, self.tcp_port_out)
2317 self.assertEqual(sessions[1].outside_port, self.udp_port_out)
2318 self.assertEqual(sessions[2].outside_port, self.icmp_id_out)
2320 # in2out 3rd interface
2321 pkts = self.create_stream_in(self.pg6, self.pg3)
2322 self.pg6.add_stream(pkts)
2323 self.pg_enable_capture(self.pg_interfaces)
2325 capture = self.pg3.get_capture(len(pkts))
2326 self.verify_capture_out(capture, static_nat_ip, True)
2328 # out2in 3rd interface
2329 pkts = self.create_stream_out(self.pg3, static_nat_ip)
2330 self.pg3.add_stream(pkts)
2331 self.pg_enable_capture(self.pg_interfaces)
2333 capture = self.pg6.get_capture(len(pkts))
2334 self.verify_capture_in(capture, self.pg6)
2336 # general user and session dump verifications
2337 users = self.vapi.nat44_user_dump()
2338 self.assertGreaterEqual(len(users), 3)
2339 addresses = self.vapi.nat44_address_dump()
2340 self.assertEqual(len(addresses), 1)
2342 sessions = self.vapi.nat44_user_session_dump(user.ip_address,
2344 for session in sessions:
2345 self.assertEqual(user.ip_address, session.inside_ip_address)
2346 self.assertTrue(session.total_bytes > session.total_pkts > 0)
2347 self.assertTrue(session.protocol in
2348 [IP_PROTOS.tcp, IP_PROTOS.udp,
2350 self.assertFalse(session.flags &
2351 self.config_flags.NAT_IS_EXT_HOST_VALID)
2354 sessions = self.vapi.nat44_user_session_dump(self.pg4.remote_ip4n, 10)
2355 self.assertGreaterEqual(len(sessions), 4)
2356 for session in sessions:
2357 self.assertFalse(session.flags & self.config_flags.NAT_IS_STATIC)
2358 self.assertEqual(str(session.inside_ip_address),
2359 self.pg4.remote_ip4)
2360 self.assertEqual(session.outside_ip_address,
2361 addresses[0].ip_address)
2364 sessions = self.vapi.nat44_user_session_dump(self.pg6.remote_ip4n, 20)
2365 self.assertGreaterEqual(len(sessions), 3)
2366 for session in sessions:
2367 self.assertTrue(session.flags & self.config_flags.NAT_IS_STATIC)
2368 self.assertEqual(str(session.inside_ip_address),
2369 self.pg6.remote_ip4)
2370 self.assertEqual(str(session.outside_ip_address),
2372 self.assertTrue(session.inside_port in
2373 [self.tcp_port_in, self.udp_port_in,
2376 def test_hairpinning(self):
2377 """ NAT44 hairpinning - 1:1 NAPT """
2379 host = self.pg0.remote_hosts[0]
2380 server = self.pg0.remote_hosts[1]
2383 server_in_port = 5678
2384 server_out_port = 8765
2386 self.nat44_add_address(self.nat_addr)
2387 flags = self.config_flags.NAT_IS_INSIDE
2388 self.vapi.nat44_interface_add_del_feature(
2389 sw_if_index=self.pg0.sw_if_index,
2390 flags=flags, is_add=1)
2391 self.vapi.nat44_interface_add_del_feature(
2392 sw_if_index=self.pg1.sw_if_index,
2395 # add static mapping for server
2396 self.nat44_add_static_mapping(server.ip4, self.nat_addr,
2397 server_in_port, server_out_port,
2398 proto=IP_PROTOS.tcp)
2400 # send packet from host to server
2401 p = (Ether(src=host.mac, dst=self.pg0.local_mac) /
2402 IP(src=host.ip4, dst=self.nat_addr) /
2403 TCP(sport=host_in_port, dport=server_out_port))
2404 self.pg0.add_stream(p)
2405 self.pg_enable_capture(self.pg_interfaces)
2407 capture = self.pg0.get_capture(1)
2412 self.assertEqual(ip.src, self.nat_addr)
2413 self.assertEqual(ip.dst, server.ip4)
2414 self.assertNotEqual(tcp.sport, host_in_port)
2415 self.assertEqual(tcp.dport, server_in_port)
2416 self.assert_packet_checksums_valid(p)
2417 host_out_port = tcp.sport
2419 self.logger.error(ppp("Unexpected or invalid packet:", p))
2422 # send reply from server to host
2423 p = (Ether(src=server.mac, dst=self.pg0.local_mac) /
2424 IP(src=server.ip4, dst=self.nat_addr) /
2425 TCP(sport=server_in_port, dport=host_out_port))
2426 self.pg0.add_stream(p)
2427 self.pg_enable_capture(self.pg_interfaces)
2429 capture = self.pg0.get_capture(1)
2434 self.assertEqual(ip.src, self.nat_addr)
2435 self.assertEqual(ip.dst, host.ip4)
2436 self.assertEqual(tcp.sport, server_out_port)
2437 self.assertEqual(tcp.dport, host_in_port)
2438 self.assert_packet_checksums_valid(p)
2440 self.logger.error(ppp("Unexpected or invalid packet:", p))
2443 def test_hairpinning2(self):
2444 """ NAT44 hairpinning - 1:1 NAT"""
2446 server1_nat_ip = "10.0.0.10"
2447 server2_nat_ip = "10.0.0.11"
2448 host = self.pg0.remote_hosts[0]
2449 server1 = self.pg0.remote_hosts[1]
2450 server2 = self.pg0.remote_hosts[2]
2451 server_tcp_port = 22
2452 server_udp_port = 20
2454 self.nat44_add_address(self.nat_addr)
2455 flags = self.config_flags.NAT_IS_INSIDE
2456 self.vapi.nat44_interface_add_del_feature(
2457 sw_if_index=self.pg0.sw_if_index,
2458 flags=flags, is_add=1)
2459 self.vapi.nat44_interface_add_del_feature(
2460 sw_if_index=self.pg1.sw_if_index,
2463 # add static mapping for servers
2464 self.nat44_add_static_mapping(server1.ip4, server1_nat_ip)
2465 self.nat44_add_static_mapping(server2.ip4, server2_nat_ip)
2469 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2470 IP(src=host.ip4, dst=server1_nat_ip) /
2471 TCP(sport=self.tcp_port_in, dport=server_tcp_port))
2473 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2474 IP(src=host.ip4, dst=server1_nat_ip) /
2475 UDP(sport=self.udp_port_in, dport=server_udp_port))
2477 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2478 IP(src=host.ip4, dst=server1_nat_ip) /
2479 ICMP(id=self.icmp_id_in, type='echo-request'))
2481 self.pg0.add_stream(pkts)
2482 self.pg_enable_capture(self.pg_interfaces)
2484 capture = self.pg0.get_capture(len(pkts))
2485 for packet in capture:
2487 self.assertEqual(packet[IP].src, self.nat_addr)
2488 self.assertEqual(packet[IP].dst, server1.ip4)
2489 if packet.haslayer(TCP):
2490 self.assertNotEqual(packet[TCP].sport, self.tcp_port_in)
2491 self.assertEqual(packet[TCP].dport, server_tcp_port)
2492 self.tcp_port_out = packet[TCP].sport
2493 self.assert_packet_checksums_valid(packet)
2494 elif packet.haslayer(UDP):
2495 self.assertNotEqual(packet[UDP].sport, self.udp_port_in)
2496 self.assertEqual(packet[UDP].dport, server_udp_port)
2497 self.udp_port_out = packet[UDP].sport
2499 self.assertNotEqual(packet[ICMP].id, self.icmp_id_in)
2500 self.icmp_id_out = packet[ICMP].id
2502 self.logger.error(ppp("Unexpected or invalid packet:", packet))
2507 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2508 IP(src=server1.ip4, dst=self.nat_addr) /
2509 TCP(sport=server_tcp_port, dport=self.tcp_port_out))
2511 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2512 IP(src=server1.ip4, dst=self.nat_addr) /
2513 UDP(sport=server_udp_port, dport=self.udp_port_out))
2515 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2516 IP(src=server1.ip4, dst=self.nat_addr) /
2517 ICMP(id=self.icmp_id_out, type='echo-reply'))
2519 self.pg0.add_stream(pkts)
2520 self.pg_enable_capture(self.pg_interfaces)
2522 capture = self.pg0.get_capture(len(pkts))
2523 for packet in capture:
2525 self.assertEqual(packet[IP].src, server1_nat_ip)
2526 self.assertEqual(packet[IP].dst, host.ip4)
2527 if packet.haslayer(TCP):
2528 self.assertEqual(packet[TCP].dport, self.tcp_port_in)
2529 self.assertEqual(packet[TCP].sport, server_tcp_port)
2530 self.assert_packet_checksums_valid(packet)
2531 elif packet.haslayer(UDP):
2532 self.assertEqual(packet[UDP].dport, self.udp_port_in)
2533 self.assertEqual(packet[UDP].sport, server_udp_port)
2535 self.assertEqual(packet[ICMP].id, self.icmp_id_in)
2537 self.logger.error(ppp("Unexpected or invalid packet:", packet))
2540 # server2 to server1
2542 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2543 IP(src=server2.ip4, dst=server1_nat_ip) /
2544 TCP(sport=self.tcp_port_in, dport=server_tcp_port))
2546 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2547 IP(src=server2.ip4, dst=server1_nat_ip) /
2548 UDP(sport=self.udp_port_in, dport=server_udp_port))
2550 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2551 IP(src=server2.ip4, dst=server1_nat_ip) /
2552 ICMP(id=self.icmp_id_in, type='echo-request'))
2554 self.pg0.add_stream(pkts)
2555 self.pg_enable_capture(self.pg_interfaces)
2557 capture = self.pg0.get_capture(len(pkts))
2558 for packet in capture:
2560 self.assertEqual(packet[IP].src, server2_nat_ip)
2561 self.assertEqual(packet[IP].dst, server1.ip4)
2562 if packet.haslayer(TCP):
2563 self.assertEqual(packet[TCP].sport, self.tcp_port_in)
2564 self.assertEqual(packet[TCP].dport, server_tcp_port)
2565 self.tcp_port_out = packet[TCP].sport
2566 self.assert_packet_checksums_valid(packet)
2567 elif packet.haslayer(UDP):
2568 self.assertEqual(packet[UDP].sport, self.udp_port_in)
2569 self.assertEqual(packet[UDP].dport, server_udp_port)
2570 self.udp_port_out = packet[UDP].sport
2572 self.assertEqual(packet[ICMP].id, self.icmp_id_in)
2573 self.icmp_id_out = packet[ICMP].id
2575 self.logger.error(ppp("Unexpected or invalid packet:", packet))
2578 # server1 to server2
2580 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2581 IP(src=server1.ip4, dst=server2_nat_ip) /
2582 TCP(sport=server_tcp_port, dport=self.tcp_port_out))
2584 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2585 IP(src=server1.ip4, dst=server2_nat_ip) /
2586 UDP(sport=server_udp_port, dport=self.udp_port_out))
2588 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2589 IP(src=server1.ip4, dst=server2_nat_ip) /
2590 ICMP(id=self.icmp_id_out, type='echo-reply'))
2592 self.pg0.add_stream(pkts)
2593 self.pg_enable_capture(self.pg_interfaces)
2595 capture = self.pg0.get_capture(len(pkts))
2596 for packet in capture:
2598 self.assertEqual(packet[IP].src, server1_nat_ip)
2599 self.assertEqual(packet[IP].dst, server2.ip4)
2600 if packet.haslayer(TCP):
2601 self.assertEqual(packet[TCP].dport, self.tcp_port_in)
2602 self.assertEqual(packet[TCP].sport, server_tcp_port)
2603 self.assert_packet_checksums_valid(packet)
2604 elif packet.haslayer(UDP):
2605 self.assertEqual(packet[UDP].dport, self.udp_port_in)
2606 self.assertEqual(packet[UDP].sport, server_udp_port)
2608 self.assertEqual(packet[ICMP].id, self.icmp_id_in)
2610 self.logger.error(ppp("Unexpected or invalid packet:", packet))
2613 def test_max_translations_per_user(self):
2614 """ MAX translations per user - recycle the least recently used """
2616 self.nat44_add_address(self.nat_addr)
2617 flags = self.config_flags.NAT_IS_INSIDE
2618 self.vapi.nat44_interface_add_del_feature(
2619 sw_if_index=self.pg0.sw_if_index,
2620 flags=flags, is_add=1)
2621 self.vapi.nat44_interface_add_del_feature(
2622 sw_if_index=self.pg1.sw_if_index,
2625 # get maximum number of translations per user
2626 nat44_config = self.vapi.nat_show_config()
2628 # send more than maximum number of translations per user packets
2629 pkts_num = nat44_config.max_translations_per_user + 5
2631 for port in range(0, pkts_num):
2632 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2633 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
2634 TCP(sport=1025 + port))
2636 self.pg0.add_stream(pkts)
2637 self.pg_enable_capture(self.pg_interfaces)
2640 # verify number of translated packet
2641 self.pg1.get_capture(pkts_num)
2643 users = self.vapi.nat44_user_dump()
2645 if user.ip_address == self.pg0.remote_ip4n:
2646 self.assertEqual(user.nsessions,
2647 nat44_config.max_translations_per_user)
2648 self.assertEqual(user.nstaticsessions, 0)
2651 self.nat44_add_static_mapping(self.pg0.remote_ip4, self.nat_addr,
2653 proto=IP_PROTOS.tcp)
2654 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2655 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
2656 TCP(sport=tcp_port))
2657 self.pg0.add_stream(p)
2658 self.pg_enable_capture(self.pg_interfaces)
2660 self.pg1.get_capture(1)
2661 users = self.vapi.nat44_user_dump()
2663 if user.ip_address == self.pg0.remote_ip4n:
2664 self.assertEqual(user.nsessions,
2665 nat44_config.max_translations_per_user - 1)
2666 self.assertEqual(user.nstaticsessions, 1)
2668 def test_interface_addr(self):
2669 """ Acquire NAT44 addresses from interface """
2670 self.vapi.nat44_add_del_interface_addr(
2672 sw_if_index=self.pg7.sw_if_index)
2674 # no address in NAT pool
2675 addresses = self.vapi.nat44_address_dump()
2676 self.assertEqual(0, len(addresses))
2678 # configure interface address and check NAT address pool
2679 self.pg7.config_ip4()
2680 addresses = self.vapi.nat44_address_dump()
2681 self.assertEqual(1, len(addresses))
2682 self.assertEqual(str(addresses[0].ip_address), self.pg7.local_ip4)
2684 # remove interface address and check NAT address pool
2685 self.pg7.unconfig_ip4()
2686 addresses = self.vapi.nat44_address_dump()
2687 self.assertEqual(0, len(addresses))
2689 def test_interface_addr_static_mapping(self):
2690 """ Static mapping with addresses from interface """
2693 self.vapi.nat44_add_del_interface_addr(
2695 sw_if_index=self.pg7.sw_if_index)
2696 self.nat44_add_static_mapping(
2698 external_sw_if_index=self.pg7.sw_if_index,
2701 # static mappings with external interface
2702 static_mappings = self.vapi.nat44_static_mapping_dump()
2703 self.assertEqual(1, len(static_mappings))
2704 self.assertEqual(self.pg7.sw_if_index,
2705 static_mappings[0].external_sw_if_index)
2706 self.assertEqual((static_mappings[0].tag).split(b'\0', 1)[0], tag)
2708 # configure interface address and check static mappings
2709 self.pg7.config_ip4()
2710 static_mappings = self.vapi.nat44_static_mapping_dump()
2711 self.assertEqual(2, len(static_mappings))
2713 for sm in static_mappings:
2714 if sm.external_sw_if_index == 0xFFFFFFFF:
2715 self.assertEqual(str(sm.external_ip_address),
2717 self.assertEqual((sm.tag).split(b'\0', 1)[0], tag)
2719 self.assertTrue(resolved)
2721 # remove interface address and check static mappings
2722 self.pg7.unconfig_ip4()
2723 static_mappings = self.vapi.nat44_static_mapping_dump()
2724 self.assertEqual(1, len(static_mappings))
2725 self.assertEqual(self.pg7.sw_if_index,
2726 static_mappings[0].external_sw_if_index)
2727 self.assertEqual((static_mappings[0].tag).split(b'\0', 1)[0], tag)
2729 # configure interface address again and check static mappings
2730 self.pg7.config_ip4()
2731 static_mappings = self.vapi.nat44_static_mapping_dump()
2732 self.assertEqual(2, len(static_mappings))
2734 for sm in static_mappings:
2735 if sm.external_sw_if_index == 0xFFFFFFFF:
2736 self.assertEqual(str(sm.external_ip_address),
2738 self.assertEqual((sm.tag).split(b'\0', 1)[0], tag)
2740 self.assertTrue(resolved)
2742 # remove static mapping
2743 self.nat44_add_static_mapping(
2745 external_sw_if_index=self.pg7.sw_if_index,
2748 static_mappings = self.vapi.nat44_static_mapping_dump()
2749 self.assertEqual(0, len(static_mappings))
2751 def test_interface_addr_identity_nat(self):
2752 """ Identity NAT with addresses from interface """
2755 self.vapi.nat44_add_del_interface_addr(
2757 sw_if_index=self.pg7.sw_if_index)
2758 self.vapi.nat44_add_del_identity_mapping(
2760 sw_if_index=self.pg7.sw_if_index,
2762 protocol=IP_PROTOS.tcp,
2765 # identity mappings with external interface
2766 identity_mappings = self.vapi.nat44_identity_mapping_dump()
2767 self.assertEqual(1, len(identity_mappings))
2768 self.assertEqual(self.pg7.sw_if_index,
2769 identity_mappings[0].sw_if_index)
2771 # configure interface address and check identity mappings
2772 self.pg7.config_ip4()
2773 identity_mappings = self.vapi.nat44_identity_mapping_dump()
2775 self.assertEqual(2, len(identity_mappings))
2776 for sm in identity_mappings:
2777 if sm.sw_if_index == 0xFFFFFFFF:
2778 self.assertEqual(str(identity_mappings[0].ip_address),
2780 self.assertEqual(port, identity_mappings[0].port)
2781 self.assertEqual(IP_PROTOS.tcp, identity_mappings[0].protocol)
2783 self.assertTrue(resolved)
2785 # remove interface address and check identity mappings
2786 self.pg7.unconfig_ip4()
2787 identity_mappings = self.vapi.nat44_identity_mapping_dump()
2788 self.assertEqual(1, len(identity_mappings))
2789 self.assertEqual(self.pg7.sw_if_index,
2790 identity_mappings[0].sw_if_index)
2792 def test_ipfix_nat44_sess(self):
2793 """ IPFIX logging NAT44 session created/deleted """
2794 self.ipfix_domain_id = 10
2795 self.ipfix_src_port = 20202
2796 collector_port = 30303
2797 bind_layers(UDP, IPFIX, dport=30303)
2798 self.nat44_add_address(self.nat_addr)
2799 flags = self.config_flags.NAT_IS_INSIDE
2800 self.vapi.nat44_interface_add_del_feature(
2801 sw_if_index=self.pg0.sw_if_index,
2802 flags=flags, is_add=1)
2803 self.vapi.nat44_interface_add_del_feature(
2804 sw_if_index=self.pg1.sw_if_index,
2806 self.vapi.set_ipfix_exporter(collector_address=self.pg3.remote_ip4n,
2807 src_address=self.pg3.local_ip4n,
2809 template_interval=10,
2810 collector_port=collector_port)
2811 self.vapi.nat_ipfix_enable_disable(domain_id=self.ipfix_domain_id,
2812 src_port=self.ipfix_src_port,
2815 pkts = self.create_stream_in(self.pg0, self.pg1)
2816 self.pg0.add_stream(pkts)
2817 self.pg_enable_capture(self.pg_interfaces)
2819 capture = self.pg1.get_capture(len(pkts))
2820 self.verify_capture_out(capture)
2821 self.nat44_add_address(self.nat_addr, is_add=0)
2822 self.vapi.ipfix_flush()
2823 capture = self.pg3.get_capture(9)
2824 ipfix = IPFIXDecoder()
2825 # first load template
2827 self.assertTrue(p.haslayer(IPFIX))
2828 self.assertEqual(p[IP].src, self.pg3.local_ip4)
2829 self.assertEqual(p[IP].dst, self.pg3.remote_ip4)
2830 self.assertEqual(p[UDP].sport, self.ipfix_src_port)
2831 self.assertEqual(p[UDP].dport, collector_port)
2832 self.assertEqual(p[IPFIX].observationDomainID,
2833 self.ipfix_domain_id)
2834 if p.haslayer(Template):
2835 ipfix.add_template(p.getlayer(Template))
2836 # verify events in data set
2838 if p.haslayer(Data):
2839 data = ipfix.decode_data_set(p.getlayer(Set))
2840 self.verify_ipfix_nat44_ses(data)
2842 def test_ipfix_addr_exhausted(self):
2843 """ IPFIX logging NAT addresses exhausted """
2844 flags = self.config_flags.NAT_IS_INSIDE
2845 self.vapi.nat44_interface_add_del_feature(
2846 sw_if_index=self.pg0.sw_if_index,
2847 flags=flags, is_add=1)
2848 self.vapi.nat44_interface_add_del_feature(
2849 sw_if_index=self.pg1.sw_if_index,
2851 self.vapi.set_ipfix_exporter(collector_address=self.pg3.remote_ip4n,
2852 src_address=self.pg3.local_ip4n,
2854 template_interval=10)
2855 self.vapi.nat_ipfix_enable_disable(domain_id=self.ipfix_domain_id,
2856 src_port=self.ipfix_src_port,
2859 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
2860 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
2862 self.pg0.add_stream(p)
2863 self.pg_enable_capture(self.pg_interfaces)
2865 self.pg1.assert_nothing_captured()
2867 self.vapi.ipfix_flush()
2868 capture = self.pg3.get_capture(9)
2869 ipfix = IPFIXDecoder()
2870 # first load template
2872 self.assertTrue(p.haslayer(IPFIX))
2873 self.assertEqual(p[IP].src, self.pg3.local_ip4)
2874 self.assertEqual(p[IP].dst, self.pg3.remote_ip4)
2875 self.assertEqual(p[UDP].sport, self.ipfix_src_port)
2876 self.assertEqual(p[UDP].dport, 4739)
2877 self.assertEqual(p[IPFIX].observationDomainID,
2878 self.ipfix_domain_id)
2879 if p.haslayer(Template):
2880 ipfix.add_template(p.getlayer(Template))
2881 # verify events in data set
2883 if p.haslayer(Data):
2884 data = ipfix.decode_data_set(p.getlayer(Set))
2885 self.verify_ipfix_addr_exhausted(data)
2887 @unittest.skipUnless(running_extended_tests, "part of extended tests")
2888 def test_ipfix_max_sessions(self):
2889 """ IPFIX logging maximum session entries exceeded """
2890 self.nat44_add_address(self.nat_addr)
2891 flags = self.config_flags.NAT_IS_INSIDE
2892 self.vapi.nat44_interface_add_del_feature(
2893 sw_if_index=self.pg0.sw_if_index,
2894 flags=flags, is_add=1)
2895 self.vapi.nat44_interface_add_del_feature(
2896 sw_if_index=self.pg1.sw_if_index,
2899 nat44_config = self.vapi.nat_show_config()
2900 max_sessions = 10 * nat44_config.translation_buckets
2903 for i in range(0, max_sessions):
2904 src = "10.10.%u.%u" % ((i & 0xFF00) >> 8, i & 0xFF)
2905 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2906 IP(src=src, dst=self.pg1.remote_ip4) /
2909 self.pg0.add_stream(pkts)
2910 self.pg_enable_capture(self.pg_interfaces)
2913 self.pg1.get_capture(max_sessions)
2914 self.vapi.set_ipfix_exporter(collector_address=self.pg3.remote_ip4n,
2915 src_address=self.pg3.local_ip4n,
2917 template_interval=10)
2918 self.vapi.nat_ipfix_enable_disable(domain_id=self.ipfix_domain_id,
2919 src_port=self.ipfix_src_port,
2922 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2923 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
2925 self.pg0.add_stream(p)
2926 self.pg_enable_capture(self.pg_interfaces)
2928 self.pg1.assert_nothing_captured()
2930 self.vapi.ipfix_flush()
2931 capture = self.pg3.get_capture(9)
2932 ipfix = IPFIXDecoder()
2933 # first load template
2935 self.assertTrue(p.haslayer(IPFIX))
2936 self.assertEqual(p[IP].src, self.pg3.local_ip4)
2937 self.assertEqual(p[IP].dst, self.pg3.remote_ip4)
2938 self.assertEqual(p[UDP].sport, self.ipfix_src_port)
2939 self.assertEqual(p[UDP].dport, 4739)
2940 self.assertEqual(p[IPFIX].observationDomainID,
2941 self.ipfix_domain_id)
2942 if p.haslayer(Template):
2943 ipfix.add_template(p.getlayer(Template))
2944 # verify events in data set
2946 if p.haslayer(Data):
2947 data = ipfix.decode_data_set(p.getlayer(Set))
2948 self.verify_ipfix_max_sessions(data, max_sessions)
2950 def test_syslog_apmap(self):
2951 """ Test syslog address and port mapping creation and deletion """
2952 self.vapi.syslog_set_filter(
2953 self.SYSLOG_SEVERITY.SYSLOG_API_SEVERITY_INFO)
2954 self.vapi.syslog_set_sender(self.pg3.local_ip4n, self.pg3.remote_ip4n)
2955 self.nat44_add_address(self.nat_addr)
2956 flags = self.config_flags.NAT_IS_INSIDE
2957 self.vapi.nat44_interface_add_del_feature(
2958 sw_if_index=self.pg0.sw_if_index,
2959 flags=flags, is_add=1)
2960 self.vapi.nat44_interface_add_del_feature(
2961 sw_if_index=self.pg1.sw_if_index,
2964 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2965 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
2966 TCP(sport=self.tcp_port_in, dport=20))
2967 self.pg0.add_stream(p)
2968 self.pg_enable_capture(self.pg_interfaces)
2970 capture = self.pg1.get_capture(1)
2971 self.tcp_port_out = capture[0][TCP].sport
2972 capture = self.pg3.get_capture(1)
2973 self.verify_syslog_apmap(capture[0][Raw].load)
2975 self.pg_enable_capture(self.pg_interfaces)
2977 self.nat44_add_address(self.nat_addr, is_add=0)
2978 capture = self.pg3.get_capture(1)
2979 self.verify_syslog_apmap(capture[0][Raw].load, False)
2981 def test_pool_addr_fib(self):
2982 """ NAT44 add pool addresses to FIB """
2983 static_addr = '10.0.0.10'
2984 self.nat44_add_address(self.nat_addr)
2985 flags = self.config_flags.NAT_IS_INSIDE
2986 self.vapi.nat44_interface_add_del_feature(
2987 sw_if_index=self.pg0.sw_if_index,
2988 flags=flags, is_add=1)
2989 self.vapi.nat44_interface_add_del_feature(
2990 sw_if_index=self.pg1.sw_if_index,
2992 self.nat44_add_static_mapping(self.pg0.remote_ip4, static_addr)
2995 p = (Ether(src=self.pg1.remote_mac, dst='ff:ff:ff:ff:ff:ff') /
2996 ARP(op=ARP.who_has, pdst=self.nat_addr,
2997 psrc=self.pg1.remote_ip4, hwsrc=self.pg1.remote_mac))
2998 self.pg1.add_stream(p)
2999 self.pg_enable_capture(self.pg_interfaces)
3001 capture = self.pg1.get_capture(1)
3002 self.assertTrue(capture[0].haslayer(ARP))
3003 self.assertTrue(capture[0][ARP].op, ARP.is_at)
3006 p = (Ether(src=self.pg1.remote_mac, dst='ff:ff:ff:ff:ff:ff') /
3007 ARP(op=ARP.who_has, pdst=static_addr,
3008 psrc=self.pg1.remote_ip4, hwsrc=self.pg1.remote_mac))
3009 self.pg1.add_stream(p)
3010 self.pg_enable_capture(self.pg_interfaces)
3012 capture = self.pg1.get_capture(1)
3013 self.assertTrue(capture[0].haslayer(ARP))
3014 self.assertTrue(capture[0][ARP].op, ARP.is_at)
3016 # send ARP to non-NAT44 interface
3017 p = (Ether(src=self.pg2.remote_mac, dst='ff:ff:ff:ff:ff:ff') /
3018 ARP(op=ARP.who_has, pdst=self.nat_addr,
3019 psrc=self.pg2.remote_ip4, hwsrc=self.pg2.remote_mac))
3020 self.pg2.add_stream(p)
3021 self.pg_enable_capture(self.pg_interfaces)
3023 self.pg1.assert_nothing_captured()
3025 # remove addresses and verify
3026 self.nat44_add_address(self.nat_addr, is_add=0)
3027 self.nat44_add_static_mapping(self.pg0.remote_ip4, static_addr,
3030 p = (Ether(src=self.pg1.remote_mac, dst='ff:ff:ff:ff:ff:ff') /
3031 ARP(op=ARP.who_has, pdst=self.nat_addr,
3032 psrc=self.pg1.remote_ip4, hwsrc=self.pg1.remote_mac))
3033 self.pg1.add_stream(p)
3034 self.pg_enable_capture(self.pg_interfaces)
3036 self.pg1.assert_nothing_captured()
3038 p = (Ether(src=self.pg1.remote_mac, dst='ff:ff:ff:ff:ff:ff') /
3039 ARP(op=ARP.who_has, pdst=static_addr,
3040 psrc=self.pg1.remote_ip4, hwsrc=self.pg1.remote_mac))
3041 self.pg1.add_stream(p)
3042 self.pg_enable_capture(self.pg_interfaces)
3044 self.pg1.assert_nothing_captured()
3046 def test_vrf_mode(self):
3047 """ NAT44 tenant VRF aware address pool mode """
3051 nat_ip1 = "10.0.0.10"
3052 nat_ip2 = "10.0.0.11"
3054 self.pg0.unconfig_ip4()
3055 self.pg1.unconfig_ip4()
3056 self.vapi.ip_table_add_del(is_add=1, table_id=vrf_id1)
3057 self.vapi.ip_table_add_del(is_add=1, table_id=vrf_id2)
3058 self.pg0.set_table_ip4(vrf_id1)
3059 self.pg1.set_table_ip4(vrf_id2)
3060 self.pg0.config_ip4()
3061 self.pg1.config_ip4()
3062 self.pg0.resolve_arp()
3063 self.pg1.resolve_arp()
3065 self.nat44_add_address(nat_ip1, vrf_id=vrf_id1)
3066 self.nat44_add_address(nat_ip2, vrf_id=vrf_id2)
3067 flags = self.config_flags.NAT_IS_INSIDE
3068 self.vapi.nat44_interface_add_del_feature(
3069 sw_if_index=self.pg0.sw_if_index,
3070 flags=flags, is_add=1)
3071 self.vapi.nat44_interface_add_del_feature(
3072 sw_if_index=self.pg1.sw_if_index,
3073 flags=flags, is_add=1)
3074 self.vapi.nat44_interface_add_del_feature(
3075 sw_if_index=self.pg2.sw_if_index,
3080 pkts = self.create_stream_in(self.pg0, self.pg2)
3081 self.pg0.add_stream(pkts)
3082 self.pg_enable_capture(self.pg_interfaces)
3084 capture = self.pg2.get_capture(len(pkts))
3085 self.verify_capture_out(capture, nat_ip1)
3088 pkts = self.create_stream_in(self.pg1, self.pg2)
3089 self.pg1.add_stream(pkts)
3090 self.pg_enable_capture(self.pg_interfaces)
3092 capture = self.pg2.get_capture(len(pkts))
3093 self.verify_capture_out(capture, nat_ip2)
3096 self.pg0.unconfig_ip4()
3097 self.pg1.unconfig_ip4()
3098 self.pg0.set_table_ip4(0)
3099 self.pg1.set_table_ip4(0)
3100 self.pg0.config_ip4()
3101 self.pg1.config_ip4()
3102 self.pg0.resolve_arp()
3103 self.pg1.resolve_arp()
3104 self.vapi.ip_table_add_del(is_add=0, table_id=vrf_id1)
3105 self.vapi.ip_table_add_del(is_add=0, table_id=vrf_id2)
3107 def test_vrf_feature_independent(self):
3108 """ NAT44 tenant VRF independent address pool mode """
3110 nat_ip1 = "10.0.0.10"
3111 nat_ip2 = "10.0.0.11"
3113 self.nat44_add_address(nat_ip1)
3114 self.nat44_add_address(nat_ip2, vrf_id=99)
3115 flags = self.config_flags.NAT_IS_INSIDE
3116 self.vapi.nat44_interface_add_del_feature(
3117 sw_if_index=self.pg0.sw_if_index,
3118 flags=flags, is_add=1)
3119 self.vapi.nat44_interface_add_del_feature(
3120 sw_if_index=self.pg1.sw_if_index,
3121 flags=flags, is_add=1)
3122 self.vapi.nat44_interface_add_del_feature(
3123 sw_if_index=self.pg2.sw_if_index,
3127 pkts = self.create_stream_in(self.pg0, self.pg2)
3128 self.pg0.add_stream(pkts)
3129 self.pg_enable_capture(self.pg_interfaces)
3131 capture = self.pg2.get_capture(len(pkts))
3132 self.verify_capture_out(capture, nat_ip1)
3135 pkts = self.create_stream_in(self.pg1, self.pg2)
3136 self.pg1.add_stream(pkts)
3137 self.pg_enable_capture(self.pg_interfaces)
3139 capture = self.pg2.get_capture(len(pkts))
3140 self.verify_capture_out(capture, nat_ip1)
3142 def create_routes_and_neigbors(self):
3143 r1 = VppIpRoute(self, self.pg7.remote_ip4, 32,
3144 [VppRoutePath(self.pg7.remote_ip4,
3145 self.pg7.sw_if_index)])
3146 r2 = VppIpRoute(self, self.pg8.remote_ip4, 32,
3147 [VppRoutePath(self.pg8.remote_ip4,
3148 self.pg8.sw_if_index)])
3152 n1 = VppNeighbor(self,
3153 self.pg7.sw_if_index,
3154 self.pg7.remote_mac,
3155 self.pg7.remote_ip4,
3157 n2 = VppNeighbor(self,
3158 self.pg8.sw_if_index,
3159 self.pg8.remote_mac,
3160 self.pg8.remote_ip4,
3165 def test_dynamic_ipless_interfaces(self):
3166 """ NAT44 interfaces without configured IP address """
3167 self.create_routes_and_neigbors()
3168 self.nat44_add_address(self.nat_addr)
3169 flags = self.config_flags.NAT_IS_INSIDE
3170 self.vapi.nat44_interface_add_del_feature(
3171 sw_if_index=self.pg7.sw_if_index,
3172 flags=flags, is_add=1)
3173 self.vapi.nat44_interface_add_del_feature(
3174 sw_if_index=self.pg8.sw_if_index,
3178 pkts = self.create_stream_in(self.pg7, self.pg8)
3179 self.pg7.add_stream(pkts)
3180 self.pg_enable_capture(self.pg_interfaces)
3182 capture = self.pg8.get_capture(len(pkts))
3183 self.verify_capture_out(capture)
3186 pkts = self.create_stream_out(self.pg8, self.nat_addr)
3187 self.pg8.add_stream(pkts)
3188 self.pg_enable_capture(self.pg_interfaces)
3190 capture = self.pg7.get_capture(len(pkts))
3191 self.verify_capture_in(capture, self.pg7)
3193 def test_static_ipless_interfaces(self):
3194 """ NAT44 interfaces without configured IP address - 1:1 NAT """
3196 self.create_routes_and_neigbors()
3197 self.nat44_add_static_mapping(self.pg7.remote_ip4, self.nat_addr)
3198 flags = self.config_flags.NAT_IS_INSIDE
3199 self.vapi.nat44_interface_add_del_feature(
3200 sw_if_index=self.pg7.sw_if_index,
3201 flags=flags, is_add=1)
3202 self.vapi.nat44_interface_add_del_feature(
3203 sw_if_index=self.pg8.sw_if_index,
3207 pkts = self.create_stream_out(self.pg8)
3208 self.pg8.add_stream(pkts)
3209 self.pg_enable_capture(self.pg_interfaces)
3211 capture = self.pg7.get_capture(len(pkts))
3212 self.verify_capture_in(capture, self.pg7)
3215 pkts = self.create_stream_in(self.pg7, self.pg8)
3216 self.pg7.add_stream(pkts)
3217 self.pg_enable_capture(self.pg_interfaces)
3219 capture = self.pg8.get_capture(len(pkts))
3220 self.verify_capture_out(capture, self.nat_addr, True)
3222 def test_static_with_port_ipless_interfaces(self):
3223 """ NAT44 interfaces without configured IP address - 1:1 NAPT """
3225 self.tcp_port_out = 30606
3226 self.udp_port_out = 30607
3227 self.icmp_id_out = 30608
3229 self.create_routes_and_neigbors()
3230 self.nat44_add_address(self.nat_addr)
3231 self.nat44_add_static_mapping(self.pg7.remote_ip4, self.nat_addr,
3232 self.tcp_port_in, self.tcp_port_out,
3233 proto=IP_PROTOS.tcp)
3234 self.nat44_add_static_mapping(self.pg7.remote_ip4, self.nat_addr,
3235 self.udp_port_in, self.udp_port_out,
3236 proto=IP_PROTOS.udp)
3237 self.nat44_add_static_mapping(self.pg7.remote_ip4, self.nat_addr,
3238 self.icmp_id_in, self.icmp_id_out,
3239 proto=IP_PROTOS.icmp)
3240 flags = self.config_flags.NAT_IS_INSIDE
3241 self.vapi.nat44_interface_add_del_feature(
3242 sw_if_index=self.pg7.sw_if_index,
3243 flags=flags, is_add=1)
3244 self.vapi.nat44_interface_add_del_feature(
3245 sw_if_index=self.pg8.sw_if_index,
3249 pkts = self.create_stream_out(self.pg8)
3250 self.pg8.add_stream(pkts)
3251 self.pg_enable_capture(self.pg_interfaces)
3253 capture = self.pg7.get_capture(len(pkts))
3254 self.verify_capture_in(capture, self.pg7)
3257 pkts = self.create_stream_in(self.pg7, self.pg8)
3258 self.pg7.add_stream(pkts)
3259 self.pg_enable_capture(self.pg_interfaces)
3261 capture = self.pg8.get_capture(len(pkts))
3262 self.verify_capture_out(capture)
3264 def test_static_unknown_proto(self):
3265 """ 1:1 NAT translate packet with unknown protocol """
3266 nat_ip = "10.0.0.10"
3267 self.nat44_add_static_mapping(self.pg0.remote_ip4, nat_ip)
3268 flags = self.config_flags.NAT_IS_INSIDE
3269 self.vapi.nat44_interface_add_del_feature(
3270 sw_if_index=self.pg0.sw_if_index,
3271 flags=flags, is_add=1)
3272 self.vapi.nat44_interface_add_del_feature(
3273 sw_if_index=self.pg1.sw_if_index,
3277 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
3278 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
3280 IP(src=self.pg2.remote_ip4, dst=self.pg3.remote_ip4) /
3281 TCP(sport=1234, dport=1234))
3282 self.pg0.add_stream(p)
3283 self.pg_enable_capture(self.pg_interfaces)
3285 p = self.pg1.get_capture(1)
3288 self.assertEqual(packet[IP].src, nat_ip)
3289 self.assertEqual(packet[IP].dst, self.pg1.remote_ip4)
3290 self.assertEqual(packet.haslayer(GRE), 1)
3291 self.assert_packet_checksums_valid(packet)
3293 self.logger.error(ppp("Unexpected or invalid packet:", packet))
3297 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
3298 IP(src=self.pg1.remote_ip4, dst=nat_ip) /
3300 IP(src=self.pg3.remote_ip4, dst=self.pg2.remote_ip4) /
3301 TCP(sport=1234, dport=1234))
3302 self.pg1.add_stream(p)
3303 self.pg_enable_capture(self.pg_interfaces)
3305 p = self.pg0.get_capture(1)
3308 self.assertEqual(packet[IP].src, self.pg1.remote_ip4)
3309 self.assertEqual(packet[IP].dst, self.pg0.remote_ip4)
3310 self.assertEqual(packet.haslayer(GRE), 1)
3311 self.assert_packet_checksums_valid(packet)
3313 self.logger.error(ppp("Unexpected or invalid packet:", packet))
3316 def test_hairpinning_static_unknown_proto(self):
3317 """ 1:1 NAT translate packet with unknown protocol - hairpinning """
3319 host = self.pg0.remote_hosts[0]
3320 server = self.pg0.remote_hosts[1]
3322 host_nat_ip = "10.0.0.10"
3323 server_nat_ip = "10.0.0.11"
3325 self.nat44_add_static_mapping(host.ip4, host_nat_ip)
3326 self.nat44_add_static_mapping(server.ip4, server_nat_ip)
3327 flags = self.config_flags.NAT_IS_INSIDE
3328 self.vapi.nat44_interface_add_del_feature(
3329 sw_if_index=self.pg0.sw_if_index,
3330 flags=flags, is_add=1)
3331 self.vapi.nat44_interface_add_del_feature(
3332 sw_if_index=self.pg1.sw_if_index,
3336 p = (Ether(dst=self.pg0.local_mac, src=host.mac) /
3337 IP(src=host.ip4, dst=server_nat_ip) /
3339 IP(src=self.pg2.remote_ip4, dst=self.pg3.remote_ip4) /
3340 TCP(sport=1234, dport=1234))
3341 self.pg0.add_stream(p)
3342 self.pg_enable_capture(self.pg_interfaces)
3344 p = self.pg0.get_capture(1)
3347 self.assertEqual(packet[IP].src, host_nat_ip)
3348 self.assertEqual(packet[IP].dst, server.ip4)
3349 self.assertEqual(packet.haslayer(GRE), 1)
3350 self.assert_packet_checksums_valid(packet)
3352 self.logger.error(ppp("Unexpected or invalid packet:", packet))
3356 p = (Ether(dst=self.pg0.local_mac, src=server.mac) /
3357 IP(src=server.ip4, dst=host_nat_ip) /
3359 IP(src=self.pg3.remote_ip4, dst=self.pg2.remote_ip4) /
3360 TCP(sport=1234, dport=1234))
3361 self.pg0.add_stream(p)
3362 self.pg_enable_capture(self.pg_interfaces)
3364 p = self.pg0.get_capture(1)
3367 self.assertEqual(packet[IP].src, server_nat_ip)
3368 self.assertEqual(packet[IP].dst, host.ip4)
3369 self.assertEqual(packet.haslayer(GRE), 1)
3370 self.assert_packet_checksums_valid(packet)
3372 self.logger.error(ppp("Unexpected or invalid packet:", packet))
3375 def test_output_feature(self):
3376 """ NAT44 interface output feature (in2out postrouting) """
3377 self.nat44_add_address(self.nat_addr)
3378 flags = self.config_flags.NAT_IS_INSIDE
3379 self.vapi.nat44_interface_add_del_output_feature(
3380 is_add=1, flags=flags,
3381 sw_if_index=self.pg0.sw_if_index)
3382 self.vapi.nat44_interface_add_del_output_feature(
3383 is_add=1, flags=flags,
3384 sw_if_index=self.pg1.sw_if_index)
3385 self.vapi.nat44_interface_add_del_output_feature(
3387 sw_if_index=self.pg3.sw_if_index)
3390 pkts = self.create_stream_in(self.pg0, self.pg3)
3391 self.pg0.add_stream(pkts)
3392 self.pg_enable_capture(self.pg_interfaces)
3394 capture = self.pg3.get_capture(len(pkts))
3395 self.verify_capture_out(capture)
3398 pkts = self.create_stream_out(self.pg3)
3399 self.pg3.add_stream(pkts)
3400 self.pg_enable_capture(self.pg_interfaces)
3402 capture = self.pg0.get_capture(len(pkts))
3403 self.verify_capture_in(capture, self.pg0)
3405 # from non-NAT interface to NAT inside interface
3406 pkts = self.create_stream_in(self.pg2, self.pg0)
3407 self.pg2.add_stream(pkts)
3408 self.pg_enable_capture(self.pg_interfaces)
3410 capture = self.pg0.get_capture(len(pkts))
3411 self.verify_capture_no_translation(capture, self.pg2, self.pg0)
3413 def test_output_feature_vrf_aware(self):
3414 """ NAT44 interface output feature VRF aware (in2out postrouting) """
3415 nat_ip_vrf10 = "10.0.0.10"
3416 nat_ip_vrf20 = "10.0.0.20"
3418 r1 = VppIpRoute(self, self.pg3.remote_ip4, 32,
3419 [VppRoutePath(self.pg3.remote_ip4,
3420 self.pg3.sw_if_index)],
3422 r2 = VppIpRoute(self, self.pg3.remote_ip4, 32,
3423 [VppRoutePath(self.pg3.remote_ip4,
3424 self.pg3.sw_if_index)],
3429 self.nat44_add_address(nat_ip_vrf10, vrf_id=10)
3430 self.nat44_add_address(nat_ip_vrf20, vrf_id=20)
3431 flags = self.config_flags.NAT_IS_INSIDE
3432 self.vapi.nat44_interface_add_del_output_feature(
3433 is_add=1, flags=flags,
3434 sw_if_index=self.pg4.sw_if_index)
3435 self.vapi.nat44_interface_add_del_output_feature(
3436 is_add=1, flags=flags,
3437 sw_if_index=self.pg6.sw_if_index)
3438 self.vapi.nat44_interface_add_del_output_feature(
3440 sw_if_index=self.pg3.sw_if_index)
3443 pkts = self.create_stream_in(self.pg4, self.pg3)
3444 self.pg4.add_stream(pkts)
3445 self.pg_enable_capture(self.pg_interfaces)
3447 capture = self.pg3.get_capture(len(pkts))
3448 self.verify_capture_out(capture, nat_ip=nat_ip_vrf10)
3451 pkts = self.create_stream_out(self.pg3, dst_ip=nat_ip_vrf10)
3452 self.pg3.add_stream(pkts)
3453 self.pg_enable_capture(self.pg_interfaces)
3455 capture = self.pg4.get_capture(len(pkts))
3456 self.verify_capture_in(capture, self.pg4)
3459 pkts = self.create_stream_in(self.pg6, self.pg3)
3460 self.pg6.add_stream(pkts)
3461 self.pg_enable_capture(self.pg_interfaces)
3463 capture = self.pg3.get_capture(len(pkts))
3464 self.verify_capture_out(capture, nat_ip=nat_ip_vrf20)
3467 pkts = self.create_stream_out(self.pg3, dst_ip=nat_ip_vrf20)
3468 self.pg3.add_stream(pkts)
3469 self.pg_enable_capture(self.pg_interfaces)
3471 capture = self.pg6.get_capture(len(pkts))
3472 self.verify_capture_in(capture, self.pg6)
3474 def test_output_feature_hairpinning(self):
3475 """ NAT44 interface output feature hairpinning (in2out postrouting) """
3476 host = self.pg0.remote_hosts[0]
3477 server = self.pg0.remote_hosts[1]
3480 server_in_port = 5678
3481 server_out_port = 8765
3483 self.nat44_add_address(self.nat_addr)
3484 flags = self.config_flags.NAT_IS_INSIDE
3485 self.vapi.nat44_interface_add_del_output_feature(
3486 is_add=1, flags=flags,
3487 sw_if_index=self.pg0.sw_if_index)
3488 self.vapi.nat44_interface_add_del_output_feature(
3490 sw_if_index=self.pg1.sw_if_index)
3492 # add static mapping for server
3493 self.nat44_add_static_mapping(server.ip4, self.nat_addr,
3494 server_in_port, server_out_port,
3495 proto=IP_PROTOS.tcp)
3497 # send packet from host to server
3498 p = (Ether(src=host.mac, dst=self.pg0.local_mac) /
3499 IP(src=host.ip4, dst=self.nat_addr) /
3500 TCP(sport=host_in_port, dport=server_out_port))
3501 self.pg0.add_stream(p)
3502 self.pg_enable_capture(self.pg_interfaces)
3504 capture = self.pg0.get_capture(1)
3509 self.assertEqual(ip.src, self.nat_addr)
3510 self.assertEqual(ip.dst, server.ip4)
3511 self.assertNotEqual(tcp.sport, host_in_port)
3512 self.assertEqual(tcp.dport, server_in_port)
3513 self.assert_packet_checksums_valid(p)
3514 host_out_port = tcp.sport
3516 self.logger.error(ppp("Unexpected or invalid packet:", p))
3519 # send reply from server to host
3520 p = (Ether(src=server.mac, dst=self.pg0.local_mac) /
3521 IP(src=server.ip4, dst=self.nat_addr) /
3522 TCP(sport=server_in_port, dport=host_out_port))
3523 self.pg0.add_stream(p)
3524 self.pg_enable_capture(self.pg_interfaces)
3526 capture = self.pg0.get_capture(1)
3531 self.assertEqual(ip.src, self.nat_addr)
3532 self.assertEqual(ip.dst, host.ip4)
3533 self.assertEqual(tcp.sport, server_out_port)
3534 self.assertEqual(tcp.dport, host_in_port)
3535 self.assert_packet_checksums_valid(p)
3537 self.logger.error(ppp("Unexpected or invalid packet:", p))
3540 def test_one_armed_nat44(self):
3541 """ One armed NAT44 """
3542 remote_host = self.pg9.remote_hosts[0]
3543 local_host = self.pg9.remote_hosts[1]
3546 self.nat44_add_address(self.nat_addr)
3547 flags = self.config_flags.NAT_IS_INSIDE
3548 self.vapi.nat44_interface_add_del_feature(
3549 sw_if_index=self.pg9.sw_if_index,
3551 self.vapi.nat44_interface_add_del_feature(
3552 sw_if_index=self.pg9.sw_if_index,
3553 flags=flags, is_add=1)
3556 p = (Ether(src=self.pg9.remote_mac, dst=self.pg9.local_mac) /
3557 IP(src=local_host.ip4, dst=remote_host.ip4) /
3558 TCP(sport=12345, dport=80))
3559 self.pg9.add_stream(p)
3560 self.pg_enable_capture(self.pg_interfaces)
3562 capture = self.pg9.get_capture(1)
3567 self.assertEqual(ip.src, self.nat_addr)
3568 self.assertEqual(ip.dst, remote_host.ip4)
3569 self.assertNotEqual(tcp.sport, 12345)
3570 external_port = tcp.sport
3571 self.assertEqual(tcp.dport, 80)
3572 self.assert_packet_checksums_valid(p)
3574 self.logger.error(ppp("Unexpected or invalid packet:", p))
3578 p = (Ether(src=self.pg9.remote_mac, dst=self.pg9.local_mac) /
3579 IP(src=remote_host.ip4, dst=self.nat_addr) /
3580 TCP(sport=80, dport=external_port))
3581 self.pg9.add_stream(p)
3582 self.pg_enable_capture(self.pg_interfaces)
3584 capture = self.pg9.get_capture(1)
3589 self.assertEqual(ip.src, remote_host.ip4)
3590 self.assertEqual(ip.dst, local_host.ip4)
3591 self.assertEqual(tcp.sport, 80)
3592 self.assertEqual(tcp.dport, 12345)
3593 self.assert_packet_checksums_valid(p)
3595 self.logger.error(ppp("Unexpected or invalid packet:", p))
3598 err = self.statistics.get_err_counter(
3599 '/err/nat44-classify/next in2out')
3600 self.assertEqual(err, 1)
3601 err = self.statistics.get_err_counter(
3602 '/err/nat44-classify/next out2in')
3603 self.assertEqual(err, 1)
3605 def test_del_session(self):
3606 """ Delete NAT44 session """
3607 self.nat44_add_address(self.nat_addr)
3608 flags = self.config_flags.NAT_IS_INSIDE
3609 self.vapi.nat44_interface_add_del_feature(
3610 sw_if_index=self.pg0.sw_if_index,
3611 flags=flags, is_add=1)
3612 self.vapi.nat44_interface_add_del_feature(
3613 sw_if_index=self.pg1.sw_if_index,
3616 pkts = self.create_stream_in(self.pg0, self.pg1)
3617 self.pg0.add_stream(pkts)
3618 self.pg_enable_capture(self.pg_interfaces)
3620 self.pg1.get_capture(len(pkts))
3622 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4n, 0)
3623 nsessions = len(sessions)
3625 self.vapi.nat44_del_session(address=sessions[0].inside_ip_address,
3626 port=sessions[0].inside_port,
3627 protocol=sessions[0].protocol,
3628 flags=self.config_flags.NAT_IS_INSIDE)
3629 self.vapi.nat44_del_session(address=sessions[1].outside_ip_address,
3630 port=sessions[1].outside_port,
3631 protocol=sessions[1].protocol)
3633 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4n, 0)
3634 self.assertEqual(nsessions - len(sessions), 2)
3636 self.vapi.nat44_del_session(address=sessions[0].inside_ip_address,
3637 port=sessions[0].inside_port,
3638 protocol=sessions[0].protocol,
3639 flags=self.config_flags.NAT_IS_INSIDE)
3641 self.verify_no_nat44_user()
3643 def test_set_get_reass(self):
3644 """ NAT44 set/get virtual fragmentation reassembly """
3645 reas_cfg1 = self.vapi.nat_get_reass()
3647 self.vapi.nat_set_reass(timeout=reas_cfg1.ip4_timeout + 5,
3648 max_reass=reas_cfg1.ip4_max_reass * 2,
3649 max_frag=reas_cfg1.ip4_max_frag * 2,
3652 reas_cfg2 = self.vapi.nat_get_reass()
3654 self.assertEqual(reas_cfg1.ip4_timeout + 5, reas_cfg2.ip4_timeout)
3655 self.assertEqual(reas_cfg1.ip4_max_reass * 2, reas_cfg2.ip4_max_reass)
3656 self.assertEqual(reas_cfg1.ip4_max_frag * 2, reas_cfg2.ip4_max_frag)
3658 self.vapi.nat_set_reass(timeout=2, max_reass=1024, max_frag=5,
3660 self.assertTrue(self.vapi.nat_get_reass().ip4_drop_frag)
3662 def test_frag_in_order(self):
3663 """ NAT44 translate fragments arriving in order """
3665 self.nat44_add_address(self.nat_addr)
3666 flags = self.config_flags.NAT_IS_INSIDE
3667 self.vapi.nat44_interface_add_del_feature(
3668 sw_if_index=self.pg0.sw_if_index,
3669 flags=flags, is_add=1)
3670 self.vapi.nat44_interface_add_del_feature(
3671 sw_if_index=self.pg1.sw_if_index,
3674 reas_cfg1 = self.vapi.nat_get_reass()
3675 # this test was intermittently failing in some cases
3676 # until we temporarily bump the reassembly timeouts
3677 self.vapi.nat_set_reass(timeout=20, max_reass=1024, max_frag=5,
3680 self.frag_in_order(proto=IP_PROTOS.tcp)
3681 self.frag_in_order(proto=IP_PROTOS.udp)
3682 self.frag_in_order(proto=IP_PROTOS.icmp)
3684 # restore the reassembly timeouts
3685 self.vapi.nat_set_reass(timeout=reas_cfg1.ip4_timeout,
3686 max_reass=reas_cfg1.ip4_max_reass,
3687 max_frag=reas_cfg1.ip4_max_frag,
3688 drop_frag=reas_cfg1.ip4_drop_frag)
3690 def test_frag_forwarding(self):
3691 """ NAT44 forwarding fragment test """
3692 self.vapi.nat44_add_del_interface_addr(
3694 sw_if_index=self.pg1.sw_if_index)
3695 flags = self.config_flags.NAT_IS_INSIDE
3696 self.vapi.nat44_interface_add_del_feature(
3697 sw_if_index=self.pg0.sw_if_index,
3698 flags=flags, is_add=1)
3699 self.vapi.nat44_interface_add_del_feature(
3700 sw_if_index=self.pg1.sw_if_index,
3702 self.vapi.nat44_forwarding_enable_disable(enable=1)
3704 data = b"A" * 16 + b"B" * 16 + b"C" * 3
3705 pkts = self.create_stream_frag(self.pg1,
3706 self.pg0.remote_ip4,
3710 proto=IP_PROTOS.udp)
3711 self.pg1.add_stream(pkts)
3712 self.pg_enable_capture(self.pg_interfaces)
3714 frags = self.pg0.get_capture(len(pkts))
3715 p = self.reass_frags_and_verify(frags,
3716 self.pg1.remote_ip4,
3717 self.pg0.remote_ip4)
3718 self.assertEqual(p[UDP].sport, 4789)
3719 self.assertEqual(p[UDP].dport, 4789)
3720 self.assertEqual(data, p[Raw].load)
3722 def test_reass_hairpinning(self):
3723 """ NAT44 fragments hairpinning """
3725 self.server = self.pg0.remote_hosts[1]
3726 self.host_in_port = random.randint(1025, 65535)
3727 self.server_in_port = random.randint(1025, 65535)
3728 self.server_out_port = random.randint(1025, 65535)
3730 self.nat44_add_address(self.nat_addr)
3731 flags = self.config_flags.NAT_IS_INSIDE
3732 self.vapi.nat44_interface_add_del_feature(
3733 sw_if_index=self.pg0.sw_if_index,
3734 flags=flags, is_add=1)
3735 self.vapi.nat44_interface_add_del_feature(
3736 sw_if_index=self.pg1.sw_if_index,
3738 # add static mapping for server
3739 self.nat44_add_static_mapping(self.server.ip4, self.nat_addr,
3740 self.server_in_port,
3741 self.server_out_port,
3742 proto=IP_PROTOS.tcp)
3743 self.nat44_add_static_mapping(self.server.ip4, self.nat_addr,
3744 self.server_in_port,
3745 self.server_out_port,
3746 proto=IP_PROTOS.udp)
3747 self.nat44_add_static_mapping(self.server.ip4, self.nat_addr)
3749 self.reass_hairpinning(proto=IP_PROTOS.tcp)
3750 self.reass_hairpinning(proto=IP_PROTOS.udp)
3751 self.reass_hairpinning(proto=IP_PROTOS.icmp)
3753 def test_frag_out_of_order(self):
3754 """ NAT44 translate fragments arriving out of order """
3756 self.nat44_add_address(self.nat_addr)
3757 flags = self.config_flags.NAT_IS_INSIDE
3758 self.vapi.nat44_interface_add_del_feature(
3759 sw_if_index=self.pg0.sw_if_index,
3760 flags=flags, is_add=1)
3761 self.vapi.nat44_interface_add_del_feature(
3762 sw_if_index=self.pg1.sw_if_index,
3765 self.frag_out_of_order(proto=IP_PROTOS.tcp)
3766 self.frag_out_of_order(proto=IP_PROTOS.udp)
3767 self.frag_out_of_order(proto=IP_PROTOS.icmp)
3769 def test_port_restricted(self):
3770 """ Port restricted NAT44 (MAP-E CE) """
3771 self.nat44_add_address(self.nat_addr)
3772 flags = self.config_flags.NAT_IS_INSIDE
3773 self.vapi.nat44_interface_add_del_feature(
3774 sw_if_index=self.pg0.sw_if_index,
3775 flags=flags, is_add=1)
3776 self.vapi.nat44_interface_add_del_feature(
3777 sw_if_index=self.pg1.sw_if_index,
3779 self.vapi.nat_set_addr_and_port_alloc_alg(alg=1,
3784 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
3785 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
3786 TCP(sport=4567, dport=22))
3787 self.pg0.add_stream(p)
3788 self.pg_enable_capture(self.pg_interfaces)
3790 capture = self.pg1.get_capture(1)
3795 self.assertEqual(ip.dst, self.pg1.remote_ip4)
3796 self.assertEqual(ip.src, self.nat_addr)
3797 self.assertEqual(tcp.dport, 22)
3798 self.assertNotEqual(tcp.sport, 4567)
3799 self.assertEqual((tcp.sport >> 6) & 63, 10)
3800 self.assert_packet_checksums_valid(p)
3802 self.logger.error(ppp("Unexpected or invalid packet:", p))
3805 def test_port_range(self):
3806 """ External address port range """
3807 self.nat44_add_address(self.nat_addr)
3808 flags = self.config_flags.NAT_IS_INSIDE
3809 self.vapi.nat44_interface_add_del_feature(
3810 sw_if_index=self.pg0.sw_if_index,
3811 flags=flags, is_add=1)
3812 self.vapi.nat44_interface_add_del_feature(
3813 sw_if_index=self.pg1.sw_if_index,
3815 self.vapi.nat_set_addr_and_port_alloc_alg(alg=2,
3820 for port in range(0, 5):
3821 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
3822 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
3823 TCP(sport=1125 + port))
3825 self.pg0.add_stream(pkts)
3826 self.pg_enable_capture(self.pg_interfaces)
3828 capture = self.pg1.get_capture(3)
3831 self.assertGreaterEqual(tcp.sport, 1025)
3832 self.assertLessEqual(tcp.sport, 1027)
3834 def test_ipfix_max_frags(self):
3835 """ IPFIX logging maximum fragments pending reassembly exceeded """
3836 self.nat44_add_address(self.nat_addr)
3837 flags = self.config_flags.NAT_IS_INSIDE
3838 self.vapi.nat44_interface_add_del_feature(
3839 sw_if_index=self.pg0.sw_if_index,
3840 flags=flags, is_add=1)
3841 self.vapi.nat44_interface_add_del_feature(
3842 sw_if_index=self.pg1.sw_if_index,
3844 self.vapi.nat_set_reass(timeout=2, max_reass=1024, max_frag=1,
3846 self.vapi.set_ipfix_exporter(collector_address=self.pg3.remote_ip4n,
3847 src_address=self.pg3.local_ip4n,
3849 template_interval=10)
3850 self.vapi.nat_ipfix_enable_disable(domain_id=self.ipfix_domain_id,
3851 src_port=self.ipfix_src_port,
3854 data = b"A" * 4 + b"B" * 16 + b"C" * 3
3855 self.tcp_port_in = random.randint(1025, 65535)
3856 pkts = self.create_stream_frag(self.pg0,
3857 self.pg1.remote_ip4,
3862 self.pg0.add_stream(pkts)
3863 self.pg_enable_capture(self.pg_interfaces)
3865 self.pg1.assert_nothing_captured()
3867 self.vapi.ipfix_flush()
3868 capture = self.pg3.get_capture(9)
3869 ipfix = IPFIXDecoder()
3870 # first load template
3872 self.assertTrue(p.haslayer(IPFIX))
3873 self.assertEqual(p[IP].src, self.pg3.local_ip4)
3874 self.assertEqual(p[IP].dst, self.pg3.remote_ip4)
3875 self.assertEqual(p[UDP].sport, self.ipfix_src_port)
3876 self.assertEqual(p[UDP].dport, 4739)
3877 self.assertEqual(p[IPFIX].observationDomainID,
3878 self.ipfix_domain_id)
3879 if p.haslayer(Template):
3880 ipfix.add_template(p.getlayer(Template))
3881 # verify events in data set
3883 if p.haslayer(Data):
3884 data = ipfix.decode_data_set(p.getlayer(Set))
3885 self.verify_ipfix_max_fragments_ip4(data, 1,
3886 self.pg0.remote_ip4n)
3888 def test_multiple_outside_vrf(self):
3889 """ Multiple outside VRF """
3893 self.pg1.unconfig_ip4()
3894 self.pg2.unconfig_ip4()
3895 self.vapi.ip_table_add_del(is_add=1, table_id=vrf_id1)
3896 self.vapi.ip_table_add_del(is_add=1, table_id=vrf_id2)
3897 self.pg1.set_table_ip4(vrf_id1)
3898 self.pg2.set_table_ip4(vrf_id2)
3899 self.pg1.config_ip4()
3900 self.pg2.config_ip4()
3901 self.pg1.resolve_arp()
3902 self.pg2.resolve_arp()
3904 self.nat44_add_address(self.nat_addr)
3905 flags = self.config_flags.NAT_IS_INSIDE
3906 self.vapi.nat44_interface_add_del_feature(
3907 sw_if_index=self.pg0.sw_if_index,
3908 flags=flags, is_add=1)
3909 self.vapi.nat44_interface_add_del_feature(
3910 sw_if_index=self.pg1.sw_if_index,
3912 self.vapi.nat44_interface_add_del_feature(
3913 sw_if_index=self.pg2.sw_if_index,
3918 pkts = self.create_stream_in(self.pg0, self.pg1)
3919 self.pg0.add_stream(pkts)
3920 self.pg_enable_capture(self.pg_interfaces)
3922 capture = self.pg1.get_capture(len(pkts))
3923 self.verify_capture_out(capture, self.nat_addr)
3925 pkts = self.create_stream_out(self.pg1, self.nat_addr)
3926 self.pg1.add_stream(pkts)
3927 self.pg_enable_capture(self.pg_interfaces)
3929 capture = self.pg0.get_capture(len(pkts))
3930 self.verify_capture_in(capture, self.pg0)
3932 self.tcp_port_in = 60303
3933 self.udp_port_in = 60304
3934 self.icmp_id_in = 60305
3937 pkts = self.create_stream_in(self.pg0, self.pg2)
3938 self.pg0.add_stream(pkts)
3939 self.pg_enable_capture(self.pg_interfaces)
3941 capture = self.pg2.get_capture(len(pkts))
3942 self.verify_capture_out(capture, self.nat_addr)
3944 pkts = self.create_stream_out(self.pg2, self.nat_addr)
3945 self.pg2.add_stream(pkts)
3946 self.pg_enable_capture(self.pg_interfaces)
3948 capture = self.pg0.get_capture(len(pkts))
3949 self.verify_capture_in(capture, self.pg0)
3952 self.nat44_add_address(self.nat_addr, is_add=0)
3953 self.pg1.unconfig_ip4()
3954 self.pg2.unconfig_ip4()
3955 self.pg1.set_table_ip4(0)
3956 self.pg2.set_table_ip4(0)
3957 self.pg1.config_ip4()
3958 self.pg2.config_ip4()
3959 self.pg1.resolve_arp()
3960 self.pg2.resolve_arp()
3962 @unittest.skipUnless(running_extended_tests, "part of extended tests")
3963 def test_session_timeout(self):
3964 """ NAT44 session timeouts """
3965 self.nat44_add_address(self.nat_addr)
3966 flags = self.config_flags.NAT_IS_INSIDE
3967 self.vapi.nat44_interface_add_del_feature(
3968 sw_if_index=self.pg0.sw_if_index,
3969 flags=flags, is_add=1)
3970 self.vapi.nat44_interface_add_del_feature(
3971 sw_if_index=self.pg1.sw_if_index,
3973 self.vapi.nat_set_timeouts(udp=5, tcp_established=7440,
3974 tcp_transitory=240, icmp=60)
3978 for i in range(0, max_sessions):
3979 src = "10.10.%u.%u" % ((i & 0xFF00) >> 8, i & 0xFF)
3980 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
3981 IP(src=src, dst=self.pg1.remote_ip4) /
3982 UDP(sport=1025, dport=53))
3984 self.pg0.add_stream(pkts)
3985 self.pg_enable_capture(self.pg_interfaces)
3987 self.pg1.get_capture(max_sessions)
3992 for i in range(0, max_sessions):
3993 src = "10.10.%u.%u" % ((i & 0xFF00) >> 8, i & 0xFF)
3994 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
3995 IP(src=src, dst=self.pg1.remote_ip4) /
3996 UDP(sport=1026, dport=53))
3998 self.pg0.add_stream(pkts)
3999 self.pg_enable_capture(self.pg_interfaces)
4001 self.pg1.get_capture(max_sessions)
4004 users = self.vapi.nat44_user_dump()
4006 nsessions = nsessions + user.nsessions
4007 self.assertLess(nsessions, 2 * max_sessions)
4009 def test_mss_clamping(self):
4010 """ TCP MSS clamping """
4011 self.nat44_add_address(self.nat_addr)
4012 flags = self.config_flags.NAT_IS_INSIDE
4013 self.vapi.nat44_interface_add_del_feature(
4014 sw_if_index=self.pg0.sw_if_index,
4015 flags=flags, is_add=1)
4016 self.vapi.nat44_interface_add_del_feature(
4017 sw_if_index=self.pg1.sw_if_index,
4020 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
4021 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
4022 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
4023 flags="S", options=[('MSS', 1400)]))
4025 self.vapi.nat_set_mss_clamping(enable=1, mss_value=1000)
4026 self.pg0.add_stream(p)
4027 self.pg_enable_capture(self.pg_interfaces)
4029 capture = self.pg1.get_capture(1)
4030 # Negotiated MSS value greater than configured - changed
4031 self.verify_mss_value(capture[0], 1000)
4033 self.vapi.nat_set_mss_clamping(enable=0, mss_value=1500)
4034 self.pg0.add_stream(p)
4035 self.pg_enable_capture(self.pg_interfaces)
4037 capture = self.pg1.get_capture(1)
4038 # MSS clamping disabled - negotiated MSS unchanged
4039 self.verify_mss_value(capture[0], 1400)
4041 self.vapi.nat_set_mss_clamping(enable=1, mss_value=1500)
4042 self.pg0.add_stream(p)
4043 self.pg_enable_capture(self.pg_interfaces)
4045 capture = self.pg1.get_capture(1)
4046 # Negotiated MSS value smaller than configured - unchanged
4047 self.verify_mss_value(capture[0], 1400)
4049 @unittest.skipUnless(running_extended_tests, "part of extended tests")
4050 def test_ha_send(self):
4051 """ Send HA session synchronization events (active) """
4052 self.nat44_add_address(self.nat_addr)
4053 flags = self.config_flags.NAT_IS_INSIDE
4054 self.vapi.nat44_interface_add_del_feature(
4055 sw_if_index=self.pg0.sw_if_index,
4056 flags=flags, is_add=1)
4057 self.vapi.nat44_interface_add_del_feature(
4058 sw_if_index=self.pg1.sw_if_index,
4060 self.vapi.nat_ha_set_listener(ip_address=self.pg3.local_ip4,
4063 self.vapi.nat_ha_set_failover(ip_address=self.pg3.remote_ip4,
4064 port=12346, session_refresh_interval=10)
4065 bind_layers(UDP, HANATStateSync, sport=12345)
4068 pkts = self.create_stream_in(self.pg0, self.pg1)
4069 self.pg0.add_stream(pkts)
4070 self.pg_enable_capture(self.pg_interfaces)
4072 capture = self.pg1.get_capture(len(pkts))
4073 self.verify_capture_out(capture)
4074 # active send HA events
4075 self.vapi.nat_ha_flush()
4076 stats = self.statistics.get_counter('/nat44/ha/add-event-send')
4077 self.assertEqual(stats[0][0], 3)
4078 capture = self.pg3.get_capture(1)
4080 self.assert_packet_checksums_valid(p)
4084 hanat = p[HANATStateSync]
4086 self.logger.error(ppp("Invalid packet:", p))
4089 self.assertEqual(ip.src, self.pg3.local_ip4)
4090 self.assertEqual(ip.dst, self.pg3.remote_ip4)
4091 self.assertEqual(udp.sport, 12345)
4092 self.assertEqual(udp.dport, 12346)
4093 self.assertEqual(hanat.version, 1)
4094 self.assertEqual(hanat.thread_index, 0)
4095 self.assertEqual(hanat.count, 3)
4096 seq = hanat.sequence_number
4097 for event in hanat.events:
4098 self.assertEqual(event.event_type, 1)
4099 self.assertEqual(event.in_addr, self.pg0.remote_ip4)
4100 self.assertEqual(event.out_addr, self.nat_addr)
4101 self.assertEqual(event.fib_index, 0)
4103 # ACK received events
4104 ack = (Ether(dst=self.pg3.local_mac, src=self.pg3.remote_mac) /
4105 IP(src=self.pg3.remote_ip4, dst=self.pg3.local_ip4) /
4106 UDP(sport=12346, dport=12345) /
4107 HANATStateSync(sequence_number=seq, flags='ACK'))
4108 self.pg3.add_stream(ack)
4110 stats = self.statistics.get_counter('/nat44/ha/ack-recv')
4111 self.assertEqual(stats[0][0], 1)
4113 # delete one session
4114 self.pg_enable_capture(self.pg_interfaces)
4115 self.vapi.nat44_del_session(address=self.pg0.remote_ip4n,
4116 port=self.tcp_port_in,
4117 protocol=IP_PROTOS.tcp,
4118 flags=self.config_flags.NAT_IS_INSIDE)
4119 self.vapi.nat_ha_flush()
4120 stats = self.statistics.get_counter('/nat44/ha/del-event-send')
4121 self.assertEqual(stats[0][0], 1)
4122 capture = self.pg3.get_capture(1)
4125 hanat = p[HANATStateSync]
4127 self.logger.error(ppp("Invalid packet:", p))
4130 self.assertGreater(hanat.sequence_number, seq)
4132 # do not send ACK, active retry send HA event again
4133 self.pg_enable_capture(self.pg_interfaces)
4135 stats = self.statistics.get_counter('/nat44/ha/retry-count')
4136 self.assertEqual(stats[0][0], 3)
4137 stats = self.statistics.get_counter('/nat44/ha/missed-count')
4138 self.assertEqual(stats[0][0], 1)
4139 capture = self.pg3.get_capture(3)
4140 for packet in capture:
4141 self.assertEqual(packet, p)
4143 # session counters refresh
4144 pkts = self.create_stream_out(self.pg1)
4145 self.pg1.add_stream(pkts)
4146 self.pg_enable_capture(self.pg_interfaces)
4148 self.pg0.get_capture(2)
4149 self.vapi.nat_ha_flush()
4150 stats = self.statistics.get_counter('/nat44/ha/refresh-event-send')
4151 self.assertEqual(stats[0][0], 2)
4152 capture = self.pg3.get_capture(1)
4154 self.assert_packet_checksums_valid(p)
4158 hanat = p[HANATStateSync]
4160 self.logger.error(ppp("Invalid packet:", p))
4163 self.assertEqual(ip.src, self.pg3.local_ip4)
4164 self.assertEqual(ip.dst, self.pg3.remote_ip4)
4165 self.assertEqual(udp.sport, 12345)
4166 self.assertEqual(udp.dport, 12346)
4167 self.assertEqual(hanat.version, 1)
4168 self.assertEqual(hanat.count, 2)
4169 seq = hanat.sequence_number
4170 for event in hanat.events:
4171 self.assertEqual(event.event_type, 3)
4172 self.assertEqual(event.out_addr, self.nat_addr)
4173 self.assertEqual(event.fib_index, 0)
4174 self.assertEqual(event.total_pkts, 2)
4175 self.assertGreater(event.total_bytes, 0)
4177 ack = (Ether(dst=self.pg3.local_mac, src=self.pg3.remote_mac) /
4178 IP(src=self.pg3.remote_ip4, dst=self.pg3.local_ip4) /
4179 UDP(sport=12346, dport=12345) /
4180 HANATStateSync(sequence_number=seq, flags='ACK'))
4181 self.pg3.add_stream(ack)
4183 stats = self.statistics.get_counter('/nat44/ha/ack-recv')
4184 self.assertEqual(stats[0][0], 2)
4186 def test_ha_recv(self):
4187 """ Receive HA session synchronization events (passive) """
4188 self.nat44_add_address(self.nat_addr)
4189 flags = self.config_flags.NAT_IS_INSIDE
4190 self.vapi.nat44_interface_add_del_feature(
4191 sw_if_index=self.pg0.sw_if_index,
4192 flags=flags, is_add=1)
4193 self.vapi.nat44_interface_add_del_feature(
4194 sw_if_index=self.pg1.sw_if_index,
4196 self.vapi.nat_ha_set_listener(ip_address=self.pg3.local_ip4,
4199 bind_layers(UDP, HANATStateSync, sport=12345)
4201 self.tcp_port_out = random.randint(1025, 65535)
4202 self.udp_port_out = random.randint(1025, 65535)
4204 # send HA session add events to failover/passive
4205 p = (Ether(dst=self.pg3.local_mac, src=self.pg3.remote_mac) /
4206 IP(src=self.pg3.remote_ip4, dst=self.pg3.local_ip4) /
4207 UDP(sport=12346, dport=12345) /
4208 HANATStateSync(sequence_number=1, events=[
4209 Event(event_type='add', protocol='tcp',
4210 in_addr=self.pg0.remote_ip4, out_addr=self.nat_addr,
4211 in_port=self.tcp_port_in, out_port=self.tcp_port_out,
4212 eh_addr=self.pg1.remote_ip4,
4213 ehn_addr=self.pg1.remote_ip4,
4214 eh_port=self.tcp_external_port,
4215 ehn_port=self.tcp_external_port, fib_index=0),
4216 Event(event_type='add', protocol='udp',
4217 in_addr=self.pg0.remote_ip4, out_addr=self.nat_addr,
4218 in_port=self.udp_port_in, out_port=self.udp_port_out,
4219 eh_addr=self.pg1.remote_ip4,
4220 ehn_addr=self.pg1.remote_ip4,
4221 eh_port=self.udp_external_port,
4222 ehn_port=self.udp_external_port, fib_index=0)]))
4224 self.pg3.add_stream(p)
4225 self.pg_enable_capture(self.pg_interfaces)
4228 capture = self.pg3.get_capture(1)
4231 hanat = p[HANATStateSync]
4233 self.logger.error(ppp("Invalid packet:", p))
4236 self.assertEqual(hanat.sequence_number, 1)
4237 self.assertEqual(hanat.flags, 'ACK')
4238 self.assertEqual(hanat.version, 1)
4239 self.assertEqual(hanat.thread_index, 0)
4240 stats = self.statistics.get_counter('/nat44/ha/ack-send')
4241 self.assertEqual(stats[0][0], 1)
4242 stats = self.statistics.get_counter('/nat44/ha/add-event-recv')
4243 self.assertEqual(stats[0][0], 2)
4244 users = self.statistics.get_counter('/nat44/total-users')
4245 self.assertEqual(users[0][0], 1)
4246 sessions = self.statistics.get_counter('/nat44/total-sessions')
4247 self.assertEqual(sessions[0][0], 2)
4248 users = self.vapi.nat44_user_dump()
4249 self.assertEqual(len(users), 1)
4250 self.assertEqual(str(users[0].ip_address),
4251 self.pg0.remote_ip4)
4252 # there should be 2 sessions created by HA
4253 sessions = self.vapi.nat44_user_session_dump(users[0].ip_address,
4255 self.assertEqual(len(sessions), 2)
4256 for session in sessions:
4257 self.assertEqual(str(session.inside_ip_address),
4258 self.pg0.remote_ip4)
4259 self.assertEqual(str(session.outside_ip_address),
4261 self.assertIn(session.inside_port,
4262 [self.tcp_port_in, self.udp_port_in])
4263 self.assertIn(session.outside_port,
4264 [self.tcp_port_out, self.udp_port_out])
4265 self.assertIn(session.protocol, [IP_PROTOS.tcp, IP_PROTOS.udp])
4267 # send HA session delete event to failover/passive
4268 p = (Ether(dst=self.pg3.local_mac, src=self.pg3.remote_mac) /
4269 IP(src=self.pg3.remote_ip4, dst=self.pg3.local_ip4) /
4270 UDP(sport=12346, dport=12345) /
4271 HANATStateSync(sequence_number=2, events=[
4272 Event(event_type='del', protocol='udp',
4273 in_addr=self.pg0.remote_ip4, out_addr=self.nat_addr,
4274 in_port=self.udp_port_in, out_port=self.udp_port_out,
4275 eh_addr=self.pg1.remote_ip4,
4276 ehn_addr=self.pg1.remote_ip4,
4277 eh_port=self.udp_external_port,
4278 ehn_port=self.udp_external_port, fib_index=0)]))
4280 self.pg3.add_stream(p)
4281 self.pg_enable_capture(self.pg_interfaces)
4284 capture = self.pg3.get_capture(1)
4287 hanat = p[HANATStateSync]
4289 self.logger.error(ppp("Invalid packet:", p))
4292 self.assertEqual(hanat.sequence_number, 2)
4293 self.assertEqual(hanat.flags, 'ACK')
4294 self.assertEqual(hanat.version, 1)
4295 users = self.vapi.nat44_user_dump()
4296 self.assertEqual(len(users), 1)
4297 self.assertEqual(str(users[0].ip_address),
4298 self.pg0.remote_ip4)
4299 # now we should have only 1 session, 1 deleted by HA
4300 sessions = self.vapi.nat44_user_session_dump(users[0].ip_address,
4302 self.assertEqual(len(sessions), 1)
4303 stats = self.statistics.get_counter('/nat44/ha/del-event-recv')
4304 self.assertEqual(stats[0][0], 1)
4306 stats = self.statistics.get_err_counter('/err/nat-ha/pkts-processed')
4307 self.assertEqual(stats, 2)
4309 # send HA session refresh event to failover/passive
4310 p = (Ether(dst=self.pg3.local_mac, src=self.pg3.remote_mac) /
4311 IP(src=self.pg3.remote_ip4, dst=self.pg3.local_ip4) /
4312 UDP(sport=12346, dport=12345) /
4313 HANATStateSync(sequence_number=3, events=[
4314 Event(event_type='refresh', protocol='tcp',
4315 in_addr=self.pg0.remote_ip4, out_addr=self.nat_addr,
4316 in_port=self.tcp_port_in, out_port=self.tcp_port_out,
4317 eh_addr=self.pg1.remote_ip4,
4318 ehn_addr=self.pg1.remote_ip4,
4319 eh_port=self.tcp_external_port,
4320 ehn_port=self.tcp_external_port, fib_index=0,
4321 total_bytes=1024, total_pkts=2)]))
4322 self.pg3.add_stream(p)
4323 self.pg_enable_capture(self.pg_interfaces)
4326 capture = self.pg3.get_capture(1)
4329 hanat = p[HANATStateSync]
4331 self.logger.error(ppp("Invalid packet:", p))
4334 self.assertEqual(hanat.sequence_number, 3)
4335 self.assertEqual(hanat.flags, 'ACK')
4336 self.assertEqual(hanat.version, 1)
4337 users = self.vapi.nat44_user_dump()
4338 self.assertEqual(len(users), 1)
4339 self.assertEqual(str(users[0].ip_address),
4340 self.pg0.remote_ip4)
4341 sessions = self.vapi.nat44_user_session_dump(users[0].ip_address,
4343 self.assertEqual(len(sessions), 1)
4344 session = sessions[0]
4345 self.assertEqual(session.total_bytes, 1024)
4346 self.assertEqual(session.total_pkts, 2)
4347 stats = self.statistics.get_counter('/nat44/ha/refresh-event-recv')
4348 self.assertEqual(stats[0][0], 1)
4350 stats = self.statistics.get_err_counter('/err/nat-ha/pkts-processed')
4351 self.assertEqual(stats, 3)
4353 # send packet to test session created by HA
4354 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
4355 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
4356 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out))
4357 self.pg1.add_stream(p)
4358 self.pg_enable_capture(self.pg_interfaces)
4360 capture = self.pg0.get_capture(1)
4366 self.logger.error(ppp("Invalid packet:", p))
4369 self.assertEqual(ip.src, self.pg1.remote_ip4)
4370 self.assertEqual(ip.dst, self.pg0.remote_ip4)
4371 self.assertEqual(tcp.sport, self.tcp_external_port)
4372 self.assertEqual(tcp.dport, self.tcp_port_in)
4375 super(TestNAT44, self).tearDown()
4377 self.vapi.cli("clear logging")
4379 def show_commands_at_teardown(self):
4380 self.logger.info(self.vapi.cli("show nat44 addresses"))
4381 self.logger.info(self.vapi.cli("show nat44 interfaces"))
4382 self.logger.info(self.vapi.cli("show nat44 static mappings"))
4383 self.logger.info(self.vapi.cli("show nat44 interface address"))
4384 self.logger.info(self.vapi.cli("show nat44 sessions detail"))
4385 self.logger.info(self.vapi.cli("show nat virtual-reassembly"))
4386 self.logger.info(self.vapi.cli("show nat44 hash tables detail"))
4387 self.logger.info(self.vapi.cli("show nat timeouts"))
4389 self.vapi.cli("show nat addr-port-assignment-alg"))
4390 self.logger.info(self.vapi.cli("show nat ha"))
4393 class TestNAT44EndpointDependent(MethodHolder):
4394 """ Endpoint-Dependent mapping and filtering test cases """
4397 def setUpConstants(cls):
4398 super(TestNAT44EndpointDependent, cls).setUpConstants()
4399 cls.vpp_cmdline.extend(["nat", "{", "endpoint-dependent", "}"])
4402 def setUpClass(cls):
4403 super(TestNAT44EndpointDependent, cls).setUpClass()
4404 cls.vapi.cli("set log class nat level debug")
4406 cls.tcp_port_in = 6303
4407 cls.tcp_port_out = 6303
4408 cls.udp_port_in = 6304
4409 cls.udp_port_out = 6304
4410 cls.icmp_id_in = 6305
4411 cls.icmp_id_out = 6305
4412 cls.nat_addr = '10.0.0.3'
4413 cls.ipfix_src_port = 4739
4414 cls.ipfix_domain_id = 1
4415 cls.tcp_external_port = 80
4417 cls.create_pg_interfaces(range(7))
4418 cls.interfaces = list(cls.pg_interfaces[0:3])
4420 for i in cls.interfaces:
4425 cls.pg0.generate_remote_hosts(3)
4426 cls.pg0.configure_ipv4_neighbors()
4430 cls.pg4.generate_remote_hosts(2)
4431 cls.pg4.config_ip4()
4432 cls.vapi.sw_interface_add_del_address(
4433 sw_if_index=cls.pg4.sw_if_index,
4434 prefix=VppIpPrefix("10.0.0.1", 24).encode())
4437 cls.pg4.resolve_arp()
4438 cls.pg4._remote_hosts[1]._ip4 = cls.pg4._remote_hosts[0]._ip4
4439 cls.pg4.resolve_arp()
4441 zero_ip4n = socket.inet_pton(socket.AF_INET, "0.0.0.0")
4442 cls.vapi.ip_table_add_del(is_add=1, table_id=1)
4444 cls.pg5._local_ip4 = VppIpPrefix("10.1.1.1",
4445 cls.pg5.local_ip4_prefix.len)
4446 cls.pg5._remote_hosts[0]._ip4 = "10.1.1.2"
4447 cls.pg5._remote_hosts[0]._ip4n = socket.inet_pton(
4448 socket.AF_INET, cls.pg5.remote_ip4)
4449 cls.pg5.set_table_ip4(1)
4450 cls.pg5.config_ip4()
4452 r1 = VppIpRoute(cls, cls.pg5.remote_ip4, 32,
4453 [VppRoutePath("0.0.0.0",
4454 cls.pg5.sw_if_index)],
4459 cls.pg6._local_ip4 = VppIpPrefix("10.1.2.1",
4460 cls.pg6.local_ip4_prefix.len)
4461 cls.pg6._remote_hosts[0]._ip4 = "10.1.2.2"
4462 cls.pg6._remote_hosts[0]._ip4n = socket.inet_pton(
4463 socket.AF_INET, cls.pg6.remote_ip4)
4464 cls.pg6.set_table_ip4(1)
4465 cls.pg6.config_ip4()
4468 r2 = VppIpRoute(cls, cls.pg6.remote_ip4, 32,
4469 [VppRoutePath("0.0.0.0",
4470 cls.pg6.sw_if_index)],
4473 r3 = VppIpRoute(cls, cls.pg6.remote_ip4, 16,
4474 [VppRoutePath("0.0.0.0",
4479 r4 = VppIpRoute(cls, "0.0.0.0", 0,
4480 [VppRoutePath("0.0.0.0", 0xffffffff,
4484 r5 = VppIpRoute(cls, "0.0.0.0", 0,
4485 [VppRoutePath(cls.pg1.local_ip4,
4486 cls.pg1.sw_if_index)],
4493 cls.pg5.resolve_arp()
4494 cls.pg6.resolve_arp()
4497 super(TestNAT44EndpointDependent, cls).tearDownClass()
4501 def tearDownClass(cls):
4502 super(TestNAT44EndpointDependent, cls).tearDownClass()
4504 def test_frag_in_order(self):
4505 """ NAT44 translate fragments arriving in order """
4506 self.nat44_add_address(self.nat_addr)
4507 flags = self.config_flags.NAT_IS_INSIDE
4508 self.vapi.nat44_interface_add_del_feature(
4509 sw_if_index=self.pg0.sw_if_index,
4510 flags=flags, is_add=1)
4511 self.vapi.nat44_interface_add_del_feature(
4512 sw_if_index=self.pg1.sw_if_index,
4514 self.frag_in_order(proto=IP_PROTOS.tcp)
4515 self.frag_in_order(proto=IP_PROTOS.udp)
4516 self.frag_in_order(proto=IP_PROTOS.icmp)
4518 def test_frag_in_order_dont_translate(self):
4519 """ NAT44 don't translate fragments arriving in order """
4520 flags = self.config_flags.NAT_IS_INSIDE
4521 self.vapi.nat44_interface_add_del_feature(
4522 sw_if_index=self.pg0.sw_if_index,
4523 flags=flags, is_add=1)
4524 self.vapi.nat44_interface_add_del_feature(
4525 sw_if_index=self.pg1.sw_if_index,
4527 self.vapi.nat44_forwarding_enable_disable(enable=True)
4528 reas_cfg1 = self.vapi.nat_get_reass()
4529 # this test was intermittently failing in some cases
4530 # until we temporarily bump the reassembly timeouts
4531 self.vapi.nat_set_reass(timeout=20, max_reass=1024, max_frag=5,
4533 self.frag_in_order(proto=IP_PROTOS.tcp, dont_translate=True)
4534 # restore the reassembly timeouts
4535 self.vapi.nat_set_reass(timeout=reas_cfg1.ip4_timeout,
4536 max_reass=reas_cfg1.ip4_max_reass,
4537 max_frag=reas_cfg1.ip4_max_frag,
4538 drop_frag=reas_cfg1.ip4_drop_frag)
4540 def test_frag_out_of_order(self):
4541 """ NAT44 translate fragments arriving out of order """
4542 self.nat44_add_address(self.nat_addr)
4543 flags = self.config_flags.NAT_IS_INSIDE
4544 self.vapi.nat44_interface_add_del_feature(
4545 sw_if_index=self.pg0.sw_if_index,
4546 flags=flags, is_add=1)
4547 self.vapi.nat44_interface_add_del_feature(
4548 sw_if_index=self.pg1.sw_if_index,
4550 self.frag_out_of_order(proto=IP_PROTOS.tcp)
4551 self.frag_out_of_order(proto=IP_PROTOS.udp)
4552 self.frag_out_of_order(proto=IP_PROTOS.icmp)
4554 def test_frag_out_of_order_dont_translate(self):
4555 """ NAT44 don't translate fragments arriving out of order """
4556 flags = self.config_flags.NAT_IS_INSIDE
4557 self.vapi.nat44_interface_add_del_feature(
4558 sw_if_index=self.pg0.sw_if_index,
4559 flags=flags, is_add=1)
4560 self.vapi.nat44_interface_add_del_feature(
4561 sw_if_index=self.pg1.sw_if_index,
4563 self.vapi.nat44_forwarding_enable_disable(enable=True)
4564 self.frag_out_of_order(proto=IP_PROTOS.tcp, dont_translate=True)
4566 def test_frag_in_order_in_plus_out(self):
4567 """ in+out interface fragments in order """
4568 flags = self.config_flags.NAT_IS_INSIDE
4569 self.vapi.nat44_interface_add_del_feature(
4570 sw_if_index=self.pg0.sw_if_index,
4572 self.vapi.nat44_interface_add_del_feature(
4573 sw_if_index=self.pg0.sw_if_index,
4574 flags=flags, is_add=1)
4575 self.vapi.nat44_interface_add_del_feature(
4576 sw_if_index=self.pg1.sw_if_index,
4578 self.vapi.nat44_interface_add_del_feature(
4579 sw_if_index=self.pg1.sw_if_index,
4580 flags=flags, is_add=1)
4582 self.server = self.pg1.remote_hosts[0]
4584 self.server_in_addr = self.server.ip4
4585 self.server_out_addr = '11.11.11.11'
4586 self.server_in_port = random.randint(1025, 65535)
4587 self.server_out_port = random.randint(1025, 65535)
4589 self.nat44_add_address(self.server_out_addr)
4591 # add static mappings for server
4592 self.nat44_add_static_mapping(self.server_in_addr,
4593 self.server_out_addr,
4594 self.server_in_port,
4595 self.server_out_port,
4596 proto=IP_PROTOS.tcp)
4597 self.nat44_add_static_mapping(self.server_in_addr,
4598 self.server_out_addr,
4599 self.server_in_port,
4600 self.server_out_port,
4601 proto=IP_PROTOS.udp)
4602 self.nat44_add_static_mapping(self.server_in_addr,
4603 self.server_out_addr,
4604 proto=IP_PROTOS.icmp)
4606 self.vapi.nat_set_reass(timeout=10, max_reass=1024, max_frag=5,
4609 self.frag_in_order_in_plus_out(proto=IP_PROTOS.tcp)
4610 self.frag_in_order_in_plus_out(proto=IP_PROTOS.udp)
4611 self.frag_in_order_in_plus_out(proto=IP_PROTOS.icmp)
4613 def test_frag_out_of_order_in_plus_out(self):
4614 """ in+out interface fragments out of order """
4615 flags = self.config_flags.NAT_IS_INSIDE
4616 self.vapi.nat44_interface_add_del_feature(
4617 sw_if_index=self.pg0.sw_if_index,
4619 self.vapi.nat44_interface_add_del_feature(
4620 sw_if_index=self.pg0.sw_if_index,
4621 flags=flags, is_add=1)
4622 self.vapi.nat44_interface_add_del_feature(
4623 sw_if_index=self.pg1.sw_if_index,
4625 self.vapi.nat44_interface_add_del_feature(
4626 sw_if_index=self.pg1.sw_if_index,
4627 flags=flags, is_add=1)
4629 self.server = self.pg1.remote_hosts[0]
4631 self.server_in_addr = self.server.ip4
4632 self.server_out_addr = '11.11.11.11'
4633 self.server_in_port = random.randint(1025, 65535)
4634 self.server_out_port = random.randint(1025, 65535)
4636 self.nat44_add_address(self.server_out_addr)
4638 # add static mappings for server
4639 self.nat44_add_static_mapping(self.server_in_addr,
4640 self.server_out_addr,
4641 self.server_in_port,
4642 self.server_out_port,
4643 proto=IP_PROTOS.tcp)
4644 self.nat44_add_static_mapping(self.server_in_addr,
4645 self.server_out_addr,
4646 self.server_in_port,
4647 self.server_out_port,
4648 proto=IP_PROTOS.udp)
4649 self.nat44_add_static_mapping(self.server_in_addr,
4650 self.server_out_addr,
4651 proto=IP_PROTOS.icmp)
4653 self.vapi.nat_set_reass(timeout=10, max_reass=1024, max_frag=5,
4656 self.frag_out_of_order_in_plus_out(proto=IP_PROTOS.tcp)
4657 self.frag_out_of_order_in_plus_out(proto=IP_PROTOS.udp)
4658 self.frag_out_of_order_in_plus_out(proto=IP_PROTOS.icmp)
4660 def test_reass_hairpinning(self):
4661 """ NAT44 fragments hairpinning """
4662 self.server = self.pg0.remote_hosts[1]
4663 self.host_in_port = random.randint(1025, 65535)
4664 self.server_in_port = random.randint(1025, 65535)
4665 self.server_out_port = random.randint(1025, 65535)
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,
4675 # add static mapping for server
4676 self.nat44_add_static_mapping(self.server.ip4, self.nat_addr,
4677 self.server_in_port,
4678 self.server_out_port,
4679 proto=IP_PROTOS.tcp)
4680 self.nat44_add_static_mapping(self.server.ip4, self.nat_addr,
4681 self.server_in_port,
4682 self.server_out_port,
4683 proto=IP_PROTOS.udp)
4684 self.nat44_add_static_mapping(self.server.ip4, self.nat_addr)
4686 self.reass_hairpinning(proto=IP_PROTOS.tcp)
4687 self.reass_hairpinning(proto=IP_PROTOS.udp)
4688 self.reass_hairpinning(proto=IP_PROTOS.icmp)
4690 def test_dynamic(self):
4691 """ NAT44 dynamic translation test """
4693 self.nat44_add_address(self.nat_addr)
4694 flags = self.config_flags.NAT_IS_INSIDE
4695 self.vapi.nat44_interface_add_del_feature(
4696 sw_if_index=self.pg0.sw_if_index,
4697 flags=flags, is_add=1)
4698 self.vapi.nat44_interface_add_del_feature(
4699 sw_if_index=self.pg1.sw_if_index,
4702 nat_config = self.vapi.nat_show_config()
4703 self.assertEqual(1, nat_config.endpoint_dependent)
4706 tcpn = self.statistics.get_err_counter(
4707 '/err/nat44-ed-in2out-slowpath/TCP packets')
4708 udpn = self.statistics.get_err_counter(
4709 '/err/nat44-ed-in2out-slowpath/UDP packets')
4710 icmpn = self.statistics.get_err_counter(
4711 '/err/nat44-ed-in2out-slowpath/ICMP packets')
4712 totaln = self.statistics.get_err_counter(
4713 '/err/nat44-ed-in2out-slowpath/good in2out packets processed')
4715 pkts = self.create_stream_in(self.pg0, self.pg1)
4716 self.pg0.add_stream(pkts)
4717 self.pg_enable_capture(self.pg_interfaces)
4719 capture = self.pg1.get_capture(len(pkts))
4720 self.verify_capture_out(capture)
4722 err = self.statistics.get_err_counter(
4723 '/err/nat44-ed-in2out-slowpath/TCP packets')
4724 self.assertEqual(err - tcpn, 1)
4725 err = self.statistics.get_err_counter(
4726 '/err/nat44-ed-in2out-slowpath/UDP packets')
4727 self.assertEqual(err - udpn, 1)
4728 err = self.statistics.get_err_counter(
4729 '/err/nat44-ed-in2out-slowpath/ICMP packets')
4730 self.assertEqual(err - icmpn, 1)
4731 err = self.statistics.get_err_counter(
4732 '/err/nat44-ed-in2out-slowpath/good in2out packets processed')
4733 self.assertEqual(err - totaln, 3)
4736 tcpn = self.statistics.get_err_counter(
4737 '/err/nat44-ed-out2in/TCP packets')
4738 udpn = self.statistics.get_err_counter(
4739 '/err/nat44-ed-out2in/UDP packets')
4740 icmpn = self.statistics.get_err_counter(
4741 '/err/nat44-ed-out2in-slowpath/ICMP packets')
4742 totaln = self.statistics.get_err_counter(
4743 '/err/nat44-ed-out2in/good out2in packets processed')
4745 pkts = self.create_stream_out(self.pg1)
4746 self.pg1.add_stream(pkts)
4747 self.pg_enable_capture(self.pg_interfaces)
4749 capture = self.pg0.get_capture(len(pkts))
4750 self.verify_capture_in(capture, self.pg0)
4752 err = self.statistics.get_err_counter(
4753 '/err/nat44-ed-out2in/TCP packets')
4754 self.assertEqual(err - tcpn, 1)
4755 err = self.statistics.get_err_counter(
4756 '/err/nat44-ed-out2in/UDP packets')
4757 self.assertEqual(err - udpn, 1)
4758 err = self.statistics.get_err_counter(
4759 '/err/nat44-ed-out2in-slowpath/ICMP packets')
4760 self.assertEqual(err - icmpn, 1)
4761 err = self.statistics.get_err_counter(
4762 '/err/nat44-ed-out2in/good out2in packets processed')
4763 self.assertEqual(err - totaln, 2)
4765 users = self.statistics.get_counter('/nat44/total-users')
4766 self.assertEqual(users[0][0], 1)
4767 sessions = self.statistics.get_counter('/nat44/total-sessions')
4768 self.assertEqual(sessions[0][0], 3)
4770 def test_forwarding(self):
4771 """ NAT44 forwarding test """
4773 flags = self.config_flags.NAT_IS_INSIDE
4774 self.vapi.nat44_interface_add_del_feature(
4775 sw_if_index=self.pg0.sw_if_index,
4776 flags=flags, is_add=1)
4777 self.vapi.nat44_interface_add_del_feature(
4778 sw_if_index=self.pg1.sw_if_index,
4780 self.vapi.nat44_forwarding_enable_disable(enable=1)
4782 real_ip = self.pg0.remote_ip4
4783 alias_ip = self.nat_addr
4784 flags = self.config_flags.NAT_IS_ADDR_ONLY
4785 self.vapi.nat44_add_del_static_mapping(is_add=1,
4786 local_ip_address=real_ip,
4787 external_ip_address=alias_ip,
4788 external_sw_if_index=0xFFFFFFFF,
4792 # in2out - static mapping match
4794 pkts = self.create_stream_out(self.pg1)
4795 self.pg1.add_stream(pkts)
4796 self.pg_enable_capture(self.pg_interfaces)
4798 capture = self.pg0.get_capture(len(pkts))
4799 self.verify_capture_in(capture, self.pg0)
4801 pkts = self.create_stream_in(self.pg0, self.pg1)
4802 self.pg0.add_stream(pkts)
4803 self.pg_enable_capture(self.pg_interfaces)
4805 capture = self.pg1.get_capture(len(pkts))
4806 self.verify_capture_out(capture, same_port=True)
4808 # in2out - no static mapping match
4810 host0 = self.pg0.remote_hosts[0]
4811 self.pg0.remote_hosts[0] = self.pg0.remote_hosts[1]
4813 pkts = self.create_stream_out(self.pg1,
4814 dst_ip=self.pg0.remote_ip4,
4815 use_inside_ports=True)
4816 self.pg1.add_stream(pkts)
4817 self.pg_enable_capture(self.pg_interfaces)
4819 capture = self.pg0.get_capture(len(pkts))
4820 self.verify_capture_in(capture, self.pg0)
4822 pkts = self.create_stream_in(self.pg0, self.pg1)
4823 self.pg0.add_stream(pkts)
4824 self.pg_enable_capture(self.pg_interfaces)
4826 capture = self.pg1.get_capture(len(pkts))
4827 self.verify_capture_out(capture, nat_ip=self.pg0.remote_ip4,
4830 self.pg0.remote_hosts[0] = host0
4832 user = self.pg0.remote_hosts[1]
4833 sessions = self.vapi.nat44_user_session_dump(user.ip4n, 0)
4834 self.assertEqual(len(sessions), 3)
4835 self.assertTrue(sessions[0].flags &
4836 self.config_flags.NAT_IS_EXT_HOST_VALID)
4837 self.vapi.nat44_del_session(
4838 address=sessions[0].inside_ip_address,
4839 port=sessions[0].inside_port,
4840 protocol=sessions[0].protocol,
4841 flags=(self.config_flags.NAT_IS_INSIDE |
4842 self.config_flags.NAT_IS_EXT_HOST_VALID),
4843 ext_host_address=sessions[0].ext_host_address,
4844 ext_host_port=sessions[0].ext_host_port)
4845 sessions = self.vapi.nat44_user_session_dump(user.ip4n, 0)
4846 self.assertEqual(len(sessions), 2)
4849 self.vapi.nat44_forwarding_enable_disable(enable=0)
4850 flags = self.config_flags.NAT_IS_ADDR_ONLY
4851 self.vapi.nat44_add_del_static_mapping(
4853 local_ip_address=real_ip,
4854 external_ip_address=alias_ip,
4855 external_sw_if_index=0xFFFFFFFF,
4858 def test_static_lb(self):
4859 """ NAT44 local service load balancing """
4860 external_addr_n = self.nat_addr
4863 server1 = self.pg0.remote_hosts[0]
4864 server2 = self.pg0.remote_hosts[1]
4866 locals = [{'addr': server1.ip4n,
4870 {'addr': server2.ip4n,
4875 self.nat44_add_address(self.nat_addr)
4876 self.vapi.nat44_add_del_lb_static_mapping(
4878 external_addr=external_addr_n,
4879 external_port=external_port,
4880 protocol=IP_PROTOS.tcp,
4881 local_num=len(locals),
4883 flags = self.config_flags.NAT_IS_INSIDE
4884 self.vapi.nat44_interface_add_del_feature(
4885 sw_if_index=self.pg0.sw_if_index,
4886 flags=flags, is_add=1)
4887 self.vapi.nat44_interface_add_del_feature(
4888 sw_if_index=self.pg1.sw_if_index,
4891 # from client to service
4892 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
4893 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
4894 TCP(sport=12345, dport=external_port))
4895 self.pg1.add_stream(p)
4896 self.pg_enable_capture(self.pg_interfaces)
4898 capture = self.pg0.get_capture(1)
4904 self.assertIn(ip.dst, [server1.ip4, server2.ip4])
4905 if ip.dst == server1.ip4:
4909 self.assertEqual(tcp.dport, local_port)
4910 self.assert_packet_checksums_valid(p)
4912 self.logger.error(ppp("Unexpected or invalid packet:", p))
4915 # from service back to client
4916 p = (Ether(src=server.mac, dst=self.pg0.local_mac) /
4917 IP(src=server.ip4, dst=self.pg1.remote_ip4) /
4918 TCP(sport=local_port, dport=12345))
4919 self.pg0.add_stream(p)
4920 self.pg_enable_capture(self.pg_interfaces)
4922 capture = self.pg1.get_capture(1)
4927 self.assertEqual(ip.src, self.nat_addr)
4928 self.assertEqual(tcp.sport, external_port)
4929 self.assert_packet_checksums_valid(p)
4931 self.logger.error(ppp("Unexpected or invalid packet:", p))
4934 sessions = self.vapi.nat44_user_session_dump(server.ip4n, 0)
4935 self.assertEqual(len(sessions), 1)
4936 self.assertTrue(sessions[0].flags &
4937 self.config_flags.NAT_IS_EXT_HOST_VALID)
4938 self.vapi.nat44_del_session(
4939 address=sessions[0].inside_ip_address,
4940 port=sessions[0].inside_port,
4941 protocol=sessions[0].protocol,
4942 flags=(self.config_flags.NAT_IS_INSIDE |
4943 self.config_flags.NAT_IS_EXT_HOST_VALID),
4944 ext_host_address=sessions[0].ext_host_address,
4945 ext_host_port=sessions[0].ext_host_port)
4946 sessions = self.vapi.nat44_user_session_dump(server.ip4n, 0)
4947 self.assertEqual(len(sessions), 0)
4949 @unittest.skipUnless(running_extended_tests, "part of extended tests")
4950 def test_static_lb_multi_clients(self):
4951 """ NAT44 local service load balancing - multiple clients"""
4953 external_addr = self.nat_addr
4956 server1 = self.pg0.remote_hosts[0]
4957 server2 = self.pg0.remote_hosts[1]
4958 server3 = self.pg0.remote_hosts[2]
4960 locals = [{'addr': server1.ip4n,
4964 {'addr': server2.ip4n,
4969 self.nat44_add_address(self.nat_addr)
4970 self.vapi.nat44_add_del_lb_static_mapping(is_add=1,
4971 external_addr=external_addr,
4972 external_port=external_port,
4973 protocol=IP_PROTOS.tcp,
4974 local_num=len(locals),
4976 flags = self.config_flags.NAT_IS_INSIDE
4977 self.vapi.nat44_interface_add_del_feature(
4978 sw_if_index=self.pg0.sw_if_index,
4979 flags=flags, is_add=1)
4980 self.vapi.nat44_interface_add_del_feature(
4981 sw_if_index=self.pg1.sw_if_index,
4986 clients = ip4_range(self.pg1.remote_ip4, 10, 50)
4988 for client in clients:
4989 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
4990 IP(src=client, dst=self.nat_addr) /
4991 TCP(sport=12345, dport=external_port))
4993 self.pg1.add_stream(pkts)
4994 self.pg_enable_capture(self.pg_interfaces)
4996 capture = self.pg0.get_capture(len(pkts))
4998 if p[IP].dst == server1.ip4:
5002 self.assertGreater(server1_n, server2_n)
5005 'addr': server3.ip4n,
5012 self.vapi.nat44_lb_static_mapping_add_del_local(
5014 external_addr=external_addr,
5015 external_port=external_port,
5017 protocol=IP_PROTOS.tcp)
5021 clients = ip4_range(self.pg1.remote_ip4, 60, 110)
5023 for client in clients:
5024 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
5025 IP(src=client, dst=self.nat_addr) /
5026 TCP(sport=12346, dport=external_port))
5028 self.assertGreater(len(pkts), 0)
5029 self.pg1.add_stream(pkts)
5030 self.pg_enable_capture(self.pg_interfaces)
5032 capture = self.pg0.get_capture(len(pkts))
5034 if p[IP].dst == server1.ip4:
5036 elif p[IP].dst == server2.ip4:
5040 self.assertGreater(server1_n, 0)
5041 self.assertGreater(server2_n, 0)
5042 self.assertGreater(server3_n, 0)
5045 'addr': server2.ip4n,
5051 # remove one back-end
5052 self.vapi.nat44_lb_static_mapping_add_del_local(
5054 external_addr=external_addr,
5055 external_port=external_port,
5057 protocol=IP_PROTOS.tcp)
5061 self.pg1.add_stream(pkts)
5062 self.pg_enable_capture(self.pg_interfaces)
5064 capture = self.pg0.get_capture(len(pkts))
5066 if p[IP].dst == server1.ip4:
5068 elif p[IP].dst == server2.ip4:
5072 self.assertGreater(server1_n, 0)
5073 self.assertEqual(server2_n, 0)
5074 self.assertGreater(server3_n, 0)
5076 def test_static_lb_2(self):
5077 """ NAT44 local service load balancing (asymmetrical rule) """
5078 external_addr = self.nat_addr
5081 server1 = self.pg0.remote_hosts[0]
5082 server2 = self.pg0.remote_hosts[1]
5084 locals = [{'addr': server1.ip4n,
5088 {'addr': server2.ip4n,
5093 self.vapi.nat44_forwarding_enable_disable(enable=1)
5094 flags = self.config_flags.NAT_IS_OUT2IN_ONLY
5095 self.vapi.nat44_add_del_lb_static_mapping(is_add=1, flags=flags,
5096 external_addr=external_addr,
5097 external_port=external_port,
5098 protocol=IP_PROTOS.tcp,
5099 local_num=len(locals),
5101 flags = self.config_flags.NAT_IS_INSIDE
5102 self.vapi.nat44_interface_add_del_feature(
5103 sw_if_index=self.pg0.sw_if_index,
5104 flags=flags, is_add=1)
5105 self.vapi.nat44_interface_add_del_feature(
5106 sw_if_index=self.pg1.sw_if_index,
5109 # from client to service
5110 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
5111 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
5112 TCP(sport=12345, dport=external_port))
5113 self.pg1.add_stream(p)
5114 self.pg_enable_capture(self.pg_interfaces)
5116 capture = self.pg0.get_capture(1)
5122 self.assertIn(ip.dst, [server1.ip4, server2.ip4])
5123 if ip.dst == server1.ip4:
5127 self.assertEqual(tcp.dport, local_port)
5128 self.assert_packet_checksums_valid(p)
5130 self.logger.error(ppp("Unexpected or invalid packet:", p))
5133 # from service back to client
5134 p = (Ether(src=server.mac, dst=self.pg0.local_mac) /
5135 IP(src=server.ip4, dst=self.pg1.remote_ip4) /
5136 TCP(sport=local_port, dport=12345))
5137 self.pg0.add_stream(p)
5138 self.pg_enable_capture(self.pg_interfaces)
5140 capture = self.pg1.get_capture(1)
5145 self.assertEqual(ip.src, self.nat_addr)
5146 self.assertEqual(tcp.sport, external_port)
5147 self.assert_packet_checksums_valid(p)
5149 self.logger.error(ppp("Unexpected or invalid packet:", p))
5152 # from client to server (no translation)
5153 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
5154 IP(src=self.pg1.remote_ip4, dst=server1.ip4) /
5155 TCP(sport=12346, dport=local_port))
5156 self.pg1.add_stream(p)
5157 self.pg_enable_capture(self.pg_interfaces)
5159 capture = self.pg0.get_capture(1)
5165 self.assertEqual(ip.dst, server1.ip4)
5166 self.assertEqual(tcp.dport, local_port)
5167 self.assert_packet_checksums_valid(p)
5169 self.logger.error(ppp("Unexpected or invalid packet:", p))
5172 # from service back to client (no translation)
5173 p = (Ether(src=server1.mac, dst=self.pg0.local_mac) /
5174 IP(src=server1.ip4, dst=self.pg1.remote_ip4) /
5175 TCP(sport=local_port, dport=12346))
5176 self.pg0.add_stream(p)
5177 self.pg_enable_capture(self.pg_interfaces)
5179 capture = self.pg1.get_capture(1)
5184 self.assertEqual(ip.src, server1.ip4)
5185 self.assertEqual(tcp.sport, local_port)
5186 self.assert_packet_checksums_valid(p)
5188 self.logger.error(ppp("Unexpected or invalid packet:", p))
5191 def test_lb_affinity(self):
5192 """ NAT44 local service load balancing affinity """
5193 external_addr = self.nat_addr
5196 server1 = self.pg0.remote_hosts[0]
5197 server2 = self.pg0.remote_hosts[1]
5199 locals = [{'addr': server1.ip4n,
5203 {'addr': server2.ip4n,
5208 self.nat44_add_address(self.nat_addr)
5209 self.vapi.nat44_add_del_lb_static_mapping(is_add=1,
5210 external_addr=external_addr,
5211 external_port=external_port,
5212 protocol=IP_PROTOS.tcp,
5214 local_num=len(locals),
5216 flags = self.config_flags.NAT_IS_INSIDE
5217 self.vapi.nat44_interface_add_del_feature(
5218 sw_if_index=self.pg0.sw_if_index,
5219 flags=flags, is_add=1)
5220 self.vapi.nat44_interface_add_del_feature(
5221 sw_if_index=self.pg1.sw_if_index,
5224 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
5225 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
5226 TCP(sport=1025, dport=external_port))
5227 self.pg1.add_stream(p)
5228 self.pg_enable_capture(self.pg_interfaces)
5230 capture = self.pg0.get_capture(1)
5231 backend = capture[0][IP].dst
5233 sessions = self.vapi.nat44_user_session_dump(backend, 0)
5234 self.assertEqual(len(sessions), 1)
5235 self.assertTrue(sessions[0].flags &
5236 self.config_flags.NAT_IS_EXT_HOST_VALID)
5237 self.vapi.nat44_del_session(
5238 address=sessions[0].inside_ip_address,
5239 port=sessions[0].inside_port,
5240 protocol=sessions[0].protocol,
5241 flags=(self.config_flags.NAT_IS_INSIDE |
5242 self.config_flags.NAT_IS_EXT_HOST_VALID),
5243 ext_host_address=sessions[0].ext_host_address,
5244 ext_host_port=sessions[0].ext_host_port)
5247 for port in range(1030, 1100):
5248 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
5249 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
5250 TCP(sport=port, dport=external_port))
5252 self.pg1.add_stream(pkts)
5253 self.pg_enable_capture(self.pg_interfaces)
5255 capture = self.pg0.get_capture(len(pkts))
5257 self.assertEqual(p[IP].dst, backend)
5259 def test_unknown_proto(self):
5260 """ NAT44 translate packet with unknown protocol """
5261 self.nat44_add_address(self.nat_addr)
5262 flags = self.config_flags.NAT_IS_INSIDE
5263 self.vapi.nat44_interface_add_del_feature(
5264 sw_if_index=self.pg0.sw_if_index,
5265 flags=flags, is_add=1)
5266 self.vapi.nat44_interface_add_del_feature(
5267 sw_if_index=self.pg1.sw_if_index,
5271 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
5272 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
5273 TCP(sport=self.tcp_port_in, dport=20))
5274 self.pg0.add_stream(p)
5275 self.pg_enable_capture(self.pg_interfaces)
5277 p = self.pg1.get_capture(1)
5279 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
5280 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
5282 IP(src=self.pg2.remote_ip4, dst=self.pg2.remote_ip4) /
5283 TCP(sport=1234, dport=1234))
5284 self.pg0.add_stream(p)
5285 self.pg_enable_capture(self.pg_interfaces)
5287 p = self.pg1.get_capture(1)
5290 self.assertEqual(packet[IP].src, self.nat_addr)
5291 self.assertEqual(packet[IP].dst, self.pg1.remote_ip4)
5292 self.assertEqual(packet.haslayer(GRE), 1)
5293 self.assert_packet_checksums_valid(packet)
5295 self.logger.error(ppp("Unexpected or invalid packet:", packet))
5299 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
5300 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
5302 IP(src=self.pg2.remote_ip4, dst=self.pg2.remote_ip4) /
5303 TCP(sport=1234, dport=1234))
5304 self.pg1.add_stream(p)
5305 self.pg_enable_capture(self.pg_interfaces)
5307 p = self.pg0.get_capture(1)
5310 self.assertEqual(packet[IP].src, self.pg1.remote_ip4)
5311 self.assertEqual(packet[IP].dst, self.pg0.remote_ip4)
5312 self.assertEqual(packet.haslayer(GRE), 1)
5313 self.assert_packet_checksums_valid(packet)
5315 self.logger.error(ppp("Unexpected or invalid packet:", packet))
5318 def test_hairpinning_unknown_proto(self):
5319 """ NAT44 translate packet with unknown protocol - hairpinning """
5320 host = self.pg0.remote_hosts[0]
5321 server = self.pg0.remote_hosts[1]
5323 server_out_port = 8765
5324 server_nat_ip = "10.0.0.11"
5326 self.nat44_add_address(self.nat_addr)
5327 flags = self.config_flags.NAT_IS_INSIDE
5328 self.vapi.nat44_interface_add_del_feature(
5329 sw_if_index=self.pg0.sw_if_index,
5330 flags=flags, is_add=1)
5331 self.vapi.nat44_interface_add_del_feature(
5332 sw_if_index=self.pg1.sw_if_index,
5335 # add static mapping for server
5336 self.nat44_add_static_mapping(server.ip4, server_nat_ip)
5339 p = (Ether(src=host.mac, dst=self.pg0.local_mac) /
5340 IP(src=host.ip4, dst=server_nat_ip) /
5341 TCP(sport=host_in_port, dport=server_out_port))
5342 self.pg0.add_stream(p)
5343 self.pg_enable_capture(self.pg_interfaces)
5345 self.pg0.get_capture(1)
5347 p = (Ether(dst=self.pg0.local_mac, src=host.mac) /
5348 IP(src=host.ip4, dst=server_nat_ip) /
5350 IP(src=self.pg2.remote_ip4, dst=self.pg2.remote_ip4) /
5351 TCP(sport=1234, dport=1234))
5352 self.pg0.add_stream(p)
5353 self.pg_enable_capture(self.pg_interfaces)
5355 p = self.pg0.get_capture(1)
5358 self.assertEqual(packet[IP].src, self.nat_addr)
5359 self.assertEqual(packet[IP].dst, server.ip4)
5360 self.assertEqual(packet.haslayer(GRE), 1)
5361 self.assert_packet_checksums_valid(packet)
5363 self.logger.error(ppp("Unexpected or invalid packet:", packet))
5367 p = (Ether(dst=self.pg0.local_mac, src=server.mac) /
5368 IP(src=server.ip4, dst=self.nat_addr) /
5370 IP(src=self.pg2.remote_ip4, dst=self.pg2.remote_ip4) /
5371 TCP(sport=1234, dport=1234))
5372 self.pg0.add_stream(p)
5373 self.pg_enable_capture(self.pg_interfaces)
5375 p = self.pg0.get_capture(1)
5378 self.assertEqual(packet[IP].src, server_nat_ip)
5379 self.assertEqual(packet[IP].dst, host.ip4)
5380 self.assertEqual(packet.haslayer(GRE), 1)
5381 self.assert_packet_checksums_valid(packet)
5383 self.logger.error(ppp("Unexpected or invalid packet:", packet))
5386 def test_output_feature_and_service(self):
5387 """ NAT44 interface output feature and services """
5388 external_addr = '1.2.3.4'
5392 self.vapi.nat44_forwarding_enable_disable(enable=1)
5393 self.nat44_add_address(self.nat_addr)
5394 flags = self.config_flags.NAT_IS_ADDR_ONLY
5395 self.vapi.nat44_add_del_identity_mapping(
5396 ip_address=self.pg1.remote_ip4n, sw_if_index=0xFFFFFFFF,
5397 flags=flags, is_add=1)
5398 flags = self.config_flags.NAT_IS_OUT2IN_ONLY
5399 self.nat44_add_static_mapping(self.pg0.remote_ip4, external_addr,
5400 local_port, external_port,
5401 proto=IP_PROTOS.tcp, flags=flags)
5402 flags = self.config_flags.NAT_IS_INSIDE
5403 self.vapi.nat44_interface_add_del_feature(
5404 sw_if_index=self.pg0.sw_if_index,
5406 self.vapi.nat44_interface_add_del_feature(
5407 sw_if_index=self.pg0.sw_if_index,
5408 flags=flags, is_add=1)
5409 self.vapi.nat44_interface_add_del_output_feature(
5411 sw_if_index=self.pg1.sw_if_index)
5413 # from client to service
5414 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
5415 IP(src=self.pg1.remote_ip4, dst=external_addr) /
5416 TCP(sport=12345, dport=external_port))
5417 self.pg1.add_stream(p)
5418 self.pg_enable_capture(self.pg_interfaces)
5420 capture = self.pg0.get_capture(1)
5425 self.assertEqual(ip.dst, self.pg0.remote_ip4)
5426 self.assertEqual(tcp.dport, local_port)
5427 self.assert_packet_checksums_valid(p)
5429 self.logger.error(ppp("Unexpected or invalid packet:", p))
5432 # from service back to client
5433 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5434 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
5435 TCP(sport=local_port, dport=12345))
5436 self.pg0.add_stream(p)
5437 self.pg_enable_capture(self.pg_interfaces)
5439 capture = self.pg1.get_capture(1)
5444 self.assertEqual(ip.src, external_addr)
5445 self.assertEqual(tcp.sport, external_port)
5446 self.assert_packet_checksums_valid(p)
5448 self.logger.error(ppp("Unexpected or invalid packet:", p))
5451 # from local network host to external network
5452 pkts = self.create_stream_in(self.pg0, self.pg1)
5453 self.pg0.add_stream(pkts)
5454 self.pg_enable_capture(self.pg_interfaces)
5456 capture = self.pg1.get_capture(len(pkts))
5457 self.verify_capture_out(capture)
5458 pkts = self.create_stream_in(self.pg0, self.pg1)
5459 self.pg0.add_stream(pkts)
5460 self.pg_enable_capture(self.pg_interfaces)
5462 capture = self.pg1.get_capture(len(pkts))
5463 self.verify_capture_out(capture)
5465 # from external network back to local network host
5466 pkts = self.create_stream_out(self.pg1)
5467 self.pg1.add_stream(pkts)
5468 self.pg_enable_capture(self.pg_interfaces)
5470 capture = self.pg0.get_capture(len(pkts))
5471 self.verify_capture_in(capture, self.pg0)
5473 def test_output_feature_and_service2(self):
5474 """ NAT44 interface output feature and service host direct access """
5475 self.vapi.nat44_forwarding_enable_disable(enable=1)
5476 self.nat44_add_address(self.nat_addr)
5477 self.vapi.nat44_interface_add_del_output_feature(
5479 sw_if_index=self.pg1.sw_if_index)
5481 # session initiated from service host - translate
5482 pkts = self.create_stream_in(self.pg0, self.pg1)
5483 self.pg0.add_stream(pkts)
5484 self.pg_enable_capture(self.pg_interfaces)
5486 capture = self.pg1.get_capture(len(pkts))
5487 self.verify_capture_out(capture)
5489 pkts = self.create_stream_out(self.pg1)
5490 self.pg1.add_stream(pkts)
5491 self.pg_enable_capture(self.pg_interfaces)
5493 capture = self.pg0.get_capture(len(pkts))
5494 self.verify_capture_in(capture, self.pg0)
5496 # session initiated from remote host - do not translate
5497 self.tcp_port_in = 60303
5498 self.udp_port_in = 60304
5499 self.icmp_id_in = 60305
5500 pkts = self.create_stream_out(self.pg1,
5501 self.pg0.remote_ip4,
5502 use_inside_ports=True)
5503 self.pg1.add_stream(pkts)
5504 self.pg_enable_capture(self.pg_interfaces)
5506 capture = self.pg0.get_capture(len(pkts))
5507 self.verify_capture_in(capture, self.pg0)
5509 pkts = self.create_stream_in(self.pg0, self.pg1)
5510 self.pg0.add_stream(pkts)
5511 self.pg_enable_capture(self.pg_interfaces)
5513 capture = self.pg1.get_capture(len(pkts))
5514 self.verify_capture_out(capture, nat_ip=self.pg0.remote_ip4,
5517 def test_output_feature_and_service3(self):
5518 """ NAT44 interface output feature and DST NAT """
5519 external_addr = '1.2.3.4'
5523 self.vapi.nat44_forwarding_enable_disable(enable=1)
5524 self.nat44_add_address(self.nat_addr)
5525 flags = self.config_flags.NAT_IS_OUT2IN_ONLY
5526 self.nat44_add_static_mapping(self.pg1.remote_ip4, external_addr,
5527 local_port, external_port,
5528 proto=IP_PROTOS.tcp, flags=flags)
5529 flags = self.config_flags.NAT_IS_INSIDE
5530 self.vapi.nat44_interface_add_del_feature(
5531 sw_if_index=self.pg0.sw_if_index,
5533 self.vapi.nat44_interface_add_del_feature(
5534 sw_if_index=self.pg0.sw_if_index,
5535 flags=flags, is_add=1)
5536 self.vapi.nat44_interface_add_del_output_feature(
5538 sw_if_index=self.pg1.sw_if_index)
5540 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5541 IP(src=self.pg0.remote_ip4, dst=external_addr) /
5542 TCP(sport=12345, dport=external_port))
5543 self.pg0.add_stream(p)
5544 self.pg_enable_capture(self.pg_interfaces)
5546 capture = self.pg1.get_capture(1)
5551 self.assertEqual(ip.src, self.pg0.remote_ip4)
5552 self.assertEqual(tcp.sport, 12345)
5553 self.assertEqual(ip.dst, self.pg1.remote_ip4)
5554 self.assertEqual(tcp.dport, local_port)
5555 self.assert_packet_checksums_valid(p)
5557 self.logger.error(ppp("Unexpected or invalid packet:", p))
5560 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
5561 IP(src=self.pg1.remote_ip4, dst=self.pg0.remote_ip4) /
5562 TCP(sport=local_port, dport=12345))
5563 self.pg1.add_stream(p)
5564 self.pg_enable_capture(self.pg_interfaces)
5566 capture = self.pg0.get_capture(1)
5571 self.assertEqual(ip.src, external_addr)
5572 self.assertEqual(tcp.sport, external_port)
5573 self.assertEqual(ip.dst, self.pg0.remote_ip4)
5574 self.assertEqual(tcp.dport, 12345)
5575 self.assert_packet_checksums_valid(p)
5577 self.logger.error(ppp("Unexpected or invalid packet:", p))
5580 def test_next_src_nat(self):
5581 """ On way back forward packet to nat44-in2out node. """
5582 twice_nat_addr = '10.0.1.3'
5585 post_twice_nat_port = 0
5587 self.vapi.nat44_forwarding_enable_disable(enable=1)
5588 self.nat44_add_address(twice_nat_addr, twice_nat=1)
5589 flags = (self.config_flags.NAT_IS_OUT2IN_ONLY |
5590 self.config_flags.NAT_IS_SELF_TWICE_NAT)
5591 self.nat44_add_static_mapping(self.pg6.remote_ip4, self.pg1.remote_ip4,
5592 local_port, external_port,
5593 proto=IP_PROTOS.tcp, vrf_id=1,
5595 self.vapi.nat44_interface_add_del_feature(
5596 sw_if_index=self.pg6.sw_if_index,
5599 p = (Ether(src=self.pg6.remote_mac, dst=self.pg6.local_mac) /
5600 IP(src=self.pg6.remote_ip4, dst=self.pg1.remote_ip4) /
5601 TCP(sport=12345, dport=external_port))
5602 self.pg6.add_stream(p)
5603 self.pg_enable_capture(self.pg_interfaces)
5605 capture = self.pg6.get_capture(1)
5610 self.assertEqual(ip.src, twice_nat_addr)
5611 self.assertNotEqual(tcp.sport, 12345)
5612 post_twice_nat_port = tcp.sport
5613 self.assertEqual(ip.dst, self.pg6.remote_ip4)
5614 self.assertEqual(tcp.dport, local_port)
5615 self.assert_packet_checksums_valid(p)
5617 self.logger.error(ppp("Unexpected or invalid packet:", p))
5620 p = (Ether(src=self.pg6.remote_mac, dst=self.pg6.local_mac) /
5621 IP(src=self.pg6.remote_ip4, dst=twice_nat_addr) /
5622 TCP(sport=local_port, dport=post_twice_nat_port))
5623 self.pg6.add_stream(p)
5624 self.pg_enable_capture(self.pg_interfaces)
5626 capture = self.pg6.get_capture(1)
5631 self.assertEqual(ip.src, self.pg1.remote_ip4)
5632 self.assertEqual(tcp.sport, external_port)
5633 self.assertEqual(ip.dst, self.pg6.remote_ip4)
5634 self.assertEqual(tcp.dport, 12345)
5635 self.assert_packet_checksums_valid(p)
5637 self.logger.error(ppp("Unexpected or invalid packet:", p))
5640 def twice_nat_common(self, self_twice_nat=False, same_pg=False, lb=False,
5642 twice_nat_addr = '10.0.1.3'
5650 port_in1 = port_in + 1
5651 port_in2 = port_in + 2
5656 server1 = self.pg0.remote_hosts[0]
5657 server2 = self.pg0.remote_hosts[1]
5669 eh_translate = ((not self_twice_nat) or (not lb and same_pg) or
5672 self.nat44_add_address(self.nat_addr)
5673 self.nat44_add_address(twice_nat_addr, twice_nat=1)
5677 flags |= self.config_flags.NAT_IS_SELF_TWICE_NAT
5679 flags |= self.config_flags.NAT_IS_TWICE_NAT
5682 self.nat44_add_static_mapping(pg0.remote_ip4, self.nat_addr,
5684 proto=IP_PROTOS.tcp,
5687 locals = [{'addr': server1.ip4n,
5691 {'addr': server2.ip4n,
5695 out_addr = self.nat_addr
5697 self.vapi.nat44_add_del_lb_static_mapping(is_add=1, flags=flags,
5698 external_addr=out_addr,
5699 external_port=port_out,
5700 protocol=IP_PROTOS.tcp,
5701 local_num=len(locals),
5703 flags = self.config_flags.NAT_IS_INSIDE
5704 self.vapi.nat44_interface_add_del_feature(
5705 sw_if_index=pg0.sw_if_index,
5706 flags=flags, is_add=1)
5707 self.vapi.nat44_interface_add_del_feature(
5708 sw_if_index=pg1.sw_if_index,
5715 assert client_id is not None
5717 client = self.pg0.remote_hosts[0]
5718 elif client_id == 2:
5719 client = self.pg0.remote_hosts[1]
5721 client = pg1.remote_hosts[0]
5722 p = (Ether(src=pg1.remote_mac, dst=pg1.local_mac) /
5723 IP(src=client.ip4, dst=self.nat_addr) /
5724 TCP(sport=eh_port_out, dport=port_out))
5726 self.pg_enable_capture(self.pg_interfaces)
5728 capture = pg0.get_capture(1)
5734 if ip.dst == server1.ip4:
5740 self.assertEqual(ip.dst, server.ip4)
5742 self.assertIn(tcp.dport, [port_in1, port_in2])
5744 self.assertEqual(tcp.dport, port_in)
5746 self.assertEqual(ip.src, twice_nat_addr)
5747 self.assertNotEqual(tcp.sport, eh_port_out)
5749 self.assertEqual(ip.src, client.ip4)
5750 self.assertEqual(tcp.sport, eh_port_out)
5752 eh_port_in = tcp.sport
5753 saved_port_in = tcp.dport
5754 self.assert_packet_checksums_valid(p)
5756 self.logger.error(ppp("Unexpected or invalid packet:", p))
5759 p = (Ether(src=server.mac, dst=pg0.local_mac) /
5760 IP(src=server.ip4, dst=eh_addr_in) /
5761 TCP(sport=saved_port_in, dport=eh_port_in))
5763 self.pg_enable_capture(self.pg_interfaces)
5765 capture = pg1.get_capture(1)
5770 self.assertEqual(ip.dst, client.ip4)
5771 self.assertEqual(ip.src, self.nat_addr)
5772 self.assertEqual(tcp.dport, eh_port_out)
5773 self.assertEqual(tcp.sport, port_out)
5774 self.assert_packet_checksums_valid(p)
5776 self.logger.error(ppp("Unexpected or invalid packet:", p))
5780 sessions = self.vapi.nat44_user_session_dump(server.ip4n, 0)
5781 self.assertEqual(len(sessions), 1)
5782 self.assertTrue(sessions[0].flags &
5783 self.config_flags.NAT_IS_EXT_HOST_VALID)
5784 self.assertTrue(sessions[0].flags &
5785 self.config_flags.NAT_IS_TWICE_NAT)
5786 self.logger.info(self.vapi.cli("show nat44 sessions detail"))
5787 self.vapi.nat44_del_session(
5788 address=sessions[0].inside_ip_address,
5789 port=sessions[0].inside_port,
5790 protocol=sessions[0].protocol,
5791 flags=(self.config_flags.NAT_IS_INSIDE |
5792 self.config_flags.NAT_IS_EXT_HOST_VALID),
5793 ext_host_address=sessions[0].ext_host_nat_address,
5794 ext_host_port=sessions[0].ext_host_nat_port)
5795 sessions = self.vapi.nat44_user_session_dump(server.ip4n, 0)
5796 self.assertEqual(len(sessions), 0)
5798 def test_twice_nat(self):
5800 self.twice_nat_common()
5802 def test_self_twice_nat_positive(self):
5803 """ Self Twice NAT44 (positive test) """
5804 self.twice_nat_common(self_twice_nat=True, same_pg=True)
5806 def test_self_twice_nat_negative(self):
5807 """ Self Twice NAT44 (negative test) """
5808 self.twice_nat_common(self_twice_nat=True)
5810 def test_twice_nat_lb(self):
5811 """ Twice NAT44 local service load balancing """
5812 self.twice_nat_common(lb=True)
5814 def test_self_twice_nat_lb_positive(self):
5815 """ Self Twice NAT44 local service load balancing (positive test) """
5816 self.twice_nat_common(lb=True, self_twice_nat=True, same_pg=True,
5819 def test_self_twice_nat_lb_negative(self):
5820 """ Self Twice NAT44 local service load balancing (negative test) """
5821 self.twice_nat_common(lb=True, self_twice_nat=True, same_pg=True,
5824 def test_twice_nat_interface_addr(self):
5825 """ Acquire twice NAT44 addresses from interface """
5826 flags = self.config_flags.NAT_IS_TWICE_NAT
5827 self.vapi.nat44_add_del_interface_addr(
5829 sw_if_index=self.pg3.sw_if_index,
5832 # no address in NAT pool
5833 adresses = self.vapi.nat44_address_dump()
5834 self.assertEqual(0, len(adresses))
5836 # configure interface address and check NAT address pool
5837 self.pg3.config_ip4()
5838 adresses = self.vapi.nat44_address_dump()
5839 self.assertEqual(1, len(adresses))
5840 self.assertEqual(str(adresses[0].ip_address),
5842 self.assertEqual(adresses[0].flags, flags)
5844 # remove interface address and check NAT address pool
5845 self.pg3.unconfig_ip4()
5846 adresses = self.vapi.nat44_address_dump()
5847 self.assertEqual(0, len(adresses))
5849 def test_tcp_close(self):
5850 """ Close TCP session from inside network - output feature """
5851 self.vapi.nat44_forwarding_enable_disable(enable=1)
5852 self.nat44_add_address(self.pg1.local_ip4)
5853 twice_nat_addr = '10.0.1.3'
5854 service_ip = '192.168.16.150'
5855 self.nat44_add_address(twice_nat_addr, twice_nat=1)
5856 flags = self.config_flags.NAT_IS_INSIDE
5857 self.vapi.nat44_interface_add_del_feature(
5858 sw_if_index=self.pg0.sw_if_index,
5860 self.vapi.nat44_interface_add_del_feature(
5861 sw_if_index=self.pg0.sw_if_index,
5862 flags=flags, is_add=1)
5863 self.vapi.nat44_interface_add_del_output_feature(
5865 sw_if_index=self.pg1.sw_if_index)
5866 flags = (self.config_flags.NAT_IS_OUT2IN_ONLY |
5867 self.config_flags.NAT_IS_TWICE_NAT)
5868 self.nat44_add_static_mapping(self.pg0.remote_ip4,
5872 proto=IP_PROTOS.tcp,
5874 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4n, 0)
5875 start_sessnum = len(sessions)
5877 # SYN packet out->in
5878 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
5879 IP(src=self.pg1.remote_ip4, dst=service_ip) /
5880 TCP(sport=33898, dport=80, flags="S"))
5881 self.pg1.add_stream(p)
5882 self.pg_enable_capture(self.pg_interfaces)
5884 capture = self.pg0.get_capture(1)
5886 tcp_port = p[TCP].sport
5888 # SYN + ACK packet in->out
5889 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5890 IP(src=self.pg0.remote_ip4, dst=twice_nat_addr) /
5891 TCP(sport=80, dport=tcp_port, flags="SA"))
5892 self.pg0.add_stream(p)
5893 self.pg_enable_capture(self.pg_interfaces)
5895 self.pg1.get_capture(1)
5897 # ACK packet out->in
5898 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
5899 IP(src=self.pg1.remote_ip4, dst=service_ip) /
5900 TCP(sport=33898, dport=80, flags="A"))
5901 self.pg1.add_stream(p)
5902 self.pg_enable_capture(self.pg_interfaces)
5904 self.pg0.get_capture(1)
5906 # FIN packet in -> out
5907 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5908 IP(src=self.pg0.remote_ip4, dst=twice_nat_addr) /
5909 TCP(sport=80, dport=tcp_port, flags="FA", seq=100, ack=300))
5910 self.pg0.add_stream(p)
5911 self.pg_enable_capture(self.pg_interfaces)
5913 self.pg1.get_capture(1)
5915 # FIN+ACK packet out -> in
5916 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
5917 IP(src=self.pg1.remote_ip4, dst=service_ip) /
5918 TCP(sport=33898, dport=80, flags="FA", seq=300, ack=101))
5919 self.pg1.add_stream(p)
5920 self.pg_enable_capture(self.pg_interfaces)
5922 self.pg0.get_capture(1)
5924 # ACK packet in -> out
5925 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5926 IP(src=self.pg0.remote_ip4, dst=twice_nat_addr) /
5927 TCP(sport=80, dport=tcp_port, flags="A", seq=101, ack=301))
5928 self.pg0.add_stream(p)
5929 self.pg_enable_capture(self.pg_interfaces)
5931 self.pg1.get_capture(1)
5933 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4n,
5935 self.assertEqual(len(sessions) - start_sessnum, 0)
5937 def test_tcp_session_close_in(self):
5938 """ Close TCP session from inside network """
5939 self.tcp_port_out = 10505
5940 self.nat44_add_address(self.nat_addr)
5941 flags = self.config_flags.NAT_IS_TWICE_NAT
5942 self.nat44_add_static_mapping(self.pg0.remote_ip4,
5946 proto=IP_PROTOS.tcp,
5948 flags = self.config_flags.NAT_IS_INSIDE
5949 self.vapi.nat44_interface_add_del_feature(
5950 sw_if_index=self.pg0.sw_if_index,
5951 flags=flags, is_add=1)
5952 self.vapi.nat44_interface_add_del_feature(
5953 sw_if_index=self.pg1.sw_if_index,
5956 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4n, 0)
5957 start_sessnum = len(sessions)
5959 self.initiate_tcp_session(self.pg0, self.pg1)
5961 # FIN packet in -> out
5962 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5963 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
5964 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
5965 flags="FA", seq=100, ack=300))
5966 self.pg0.add_stream(p)
5967 self.pg_enable_capture(self.pg_interfaces)
5969 self.pg1.get_capture(1)
5973 # ACK packet out -> in
5974 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
5975 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
5976 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
5977 flags="A", seq=300, ack=101))
5980 # FIN packet out -> in
5981 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
5982 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
5983 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
5984 flags="FA", seq=300, ack=101))
5987 self.pg1.add_stream(pkts)
5988 self.pg_enable_capture(self.pg_interfaces)
5990 self.pg0.get_capture(2)
5992 # ACK packet in -> out
5993 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5994 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
5995 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
5996 flags="A", seq=101, ack=301))
5997 self.pg0.add_stream(p)
5998 self.pg_enable_capture(self.pg_interfaces)
6000 self.pg1.get_capture(1)
6002 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4n,
6004 self.assertEqual(len(sessions) - start_sessnum, 0)
6006 def test_tcp_session_close_out(self):
6007 """ Close TCP session from outside network """
6008 self.tcp_port_out = 10505
6009 self.nat44_add_address(self.nat_addr)
6010 flags = self.config_flags.NAT_IS_TWICE_NAT
6011 self.nat44_add_static_mapping(self.pg0.remote_ip4,
6015 proto=IP_PROTOS.tcp,
6017 flags = self.config_flags.NAT_IS_INSIDE
6018 self.vapi.nat44_interface_add_del_feature(
6019 sw_if_index=self.pg0.sw_if_index,
6020 flags=flags, is_add=1)
6021 self.vapi.nat44_interface_add_del_feature(
6022 sw_if_index=self.pg1.sw_if_index,
6025 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4n, 0)
6026 start_sessnum = len(sessions)
6028 self.initiate_tcp_session(self.pg0, self.pg1)
6030 # FIN packet out -> in
6031 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
6032 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
6033 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
6034 flags="FA", seq=100, ack=300))
6035 self.pg1.add_stream(p)
6036 self.pg_enable_capture(self.pg_interfaces)
6038 self.pg0.get_capture(1)
6040 # FIN+ACK packet in -> out
6041 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6042 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6043 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
6044 flags="FA", seq=300, ack=101))
6046 self.pg0.add_stream(p)
6047 self.pg_enable_capture(self.pg_interfaces)
6049 self.pg1.get_capture(1)
6051 # ACK packet out -> in
6052 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
6053 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
6054 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
6055 flags="A", seq=101, ack=301))
6056 self.pg1.add_stream(p)
6057 self.pg_enable_capture(self.pg_interfaces)
6059 self.pg0.get_capture(1)
6061 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4n,
6063 self.assertEqual(len(sessions) - start_sessnum, 0)
6065 def test_tcp_session_close_simultaneous(self):
6066 """ Close TCP session from inside network """
6067 self.tcp_port_out = 10505
6068 self.nat44_add_address(self.nat_addr)
6069 flags = self.config_flags.NAT_IS_TWICE_NAT
6070 self.nat44_add_static_mapping(self.pg0.remote_ip4,
6074 proto=IP_PROTOS.tcp,
6076 flags = self.config_flags.NAT_IS_INSIDE
6077 self.vapi.nat44_interface_add_del_feature(
6078 sw_if_index=self.pg0.sw_if_index,
6079 flags=flags, is_add=1)
6080 self.vapi.nat44_interface_add_del_feature(
6081 sw_if_index=self.pg1.sw_if_index,
6084 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4n, 0)
6085 start_sessnum = len(sessions)
6087 self.initiate_tcp_session(self.pg0, self.pg1)
6089 # FIN packet in -> out
6090 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6091 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6092 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
6093 flags="FA", seq=100, ack=300))
6094 self.pg0.add_stream(p)
6095 self.pg_enable_capture(self.pg_interfaces)
6097 self.pg1.get_capture(1)
6099 # FIN packet out -> in
6100 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
6101 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
6102 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
6103 flags="FA", seq=300, ack=100))
6104 self.pg1.add_stream(p)
6105 self.pg_enable_capture(self.pg_interfaces)
6107 self.pg0.get_capture(1)
6109 # ACK packet in -> out
6110 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6111 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6112 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
6113 flags="A", seq=101, ack=301))
6114 self.pg0.add_stream(p)
6115 self.pg_enable_capture(self.pg_interfaces)
6117 self.pg1.get_capture(1)
6119 # ACK packet out -> in
6120 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
6121 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
6122 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
6123 flags="A", seq=301, ack=101))
6124 self.pg1.add_stream(p)
6125 self.pg_enable_capture(self.pg_interfaces)
6127 self.pg0.get_capture(1)
6129 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4n,
6131 self.assertEqual(len(sessions) - start_sessnum, 0)
6133 def test_one_armed_nat44_static(self):
6134 """ One armed NAT44 and 1:1 NAPT asymmetrical rule """
6135 remote_host = self.pg4.remote_hosts[0]
6136 local_host = self.pg4.remote_hosts[1]
6141 self.vapi.nat44_forwarding_enable_disable(enable=1)
6142 self.nat44_add_address(self.nat_addr, twice_nat=1)
6143 flags = (self.config_flags.NAT_IS_OUT2IN_ONLY |
6144 self.config_flags.NAT_IS_TWICE_NAT)
6145 self.nat44_add_static_mapping(local_host.ip4, self.nat_addr,
6146 local_port, external_port,
6147 proto=IP_PROTOS.tcp, flags=flags)
6148 flags = self.config_flags.NAT_IS_INSIDE
6149 self.vapi.nat44_interface_add_del_feature(
6150 sw_if_index=self.pg4.sw_if_index,
6152 self.vapi.nat44_interface_add_del_feature(
6153 sw_if_index=self.pg4.sw_if_index,
6154 flags=flags, is_add=1)
6156 # from client to service
6157 p = (Ether(src=self.pg4.remote_mac, dst=self.pg4.local_mac) /
6158 IP(src=remote_host.ip4, dst=self.nat_addr) /
6159 TCP(sport=12345, dport=external_port))
6160 self.pg4.add_stream(p)
6161 self.pg_enable_capture(self.pg_interfaces)
6163 capture = self.pg4.get_capture(1)
6168 self.assertEqual(ip.dst, local_host.ip4)
6169 self.assertEqual(ip.src, self.nat_addr)
6170 self.assertEqual(tcp.dport, local_port)
6171 self.assertNotEqual(tcp.sport, 12345)
6172 eh_port_in = tcp.sport
6173 self.assert_packet_checksums_valid(p)
6175 self.logger.error(ppp("Unexpected or invalid packet:", p))
6178 # from service back to client
6179 p = (Ether(src=self.pg4.remote_mac, dst=self.pg4.local_mac) /
6180 IP(src=local_host.ip4, dst=self.nat_addr) /
6181 TCP(sport=local_port, dport=eh_port_in))
6182 self.pg4.add_stream(p)
6183 self.pg_enable_capture(self.pg_interfaces)
6185 capture = self.pg4.get_capture(1)
6190 self.assertEqual(ip.src, self.nat_addr)
6191 self.assertEqual(ip.dst, remote_host.ip4)
6192 self.assertEqual(tcp.sport, external_port)
6193 self.assertEqual(tcp.dport, 12345)
6194 self.assert_packet_checksums_valid(p)
6196 self.logger.error(ppp("Unexpected or invalid packet:", p))
6199 def test_static_with_port_out2(self):
6200 """ 1:1 NAPT asymmetrical rule """
6205 self.vapi.nat44_forwarding_enable_disable(enable=1)
6206 flags = self.config_flags.NAT_IS_OUT2IN_ONLY
6207 self.nat44_add_static_mapping(self.pg0.remote_ip4, self.nat_addr,
6208 local_port, external_port,
6209 proto=IP_PROTOS.tcp, flags=flags)
6210 flags = self.config_flags.NAT_IS_INSIDE
6211 self.vapi.nat44_interface_add_del_feature(
6212 sw_if_index=self.pg0.sw_if_index,
6213 flags=flags, is_add=1)
6214 self.vapi.nat44_interface_add_del_feature(
6215 sw_if_index=self.pg1.sw_if_index,
6218 # from client to service
6219 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
6220 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
6221 TCP(sport=12345, dport=external_port))
6222 self.pg1.add_stream(p)
6223 self.pg_enable_capture(self.pg_interfaces)
6225 capture = self.pg0.get_capture(1)
6230 self.assertEqual(ip.dst, self.pg0.remote_ip4)
6231 self.assertEqual(tcp.dport, local_port)
6232 self.assert_packet_checksums_valid(p)
6234 self.logger.error(ppp("Unexpected or invalid packet:", p))
6238 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
6239 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6240 ICMP(type=11) / capture[0][IP])
6241 self.pg0.add_stream(p)
6242 self.pg_enable_capture(self.pg_interfaces)
6244 capture = self.pg1.get_capture(1)
6247 self.assertEqual(p[IP].src, self.nat_addr)
6249 self.assertEqual(inner.dst, self.nat_addr)
6250 self.assertEqual(inner[TCPerror].dport, external_port)
6252 self.logger.error(ppp("Unexpected or invalid packet:", p))
6255 # from service back to client
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=local_port, dport=12345))
6259 self.pg0.add_stream(p)
6260 self.pg_enable_capture(self.pg_interfaces)
6262 capture = self.pg1.get_capture(1)
6267 self.assertEqual(ip.src, self.nat_addr)
6268 self.assertEqual(tcp.sport, external_port)
6269 self.assert_packet_checksums_valid(p)
6271 self.logger.error(ppp("Unexpected or invalid packet:", p))
6275 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
6276 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
6277 ICMP(type=11) / capture[0][IP])
6278 self.pg1.add_stream(p)
6279 self.pg_enable_capture(self.pg_interfaces)
6281 capture = self.pg0.get_capture(1)
6284 self.assertEqual(p[IP].dst, self.pg0.remote_ip4)
6286 self.assertEqual(inner.src, self.pg0.remote_ip4)
6287 self.assertEqual(inner[TCPerror].sport, local_port)
6289 self.logger.error(ppp("Unexpected or invalid packet:", p))
6292 # from client to server (no translation)
6293 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
6294 IP(src=self.pg1.remote_ip4, dst=self.pg0.remote_ip4) /
6295 TCP(sport=12346, dport=local_port))
6296 self.pg1.add_stream(p)
6297 self.pg_enable_capture(self.pg_interfaces)
6299 capture = self.pg0.get_capture(1)
6304 self.assertEqual(ip.dst, self.pg0.remote_ip4)
6305 self.assertEqual(tcp.dport, local_port)
6306 self.assert_packet_checksums_valid(p)
6308 self.logger.error(ppp("Unexpected or invalid packet:", p))
6311 # from service back to client (no translation)
6312 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6313 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6314 TCP(sport=local_port, dport=12346))
6315 self.pg0.add_stream(p)
6316 self.pg_enable_capture(self.pg_interfaces)
6318 capture = self.pg1.get_capture(1)
6323 self.assertEqual(ip.src, self.pg0.remote_ip4)
6324 self.assertEqual(tcp.sport, local_port)
6325 self.assert_packet_checksums_valid(p)
6327 self.logger.error(ppp("Unexpected or invalid packet:", p))
6330 def test_output_feature(self):
6331 """ NAT44 interface output feature (in2out postrouting) """
6332 self.vapi.nat44_forwarding_enable_disable(enable=1)
6333 self.nat44_add_address(self.nat_addr)
6334 self.vapi.nat44_interface_add_del_feature(
6335 sw_if_index=self.pg0.sw_if_index,
6337 self.vapi.nat44_interface_add_del_output_feature(
6339 sw_if_index=self.pg1.sw_if_index)
6342 pkts = self.create_stream_in(self.pg0, self.pg1)
6343 self.pg0.add_stream(pkts)
6344 self.pg_enable_capture(self.pg_interfaces)
6346 capture = self.pg1.get_capture(len(pkts))
6347 self.verify_capture_out(capture)
6350 pkts = self.create_stream_out(self.pg1)
6351 self.pg1.add_stream(pkts)
6352 self.pg_enable_capture(self.pg_interfaces)
6354 capture = self.pg0.get_capture(len(pkts))
6355 self.verify_capture_in(capture, self.pg0)
6357 def test_multiple_vrf(self):
6358 """ Multiple VRF setup """
6359 external_addr = '1.2.3.4'
6364 self.vapi.nat44_forwarding_enable_disable(enable=1)
6365 self.nat44_add_address(self.nat_addr)
6366 flags = self.config_flags.NAT_IS_INSIDE
6367 self.vapi.nat44_interface_add_del_feature(
6368 sw_if_index=self.pg0.sw_if_index,
6370 self.vapi.nat44_interface_add_del_feature(
6371 sw_if_index=self.pg0.sw_if_index,
6372 flags=flags, is_add=1)
6373 self.vapi.nat44_interface_add_del_output_feature(
6375 sw_if_index=self.pg1.sw_if_index)
6376 self.vapi.nat44_interface_add_del_feature(
6377 sw_if_index=self.pg5.sw_if_index,
6379 self.vapi.nat44_interface_add_del_feature(
6380 sw_if_index=self.pg5.sw_if_index,
6381 flags=flags, is_add=1)
6382 self.vapi.nat44_interface_add_del_feature(
6383 sw_if_index=self.pg6.sw_if_index,
6385 flags = self.config_flags.NAT_IS_OUT2IN_ONLY
6386 self.nat44_add_static_mapping(self.pg5.remote_ip4, external_addr,
6387 local_port, external_port, vrf_id=1,
6388 proto=IP_PROTOS.tcp, flags=flags)
6389 self.nat44_add_static_mapping(
6390 self.pg0.remote_ip4,
6391 external_sw_if_index=self.pg0.sw_if_index,
6392 local_port=local_port,
6394 external_port=external_port,
6395 proto=IP_PROTOS.tcp,
6399 # from client to service (both VRF1)
6400 p = (Ether(src=self.pg6.remote_mac, dst=self.pg6.local_mac) /
6401 IP(src=self.pg6.remote_ip4, dst=external_addr) /
6402 TCP(sport=12345, dport=external_port))
6403 self.pg6.add_stream(p)
6404 self.pg_enable_capture(self.pg_interfaces)
6406 capture = self.pg5.get_capture(1)
6411 self.assertEqual(ip.dst, self.pg5.remote_ip4)
6412 self.assertEqual(tcp.dport, local_port)
6413 self.assert_packet_checksums_valid(p)
6415 self.logger.error(ppp("Unexpected or invalid packet:", p))
6418 # from service back to client (both VRF1)
6419 p = (Ether(src=self.pg5.remote_mac, dst=self.pg5.local_mac) /
6420 IP(src=self.pg5.remote_ip4, dst=self.pg6.remote_ip4) /
6421 TCP(sport=local_port, dport=12345))
6422 self.pg5.add_stream(p)
6423 self.pg_enable_capture(self.pg_interfaces)
6425 capture = self.pg6.get_capture(1)
6430 self.assertEqual(ip.src, external_addr)
6431 self.assertEqual(tcp.sport, external_port)
6432 self.assert_packet_checksums_valid(p)
6434 self.logger.error(ppp("Unexpected or invalid packet:", p))
6437 # dynamic NAT from VRF1 to VRF0 (output-feature)
6438 p = (Ether(src=self.pg5.remote_mac, dst=self.pg5.local_mac) /
6439 IP(src=self.pg5.remote_ip4, dst=self.pg1.remote_ip4) /
6440 TCP(sport=2345, dport=22))
6441 self.pg5.add_stream(p)
6442 self.pg_enable_capture(self.pg_interfaces)
6444 capture = self.pg1.get_capture(1)
6449 self.assertEqual(ip.src, self.nat_addr)
6450 self.assertNotEqual(tcp.sport, 2345)
6451 self.assert_packet_checksums_valid(p)
6454 self.logger.error(ppp("Unexpected or invalid packet:", p))
6457 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
6458 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
6459 TCP(sport=22, dport=port))
6460 self.pg1.add_stream(p)
6461 self.pg_enable_capture(self.pg_interfaces)
6463 capture = self.pg5.get_capture(1)
6468 self.assertEqual(ip.dst, self.pg5.remote_ip4)
6469 self.assertEqual(tcp.dport, 2345)
6470 self.assert_packet_checksums_valid(p)
6472 self.logger.error(ppp("Unexpected or invalid packet:", p))
6475 # from client VRF1 to service VRF0
6476 p = (Ether(src=self.pg6.remote_mac, dst=self.pg6.local_mac) /
6477 IP(src=self.pg6.remote_ip4, dst=self.pg0.local_ip4) /
6478 TCP(sport=12346, dport=external_port))
6479 self.pg6.add_stream(p)
6480 self.pg_enable_capture(self.pg_interfaces)
6482 capture = self.pg0.get_capture(1)
6487 self.assertEqual(ip.dst, self.pg0.remote_ip4)
6488 self.assertEqual(tcp.dport, local_port)
6489 self.assert_packet_checksums_valid(p)
6491 self.logger.error(ppp("Unexpected or invalid packet:", p))
6494 # from service VRF0 back to client VRF1
6495 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6496 IP(src=self.pg0.remote_ip4, dst=self.pg6.remote_ip4) /
6497 TCP(sport=local_port, dport=12346))
6498 self.pg0.add_stream(p)
6499 self.pg_enable_capture(self.pg_interfaces)
6501 capture = self.pg6.get_capture(1)
6506 self.assertEqual(ip.src, self.pg0.local_ip4)
6507 self.assertEqual(tcp.sport, external_port)
6508 self.assert_packet_checksums_valid(p)
6510 self.logger.error(ppp("Unexpected or invalid packet:", p))
6513 # from client VRF0 to service VRF1
6514 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6515 IP(src=self.pg0.remote_ip4, dst=external_addr) /
6516 TCP(sport=12347, dport=external_port))
6517 self.pg0.add_stream(p)
6518 self.pg_enable_capture(self.pg_interfaces)
6520 capture = self.pg5.get_capture(1)
6525 self.assertEqual(ip.dst, self.pg5.remote_ip4)
6526 self.assertEqual(tcp.dport, local_port)
6527 self.assert_packet_checksums_valid(p)
6529 self.logger.error(ppp("Unexpected or invalid packet:", p))
6532 # from service VRF1 back to client VRF0
6533 p = (Ether(src=self.pg5.remote_mac, dst=self.pg5.local_mac) /
6534 IP(src=self.pg5.remote_ip4, dst=self.pg0.remote_ip4) /
6535 TCP(sport=local_port, dport=12347))
6536 self.pg5.add_stream(p)
6537 self.pg_enable_capture(self.pg_interfaces)
6539 capture = self.pg0.get_capture(1)
6544 self.assertEqual(ip.src, external_addr)
6545 self.assertEqual(tcp.sport, external_port)
6546 self.assert_packet_checksums_valid(p)
6548 self.logger.error(ppp("Unexpected or invalid packet:", p))
6551 # from client to server (both VRF1, no translation)
6552 p = (Ether(src=self.pg6.remote_mac, dst=self.pg6.local_mac) /
6553 IP(src=self.pg6.remote_ip4, dst=self.pg5.remote_ip4) /
6554 TCP(sport=12348, dport=local_port))
6555 self.pg6.add_stream(p)
6556 self.pg_enable_capture(self.pg_interfaces)
6558 capture = self.pg5.get_capture(1)
6563 self.assertEqual(ip.dst, self.pg5.remote_ip4)
6564 self.assertEqual(tcp.dport, local_port)
6565 self.assert_packet_checksums_valid(p)
6567 self.logger.error(ppp("Unexpected or invalid packet:", p))
6570 # from server back to client (both VRF1, no translation)
6571 p = (Ether(src=self.pg5.remote_mac, dst=self.pg5.local_mac) /
6572 IP(src=self.pg5.remote_ip4, dst=self.pg6.remote_ip4) /
6573 TCP(sport=local_port, dport=12348))
6574 self.pg5.add_stream(p)
6575 self.pg_enable_capture(self.pg_interfaces)
6577 capture = self.pg6.get_capture(1)
6582 self.assertEqual(ip.src, self.pg5.remote_ip4)
6583 self.assertEqual(tcp.sport, local_port)
6584 self.assert_packet_checksums_valid(p)
6586 self.logger.error(ppp("Unexpected or invalid packet:", p))
6589 # from client VRF1 to server VRF0 (no translation)
6590 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6591 IP(src=self.pg0.remote_ip4, dst=self.pg6.remote_ip4) /
6592 TCP(sport=local_port, dport=12349))
6593 self.pg0.add_stream(p)
6594 self.pg_enable_capture(self.pg_interfaces)
6596 capture = self.pg6.get_capture(1)
6601 self.assertEqual(ip.src, self.pg0.remote_ip4)
6602 self.assertEqual(tcp.sport, local_port)
6603 self.assert_packet_checksums_valid(p)
6605 self.logger.error(ppp("Unexpected or invalid packet:", p))
6608 # from server VRF0 back to client VRF1 (no translation)
6609 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6610 IP(src=self.pg0.remote_ip4, dst=self.pg6.remote_ip4) /
6611 TCP(sport=local_port, dport=12349))
6612 self.pg0.add_stream(p)
6613 self.pg_enable_capture(self.pg_interfaces)
6615 capture = self.pg6.get_capture(1)
6620 self.assertEqual(ip.src, self.pg0.remote_ip4)
6621 self.assertEqual(tcp.sport, local_port)
6622 self.assert_packet_checksums_valid(p)
6624 self.logger.error(ppp("Unexpected or invalid packet:", p))
6627 # from client VRF0 to server VRF1 (no translation)
6628 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6629 IP(src=self.pg0.remote_ip4, dst=self.pg5.remote_ip4) /
6630 TCP(sport=12344, dport=local_port))
6631 self.pg0.add_stream(p)
6632 self.pg_enable_capture(self.pg_interfaces)
6634 capture = self.pg5.get_capture(1)
6639 self.assertEqual(ip.dst, self.pg5.remote_ip4)
6640 self.assertEqual(tcp.dport, local_port)
6641 self.assert_packet_checksums_valid(p)
6643 self.logger.error(ppp("Unexpected or invalid packet:", p))
6646 # from server VRF1 back to client VRF0 (no translation)
6647 p = (Ether(src=self.pg5.remote_mac, dst=self.pg5.local_mac) /
6648 IP(src=self.pg5.remote_ip4, dst=self.pg0.remote_ip4) /
6649 TCP(sport=local_port, dport=12344))
6650 self.pg5.add_stream(p)
6651 self.pg_enable_capture(self.pg_interfaces)
6653 capture = self.pg0.get_capture(1)
6658 self.assertEqual(ip.src, self.pg5.remote_ip4)
6659 self.assertEqual(tcp.sport, local_port)
6660 self.assert_packet_checksums_valid(p)
6662 self.logger.error(ppp("Unexpected or invalid packet:", p))
6665 @unittest.skipUnless(running_extended_tests, "part of extended tests")
6666 def test_session_timeout(self):
6667 """ NAT44 session timeouts """
6668 self.nat44_add_address(self.nat_addr)
6669 flags = self.config_flags.NAT_IS_INSIDE
6670 self.vapi.nat44_interface_add_del_feature(
6671 sw_if_index=self.pg0.sw_if_index,
6672 flags=flags, is_add=1)
6673 self.vapi.nat44_interface_add_del_feature(
6674 sw_if_index=self.pg1.sw_if_index,
6676 self.vapi.nat_set_timeouts(udp=300, tcp_established=7440,
6677 tcp_transitory=240, icmp=5)
6681 for i in range(0, max_sessions):
6682 src = "10.10.%u.%u" % ((i & 0xFF00) >> 8, i & 0xFF)
6683 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
6684 IP(src=src, dst=self.pg1.remote_ip4) /
6685 ICMP(id=1025, type='echo-request'))
6687 self.pg0.add_stream(pkts)
6688 self.pg_enable_capture(self.pg_interfaces)
6690 self.pg1.get_capture(max_sessions)
6695 for i in range(0, max_sessions):
6696 src = "10.11.%u.%u" % ((i & 0xFF00) >> 8, i & 0xFF)
6697 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
6698 IP(src=src, dst=self.pg1.remote_ip4) /
6699 ICMP(id=1026, type='echo-request'))
6701 self.pg0.add_stream(pkts)
6702 self.pg_enable_capture(self.pg_interfaces)
6704 self.pg1.get_capture(max_sessions)
6707 users = self.vapi.nat44_user_dump()
6709 nsessions = nsessions + user.nsessions
6710 self.assertLess(nsessions, 2 * max_sessions)
6712 @unittest.skipUnless(running_extended_tests, "part of extended tests")
6713 def test_session_rst_timeout(self):
6714 """ NAT44 session RST timeouts """
6715 self.nat44_add_address(self.nat_addr)
6716 flags = self.config_flags.NAT_IS_INSIDE
6717 self.vapi.nat44_interface_add_del_feature(
6718 sw_if_index=self.pg0.sw_if_index,
6719 flags=flags, is_add=1)
6720 self.vapi.nat44_interface_add_del_feature(
6721 sw_if_index=self.pg1.sw_if_index,
6723 self.vapi.nat_set_timeouts(udp=300, tcp_established=7440,
6724 tcp_transitory=5, icmp=60)
6726 self.initiate_tcp_session(self.pg0, self.pg1)
6727 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6728 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6729 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
6731 self.pg0.add_stream(p)
6732 self.pg_enable_capture(self.pg_interfaces)
6734 self.pg1.get_capture(1)
6738 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6739 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6740 TCP(sport=self.tcp_port_in + 1, dport=self.tcp_external_port + 1,
6742 self.pg0.add_stream(p)
6743 self.pg_enable_capture(self.pg_interfaces)
6745 self.pg1.get_capture(1)
6748 users = self.vapi.nat44_user_dump()
6749 self.assertEqual(len(users), 1)
6750 self.assertEqual(str(users[0].ip_address),
6751 self.pg0.remote_ip4)
6752 self.assertEqual(users[0].nsessions, 1)
6754 @unittest.skipUnless(running_extended_tests, "part of extended tests")
6755 def test_session_limit_per_user(self):
6756 """ Maximum sessions per user limit """
6757 self.nat44_add_address(self.nat_addr)
6758 flags = self.config_flags.NAT_IS_INSIDE
6759 self.vapi.nat44_interface_add_del_feature(
6760 sw_if_index=self.pg0.sw_if_index,
6761 flags=flags, is_add=1)
6762 self.vapi.nat44_interface_add_del_feature(
6763 sw_if_index=self.pg1.sw_if_index,
6765 self.vapi.set_ipfix_exporter(collector_address=self.pg2.remote_ip4n,
6766 src_address=self.pg2.local_ip4n,
6768 template_interval=10)
6769 self.vapi.nat_set_timeouts(udp=5, tcp_established=7440,
6770 tcp_transitory=240, icmp=60)
6772 # get maximum number of translations per user
6773 nat44_config = self.vapi.nat_show_config()
6776 for port in range(0, nat44_config.max_translations_per_user):
6777 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6778 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6779 UDP(sport=1025 + port, dport=1025 + port))
6782 self.pg0.add_stream(pkts)
6783 self.pg_enable_capture(self.pg_interfaces)
6785 capture = self.pg1.get_capture(len(pkts))
6787 self.vapi.nat_ipfix_enable_disable(domain_id=self.ipfix_domain_id,
6788 src_port=self.ipfix_src_port,
6791 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6792 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6793 UDP(sport=3001, dport=3002))
6794 self.pg0.add_stream(p)
6795 self.pg_enable_capture(self.pg_interfaces)
6797 capture = self.pg1.assert_nothing_captured()
6799 # verify IPFIX logging
6800 self.vapi.ipfix_flush()
6802 capture = self.pg2.get_capture(10)
6803 ipfix = IPFIXDecoder()
6804 # first load template
6806 self.assertTrue(p.haslayer(IPFIX))
6807 if p.haslayer(Template):
6808 ipfix.add_template(p.getlayer(Template))
6809 # verify events in data set
6811 if p.haslayer(Data):
6812 data = ipfix.decode_data_set(p.getlayer(Set))
6813 self.verify_ipfix_max_entries_per_user(
6815 nat44_config.max_translations_per_user,
6816 self.pg0.remote_ip4n)
6819 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6820 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6821 UDP(sport=3001, dport=3002))
6822 self.pg0.add_stream(p)
6823 self.pg_enable_capture(self.pg_interfaces)
6825 self.pg1.get_capture(1)
6827 def test_syslog_sess(self):
6828 """ Test syslog session creation and deletion """
6829 self.vapi.syslog_set_filter(
6830 self.SYSLOG_SEVERITY.SYSLOG_API_SEVERITY_INFO)
6831 self.vapi.syslog_set_sender(self.pg2.local_ip4n, self.pg2.remote_ip4n)
6832 self.nat44_add_address(self.nat_addr)
6833 flags = self.config_flags.NAT_IS_INSIDE
6834 self.vapi.nat44_interface_add_del_feature(
6835 sw_if_index=self.pg0.sw_if_index,
6836 flags=flags, is_add=1)
6837 self.vapi.nat44_interface_add_del_feature(
6838 sw_if_index=self.pg1.sw_if_index,
6841 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
6842 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6843 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port))
6844 self.pg0.add_stream(p)
6845 self.pg_enable_capture(self.pg_interfaces)
6847 capture = self.pg1.get_capture(1)
6848 self.tcp_port_out = capture[0][TCP].sport
6849 capture = self.pg2.get_capture(1)
6850 self.verify_syslog_sess(capture[0][Raw].load)
6852 self.pg_enable_capture(self.pg_interfaces)
6854 self.nat44_add_address(self.nat_addr, is_add=0)
6855 capture = self.pg2.get_capture(1)
6856 self.verify_syslog_sess(capture[0][Raw].load, False)
6859 super(TestNAT44EndpointDependent, self).tearDown()
6860 if not self.vpp_dead:
6862 self.vapi.cli("clear logging")
6864 def show_commands_at_teardown(self):
6865 self.logger.info(self.vapi.cli("show nat44 addresses"))
6866 self.logger.info(self.vapi.cli("show nat44 interfaces"))
6867 self.logger.info(self.vapi.cli("show nat44 static mappings"))
6868 self.logger.info(self.vapi.cli("show nat44 interface address"))
6869 self.logger.info(self.vapi.cli("show nat44 sessions detail"))
6870 self.logger.info(self.vapi.cli("show nat44 hash tables detail"))
6871 self.logger.info(self.vapi.cli("show nat timeouts"))
6874 class TestNAT44Out2InDPO(MethodHolder):
6875 """ NAT44 Test Cases using out2in DPO """
6878 def setUpConstants(cls):
6879 super(TestNAT44Out2InDPO, cls).setUpConstants()
6880 cls.vpp_cmdline.extend(["nat", "{", "out2in dpo", "}"])
6883 def setUpClass(cls):
6884 super(TestNAT44Out2InDPO, cls).setUpClass()
6885 cls.vapi.cli("set log class nat level debug")
6888 cls.tcp_port_in = 6303
6889 cls.tcp_port_out = 6303
6890 cls.udp_port_in = 6304
6891 cls.udp_port_out = 6304
6892 cls.icmp_id_in = 6305
6893 cls.icmp_id_out = 6305
6894 cls.nat_addr = '10.0.0.3'
6895 cls.dst_ip4 = '192.168.70.1'
6897 cls.create_pg_interfaces(range(2))
6900 cls.pg0.config_ip4()
6901 cls.pg0.resolve_arp()
6904 cls.pg1.config_ip6()
6905 cls.pg1.resolve_ndp()
6907 r1 = VppIpRoute(cls, "::", 0,
6908 [VppRoutePath(cls.pg1.remote_ip6,
6909 cls.pg1.sw_if_index)],
6914 super(TestNAT44Out2InDPO, cls).tearDownClass()
6918 def tearDownClass(cls):
6919 super(TestNAT44Out2InDPO, cls).tearDownClass()
6921 def configure_xlat(self):
6922 self.dst_ip6_pfx = '1:2:3::'
6923 self.dst_ip6_pfx_n = socket.inet_pton(socket.AF_INET6,
6925 self.dst_ip6_pfx_len = 96
6926 self.src_ip6_pfx = '4:5:6::'
6927 self.src_ip6_pfx_n = socket.inet_pton(socket.AF_INET6,
6929 self.src_ip6_pfx_len = 96
6930 self.vapi.map_add_domain(self.dst_ip6_pfx_n, self.dst_ip6_pfx_len,
6931 self.src_ip6_pfx_n, self.src_ip6_pfx_len,
6932 '\x00\x00\x00\x00', 0)
6934 @unittest.skip('Temporary disabled')
6935 def test_464xlat_ce(self):
6936 """ Test 464XLAT CE with NAT44 """
6938 nat_config = self.vapi.nat_show_config()
6939 self.assertEqual(1, nat_config.out2in_dpo)
6941 self.configure_xlat()
6943 flags = self.config_flags.NAT_IS_INSIDE
6944 self.vapi.nat44_interface_add_del_feature(
6945 sw_if_index=self.pg0.sw_if_index,
6946 flags=flags, is_add=1)
6947 self.vapi.nat44_add_del_address_range(first_ip_address=self.nat_addr_n,
6948 last_ip_address=self.nat_addr_n,
6949 vrf_id=0xFFFFFFFF, is_add=1)
6951 out_src_ip6 = self.compose_ip6(self.dst_ip4, self.dst_ip6_pfx,
6952 self.dst_ip6_pfx_len)
6953 out_dst_ip6 = self.compose_ip6(self.nat_addr, self.src_ip6_pfx,
6954 self.src_ip6_pfx_len)
6957 pkts = self.create_stream_in(self.pg0, self.pg1, self.dst_ip4)
6958 self.pg0.add_stream(pkts)
6959 self.pg_enable_capture(self.pg_interfaces)
6961 capture = self.pg1.get_capture(len(pkts))
6962 self.verify_capture_out_ip6(capture, nat_ip=out_dst_ip6,
6965 pkts = self.create_stream_out_ip6(self.pg1, out_src_ip6,
6967 self.pg1.add_stream(pkts)
6968 self.pg_enable_capture(self.pg_interfaces)
6970 capture = self.pg0.get_capture(len(pkts))
6971 self.verify_capture_in(capture, self.pg0)
6973 self.vapi.nat44_interface_add_del_feature(
6974 sw_if_index=self.pg0.sw_if_index,
6976 self.vapi.nat44_add_del_address_range(
6977 first_ip_address=self.nat_addr_n,
6978 last_ip_address=self.nat_addr_n,
6981 @unittest.skip('Temporary disabled')
6982 def test_464xlat_ce_no_nat(self):
6983 """ Test 464XLAT CE without NAT44 """
6985 self.configure_xlat()
6987 out_src_ip6 = self.compose_ip6(self.dst_ip4, self.dst_ip6_pfx,
6988 self.dst_ip6_pfx_len)
6989 out_dst_ip6 = self.compose_ip6(self.pg0.remote_ip4, self.src_ip6_pfx,
6990 self.src_ip6_pfx_len)
6992 pkts = self.create_stream_in(self.pg0, self.pg1, self.dst_ip4)
6993 self.pg0.add_stream(pkts)
6994 self.pg_enable_capture(self.pg_interfaces)
6996 capture = self.pg1.get_capture(len(pkts))
6997 self.verify_capture_out_ip6(capture, dst_ip=out_src_ip6,
6998 nat_ip=out_dst_ip6, same_port=True)
7000 pkts = self.create_stream_out_ip6(self.pg1, out_src_ip6, out_dst_ip6)
7001 self.pg1.add_stream(pkts)
7002 self.pg_enable_capture(self.pg_interfaces)
7004 capture = self.pg0.get_capture(len(pkts))
7005 self.verify_capture_in(capture, self.pg0)
7008 class TestDeterministicNAT(MethodHolder):
7009 """ Deterministic NAT Test Cases """
7012 def setUpConstants(cls):
7013 super(TestDeterministicNAT, cls).setUpConstants()
7014 cls.vpp_cmdline.extend(["nat", "{", "deterministic", "}"])
7017 def setUpClass(cls):
7018 super(TestDeterministicNAT, cls).setUpClass()
7019 cls.vapi.cli("set log class nat level debug")
7022 cls.tcp_port_in = 6303
7023 cls.tcp_external_port = 6303
7024 cls.udp_port_in = 6304
7025 cls.udp_external_port = 6304
7026 cls.icmp_id_in = 6305
7027 cls.nat_addr = '10.0.0.3'
7029 cls.create_pg_interfaces(range(3))
7030 cls.interfaces = list(cls.pg_interfaces)
7032 for i in cls.interfaces:
7037 cls.pg0.generate_remote_hosts(2)
7038 cls.pg0.configure_ipv4_neighbors()
7041 super(TestDeterministicNAT, cls).tearDownClass()
7045 def tearDownClass(cls):
7046 super(TestDeterministicNAT, cls).tearDownClass()
7048 def create_stream_in(self, in_if, out_if, ttl=64):
7050 Create packet stream for inside network
7052 :param in_if: Inside interface
7053 :param out_if: Outside interface
7054 :param ttl: TTL of generated packets
7058 p = (Ether(dst=in_if.local_mac, src=in_if.remote_mac) /
7059 IP(src=in_if.remote_ip4, dst=out_if.remote_ip4, ttl=ttl) /
7060 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port))
7064 p = (Ether(dst=in_if.local_mac, src=in_if.remote_mac) /
7065 IP(src=in_if.remote_ip4, dst=out_if.remote_ip4, ttl=ttl) /
7066 UDP(sport=self.udp_port_in, dport=self.udp_external_port))
7070 p = (Ether(dst=in_if.local_mac, src=in_if.remote_mac) /
7071 IP(src=in_if.remote_ip4, dst=out_if.remote_ip4, ttl=ttl) /
7072 ICMP(id=self.icmp_id_in, type='echo-request'))
7077 def create_stream_out(self, out_if, dst_ip=None, ttl=64):
7079 Create packet stream for outside network
7081 :param out_if: Outside interface
7082 :param dst_ip: Destination IP address (Default use global NAT address)
7083 :param ttl: TTL of generated packets
7086 dst_ip = self.nat_addr
7089 p = (Ether(dst=out_if.local_mac, src=out_if.remote_mac) /
7090 IP(src=out_if.remote_ip4, dst=dst_ip, ttl=ttl) /
7091 TCP(dport=self.tcp_port_out, sport=self.tcp_external_port))
7095 p = (Ether(dst=out_if.local_mac, src=out_if.remote_mac) /
7096 IP(src=out_if.remote_ip4, dst=dst_ip, ttl=ttl) /
7097 UDP(dport=self.udp_port_out, sport=self.udp_external_port))
7101 p = (Ether(dst=out_if.local_mac, src=out_if.remote_mac) /
7102 IP(src=out_if.remote_ip4, dst=dst_ip, ttl=ttl) /
7103 ICMP(id=self.icmp_external_id, type='echo-reply'))
7108 def verify_capture_out(self, capture, nat_ip=None):
7110 Verify captured packets on outside network
7112 :param capture: Captured packets
7113 :param nat_ip: Translated IP address (Default use global NAT address)
7114 :param same_port: Source port number is not translated (Default False)
7117 nat_ip = self.nat_addr
7118 for packet in capture:
7120 self.assertEqual(packet[IP].src, nat_ip)
7121 if packet.haslayer(TCP):
7122 self.tcp_port_out = packet[TCP].sport
7123 elif packet.haslayer(UDP):
7124 self.udp_port_out = packet[UDP].sport
7126 self.icmp_external_id = packet[ICMP].id
7128 self.logger.error(ppp("Unexpected or invalid packet "
7129 "(outside network):", packet))
7132 def test_deterministic_mode(self):
7133 """ NAT plugin run deterministic mode """
7134 in_addr = '172.16.255.0'
7135 out_addr = '172.17.255.50'
7136 in_addr_t = '172.16.255.20'
7140 nat_config = self.vapi.nat_show_config()
7141 self.assertEqual(1, nat_config.deterministic)
7143 self.vapi.nat_det_add_del_map(is_add=1, in_addr=in_addr,
7144 in_plen=in_plen, out_addr=out_addr,
7147 rep1 = self.vapi.nat_det_forward(in_addr_t)
7148 self.assertEqual(str(rep1.out_addr), out_addr)
7149 rep2 = self.vapi.nat_det_reverse(rep1.out_port_hi, out_addr)
7151 self.assertEqual(str(rep2.in_addr), in_addr_t)
7153 deterministic_mappings = self.vapi.nat_det_map_dump()
7154 self.assertEqual(len(deterministic_mappings), 1)
7155 dsm = deterministic_mappings[0]
7156 self.assertEqual(in_addr, str(dsm.in_addr))
7157 self.assertEqual(in_plen, dsm.in_plen)
7158 self.assertEqual(out_addr, str(dsm.out_addr))
7159 self.assertEqual(out_plen, dsm.out_plen)
7161 self.clear_nat_det()
7162 deterministic_mappings = self.vapi.nat_det_map_dump()
7163 self.assertEqual(len(deterministic_mappings), 0)
7165 def test_set_timeouts(self):
7166 """ Set deterministic NAT timeouts """
7167 timeouts_before = self.vapi.nat_get_timeouts()
7169 self.vapi.nat_set_timeouts(
7170 udp=timeouts_before.udp + 10,
7171 tcp_established=timeouts_before.tcp_established + 10,
7172 tcp_transitory=timeouts_before.tcp_transitory + 10,
7173 icmp=timeouts_before.icmp + 10)
7175 timeouts_after = self.vapi.nat_get_timeouts()
7177 self.assertNotEqual(timeouts_before.udp, timeouts_after.udp)
7178 self.assertNotEqual(timeouts_before.icmp, timeouts_after.icmp)
7179 self.assertNotEqual(timeouts_before.tcp_established,
7180 timeouts_after.tcp_established)
7181 self.assertNotEqual(timeouts_before.tcp_transitory,
7182 timeouts_after.tcp_transitory)
7184 def test_det_in(self):
7185 """ Deterministic NAT translation test (TCP, UDP, ICMP) """
7187 nat_ip = "10.0.0.10"
7189 self.vapi.nat_det_add_del_map(is_add=1, in_addr=self.pg0.remote_ip4n,
7191 out_addr=socket.inet_aton(nat_ip),
7194 flags = self.config_flags.NAT_IS_INSIDE
7195 self.vapi.nat44_interface_add_del_feature(
7196 sw_if_index=self.pg0.sw_if_index,
7197 flags=flags, is_add=1)
7198 self.vapi.nat44_interface_add_del_feature(
7199 sw_if_index=self.pg1.sw_if_index,
7203 pkts = self.create_stream_in(self.pg0, self.pg1)
7204 self.pg0.add_stream(pkts)
7205 self.pg_enable_capture(self.pg_interfaces)
7207 capture = self.pg1.get_capture(len(pkts))
7208 self.verify_capture_out(capture, nat_ip)
7211 pkts = self.create_stream_out(self.pg1, nat_ip)
7212 self.pg1.add_stream(pkts)
7213 self.pg_enable_capture(self.pg_interfaces)
7215 capture = self.pg0.get_capture(len(pkts))
7216 self.verify_capture_in(capture, self.pg0)
7219 sessions = self.vapi.nat_det_session_dump(self.pg0.remote_ip4n)
7220 self.assertEqual(len(sessions), 3)
7224 self.assertEqual(str(s.ext_addr), self.pg1.remote_ip4)
7225 self.assertEqual(s.in_port, self.tcp_port_in)
7226 self.assertEqual(s.out_port, self.tcp_port_out)
7227 self.assertEqual(s.ext_port, self.tcp_external_port)
7231 self.assertEqual(str(s.ext_addr), self.pg1.remote_ip4)
7232 self.assertEqual(s.in_port, self.udp_port_in)
7233 self.assertEqual(s.out_port, self.udp_port_out)
7234 self.assertEqual(s.ext_port, self.udp_external_port)
7238 self.assertEqual(str(s.ext_addr), self.pg1.remote_ip4)
7239 self.assertEqual(s.in_port, self.icmp_id_in)
7240 self.assertEqual(s.out_port, self.icmp_external_id)
7242 def test_multiple_users(self):
7243 """ Deterministic NAT multiple users """
7245 nat_ip = "10.0.0.10"
7247 external_port = 6303
7249 host0 = self.pg0.remote_hosts[0]
7250 host1 = self.pg0.remote_hosts[1]
7252 self.vapi.nat_det_add_del_map(is_add=1, in_addr=host0.ip4n, in_plen=24,
7253 out_addr=socket.inet_aton(nat_ip),
7255 flags = self.config_flags.NAT_IS_INSIDE
7256 self.vapi.nat44_interface_add_del_feature(
7257 sw_if_index=self.pg0.sw_if_index,
7258 flags=flags, is_add=1)
7259 self.vapi.nat44_interface_add_del_feature(
7260 sw_if_index=self.pg1.sw_if_index,
7264 p = (Ether(src=host0.mac, dst=self.pg0.local_mac) /
7265 IP(src=host0.ip4, dst=self.pg1.remote_ip4) /
7266 TCP(sport=port_in, dport=external_port))
7267 self.pg0.add_stream(p)
7268 self.pg_enable_capture(self.pg_interfaces)
7270 capture = self.pg1.get_capture(1)
7275 self.assertEqual(ip.src, nat_ip)
7276 self.assertEqual(ip.dst, self.pg1.remote_ip4)
7277 self.assertEqual(tcp.dport, external_port)
7278 port_out0 = tcp.sport
7280 self.logger.error(ppp("Unexpected or invalid packet:", p))
7284 p = (Ether(src=host1.mac, dst=self.pg0.local_mac) /
7285 IP(src=host1.ip4, dst=self.pg1.remote_ip4) /
7286 TCP(sport=port_in, dport=external_port))
7287 self.pg0.add_stream(p)
7288 self.pg_enable_capture(self.pg_interfaces)
7290 capture = self.pg1.get_capture(1)
7295 self.assertEqual(ip.src, nat_ip)
7296 self.assertEqual(ip.dst, self.pg1.remote_ip4)
7297 self.assertEqual(tcp.dport, external_port)
7298 port_out1 = tcp.sport
7300 self.logger.error(ppp("Unexpected or invalid packet:", p))
7303 dms = self.vapi.nat_det_map_dump()
7304 self.assertEqual(1, len(dms))
7305 self.assertEqual(2, dms[0].ses_num)
7308 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
7309 IP(src=self.pg1.remote_ip4, dst=nat_ip) /
7310 TCP(sport=external_port, dport=port_out0))
7311 self.pg1.add_stream(p)
7312 self.pg_enable_capture(self.pg_interfaces)
7314 capture = self.pg0.get_capture(1)
7319 self.assertEqual(ip.src, self.pg1.remote_ip4)
7320 self.assertEqual(ip.dst, host0.ip4)
7321 self.assertEqual(tcp.dport, port_in)
7322 self.assertEqual(tcp.sport, external_port)
7324 self.logger.error(ppp("Unexpected or invalid packet:", p))
7328 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
7329 IP(src=self.pg1.remote_ip4, dst=nat_ip) /
7330 TCP(sport=external_port, dport=port_out1))
7331 self.pg1.add_stream(p)
7332 self.pg_enable_capture(self.pg_interfaces)
7334 capture = self.pg0.get_capture(1)
7339 self.assertEqual(ip.src, self.pg1.remote_ip4)
7340 self.assertEqual(ip.dst, host1.ip4)
7341 self.assertEqual(tcp.dport, port_in)
7342 self.assertEqual(tcp.sport, external_port)
7344 self.logger.error(ppp("Unexpected or invalid packet", p))
7347 # session close api test
7348 self.vapi.nat_det_close_session_out(socket.inet_aton(nat_ip),
7350 self.pg1.remote_ip4n,
7352 dms = self.vapi.nat_det_map_dump()
7353 self.assertEqual(dms[0].ses_num, 1)
7355 self.vapi.nat_det_close_session_in(host0.ip4n,
7357 self.pg1.remote_ip4n,
7359 dms = self.vapi.nat_det_map_dump()
7360 self.assertEqual(dms[0].ses_num, 0)
7362 def test_tcp_session_close_detection_in(self):
7363 """ Deterministic NAT TCP session close from inside network """
7364 self.vapi.nat_det_add_del_map(is_add=1, in_addr=self.pg0.remote_ip4n,
7366 out_addr=socket.inet_aton(self.nat_addr),
7368 flags = self.config_flags.NAT_IS_INSIDE
7369 self.vapi.nat44_interface_add_del_feature(
7370 sw_if_index=self.pg0.sw_if_index,
7371 flags=flags, is_add=1)
7372 self.vapi.nat44_interface_add_del_feature(
7373 sw_if_index=self.pg1.sw_if_index,
7376 self.initiate_tcp_session(self.pg0, self.pg1)
7378 # close the session from inside
7380 # FIN packet in -> out
7381 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
7382 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
7383 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
7385 self.pg0.add_stream(p)
7386 self.pg_enable_capture(self.pg_interfaces)
7388 self.pg1.get_capture(1)
7392 # ACK packet out -> in
7393 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
7394 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
7395 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
7399 # FIN packet out -> in
7400 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
7401 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
7402 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
7406 self.pg1.add_stream(pkts)
7407 self.pg_enable_capture(self.pg_interfaces)
7409 self.pg0.get_capture(2)
7411 # ACK packet in -> out
7412 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
7413 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
7414 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
7416 self.pg0.add_stream(p)
7417 self.pg_enable_capture(self.pg_interfaces)
7419 self.pg1.get_capture(1)
7421 # Check if deterministic NAT44 closed the session
7422 dms = self.vapi.nat_det_map_dump()
7423 self.assertEqual(0, dms[0].ses_num)
7425 self.logger.error("TCP session termination failed")
7428 def test_tcp_session_close_detection_out(self):
7429 """ Deterministic NAT TCP session close from outside network """
7430 self.vapi.nat_det_add_del_map(is_add=1, in_addr=self.pg0.remote_ip4n,
7432 out_addr=socket.inet_aton(self.nat_addr),
7434 flags = self.config_flags.NAT_IS_INSIDE
7435 self.vapi.nat44_interface_add_del_feature(
7436 sw_if_index=self.pg0.sw_if_index,
7437 flags=flags, is_add=1)
7438 self.vapi.nat44_interface_add_del_feature(
7439 sw_if_index=self.pg1.sw_if_index,
7442 self.initiate_tcp_session(self.pg0, self.pg1)
7444 # close the session from outside
7446 # FIN packet out -> in
7447 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
7448 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
7449 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
7451 self.pg1.add_stream(p)
7452 self.pg_enable_capture(self.pg_interfaces)
7454 self.pg0.get_capture(1)
7458 # ACK packet in -> out
7459 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
7460 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
7461 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
7465 # ACK packet in -> out
7466 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
7467 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
7468 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
7472 self.pg0.add_stream(pkts)
7473 self.pg_enable_capture(self.pg_interfaces)
7475 self.pg1.get_capture(2)
7477 # ACK packet out -> in
7478 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
7479 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
7480 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
7482 self.pg1.add_stream(p)
7483 self.pg_enable_capture(self.pg_interfaces)
7485 self.pg0.get_capture(1)
7487 # Check if deterministic NAT44 closed the session
7488 dms = self.vapi.nat_det_map_dump()
7489 self.assertEqual(0, dms[0].ses_num)
7491 self.logger.error("TCP session termination failed")
7494 @unittest.skipUnless(running_extended_tests, "part of extended tests")
7495 def test_session_timeout(self):
7496 """ Deterministic NAT session timeouts """
7497 self.vapi.nat_det_add_del_map(is_add=1, in_addr=self.pg0.remote_ip4n,
7499 out_addr=socket.inet_aton(self.nat_addr),
7501 flags = self.config_flags.NAT_IS_INSIDE
7502 self.vapi.nat44_interface_add_del_feature(
7503 sw_if_index=self.pg0.sw_if_index,
7504 flags=flags, is_add=1)
7505 self.vapi.nat44_interface_add_del_feature(
7506 sw_if_index=self.pg1.sw_if_index,
7509 self.initiate_tcp_session(self.pg0, self.pg1)
7510 self.vapi.nat_set_timeouts(udp=5, tcp_established=5, tcp_transitory=5,
7512 pkts = self.create_stream_in(self.pg0, self.pg1)
7513 self.pg0.add_stream(pkts)
7514 self.pg_enable_capture(self.pg_interfaces)
7516 capture = self.pg1.get_capture(len(pkts))
7519 dms = self.vapi.nat_det_map_dump()
7520 self.assertEqual(0, dms[0].ses_num)
7522 @unittest.skipUnless(running_extended_tests, "part of extended tests")
7523 def test_session_limit_per_user(self):
7524 """ Deterministic NAT maximum sessions per user limit """
7525 self.vapi.nat_det_add_del_map(is_add=1, in_addr=self.pg0.remote_ip4n,
7527 out_addr=socket.inet_aton(self.nat_addr),
7529 flags = self.config_flags.NAT_IS_INSIDE
7530 self.vapi.nat44_interface_add_del_feature(
7531 sw_if_index=self.pg0.sw_if_index,
7532 flags=flags, is_add=1)
7533 self.vapi.nat44_interface_add_del_feature(
7534 sw_if_index=self.pg1.sw_if_index,
7536 self.vapi.set_ipfix_exporter(collector_address=self.pg2.remote_ip4n,
7537 src_address=self.pg2.local_ip4n,
7539 template_interval=10)
7540 self.vapi.nat_ipfix_enable_disable(domain_id=1, src_port=4739,
7544 for port in range(1025, 2025):
7545 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
7546 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
7547 UDP(sport=port, dport=port))
7550 self.pg0.add_stream(pkts)
7551 self.pg_enable_capture(self.pg_interfaces)
7553 capture = self.pg1.get_capture(len(pkts))
7555 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
7556 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
7557 UDP(sport=3001, dport=3002))
7558 self.pg0.add_stream(p)
7559 self.pg_enable_capture(self.pg_interfaces)
7561 capture = self.pg1.assert_nothing_captured()
7563 # verify ICMP error packet
7564 capture = self.pg0.get_capture(1)
7566 self.assertTrue(p.haslayer(ICMP))
7568 self.assertEqual(icmp.type, 3)
7569 self.assertEqual(icmp.code, 1)
7570 self.assertTrue(icmp.haslayer(IPerror))
7571 inner_ip = icmp[IPerror]
7572 self.assertEqual(inner_ip[UDPerror].sport, 3001)
7573 self.assertEqual(inner_ip[UDPerror].dport, 3002)
7575 dms = self.vapi.nat_det_map_dump()
7577 self.assertEqual(1000, dms[0].ses_num)
7579 # verify IPFIX logging
7580 self.vapi.ipfix_flush()
7582 capture = self.pg2.get_capture(2)
7583 ipfix = IPFIXDecoder()
7584 # first load template
7586 self.assertTrue(p.haslayer(IPFIX))
7587 if p.haslayer(Template):
7588 ipfix.add_template(p.getlayer(Template))
7589 # verify events in data set
7591 if p.haslayer(Data):
7592 data = ipfix.decode_data_set(p.getlayer(Set))
7593 self.verify_ipfix_max_entries_per_user(data,
7595 self.pg0.remote_ip4n)
7597 def clear_nat_det(self):
7599 Clear deterministic NAT configuration.
7601 self.vapi.nat_ipfix_enable_disable(domain_id=1, src_port=4739,
7603 self.vapi.nat_set_timeouts(udp=300, tcp_established=7440,
7604 tcp_transitory=240, icmp=60)
7605 deterministic_mappings = self.vapi.nat_det_map_dump()
7606 for dsm in deterministic_mappings:
7607 self.vapi.nat_det_add_del_map(is_add=0, in_addr=dsm.in_addr,
7608 in_plen=dsm.in_plen,
7609 out_addr=dsm.out_addr,
7610 out_plen=dsm.out_plen)
7612 interfaces = self.vapi.nat44_interface_dump()
7613 for intf in interfaces:
7614 self.vapi.nat44_interface_add_del_feature(
7615 sw_if_index=intf.sw_if_index,
7619 super(TestDeterministicNAT, self).tearDown()
7620 if not self.vpp_dead:
7621 self.clear_nat_det()
7623 def show_commands_at_teardown(self):
7624 self.logger.info(self.vapi.cli("show nat44 interfaces"))
7625 self.logger.info(self.vapi.cli("show nat timeouts"))
7627 self.vapi.cli("show nat44 deterministic mappings"))
7629 self.vapi.cli("show nat44 deterministic sessions"))
7632 class TestNAT64(MethodHolder):
7633 """ NAT64 Test Cases """
7636 def setUpConstants(cls):
7637 super(TestNAT64, cls).setUpConstants()
7638 cls.vpp_cmdline.extend(["nat", "{", "nat64 bib hash buckets 128",
7639 "nat64 st hash buckets 256", "}"])
7642 def setUpClass(cls):
7643 super(TestNAT64, cls).setUpClass()
7646 cls.tcp_port_in = 6303
7647 cls.tcp_port_out = 6303
7648 cls.udp_port_in = 6304
7649 cls.udp_port_out = 6304
7650 cls.icmp_id_in = 6305
7651 cls.icmp_id_out = 6305
7652 cls.tcp_external_port = 80
7653 cls.nat_addr = '10.0.0.3'
7654 cls.nat_addr_n = socket.inet_pton(socket.AF_INET, cls.nat_addr)
7656 cls.vrf1_nat_addr = '10.0.10.3'
7657 cls.ipfix_src_port = 4739
7658 cls.ipfix_domain_id = 1
7660 cls.create_pg_interfaces(range(6))
7661 cls.ip6_interfaces = list(cls.pg_interfaces[0:1])
7662 cls.ip6_interfaces.append(cls.pg_interfaces[2])
7663 cls.ip4_interfaces = list(cls.pg_interfaces[1:2])
7665 cls.vapi.ip_table_add_del(is_ipv6=1, is_add=1,
7666 table_id=cls.vrf1_id)
7668 cls.pg_interfaces[2].set_table_ip6(cls.vrf1_id)
7670 cls.pg0.generate_remote_hosts(2)
7672 for i in cls.ip6_interfaces:
7675 i.configure_ipv6_neighbors()
7677 for i in cls.ip4_interfaces:
7683 cls.pg3.config_ip4()
7684 cls.pg3.resolve_arp()
7685 cls.pg3.config_ip6()
7686 cls.pg3.configure_ipv6_neighbors()
7689 cls.pg5.config_ip6()
7692 super(TestNAT64, cls).tearDownClass()
7696 def tearDownClass(cls):
7697 super(TestNAT64, cls).tearDownClass()
7699 def test_nat64_inside_interface_handles_neighbor_advertisement(self):
7700 """ NAT64 inside interface handles Neighbor Advertisement """
7702 flags = self.config_flags.NAT_IS_INSIDE
7703 self.vapi.nat64_add_del_interface(is_add=1, flags=flags,
7704 sw_if_index=self.pg5.sw_if_index)
7707 ping = (Ether(dst=self.pg5.local_mac, src=self.pg5.remote_mac) /
7708 IPv6(src=self.pg5.remote_ip6, dst=self.pg5.local_ip6) /
7709 ICMPv6EchoRequest())
7711 self.pg5.add_stream(pkts)
7712 self.pg_enable_capture(self.pg_interfaces)
7715 # Wait for Neighbor Solicitation
7716 capture = self.pg5.get_capture(len(pkts))
7719 self.assertEqual(packet[IPv6].src, self.pg5.local_ip6)
7720 self.assertEqual(packet.haslayer(ICMPv6ND_NS), 1)
7721 tgt = packet[ICMPv6ND_NS].tgt
7723 self.logger.error(ppp("Unexpected or invalid packet:", packet))
7726 # Send Neighbor Advertisement
7727 p = (Ether(dst=self.pg5.local_mac, src=self.pg5.remote_mac) /
7728 IPv6(src=self.pg5.remote_ip6, dst=self.pg5.local_ip6) /
7729 ICMPv6ND_NA(tgt=tgt) /
7730 ICMPv6NDOptDstLLAddr(lladdr=self.pg5.remote_mac))
7732 self.pg5.add_stream(pkts)
7733 self.pg_enable_capture(self.pg_interfaces)
7736 # Try to send ping again
7738 self.pg5.add_stream(pkts)
7739 self.pg_enable_capture(self.pg_interfaces)
7742 # Wait for ping reply
7743 capture = self.pg5.get_capture(len(pkts))
7746 self.assertEqual(packet[IPv6].src, self.pg5.local_ip6)
7747 self.assertEqual(packet[IPv6].dst, self.pg5.remote_ip6)
7748 self.assertEqual(packet.haslayer(ICMPv6EchoReply), 1)
7750 self.logger.error(ppp("Unexpected or invalid packet:", packet))
7753 def test_pool(self):
7754 """ Add/delete address to NAT64 pool """
7755 nat_addr = '1.2.3.4'
7757 self.vapi.nat64_add_del_pool_addr_range(start_addr=nat_addr,
7759 vrf_id=0xFFFFFFFF, is_add=1)
7761 addresses = self.vapi.nat64_pool_addr_dump()
7762 self.assertEqual(len(addresses), 1)
7763 self.assertEqual(str(addresses[0].address), nat_addr)
7765 self.vapi.nat64_add_del_pool_addr_range(start_addr=nat_addr,
7767 vrf_id=0xFFFFFFFF, is_add=0)
7769 addresses = self.vapi.nat64_pool_addr_dump()
7770 self.assertEqual(len(addresses), 0)
7772 def test_interface(self):
7773 """ Enable/disable NAT64 feature on the interface """
7774 flags = self.config_flags.NAT_IS_INSIDE
7775 self.vapi.nat64_add_del_interface(is_add=1, flags=flags,
7776 sw_if_index=self.pg0.sw_if_index)
7777 self.vapi.nat64_add_del_interface(is_add=1, flags=0,
7778 sw_if_index=self.pg1.sw_if_index)
7780 interfaces = self.vapi.nat64_interface_dump()
7781 self.assertEqual(len(interfaces), 2)
7784 for intf in interfaces:
7785 if intf.sw_if_index == self.pg0.sw_if_index:
7786 self.assertEqual(intf.flags, self.config_flags.NAT_IS_INSIDE)
7788 elif intf.sw_if_index == self.pg1.sw_if_index:
7789 self.assertEqual(intf.flags, self.config_flags.NAT_IS_OUTSIDE)
7791 self.assertTrue(pg0_found)
7792 self.assertTrue(pg1_found)
7794 features = self.vapi.cli("show interface features pg0")
7795 self.assertIn('nat64-in2out', features)
7796 features = self.vapi.cli("show interface features pg1")
7797 self.assertIn('nat64-out2in', features)
7799 self.vapi.nat64_add_del_interface(is_add=0, flags=flags,
7800 sw_if_index=self.pg0.sw_if_index)
7801 self.vapi.nat64_add_del_interface(is_add=0, flags=flags,
7802 sw_if_index=self.pg1.sw_if_index)
7804 interfaces = self.vapi.nat64_interface_dump()
7805 self.assertEqual(len(interfaces), 0)
7807 def test_static_bib(self):
7808 """ Add/delete static BIB entry """
7809 in_addr = '2001:db8:85a3::8a2e:370:7334'
7810 out_addr = '10.1.1.3'
7813 proto = IP_PROTOS.tcp
7815 self.vapi.nat64_add_del_static_bib(i_addr=in_addr, o_addr=out_addr,
7816 i_port=in_port, o_port=out_port,
7817 proto=proto, vrf_id=0, is_add=1)
7818 bib = self.vapi.nat64_bib_dump(proto=IP_PROTOS.tcp)
7821 if bibe.flags & self.config_flags.NAT_IS_STATIC:
7823 self.assertEqual(str(bibe.i_addr), in_addr)
7824 self.assertEqual(str(bibe.o_addr), out_addr)
7825 self.assertEqual(bibe.i_port, in_port)
7826 self.assertEqual(bibe.o_port, out_port)
7827 self.assertEqual(static_bib_num, 1)
7828 bibs = self.statistics.get_counter('/nat64/total-bibs')
7829 self.assertEqual(bibs[0][0], 1)
7831 self.vapi.nat64_add_del_static_bib(i_addr=in_addr, o_addr=out_addr,
7832 i_port=in_port, o_port=out_port,
7833 proto=proto, vrf_id=0, is_add=0)
7834 bib = self.vapi.nat64_bib_dump(proto=IP_PROTOS.tcp)
7837 if bibe.flags & self.config_flags.NAT_IS_STATIC:
7839 self.assertEqual(static_bib_num, 0)
7840 bibs = self.statistics.get_counter('/nat64/total-bibs')
7841 self.assertEqual(bibs[0][0], 0)
7843 def test_set_timeouts(self):
7844 """ Set NAT64 timeouts """
7845 # verify default values
7846 timeouts = self.vapi.nat_get_timeouts()
7847 self.assertEqual(timeouts.udp, 300)
7848 self.assertEqual(timeouts.icmp, 60)
7849 self.assertEqual(timeouts.tcp_transitory, 240)
7850 self.assertEqual(timeouts.tcp_established, 7440)
7852 # set and verify custom values
7853 self.vapi.nat_set_timeouts(udp=200, tcp_established=7450,
7854 tcp_transitory=250, icmp=30)
7855 timeouts = self.vapi.nat_get_timeouts()
7856 self.assertEqual(timeouts.udp, 200)
7857 self.assertEqual(timeouts.icmp, 30)
7858 self.assertEqual(timeouts.tcp_transitory, 250)
7859 self.assertEqual(timeouts.tcp_established, 7450)
7861 def test_dynamic(self):
7862 """ NAT64 dynamic translation test """
7863 self.tcp_port_in = 6303
7864 self.udp_port_in = 6304
7865 self.icmp_id_in = 6305
7867 ses_num_start = self.nat64_get_ses_num()
7869 self.vapi.nat64_add_del_pool_addr_range(start_addr=self.nat_addr,
7870 end_addr=self.nat_addr,
7873 flags = self.config_flags.NAT_IS_INSIDE
7874 self.vapi.nat64_add_del_interface(is_add=1, flags=flags,
7875 sw_if_index=self.pg0.sw_if_index)
7876 self.vapi.nat64_add_del_interface(is_add=1, flags=0,
7877 sw_if_index=self.pg1.sw_if_index)
7880 tcpn = self.statistics.get_err_counter('/err/nat64-in2out/TCP packets')
7881 udpn = self.statistics.get_err_counter('/err/nat64-in2out/UDP packets')
7882 icmpn = self.statistics.get_err_counter(
7883 '/err/nat64-in2out/ICMP packets')
7884 totaln = self.statistics.get_err_counter(
7885 '/err/nat64-in2out/good in2out packets processed')
7887 pkts = self.create_stream_in_ip6(self.pg0, self.pg1)
7888 self.pg0.add_stream(pkts)
7889 self.pg_enable_capture(self.pg_interfaces)
7891 capture = self.pg1.get_capture(len(pkts))
7892 self.verify_capture_out(capture, nat_ip=self.nat_addr,
7893 dst_ip=self.pg1.remote_ip4)
7895 err = self.statistics.get_err_counter('/err/nat64-in2out/TCP packets')
7896 self.assertEqual(err - tcpn, 1)
7897 err = self.statistics.get_err_counter('/err/nat64-in2out/UDP packets')
7898 self.assertEqual(err - udpn, 1)
7899 err = self.statistics.get_err_counter('/err/nat64-in2out/ICMP packets')
7900 self.assertEqual(err - icmpn, 1)
7901 err = self.statistics.get_err_counter(
7902 '/err/nat64-in2out/good in2out packets processed')
7903 self.assertEqual(err - totaln, 3)
7906 tcpn = self.statistics.get_err_counter('/err/nat64-out2in/TCP packets')
7907 udpn = self.statistics.get_err_counter('/err/nat64-out2in/UDP packets')
7908 icmpn = self.statistics.get_err_counter(
7909 '/err/nat64-out2in/ICMP packets')
7910 totaln = self.statistics.get_err_counter(
7911 '/err/nat64-out2in/good out2in packets processed')
7913 pkts = self.create_stream_out(self.pg1, dst_ip=self.nat_addr)
7914 self.pg1.add_stream(pkts)
7915 self.pg_enable_capture(self.pg_interfaces)
7917 capture = self.pg0.get_capture(len(pkts))
7918 ip = IPv6(src=''.join(['64:ff9b::', self.pg1.remote_ip4]))
7919 self.verify_capture_in_ip6(capture, ip[IPv6].src, self.pg0.remote_ip6)
7921 err = self.statistics.get_err_counter('/err/nat64-out2in/TCP packets')
7922 self.assertEqual(err - tcpn, 1)
7923 err = self.statistics.get_err_counter('/err/nat64-out2in/UDP packets')
7924 self.assertEqual(err - udpn, 1)
7925 err = self.statistics.get_err_counter('/err/nat64-out2in/ICMP packets')
7926 self.assertEqual(err - icmpn, 1)
7927 err = self.statistics.get_err_counter(
7928 '/err/nat64-out2in/good out2in packets processed')
7929 self.assertEqual(err - totaln, 3)
7931 bibs = self.statistics.get_counter('/nat64/total-bibs')
7932 self.assertEqual(bibs[0][0], 3)
7933 sessions = self.statistics.get_counter('/nat64/total-sessions')
7934 self.assertEqual(sessions[0][0], 3)
7937 pkts = self.create_stream_in_ip6(self.pg0, self.pg1)
7938 self.pg0.add_stream(pkts)
7939 self.pg_enable_capture(self.pg_interfaces)
7941 capture = self.pg1.get_capture(len(pkts))
7942 self.verify_capture_out(capture, nat_ip=self.nat_addr,
7943 dst_ip=self.pg1.remote_ip4)
7946 pkts = self.create_stream_out(self.pg1, dst_ip=self.nat_addr)
7947 self.pg1.add_stream(pkts)
7948 self.pg_enable_capture(self.pg_interfaces)
7950 capture = self.pg0.get_capture(len(pkts))
7951 self.verify_capture_in_ip6(capture, ip[IPv6].src, self.pg0.remote_ip6)
7953 ses_num_end = self.nat64_get_ses_num()
7955 self.assertEqual(ses_num_end - ses_num_start, 3)
7957 # tenant with specific VRF
7958 self.vapi.nat64_add_del_pool_addr_range(start_addr=self.vrf1_nat_addr,
7959 end_addr=self.vrf1_nat_addr,
7960 vrf_id=self.vrf1_id, is_add=1)
7961 flags = self.config_flags.NAT_IS_INSIDE
7962 self.vapi.nat64_add_del_interface(is_add=1, flags=flags,
7963 sw_if_index=self.pg2.sw_if_index)
7965 pkts = self.create_stream_in_ip6(self.pg2, self.pg1)
7966 self.pg2.add_stream(pkts)
7967 self.pg_enable_capture(self.pg_interfaces)
7969 capture = self.pg1.get_capture(len(pkts))
7970 self.verify_capture_out(capture, nat_ip=self.vrf1_nat_addr,
7971 dst_ip=self.pg1.remote_ip4)
7973 pkts = self.create_stream_out(self.pg1, dst_ip=self.vrf1_nat_addr)
7974 self.pg1.add_stream(pkts)
7975 self.pg_enable_capture(self.pg_interfaces)
7977 capture = self.pg2.get_capture(len(pkts))
7978 self.verify_capture_in_ip6(capture, ip[IPv6].src, self.pg2.remote_ip6)
7980 def test_static(self):
7981 """ NAT64 static translation test """
7982 self.tcp_port_in = 60303
7983 self.udp_port_in = 60304
7984 self.icmp_id_in = 60305
7985 self.tcp_port_out = 60303
7986 self.udp_port_out = 60304
7987 self.icmp_id_out = 60305
7989 ses_num_start = self.nat64_get_ses_num()
7991 self.vapi.nat64_add_del_pool_addr_range(start_addr=self.nat_addr,
7992 end_addr=self.nat_addr,
7995 flags = self.config_flags.NAT_IS_INSIDE
7996 self.vapi.nat64_add_del_interface(is_add=1, flags=flags,
7997 sw_if_index=self.pg0.sw_if_index)
7998 self.vapi.nat64_add_del_interface(is_add=1, flags=0,
7999 sw_if_index=self.pg1.sw_if_index)
8001 self.vapi.nat64_add_del_static_bib(i_addr=self.pg0.remote_ip6n,
8002 o_addr=self.nat_addr,
8003 i_port=self.tcp_port_in,
8004 o_port=self.tcp_port_out,
8005 proto=IP_PROTOS.tcp, vrf_id=0,
8007 self.vapi.nat64_add_del_static_bib(i_addr=self.pg0.remote_ip6n,
8008 o_addr=self.nat_addr,
8009 i_port=self.udp_port_in,
8010 o_port=self.udp_port_out,
8011 proto=IP_PROTOS.udp, vrf_id=0,
8013 self.vapi.nat64_add_del_static_bib(i_addr=self.pg0.remote_ip6n,
8014 o_addr=self.nat_addr,
8015 i_port=self.icmp_id_in,
8016 o_port=self.icmp_id_out,
8017 proto=IP_PROTOS.icmp, vrf_id=0,
8021 pkts = self.create_stream_in_ip6(self.pg0, self.pg1)
8022 self.pg0.add_stream(pkts)
8023 self.pg_enable_capture(self.pg_interfaces)
8025 capture = self.pg1.get_capture(len(pkts))
8026 self.verify_capture_out(capture, nat_ip=self.nat_addr,
8027 dst_ip=self.pg1.remote_ip4, same_port=True)
8030 pkts = self.create_stream_out(self.pg1, dst_ip=self.nat_addr)
8031 self.pg1.add_stream(pkts)
8032 self.pg_enable_capture(self.pg_interfaces)
8034 capture = self.pg0.get_capture(len(pkts))
8035 ip = IPv6(src=''.join(['64:ff9b::', self.pg1.remote_ip4]))
8036 self.verify_capture_in_ip6(capture, ip[IPv6].src, self.pg0.remote_ip6)
8038 ses_num_end = self.nat64_get_ses_num()
8040 self.assertEqual(ses_num_end - ses_num_start, 3)
8042 @unittest.skipUnless(running_extended_tests, "part of extended tests")
8043 def test_session_timeout(self):
8044 """ NAT64 session timeout """
8045 self.icmp_id_in = 1234
8046 self.vapi.nat64_add_del_pool_addr_range(start_addr=self.nat_addr,
8047 end_addr=self.nat_addr,
8050 flags = self.config_flags.NAT_IS_INSIDE
8051 self.vapi.nat64_add_del_interface(is_add=1, flags=flags,
8052 sw_if_index=self.pg0.sw_if_index)
8053 self.vapi.nat64_add_del_interface(is_add=1, flags=0,
8054 sw_if_index=self.pg1.sw_if_index)
8055 self.vapi.nat_set_timeouts(udp=300, tcp_established=5,
8059 pkts = self.create_stream_in_ip6(self.pg0, self.pg1)
8060 self.pg0.add_stream(pkts)
8061 self.pg_enable_capture(self.pg_interfaces)
8063 capture = self.pg1.get_capture(len(pkts))
8065 ses_num_before_timeout = self.nat64_get_ses_num()
8069 # ICMP and TCP session after timeout
8070 ses_num_after_timeout = self.nat64_get_ses_num()
8071 self.assertEqual(ses_num_before_timeout - ses_num_after_timeout, 2)
8073 def test_icmp_error(self):
8074 """ NAT64 ICMP Error message translation """
8075 self.tcp_port_in = 6303
8076 self.udp_port_in = 6304
8077 self.icmp_id_in = 6305
8079 self.vapi.nat64_add_del_pool_addr_range(start_addr=self.nat_addr,
8080 end_addr=self.nat_addr,
8083 flags = self.config_flags.NAT_IS_INSIDE
8084 self.vapi.nat64_add_del_interface(is_add=1, flags=flags,
8085 sw_if_index=self.pg0.sw_if_index)
8086 self.vapi.nat64_add_del_interface(is_add=1, flags=0,
8087 sw_if_index=self.pg1.sw_if_index)
8089 # send some packets to create sessions
8090 pkts = self.create_stream_in_ip6(self.pg0, self.pg1)
8091 self.pg0.add_stream(pkts)
8092 self.pg_enable_capture(self.pg_interfaces)
8094 capture_ip4 = self.pg1.get_capture(len(pkts))
8095 self.verify_capture_out(capture_ip4,
8096 nat_ip=self.nat_addr,
8097 dst_ip=self.pg1.remote_ip4)
8099 pkts = self.create_stream_out(self.pg1, dst_ip=self.nat_addr)
8100 self.pg1.add_stream(pkts)
8101 self.pg_enable_capture(self.pg_interfaces)
8103 capture_ip6 = self.pg0.get_capture(len(pkts))
8104 ip = IPv6(src=''.join(['64:ff9b::', self.pg1.remote_ip4]))
8105 self.verify_capture_in_ip6(capture_ip6, ip[IPv6].src,
8106 self.pg0.remote_ip6)
8109 pkts = [Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
8110 IPv6(src=self.pg0.remote_ip6, dst=ip[IPv6].src) /
8111 ICMPv6DestUnreach(code=1) /
8112 packet[IPv6] for packet in capture_ip6]
8113 self.pg0.add_stream(pkts)
8114 self.pg_enable_capture(self.pg_interfaces)
8116 capture = self.pg1.get_capture(len(pkts))
8117 for packet in capture:
8119 self.assertEqual(packet[IP].src, self.nat_addr)
8120 self.assertEqual(packet[IP].dst, self.pg1.remote_ip4)
8121 self.assertEqual(packet[ICMP].type, 3)
8122 self.assertEqual(packet[ICMP].code, 13)
8123 inner = packet[IPerror]
8124 self.assertEqual(inner.src, self.pg1.remote_ip4)
8125 self.assertEqual(inner.dst, self.nat_addr)
8126 self.assert_packet_checksums_valid(packet)
8127 if inner.haslayer(TCPerror):
8128 self.assertEqual(inner[TCPerror].dport, self.tcp_port_out)
8129 elif inner.haslayer(UDPerror):
8130 self.assertEqual(inner[UDPerror].dport, self.udp_port_out)
8132 self.assertEqual(inner[ICMPerror].id, self.icmp_id_out)
8134 self.logger.error(ppp("Unexpected or invalid packet:", packet))
8138 pkts = [Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
8139 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
8140 ICMP(type=3, code=13) /
8141 packet[IP] for packet in capture_ip4]
8142 self.pg1.add_stream(pkts)
8143 self.pg_enable_capture(self.pg_interfaces)
8145 capture = self.pg0.get_capture(len(pkts))
8146 for packet in capture:
8148 self.assertEqual(packet[IPv6].src, ip.src)
8149 self.assertEqual(packet[IPv6].dst, self.pg0.remote_ip6)
8150 icmp = packet[ICMPv6DestUnreach]
8151 self.assertEqual(icmp.code, 1)
8152 inner = icmp[IPerror6]
8153 self.assertEqual(inner.src, self.pg0.remote_ip6)
8154 self.assertEqual(inner.dst, ip.src)
8155 self.assert_icmpv6_checksum_valid(packet)
8156 if inner.haslayer(TCPerror):
8157 self.assertEqual(inner[TCPerror].sport, self.tcp_port_in)
8158 elif inner.haslayer(UDPerror):
8159 self.assertEqual(inner[UDPerror].sport, self.udp_port_in)
8161 self.assertEqual(inner[ICMPv6EchoRequest].id,
8164 self.logger.error(ppp("Unexpected or invalid packet:", packet))
8167 def test_hairpinning(self):
8168 """ NAT64 hairpinning """
8170 client = self.pg0.remote_hosts[0]
8171 server = self.pg0.remote_hosts[1]
8172 server_tcp_in_port = 22
8173 server_tcp_out_port = 4022
8174 server_udp_in_port = 23
8175 server_udp_out_port = 4023
8176 client_tcp_in_port = 1234
8177 client_udp_in_port = 1235
8178 client_tcp_out_port = 0
8179 client_udp_out_port = 0
8180 ip = IPv6(src=''.join(['64:ff9b::', self.nat_addr]))
8181 nat_addr_ip6 = ip.src
8183 self.vapi.nat64_add_del_pool_addr_range(start_addr=self.nat_addr,
8184 end_addr=self.nat_addr,
8187 flags = self.config_flags.NAT_IS_INSIDE
8188 self.vapi.nat64_add_del_interface(is_add=1, flags=flags,
8189 sw_if_index=self.pg0.sw_if_index)
8190 self.vapi.nat64_add_del_interface(is_add=1, flags=0,
8191 sw_if_index=self.pg1.sw_if_index)
8193 self.vapi.nat64_add_del_static_bib(i_addr=server.ip6n,
8194 o_addr=self.nat_addr,
8195 i_port=server_tcp_in_port,
8196 o_port=server_tcp_out_port,
8197 proto=IP_PROTOS.tcp, vrf_id=0,
8199 self.vapi.nat64_add_del_static_bib(i_addr=server.ip6n,
8200 o_addr=self.nat_addr,
8201 i_port=server_udp_in_port,
8202 o_port=server_udp_out_port,
8203 proto=IP_PROTOS.udp, vrf_id=0,
8208 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
8209 IPv6(src=client.ip6, dst=nat_addr_ip6) /
8210 TCP(sport=client_tcp_in_port, dport=server_tcp_out_port))
8212 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
8213 IPv6(src=client.ip6, dst=nat_addr_ip6) /
8214 UDP(sport=client_udp_in_port, dport=server_udp_out_port))
8216 self.pg0.add_stream(pkts)
8217 self.pg_enable_capture(self.pg_interfaces)
8219 capture = self.pg0.get_capture(len(pkts))
8220 for packet in capture:
8222 self.assertEqual(packet[IPv6].src, nat_addr_ip6)
8223 self.assertEqual(packet[IPv6].dst, server.ip6)
8224 self.assert_packet_checksums_valid(packet)
8225 if packet.haslayer(TCP):
8226 self.assertNotEqual(packet[TCP].sport, client_tcp_in_port)
8227 self.assertEqual(packet[TCP].dport, server_tcp_in_port)
8228 client_tcp_out_port = packet[TCP].sport
8230 self.assertNotEqual(packet[UDP].sport, client_udp_in_port)
8231 self.assertEqual(packet[UDP].dport, server_udp_in_port)
8232 client_udp_out_port = packet[UDP].sport
8234 self.logger.error(ppp("Unexpected or invalid packet:", packet))
8239 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
8240 IPv6(src=server.ip6, dst=nat_addr_ip6) /
8241 TCP(sport=server_tcp_in_port, dport=client_tcp_out_port))
8243 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
8244 IPv6(src=server.ip6, dst=nat_addr_ip6) /
8245 UDP(sport=server_udp_in_port, dport=client_udp_out_port))
8247 self.pg0.add_stream(pkts)
8248 self.pg_enable_capture(self.pg_interfaces)
8250 capture = self.pg0.get_capture(len(pkts))
8251 for packet in capture:
8253 self.assertEqual(packet[IPv6].src, nat_addr_ip6)
8254 self.assertEqual(packet[IPv6].dst, client.ip6)
8255 self.assert_packet_checksums_valid(packet)
8256 if packet.haslayer(TCP):
8257 self.assertEqual(packet[TCP].sport, server_tcp_out_port)
8258 self.assertEqual(packet[TCP].dport, client_tcp_in_port)
8260 self.assertEqual(packet[UDP].sport, server_udp_out_port)
8261 self.assertEqual(packet[UDP].dport, client_udp_in_port)
8263 self.logger.error(ppp("Unexpected or invalid packet:", packet))
8268 pkts = [Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
8269 IPv6(src=client.ip6, dst=nat_addr_ip6) /
8270 ICMPv6DestUnreach(code=1) /
8271 packet[IPv6] for packet in capture]
8272 self.pg0.add_stream(pkts)
8273 self.pg_enable_capture(self.pg_interfaces)
8275 capture = self.pg0.get_capture(len(pkts))
8276 for packet in capture:
8278 self.assertEqual(packet[IPv6].src, nat_addr_ip6)
8279 self.assertEqual(packet[IPv6].dst, server.ip6)
8280 icmp = packet[ICMPv6DestUnreach]
8281 self.assertEqual(icmp.code, 1)
8282 inner = icmp[IPerror6]
8283 self.assertEqual(inner.src, server.ip6)
8284 self.assertEqual(inner.dst, nat_addr_ip6)
8285 self.assert_packet_checksums_valid(packet)
8286 if inner.haslayer(TCPerror):
8287 self.assertEqual(inner[TCPerror].sport, server_tcp_in_port)
8288 self.assertEqual(inner[TCPerror].dport,
8289 client_tcp_out_port)
8291 self.assertEqual(inner[UDPerror].sport, server_udp_in_port)
8292 self.assertEqual(inner[UDPerror].dport,
8293 client_udp_out_port)
8295 self.logger.error(ppp("Unexpected or invalid packet:", packet))
8298 def test_prefix(self):
8299 """ NAT64 Network-Specific Prefix """
8301 self.vapi.nat64_add_del_pool_addr_range(start_addr=self.nat_addr,
8302 end_addr=self.nat_addr,
8305 flags = self.config_flags.NAT_IS_INSIDE
8306 self.vapi.nat64_add_del_interface(is_add=1, flags=flags,
8307 sw_if_index=self.pg0.sw_if_index)
8308 self.vapi.nat64_add_del_interface(is_add=1, flags=0,
8309 sw_if_index=self.pg1.sw_if_index)
8310 self.vapi.nat64_add_del_pool_addr_range(start_addr=self.vrf1_nat_addr,
8311 end_addr=self.vrf1_nat_addr,
8312 vrf_id=self.vrf1_id, is_add=1)
8313 self.vapi.nat64_add_del_interface(is_add=1, flags=flags,
8314 sw_if_index=self.pg2.sw_if_index)
8317 global_pref64 = "2001:db8::"
8318 global_pref64_len = 32
8319 global_pref64_str = "{}/{}".format(global_pref64, global_pref64_len)
8320 self.vapi.nat64_add_del_prefix(prefix=global_pref64_str, vrf_id=0,
8323 prefix = self.vapi.nat64_prefix_dump()
8324 self.assertEqual(len(prefix), 1)
8325 self.assertEqual(prefix[0].prefix,
8326 IPv6Network(unicode(global_pref64_str)))
8327 self.assertEqual(prefix[0].vrf_id, 0)
8329 # Add tenant specific prefix
8330 vrf1_pref64 = "2001:db8:122:300::"
8331 vrf1_pref64_len = 56
8332 vrf1_pref64_str = "{}/{}".format(vrf1_pref64, vrf1_pref64_len)
8333 self.vapi.nat64_add_del_prefix(prefix=vrf1_pref64_str,
8334 vrf_id=self.vrf1_id, is_add=1)
8336 prefix = self.vapi.nat64_prefix_dump()
8337 self.assertEqual(len(prefix), 2)
8340 pkts = self.create_stream_in_ip6(self.pg0,
8343 plen=global_pref64_len)
8344 self.pg0.add_stream(pkts)
8345 self.pg_enable_capture(self.pg_interfaces)
8347 capture = self.pg1.get_capture(len(pkts))
8348 self.verify_capture_out(capture, nat_ip=self.nat_addr,
8349 dst_ip=self.pg1.remote_ip4)
8351 pkts = self.create_stream_out(self.pg1, dst_ip=self.nat_addr)
8352 self.pg1.add_stream(pkts)
8353 self.pg_enable_capture(self.pg_interfaces)
8355 capture = self.pg0.get_capture(len(pkts))
8356 dst_ip = self.compose_ip6(self.pg1.remote_ip4,
8359 self.verify_capture_in_ip6(capture, dst_ip, self.pg0.remote_ip6)
8361 # Tenant specific prefix
8362 pkts = self.create_stream_in_ip6(self.pg2,
8365 plen=vrf1_pref64_len)
8366 self.pg2.add_stream(pkts)
8367 self.pg_enable_capture(self.pg_interfaces)
8369 capture = self.pg1.get_capture(len(pkts))
8370 self.verify_capture_out(capture, nat_ip=self.vrf1_nat_addr,
8371 dst_ip=self.pg1.remote_ip4)
8373 pkts = self.create_stream_out(self.pg1, dst_ip=self.vrf1_nat_addr)
8374 self.pg1.add_stream(pkts)
8375 self.pg_enable_capture(self.pg_interfaces)
8377 capture = self.pg2.get_capture(len(pkts))
8378 dst_ip = self.compose_ip6(self.pg1.remote_ip4,
8381 self.verify_capture_in_ip6(capture, dst_ip, self.pg2.remote_ip6)
8383 def test_unknown_proto(self):
8384 """ NAT64 translate packet with unknown protocol """
8386 self.vapi.nat64_add_del_pool_addr_range(start_addr=self.nat_addr,
8387 end_addr=self.nat_addr,
8390 flags = self.config_flags.NAT_IS_INSIDE
8391 self.vapi.nat64_add_del_interface(is_add=1, flags=flags,
8392 sw_if_index=self.pg0.sw_if_index)
8393 self.vapi.nat64_add_del_interface(is_add=1, flags=0,
8394 sw_if_index=self.pg1.sw_if_index)
8395 remote_ip6 = self.compose_ip6(self.pg1.remote_ip4, '64:ff9b::', 96)
8398 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
8399 IPv6(src=self.pg0.remote_ip6, dst=remote_ip6) /
8400 TCP(sport=self.tcp_port_in, dport=20))
8401 self.pg0.add_stream(p)
8402 self.pg_enable_capture(self.pg_interfaces)
8404 p = self.pg1.get_capture(1)
8406 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
8407 IPv6(src=self.pg0.remote_ip6, dst=remote_ip6, nh=47) /
8409 IP(src=self.pg2.local_ip4, dst=self.pg2.remote_ip4) /
8410 TCP(sport=1234, dport=1234))
8411 self.pg0.add_stream(p)
8412 self.pg_enable_capture(self.pg_interfaces)
8414 p = self.pg1.get_capture(1)
8417 self.assertEqual(packet[IP].src, self.nat_addr)
8418 self.assertEqual(packet[IP].dst, self.pg1.remote_ip4)
8419 self.assertEqual(packet.haslayer(GRE), 1)
8420 self.assert_packet_checksums_valid(packet)
8422 self.logger.error(ppp("Unexpected or invalid packet:", packet))
8426 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
8427 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
8429 IP(src=self.pg2.remote_ip4, dst=self.pg2.local_ip4) /
8430 TCP(sport=1234, dport=1234))
8431 self.pg1.add_stream(p)
8432 self.pg_enable_capture(self.pg_interfaces)
8434 p = self.pg0.get_capture(1)
8437 self.assertEqual(packet[IPv6].src, remote_ip6)
8438 self.assertEqual(packet[IPv6].dst, self.pg0.remote_ip6)
8439 self.assertEqual(packet[IPv6].nh, 47)
8441 self.logger.error(ppp("Unexpected or invalid packet:", packet))
8444 def test_hairpinning_unknown_proto(self):
8445 """ NAT64 translate packet with unknown protocol - hairpinning """
8447 client = self.pg0.remote_hosts[0]
8448 server = self.pg0.remote_hosts[1]
8449 server_tcp_in_port = 22
8450 server_tcp_out_port = 4022
8451 client_tcp_in_port = 1234
8452 client_tcp_out_port = 1235
8453 server_nat_ip = "10.0.0.100"
8454 client_nat_ip = "10.0.0.110"
8455 server_nat_ip6 = self.compose_ip6(server_nat_ip, '64:ff9b::', 96)
8456 client_nat_ip6 = self.compose_ip6(client_nat_ip, '64:ff9b::', 96)
8458 self.vapi.nat64_add_del_pool_addr_range(start_addr=server_nat_ip,
8459 end_addr=client_nat_ip,
8462 flags = self.config_flags.NAT_IS_INSIDE
8463 self.vapi.nat64_add_del_interface(is_add=1, flags=flags,
8464 sw_if_index=self.pg0.sw_if_index)
8465 self.vapi.nat64_add_del_interface(is_add=1, flags=0,
8466 sw_if_index=self.pg1.sw_if_index)
8468 self.vapi.nat64_add_del_static_bib(i_addr=server.ip6n,
8469 o_addr=server_nat_ip,
8470 i_port=server_tcp_in_port,
8471 o_port=server_tcp_out_port,
8472 proto=IP_PROTOS.tcp, vrf_id=0,
8475 self.vapi.nat64_add_del_static_bib(i_addr=server.ip6n,
8476 o_addr=server_nat_ip, i_port=0,
8478 proto=IP_PROTOS.gre, vrf_id=0,
8481 self.vapi.nat64_add_del_static_bib(i_addr=client.ip6n,
8482 o_addr=client_nat_ip,
8483 i_port=client_tcp_in_port,
8484 o_port=client_tcp_out_port,
8485 proto=IP_PROTOS.tcp, vrf_id=0,
8489 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
8490 IPv6(src=client.ip6, dst=server_nat_ip6) /
8491 TCP(sport=client_tcp_in_port, dport=server_tcp_out_port))
8492 self.pg0.add_stream(p)
8493 self.pg_enable_capture(self.pg_interfaces)
8495 p = self.pg0.get_capture(1)
8497 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
8498 IPv6(src=client.ip6, dst=server_nat_ip6, nh=IP_PROTOS.gre) /
8500 IP(src=self.pg2.local_ip4, dst=self.pg2.remote_ip4) /
8501 TCP(sport=1234, dport=1234))
8502 self.pg0.add_stream(p)
8503 self.pg_enable_capture(self.pg_interfaces)
8505 p = self.pg0.get_capture(1)
8508 self.assertEqual(packet[IPv6].src, client_nat_ip6)
8509 self.assertEqual(packet[IPv6].dst, server.ip6)
8510 self.assertEqual(packet[IPv6].nh, IP_PROTOS.gre)
8512 self.logger.error(ppp("Unexpected or invalid packet:", packet))
8516 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
8517 IPv6(src=server.ip6, dst=client_nat_ip6, nh=IP_PROTOS.gre) /
8519 IP(src=self.pg2.remote_ip4, dst=self.pg2.local_ip4) /
8520 TCP(sport=1234, dport=1234))
8521 self.pg0.add_stream(p)
8522 self.pg_enable_capture(self.pg_interfaces)
8524 p = self.pg0.get_capture(1)
8527 self.assertEqual(packet[IPv6].src, server_nat_ip6)
8528 self.assertEqual(packet[IPv6].dst, client.ip6)
8529 self.assertEqual(packet[IPv6].nh, IP_PROTOS.gre)
8531 self.logger.error(ppp("Unexpected or invalid packet:", packet))
8534 def test_one_armed_nat64(self):
8535 """ One armed NAT64 """
8537 remote_host_ip6 = self.compose_ip6(self.pg3.remote_ip4,
8541 self.vapi.nat64_add_del_pool_addr_range(start_addr=self.nat_addr,
8542 end_addr=self.nat_addr,
8545 flags = self.config_flags.NAT_IS_INSIDE
8546 self.vapi.nat64_add_del_interface(is_add=1, flags=flags,
8547 sw_if_index=self.pg3.sw_if_index)
8548 self.vapi.nat64_add_del_interface(is_add=1, flags=0,
8549 sw_if_index=self.pg3.sw_if_index)
8552 p = (Ether(src=self.pg3.remote_mac, dst=self.pg3.local_mac) /
8553 IPv6(src=self.pg3.remote_ip6, dst=remote_host_ip6) /
8554 TCP(sport=12345, dport=80))
8555 self.pg3.add_stream(p)
8556 self.pg_enable_capture(self.pg_interfaces)
8558 capture = self.pg3.get_capture(1)
8563 self.assertEqual(ip.src, self.nat_addr)
8564 self.assertEqual(ip.dst, self.pg3.remote_ip4)
8565 self.assertNotEqual(tcp.sport, 12345)
8566 external_port = tcp.sport
8567 self.assertEqual(tcp.dport, 80)
8568 self.assert_packet_checksums_valid(p)
8570 self.logger.error(ppp("Unexpected or invalid packet:", p))
8574 p = (Ether(src=self.pg3.remote_mac, dst=self.pg3.local_mac) /
8575 IP(src=self.pg3.remote_ip4, dst=self.nat_addr) /
8576 TCP(sport=80, dport=external_port))
8577 self.pg3.add_stream(p)
8578 self.pg_enable_capture(self.pg_interfaces)
8580 capture = self.pg3.get_capture(1)
8585 self.assertEqual(ip.src, remote_host_ip6)
8586 self.assertEqual(ip.dst, self.pg3.remote_ip6)
8587 self.assertEqual(tcp.sport, 80)
8588 self.assertEqual(tcp.dport, 12345)
8589 self.assert_packet_checksums_valid(p)
8591 self.logger.error(ppp("Unexpected or invalid packet:", p))
8594 def test_frag_in_order(self):
8595 """ NAT64 translate fragments arriving in order """
8596 self.tcp_port_in = random.randint(1025, 65535)
8598 self.vapi.nat64_add_del_pool_addr_range(start_addr=self.nat_addr,
8599 end_addr=self.nat_addr,
8602 flags = self.config_flags.NAT_IS_INSIDE
8603 self.vapi.nat64_add_del_interface(is_add=1, flags=flags,
8604 sw_if_index=self.pg0.sw_if_index)
8605 self.vapi.nat64_add_del_interface(is_add=1, flags=0,
8606 sw_if_index=self.pg1.sw_if_index)
8608 reass = self.vapi.nat_reass_dump()
8609 reass_n_start = len(reass)
8613 pkts = self.create_stream_frag_ip6(self.pg0, self.pg1.remote_ip4,
8614 self.tcp_port_in, 20, data)
8615 self.pg0.add_stream(pkts)
8616 self.pg_enable_capture(self.pg_interfaces)
8618 frags = self.pg1.get_capture(len(pkts))
8619 p = self.reass_frags_and_verify(frags,
8621 self.pg1.remote_ip4)
8622 self.assertEqual(p[TCP].dport, 20)
8623 self.assertNotEqual(p[TCP].sport, self.tcp_port_in)
8624 self.tcp_port_out = p[TCP].sport
8625 self.assertEqual(data, p[Raw].load)
8628 data = b"A" * 4 + b"b" * 16 + b"C" * 3
8629 pkts = self.create_stream_frag(self.pg1,
8634 self.pg1.add_stream(pkts)
8635 self.pg_enable_capture(self.pg_interfaces)
8637 frags = self.pg0.get_capture(len(pkts))
8638 src = self.compose_ip6(self.pg1.remote_ip4, '64:ff9b::', 96)
8639 p = self.reass_frags_and_verify_ip6(frags, src, self.pg0.remote_ip6)
8640 self.assertEqual(p[TCP].sport, 20)
8641 self.assertEqual(p[TCP].dport, self.tcp_port_in)
8642 self.assertEqual(data, p[Raw].load)
8644 reass = self.vapi.nat_reass_dump()
8645 reass_n_end = len(reass)
8647 self.assertEqual(reass_n_end - reass_n_start, 2)
8649 def test_reass_hairpinning(self):
8650 """ NAT64 fragments hairpinning """
8652 server = self.pg0.remote_hosts[1]
8653 server_in_port = random.randint(1025, 65535)
8654 server_out_port = random.randint(1025, 65535)
8655 client_in_port = random.randint(1025, 65535)
8656 ip = IPv6(src=''.join(['64:ff9b::', self.nat_addr]))
8657 nat_addr_ip6 = ip.src
8659 self.vapi.nat64_add_del_pool_addr_range(start_addr=self.nat_addr,
8660 end_addr=self.nat_addr,
8663 flags = self.config_flags.NAT_IS_INSIDE
8664 self.vapi.nat64_add_del_interface(is_add=1, flags=flags,
8665 sw_if_index=self.pg0.sw_if_index)
8666 self.vapi.nat64_add_del_interface(is_add=1, flags=0,
8667 sw_if_index=self.pg1.sw_if_index)
8669 # add static BIB entry for server
8670 self.vapi.nat64_add_del_static_bib(i_addr=server.ip6n,
8671 o_addr=self.nat_addr,
8672 i_port=server_in_port,
8673 o_port=server_out_port,
8674 proto=IP_PROTOS.tcp, vrf_id=0,
8677 # send packet from host to server
8678 pkts = self.create_stream_frag_ip6(self.pg0,
8683 self.pg0.add_stream(pkts)
8684 self.pg_enable_capture(self.pg_interfaces)
8686 frags = self.pg0.get_capture(len(pkts))
8687 p = self.reass_frags_and_verify_ip6(frags, nat_addr_ip6, server.ip6)
8688 self.assertNotEqual(p[TCP].sport, client_in_port)
8689 self.assertEqual(p[TCP].dport, server_in_port)
8690 self.assertEqual(data, p[Raw].load)
8692 def test_frag_out_of_order(self):
8693 """ NAT64 translate fragments arriving out of order """
8694 self.tcp_port_in = random.randint(1025, 65535)
8696 self.vapi.nat64_add_del_pool_addr_range(start_addr=self.nat_addr,
8697 end_addr=self.nat_addr,
8700 flags = self.config_flags.NAT_IS_INSIDE
8701 self.vapi.nat64_add_del_interface(is_add=1, flags=flags,
8702 sw_if_index=self.pg0.sw_if_index)
8703 self.vapi.nat64_add_del_interface(is_add=1, flags=0,
8704 sw_if_index=self.pg1.sw_if_index)
8708 pkts = self.create_stream_frag_ip6(self.pg0, self.pg1.remote_ip4,
8709 self.tcp_port_in, 20, data)
8711 self.pg0.add_stream(pkts)
8712 self.pg_enable_capture(self.pg_interfaces)
8714 frags = self.pg1.get_capture(len(pkts))
8715 p = self.reass_frags_and_verify(frags,
8717 self.pg1.remote_ip4)
8718 self.assertEqual(p[TCP].dport, 20)
8719 self.assertNotEqual(p[TCP].sport, self.tcp_port_in)
8720 self.tcp_port_out = p[TCP].sport
8721 self.assertEqual(data, p[Raw].load)
8724 data = b"A" * 4 + b"B" * 16 + b"C" * 3
8725 pkts = self.create_stream_frag(self.pg1,
8731 self.pg1.add_stream(pkts)
8732 self.pg_enable_capture(self.pg_interfaces)
8734 frags = self.pg0.get_capture(len(pkts))
8735 src = self.compose_ip6(self.pg1.remote_ip4, '64:ff9b::', 96)
8736 p = self.reass_frags_and_verify_ip6(frags, src, self.pg0.remote_ip6)
8737 self.assertEqual(p[TCP].sport, 20)
8738 self.assertEqual(p[TCP].dport, self.tcp_port_in)
8739 self.assertEqual(data, p[Raw].load)
8741 def test_interface_addr(self):
8742 """ Acquire NAT64 pool addresses from interface """
8743 self.vapi.nat64_add_del_interface_addr(
8745 sw_if_index=self.pg4.sw_if_index)
8747 # no address in NAT64 pool
8748 addresses = self.vapi.nat44_address_dump()
8749 self.assertEqual(0, len(addresses))
8751 # configure interface address and check NAT64 address pool
8752 self.pg4.config_ip4()
8753 addresses = self.vapi.nat64_pool_addr_dump()
8754 self.assertEqual(len(addresses), 1)
8756 self.assertEqual(str(addresses[0].address),
8759 # remove interface address and check NAT64 address pool
8760 self.pg4.unconfig_ip4()
8761 addresses = self.vapi.nat64_pool_addr_dump()
8762 self.assertEqual(0, len(addresses))
8764 @unittest.skipUnless(running_extended_tests, "part of extended tests")
8765 def test_ipfix_max_bibs_sessions(self):
8766 """ IPFIX logging maximum session and BIB entries exceeded """
8769 remote_host_ip6 = self.compose_ip6(self.pg1.remote_ip4,
8773 self.vapi.nat64_add_del_pool_addr_range(start_addr=self.nat_addr,
8774 end_addr=self.nat_addr,
8777 flags = self.config_flags.NAT_IS_INSIDE
8778 self.vapi.nat64_add_del_interface(is_add=1, flags=flags,
8779 sw_if_index=self.pg0.sw_if_index)
8780 self.vapi.nat64_add_del_interface(is_add=1, flags=0,
8781 sw_if_index=self.pg1.sw_if_index)
8785 for i in range(0, max_bibs):
8786 src = "fd01:aa::%x" % (i)
8787 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
8788 IPv6(src=src, dst=remote_host_ip6) /
8789 TCP(sport=12345, dport=80))
8791 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
8792 IPv6(src=src, dst=remote_host_ip6) /
8793 TCP(sport=12345, dport=22))
8795 self.pg0.add_stream(pkts)
8796 self.pg_enable_capture(self.pg_interfaces)
8798 self.pg1.get_capture(max_sessions)
8800 self.vapi.set_ipfix_exporter(collector_address=self.pg3.remote_ip4n,
8801 src_address=self.pg3.local_ip4n,
8803 template_interval=10)
8804 self.vapi.nat_ipfix_enable_disable(domain_id=self.ipfix_domain_id,
8805 src_port=self.ipfix_src_port,
8808 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
8809 IPv6(src=src, dst=remote_host_ip6) /
8810 TCP(sport=12345, dport=25))
8811 self.pg0.add_stream(p)
8812 self.pg_enable_capture(self.pg_interfaces)
8814 self.pg1.assert_nothing_captured()
8816 self.vapi.ipfix_flush()
8817 capture = self.pg3.get_capture(9)
8818 ipfix = IPFIXDecoder()
8819 # first load template
8821 self.assertTrue(p.haslayer(IPFIX))
8822 self.assertEqual(p[IP].src, self.pg3.local_ip4)
8823 self.assertEqual(p[IP].dst, self.pg3.remote_ip4)
8824 self.assertEqual(p[UDP].sport, self.ipfix_src_port)
8825 self.assertEqual(p[UDP].dport, 4739)
8826 self.assertEqual(p[IPFIX].observationDomainID,
8827 self.ipfix_domain_id)
8828 if p.haslayer(Template):
8829 ipfix.add_template(p.getlayer(Template))
8830 # verify events in data set
8832 if p.haslayer(Data):
8833 data = ipfix.decode_data_set(p.getlayer(Set))
8834 self.verify_ipfix_max_sessions(data, max_sessions)
8836 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
8837 IPv6(src=self.pg0.remote_ip6, dst=remote_host_ip6) /
8838 TCP(sport=12345, dport=80))
8839 self.pg0.add_stream(p)
8840 self.pg_enable_capture(self.pg_interfaces)
8842 self.pg1.assert_nothing_captured()
8844 self.vapi.ipfix_flush()
8845 capture = self.pg3.get_capture(1)
8846 # verify events in data set
8848 self.assertTrue(p.haslayer(IPFIX))
8849 self.assertEqual(p[IP].src, self.pg3.local_ip4)
8850 self.assertEqual(p[IP].dst, self.pg3.remote_ip4)
8851 self.assertEqual(p[UDP].sport, self.ipfix_src_port)
8852 self.assertEqual(p[UDP].dport, 4739)
8853 self.assertEqual(p[IPFIX].observationDomainID,
8854 self.ipfix_domain_id)
8855 if p.haslayer(Data):
8856 data = ipfix.decode_data_set(p.getlayer(Set))
8857 self.verify_ipfix_max_bibs(data, max_bibs)
8859 def test_ipfix_max_frags(self):
8860 """ IPFIX logging maximum fragments pending reassembly exceeded """
8861 self.vapi.nat64_add_del_pool_addr_range(start_addr=self.nat_addr,
8862 end_addr=self.nat_addr,
8865 flags = self.config_flags.NAT_IS_INSIDE
8866 self.vapi.nat64_add_del_interface(is_add=1, flags=flags,
8867 sw_if_index=self.pg0.sw_if_index)
8868 self.vapi.nat64_add_del_interface(is_add=1, flags=0,
8869 sw_if_index=self.pg1.sw_if_index)
8870 self.vapi.nat_set_reass(timeout=2, max_reass=1024, max_frag=1,
8871 drop_frag=0, is_ip6=1)
8872 self.vapi.set_ipfix_exporter(collector_address=self.pg3.remote_ip4n,
8873 src_address=self.pg3.local_ip4n,
8875 template_interval=10)
8876 self.vapi.nat_ipfix_enable_disable(domain_id=self.ipfix_domain_id,
8877 src_port=self.ipfix_src_port,
8881 pkts = self.create_stream_frag_ip6(self.pg0, self.pg1.remote_ip4,
8882 self.tcp_port_in, 20, data)
8884 self.pg0.add_stream(pkts)
8885 self.pg_enable_capture(self.pg_interfaces)
8887 self.pg1.assert_nothing_captured()
8889 self.vapi.ipfix_flush()
8890 capture = self.pg3.get_capture(9)
8891 ipfix = IPFIXDecoder()
8892 # first load template
8894 self.assertTrue(p.haslayer(IPFIX))
8895 self.assertEqual(p[IP].src, self.pg3.local_ip4)
8896 self.assertEqual(p[IP].dst, self.pg3.remote_ip4)
8897 self.assertEqual(p[UDP].sport, self.ipfix_src_port)
8898 self.assertEqual(p[UDP].dport, 4739)
8899 self.assertEqual(p[IPFIX].observationDomainID,
8900 self.ipfix_domain_id)
8901 if p.haslayer(Template):
8902 ipfix.add_template(p.getlayer(Template))
8903 # verify events in data set
8905 if p.haslayer(Data):
8906 data = ipfix.decode_data_set(p.getlayer(Set))
8907 self.verify_ipfix_max_fragments_ip6(data, 1,
8908 self.pg0.remote_ip6n)
8910 def test_ipfix_bib_ses(self):
8911 """ IPFIX logging NAT64 BIB/session create and delete events """
8912 self.tcp_port_in = random.randint(1025, 65535)
8913 remote_host_ip6 = self.compose_ip6(self.pg1.remote_ip4,
8917 self.vapi.nat64_add_del_pool_addr_range(start_addr=self.nat_addr,
8918 end_addr=self.nat_addr,
8921 flags = self.config_flags.NAT_IS_INSIDE
8922 self.vapi.nat64_add_del_interface(is_add=1, flags=flags,
8923 sw_if_index=self.pg0.sw_if_index)
8924 self.vapi.nat64_add_del_interface(is_add=1, flags=0,
8925 sw_if_index=self.pg1.sw_if_index)
8926 self.vapi.set_ipfix_exporter(collector_address=self.pg3.remote_ip4n,
8927 src_address=self.pg3.local_ip4n,
8929 template_interval=10)
8930 self.vapi.nat_ipfix_enable_disable(domain_id=self.ipfix_domain_id,
8931 src_port=self.ipfix_src_port,
8935 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
8936 IPv6(src=self.pg0.remote_ip6, dst=remote_host_ip6) /
8937 TCP(sport=self.tcp_port_in, dport=25))
8938 self.pg0.add_stream(p)
8939 self.pg_enable_capture(self.pg_interfaces)
8941 p = self.pg1.get_capture(1)
8942 self.tcp_port_out = p[0][TCP].sport
8943 self.vapi.ipfix_flush()
8944 capture = self.pg3.get_capture(10)
8945 ipfix = IPFIXDecoder()
8946 # first load template
8948 self.assertTrue(p.haslayer(IPFIX))
8949 self.assertEqual(p[IP].src, self.pg3.local_ip4)
8950 self.assertEqual(p[IP].dst, self.pg3.remote_ip4)
8951 self.assertEqual(p[UDP].sport, self.ipfix_src_port)
8952 self.assertEqual(p[UDP].dport, 4739)
8953 self.assertEqual(p[IPFIX].observationDomainID,
8954 self.ipfix_domain_id)
8955 if p.haslayer(Template):
8956 ipfix.add_template(p.getlayer(Template))
8957 # verify events in data set
8959 if p.haslayer(Data):
8960 data = ipfix.decode_data_set(p.getlayer(Set))
8961 if scapy.compat.orb(data[0][230]) == 10:
8962 self.verify_ipfix_bib(data, 1, self.pg0.remote_ip6n)
8963 elif scapy.compat.orb(data[0][230]) == 6:
8964 self.verify_ipfix_nat64_ses(data,
8966 self.pg0.remote_ip6n,
8967 self.pg1.remote_ip4,
8970 self.logger.error(ppp("Unexpected or invalid packet: ", p))
8973 self.pg_enable_capture(self.pg_interfaces)
8974 self.vapi.nat64_add_del_pool_addr_range(start_addr=self.nat_addr,
8975 end_addr=self.nat_addr,
8978 self.vapi.ipfix_flush()
8979 capture = self.pg3.get_capture(2)
8980 # verify events in data set
8982 self.assertTrue(p.haslayer(IPFIX))
8983 self.assertEqual(p[IP].src, self.pg3.local_ip4)
8984 self.assertEqual(p[IP].dst, self.pg3.remote_ip4)
8985 self.assertEqual(p[UDP].sport, self.ipfix_src_port)
8986 self.assertEqual(p[UDP].dport, 4739)
8987 self.assertEqual(p[IPFIX].observationDomainID,
8988 self.ipfix_domain_id)
8989 if p.haslayer(Data):
8990 data = ipfix.decode_data_set(p.getlayer(Set))
8991 if scapy.compat.orb(data[0][230]) == 11:
8992 self.verify_ipfix_bib(data, 0, self.pg0.remote_ip6n)
8993 elif scapy.compat.orb(data[0][230]) == 7:
8994 self.verify_ipfix_nat64_ses(data,
8996 self.pg0.remote_ip6n,
8997 self.pg1.remote_ip4,
9000 self.logger.error(ppp("Unexpected or invalid packet: ", p))
9002 def test_syslog_sess(self):
9003 """ Test syslog session creation and deletion """
9004 self.tcp_port_in = random.randint(1025, 65535)
9005 remote_host_ip6 = self.compose_ip6(self.pg1.remote_ip4,
9009 self.vapi.nat64_add_del_pool_addr_range(start_addr=self.nat_addr,
9010 end_addr=self.nat_addr,
9013 flags = self.config_flags.NAT_IS_INSIDE
9014 self.vapi.nat64_add_del_interface(is_add=1, flags=flags,
9015 sw_if_index=self.pg0.sw_if_index)
9016 self.vapi.nat64_add_del_interface(is_add=1, flags=0,
9017 sw_if_index=self.pg1.sw_if_index)
9018 self.vapi.syslog_set_filter(
9019 self.SYSLOG_SEVERITY.SYSLOG_API_SEVERITY_INFO)
9020 self.vapi.syslog_set_sender(self.pg3.local_ip4n, self.pg3.remote_ip4n)
9022 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
9023 IPv6(src=self.pg0.remote_ip6, dst=remote_host_ip6) /
9024 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port))
9025 self.pg0.add_stream(p)
9026 self.pg_enable_capture(self.pg_interfaces)
9028 p = self.pg1.get_capture(1)
9029 self.tcp_port_out = p[0][TCP].sport
9030 capture = self.pg3.get_capture(1)
9031 self.verify_syslog_sess(capture[0][Raw].load, is_ip6=True)
9033 self.pg_enable_capture(self.pg_interfaces)
9035 self.vapi.nat64_add_del_pool_addr_range(start_addr=self.nat_addr,
9036 end_addr=self.nat_addr,
9039 capture = self.pg3.get_capture(1)
9040 self.verify_syslog_sess(capture[0][Raw].load, False, True)
9042 def nat64_get_ses_num(self):
9044 Return number of active NAT64 sessions.
9046 st = self.vapi.nat64_st_dump(proto=255)
9049 def clear_nat64(self):
9051 Clear NAT64 configuration.
9053 self.vapi.nat_ipfix_enable_disable(domain_id=self.ipfix_domain_id,
9054 src_port=self.ipfix_src_port,
9056 self.ipfix_src_port = 4739
9057 self.ipfix_domain_id = 1
9059 self.vapi.syslog_set_filter(
9060 self.SYSLOG_SEVERITY.SYSLOG_API_SEVERITY_EMERG)
9062 self.vapi.nat_set_timeouts(udp=300, tcp_established=7440,
9063 tcp_transitory=240, icmp=60)
9065 interfaces = self.vapi.nat64_interface_dump()
9066 for intf in interfaces:
9067 self.vapi.nat64_add_del_interface(is_add=0, flags=intf.flags,
9068 sw_if_index=intf.sw_if_index)
9070 bib = self.vapi.nat64_bib_dump(proto=255)
9072 if bibe.flags & self.config_flags.NAT_IS_STATIC:
9073 self.vapi.nat64_add_del_static_bib(i_addr=bibe.i_addr,
9081 adresses = self.vapi.nat64_pool_addr_dump()
9082 for addr in adresses:
9083 self.vapi.nat64_add_del_pool_addr_range(start_addr=addr.address,
9084 end_addr=addr.address,
9088 prefixes = self.vapi.nat64_prefix_dump()
9089 for prefix in prefixes:
9090 self.vapi.nat64_add_del_prefix(prefix=str(prefix.prefix),
9091 vrf_id=prefix.vrf_id, is_add=0)
9093 bibs = self.statistics.get_counter('/nat64/total-bibs')
9094 self.assertEqual(bibs[0][0], 0)
9095 sessions = self.statistics.get_counter('/nat64/total-sessions')
9096 self.assertEqual(sessions[0][0], 0)
9099 super(TestNAT64, self).tearDown()
9100 if not self.vpp_dead:
9103 def show_commands_at_teardown(self):
9104 self.logger.info(self.vapi.cli("show nat64 pool"))
9105 self.logger.info(self.vapi.cli("show nat64 interfaces"))
9106 self.logger.info(self.vapi.cli("show nat64 prefix"))
9107 self.logger.info(self.vapi.cli("show nat64 bib all"))
9108 self.logger.info(self.vapi.cli("show nat64 session table all"))
9109 self.logger.info(self.vapi.cli("show nat virtual-reassembly"))
9112 class TestDSlite(MethodHolder):
9113 """ DS-Lite Test Cases """
9116 def setUpClass(cls):
9117 super(TestDSlite, cls).setUpClass()
9120 cls.nat_addr = '10.0.0.3'
9122 cls.create_pg_interfaces(range(3))
9124 cls.pg0.config_ip4()
9125 cls.pg0.resolve_arp()
9127 cls.pg1.config_ip6()
9128 cls.pg1.generate_remote_hosts(2)
9129 cls.pg1.configure_ipv6_neighbors()
9131 cls.pg2.config_ip4()
9132 cls.pg2.resolve_arp()
9135 super(TestDSlite, cls).tearDownClass()
9139 def tearDownClass(cls):
9140 super(TestDSlite, cls).tearDownClass()
9142 def verify_syslog_apmadd(self, data, isaddr, isport, xsaddr, xsport,
9144 message = data.decode('utf-8')
9146 message = SyslogMessage.parse(message)
9147 except ParseError as e:
9148 self.logger.error(e)
9150 self.assertEqual(message.severity, SyslogSeverity.info)
9151 self.assertEqual(message.appname, 'NAT')
9152 self.assertEqual(message.msgid, 'APMADD')
9153 sd_params = message.sd.get('napmap')
9154 self.assertTrue(sd_params is not None)
9155 self.assertEqual(sd_params.get('IATYP'), 'IPv4')
9156 self.assertEqual(sd_params.get('ISADDR'), isaddr)
9157 self.assertEqual(sd_params.get('ISPORT'), "%d" % isport)
9158 self.assertEqual(sd_params.get('XATYP'), 'IPv4')
9159 self.assertEqual(sd_params.get('XSADDR'), xsaddr)
9160 self.assertEqual(sd_params.get('XSPORT'), "%d" % xsport)
9161 self.assertEqual(sd_params.get('PROTO'), "%d" % proto)
9162 self.assertTrue(sd_params.get('SSUBIX') is not None)
9163 self.assertEqual(sd_params.get('SV6ENC'), sv6enc)
9165 def test_dslite(self):
9166 """ Test DS-Lite """
9167 nat_config = self.vapi.nat_show_config()
9168 self.assertEqual(0, nat_config.dslite_ce)
9170 self.vapi.dslite_add_del_pool_addr_range(start_addr=self.nat_addr,
9171 end_addr=self.nat_addr,
9173 aftr_ip4 = '192.0.0.1'
9174 aftr_ip6 = '2001:db8:85a3::8a2e:370:1'
9175 self.vapi.dslite_set_aftr_addr(ip4_addr=aftr_ip4, ip6_addr=aftr_ip6)
9176 self.vapi.syslog_set_sender(self.pg2.local_ip4n, self.pg2.remote_ip4n)
9179 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
9180 IPv6(dst=aftr_ip6, src=self.pg1.remote_hosts[0].ip6) /
9181 IP(dst=self.pg0.remote_ip4, src='192.168.1.1') /
9182 UDP(sport=20000, dport=10000))
9183 self.pg1.add_stream(p)
9184 self.pg_enable_capture(self.pg_interfaces)
9186 capture = self.pg0.get_capture(1)
9187 capture = capture[0]
9188 self.assertFalse(capture.haslayer(IPv6))
9189 self.assertEqual(capture[IP].src, self.nat_addr)
9190 self.assertEqual(capture[IP].dst, self.pg0.remote_ip4)
9191 self.assertNotEqual(capture[UDP].sport, 20000)
9192 self.assertEqual(capture[UDP].dport, 10000)
9193 self.assert_packet_checksums_valid(capture)
9194 out_port = capture[UDP].sport
9195 capture = self.pg2.get_capture(1)
9196 self.verify_syslog_apmadd(capture[0][Raw].load, '192.168.1.1',
9197 20000, self.nat_addr, out_port,
9198 self.pg1.remote_hosts[0].ip6, IP_PROTOS.udp)
9200 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
9201 IP(dst=self.nat_addr, src=self.pg0.remote_ip4) /
9202 UDP(sport=10000, dport=out_port))
9203 self.pg0.add_stream(p)
9204 self.pg_enable_capture(self.pg_interfaces)
9206 capture = self.pg1.get_capture(1)
9207 capture = capture[0]
9208 self.assertEqual(capture[IPv6].src, aftr_ip6)
9209 self.assertEqual(capture[IPv6].dst, self.pg1.remote_hosts[0].ip6)
9210 self.assertEqual(capture[IP].src, self.pg0.remote_ip4)
9211 self.assertEqual(capture[IP].dst, '192.168.1.1')
9212 self.assertEqual(capture[UDP].sport, 10000)
9213 self.assertEqual(capture[UDP].dport, 20000)
9214 self.assert_packet_checksums_valid(capture)
9217 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
9218 IPv6(dst=aftr_ip6, src=self.pg1.remote_hosts[1].ip6) /
9219 IP(dst=self.pg0.remote_ip4, src='192.168.1.1') /
9220 TCP(sport=20001, dport=10001))
9221 self.pg1.add_stream(p)
9222 self.pg_enable_capture(self.pg_interfaces)
9224 capture = self.pg0.get_capture(1)
9225 capture = capture[0]
9226 self.assertFalse(capture.haslayer(IPv6))
9227 self.assertEqual(capture[IP].src, self.nat_addr)
9228 self.assertEqual(capture[IP].dst, self.pg0.remote_ip4)
9229 self.assertNotEqual(capture[TCP].sport, 20001)
9230 self.assertEqual(capture[TCP].dport, 10001)
9231 self.assert_packet_checksums_valid(capture)
9232 out_port = capture[TCP].sport
9234 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
9235 IP(dst=self.nat_addr, src=self.pg0.remote_ip4) /
9236 TCP(sport=10001, dport=out_port))
9237 self.pg0.add_stream(p)
9238 self.pg_enable_capture(self.pg_interfaces)
9240 capture = self.pg1.get_capture(1)
9241 capture = capture[0]
9242 self.assertEqual(capture[IPv6].src, aftr_ip6)
9243 self.assertEqual(capture[IPv6].dst, self.pg1.remote_hosts[1].ip6)
9244 self.assertEqual(capture[IP].src, self.pg0.remote_ip4)
9245 self.assertEqual(capture[IP].dst, '192.168.1.1')
9246 self.assertEqual(capture[TCP].sport, 10001)
9247 self.assertEqual(capture[TCP].dport, 20001)
9248 self.assert_packet_checksums_valid(capture)
9251 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
9252 IPv6(dst=aftr_ip6, src=self.pg1.remote_hosts[1].ip6) /
9253 IP(dst=self.pg0.remote_ip4, src='192.168.1.1') /
9254 ICMP(id=4000, type='echo-request'))
9255 self.pg1.add_stream(p)
9256 self.pg_enable_capture(self.pg_interfaces)
9258 capture = self.pg0.get_capture(1)
9259 capture = capture[0]
9260 self.assertFalse(capture.haslayer(IPv6))
9261 self.assertEqual(capture[IP].src, self.nat_addr)
9262 self.assertEqual(capture[IP].dst, self.pg0.remote_ip4)
9263 self.assertNotEqual(capture[ICMP].id, 4000)
9264 self.assert_packet_checksums_valid(capture)
9265 out_id = capture[ICMP].id
9267 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
9268 IP(dst=self.nat_addr, src=self.pg0.remote_ip4) /
9269 ICMP(id=out_id, type='echo-reply'))
9270 self.pg0.add_stream(p)
9271 self.pg_enable_capture(self.pg_interfaces)
9273 capture = self.pg1.get_capture(1)
9274 capture = capture[0]
9275 self.assertEqual(capture[IPv6].src, aftr_ip6)
9276 self.assertEqual(capture[IPv6].dst, self.pg1.remote_hosts[1].ip6)
9277 self.assertEqual(capture[IP].src, self.pg0.remote_ip4)
9278 self.assertEqual(capture[IP].dst, '192.168.1.1')
9279 self.assertEqual(capture[ICMP].id, 4000)
9280 self.assert_packet_checksums_valid(capture)
9282 # ping DS-Lite AFTR tunnel endpoint address
9283 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
9284 IPv6(src=self.pg1.remote_hosts[1].ip6, dst=aftr_ip6) /
9285 ICMPv6EchoRequest())
9286 self.pg1.add_stream(p)
9287 self.pg_enable_capture(self.pg_interfaces)
9289 capture = self.pg1.get_capture(1)
9290 capture = capture[0]
9291 self.assertEqual(capture[IPv6].src, aftr_ip6)
9292 self.assertEqual(capture[IPv6].dst, self.pg1.remote_hosts[1].ip6)
9293 self.assertTrue(capture.haslayer(ICMPv6EchoReply))
9295 b4s = self.statistics.get_counter('/dslite/total-b4s')
9296 self.assertEqual(b4s[0][0], 2)
9297 sessions = self.statistics.get_counter('/dslite/total-sessions')
9298 self.assertEqual(sessions[0][0], 3)
9301 super(TestDSlite, self).tearDown()
9303 def show_commands_at_teardown(self):
9304 self.logger.info(self.vapi.cli("show dslite pool"))
9306 self.vapi.cli("show dslite aftr-tunnel-endpoint-address"))
9307 self.logger.info(self.vapi.cli("show dslite sessions"))
9310 class TestDSliteCE(MethodHolder):
9311 """ DS-Lite CE Test Cases """
9314 def setUpConstants(cls):
9315 super(TestDSliteCE, cls).setUpConstants()
9316 cls.vpp_cmdline.extend(["nat", "{", "dslite ce", "}"])
9319 def setUpClass(cls):
9320 super(TestDSliteCE, cls).setUpClass()
9323 cls.create_pg_interfaces(range(2))
9325 cls.pg0.config_ip4()
9326 cls.pg0.resolve_arp()
9328 cls.pg1.config_ip6()
9329 cls.pg1.generate_remote_hosts(1)
9330 cls.pg1.configure_ipv6_neighbors()
9333 super(TestDSliteCE, cls).tearDownClass()
9337 def tearDownClass(cls):
9338 super(TestDSliteCE, cls).tearDownClass()
9340 def test_dslite_ce(self):
9341 """ Test DS-Lite CE """
9343 nat_config = self.vapi.nat_show_config()
9344 self.assertEqual(1, nat_config.dslite_ce)
9346 b4_ip4 = '192.0.0.2'
9347 b4_ip6 = '2001:db8:62aa::375e:f4c1:1'
9348 self.vapi.dslite_set_b4_addr(ip4_addr=b4_ip4, ip6_addr=b4_ip6)
9350 aftr_ip4 = '192.0.0.1'
9351 aftr_ip6 = '2001:db8:85a3::8a2e:370:1'
9352 aftr_ip6_n = socket.inet_pton(socket.AF_INET6, aftr_ip6)
9353 self.vapi.dslite_set_aftr_addr(ip4_addr=aftr_ip4, ip6_addr=aftr_ip6)
9355 r1 = VppIpRoute(self, aftr_ip6, 128,
9356 [VppRoutePath(self.pg1.remote_ip6,
9357 self.pg1.sw_if_index)])
9361 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
9362 IP(dst=self.pg1.remote_ip4, src=self.pg0.remote_ip4) /
9363 UDP(sport=10000, dport=20000))
9364 self.pg0.add_stream(p)
9365 self.pg_enable_capture(self.pg_interfaces)
9367 capture = self.pg1.get_capture(1)
9368 capture = capture[0]
9369 self.assertEqual(capture[IPv6].src, b4_ip6)
9370 self.assertEqual(capture[IPv6].dst, aftr_ip6)
9371 self.assertEqual(capture[IP].src, self.pg0.remote_ip4)
9372 self.assertEqual(capture[IP].dst, self.pg1.remote_ip4)
9373 self.assertEqual(capture[UDP].sport, 10000)
9374 self.assertEqual(capture[UDP].dport, 20000)
9375 self.assert_packet_checksums_valid(capture)
9378 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
9379 IPv6(dst=b4_ip6, src=aftr_ip6) /
9380 IP(dst=self.pg0.remote_ip4, src=self.pg1.remote_ip4) /
9381 UDP(sport=20000, dport=10000))
9382 self.pg1.add_stream(p)
9383 self.pg_enable_capture(self.pg_interfaces)
9385 capture = self.pg0.get_capture(1)
9386 capture = capture[0]
9387 self.assertFalse(capture.haslayer(IPv6))
9388 self.assertEqual(capture[IP].src, self.pg1.remote_ip4)
9389 self.assertEqual(capture[IP].dst, self.pg0.remote_ip4)
9390 self.assertEqual(capture[UDP].sport, 20000)
9391 self.assertEqual(capture[UDP].dport, 10000)
9392 self.assert_packet_checksums_valid(capture)
9394 # ping DS-Lite B4 tunnel endpoint address
9395 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
9396 IPv6(src=self.pg1.remote_hosts[0].ip6, dst=b4_ip6) /
9397 ICMPv6EchoRequest())
9398 self.pg1.add_stream(p)
9399 self.pg_enable_capture(self.pg_interfaces)
9401 capture = self.pg1.get_capture(1)
9402 capture = capture[0]
9403 self.assertEqual(capture[IPv6].src, b4_ip6)
9404 self.assertEqual(capture[IPv6].dst, self.pg1.remote_hosts[0].ip6)
9405 self.assertTrue(capture.haslayer(ICMPv6EchoReply))
9408 super(TestDSliteCE, self).tearDown()
9410 def show_commands_at_teardown(self):
9412 self.vapi.cli("show dslite aftr-tunnel-endpoint-address"))
9414 self.vapi.cli("show dslite b4-tunnel-endpoint-address"))
9417 class TestNAT66(MethodHolder):
9418 """ NAT66 Test Cases """
9421 def setUpClass(cls):
9422 super(TestNAT66, cls).setUpClass()
9425 cls.nat_addr = 'fd01:ff::2'
9427 cls.create_pg_interfaces(range(2))
9428 cls.interfaces = list(cls.pg_interfaces)
9430 for i in cls.interfaces:
9433 i.configure_ipv6_neighbors()
9436 super(TestNAT66, cls).tearDownClass()
9440 def tearDownClass(cls):
9441 super(TestNAT66, cls).tearDownClass()
9443 def test_static(self):
9444 """ 1:1 NAT66 test """
9445 flags = self.config_flags.NAT_IS_INSIDE
9446 self.vapi.nat66_add_del_interface(is_add=1, flags=flags,
9447 sw_if_index=self.pg0.sw_if_index)
9448 self.vapi.nat66_add_del_interface(is_add=1,
9449 sw_if_index=self.pg1.sw_if_index)
9450 self.vapi.nat66_add_del_static_mapping(
9451 local_ip_address=self.pg0.remote_ip6n,
9452 external_ip_address=self.nat_addr,
9457 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
9458 IPv6(src=self.pg0.remote_ip6, dst=self.pg1.remote_ip6) /
9461 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
9462 IPv6(src=self.pg0.remote_ip6, dst=self.pg1.remote_ip6) /
9465 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
9466 IPv6(src=self.pg0.remote_ip6, dst=self.pg1.remote_ip6) /
9467 ICMPv6EchoRequest())
9469 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
9470 IPv6(src=self.pg0.remote_ip6, dst=self.pg1.remote_ip6) /
9471 GRE() / IP() / TCP())
9473 self.pg0.add_stream(pkts)
9474 self.pg_enable_capture(self.pg_interfaces)
9476 capture = self.pg1.get_capture(len(pkts))
9477 for packet in capture:
9479 self.assertEqual(packet[IPv6].src, self.nat_addr)
9480 self.assertEqual(packet[IPv6].dst, self.pg1.remote_ip6)
9481 self.assert_packet_checksums_valid(packet)
9483 self.logger.error(ppp("Unexpected or invalid packet:", packet))
9488 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
9489 IPv6(src=self.pg1.remote_ip6, dst=self.nat_addr) /
9492 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
9493 IPv6(src=self.pg1.remote_ip6, dst=self.nat_addr) /
9496 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
9497 IPv6(src=self.pg1.remote_ip6, dst=self.nat_addr) /
9500 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
9501 IPv6(src=self.pg1.remote_ip6, dst=self.nat_addr) /
9502 GRE() / IP() / TCP())
9504 self.pg1.add_stream(pkts)
9505 self.pg_enable_capture(self.pg_interfaces)
9507 capture = self.pg0.get_capture(len(pkts))
9508 for packet in capture:
9510 self.assertEqual(packet[IPv6].src, self.pg1.remote_ip6)
9511 self.assertEqual(packet[IPv6].dst, self.pg0.remote_ip6)
9512 self.assert_packet_checksums_valid(packet)
9514 self.logger.error(ppp("Unexpected or invalid packet:", packet))
9517 sm = self.vapi.nat66_static_mapping_dump()
9518 self.assertEqual(len(sm), 1)
9519 self.assertEqual(sm[0].total_pkts, 8)
9521 def test_check_no_translate(self):
9522 """ NAT66 translate only when egress interface is outside interface """
9523 flags = self.config_flags.NAT_IS_INSIDE
9524 self.vapi.nat66_add_del_interface(is_add=1, flags=flags,
9525 sw_if_index=self.pg0.sw_if_index)
9526 self.vapi.nat66_add_del_interface(is_add=1, flags=flags,
9527 sw_if_index=self.pg1.sw_if_index)
9528 self.vapi.nat66_add_del_static_mapping(
9529 local_ip_address=self.pg0.remote_ip6n,
9530 external_ip_address=self.nat_addr,
9534 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
9535 IPv6(src=self.pg0.remote_ip6, dst=self.pg1.remote_ip6) /
9537 self.pg0.add_stream([p])
9538 self.pg_enable_capture(self.pg_interfaces)
9540 capture = self.pg1.get_capture(1)
9543 self.assertEqual(packet[IPv6].src, self.pg0.remote_ip6)
9544 self.assertEqual(packet[IPv6].dst, self.pg1.remote_ip6)
9546 self.logger.error(ppp("Unexpected or invalid packet:", packet))
9549 def clear_nat66(self):
9551 Clear NAT66 configuration.
9553 interfaces = self.vapi.nat66_interface_dump()
9554 for intf in interfaces:
9555 self.vapi.nat66_add_del_interface(is_add=0, flags=intf.flags,
9556 sw_if_index=intf.sw_if_index)
9558 static_mappings = self.vapi.nat66_static_mapping_dump()
9559 for sm in static_mappings:
9560 self.vapi.nat66_add_del_static_mapping(
9561 local_ip_address=sm.local_ip_address,
9562 external_ip_address=sm.external_ip_address, vrf_id=sm.vrf_id,
9566 super(TestNAT66, self).tearDown()
9569 def show_commands_at_teardown(self):
9570 self.logger.info(self.vapi.cli("show nat66 interfaces"))
9571 self.logger.info(self.vapi.cli("show nat66 static mappings"))
9574 if __name__ == '__main__':
9575 unittest.main(testRunner=VppTestRunner)