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, '')
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(9))
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 cls.pg7.config_ip4()
4498 cls.pg7.resolve_arp()
4499 cls.pg7.generate_remote_hosts(3)
4500 cls.pg7.configure_ipv4_neighbors()
4503 cls.pg8.config_ip4()
4504 cls.pg8.resolve_arp()
4507 super(TestNAT44EndpointDependent, cls).tearDownClass()
4511 def tearDownClass(cls):
4512 super(TestNAT44EndpointDependent, cls).tearDownClass()
4514 def test_frag_in_order(self):
4515 """ NAT44 translate fragments arriving in order """
4516 self.nat44_add_address(self.nat_addr)
4517 flags = self.config_flags.NAT_IS_INSIDE
4518 self.vapi.nat44_interface_add_del_feature(
4519 sw_if_index=self.pg0.sw_if_index,
4520 flags=flags, is_add=1)
4521 self.vapi.nat44_interface_add_del_feature(
4522 sw_if_index=self.pg1.sw_if_index,
4524 self.frag_in_order(proto=IP_PROTOS.tcp)
4525 self.frag_in_order(proto=IP_PROTOS.udp)
4526 self.frag_in_order(proto=IP_PROTOS.icmp)
4528 def test_frag_in_order_dont_translate(self):
4529 """ NAT44 don't translate fragments arriving in order """
4530 flags = self.config_flags.NAT_IS_INSIDE
4531 self.vapi.nat44_interface_add_del_feature(
4532 sw_if_index=self.pg0.sw_if_index,
4533 flags=flags, is_add=1)
4534 self.vapi.nat44_interface_add_del_feature(
4535 sw_if_index=self.pg1.sw_if_index,
4537 self.vapi.nat44_forwarding_enable_disable(enable=True)
4538 reas_cfg1 = self.vapi.nat_get_reass()
4539 # this test was intermittently failing in some cases
4540 # until we temporarily bump the reassembly timeouts
4541 self.vapi.nat_set_reass(timeout=20, max_reass=1024, max_frag=5,
4543 self.frag_in_order(proto=IP_PROTOS.tcp, dont_translate=True)
4544 # restore the reassembly timeouts
4545 self.vapi.nat_set_reass(timeout=reas_cfg1.ip4_timeout,
4546 max_reass=reas_cfg1.ip4_max_reass,
4547 max_frag=reas_cfg1.ip4_max_frag,
4548 drop_frag=reas_cfg1.ip4_drop_frag)
4550 def test_frag_out_of_order(self):
4551 """ NAT44 translate fragments arriving out of order """
4552 self.nat44_add_address(self.nat_addr)
4553 flags = self.config_flags.NAT_IS_INSIDE
4554 self.vapi.nat44_interface_add_del_feature(
4555 sw_if_index=self.pg0.sw_if_index,
4556 flags=flags, is_add=1)
4557 self.vapi.nat44_interface_add_del_feature(
4558 sw_if_index=self.pg1.sw_if_index,
4560 self.frag_out_of_order(proto=IP_PROTOS.tcp)
4561 self.frag_out_of_order(proto=IP_PROTOS.udp)
4562 self.frag_out_of_order(proto=IP_PROTOS.icmp)
4564 def test_frag_out_of_order_dont_translate(self):
4565 """ NAT44 don't translate fragments arriving out of order """
4566 flags = self.config_flags.NAT_IS_INSIDE
4567 self.vapi.nat44_interface_add_del_feature(
4568 sw_if_index=self.pg0.sw_if_index,
4569 flags=flags, is_add=1)
4570 self.vapi.nat44_interface_add_del_feature(
4571 sw_if_index=self.pg1.sw_if_index,
4573 self.vapi.nat44_forwarding_enable_disable(enable=True)
4574 self.frag_out_of_order(proto=IP_PROTOS.tcp, dont_translate=True)
4576 def test_frag_in_order_in_plus_out(self):
4577 """ in+out interface fragments in order """
4578 flags = self.config_flags.NAT_IS_INSIDE
4579 self.vapi.nat44_interface_add_del_feature(
4580 sw_if_index=self.pg0.sw_if_index,
4582 self.vapi.nat44_interface_add_del_feature(
4583 sw_if_index=self.pg0.sw_if_index,
4584 flags=flags, is_add=1)
4585 self.vapi.nat44_interface_add_del_feature(
4586 sw_if_index=self.pg1.sw_if_index,
4588 self.vapi.nat44_interface_add_del_feature(
4589 sw_if_index=self.pg1.sw_if_index,
4590 flags=flags, is_add=1)
4592 self.server = self.pg1.remote_hosts[0]
4594 self.server_in_addr = self.server.ip4
4595 self.server_out_addr = '11.11.11.11'
4596 self.server_in_port = random.randint(1025, 65535)
4597 self.server_out_port = random.randint(1025, 65535)
4599 self.nat44_add_address(self.server_out_addr)
4601 # add static mappings for server
4602 self.nat44_add_static_mapping(self.server_in_addr,
4603 self.server_out_addr,
4604 self.server_in_port,
4605 self.server_out_port,
4606 proto=IP_PROTOS.tcp)
4607 self.nat44_add_static_mapping(self.server_in_addr,
4608 self.server_out_addr,
4609 self.server_in_port,
4610 self.server_out_port,
4611 proto=IP_PROTOS.udp)
4612 self.nat44_add_static_mapping(self.server_in_addr,
4613 self.server_out_addr,
4614 proto=IP_PROTOS.icmp)
4616 self.vapi.nat_set_reass(timeout=10, max_reass=1024, max_frag=5,
4619 self.frag_in_order_in_plus_out(proto=IP_PROTOS.tcp)
4620 self.frag_in_order_in_plus_out(proto=IP_PROTOS.udp)
4621 self.frag_in_order_in_plus_out(proto=IP_PROTOS.icmp)
4623 def test_frag_out_of_order_in_plus_out(self):
4624 """ in+out interface fragments out of order """
4625 flags = self.config_flags.NAT_IS_INSIDE
4626 self.vapi.nat44_interface_add_del_feature(
4627 sw_if_index=self.pg0.sw_if_index,
4629 self.vapi.nat44_interface_add_del_feature(
4630 sw_if_index=self.pg0.sw_if_index,
4631 flags=flags, is_add=1)
4632 self.vapi.nat44_interface_add_del_feature(
4633 sw_if_index=self.pg1.sw_if_index,
4635 self.vapi.nat44_interface_add_del_feature(
4636 sw_if_index=self.pg1.sw_if_index,
4637 flags=flags, is_add=1)
4639 self.server = self.pg1.remote_hosts[0]
4641 self.server_in_addr = self.server.ip4
4642 self.server_out_addr = '11.11.11.11'
4643 self.server_in_port = random.randint(1025, 65535)
4644 self.server_out_port = random.randint(1025, 65535)
4646 self.nat44_add_address(self.server_out_addr)
4648 # add static mappings for server
4649 self.nat44_add_static_mapping(self.server_in_addr,
4650 self.server_out_addr,
4651 self.server_in_port,
4652 self.server_out_port,
4653 proto=IP_PROTOS.tcp)
4654 self.nat44_add_static_mapping(self.server_in_addr,
4655 self.server_out_addr,
4656 self.server_in_port,
4657 self.server_out_port,
4658 proto=IP_PROTOS.udp)
4659 self.nat44_add_static_mapping(self.server_in_addr,
4660 self.server_out_addr,
4661 proto=IP_PROTOS.icmp)
4663 self.vapi.nat_set_reass(timeout=10, max_reass=1024, max_frag=5,
4666 self.frag_out_of_order_in_plus_out(proto=IP_PROTOS.tcp)
4667 self.frag_out_of_order_in_plus_out(proto=IP_PROTOS.udp)
4668 self.frag_out_of_order_in_plus_out(proto=IP_PROTOS.icmp)
4670 def test_reass_hairpinning(self):
4671 """ NAT44 fragments hairpinning """
4672 self.server = self.pg0.remote_hosts[1]
4673 self.host_in_port = random.randint(1025, 65535)
4674 self.server_in_port = random.randint(1025, 65535)
4675 self.server_out_port = random.randint(1025, 65535)
4677 self.nat44_add_address(self.nat_addr)
4678 flags = self.config_flags.NAT_IS_INSIDE
4679 self.vapi.nat44_interface_add_del_feature(
4680 sw_if_index=self.pg0.sw_if_index,
4681 flags=flags, is_add=1)
4682 self.vapi.nat44_interface_add_del_feature(
4683 sw_if_index=self.pg1.sw_if_index,
4685 # add static mapping for server
4686 self.nat44_add_static_mapping(self.server.ip4, self.nat_addr,
4687 self.server_in_port,
4688 self.server_out_port,
4689 proto=IP_PROTOS.tcp)
4690 self.nat44_add_static_mapping(self.server.ip4, self.nat_addr,
4691 self.server_in_port,
4692 self.server_out_port,
4693 proto=IP_PROTOS.udp)
4694 self.nat44_add_static_mapping(self.server.ip4, self.nat_addr)
4696 self.reass_hairpinning(proto=IP_PROTOS.tcp)
4697 self.reass_hairpinning(proto=IP_PROTOS.udp)
4698 self.reass_hairpinning(proto=IP_PROTOS.icmp)
4700 def test_dynamic(self):
4701 """ NAT44 dynamic translation test """
4703 self.nat44_add_address(self.nat_addr)
4704 flags = self.config_flags.NAT_IS_INSIDE
4705 self.vapi.nat44_interface_add_del_feature(
4706 sw_if_index=self.pg0.sw_if_index,
4707 flags=flags, is_add=1)
4708 self.vapi.nat44_interface_add_del_feature(
4709 sw_if_index=self.pg1.sw_if_index,
4712 nat_config = self.vapi.nat_show_config()
4713 self.assertEqual(1, nat_config.endpoint_dependent)
4716 tcpn = self.statistics.get_err_counter(
4717 '/err/nat44-ed-in2out-slowpath/TCP packets')
4718 udpn = self.statistics.get_err_counter(
4719 '/err/nat44-ed-in2out-slowpath/UDP packets')
4720 icmpn = self.statistics.get_err_counter(
4721 '/err/nat44-ed-in2out-slowpath/ICMP packets')
4722 totaln = self.statistics.get_err_counter(
4723 '/err/nat44-ed-in2out-slowpath/good in2out packets processed')
4725 pkts = self.create_stream_in(self.pg0, self.pg1)
4726 self.pg0.add_stream(pkts)
4727 self.pg_enable_capture(self.pg_interfaces)
4729 capture = self.pg1.get_capture(len(pkts))
4730 self.verify_capture_out(capture)
4732 err = self.statistics.get_err_counter(
4733 '/err/nat44-ed-in2out-slowpath/TCP packets')
4734 self.assertEqual(err - tcpn, 1)
4735 err = self.statistics.get_err_counter(
4736 '/err/nat44-ed-in2out-slowpath/UDP packets')
4737 self.assertEqual(err - udpn, 1)
4738 err = self.statistics.get_err_counter(
4739 '/err/nat44-ed-in2out-slowpath/ICMP packets')
4740 self.assertEqual(err - icmpn, 1)
4741 err = self.statistics.get_err_counter(
4742 '/err/nat44-ed-in2out-slowpath/good in2out packets processed')
4743 self.assertEqual(err - totaln, 3)
4746 tcpn = self.statistics.get_err_counter(
4747 '/err/nat44-ed-out2in/TCP packets')
4748 udpn = self.statistics.get_err_counter(
4749 '/err/nat44-ed-out2in/UDP packets')
4750 icmpn = self.statistics.get_err_counter(
4751 '/err/nat44-ed-out2in-slowpath/ICMP packets')
4752 totaln = self.statistics.get_err_counter(
4753 '/err/nat44-ed-out2in/good out2in packets processed')
4755 pkts = self.create_stream_out(self.pg1)
4756 self.pg1.add_stream(pkts)
4757 self.pg_enable_capture(self.pg_interfaces)
4759 capture = self.pg0.get_capture(len(pkts))
4760 self.verify_capture_in(capture, self.pg0)
4762 err = self.statistics.get_err_counter(
4763 '/err/nat44-ed-out2in/TCP packets')
4764 self.assertEqual(err - tcpn, 1)
4765 err = self.statistics.get_err_counter(
4766 '/err/nat44-ed-out2in/UDP packets')
4767 self.assertEqual(err - udpn, 1)
4768 err = self.statistics.get_err_counter(
4769 '/err/nat44-ed-out2in-slowpath/ICMP packets')
4770 self.assertEqual(err - icmpn, 1)
4771 err = self.statistics.get_err_counter(
4772 '/err/nat44-ed-out2in/good out2in packets processed')
4773 self.assertEqual(err - totaln, 2)
4775 users = self.statistics.get_counter('/nat44/total-users')
4776 self.assertEqual(users[0][0], 1)
4777 sessions = self.statistics.get_counter('/nat44/total-sessions')
4778 self.assertEqual(sessions[0][0], 3)
4780 def test_dynamic_output_feature_vrf(self):
4781 """ NAT44 dynamic translation test: output-feature, VRF"""
4783 # other then default (0)
4786 self.nat44_add_address(self.nat_addr)
4787 flags = self.config_flags.NAT_IS_INSIDE
4788 self.vapi.nat44_interface_add_del_output_feature(
4789 sw_if_index=self.pg7.sw_if_index,
4790 flags=flags, is_add=1)
4791 self.vapi.nat44_interface_add_del_output_feature(
4792 sw_if_index=self.pg8.sw_if_index,
4796 self.vapi.ip_table_add_del(is_add=1, table_id=new_vrf_id)
4798 self.pg7.unconfig_ip4()
4799 self.pg7.set_table_ip4(new_vrf_id)
4800 self.pg7.config_ip4()
4801 self.pg7.resolve_arp()
4803 self.pg8.unconfig_ip4()
4804 self.pg8.set_table_ip4(new_vrf_id)
4805 self.pg8.config_ip4()
4806 self.pg8.resolve_arp()
4808 nat_config = self.vapi.nat_show_config()
4809 self.assertEqual(1, nat_config.endpoint_dependent)
4812 tcpn = self.statistics.get_err_counter(
4813 '/err/nat44-ed-in2out-slowpath/TCP packets')
4814 udpn = self.statistics.get_err_counter(
4815 '/err/nat44-ed-in2out-slowpath/UDP packets')
4816 icmpn = self.statistics.get_err_counter(
4817 '/err/nat44-ed-in2out-slowpath/ICMP packets')
4818 totaln = self.statistics.get_err_counter(
4819 '/err/nat44-ed-in2out-slowpath/good in2out packets processed')
4821 pkts = self.create_stream_in(self.pg7, self.pg8)
4822 self.pg7.add_stream(pkts)
4823 self.pg_enable_capture(self.pg_interfaces)
4825 capture = self.pg8.get_capture(len(pkts))
4826 self.verify_capture_out(capture)
4828 err = self.statistics.get_err_counter(
4829 '/err/nat44-ed-in2out-slowpath/TCP packets')
4830 self.assertEqual(err - tcpn, 1)
4831 err = self.statistics.get_err_counter(
4832 '/err/nat44-ed-in2out-slowpath/UDP packets')
4833 self.assertEqual(err - udpn, 1)
4834 err = self.statistics.get_err_counter(
4835 '/err/nat44-ed-in2out-slowpath/ICMP packets')
4836 self.assertEqual(err - icmpn, 1)
4837 err = self.statistics.get_err_counter(
4838 '/err/nat44-ed-in2out-slowpath/good in2out packets processed')
4839 self.assertEqual(err - totaln, 3)
4842 tcpn = self.statistics.get_err_counter(
4843 '/err/nat44-ed-out2in/TCP packets')
4844 udpn = self.statistics.get_err_counter(
4845 '/err/nat44-ed-out2in/UDP packets')
4846 icmpn = self.statistics.get_err_counter(
4847 '/err/nat44-ed-out2in-slowpath/ICMP packets')
4848 totaln = self.statistics.get_err_counter(
4849 '/err/nat44-ed-out2in/good out2in packets processed')
4851 pkts = self.create_stream_out(self.pg8)
4852 self.pg8.add_stream(pkts)
4853 self.pg_enable_capture(self.pg_interfaces)
4855 capture = self.pg7.get_capture(len(pkts))
4856 self.verify_capture_in(capture, self.pg7)
4858 err = self.statistics.get_err_counter(
4859 '/err/nat44-ed-out2in/TCP packets')
4860 self.assertEqual(err - tcpn, 1)
4861 err = self.statistics.get_err_counter(
4862 '/err/nat44-ed-out2in/UDP packets')
4863 self.assertEqual(err - udpn, 1)
4864 err = self.statistics.get_err_counter(
4865 '/err/nat44-ed-out2in-slowpath/ICMP packets')
4866 self.assertEqual(err - icmpn, 1)
4867 err = self.statistics.get_err_counter(
4868 '/err/nat44-ed-out2in/good out2in packets processed')
4869 self.assertEqual(err - totaln, 2)
4871 users = self.statistics.get_counter('/nat44/total-users')
4872 self.assertEqual(users[0][0], 1)
4873 sessions = self.statistics.get_counter('/nat44/total-sessions')
4874 self.assertEqual(sessions[0][0], 3)
4877 self.pg7.unconfig_ip4()
4878 self.pg7.set_table_ip4(1)
4879 self.pg7.config_ip4()
4880 self.pg7.resolve_arp()
4882 self.pg8.unconfig_ip4()
4883 self.pg8.set_table_ip4(1)
4884 self.pg8.config_ip4()
4885 self.pg8.resolve_arp()
4887 self.vapi.ip_table_add_del(is_add=0, table_id=new_vrf_id)
4889 def test_forwarding(self):
4890 """ NAT44 forwarding test """
4892 flags = self.config_flags.NAT_IS_INSIDE
4893 self.vapi.nat44_interface_add_del_feature(
4894 sw_if_index=self.pg0.sw_if_index,
4895 flags=flags, is_add=1)
4896 self.vapi.nat44_interface_add_del_feature(
4897 sw_if_index=self.pg1.sw_if_index,
4899 self.vapi.nat44_forwarding_enable_disable(enable=1)
4901 real_ip = self.pg0.remote_ip4
4902 alias_ip = self.nat_addr
4903 flags = self.config_flags.NAT_IS_ADDR_ONLY
4904 self.vapi.nat44_add_del_static_mapping(is_add=1,
4905 local_ip_address=real_ip,
4906 external_ip_address=alias_ip,
4907 external_sw_if_index=0xFFFFFFFF,
4911 # in2out - static mapping match
4913 pkts = self.create_stream_out(self.pg1)
4914 self.pg1.add_stream(pkts)
4915 self.pg_enable_capture(self.pg_interfaces)
4917 capture = self.pg0.get_capture(len(pkts))
4918 self.verify_capture_in(capture, self.pg0)
4920 pkts = self.create_stream_in(self.pg0, self.pg1)
4921 self.pg0.add_stream(pkts)
4922 self.pg_enable_capture(self.pg_interfaces)
4924 capture = self.pg1.get_capture(len(pkts))
4925 self.verify_capture_out(capture, same_port=True)
4927 # in2out - no static mapping match
4929 host0 = self.pg0.remote_hosts[0]
4930 self.pg0.remote_hosts[0] = self.pg0.remote_hosts[1]
4932 pkts = self.create_stream_out(self.pg1,
4933 dst_ip=self.pg0.remote_ip4,
4934 use_inside_ports=True)
4935 self.pg1.add_stream(pkts)
4936 self.pg_enable_capture(self.pg_interfaces)
4938 capture = self.pg0.get_capture(len(pkts))
4939 self.verify_capture_in(capture, self.pg0)
4941 pkts = self.create_stream_in(self.pg0, self.pg1)
4942 self.pg0.add_stream(pkts)
4943 self.pg_enable_capture(self.pg_interfaces)
4945 capture = self.pg1.get_capture(len(pkts))
4946 self.verify_capture_out(capture, nat_ip=self.pg0.remote_ip4,
4949 self.pg0.remote_hosts[0] = host0
4951 user = self.pg0.remote_hosts[1]
4952 sessions = self.vapi.nat44_user_session_dump(user.ip4n, 0)
4953 self.assertEqual(len(sessions), 3)
4954 self.assertTrue(sessions[0].flags &
4955 self.config_flags.NAT_IS_EXT_HOST_VALID)
4956 self.vapi.nat44_del_session(
4957 address=sessions[0].inside_ip_address,
4958 port=sessions[0].inside_port,
4959 protocol=sessions[0].protocol,
4960 flags=(self.config_flags.NAT_IS_INSIDE |
4961 self.config_flags.NAT_IS_EXT_HOST_VALID),
4962 ext_host_address=sessions[0].ext_host_address,
4963 ext_host_port=sessions[0].ext_host_port)
4964 sessions = self.vapi.nat44_user_session_dump(user.ip4n, 0)
4965 self.assertEqual(len(sessions), 2)
4968 self.vapi.nat44_forwarding_enable_disable(enable=0)
4969 flags = self.config_flags.NAT_IS_ADDR_ONLY
4970 self.vapi.nat44_add_del_static_mapping(
4972 local_ip_address=real_ip,
4973 external_ip_address=alias_ip,
4974 external_sw_if_index=0xFFFFFFFF,
4977 def test_static_lb(self):
4978 """ NAT44 local service load balancing """
4979 external_addr_n = self.nat_addr
4982 server1 = self.pg0.remote_hosts[0]
4983 server2 = self.pg0.remote_hosts[1]
4985 locals = [{'addr': server1.ip4n,
4989 {'addr': server2.ip4n,
4994 self.nat44_add_address(self.nat_addr)
4995 self.vapi.nat44_add_del_lb_static_mapping(
4997 external_addr=external_addr_n,
4998 external_port=external_port,
4999 protocol=IP_PROTOS.tcp,
5000 local_num=len(locals),
5002 flags = self.config_flags.NAT_IS_INSIDE
5003 self.vapi.nat44_interface_add_del_feature(
5004 sw_if_index=self.pg0.sw_if_index,
5005 flags=flags, is_add=1)
5006 self.vapi.nat44_interface_add_del_feature(
5007 sw_if_index=self.pg1.sw_if_index,
5010 # from client to service
5011 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
5012 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
5013 TCP(sport=12345, dport=external_port))
5014 self.pg1.add_stream(p)
5015 self.pg_enable_capture(self.pg_interfaces)
5017 capture = self.pg0.get_capture(1)
5023 self.assertIn(ip.dst, [server1.ip4, server2.ip4])
5024 if ip.dst == server1.ip4:
5028 self.assertEqual(tcp.dport, local_port)
5029 self.assert_packet_checksums_valid(p)
5031 self.logger.error(ppp("Unexpected or invalid packet:", p))
5034 # from service back to client
5035 p = (Ether(src=server.mac, dst=self.pg0.local_mac) /
5036 IP(src=server.ip4, dst=self.pg1.remote_ip4) /
5037 TCP(sport=local_port, dport=12345))
5038 self.pg0.add_stream(p)
5039 self.pg_enable_capture(self.pg_interfaces)
5041 capture = self.pg1.get_capture(1)
5046 self.assertEqual(ip.src, self.nat_addr)
5047 self.assertEqual(tcp.sport, external_port)
5048 self.assert_packet_checksums_valid(p)
5050 self.logger.error(ppp("Unexpected or invalid packet:", p))
5053 sessions = self.vapi.nat44_user_session_dump(server.ip4n, 0)
5054 self.assertEqual(len(sessions), 1)
5055 self.assertTrue(sessions[0].flags &
5056 self.config_flags.NAT_IS_EXT_HOST_VALID)
5057 self.vapi.nat44_del_session(
5058 address=sessions[0].inside_ip_address,
5059 port=sessions[0].inside_port,
5060 protocol=sessions[0].protocol,
5061 flags=(self.config_flags.NAT_IS_INSIDE |
5062 self.config_flags.NAT_IS_EXT_HOST_VALID),
5063 ext_host_address=sessions[0].ext_host_address,
5064 ext_host_port=sessions[0].ext_host_port)
5065 sessions = self.vapi.nat44_user_session_dump(server.ip4n, 0)
5066 self.assertEqual(len(sessions), 0)
5068 @unittest.skipUnless(running_extended_tests, "part of extended tests")
5069 def test_static_lb_multi_clients(self):
5070 """ NAT44 local service load balancing - multiple clients"""
5072 external_addr = self.nat_addr
5075 server1 = self.pg0.remote_hosts[0]
5076 server2 = self.pg0.remote_hosts[1]
5077 server3 = self.pg0.remote_hosts[2]
5079 locals = [{'addr': server1.ip4n,
5083 {'addr': server2.ip4n,
5088 self.nat44_add_address(self.nat_addr)
5089 self.vapi.nat44_add_del_lb_static_mapping(is_add=1,
5090 external_addr=external_addr,
5091 external_port=external_port,
5092 protocol=IP_PROTOS.tcp,
5093 local_num=len(locals),
5095 flags = self.config_flags.NAT_IS_INSIDE
5096 self.vapi.nat44_interface_add_del_feature(
5097 sw_if_index=self.pg0.sw_if_index,
5098 flags=flags, is_add=1)
5099 self.vapi.nat44_interface_add_del_feature(
5100 sw_if_index=self.pg1.sw_if_index,
5105 clients = ip4_range(self.pg1.remote_ip4, 10, 50)
5107 for client in clients:
5108 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
5109 IP(src=client, dst=self.nat_addr) /
5110 TCP(sport=12345, dport=external_port))
5112 self.pg1.add_stream(pkts)
5113 self.pg_enable_capture(self.pg_interfaces)
5115 capture = self.pg0.get_capture(len(pkts))
5117 if p[IP].dst == server1.ip4:
5121 self.assertGreater(server1_n, server2_n)
5124 'addr': server3.ip4n,
5131 self.vapi.nat44_lb_static_mapping_add_del_local(
5133 external_addr=external_addr,
5134 external_port=external_port,
5136 protocol=IP_PROTOS.tcp)
5140 clients = ip4_range(self.pg1.remote_ip4, 60, 110)
5142 for client in clients:
5143 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
5144 IP(src=client, dst=self.nat_addr) /
5145 TCP(sport=12346, dport=external_port))
5147 self.assertGreater(len(pkts), 0)
5148 self.pg1.add_stream(pkts)
5149 self.pg_enable_capture(self.pg_interfaces)
5151 capture = self.pg0.get_capture(len(pkts))
5153 if p[IP].dst == server1.ip4:
5155 elif p[IP].dst == server2.ip4:
5159 self.assertGreater(server1_n, 0)
5160 self.assertGreater(server2_n, 0)
5161 self.assertGreater(server3_n, 0)
5164 'addr': server2.ip4n,
5170 # remove one back-end
5171 self.vapi.nat44_lb_static_mapping_add_del_local(
5173 external_addr=external_addr,
5174 external_port=external_port,
5176 protocol=IP_PROTOS.tcp)
5180 self.pg1.add_stream(pkts)
5181 self.pg_enable_capture(self.pg_interfaces)
5183 capture = self.pg0.get_capture(len(pkts))
5185 if p[IP].dst == server1.ip4:
5187 elif p[IP].dst == server2.ip4:
5191 self.assertGreater(server1_n, 0)
5192 self.assertEqual(server2_n, 0)
5193 self.assertGreater(server3_n, 0)
5195 def test_static_lb_2(self):
5196 """ NAT44 local service load balancing (asymmetrical rule) """
5197 external_addr = self.nat_addr
5200 server1 = self.pg0.remote_hosts[0]
5201 server2 = self.pg0.remote_hosts[1]
5203 locals = [{'addr': server1.ip4n,
5207 {'addr': server2.ip4n,
5212 self.vapi.nat44_forwarding_enable_disable(enable=1)
5213 flags = self.config_flags.NAT_IS_OUT2IN_ONLY
5214 self.vapi.nat44_add_del_lb_static_mapping(is_add=1, flags=flags,
5215 external_addr=external_addr,
5216 external_port=external_port,
5217 protocol=IP_PROTOS.tcp,
5218 local_num=len(locals),
5220 flags = self.config_flags.NAT_IS_INSIDE
5221 self.vapi.nat44_interface_add_del_feature(
5222 sw_if_index=self.pg0.sw_if_index,
5223 flags=flags, is_add=1)
5224 self.vapi.nat44_interface_add_del_feature(
5225 sw_if_index=self.pg1.sw_if_index,
5228 # from client to service
5229 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
5230 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
5231 TCP(sport=12345, dport=external_port))
5232 self.pg1.add_stream(p)
5233 self.pg_enable_capture(self.pg_interfaces)
5235 capture = self.pg0.get_capture(1)
5241 self.assertIn(ip.dst, [server1.ip4, server2.ip4])
5242 if ip.dst == server1.ip4:
5246 self.assertEqual(tcp.dport, local_port)
5247 self.assert_packet_checksums_valid(p)
5249 self.logger.error(ppp("Unexpected or invalid packet:", p))
5252 # from service back to client
5253 p = (Ether(src=server.mac, dst=self.pg0.local_mac) /
5254 IP(src=server.ip4, dst=self.pg1.remote_ip4) /
5255 TCP(sport=local_port, dport=12345))
5256 self.pg0.add_stream(p)
5257 self.pg_enable_capture(self.pg_interfaces)
5259 capture = self.pg1.get_capture(1)
5264 self.assertEqual(ip.src, self.nat_addr)
5265 self.assertEqual(tcp.sport, external_port)
5266 self.assert_packet_checksums_valid(p)
5268 self.logger.error(ppp("Unexpected or invalid packet:", p))
5271 # from client to server (no translation)
5272 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
5273 IP(src=self.pg1.remote_ip4, dst=server1.ip4) /
5274 TCP(sport=12346, dport=local_port))
5275 self.pg1.add_stream(p)
5276 self.pg_enable_capture(self.pg_interfaces)
5278 capture = self.pg0.get_capture(1)
5284 self.assertEqual(ip.dst, server1.ip4)
5285 self.assertEqual(tcp.dport, local_port)
5286 self.assert_packet_checksums_valid(p)
5288 self.logger.error(ppp("Unexpected or invalid packet:", p))
5291 # from service back to client (no translation)
5292 p = (Ether(src=server1.mac, dst=self.pg0.local_mac) /
5293 IP(src=server1.ip4, dst=self.pg1.remote_ip4) /
5294 TCP(sport=local_port, dport=12346))
5295 self.pg0.add_stream(p)
5296 self.pg_enable_capture(self.pg_interfaces)
5298 capture = self.pg1.get_capture(1)
5303 self.assertEqual(ip.src, server1.ip4)
5304 self.assertEqual(tcp.sport, local_port)
5305 self.assert_packet_checksums_valid(p)
5307 self.logger.error(ppp("Unexpected or invalid packet:", p))
5310 def test_lb_affinity(self):
5311 """ NAT44 local service load balancing affinity """
5312 external_addr = self.nat_addr
5315 server1 = self.pg0.remote_hosts[0]
5316 server2 = self.pg0.remote_hosts[1]
5318 locals = [{'addr': server1.ip4n,
5322 {'addr': server2.ip4n,
5327 self.nat44_add_address(self.nat_addr)
5328 self.vapi.nat44_add_del_lb_static_mapping(is_add=1,
5329 external_addr=external_addr,
5330 external_port=external_port,
5331 protocol=IP_PROTOS.tcp,
5333 local_num=len(locals),
5335 flags = self.config_flags.NAT_IS_INSIDE
5336 self.vapi.nat44_interface_add_del_feature(
5337 sw_if_index=self.pg0.sw_if_index,
5338 flags=flags, is_add=1)
5339 self.vapi.nat44_interface_add_del_feature(
5340 sw_if_index=self.pg1.sw_if_index,
5343 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
5344 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
5345 TCP(sport=1025, dport=external_port))
5346 self.pg1.add_stream(p)
5347 self.pg_enable_capture(self.pg_interfaces)
5349 capture = self.pg0.get_capture(1)
5350 backend = capture[0][IP].dst
5352 sessions = self.vapi.nat44_user_session_dump(backend, 0)
5353 self.assertEqual(len(sessions), 1)
5354 self.assertTrue(sessions[0].flags &
5355 self.config_flags.NAT_IS_EXT_HOST_VALID)
5356 self.vapi.nat44_del_session(
5357 address=sessions[0].inside_ip_address,
5358 port=sessions[0].inside_port,
5359 protocol=sessions[0].protocol,
5360 flags=(self.config_flags.NAT_IS_INSIDE |
5361 self.config_flags.NAT_IS_EXT_HOST_VALID),
5362 ext_host_address=sessions[0].ext_host_address,
5363 ext_host_port=sessions[0].ext_host_port)
5366 for port in range(1030, 1100):
5367 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
5368 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
5369 TCP(sport=port, dport=external_port))
5371 self.pg1.add_stream(pkts)
5372 self.pg_enable_capture(self.pg_interfaces)
5374 capture = self.pg0.get_capture(len(pkts))
5376 self.assertEqual(p[IP].dst, backend)
5378 def test_unknown_proto(self):
5379 """ NAT44 translate packet with unknown protocol """
5380 self.nat44_add_address(self.nat_addr)
5381 flags = self.config_flags.NAT_IS_INSIDE
5382 self.vapi.nat44_interface_add_del_feature(
5383 sw_if_index=self.pg0.sw_if_index,
5384 flags=flags, is_add=1)
5385 self.vapi.nat44_interface_add_del_feature(
5386 sw_if_index=self.pg1.sw_if_index,
5390 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
5391 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
5392 TCP(sport=self.tcp_port_in, dport=20))
5393 self.pg0.add_stream(p)
5394 self.pg_enable_capture(self.pg_interfaces)
5396 p = self.pg1.get_capture(1)
5398 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
5399 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
5401 IP(src=self.pg2.remote_ip4, dst=self.pg2.remote_ip4) /
5402 TCP(sport=1234, dport=1234))
5403 self.pg0.add_stream(p)
5404 self.pg_enable_capture(self.pg_interfaces)
5406 p = self.pg1.get_capture(1)
5409 self.assertEqual(packet[IP].src, self.nat_addr)
5410 self.assertEqual(packet[IP].dst, self.pg1.remote_ip4)
5411 self.assertEqual(packet.haslayer(GRE), 1)
5412 self.assert_packet_checksums_valid(packet)
5414 self.logger.error(ppp("Unexpected or invalid packet:", packet))
5418 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
5419 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
5421 IP(src=self.pg2.remote_ip4, dst=self.pg2.remote_ip4) /
5422 TCP(sport=1234, dport=1234))
5423 self.pg1.add_stream(p)
5424 self.pg_enable_capture(self.pg_interfaces)
5426 p = self.pg0.get_capture(1)
5429 self.assertEqual(packet[IP].src, self.pg1.remote_ip4)
5430 self.assertEqual(packet[IP].dst, self.pg0.remote_ip4)
5431 self.assertEqual(packet.haslayer(GRE), 1)
5432 self.assert_packet_checksums_valid(packet)
5434 self.logger.error(ppp("Unexpected or invalid packet:", packet))
5437 def test_hairpinning_unknown_proto(self):
5438 """ NAT44 translate packet with unknown protocol - hairpinning """
5439 host = self.pg0.remote_hosts[0]
5440 server = self.pg0.remote_hosts[1]
5442 server_out_port = 8765
5443 server_nat_ip = "10.0.0.11"
5445 self.nat44_add_address(self.nat_addr)
5446 flags = self.config_flags.NAT_IS_INSIDE
5447 self.vapi.nat44_interface_add_del_feature(
5448 sw_if_index=self.pg0.sw_if_index,
5449 flags=flags, is_add=1)
5450 self.vapi.nat44_interface_add_del_feature(
5451 sw_if_index=self.pg1.sw_if_index,
5454 # add static mapping for server
5455 self.nat44_add_static_mapping(server.ip4, server_nat_ip)
5458 p = (Ether(src=host.mac, dst=self.pg0.local_mac) /
5459 IP(src=host.ip4, dst=server_nat_ip) /
5460 TCP(sport=host_in_port, dport=server_out_port))
5461 self.pg0.add_stream(p)
5462 self.pg_enable_capture(self.pg_interfaces)
5464 self.pg0.get_capture(1)
5466 p = (Ether(dst=self.pg0.local_mac, src=host.mac) /
5467 IP(src=host.ip4, dst=server_nat_ip) /
5469 IP(src=self.pg2.remote_ip4, dst=self.pg2.remote_ip4) /
5470 TCP(sport=1234, dport=1234))
5471 self.pg0.add_stream(p)
5472 self.pg_enable_capture(self.pg_interfaces)
5474 p = self.pg0.get_capture(1)
5477 self.assertEqual(packet[IP].src, self.nat_addr)
5478 self.assertEqual(packet[IP].dst, server.ip4)
5479 self.assertEqual(packet.haslayer(GRE), 1)
5480 self.assert_packet_checksums_valid(packet)
5482 self.logger.error(ppp("Unexpected or invalid packet:", packet))
5486 p = (Ether(dst=self.pg0.local_mac, src=server.mac) /
5487 IP(src=server.ip4, dst=self.nat_addr) /
5489 IP(src=self.pg2.remote_ip4, dst=self.pg2.remote_ip4) /
5490 TCP(sport=1234, dport=1234))
5491 self.pg0.add_stream(p)
5492 self.pg_enable_capture(self.pg_interfaces)
5494 p = self.pg0.get_capture(1)
5497 self.assertEqual(packet[IP].src, server_nat_ip)
5498 self.assertEqual(packet[IP].dst, host.ip4)
5499 self.assertEqual(packet.haslayer(GRE), 1)
5500 self.assert_packet_checksums_valid(packet)
5502 self.logger.error(ppp("Unexpected or invalid packet:", packet))
5505 def test_output_feature_and_service(self):
5506 """ NAT44 interface output feature and services """
5507 external_addr = '1.2.3.4'
5511 self.vapi.nat44_forwarding_enable_disable(enable=1)
5512 self.nat44_add_address(self.nat_addr)
5513 flags = self.config_flags.NAT_IS_ADDR_ONLY
5514 self.vapi.nat44_add_del_identity_mapping(
5515 ip_address=self.pg1.remote_ip4n, sw_if_index=0xFFFFFFFF,
5516 flags=flags, is_add=1)
5517 flags = self.config_flags.NAT_IS_OUT2IN_ONLY
5518 self.nat44_add_static_mapping(self.pg0.remote_ip4, external_addr,
5519 local_port, external_port,
5520 proto=IP_PROTOS.tcp, flags=flags)
5521 flags = self.config_flags.NAT_IS_INSIDE
5522 self.vapi.nat44_interface_add_del_feature(
5523 sw_if_index=self.pg0.sw_if_index,
5525 self.vapi.nat44_interface_add_del_feature(
5526 sw_if_index=self.pg0.sw_if_index,
5527 flags=flags, is_add=1)
5528 self.vapi.nat44_interface_add_del_output_feature(
5530 sw_if_index=self.pg1.sw_if_index)
5532 # from client to service
5533 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
5534 IP(src=self.pg1.remote_ip4, dst=external_addr) /
5535 TCP(sport=12345, dport=external_port))
5536 self.pg1.add_stream(p)
5537 self.pg_enable_capture(self.pg_interfaces)
5539 capture = self.pg0.get_capture(1)
5544 self.assertEqual(ip.dst, self.pg0.remote_ip4)
5545 self.assertEqual(tcp.dport, local_port)
5546 self.assert_packet_checksums_valid(p)
5548 self.logger.error(ppp("Unexpected or invalid packet:", p))
5551 # from service back to client
5552 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5553 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
5554 TCP(sport=local_port, dport=12345))
5555 self.pg0.add_stream(p)
5556 self.pg_enable_capture(self.pg_interfaces)
5558 capture = self.pg1.get_capture(1)
5563 self.assertEqual(ip.src, external_addr)
5564 self.assertEqual(tcp.sport, external_port)
5565 self.assert_packet_checksums_valid(p)
5567 self.logger.error(ppp("Unexpected or invalid packet:", p))
5570 # from local network host to external network
5571 pkts = self.create_stream_in(self.pg0, self.pg1)
5572 self.pg0.add_stream(pkts)
5573 self.pg_enable_capture(self.pg_interfaces)
5575 capture = self.pg1.get_capture(len(pkts))
5576 self.verify_capture_out(capture)
5577 pkts = self.create_stream_in(self.pg0, self.pg1)
5578 self.pg0.add_stream(pkts)
5579 self.pg_enable_capture(self.pg_interfaces)
5581 capture = self.pg1.get_capture(len(pkts))
5582 self.verify_capture_out(capture)
5584 # from external network back to local network host
5585 pkts = self.create_stream_out(self.pg1)
5586 self.pg1.add_stream(pkts)
5587 self.pg_enable_capture(self.pg_interfaces)
5589 capture = self.pg0.get_capture(len(pkts))
5590 self.verify_capture_in(capture, self.pg0)
5592 def test_output_feature_and_service2(self):
5593 """ NAT44 interface output feature and service host direct access """
5594 self.vapi.nat44_forwarding_enable_disable(enable=1)
5595 self.nat44_add_address(self.nat_addr)
5596 self.vapi.nat44_interface_add_del_output_feature(
5598 sw_if_index=self.pg1.sw_if_index)
5600 # session initiated from service host - translate
5601 pkts = self.create_stream_in(self.pg0, self.pg1)
5602 self.pg0.add_stream(pkts)
5603 self.pg_enable_capture(self.pg_interfaces)
5605 capture = self.pg1.get_capture(len(pkts))
5606 self.verify_capture_out(capture)
5608 pkts = self.create_stream_out(self.pg1)
5609 self.pg1.add_stream(pkts)
5610 self.pg_enable_capture(self.pg_interfaces)
5612 capture = self.pg0.get_capture(len(pkts))
5613 self.verify_capture_in(capture, self.pg0)
5615 # session initiated from remote host - do not translate
5616 self.tcp_port_in = 60303
5617 self.udp_port_in = 60304
5618 self.icmp_id_in = 60305
5619 pkts = self.create_stream_out(self.pg1,
5620 self.pg0.remote_ip4,
5621 use_inside_ports=True)
5622 self.pg1.add_stream(pkts)
5623 self.pg_enable_capture(self.pg_interfaces)
5625 capture = self.pg0.get_capture(len(pkts))
5626 self.verify_capture_in(capture, self.pg0)
5628 pkts = self.create_stream_in(self.pg0, self.pg1)
5629 self.pg0.add_stream(pkts)
5630 self.pg_enable_capture(self.pg_interfaces)
5632 capture = self.pg1.get_capture(len(pkts))
5633 self.verify_capture_out(capture, nat_ip=self.pg0.remote_ip4,
5636 def test_output_feature_and_service3(self):
5637 """ NAT44 interface output feature and DST NAT """
5638 external_addr = '1.2.3.4'
5642 self.vapi.nat44_forwarding_enable_disable(enable=1)
5643 self.nat44_add_address(self.nat_addr)
5644 flags = self.config_flags.NAT_IS_OUT2IN_ONLY
5645 self.nat44_add_static_mapping(self.pg1.remote_ip4, external_addr,
5646 local_port, external_port,
5647 proto=IP_PROTOS.tcp, flags=flags)
5648 flags = self.config_flags.NAT_IS_INSIDE
5649 self.vapi.nat44_interface_add_del_feature(
5650 sw_if_index=self.pg0.sw_if_index,
5652 self.vapi.nat44_interface_add_del_feature(
5653 sw_if_index=self.pg0.sw_if_index,
5654 flags=flags, is_add=1)
5655 self.vapi.nat44_interface_add_del_output_feature(
5657 sw_if_index=self.pg1.sw_if_index)
5659 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5660 IP(src=self.pg0.remote_ip4, dst=external_addr) /
5661 TCP(sport=12345, dport=external_port))
5662 self.pg0.add_stream(p)
5663 self.pg_enable_capture(self.pg_interfaces)
5665 capture = self.pg1.get_capture(1)
5670 self.assertEqual(ip.src, self.pg0.remote_ip4)
5671 self.assertEqual(tcp.sport, 12345)
5672 self.assertEqual(ip.dst, self.pg1.remote_ip4)
5673 self.assertEqual(tcp.dport, local_port)
5674 self.assert_packet_checksums_valid(p)
5676 self.logger.error(ppp("Unexpected or invalid packet:", p))
5679 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
5680 IP(src=self.pg1.remote_ip4, dst=self.pg0.remote_ip4) /
5681 TCP(sport=local_port, dport=12345))
5682 self.pg1.add_stream(p)
5683 self.pg_enable_capture(self.pg_interfaces)
5685 capture = self.pg0.get_capture(1)
5690 self.assertEqual(ip.src, external_addr)
5691 self.assertEqual(tcp.sport, external_port)
5692 self.assertEqual(ip.dst, self.pg0.remote_ip4)
5693 self.assertEqual(tcp.dport, 12345)
5694 self.assert_packet_checksums_valid(p)
5696 self.logger.error(ppp("Unexpected or invalid packet:", p))
5699 def test_next_src_nat(self):
5700 """ On way back forward packet to nat44-in2out node. """
5701 twice_nat_addr = '10.0.1.3'
5704 post_twice_nat_port = 0
5706 self.vapi.nat44_forwarding_enable_disable(enable=1)
5707 self.nat44_add_address(twice_nat_addr, twice_nat=1)
5708 flags = (self.config_flags.NAT_IS_OUT2IN_ONLY |
5709 self.config_flags.NAT_IS_SELF_TWICE_NAT)
5710 self.nat44_add_static_mapping(self.pg6.remote_ip4, self.pg1.remote_ip4,
5711 local_port, external_port,
5712 proto=IP_PROTOS.tcp, vrf_id=1,
5714 self.vapi.nat44_interface_add_del_feature(
5715 sw_if_index=self.pg6.sw_if_index,
5718 p = (Ether(src=self.pg6.remote_mac, dst=self.pg6.local_mac) /
5719 IP(src=self.pg6.remote_ip4, dst=self.pg1.remote_ip4) /
5720 TCP(sport=12345, dport=external_port))
5721 self.pg6.add_stream(p)
5722 self.pg_enable_capture(self.pg_interfaces)
5724 capture = self.pg6.get_capture(1)
5729 self.assertEqual(ip.src, twice_nat_addr)
5730 self.assertNotEqual(tcp.sport, 12345)
5731 post_twice_nat_port = tcp.sport
5732 self.assertEqual(ip.dst, self.pg6.remote_ip4)
5733 self.assertEqual(tcp.dport, local_port)
5734 self.assert_packet_checksums_valid(p)
5736 self.logger.error(ppp("Unexpected or invalid packet:", p))
5739 p = (Ether(src=self.pg6.remote_mac, dst=self.pg6.local_mac) /
5740 IP(src=self.pg6.remote_ip4, dst=twice_nat_addr) /
5741 TCP(sport=local_port, dport=post_twice_nat_port))
5742 self.pg6.add_stream(p)
5743 self.pg_enable_capture(self.pg_interfaces)
5745 capture = self.pg6.get_capture(1)
5750 self.assertEqual(ip.src, self.pg1.remote_ip4)
5751 self.assertEqual(tcp.sport, external_port)
5752 self.assertEqual(ip.dst, self.pg6.remote_ip4)
5753 self.assertEqual(tcp.dport, 12345)
5754 self.assert_packet_checksums_valid(p)
5756 self.logger.error(ppp("Unexpected or invalid packet:", p))
5759 def twice_nat_common(self, self_twice_nat=False, same_pg=False, lb=False,
5761 twice_nat_addr = '10.0.1.3'
5769 port_in1 = port_in + 1
5770 port_in2 = port_in + 2
5775 server1 = self.pg0.remote_hosts[0]
5776 server2 = self.pg0.remote_hosts[1]
5788 eh_translate = ((not self_twice_nat) or (not lb and same_pg) or
5791 self.nat44_add_address(self.nat_addr)
5792 self.nat44_add_address(twice_nat_addr, twice_nat=1)
5796 flags |= self.config_flags.NAT_IS_SELF_TWICE_NAT
5798 flags |= self.config_flags.NAT_IS_TWICE_NAT
5801 self.nat44_add_static_mapping(pg0.remote_ip4, self.nat_addr,
5803 proto=IP_PROTOS.tcp,
5806 locals = [{'addr': server1.ip4n,
5810 {'addr': server2.ip4n,
5814 out_addr = self.nat_addr
5816 self.vapi.nat44_add_del_lb_static_mapping(is_add=1, flags=flags,
5817 external_addr=out_addr,
5818 external_port=port_out,
5819 protocol=IP_PROTOS.tcp,
5820 local_num=len(locals),
5822 flags = self.config_flags.NAT_IS_INSIDE
5823 self.vapi.nat44_interface_add_del_feature(
5824 sw_if_index=pg0.sw_if_index,
5825 flags=flags, is_add=1)
5826 self.vapi.nat44_interface_add_del_feature(
5827 sw_if_index=pg1.sw_if_index,
5834 assert client_id is not None
5836 client = self.pg0.remote_hosts[0]
5837 elif client_id == 2:
5838 client = self.pg0.remote_hosts[1]
5840 client = pg1.remote_hosts[0]
5841 p = (Ether(src=pg1.remote_mac, dst=pg1.local_mac) /
5842 IP(src=client.ip4, dst=self.nat_addr) /
5843 TCP(sport=eh_port_out, dport=port_out))
5845 self.pg_enable_capture(self.pg_interfaces)
5847 capture = pg0.get_capture(1)
5853 if ip.dst == server1.ip4:
5859 self.assertEqual(ip.dst, server.ip4)
5861 self.assertIn(tcp.dport, [port_in1, port_in2])
5863 self.assertEqual(tcp.dport, port_in)
5865 self.assertEqual(ip.src, twice_nat_addr)
5866 self.assertNotEqual(tcp.sport, eh_port_out)
5868 self.assertEqual(ip.src, client.ip4)
5869 self.assertEqual(tcp.sport, eh_port_out)
5871 eh_port_in = tcp.sport
5872 saved_port_in = tcp.dport
5873 self.assert_packet_checksums_valid(p)
5875 self.logger.error(ppp("Unexpected or invalid packet:", p))
5878 p = (Ether(src=server.mac, dst=pg0.local_mac) /
5879 IP(src=server.ip4, dst=eh_addr_in) /
5880 TCP(sport=saved_port_in, dport=eh_port_in))
5882 self.pg_enable_capture(self.pg_interfaces)
5884 capture = pg1.get_capture(1)
5889 self.assertEqual(ip.dst, client.ip4)
5890 self.assertEqual(ip.src, self.nat_addr)
5891 self.assertEqual(tcp.dport, eh_port_out)
5892 self.assertEqual(tcp.sport, port_out)
5893 self.assert_packet_checksums_valid(p)
5895 self.logger.error(ppp("Unexpected or invalid packet:", p))
5899 sessions = self.vapi.nat44_user_session_dump(server.ip4n, 0)
5900 self.assertEqual(len(sessions), 1)
5901 self.assertTrue(sessions[0].flags &
5902 self.config_flags.NAT_IS_EXT_HOST_VALID)
5903 self.assertTrue(sessions[0].flags &
5904 self.config_flags.NAT_IS_TWICE_NAT)
5905 self.logger.info(self.vapi.cli("show nat44 sessions detail"))
5906 self.vapi.nat44_del_session(
5907 address=sessions[0].inside_ip_address,
5908 port=sessions[0].inside_port,
5909 protocol=sessions[0].protocol,
5910 flags=(self.config_flags.NAT_IS_INSIDE |
5911 self.config_flags.NAT_IS_EXT_HOST_VALID),
5912 ext_host_address=sessions[0].ext_host_nat_address,
5913 ext_host_port=sessions[0].ext_host_nat_port)
5914 sessions = self.vapi.nat44_user_session_dump(server.ip4n, 0)
5915 self.assertEqual(len(sessions), 0)
5917 def test_twice_nat(self):
5919 self.twice_nat_common()
5921 def test_self_twice_nat_positive(self):
5922 """ Self Twice NAT44 (positive test) """
5923 self.twice_nat_common(self_twice_nat=True, same_pg=True)
5925 def test_self_twice_nat_negative(self):
5926 """ Self Twice NAT44 (negative test) """
5927 self.twice_nat_common(self_twice_nat=True)
5929 def test_twice_nat_lb(self):
5930 """ Twice NAT44 local service load balancing """
5931 self.twice_nat_common(lb=True)
5933 def test_self_twice_nat_lb_positive(self):
5934 """ Self Twice NAT44 local service load balancing (positive test) """
5935 self.twice_nat_common(lb=True, self_twice_nat=True, same_pg=True,
5938 def test_self_twice_nat_lb_negative(self):
5939 """ Self Twice NAT44 local service load balancing (negative test) """
5940 self.twice_nat_common(lb=True, self_twice_nat=True, same_pg=True,
5943 def test_twice_nat_interface_addr(self):
5944 """ Acquire twice NAT44 addresses from interface """
5945 flags = self.config_flags.NAT_IS_TWICE_NAT
5946 self.vapi.nat44_add_del_interface_addr(
5948 sw_if_index=self.pg3.sw_if_index,
5951 # no address in NAT pool
5952 adresses = self.vapi.nat44_address_dump()
5953 self.assertEqual(0, len(adresses))
5955 # configure interface address and check NAT address pool
5956 self.pg3.config_ip4()
5957 adresses = self.vapi.nat44_address_dump()
5958 self.assertEqual(1, len(adresses))
5959 self.assertEqual(str(adresses[0].ip_address),
5961 self.assertEqual(adresses[0].flags, flags)
5963 # remove interface address and check NAT address pool
5964 self.pg3.unconfig_ip4()
5965 adresses = self.vapi.nat44_address_dump()
5966 self.assertEqual(0, len(adresses))
5968 def test_tcp_close(self):
5969 """ Close TCP session from inside network - output feature """
5970 self.vapi.nat44_forwarding_enable_disable(enable=1)
5971 self.nat44_add_address(self.pg1.local_ip4)
5972 twice_nat_addr = '10.0.1.3'
5973 service_ip = '192.168.16.150'
5974 self.nat44_add_address(twice_nat_addr, twice_nat=1)
5975 flags = self.config_flags.NAT_IS_INSIDE
5976 self.vapi.nat44_interface_add_del_feature(
5977 sw_if_index=self.pg0.sw_if_index,
5979 self.vapi.nat44_interface_add_del_feature(
5980 sw_if_index=self.pg0.sw_if_index,
5981 flags=flags, is_add=1)
5982 self.vapi.nat44_interface_add_del_output_feature(
5984 sw_if_index=self.pg1.sw_if_index)
5985 flags = (self.config_flags.NAT_IS_OUT2IN_ONLY |
5986 self.config_flags.NAT_IS_TWICE_NAT)
5987 self.nat44_add_static_mapping(self.pg0.remote_ip4,
5991 proto=IP_PROTOS.tcp,
5993 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4n, 0)
5994 start_sessnum = len(sessions)
5996 # SYN packet out->in
5997 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
5998 IP(src=self.pg1.remote_ip4, dst=service_ip) /
5999 TCP(sport=33898, dport=80, flags="S"))
6000 self.pg1.add_stream(p)
6001 self.pg_enable_capture(self.pg_interfaces)
6003 capture = self.pg0.get_capture(1)
6005 tcp_port = p[TCP].sport
6007 # SYN + ACK packet in->out
6008 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6009 IP(src=self.pg0.remote_ip4, dst=twice_nat_addr) /
6010 TCP(sport=80, dport=tcp_port, flags="SA"))
6011 self.pg0.add_stream(p)
6012 self.pg_enable_capture(self.pg_interfaces)
6014 self.pg1.get_capture(1)
6016 # ACK packet out->in
6017 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
6018 IP(src=self.pg1.remote_ip4, dst=service_ip) /
6019 TCP(sport=33898, dport=80, flags="A"))
6020 self.pg1.add_stream(p)
6021 self.pg_enable_capture(self.pg_interfaces)
6023 self.pg0.get_capture(1)
6025 # FIN packet in -> out
6026 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6027 IP(src=self.pg0.remote_ip4, dst=twice_nat_addr) /
6028 TCP(sport=80, dport=tcp_port, flags="FA", seq=100, ack=300))
6029 self.pg0.add_stream(p)
6030 self.pg_enable_capture(self.pg_interfaces)
6032 self.pg1.get_capture(1)
6034 # FIN+ACK packet out -> in
6035 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
6036 IP(src=self.pg1.remote_ip4, dst=service_ip) /
6037 TCP(sport=33898, dport=80, flags="FA", seq=300, ack=101))
6038 self.pg1.add_stream(p)
6039 self.pg_enable_capture(self.pg_interfaces)
6041 self.pg0.get_capture(1)
6043 # ACK packet in -> out
6044 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6045 IP(src=self.pg0.remote_ip4, dst=twice_nat_addr) /
6046 TCP(sport=80, dport=tcp_port, flags="A", seq=101, ack=301))
6047 self.pg0.add_stream(p)
6048 self.pg_enable_capture(self.pg_interfaces)
6050 self.pg1.get_capture(1)
6052 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4n,
6054 self.assertEqual(len(sessions) - start_sessnum, 0)
6056 def test_tcp_session_close_in(self):
6057 """ Close TCP session from inside network """
6058 self.tcp_port_out = 10505
6059 self.nat44_add_address(self.nat_addr)
6060 flags = self.config_flags.NAT_IS_TWICE_NAT
6061 self.nat44_add_static_mapping(self.pg0.remote_ip4,
6065 proto=IP_PROTOS.tcp,
6067 flags = self.config_flags.NAT_IS_INSIDE
6068 self.vapi.nat44_interface_add_del_feature(
6069 sw_if_index=self.pg0.sw_if_index,
6070 flags=flags, is_add=1)
6071 self.vapi.nat44_interface_add_del_feature(
6072 sw_if_index=self.pg1.sw_if_index,
6075 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4n, 0)
6076 start_sessnum = len(sessions)
6078 self.initiate_tcp_session(self.pg0, self.pg1)
6080 # FIN packet in -> out
6081 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6082 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6083 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
6084 flags="FA", seq=100, ack=300))
6085 self.pg0.add_stream(p)
6086 self.pg_enable_capture(self.pg_interfaces)
6088 self.pg1.get_capture(1)
6092 # ACK packet out -> in
6093 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
6094 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
6095 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
6096 flags="A", seq=300, ack=101))
6099 # FIN packet out -> in
6100 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
6101 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
6102 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
6103 flags="FA", seq=300, ack=101))
6106 self.pg1.add_stream(pkts)
6107 self.pg_enable_capture(self.pg_interfaces)
6109 self.pg0.get_capture(2)
6111 # ACK packet in -> out
6112 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6113 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6114 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
6115 flags="A", seq=101, ack=301))
6116 self.pg0.add_stream(p)
6117 self.pg_enable_capture(self.pg_interfaces)
6119 self.pg1.get_capture(1)
6121 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4n,
6123 self.assertEqual(len(sessions) - start_sessnum, 0)
6125 def test_tcp_session_close_out(self):
6126 """ Close TCP session from outside network """
6127 self.tcp_port_out = 10505
6128 self.nat44_add_address(self.nat_addr)
6129 flags = self.config_flags.NAT_IS_TWICE_NAT
6130 self.nat44_add_static_mapping(self.pg0.remote_ip4,
6134 proto=IP_PROTOS.tcp,
6136 flags = self.config_flags.NAT_IS_INSIDE
6137 self.vapi.nat44_interface_add_del_feature(
6138 sw_if_index=self.pg0.sw_if_index,
6139 flags=flags, is_add=1)
6140 self.vapi.nat44_interface_add_del_feature(
6141 sw_if_index=self.pg1.sw_if_index,
6144 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4n, 0)
6145 start_sessnum = len(sessions)
6147 self.initiate_tcp_session(self.pg0, self.pg1)
6149 # FIN packet out -> in
6150 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
6151 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
6152 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
6153 flags="FA", seq=100, ack=300))
6154 self.pg1.add_stream(p)
6155 self.pg_enable_capture(self.pg_interfaces)
6157 self.pg0.get_capture(1)
6159 # FIN+ACK packet in -> out
6160 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6161 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6162 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
6163 flags="FA", seq=300, ack=101))
6165 self.pg0.add_stream(p)
6166 self.pg_enable_capture(self.pg_interfaces)
6168 self.pg1.get_capture(1)
6170 # ACK packet out -> in
6171 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
6172 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
6173 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
6174 flags="A", seq=101, ack=301))
6175 self.pg1.add_stream(p)
6176 self.pg_enable_capture(self.pg_interfaces)
6178 self.pg0.get_capture(1)
6180 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4n,
6182 self.assertEqual(len(sessions) - start_sessnum, 0)
6184 def test_tcp_session_close_simultaneous(self):
6185 """ Close TCP session from inside network """
6186 self.tcp_port_out = 10505
6187 self.nat44_add_address(self.nat_addr)
6188 flags = self.config_flags.NAT_IS_TWICE_NAT
6189 self.nat44_add_static_mapping(self.pg0.remote_ip4,
6193 proto=IP_PROTOS.tcp,
6195 flags = self.config_flags.NAT_IS_INSIDE
6196 self.vapi.nat44_interface_add_del_feature(
6197 sw_if_index=self.pg0.sw_if_index,
6198 flags=flags, is_add=1)
6199 self.vapi.nat44_interface_add_del_feature(
6200 sw_if_index=self.pg1.sw_if_index,
6203 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4n, 0)
6204 start_sessnum = len(sessions)
6206 self.initiate_tcp_session(self.pg0, self.pg1)
6208 # FIN packet in -> out
6209 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6210 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6211 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
6212 flags="FA", seq=100, ack=300))
6213 self.pg0.add_stream(p)
6214 self.pg_enable_capture(self.pg_interfaces)
6216 self.pg1.get_capture(1)
6218 # FIN packet out -> in
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=self.tcp_external_port, dport=self.tcp_port_out,
6222 flags="FA", seq=300, ack=100))
6223 self.pg1.add_stream(p)
6224 self.pg_enable_capture(self.pg_interfaces)
6226 self.pg0.get_capture(1)
6228 # ACK packet in -> out
6229 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6230 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6231 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
6232 flags="A", seq=101, ack=301))
6233 self.pg0.add_stream(p)
6234 self.pg_enable_capture(self.pg_interfaces)
6236 self.pg1.get_capture(1)
6238 # ACK packet out -> in
6239 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
6240 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
6241 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
6242 flags="A", seq=301, ack=101))
6243 self.pg1.add_stream(p)
6244 self.pg_enable_capture(self.pg_interfaces)
6246 self.pg0.get_capture(1)
6248 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4n,
6250 self.assertEqual(len(sessions) - start_sessnum, 0)
6252 def test_one_armed_nat44_static(self):
6253 """ One armed NAT44 and 1:1 NAPT asymmetrical rule """
6254 remote_host = self.pg4.remote_hosts[0]
6255 local_host = self.pg4.remote_hosts[1]
6260 self.vapi.nat44_forwarding_enable_disable(enable=1)
6261 self.nat44_add_address(self.nat_addr, twice_nat=1)
6262 flags = (self.config_flags.NAT_IS_OUT2IN_ONLY |
6263 self.config_flags.NAT_IS_TWICE_NAT)
6264 self.nat44_add_static_mapping(local_host.ip4, self.nat_addr,
6265 local_port, external_port,
6266 proto=IP_PROTOS.tcp, flags=flags)
6267 flags = self.config_flags.NAT_IS_INSIDE
6268 self.vapi.nat44_interface_add_del_feature(
6269 sw_if_index=self.pg4.sw_if_index,
6271 self.vapi.nat44_interface_add_del_feature(
6272 sw_if_index=self.pg4.sw_if_index,
6273 flags=flags, is_add=1)
6275 # from client to service
6276 p = (Ether(src=self.pg4.remote_mac, dst=self.pg4.local_mac) /
6277 IP(src=remote_host.ip4, dst=self.nat_addr) /
6278 TCP(sport=12345, dport=external_port))
6279 self.pg4.add_stream(p)
6280 self.pg_enable_capture(self.pg_interfaces)
6282 capture = self.pg4.get_capture(1)
6287 self.assertEqual(ip.dst, local_host.ip4)
6288 self.assertEqual(ip.src, self.nat_addr)
6289 self.assertEqual(tcp.dport, local_port)
6290 self.assertNotEqual(tcp.sport, 12345)
6291 eh_port_in = tcp.sport
6292 self.assert_packet_checksums_valid(p)
6294 self.logger.error(ppp("Unexpected or invalid packet:", p))
6297 # from service back to client
6298 p = (Ether(src=self.pg4.remote_mac, dst=self.pg4.local_mac) /
6299 IP(src=local_host.ip4, dst=self.nat_addr) /
6300 TCP(sport=local_port, dport=eh_port_in))
6301 self.pg4.add_stream(p)
6302 self.pg_enable_capture(self.pg_interfaces)
6304 capture = self.pg4.get_capture(1)
6309 self.assertEqual(ip.src, self.nat_addr)
6310 self.assertEqual(ip.dst, remote_host.ip4)
6311 self.assertEqual(tcp.sport, external_port)
6312 self.assertEqual(tcp.dport, 12345)
6313 self.assert_packet_checksums_valid(p)
6315 self.logger.error(ppp("Unexpected or invalid packet:", p))
6318 def test_static_with_port_out2(self):
6319 """ 1:1 NAPT asymmetrical rule """
6324 self.vapi.nat44_forwarding_enable_disable(enable=1)
6325 flags = self.config_flags.NAT_IS_OUT2IN_ONLY
6326 self.nat44_add_static_mapping(self.pg0.remote_ip4, self.nat_addr,
6327 local_port, external_port,
6328 proto=IP_PROTOS.tcp, flags=flags)
6329 flags = self.config_flags.NAT_IS_INSIDE
6330 self.vapi.nat44_interface_add_del_feature(
6331 sw_if_index=self.pg0.sw_if_index,
6332 flags=flags, is_add=1)
6333 self.vapi.nat44_interface_add_del_feature(
6334 sw_if_index=self.pg1.sw_if_index,
6337 # from client to service
6338 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
6339 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
6340 TCP(sport=12345, dport=external_port))
6341 self.pg1.add_stream(p)
6342 self.pg_enable_capture(self.pg_interfaces)
6344 capture = self.pg0.get_capture(1)
6349 self.assertEqual(ip.dst, self.pg0.remote_ip4)
6350 self.assertEqual(tcp.dport, local_port)
6351 self.assert_packet_checksums_valid(p)
6353 self.logger.error(ppp("Unexpected or invalid packet:", p))
6357 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
6358 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6359 ICMP(type=11) / capture[0][IP])
6360 self.pg0.add_stream(p)
6361 self.pg_enable_capture(self.pg_interfaces)
6363 capture = self.pg1.get_capture(1)
6366 self.assertEqual(p[IP].src, self.nat_addr)
6368 self.assertEqual(inner.dst, self.nat_addr)
6369 self.assertEqual(inner[TCPerror].dport, external_port)
6371 self.logger.error(ppp("Unexpected or invalid packet:", p))
6374 # from service back to client
6375 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6376 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6377 TCP(sport=local_port, dport=12345))
6378 self.pg0.add_stream(p)
6379 self.pg_enable_capture(self.pg_interfaces)
6381 capture = self.pg1.get_capture(1)
6386 self.assertEqual(ip.src, self.nat_addr)
6387 self.assertEqual(tcp.sport, external_port)
6388 self.assert_packet_checksums_valid(p)
6390 self.logger.error(ppp("Unexpected or invalid packet:", p))
6394 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
6395 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
6396 ICMP(type=11) / capture[0][IP])
6397 self.pg1.add_stream(p)
6398 self.pg_enable_capture(self.pg_interfaces)
6400 capture = self.pg0.get_capture(1)
6403 self.assertEqual(p[IP].dst, self.pg0.remote_ip4)
6405 self.assertEqual(inner.src, self.pg0.remote_ip4)
6406 self.assertEqual(inner[TCPerror].sport, local_port)
6408 self.logger.error(ppp("Unexpected or invalid packet:", p))
6411 # from client to server (no translation)
6412 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
6413 IP(src=self.pg1.remote_ip4, dst=self.pg0.remote_ip4) /
6414 TCP(sport=12346, dport=local_port))
6415 self.pg1.add_stream(p)
6416 self.pg_enable_capture(self.pg_interfaces)
6418 capture = self.pg0.get_capture(1)
6423 self.assertEqual(ip.dst, self.pg0.remote_ip4)
6424 self.assertEqual(tcp.dport, local_port)
6425 self.assert_packet_checksums_valid(p)
6427 self.logger.error(ppp("Unexpected or invalid packet:", p))
6430 # from service back to client (no translation)
6431 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6432 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6433 TCP(sport=local_port, dport=12346))
6434 self.pg0.add_stream(p)
6435 self.pg_enable_capture(self.pg_interfaces)
6437 capture = self.pg1.get_capture(1)
6442 self.assertEqual(ip.src, self.pg0.remote_ip4)
6443 self.assertEqual(tcp.sport, local_port)
6444 self.assert_packet_checksums_valid(p)
6446 self.logger.error(ppp("Unexpected or invalid packet:", p))
6449 def test_output_feature(self):
6450 """ NAT44 interface output feature (in2out postrouting) """
6451 self.vapi.nat44_forwarding_enable_disable(enable=1)
6452 self.nat44_add_address(self.nat_addr)
6453 self.vapi.nat44_interface_add_del_feature(
6454 sw_if_index=self.pg0.sw_if_index,
6456 self.vapi.nat44_interface_add_del_output_feature(
6458 sw_if_index=self.pg1.sw_if_index)
6461 pkts = self.create_stream_in(self.pg0, self.pg1)
6462 self.pg0.add_stream(pkts)
6463 self.pg_enable_capture(self.pg_interfaces)
6465 capture = self.pg1.get_capture(len(pkts))
6466 self.verify_capture_out(capture)
6469 pkts = self.create_stream_out(self.pg1)
6470 self.pg1.add_stream(pkts)
6471 self.pg_enable_capture(self.pg_interfaces)
6473 capture = self.pg0.get_capture(len(pkts))
6474 self.verify_capture_in(capture, self.pg0)
6476 def test_multiple_vrf(self):
6477 """ Multiple VRF setup """
6478 external_addr = '1.2.3.4'
6483 self.vapi.nat44_forwarding_enable_disable(enable=1)
6484 self.nat44_add_address(self.nat_addr)
6485 flags = self.config_flags.NAT_IS_INSIDE
6486 self.vapi.nat44_interface_add_del_feature(
6487 sw_if_index=self.pg0.sw_if_index,
6489 self.vapi.nat44_interface_add_del_feature(
6490 sw_if_index=self.pg0.sw_if_index,
6491 flags=flags, is_add=1)
6492 self.vapi.nat44_interface_add_del_output_feature(
6494 sw_if_index=self.pg1.sw_if_index)
6495 self.vapi.nat44_interface_add_del_feature(
6496 sw_if_index=self.pg5.sw_if_index,
6498 self.vapi.nat44_interface_add_del_feature(
6499 sw_if_index=self.pg5.sw_if_index,
6500 flags=flags, is_add=1)
6501 self.vapi.nat44_interface_add_del_feature(
6502 sw_if_index=self.pg6.sw_if_index,
6504 flags = self.config_flags.NAT_IS_OUT2IN_ONLY
6505 self.nat44_add_static_mapping(self.pg5.remote_ip4, external_addr,
6506 local_port, external_port, vrf_id=1,
6507 proto=IP_PROTOS.tcp, flags=flags)
6508 self.nat44_add_static_mapping(
6509 self.pg0.remote_ip4,
6510 external_sw_if_index=self.pg0.sw_if_index,
6511 local_port=local_port,
6513 external_port=external_port,
6514 proto=IP_PROTOS.tcp,
6518 # from client to service (both VRF1)
6519 p = (Ether(src=self.pg6.remote_mac, dst=self.pg6.local_mac) /
6520 IP(src=self.pg6.remote_ip4, dst=external_addr) /
6521 TCP(sport=12345, dport=external_port))
6522 self.pg6.add_stream(p)
6523 self.pg_enable_capture(self.pg_interfaces)
6525 capture = self.pg5.get_capture(1)
6530 self.assertEqual(ip.dst, self.pg5.remote_ip4)
6531 self.assertEqual(tcp.dport, local_port)
6532 self.assert_packet_checksums_valid(p)
6534 self.logger.error(ppp("Unexpected or invalid packet:", p))
6537 # from service back to client (both VRF1)
6538 p = (Ether(src=self.pg5.remote_mac, dst=self.pg5.local_mac) /
6539 IP(src=self.pg5.remote_ip4, dst=self.pg6.remote_ip4) /
6540 TCP(sport=local_port, dport=12345))
6541 self.pg5.add_stream(p)
6542 self.pg_enable_capture(self.pg_interfaces)
6544 capture = self.pg6.get_capture(1)
6549 self.assertEqual(ip.src, external_addr)
6550 self.assertEqual(tcp.sport, external_port)
6551 self.assert_packet_checksums_valid(p)
6553 self.logger.error(ppp("Unexpected or invalid packet:", p))
6556 # dynamic NAT from VRF1 to VRF0 (output-feature)
6557 p = (Ether(src=self.pg5.remote_mac, dst=self.pg5.local_mac) /
6558 IP(src=self.pg5.remote_ip4, dst=self.pg1.remote_ip4) /
6559 TCP(sport=2345, dport=22))
6560 self.pg5.add_stream(p)
6561 self.pg_enable_capture(self.pg_interfaces)
6563 capture = self.pg1.get_capture(1)
6568 self.assertEqual(ip.src, self.nat_addr)
6569 self.assertNotEqual(tcp.sport, 2345)
6570 self.assert_packet_checksums_valid(p)
6573 self.logger.error(ppp("Unexpected or invalid packet:", p))
6576 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
6577 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
6578 TCP(sport=22, dport=port))
6579 self.pg1.add_stream(p)
6580 self.pg_enable_capture(self.pg_interfaces)
6582 capture = self.pg5.get_capture(1)
6587 self.assertEqual(ip.dst, self.pg5.remote_ip4)
6588 self.assertEqual(tcp.dport, 2345)
6589 self.assert_packet_checksums_valid(p)
6591 self.logger.error(ppp("Unexpected or invalid packet:", p))
6594 # from client VRF1 to service VRF0
6595 p = (Ether(src=self.pg6.remote_mac, dst=self.pg6.local_mac) /
6596 IP(src=self.pg6.remote_ip4, dst=self.pg0.local_ip4) /
6597 TCP(sport=12346, dport=external_port))
6598 self.pg6.add_stream(p)
6599 self.pg_enable_capture(self.pg_interfaces)
6601 capture = self.pg0.get_capture(1)
6606 self.assertEqual(ip.dst, self.pg0.remote_ip4)
6607 self.assertEqual(tcp.dport, local_port)
6608 self.assert_packet_checksums_valid(p)
6610 self.logger.error(ppp("Unexpected or invalid packet:", p))
6613 # from service VRF0 back to client VRF1
6614 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6615 IP(src=self.pg0.remote_ip4, dst=self.pg6.remote_ip4) /
6616 TCP(sport=local_port, dport=12346))
6617 self.pg0.add_stream(p)
6618 self.pg_enable_capture(self.pg_interfaces)
6620 capture = self.pg6.get_capture(1)
6625 self.assertEqual(ip.src, self.pg0.local_ip4)
6626 self.assertEqual(tcp.sport, external_port)
6627 self.assert_packet_checksums_valid(p)
6629 self.logger.error(ppp("Unexpected or invalid packet:", p))
6632 # from client VRF0 to service VRF1
6633 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6634 IP(src=self.pg0.remote_ip4, dst=external_addr) /
6635 TCP(sport=12347, dport=external_port))
6636 self.pg0.add_stream(p)
6637 self.pg_enable_capture(self.pg_interfaces)
6639 capture = self.pg5.get_capture(1)
6644 self.assertEqual(ip.dst, self.pg5.remote_ip4)
6645 self.assertEqual(tcp.dport, local_port)
6646 self.assert_packet_checksums_valid(p)
6648 self.logger.error(ppp("Unexpected or invalid packet:", p))
6651 # from service VRF1 back to client VRF0
6652 p = (Ether(src=self.pg5.remote_mac, dst=self.pg5.local_mac) /
6653 IP(src=self.pg5.remote_ip4, dst=self.pg0.remote_ip4) /
6654 TCP(sport=local_port, dport=12347))
6655 self.pg5.add_stream(p)
6656 self.pg_enable_capture(self.pg_interfaces)
6658 capture = self.pg0.get_capture(1)
6663 self.assertEqual(ip.src, external_addr)
6664 self.assertEqual(tcp.sport, external_port)
6665 self.assert_packet_checksums_valid(p)
6667 self.logger.error(ppp("Unexpected or invalid packet:", p))
6670 # from client to server (both VRF1, no translation)
6671 p = (Ether(src=self.pg6.remote_mac, dst=self.pg6.local_mac) /
6672 IP(src=self.pg6.remote_ip4, dst=self.pg5.remote_ip4) /
6673 TCP(sport=12348, dport=local_port))
6674 self.pg6.add_stream(p)
6675 self.pg_enable_capture(self.pg_interfaces)
6677 capture = self.pg5.get_capture(1)
6682 self.assertEqual(ip.dst, self.pg5.remote_ip4)
6683 self.assertEqual(tcp.dport, local_port)
6684 self.assert_packet_checksums_valid(p)
6686 self.logger.error(ppp("Unexpected or invalid packet:", p))
6689 # from server back to client (both VRF1, no translation)
6690 p = (Ether(src=self.pg5.remote_mac, dst=self.pg5.local_mac) /
6691 IP(src=self.pg5.remote_ip4, dst=self.pg6.remote_ip4) /
6692 TCP(sport=local_port, dport=12348))
6693 self.pg5.add_stream(p)
6694 self.pg_enable_capture(self.pg_interfaces)
6696 capture = self.pg6.get_capture(1)
6701 self.assertEqual(ip.src, self.pg5.remote_ip4)
6702 self.assertEqual(tcp.sport, local_port)
6703 self.assert_packet_checksums_valid(p)
6705 self.logger.error(ppp("Unexpected or invalid packet:", p))
6708 # from client VRF1 to server VRF0 (no translation)
6709 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6710 IP(src=self.pg0.remote_ip4, dst=self.pg6.remote_ip4) /
6711 TCP(sport=local_port, dport=12349))
6712 self.pg0.add_stream(p)
6713 self.pg_enable_capture(self.pg_interfaces)
6715 capture = self.pg6.get_capture(1)
6720 self.assertEqual(ip.src, self.pg0.remote_ip4)
6721 self.assertEqual(tcp.sport, local_port)
6722 self.assert_packet_checksums_valid(p)
6724 self.logger.error(ppp("Unexpected or invalid packet:", p))
6727 # from server VRF0 back to client VRF1 (no translation)
6728 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6729 IP(src=self.pg0.remote_ip4, dst=self.pg6.remote_ip4) /
6730 TCP(sport=local_port, dport=12349))
6731 self.pg0.add_stream(p)
6732 self.pg_enable_capture(self.pg_interfaces)
6734 capture = self.pg6.get_capture(1)
6739 self.assertEqual(ip.src, self.pg0.remote_ip4)
6740 self.assertEqual(tcp.sport, local_port)
6741 self.assert_packet_checksums_valid(p)
6743 self.logger.error(ppp("Unexpected or invalid packet:", p))
6746 # from client VRF0 to server VRF1 (no translation)
6747 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6748 IP(src=self.pg0.remote_ip4, dst=self.pg5.remote_ip4) /
6749 TCP(sport=12344, dport=local_port))
6750 self.pg0.add_stream(p)
6751 self.pg_enable_capture(self.pg_interfaces)
6753 capture = self.pg5.get_capture(1)
6758 self.assertEqual(ip.dst, self.pg5.remote_ip4)
6759 self.assertEqual(tcp.dport, local_port)
6760 self.assert_packet_checksums_valid(p)
6762 self.logger.error(ppp("Unexpected or invalid packet:", p))
6765 # from server VRF1 back to client VRF0 (no translation)
6766 p = (Ether(src=self.pg5.remote_mac, dst=self.pg5.local_mac) /
6767 IP(src=self.pg5.remote_ip4, dst=self.pg0.remote_ip4) /
6768 TCP(sport=local_port, dport=12344))
6769 self.pg5.add_stream(p)
6770 self.pg_enable_capture(self.pg_interfaces)
6772 capture = self.pg0.get_capture(1)
6777 self.assertEqual(ip.src, self.pg5.remote_ip4)
6778 self.assertEqual(tcp.sport, local_port)
6779 self.assert_packet_checksums_valid(p)
6781 self.logger.error(ppp("Unexpected or invalid packet:", p))
6784 @unittest.skipUnless(running_extended_tests, "part of extended tests")
6785 def test_session_timeout(self):
6786 """ NAT44 session timeouts """
6787 self.nat44_add_address(self.nat_addr)
6788 flags = self.config_flags.NAT_IS_INSIDE
6789 self.vapi.nat44_interface_add_del_feature(
6790 sw_if_index=self.pg0.sw_if_index,
6791 flags=flags, is_add=1)
6792 self.vapi.nat44_interface_add_del_feature(
6793 sw_if_index=self.pg1.sw_if_index,
6795 self.vapi.nat_set_timeouts(udp=300, tcp_established=7440,
6796 tcp_transitory=240, icmp=5)
6800 for i in range(0, max_sessions):
6801 src = "10.10.%u.%u" % ((i & 0xFF00) >> 8, i & 0xFF)
6802 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
6803 IP(src=src, dst=self.pg1.remote_ip4) /
6804 ICMP(id=1025, type='echo-request'))
6806 self.pg0.add_stream(pkts)
6807 self.pg_enable_capture(self.pg_interfaces)
6809 self.pg1.get_capture(max_sessions)
6814 for i in range(0, max_sessions):
6815 src = "10.11.%u.%u" % ((i & 0xFF00) >> 8, i & 0xFF)
6816 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
6817 IP(src=src, dst=self.pg1.remote_ip4) /
6818 ICMP(id=1026, type='echo-request'))
6820 self.pg0.add_stream(pkts)
6821 self.pg_enable_capture(self.pg_interfaces)
6823 self.pg1.get_capture(max_sessions)
6826 users = self.vapi.nat44_user_dump()
6828 nsessions = nsessions + user.nsessions
6829 self.assertLess(nsessions, 2 * max_sessions)
6831 @unittest.skipUnless(running_extended_tests, "part of extended tests")
6832 def test_session_rst_timeout(self):
6833 """ NAT44 session RST timeouts """
6834 self.nat44_add_address(self.nat_addr)
6835 flags = self.config_flags.NAT_IS_INSIDE
6836 self.vapi.nat44_interface_add_del_feature(
6837 sw_if_index=self.pg0.sw_if_index,
6838 flags=flags, is_add=1)
6839 self.vapi.nat44_interface_add_del_feature(
6840 sw_if_index=self.pg1.sw_if_index,
6842 self.vapi.nat_set_timeouts(udp=300, tcp_established=7440,
6843 tcp_transitory=5, icmp=60)
6845 self.initiate_tcp_session(self.pg0, self.pg1)
6846 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6847 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6848 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
6850 self.pg0.add_stream(p)
6851 self.pg_enable_capture(self.pg_interfaces)
6853 self.pg1.get_capture(1)
6857 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6858 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6859 TCP(sport=self.tcp_port_in + 1, dport=self.tcp_external_port + 1,
6861 self.pg0.add_stream(p)
6862 self.pg_enable_capture(self.pg_interfaces)
6864 self.pg1.get_capture(1)
6867 users = self.vapi.nat44_user_dump()
6868 self.assertEqual(len(users), 1)
6869 self.assertEqual(str(users[0].ip_address),
6870 self.pg0.remote_ip4)
6871 self.assertEqual(users[0].nsessions, 1)
6873 @unittest.skipUnless(running_extended_tests, "part of extended tests")
6874 def test_session_limit_per_user(self):
6875 """ Maximum sessions per user limit """
6876 self.nat44_add_address(self.nat_addr)
6877 flags = self.config_flags.NAT_IS_INSIDE
6878 self.vapi.nat44_interface_add_del_feature(
6879 sw_if_index=self.pg0.sw_if_index,
6880 flags=flags, is_add=1)
6881 self.vapi.nat44_interface_add_del_feature(
6882 sw_if_index=self.pg1.sw_if_index,
6884 self.vapi.set_ipfix_exporter(collector_address=self.pg2.remote_ip4n,
6885 src_address=self.pg2.local_ip4n,
6887 template_interval=10)
6888 self.vapi.nat_set_timeouts(udp=5, tcp_established=7440,
6889 tcp_transitory=240, icmp=60)
6891 # get maximum number of translations per user
6892 nat44_config = self.vapi.nat_show_config()
6895 for port in range(0, nat44_config.max_translations_per_user):
6896 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6897 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6898 UDP(sport=1025 + port, dport=1025 + port))
6901 self.pg0.add_stream(pkts)
6902 self.pg_enable_capture(self.pg_interfaces)
6904 capture = self.pg1.get_capture(len(pkts))
6906 self.vapi.nat_ipfix_enable_disable(domain_id=self.ipfix_domain_id,
6907 src_port=self.ipfix_src_port,
6910 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6911 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6912 UDP(sport=3001, dport=3002))
6913 self.pg0.add_stream(p)
6914 self.pg_enable_capture(self.pg_interfaces)
6916 capture = self.pg1.assert_nothing_captured()
6918 # verify IPFIX logging
6919 self.vapi.ipfix_flush()
6921 capture = self.pg2.get_capture(10)
6922 ipfix = IPFIXDecoder()
6923 # first load template
6925 self.assertTrue(p.haslayer(IPFIX))
6926 if p.haslayer(Template):
6927 ipfix.add_template(p.getlayer(Template))
6928 # verify events in data set
6930 if p.haslayer(Data):
6931 data = ipfix.decode_data_set(p.getlayer(Set))
6932 self.verify_ipfix_max_entries_per_user(
6934 nat44_config.max_translations_per_user,
6935 self.pg0.remote_ip4n)
6938 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6939 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6940 UDP(sport=3001, dport=3002))
6941 self.pg0.add_stream(p)
6942 self.pg_enable_capture(self.pg_interfaces)
6944 self.pg1.get_capture(1)
6946 def test_syslog_sess(self):
6947 """ Test syslog session creation and deletion """
6948 self.vapi.syslog_set_filter(
6949 self.SYSLOG_SEVERITY.SYSLOG_API_SEVERITY_INFO)
6950 self.vapi.syslog_set_sender(self.pg2.local_ip4n, self.pg2.remote_ip4n)
6951 self.nat44_add_address(self.nat_addr)
6952 flags = self.config_flags.NAT_IS_INSIDE
6953 self.vapi.nat44_interface_add_del_feature(
6954 sw_if_index=self.pg0.sw_if_index,
6955 flags=flags, is_add=1)
6956 self.vapi.nat44_interface_add_del_feature(
6957 sw_if_index=self.pg1.sw_if_index,
6960 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
6961 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6962 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port))
6963 self.pg0.add_stream(p)
6964 self.pg_enable_capture(self.pg_interfaces)
6966 capture = self.pg1.get_capture(1)
6967 self.tcp_port_out = capture[0][TCP].sport
6968 capture = self.pg2.get_capture(1)
6969 self.verify_syslog_sess(capture[0][Raw].load)
6971 self.pg_enable_capture(self.pg_interfaces)
6973 self.nat44_add_address(self.nat_addr, is_add=0)
6974 capture = self.pg2.get_capture(1)
6975 self.verify_syslog_sess(capture[0][Raw].load, False)
6978 super(TestNAT44EndpointDependent, self).tearDown()
6979 if not self.vpp_dead:
6981 self.vapi.cli("clear logging")
6983 def show_commands_at_teardown(self):
6984 self.logger.info(self.vapi.cli("show nat44 addresses"))
6985 self.logger.info(self.vapi.cli("show nat44 interfaces"))
6986 self.logger.info(self.vapi.cli("show nat44 static mappings"))
6987 self.logger.info(self.vapi.cli("show nat44 interface address"))
6988 self.logger.info(self.vapi.cli("show nat44 sessions detail"))
6989 self.logger.info(self.vapi.cli("show nat44 hash tables detail"))
6990 self.logger.info(self.vapi.cli("show nat timeouts"))
6993 class TestNAT44Out2InDPO(MethodHolder):
6994 """ NAT44 Test Cases using out2in DPO """
6997 def setUpConstants(cls):
6998 super(TestNAT44Out2InDPO, cls).setUpConstants()
6999 cls.vpp_cmdline.extend(["nat", "{", "out2in dpo", "}"])
7002 def setUpClass(cls):
7003 super(TestNAT44Out2InDPO, cls).setUpClass()
7004 cls.vapi.cli("set log class nat level debug")
7007 cls.tcp_port_in = 6303
7008 cls.tcp_port_out = 6303
7009 cls.udp_port_in = 6304
7010 cls.udp_port_out = 6304
7011 cls.icmp_id_in = 6305
7012 cls.icmp_id_out = 6305
7013 cls.nat_addr = '10.0.0.3'
7014 cls.dst_ip4 = '192.168.70.1'
7016 cls.create_pg_interfaces(range(2))
7019 cls.pg0.config_ip4()
7020 cls.pg0.resolve_arp()
7023 cls.pg1.config_ip6()
7024 cls.pg1.resolve_ndp()
7026 r1 = VppIpRoute(cls, "::", 0,
7027 [VppRoutePath(cls.pg1.remote_ip6,
7028 cls.pg1.sw_if_index)],
7033 super(TestNAT44Out2InDPO, cls).tearDownClass()
7037 def tearDownClass(cls):
7038 super(TestNAT44Out2InDPO, cls).tearDownClass()
7040 def configure_xlat(self):
7041 self.dst_ip6_pfx = '1:2:3::'
7042 self.dst_ip6_pfx_n = socket.inet_pton(socket.AF_INET6,
7044 self.dst_ip6_pfx_len = 96
7045 self.src_ip6_pfx = '4:5:6::'
7046 self.src_ip6_pfx_n = socket.inet_pton(socket.AF_INET6,
7048 self.src_ip6_pfx_len = 96
7049 self.vapi.map_add_domain(self.dst_ip6_pfx_n, self.dst_ip6_pfx_len,
7050 self.src_ip6_pfx_n, self.src_ip6_pfx_len,
7051 '\x00\x00\x00\x00', 0)
7053 @unittest.skip('Temporary disabled')
7054 def test_464xlat_ce(self):
7055 """ Test 464XLAT CE with NAT44 """
7057 nat_config = self.vapi.nat_show_config()
7058 self.assertEqual(1, nat_config.out2in_dpo)
7060 self.configure_xlat()
7062 flags = self.config_flags.NAT_IS_INSIDE
7063 self.vapi.nat44_interface_add_del_feature(
7064 sw_if_index=self.pg0.sw_if_index,
7065 flags=flags, is_add=1)
7066 self.vapi.nat44_add_del_address_range(first_ip_address=self.nat_addr_n,
7067 last_ip_address=self.nat_addr_n,
7068 vrf_id=0xFFFFFFFF, is_add=1)
7070 out_src_ip6 = self.compose_ip6(self.dst_ip4, self.dst_ip6_pfx,
7071 self.dst_ip6_pfx_len)
7072 out_dst_ip6 = self.compose_ip6(self.nat_addr, self.src_ip6_pfx,
7073 self.src_ip6_pfx_len)
7076 pkts = self.create_stream_in(self.pg0, self.pg1, self.dst_ip4)
7077 self.pg0.add_stream(pkts)
7078 self.pg_enable_capture(self.pg_interfaces)
7080 capture = self.pg1.get_capture(len(pkts))
7081 self.verify_capture_out_ip6(capture, nat_ip=out_dst_ip6,
7084 pkts = self.create_stream_out_ip6(self.pg1, out_src_ip6,
7086 self.pg1.add_stream(pkts)
7087 self.pg_enable_capture(self.pg_interfaces)
7089 capture = self.pg0.get_capture(len(pkts))
7090 self.verify_capture_in(capture, self.pg0)
7092 self.vapi.nat44_interface_add_del_feature(
7093 sw_if_index=self.pg0.sw_if_index,
7095 self.vapi.nat44_add_del_address_range(
7096 first_ip_address=self.nat_addr_n,
7097 last_ip_address=self.nat_addr_n,
7100 @unittest.skip('Temporary disabled')
7101 def test_464xlat_ce_no_nat(self):
7102 """ Test 464XLAT CE without NAT44 """
7104 self.configure_xlat()
7106 out_src_ip6 = self.compose_ip6(self.dst_ip4, self.dst_ip6_pfx,
7107 self.dst_ip6_pfx_len)
7108 out_dst_ip6 = self.compose_ip6(self.pg0.remote_ip4, self.src_ip6_pfx,
7109 self.src_ip6_pfx_len)
7111 pkts = self.create_stream_in(self.pg0, self.pg1, self.dst_ip4)
7112 self.pg0.add_stream(pkts)
7113 self.pg_enable_capture(self.pg_interfaces)
7115 capture = self.pg1.get_capture(len(pkts))
7116 self.verify_capture_out_ip6(capture, dst_ip=out_src_ip6,
7117 nat_ip=out_dst_ip6, same_port=True)
7119 pkts = self.create_stream_out_ip6(self.pg1, out_src_ip6, out_dst_ip6)
7120 self.pg1.add_stream(pkts)
7121 self.pg_enable_capture(self.pg_interfaces)
7123 capture = self.pg0.get_capture(len(pkts))
7124 self.verify_capture_in(capture, self.pg0)
7127 class TestDeterministicNAT(MethodHolder):
7128 """ Deterministic NAT Test Cases """
7131 def setUpConstants(cls):
7132 super(TestDeterministicNAT, cls).setUpConstants()
7133 cls.vpp_cmdline.extend(["nat", "{", "deterministic", "}"])
7136 def setUpClass(cls):
7137 super(TestDeterministicNAT, cls).setUpClass()
7138 cls.vapi.cli("set log class nat level debug")
7141 cls.tcp_port_in = 6303
7142 cls.tcp_external_port = 6303
7143 cls.udp_port_in = 6304
7144 cls.udp_external_port = 6304
7145 cls.icmp_id_in = 6305
7146 cls.nat_addr = '10.0.0.3'
7148 cls.create_pg_interfaces(range(3))
7149 cls.interfaces = list(cls.pg_interfaces)
7151 for i in cls.interfaces:
7156 cls.pg0.generate_remote_hosts(2)
7157 cls.pg0.configure_ipv4_neighbors()
7160 super(TestDeterministicNAT, cls).tearDownClass()
7164 def tearDownClass(cls):
7165 super(TestDeterministicNAT, cls).tearDownClass()
7167 def create_stream_in(self, in_if, out_if, ttl=64):
7169 Create packet stream for inside network
7171 :param in_if: Inside interface
7172 :param out_if: Outside interface
7173 :param ttl: TTL of generated packets
7177 p = (Ether(dst=in_if.local_mac, src=in_if.remote_mac) /
7178 IP(src=in_if.remote_ip4, dst=out_if.remote_ip4, ttl=ttl) /
7179 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port))
7183 p = (Ether(dst=in_if.local_mac, src=in_if.remote_mac) /
7184 IP(src=in_if.remote_ip4, dst=out_if.remote_ip4, ttl=ttl) /
7185 UDP(sport=self.udp_port_in, dport=self.udp_external_port))
7189 p = (Ether(dst=in_if.local_mac, src=in_if.remote_mac) /
7190 IP(src=in_if.remote_ip4, dst=out_if.remote_ip4, ttl=ttl) /
7191 ICMP(id=self.icmp_id_in, type='echo-request'))
7196 def create_stream_out(self, out_if, dst_ip=None, ttl=64):
7198 Create packet stream for outside network
7200 :param out_if: Outside interface
7201 :param dst_ip: Destination IP address (Default use global NAT address)
7202 :param ttl: TTL of generated packets
7205 dst_ip = self.nat_addr
7208 p = (Ether(dst=out_if.local_mac, src=out_if.remote_mac) /
7209 IP(src=out_if.remote_ip4, dst=dst_ip, ttl=ttl) /
7210 TCP(dport=self.tcp_port_out, sport=self.tcp_external_port))
7214 p = (Ether(dst=out_if.local_mac, src=out_if.remote_mac) /
7215 IP(src=out_if.remote_ip4, dst=dst_ip, ttl=ttl) /
7216 UDP(dport=self.udp_port_out, sport=self.udp_external_port))
7220 p = (Ether(dst=out_if.local_mac, src=out_if.remote_mac) /
7221 IP(src=out_if.remote_ip4, dst=dst_ip, ttl=ttl) /
7222 ICMP(id=self.icmp_external_id, type='echo-reply'))
7227 def verify_capture_out(self, capture, nat_ip=None):
7229 Verify captured packets on outside network
7231 :param capture: Captured packets
7232 :param nat_ip: Translated IP address (Default use global NAT address)
7233 :param same_port: Source port number is not translated (Default False)
7236 nat_ip = self.nat_addr
7237 for packet in capture:
7239 self.assertEqual(packet[IP].src, nat_ip)
7240 if packet.haslayer(TCP):
7241 self.tcp_port_out = packet[TCP].sport
7242 elif packet.haslayer(UDP):
7243 self.udp_port_out = packet[UDP].sport
7245 self.icmp_external_id = packet[ICMP].id
7247 self.logger.error(ppp("Unexpected or invalid packet "
7248 "(outside network):", packet))
7251 def test_deterministic_mode(self):
7252 """ NAT plugin run deterministic mode """
7253 in_addr = '172.16.255.0'
7254 out_addr = '172.17.255.50'
7255 in_addr_t = '172.16.255.20'
7259 nat_config = self.vapi.nat_show_config()
7260 self.assertEqual(1, nat_config.deterministic)
7262 self.vapi.nat_det_add_del_map(is_add=1, in_addr=in_addr,
7263 in_plen=in_plen, out_addr=out_addr,
7266 rep1 = self.vapi.nat_det_forward(in_addr_t)
7267 self.assertEqual(str(rep1.out_addr), out_addr)
7268 rep2 = self.vapi.nat_det_reverse(rep1.out_port_hi, out_addr)
7270 self.assertEqual(str(rep2.in_addr), in_addr_t)
7272 deterministic_mappings = self.vapi.nat_det_map_dump()
7273 self.assertEqual(len(deterministic_mappings), 1)
7274 dsm = deterministic_mappings[0]
7275 self.assertEqual(in_addr, str(dsm.in_addr))
7276 self.assertEqual(in_plen, dsm.in_plen)
7277 self.assertEqual(out_addr, str(dsm.out_addr))
7278 self.assertEqual(out_plen, dsm.out_plen)
7280 self.clear_nat_det()
7281 deterministic_mappings = self.vapi.nat_det_map_dump()
7282 self.assertEqual(len(deterministic_mappings), 0)
7284 def test_set_timeouts(self):
7285 """ Set deterministic NAT timeouts """
7286 timeouts_before = self.vapi.nat_get_timeouts()
7288 self.vapi.nat_set_timeouts(
7289 udp=timeouts_before.udp + 10,
7290 tcp_established=timeouts_before.tcp_established + 10,
7291 tcp_transitory=timeouts_before.tcp_transitory + 10,
7292 icmp=timeouts_before.icmp + 10)
7294 timeouts_after = self.vapi.nat_get_timeouts()
7296 self.assertNotEqual(timeouts_before.udp, timeouts_after.udp)
7297 self.assertNotEqual(timeouts_before.icmp, timeouts_after.icmp)
7298 self.assertNotEqual(timeouts_before.tcp_established,
7299 timeouts_after.tcp_established)
7300 self.assertNotEqual(timeouts_before.tcp_transitory,
7301 timeouts_after.tcp_transitory)
7303 def test_det_in(self):
7304 """ Deterministic NAT translation test (TCP, UDP, ICMP) """
7306 nat_ip = "10.0.0.10"
7308 self.vapi.nat_det_add_del_map(is_add=1, in_addr=self.pg0.remote_ip4n,
7310 out_addr=socket.inet_aton(nat_ip),
7313 flags = self.config_flags.NAT_IS_INSIDE
7314 self.vapi.nat44_interface_add_del_feature(
7315 sw_if_index=self.pg0.sw_if_index,
7316 flags=flags, is_add=1)
7317 self.vapi.nat44_interface_add_del_feature(
7318 sw_if_index=self.pg1.sw_if_index,
7322 pkts = self.create_stream_in(self.pg0, self.pg1)
7323 self.pg0.add_stream(pkts)
7324 self.pg_enable_capture(self.pg_interfaces)
7326 capture = self.pg1.get_capture(len(pkts))
7327 self.verify_capture_out(capture, nat_ip)
7330 pkts = self.create_stream_out(self.pg1, nat_ip)
7331 self.pg1.add_stream(pkts)
7332 self.pg_enable_capture(self.pg_interfaces)
7334 capture = self.pg0.get_capture(len(pkts))
7335 self.verify_capture_in(capture, self.pg0)
7338 sessions = self.vapi.nat_det_session_dump(self.pg0.remote_ip4n)
7339 self.assertEqual(len(sessions), 3)
7343 self.assertEqual(str(s.ext_addr), self.pg1.remote_ip4)
7344 self.assertEqual(s.in_port, self.tcp_port_in)
7345 self.assertEqual(s.out_port, self.tcp_port_out)
7346 self.assertEqual(s.ext_port, self.tcp_external_port)
7350 self.assertEqual(str(s.ext_addr), self.pg1.remote_ip4)
7351 self.assertEqual(s.in_port, self.udp_port_in)
7352 self.assertEqual(s.out_port, self.udp_port_out)
7353 self.assertEqual(s.ext_port, self.udp_external_port)
7357 self.assertEqual(str(s.ext_addr), self.pg1.remote_ip4)
7358 self.assertEqual(s.in_port, self.icmp_id_in)
7359 self.assertEqual(s.out_port, self.icmp_external_id)
7361 def test_multiple_users(self):
7362 """ Deterministic NAT multiple users """
7364 nat_ip = "10.0.0.10"
7366 external_port = 6303
7368 host0 = self.pg0.remote_hosts[0]
7369 host1 = self.pg0.remote_hosts[1]
7371 self.vapi.nat_det_add_del_map(is_add=1, in_addr=host0.ip4n, in_plen=24,
7372 out_addr=socket.inet_aton(nat_ip),
7374 flags = self.config_flags.NAT_IS_INSIDE
7375 self.vapi.nat44_interface_add_del_feature(
7376 sw_if_index=self.pg0.sw_if_index,
7377 flags=flags, is_add=1)
7378 self.vapi.nat44_interface_add_del_feature(
7379 sw_if_index=self.pg1.sw_if_index,
7383 p = (Ether(src=host0.mac, dst=self.pg0.local_mac) /
7384 IP(src=host0.ip4, dst=self.pg1.remote_ip4) /
7385 TCP(sport=port_in, dport=external_port))
7386 self.pg0.add_stream(p)
7387 self.pg_enable_capture(self.pg_interfaces)
7389 capture = self.pg1.get_capture(1)
7394 self.assertEqual(ip.src, nat_ip)
7395 self.assertEqual(ip.dst, self.pg1.remote_ip4)
7396 self.assertEqual(tcp.dport, external_port)
7397 port_out0 = tcp.sport
7399 self.logger.error(ppp("Unexpected or invalid packet:", p))
7403 p = (Ether(src=host1.mac, dst=self.pg0.local_mac) /
7404 IP(src=host1.ip4, dst=self.pg1.remote_ip4) /
7405 TCP(sport=port_in, dport=external_port))
7406 self.pg0.add_stream(p)
7407 self.pg_enable_capture(self.pg_interfaces)
7409 capture = self.pg1.get_capture(1)
7414 self.assertEqual(ip.src, nat_ip)
7415 self.assertEqual(ip.dst, self.pg1.remote_ip4)
7416 self.assertEqual(tcp.dport, external_port)
7417 port_out1 = tcp.sport
7419 self.logger.error(ppp("Unexpected or invalid packet:", p))
7422 dms = self.vapi.nat_det_map_dump()
7423 self.assertEqual(1, len(dms))
7424 self.assertEqual(2, dms[0].ses_num)
7427 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
7428 IP(src=self.pg1.remote_ip4, dst=nat_ip) /
7429 TCP(sport=external_port, dport=port_out0))
7430 self.pg1.add_stream(p)
7431 self.pg_enable_capture(self.pg_interfaces)
7433 capture = self.pg0.get_capture(1)
7438 self.assertEqual(ip.src, self.pg1.remote_ip4)
7439 self.assertEqual(ip.dst, host0.ip4)
7440 self.assertEqual(tcp.dport, port_in)
7441 self.assertEqual(tcp.sport, external_port)
7443 self.logger.error(ppp("Unexpected or invalid packet:", p))
7447 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
7448 IP(src=self.pg1.remote_ip4, dst=nat_ip) /
7449 TCP(sport=external_port, dport=port_out1))
7450 self.pg1.add_stream(p)
7451 self.pg_enable_capture(self.pg_interfaces)
7453 capture = self.pg0.get_capture(1)
7458 self.assertEqual(ip.src, self.pg1.remote_ip4)
7459 self.assertEqual(ip.dst, host1.ip4)
7460 self.assertEqual(tcp.dport, port_in)
7461 self.assertEqual(tcp.sport, external_port)
7463 self.logger.error(ppp("Unexpected or invalid packet", p))
7466 # session close api test
7467 self.vapi.nat_det_close_session_out(socket.inet_aton(nat_ip),
7469 self.pg1.remote_ip4n,
7471 dms = self.vapi.nat_det_map_dump()
7472 self.assertEqual(dms[0].ses_num, 1)
7474 self.vapi.nat_det_close_session_in(host0.ip4n,
7476 self.pg1.remote_ip4n,
7478 dms = self.vapi.nat_det_map_dump()
7479 self.assertEqual(dms[0].ses_num, 0)
7481 def test_tcp_session_close_detection_in(self):
7482 """ Deterministic NAT TCP session close from inside network """
7483 self.vapi.nat_det_add_del_map(is_add=1, in_addr=self.pg0.remote_ip4n,
7485 out_addr=socket.inet_aton(self.nat_addr),
7487 flags = self.config_flags.NAT_IS_INSIDE
7488 self.vapi.nat44_interface_add_del_feature(
7489 sw_if_index=self.pg0.sw_if_index,
7490 flags=flags, is_add=1)
7491 self.vapi.nat44_interface_add_del_feature(
7492 sw_if_index=self.pg1.sw_if_index,
7495 self.initiate_tcp_session(self.pg0, self.pg1)
7497 # close the session from inside
7499 # FIN packet in -> out
7500 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
7501 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
7502 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
7504 self.pg0.add_stream(p)
7505 self.pg_enable_capture(self.pg_interfaces)
7507 self.pg1.get_capture(1)
7511 # ACK packet out -> in
7512 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
7513 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
7514 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
7518 # FIN packet out -> in
7519 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
7520 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
7521 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
7525 self.pg1.add_stream(pkts)
7526 self.pg_enable_capture(self.pg_interfaces)
7528 self.pg0.get_capture(2)
7530 # ACK packet in -> out
7531 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
7532 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
7533 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
7535 self.pg0.add_stream(p)
7536 self.pg_enable_capture(self.pg_interfaces)
7538 self.pg1.get_capture(1)
7540 # Check if deterministic NAT44 closed the session
7541 dms = self.vapi.nat_det_map_dump()
7542 self.assertEqual(0, dms[0].ses_num)
7544 self.logger.error("TCP session termination failed")
7547 def test_tcp_session_close_detection_out(self):
7548 """ Deterministic NAT TCP session close from outside network """
7549 self.vapi.nat_det_add_del_map(is_add=1, in_addr=self.pg0.remote_ip4n,
7551 out_addr=socket.inet_aton(self.nat_addr),
7553 flags = self.config_flags.NAT_IS_INSIDE
7554 self.vapi.nat44_interface_add_del_feature(
7555 sw_if_index=self.pg0.sw_if_index,
7556 flags=flags, is_add=1)
7557 self.vapi.nat44_interface_add_del_feature(
7558 sw_if_index=self.pg1.sw_if_index,
7561 self.initiate_tcp_session(self.pg0, self.pg1)
7563 # close the session from outside
7565 # FIN packet out -> in
7566 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
7567 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
7568 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
7570 self.pg1.add_stream(p)
7571 self.pg_enable_capture(self.pg_interfaces)
7573 self.pg0.get_capture(1)
7577 # ACK packet in -> out
7578 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
7579 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
7580 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
7584 # ACK packet in -> out
7585 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
7586 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
7587 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
7591 self.pg0.add_stream(pkts)
7592 self.pg_enable_capture(self.pg_interfaces)
7594 self.pg1.get_capture(2)
7596 # ACK packet out -> in
7597 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
7598 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
7599 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
7601 self.pg1.add_stream(p)
7602 self.pg_enable_capture(self.pg_interfaces)
7604 self.pg0.get_capture(1)
7606 # Check if deterministic NAT44 closed the session
7607 dms = self.vapi.nat_det_map_dump()
7608 self.assertEqual(0, dms[0].ses_num)
7610 self.logger.error("TCP session termination failed")
7613 @unittest.skipUnless(running_extended_tests, "part of extended tests")
7614 def test_session_timeout(self):
7615 """ Deterministic NAT session timeouts """
7616 self.vapi.nat_det_add_del_map(is_add=1, in_addr=self.pg0.remote_ip4n,
7618 out_addr=socket.inet_aton(self.nat_addr),
7620 flags = self.config_flags.NAT_IS_INSIDE
7621 self.vapi.nat44_interface_add_del_feature(
7622 sw_if_index=self.pg0.sw_if_index,
7623 flags=flags, is_add=1)
7624 self.vapi.nat44_interface_add_del_feature(
7625 sw_if_index=self.pg1.sw_if_index,
7628 self.initiate_tcp_session(self.pg0, self.pg1)
7629 self.vapi.nat_set_timeouts(udp=5, tcp_established=5, tcp_transitory=5,
7631 pkts = self.create_stream_in(self.pg0, self.pg1)
7632 self.pg0.add_stream(pkts)
7633 self.pg_enable_capture(self.pg_interfaces)
7635 capture = self.pg1.get_capture(len(pkts))
7638 dms = self.vapi.nat_det_map_dump()
7639 self.assertEqual(0, dms[0].ses_num)
7641 @unittest.skipUnless(running_extended_tests, "part of extended tests")
7642 def test_session_limit_per_user(self):
7643 """ Deterministic NAT maximum sessions per user limit """
7644 self.vapi.nat_det_add_del_map(is_add=1, in_addr=self.pg0.remote_ip4n,
7646 out_addr=socket.inet_aton(self.nat_addr),
7648 flags = self.config_flags.NAT_IS_INSIDE
7649 self.vapi.nat44_interface_add_del_feature(
7650 sw_if_index=self.pg0.sw_if_index,
7651 flags=flags, is_add=1)
7652 self.vapi.nat44_interface_add_del_feature(
7653 sw_if_index=self.pg1.sw_if_index,
7655 self.vapi.set_ipfix_exporter(collector_address=self.pg2.remote_ip4n,
7656 src_address=self.pg2.local_ip4n,
7658 template_interval=10)
7659 self.vapi.nat_ipfix_enable_disable(domain_id=1, src_port=4739,
7663 for port in range(1025, 2025):
7664 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
7665 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
7666 UDP(sport=port, dport=port))
7669 self.pg0.add_stream(pkts)
7670 self.pg_enable_capture(self.pg_interfaces)
7672 capture = self.pg1.get_capture(len(pkts))
7674 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
7675 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
7676 UDP(sport=3001, dport=3002))
7677 self.pg0.add_stream(p)
7678 self.pg_enable_capture(self.pg_interfaces)
7680 capture = self.pg1.assert_nothing_captured()
7682 # verify ICMP error packet
7683 capture = self.pg0.get_capture(1)
7685 self.assertTrue(p.haslayer(ICMP))
7687 self.assertEqual(icmp.type, 3)
7688 self.assertEqual(icmp.code, 1)
7689 self.assertTrue(icmp.haslayer(IPerror))
7690 inner_ip = icmp[IPerror]
7691 self.assertEqual(inner_ip[UDPerror].sport, 3001)
7692 self.assertEqual(inner_ip[UDPerror].dport, 3002)
7694 dms = self.vapi.nat_det_map_dump()
7696 self.assertEqual(1000, dms[0].ses_num)
7698 # verify IPFIX logging
7699 self.vapi.ipfix_flush()
7701 capture = self.pg2.get_capture(2)
7702 ipfix = IPFIXDecoder()
7703 # first load template
7705 self.assertTrue(p.haslayer(IPFIX))
7706 if p.haslayer(Template):
7707 ipfix.add_template(p.getlayer(Template))
7708 # verify events in data set
7710 if p.haslayer(Data):
7711 data = ipfix.decode_data_set(p.getlayer(Set))
7712 self.verify_ipfix_max_entries_per_user(data,
7714 self.pg0.remote_ip4n)
7716 def clear_nat_det(self):
7718 Clear deterministic NAT configuration.
7720 self.vapi.nat_ipfix_enable_disable(domain_id=1, src_port=4739,
7722 self.vapi.nat_set_timeouts(udp=300, tcp_established=7440,
7723 tcp_transitory=240, icmp=60)
7724 deterministic_mappings = self.vapi.nat_det_map_dump()
7725 for dsm in deterministic_mappings:
7726 self.vapi.nat_det_add_del_map(is_add=0, in_addr=dsm.in_addr,
7727 in_plen=dsm.in_plen,
7728 out_addr=dsm.out_addr,
7729 out_plen=dsm.out_plen)
7731 interfaces = self.vapi.nat44_interface_dump()
7732 for intf in interfaces:
7733 self.vapi.nat44_interface_add_del_feature(
7734 sw_if_index=intf.sw_if_index,
7738 super(TestDeterministicNAT, self).tearDown()
7739 if not self.vpp_dead:
7740 self.clear_nat_det()
7742 def show_commands_at_teardown(self):
7743 self.logger.info(self.vapi.cli("show nat44 interfaces"))
7744 self.logger.info(self.vapi.cli("show nat timeouts"))
7746 self.vapi.cli("show nat44 deterministic mappings"))
7748 self.vapi.cli("show nat44 deterministic sessions"))
7751 class TestNAT64(MethodHolder):
7752 """ NAT64 Test Cases """
7755 def setUpConstants(cls):
7756 super(TestNAT64, cls).setUpConstants()
7757 cls.vpp_cmdline.extend(["nat", "{", "nat64 bib hash buckets 128",
7758 "nat64 st hash buckets 256", "}"])
7761 def setUpClass(cls):
7762 super(TestNAT64, cls).setUpClass()
7765 cls.tcp_port_in = 6303
7766 cls.tcp_port_out = 6303
7767 cls.udp_port_in = 6304
7768 cls.udp_port_out = 6304
7769 cls.icmp_id_in = 6305
7770 cls.icmp_id_out = 6305
7771 cls.tcp_external_port = 80
7772 cls.nat_addr = '10.0.0.3'
7773 cls.nat_addr_n = socket.inet_pton(socket.AF_INET, cls.nat_addr)
7775 cls.vrf1_nat_addr = '10.0.10.3'
7776 cls.ipfix_src_port = 4739
7777 cls.ipfix_domain_id = 1
7779 cls.create_pg_interfaces(range(6))
7780 cls.ip6_interfaces = list(cls.pg_interfaces[0:1])
7781 cls.ip6_interfaces.append(cls.pg_interfaces[2])
7782 cls.ip4_interfaces = list(cls.pg_interfaces[1:2])
7784 cls.vapi.ip_table_add_del(is_ipv6=1, is_add=1,
7785 table_id=cls.vrf1_id)
7787 cls.pg_interfaces[2].set_table_ip6(cls.vrf1_id)
7789 cls.pg0.generate_remote_hosts(2)
7791 for i in cls.ip6_interfaces:
7794 i.configure_ipv6_neighbors()
7796 for i in cls.ip4_interfaces:
7802 cls.pg3.config_ip4()
7803 cls.pg3.resolve_arp()
7804 cls.pg3.config_ip6()
7805 cls.pg3.configure_ipv6_neighbors()
7808 cls.pg5.config_ip6()
7811 super(TestNAT64, cls).tearDownClass()
7815 def tearDownClass(cls):
7816 super(TestNAT64, cls).tearDownClass()
7818 def test_nat64_inside_interface_handles_neighbor_advertisement(self):
7819 """ NAT64 inside interface handles Neighbor Advertisement """
7821 flags = self.config_flags.NAT_IS_INSIDE
7822 self.vapi.nat64_add_del_interface(is_add=1, flags=flags,
7823 sw_if_index=self.pg5.sw_if_index)
7826 ping = (Ether(dst=self.pg5.local_mac, src=self.pg5.remote_mac) /
7827 IPv6(src=self.pg5.remote_ip6, dst=self.pg5.local_ip6) /
7828 ICMPv6EchoRequest())
7830 self.pg5.add_stream(pkts)
7831 self.pg_enable_capture(self.pg_interfaces)
7834 # Wait for Neighbor Solicitation
7835 capture = self.pg5.get_capture(len(pkts))
7838 self.assertEqual(packet[IPv6].src, self.pg5.local_ip6)
7839 self.assertEqual(packet.haslayer(ICMPv6ND_NS), 1)
7840 tgt = packet[ICMPv6ND_NS].tgt
7842 self.logger.error(ppp("Unexpected or invalid packet:", packet))
7845 # Send Neighbor Advertisement
7846 p = (Ether(dst=self.pg5.local_mac, src=self.pg5.remote_mac) /
7847 IPv6(src=self.pg5.remote_ip6, dst=self.pg5.local_ip6) /
7848 ICMPv6ND_NA(tgt=tgt) /
7849 ICMPv6NDOptDstLLAddr(lladdr=self.pg5.remote_mac))
7851 self.pg5.add_stream(pkts)
7852 self.pg_enable_capture(self.pg_interfaces)
7855 # Try to send ping again
7857 self.pg5.add_stream(pkts)
7858 self.pg_enable_capture(self.pg_interfaces)
7861 # Wait for ping reply
7862 capture = self.pg5.get_capture(len(pkts))
7865 self.assertEqual(packet[IPv6].src, self.pg5.local_ip6)
7866 self.assertEqual(packet[IPv6].dst, self.pg5.remote_ip6)
7867 self.assertEqual(packet.haslayer(ICMPv6EchoReply), 1)
7869 self.logger.error(ppp("Unexpected or invalid packet:", packet))
7872 def test_pool(self):
7873 """ Add/delete address to NAT64 pool """
7874 nat_addr = '1.2.3.4'
7876 self.vapi.nat64_add_del_pool_addr_range(start_addr=nat_addr,
7878 vrf_id=0xFFFFFFFF, is_add=1)
7880 addresses = self.vapi.nat64_pool_addr_dump()
7881 self.assertEqual(len(addresses), 1)
7882 self.assertEqual(str(addresses[0].address), nat_addr)
7884 self.vapi.nat64_add_del_pool_addr_range(start_addr=nat_addr,
7886 vrf_id=0xFFFFFFFF, is_add=0)
7888 addresses = self.vapi.nat64_pool_addr_dump()
7889 self.assertEqual(len(addresses), 0)
7891 def test_interface(self):
7892 """ Enable/disable NAT64 feature on the interface """
7893 flags = self.config_flags.NAT_IS_INSIDE
7894 self.vapi.nat64_add_del_interface(is_add=1, flags=flags,
7895 sw_if_index=self.pg0.sw_if_index)
7896 self.vapi.nat64_add_del_interface(is_add=1, flags=0,
7897 sw_if_index=self.pg1.sw_if_index)
7899 interfaces = self.vapi.nat64_interface_dump()
7900 self.assertEqual(len(interfaces), 2)
7903 for intf in interfaces:
7904 if intf.sw_if_index == self.pg0.sw_if_index:
7905 self.assertEqual(intf.flags, self.config_flags.NAT_IS_INSIDE)
7907 elif intf.sw_if_index == self.pg1.sw_if_index:
7908 self.assertEqual(intf.flags, self.config_flags.NAT_IS_OUTSIDE)
7910 self.assertTrue(pg0_found)
7911 self.assertTrue(pg1_found)
7913 features = self.vapi.cli("show interface features pg0")
7914 self.assertIn('nat64-in2out', features)
7915 features = self.vapi.cli("show interface features pg1")
7916 self.assertIn('nat64-out2in', features)
7918 self.vapi.nat64_add_del_interface(is_add=0, flags=flags,
7919 sw_if_index=self.pg0.sw_if_index)
7920 self.vapi.nat64_add_del_interface(is_add=0, flags=flags,
7921 sw_if_index=self.pg1.sw_if_index)
7923 interfaces = self.vapi.nat64_interface_dump()
7924 self.assertEqual(len(interfaces), 0)
7926 def test_static_bib(self):
7927 """ Add/delete static BIB entry """
7928 in_addr = '2001:db8:85a3::8a2e:370:7334'
7929 out_addr = '10.1.1.3'
7932 proto = IP_PROTOS.tcp
7934 self.vapi.nat64_add_del_static_bib(i_addr=in_addr, o_addr=out_addr,
7935 i_port=in_port, o_port=out_port,
7936 proto=proto, vrf_id=0, is_add=1)
7937 bib = self.vapi.nat64_bib_dump(proto=IP_PROTOS.tcp)
7940 if bibe.flags & self.config_flags.NAT_IS_STATIC:
7942 self.assertEqual(str(bibe.i_addr), in_addr)
7943 self.assertEqual(str(bibe.o_addr), out_addr)
7944 self.assertEqual(bibe.i_port, in_port)
7945 self.assertEqual(bibe.o_port, out_port)
7946 self.assertEqual(static_bib_num, 1)
7947 bibs = self.statistics.get_counter('/nat64/total-bibs')
7948 self.assertEqual(bibs[0][0], 1)
7950 self.vapi.nat64_add_del_static_bib(i_addr=in_addr, o_addr=out_addr,
7951 i_port=in_port, o_port=out_port,
7952 proto=proto, vrf_id=0, is_add=0)
7953 bib = self.vapi.nat64_bib_dump(proto=IP_PROTOS.tcp)
7956 if bibe.flags & self.config_flags.NAT_IS_STATIC:
7958 self.assertEqual(static_bib_num, 0)
7959 bibs = self.statistics.get_counter('/nat64/total-bibs')
7960 self.assertEqual(bibs[0][0], 0)
7962 def test_set_timeouts(self):
7963 """ Set NAT64 timeouts """
7964 # verify default values
7965 timeouts = self.vapi.nat_get_timeouts()
7966 self.assertEqual(timeouts.udp, 300)
7967 self.assertEqual(timeouts.icmp, 60)
7968 self.assertEqual(timeouts.tcp_transitory, 240)
7969 self.assertEqual(timeouts.tcp_established, 7440)
7971 # set and verify custom values
7972 self.vapi.nat_set_timeouts(udp=200, tcp_established=7450,
7973 tcp_transitory=250, icmp=30)
7974 timeouts = self.vapi.nat_get_timeouts()
7975 self.assertEqual(timeouts.udp, 200)
7976 self.assertEqual(timeouts.icmp, 30)
7977 self.assertEqual(timeouts.tcp_transitory, 250)
7978 self.assertEqual(timeouts.tcp_established, 7450)
7980 def test_dynamic(self):
7981 """ NAT64 dynamic translation test """
7982 self.tcp_port_in = 6303
7983 self.udp_port_in = 6304
7984 self.icmp_id_in = 6305
7986 ses_num_start = self.nat64_get_ses_num()
7988 self.vapi.nat64_add_del_pool_addr_range(start_addr=self.nat_addr,
7989 end_addr=self.nat_addr,
7992 flags = self.config_flags.NAT_IS_INSIDE
7993 self.vapi.nat64_add_del_interface(is_add=1, flags=flags,
7994 sw_if_index=self.pg0.sw_if_index)
7995 self.vapi.nat64_add_del_interface(is_add=1, flags=0,
7996 sw_if_index=self.pg1.sw_if_index)
7999 tcpn = self.statistics.get_err_counter('/err/nat64-in2out/TCP packets')
8000 udpn = self.statistics.get_err_counter('/err/nat64-in2out/UDP packets')
8001 icmpn = self.statistics.get_err_counter(
8002 '/err/nat64-in2out/ICMP packets')
8003 totaln = self.statistics.get_err_counter(
8004 '/err/nat64-in2out/good in2out packets processed')
8006 pkts = self.create_stream_in_ip6(self.pg0, self.pg1)
8007 self.pg0.add_stream(pkts)
8008 self.pg_enable_capture(self.pg_interfaces)
8010 capture = self.pg1.get_capture(len(pkts))
8011 self.verify_capture_out(capture, nat_ip=self.nat_addr,
8012 dst_ip=self.pg1.remote_ip4)
8014 err = self.statistics.get_err_counter('/err/nat64-in2out/TCP packets')
8015 self.assertEqual(err - tcpn, 1)
8016 err = self.statistics.get_err_counter('/err/nat64-in2out/UDP packets')
8017 self.assertEqual(err - udpn, 1)
8018 err = self.statistics.get_err_counter('/err/nat64-in2out/ICMP packets')
8019 self.assertEqual(err - icmpn, 1)
8020 err = self.statistics.get_err_counter(
8021 '/err/nat64-in2out/good in2out packets processed')
8022 self.assertEqual(err - totaln, 3)
8025 tcpn = self.statistics.get_err_counter('/err/nat64-out2in/TCP packets')
8026 udpn = self.statistics.get_err_counter('/err/nat64-out2in/UDP packets')
8027 icmpn = self.statistics.get_err_counter(
8028 '/err/nat64-out2in/ICMP packets')
8029 totaln = self.statistics.get_err_counter(
8030 '/err/nat64-out2in/good out2in packets processed')
8032 pkts = self.create_stream_out(self.pg1, dst_ip=self.nat_addr)
8033 self.pg1.add_stream(pkts)
8034 self.pg_enable_capture(self.pg_interfaces)
8036 capture = self.pg0.get_capture(len(pkts))
8037 ip = IPv6(src=''.join(['64:ff9b::', self.pg1.remote_ip4]))
8038 self.verify_capture_in_ip6(capture, ip[IPv6].src, self.pg0.remote_ip6)
8040 err = self.statistics.get_err_counter('/err/nat64-out2in/TCP packets')
8041 self.assertEqual(err - tcpn, 1)
8042 err = self.statistics.get_err_counter('/err/nat64-out2in/UDP packets')
8043 self.assertEqual(err - udpn, 1)
8044 err = self.statistics.get_err_counter('/err/nat64-out2in/ICMP packets')
8045 self.assertEqual(err - icmpn, 1)
8046 err = self.statistics.get_err_counter(
8047 '/err/nat64-out2in/good out2in packets processed')
8048 self.assertEqual(err - totaln, 3)
8050 bibs = self.statistics.get_counter('/nat64/total-bibs')
8051 self.assertEqual(bibs[0][0], 3)
8052 sessions = self.statistics.get_counter('/nat64/total-sessions')
8053 self.assertEqual(sessions[0][0], 3)
8056 pkts = self.create_stream_in_ip6(self.pg0, self.pg1)
8057 self.pg0.add_stream(pkts)
8058 self.pg_enable_capture(self.pg_interfaces)
8060 capture = self.pg1.get_capture(len(pkts))
8061 self.verify_capture_out(capture, nat_ip=self.nat_addr,
8062 dst_ip=self.pg1.remote_ip4)
8065 pkts = self.create_stream_out(self.pg1, dst_ip=self.nat_addr)
8066 self.pg1.add_stream(pkts)
8067 self.pg_enable_capture(self.pg_interfaces)
8069 capture = self.pg0.get_capture(len(pkts))
8070 self.verify_capture_in_ip6(capture, ip[IPv6].src, self.pg0.remote_ip6)
8072 ses_num_end = self.nat64_get_ses_num()
8074 self.assertEqual(ses_num_end - ses_num_start, 3)
8076 # tenant with specific VRF
8077 self.vapi.nat64_add_del_pool_addr_range(start_addr=self.vrf1_nat_addr,
8078 end_addr=self.vrf1_nat_addr,
8079 vrf_id=self.vrf1_id, is_add=1)
8080 flags = self.config_flags.NAT_IS_INSIDE
8081 self.vapi.nat64_add_del_interface(is_add=1, flags=flags,
8082 sw_if_index=self.pg2.sw_if_index)
8084 pkts = self.create_stream_in_ip6(self.pg2, self.pg1)
8085 self.pg2.add_stream(pkts)
8086 self.pg_enable_capture(self.pg_interfaces)
8088 capture = self.pg1.get_capture(len(pkts))
8089 self.verify_capture_out(capture, nat_ip=self.vrf1_nat_addr,
8090 dst_ip=self.pg1.remote_ip4)
8092 pkts = self.create_stream_out(self.pg1, dst_ip=self.vrf1_nat_addr)
8093 self.pg1.add_stream(pkts)
8094 self.pg_enable_capture(self.pg_interfaces)
8096 capture = self.pg2.get_capture(len(pkts))
8097 self.verify_capture_in_ip6(capture, ip[IPv6].src, self.pg2.remote_ip6)
8099 def test_static(self):
8100 """ NAT64 static translation test """
8101 self.tcp_port_in = 60303
8102 self.udp_port_in = 60304
8103 self.icmp_id_in = 60305
8104 self.tcp_port_out = 60303
8105 self.udp_port_out = 60304
8106 self.icmp_id_out = 60305
8108 ses_num_start = self.nat64_get_ses_num()
8110 self.vapi.nat64_add_del_pool_addr_range(start_addr=self.nat_addr,
8111 end_addr=self.nat_addr,
8114 flags = self.config_flags.NAT_IS_INSIDE
8115 self.vapi.nat64_add_del_interface(is_add=1, flags=flags,
8116 sw_if_index=self.pg0.sw_if_index)
8117 self.vapi.nat64_add_del_interface(is_add=1, flags=0,
8118 sw_if_index=self.pg1.sw_if_index)
8120 self.vapi.nat64_add_del_static_bib(i_addr=self.pg0.remote_ip6n,
8121 o_addr=self.nat_addr,
8122 i_port=self.tcp_port_in,
8123 o_port=self.tcp_port_out,
8124 proto=IP_PROTOS.tcp, vrf_id=0,
8126 self.vapi.nat64_add_del_static_bib(i_addr=self.pg0.remote_ip6n,
8127 o_addr=self.nat_addr,
8128 i_port=self.udp_port_in,
8129 o_port=self.udp_port_out,
8130 proto=IP_PROTOS.udp, vrf_id=0,
8132 self.vapi.nat64_add_del_static_bib(i_addr=self.pg0.remote_ip6n,
8133 o_addr=self.nat_addr,
8134 i_port=self.icmp_id_in,
8135 o_port=self.icmp_id_out,
8136 proto=IP_PROTOS.icmp, vrf_id=0,
8140 pkts = self.create_stream_in_ip6(self.pg0, self.pg1)
8141 self.pg0.add_stream(pkts)
8142 self.pg_enable_capture(self.pg_interfaces)
8144 capture = self.pg1.get_capture(len(pkts))
8145 self.verify_capture_out(capture, nat_ip=self.nat_addr,
8146 dst_ip=self.pg1.remote_ip4, same_port=True)
8149 pkts = self.create_stream_out(self.pg1, dst_ip=self.nat_addr)
8150 self.pg1.add_stream(pkts)
8151 self.pg_enable_capture(self.pg_interfaces)
8153 capture = self.pg0.get_capture(len(pkts))
8154 ip = IPv6(src=''.join(['64:ff9b::', self.pg1.remote_ip4]))
8155 self.verify_capture_in_ip6(capture, ip[IPv6].src, self.pg0.remote_ip6)
8157 ses_num_end = self.nat64_get_ses_num()
8159 self.assertEqual(ses_num_end - ses_num_start, 3)
8161 @unittest.skipUnless(running_extended_tests, "part of extended tests")
8162 def test_session_timeout(self):
8163 """ NAT64 session timeout """
8164 self.icmp_id_in = 1234
8165 self.vapi.nat64_add_del_pool_addr_range(start_addr=self.nat_addr,
8166 end_addr=self.nat_addr,
8169 flags = self.config_flags.NAT_IS_INSIDE
8170 self.vapi.nat64_add_del_interface(is_add=1, flags=flags,
8171 sw_if_index=self.pg0.sw_if_index)
8172 self.vapi.nat64_add_del_interface(is_add=1, flags=0,
8173 sw_if_index=self.pg1.sw_if_index)
8174 self.vapi.nat_set_timeouts(udp=300, tcp_established=5,
8178 pkts = self.create_stream_in_ip6(self.pg0, self.pg1)
8179 self.pg0.add_stream(pkts)
8180 self.pg_enable_capture(self.pg_interfaces)
8182 capture = self.pg1.get_capture(len(pkts))
8184 ses_num_before_timeout = self.nat64_get_ses_num()
8188 # ICMP and TCP session after timeout
8189 ses_num_after_timeout = self.nat64_get_ses_num()
8190 self.assertEqual(ses_num_before_timeout - ses_num_after_timeout, 2)
8192 def test_icmp_error(self):
8193 """ NAT64 ICMP Error message translation """
8194 self.tcp_port_in = 6303
8195 self.udp_port_in = 6304
8196 self.icmp_id_in = 6305
8198 self.vapi.nat64_add_del_pool_addr_range(start_addr=self.nat_addr,
8199 end_addr=self.nat_addr,
8202 flags = self.config_flags.NAT_IS_INSIDE
8203 self.vapi.nat64_add_del_interface(is_add=1, flags=flags,
8204 sw_if_index=self.pg0.sw_if_index)
8205 self.vapi.nat64_add_del_interface(is_add=1, flags=0,
8206 sw_if_index=self.pg1.sw_if_index)
8208 # send some packets to create sessions
8209 pkts = self.create_stream_in_ip6(self.pg0, self.pg1)
8210 self.pg0.add_stream(pkts)
8211 self.pg_enable_capture(self.pg_interfaces)
8213 capture_ip4 = self.pg1.get_capture(len(pkts))
8214 self.verify_capture_out(capture_ip4,
8215 nat_ip=self.nat_addr,
8216 dst_ip=self.pg1.remote_ip4)
8218 pkts = self.create_stream_out(self.pg1, dst_ip=self.nat_addr)
8219 self.pg1.add_stream(pkts)
8220 self.pg_enable_capture(self.pg_interfaces)
8222 capture_ip6 = self.pg0.get_capture(len(pkts))
8223 ip = IPv6(src=''.join(['64:ff9b::', self.pg1.remote_ip4]))
8224 self.verify_capture_in_ip6(capture_ip6, ip[IPv6].src,
8225 self.pg0.remote_ip6)
8228 pkts = [Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
8229 IPv6(src=self.pg0.remote_ip6, dst=ip[IPv6].src) /
8230 ICMPv6DestUnreach(code=1) /
8231 packet[IPv6] for packet in capture_ip6]
8232 self.pg0.add_stream(pkts)
8233 self.pg_enable_capture(self.pg_interfaces)
8235 capture = self.pg1.get_capture(len(pkts))
8236 for packet in capture:
8238 self.assertEqual(packet[IP].src, self.nat_addr)
8239 self.assertEqual(packet[IP].dst, self.pg1.remote_ip4)
8240 self.assertEqual(packet[ICMP].type, 3)
8241 self.assertEqual(packet[ICMP].code, 13)
8242 inner = packet[IPerror]
8243 self.assertEqual(inner.src, self.pg1.remote_ip4)
8244 self.assertEqual(inner.dst, self.nat_addr)
8245 self.assert_packet_checksums_valid(packet)
8246 if inner.haslayer(TCPerror):
8247 self.assertEqual(inner[TCPerror].dport, self.tcp_port_out)
8248 elif inner.haslayer(UDPerror):
8249 self.assertEqual(inner[UDPerror].dport, self.udp_port_out)
8251 self.assertEqual(inner[ICMPerror].id, self.icmp_id_out)
8253 self.logger.error(ppp("Unexpected or invalid packet:", packet))
8257 pkts = [Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
8258 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
8259 ICMP(type=3, code=13) /
8260 packet[IP] for packet in capture_ip4]
8261 self.pg1.add_stream(pkts)
8262 self.pg_enable_capture(self.pg_interfaces)
8264 capture = self.pg0.get_capture(len(pkts))
8265 for packet in capture:
8267 self.assertEqual(packet[IPv6].src, ip.src)
8268 self.assertEqual(packet[IPv6].dst, self.pg0.remote_ip6)
8269 icmp = packet[ICMPv6DestUnreach]
8270 self.assertEqual(icmp.code, 1)
8271 inner = icmp[IPerror6]
8272 self.assertEqual(inner.src, self.pg0.remote_ip6)
8273 self.assertEqual(inner.dst, ip.src)
8274 self.assert_icmpv6_checksum_valid(packet)
8275 if inner.haslayer(TCPerror):
8276 self.assertEqual(inner[TCPerror].sport, self.tcp_port_in)
8277 elif inner.haslayer(UDPerror):
8278 self.assertEqual(inner[UDPerror].sport, self.udp_port_in)
8280 self.assertEqual(inner[ICMPv6EchoRequest].id,
8283 self.logger.error(ppp("Unexpected or invalid packet:", packet))
8286 def test_hairpinning(self):
8287 """ NAT64 hairpinning """
8289 client = self.pg0.remote_hosts[0]
8290 server = self.pg0.remote_hosts[1]
8291 server_tcp_in_port = 22
8292 server_tcp_out_port = 4022
8293 server_udp_in_port = 23
8294 server_udp_out_port = 4023
8295 client_tcp_in_port = 1234
8296 client_udp_in_port = 1235
8297 client_tcp_out_port = 0
8298 client_udp_out_port = 0
8299 ip = IPv6(src=''.join(['64:ff9b::', self.nat_addr]))
8300 nat_addr_ip6 = ip.src
8302 self.vapi.nat64_add_del_pool_addr_range(start_addr=self.nat_addr,
8303 end_addr=self.nat_addr,
8306 flags = self.config_flags.NAT_IS_INSIDE
8307 self.vapi.nat64_add_del_interface(is_add=1, flags=flags,
8308 sw_if_index=self.pg0.sw_if_index)
8309 self.vapi.nat64_add_del_interface(is_add=1, flags=0,
8310 sw_if_index=self.pg1.sw_if_index)
8312 self.vapi.nat64_add_del_static_bib(i_addr=server.ip6n,
8313 o_addr=self.nat_addr,
8314 i_port=server_tcp_in_port,
8315 o_port=server_tcp_out_port,
8316 proto=IP_PROTOS.tcp, vrf_id=0,
8318 self.vapi.nat64_add_del_static_bib(i_addr=server.ip6n,
8319 o_addr=self.nat_addr,
8320 i_port=server_udp_in_port,
8321 o_port=server_udp_out_port,
8322 proto=IP_PROTOS.udp, vrf_id=0,
8327 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
8328 IPv6(src=client.ip6, dst=nat_addr_ip6) /
8329 TCP(sport=client_tcp_in_port, dport=server_tcp_out_port))
8331 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
8332 IPv6(src=client.ip6, dst=nat_addr_ip6) /
8333 UDP(sport=client_udp_in_port, dport=server_udp_out_port))
8335 self.pg0.add_stream(pkts)
8336 self.pg_enable_capture(self.pg_interfaces)
8338 capture = self.pg0.get_capture(len(pkts))
8339 for packet in capture:
8341 self.assertEqual(packet[IPv6].src, nat_addr_ip6)
8342 self.assertEqual(packet[IPv6].dst, server.ip6)
8343 self.assert_packet_checksums_valid(packet)
8344 if packet.haslayer(TCP):
8345 self.assertNotEqual(packet[TCP].sport, client_tcp_in_port)
8346 self.assertEqual(packet[TCP].dport, server_tcp_in_port)
8347 client_tcp_out_port = packet[TCP].sport
8349 self.assertNotEqual(packet[UDP].sport, client_udp_in_port)
8350 self.assertEqual(packet[UDP].dport, server_udp_in_port)
8351 client_udp_out_port = packet[UDP].sport
8353 self.logger.error(ppp("Unexpected or invalid packet:", packet))
8358 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
8359 IPv6(src=server.ip6, dst=nat_addr_ip6) /
8360 TCP(sport=server_tcp_in_port, dport=client_tcp_out_port))
8362 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
8363 IPv6(src=server.ip6, dst=nat_addr_ip6) /
8364 UDP(sport=server_udp_in_port, dport=client_udp_out_port))
8366 self.pg0.add_stream(pkts)
8367 self.pg_enable_capture(self.pg_interfaces)
8369 capture = self.pg0.get_capture(len(pkts))
8370 for packet in capture:
8372 self.assertEqual(packet[IPv6].src, nat_addr_ip6)
8373 self.assertEqual(packet[IPv6].dst, client.ip6)
8374 self.assert_packet_checksums_valid(packet)
8375 if packet.haslayer(TCP):
8376 self.assertEqual(packet[TCP].sport, server_tcp_out_port)
8377 self.assertEqual(packet[TCP].dport, client_tcp_in_port)
8379 self.assertEqual(packet[UDP].sport, server_udp_out_port)
8380 self.assertEqual(packet[UDP].dport, client_udp_in_port)
8382 self.logger.error(ppp("Unexpected or invalid packet:", packet))
8387 pkts = [Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
8388 IPv6(src=client.ip6, dst=nat_addr_ip6) /
8389 ICMPv6DestUnreach(code=1) /
8390 packet[IPv6] for packet in capture]
8391 self.pg0.add_stream(pkts)
8392 self.pg_enable_capture(self.pg_interfaces)
8394 capture = self.pg0.get_capture(len(pkts))
8395 for packet in capture:
8397 self.assertEqual(packet[IPv6].src, nat_addr_ip6)
8398 self.assertEqual(packet[IPv6].dst, server.ip6)
8399 icmp = packet[ICMPv6DestUnreach]
8400 self.assertEqual(icmp.code, 1)
8401 inner = icmp[IPerror6]
8402 self.assertEqual(inner.src, server.ip6)
8403 self.assertEqual(inner.dst, nat_addr_ip6)
8404 self.assert_packet_checksums_valid(packet)
8405 if inner.haslayer(TCPerror):
8406 self.assertEqual(inner[TCPerror].sport, server_tcp_in_port)
8407 self.assertEqual(inner[TCPerror].dport,
8408 client_tcp_out_port)
8410 self.assertEqual(inner[UDPerror].sport, server_udp_in_port)
8411 self.assertEqual(inner[UDPerror].dport,
8412 client_udp_out_port)
8414 self.logger.error(ppp("Unexpected or invalid packet:", packet))
8417 def test_prefix(self):
8418 """ NAT64 Network-Specific Prefix """
8420 self.vapi.nat64_add_del_pool_addr_range(start_addr=self.nat_addr,
8421 end_addr=self.nat_addr,
8424 flags = self.config_flags.NAT_IS_INSIDE
8425 self.vapi.nat64_add_del_interface(is_add=1, flags=flags,
8426 sw_if_index=self.pg0.sw_if_index)
8427 self.vapi.nat64_add_del_interface(is_add=1, flags=0,
8428 sw_if_index=self.pg1.sw_if_index)
8429 self.vapi.nat64_add_del_pool_addr_range(start_addr=self.vrf1_nat_addr,
8430 end_addr=self.vrf1_nat_addr,
8431 vrf_id=self.vrf1_id, is_add=1)
8432 self.vapi.nat64_add_del_interface(is_add=1, flags=flags,
8433 sw_if_index=self.pg2.sw_if_index)
8436 global_pref64 = "2001:db8::"
8437 global_pref64_len = 32
8438 global_pref64_str = "{}/{}".format(global_pref64, global_pref64_len)
8439 self.vapi.nat64_add_del_prefix(prefix=global_pref64_str, vrf_id=0,
8442 prefix = self.vapi.nat64_prefix_dump()
8443 self.assertEqual(len(prefix), 1)
8444 self.assertEqual(prefix[0].prefix,
8445 IPv6Network(unicode(global_pref64_str)))
8446 self.assertEqual(prefix[0].vrf_id, 0)
8448 # Add tenant specific prefix
8449 vrf1_pref64 = "2001:db8:122:300::"
8450 vrf1_pref64_len = 56
8451 vrf1_pref64_str = "{}/{}".format(vrf1_pref64, vrf1_pref64_len)
8452 self.vapi.nat64_add_del_prefix(prefix=vrf1_pref64_str,
8453 vrf_id=self.vrf1_id, is_add=1)
8455 prefix = self.vapi.nat64_prefix_dump()
8456 self.assertEqual(len(prefix), 2)
8459 pkts = self.create_stream_in_ip6(self.pg0,
8462 plen=global_pref64_len)
8463 self.pg0.add_stream(pkts)
8464 self.pg_enable_capture(self.pg_interfaces)
8466 capture = self.pg1.get_capture(len(pkts))
8467 self.verify_capture_out(capture, nat_ip=self.nat_addr,
8468 dst_ip=self.pg1.remote_ip4)
8470 pkts = self.create_stream_out(self.pg1, dst_ip=self.nat_addr)
8471 self.pg1.add_stream(pkts)
8472 self.pg_enable_capture(self.pg_interfaces)
8474 capture = self.pg0.get_capture(len(pkts))
8475 dst_ip = self.compose_ip6(self.pg1.remote_ip4,
8478 self.verify_capture_in_ip6(capture, dst_ip, self.pg0.remote_ip6)
8480 # Tenant specific prefix
8481 pkts = self.create_stream_in_ip6(self.pg2,
8484 plen=vrf1_pref64_len)
8485 self.pg2.add_stream(pkts)
8486 self.pg_enable_capture(self.pg_interfaces)
8488 capture = self.pg1.get_capture(len(pkts))
8489 self.verify_capture_out(capture, nat_ip=self.vrf1_nat_addr,
8490 dst_ip=self.pg1.remote_ip4)
8492 pkts = self.create_stream_out(self.pg1, dst_ip=self.vrf1_nat_addr)
8493 self.pg1.add_stream(pkts)
8494 self.pg_enable_capture(self.pg_interfaces)
8496 capture = self.pg2.get_capture(len(pkts))
8497 dst_ip = self.compose_ip6(self.pg1.remote_ip4,
8500 self.verify_capture_in_ip6(capture, dst_ip, self.pg2.remote_ip6)
8502 def test_unknown_proto(self):
8503 """ NAT64 translate packet with unknown protocol """
8505 self.vapi.nat64_add_del_pool_addr_range(start_addr=self.nat_addr,
8506 end_addr=self.nat_addr,
8509 flags = self.config_flags.NAT_IS_INSIDE
8510 self.vapi.nat64_add_del_interface(is_add=1, flags=flags,
8511 sw_if_index=self.pg0.sw_if_index)
8512 self.vapi.nat64_add_del_interface(is_add=1, flags=0,
8513 sw_if_index=self.pg1.sw_if_index)
8514 remote_ip6 = self.compose_ip6(self.pg1.remote_ip4, '64:ff9b::', 96)
8517 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
8518 IPv6(src=self.pg0.remote_ip6, dst=remote_ip6) /
8519 TCP(sport=self.tcp_port_in, dport=20))
8520 self.pg0.add_stream(p)
8521 self.pg_enable_capture(self.pg_interfaces)
8523 p = self.pg1.get_capture(1)
8525 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
8526 IPv6(src=self.pg0.remote_ip6, dst=remote_ip6, nh=47) /
8528 IP(src=self.pg2.local_ip4, dst=self.pg2.remote_ip4) /
8529 TCP(sport=1234, dport=1234))
8530 self.pg0.add_stream(p)
8531 self.pg_enable_capture(self.pg_interfaces)
8533 p = self.pg1.get_capture(1)
8536 self.assertEqual(packet[IP].src, self.nat_addr)
8537 self.assertEqual(packet[IP].dst, self.pg1.remote_ip4)
8538 self.assertEqual(packet.haslayer(GRE), 1)
8539 self.assert_packet_checksums_valid(packet)
8541 self.logger.error(ppp("Unexpected or invalid packet:", packet))
8545 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
8546 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
8548 IP(src=self.pg2.remote_ip4, dst=self.pg2.local_ip4) /
8549 TCP(sport=1234, dport=1234))
8550 self.pg1.add_stream(p)
8551 self.pg_enable_capture(self.pg_interfaces)
8553 p = self.pg0.get_capture(1)
8556 self.assertEqual(packet[IPv6].src, remote_ip6)
8557 self.assertEqual(packet[IPv6].dst, self.pg0.remote_ip6)
8558 self.assertEqual(packet[IPv6].nh, 47)
8560 self.logger.error(ppp("Unexpected or invalid packet:", packet))
8563 def test_hairpinning_unknown_proto(self):
8564 """ NAT64 translate packet with unknown protocol - hairpinning """
8566 client = self.pg0.remote_hosts[0]
8567 server = self.pg0.remote_hosts[1]
8568 server_tcp_in_port = 22
8569 server_tcp_out_port = 4022
8570 client_tcp_in_port = 1234
8571 client_tcp_out_port = 1235
8572 server_nat_ip = "10.0.0.100"
8573 client_nat_ip = "10.0.0.110"
8574 server_nat_ip6 = self.compose_ip6(server_nat_ip, '64:ff9b::', 96)
8575 client_nat_ip6 = self.compose_ip6(client_nat_ip, '64:ff9b::', 96)
8577 self.vapi.nat64_add_del_pool_addr_range(start_addr=server_nat_ip,
8578 end_addr=client_nat_ip,
8581 flags = self.config_flags.NAT_IS_INSIDE
8582 self.vapi.nat64_add_del_interface(is_add=1, flags=flags,
8583 sw_if_index=self.pg0.sw_if_index)
8584 self.vapi.nat64_add_del_interface(is_add=1, flags=0,
8585 sw_if_index=self.pg1.sw_if_index)
8587 self.vapi.nat64_add_del_static_bib(i_addr=server.ip6n,
8588 o_addr=server_nat_ip,
8589 i_port=server_tcp_in_port,
8590 o_port=server_tcp_out_port,
8591 proto=IP_PROTOS.tcp, vrf_id=0,
8594 self.vapi.nat64_add_del_static_bib(i_addr=server.ip6n,
8595 o_addr=server_nat_ip, i_port=0,
8597 proto=IP_PROTOS.gre, vrf_id=0,
8600 self.vapi.nat64_add_del_static_bib(i_addr=client.ip6n,
8601 o_addr=client_nat_ip,
8602 i_port=client_tcp_in_port,
8603 o_port=client_tcp_out_port,
8604 proto=IP_PROTOS.tcp, vrf_id=0,
8608 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
8609 IPv6(src=client.ip6, dst=server_nat_ip6) /
8610 TCP(sport=client_tcp_in_port, dport=server_tcp_out_port))
8611 self.pg0.add_stream(p)
8612 self.pg_enable_capture(self.pg_interfaces)
8614 p = self.pg0.get_capture(1)
8616 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
8617 IPv6(src=client.ip6, dst=server_nat_ip6, nh=IP_PROTOS.gre) /
8619 IP(src=self.pg2.local_ip4, dst=self.pg2.remote_ip4) /
8620 TCP(sport=1234, dport=1234))
8621 self.pg0.add_stream(p)
8622 self.pg_enable_capture(self.pg_interfaces)
8624 p = self.pg0.get_capture(1)
8627 self.assertEqual(packet[IPv6].src, client_nat_ip6)
8628 self.assertEqual(packet[IPv6].dst, server.ip6)
8629 self.assertEqual(packet[IPv6].nh, IP_PROTOS.gre)
8631 self.logger.error(ppp("Unexpected or invalid packet:", packet))
8635 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
8636 IPv6(src=server.ip6, dst=client_nat_ip6, nh=IP_PROTOS.gre) /
8638 IP(src=self.pg2.remote_ip4, dst=self.pg2.local_ip4) /
8639 TCP(sport=1234, dport=1234))
8640 self.pg0.add_stream(p)
8641 self.pg_enable_capture(self.pg_interfaces)
8643 p = self.pg0.get_capture(1)
8646 self.assertEqual(packet[IPv6].src, server_nat_ip6)
8647 self.assertEqual(packet[IPv6].dst, client.ip6)
8648 self.assertEqual(packet[IPv6].nh, IP_PROTOS.gre)
8650 self.logger.error(ppp("Unexpected or invalid packet:", packet))
8653 def test_one_armed_nat64(self):
8654 """ One armed NAT64 """
8656 remote_host_ip6 = self.compose_ip6(self.pg3.remote_ip4,
8660 self.vapi.nat64_add_del_pool_addr_range(start_addr=self.nat_addr,
8661 end_addr=self.nat_addr,
8664 flags = self.config_flags.NAT_IS_INSIDE
8665 self.vapi.nat64_add_del_interface(is_add=1, flags=flags,
8666 sw_if_index=self.pg3.sw_if_index)
8667 self.vapi.nat64_add_del_interface(is_add=1, flags=0,
8668 sw_if_index=self.pg3.sw_if_index)
8671 p = (Ether(src=self.pg3.remote_mac, dst=self.pg3.local_mac) /
8672 IPv6(src=self.pg3.remote_ip6, dst=remote_host_ip6) /
8673 TCP(sport=12345, dport=80))
8674 self.pg3.add_stream(p)
8675 self.pg_enable_capture(self.pg_interfaces)
8677 capture = self.pg3.get_capture(1)
8682 self.assertEqual(ip.src, self.nat_addr)
8683 self.assertEqual(ip.dst, self.pg3.remote_ip4)
8684 self.assertNotEqual(tcp.sport, 12345)
8685 external_port = tcp.sport
8686 self.assertEqual(tcp.dport, 80)
8687 self.assert_packet_checksums_valid(p)
8689 self.logger.error(ppp("Unexpected or invalid packet:", p))
8693 p = (Ether(src=self.pg3.remote_mac, dst=self.pg3.local_mac) /
8694 IP(src=self.pg3.remote_ip4, dst=self.nat_addr) /
8695 TCP(sport=80, dport=external_port))
8696 self.pg3.add_stream(p)
8697 self.pg_enable_capture(self.pg_interfaces)
8699 capture = self.pg3.get_capture(1)
8704 self.assertEqual(ip.src, remote_host_ip6)
8705 self.assertEqual(ip.dst, self.pg3.remote_ip6)
8706 self.assertEqual(tcp.sport, 80)
8707 self.assertEqual(tcp.dport, 12345)
8708 self.assert_packet_checksums_valid(p)
8710 self.logger.error(ppp("Unexpected or invalid packet:", p))
8713 def test_frag_in_order(self):
8714 """ NAT64 translate fragments arriving in order """
8715 self.tcp_port_in = random.randint(1025, 65535)
8717 self.vapi.nat64_add_del_pool_addr_range(start_addr=self.nat_addr,
8718 end_addr=self.nat_addr,
8721 flags = self.config_flags.NAT_IS_INSIDE
8722 self.vapi.nat64_add_del_interface(is_add=1, flags=flags,
8723 sw_if_index=self.pg0.sw_if_index)
8724 self.vapi.nat64_add_del_interface(is_add=1, flags=0,
8725 sw_if_index=self.pg1.sw_if_index)
8727 reass = self.vapi.nat_reass_dump()
8728 reass_n_start = len(reass)
8732 pkts = self.create_stream_frag_ip6(self.pg0, self.pg1.remote_ip4,
8733 self.tcp_port_in, 20, data)
8734 self.pg0.add_stream(pkts)
8735 self.pg_enable_capture(self.pg_interfaces)
8737 frags = self.pg1.get_capture(len(pkts))
8738 p = self.reass_frags_and_verify(frags,
8740 self.pg1.remote_ip4)
8741 self.assertEqual(p[TCP].dport, 20)
8742 self.assertNotEqual(p[TCP].sport, self.tcp_port_in)
8743 self.tcp_port_out = p[TCP].sport
8744 self.assertEqual(data, p[Raw].load)
8747 data = b"A" * 4 + b"b" * 16 + b"C" * 3
8748 pkts = self.create_stream_frag(self.pg1,
8753 self.pg1.add_stream(pkts)
8754 self.pg_enable_capture(self.pg_interfaces)
8756 frags = self.pg0.get_capture(len(pkts))
8757 src = self.compose_ip6(self.pg1.remote_ip4, '64:ff9b::', 96)
8758 p = self.reass_frags_and_verify_ip6(frags, src, self.pg0.remote_ip6)
8759 self.assertEqual(p[TCP].sport, 20)
8760 self.assertEqual(p[TCP].dport, self.tcp_port_in)
8761 self.assertEqual(data, p[Raw].load)
8763 reass = self.vapi.nat_reass_dump()
8764 reass_n_end = len(reass)
8766 self.assertEqual(reass_n_end - reass_n_start, 2)
8768 def test_reass_hairpinning(self):
8769 """ NAT64 fragments hairpinning """
8771 server = self.pg0.remote_hosts[1]
8772 server_in_port = random.randint(1025, 65535)
8773 server_out_port = random.randint(1025, 65535)
8774 client_in_port = random.randint(1025, 65535)
8775 ip = IPv6(src=''.join(['64:ff9b::', self.nat_addr]))
8776 nat_addr_ip6 = ip.src
8778 self.vapi.nat64_add_del_pool_addr_range(start_addr=self.nat_addr,
8779 end_addr=self.nat_addr,
8782 flags = self.config_flags.NAT_IS_INSIDE
8783 self.vapi.nat64_add_del_interface(is_add=1, flags=flags,
8784 sw_if_index=self.pg0.sw_if_index)
8785 self.vapi.nat64_add_del_interface(is_add=1, flags=0,
8786 sw_if_index=self.pg1.sw_if_index)
8788 # add static BIB entry for server
8789 self.vapi.nat64_add_del_static_bib(i_addr=server.ip6n,
8790 o_addr=self.nat_addr,
8791 i_port=server_in_port,
8792 o_port=server_out_port,
8793 proto=IP_PROTOS.tcp, vrf_id=0,
8796 # send packet from host to server
8797 pkts = self.create_stream_frag_ip6(self.pg0,
8802 self.pg0.add_stream(pkts)
8803 self.pg_enable_capture(self.pg_interfaces)
8805 frags = self.pg0.get_capture(len(pkts))
8806 p = self.reass_frags_and_verify_ip6(frags, nat_addr_ip6, server.ip6)
8807 self.assertNotEqual(p[TCP].sport, client_in_port)
8808 self.assertEqual(p[TCP].dport, server_in_port)
8809 self.assertEqual(data, p[Raw].load)
8811 def test_frag_out_of_order(self):
8812 """ NAT64 translate fragments arriving out of order """
8813 self.tcp_port_in = random.randint(1025, 65535)
8815 self.vapi.nat64_add_del_pool_addr_range(start_addr=self.nat_addr,
8816 end_addr=self.nat_addr,
8819 flags = self.config_flags.NAT_IS_INSIDE
8820 self.vapi.nat64_add_del_interface(is_add=1, flags=flags,
8821 sw_if_index=self.pg0.sw_if_index)
8822 self.vapi.nat64_add_del_interface(is_add=1, flags=0,
8823 sw_if_index=self.pg1.sw_if_index)
8827 pkts = self.create_stream_frag_ip6(self.pg0, self.pg1.remote_ip4,
8828 self.tcp_port_in, 20, data)
8830 self.pg0.add_stream(pkts)
8831 self.pg_enable_capture(self.pg_interfaces)
8833 frags = self.pg1.get_capture(len(pkts))
8834 p = self.reass_frags_and_verify(frags,
8836 self.pg1.remote_ip4)
8837 self.assertEqual(p[TCP].dport, 20)
8838 self.assertNotEqual(p[TCP].sport, self.tcp_port_in)
8839 self.tcp_port_out = p[TCP].sport
8840 self.assertEqual(data, p[Raw].load)
8843 data = b"A" * 4 + b"B" * 16 + b"C" * 3
8844 pkts = self.create_stream_frag(self.pg1,
8850 self.pg1.add_stream(pkts)
8851 self.pg_enable_capture(self.pg_interfaces)
8853 frags = self.pg0.get_capture(len(pkts))
8854 src = self.compose_ip6(self.pg1.remote_ip4, '64:ff9b::', 96)
8855 p = self.reass_frags_and_verify_ip6(frags, src, self.pg0.remote_ip6)
8856 self.assertEqual(p[TCP].sport, 20)
8857 self.assertEqual(p[TCP].dport, self.tcp_port_in)
8858 self.assertEqual(data, p[Raw].load)
8860 def test_interface_addr(self):
8861 """ Acquire NAT64 pool addresses from interface """
8862 self.vapi.nat64_add_del_interface_addr(
8864 sw_if_index=self.pg4.sw_if_index)
8866 # no address in NAT64 pool
8867 addresses = self.vapi.nat44_address_dump()
8868 self.assertEqual(0, len(addresses))
8870 # configure interface address and check NAT64 address pool
8871 self.pg4.config_ip4()
8872 addresses = self.vapi.nat64_pool_addr_dump()
8873 self.assertEqual(len(addresses), 1)
8875 self.assertEqual(str(addresses[0].address),
8878 # remove interface address and check NAT64 address pool
8879 self.pg4.unconfig_ip4()
8880 addresses = self.vapi.nat64_pool_addr_dump()
8881 self.assertEqual(0, len(addresses))
8883 @unittest.skipUnless(running_extended_tests, "part of extended tests")
8884 def test_ipfix_max_bibs_sessions(self):
8885 """ IPFIX logging maximum session and BIB entries exceeded """
8888 remote_host_ip6 = self.compose_ip6(self.pg1.remote_ip4,
8892 self.vapi.nat64_add_del_pool_addr_range(start_addr=self.nat_addr,
8893 end_addr=self.nat_addr,
8896 flags = self.config_flags.NAT_IS_INSIDE
8897 self.vapi.nat64_add_del_interface(is_add=1, flags=flags,
8898 sw_if_index=self.pg0.sw_if_index)
8899 self.vapi.nat64_add_del_interface(is_add=1, flags=0,
8900 sw_if_index=self.pg1.sw_if_index)
8904 for i in range(0, max_bibs):
8905 src = "fd01:aa::%x" % (i)
8906 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
8907 IPv6(src=src, dst=remote_host_ip6) /
8908 TCP(sport=12345, dport=80))
8910 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
8911 IPv6(src=src, dst=remote_host_ip6) /
8912 TCP(sport=12345, dport=22))
8914 self.pg0.add_stream(pkts)
8915 self.pg_enable_capture(self.pg_interfaces)
8917 self.pg1.get_capture(max_sessions)
8919 self.vapi.set_ipfix_exporter(collector_address=self.pg3.remote_ip4n,
8920 src_address=self.pg3.local_ip4n,
8922 template_interval=10)
8923 self.vapi.nat_ipfix_enable_disable(domain_id=self.ipfix_domain_id,
8924 src_port=self.ipfix_src_port,
8927 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
8928 IPv6(src=src, dst=remote_host_ip6) /
8929 TCP(sport=12345, dport=25))
8930 self.pg0.add_stream(p)
8931 self.pg_enable_capture(self.pg_interfaces)
8933 self.pg1.assert_nothing_captured()
8935 self.vapi.ipfix_flush()
8936 capture = self.pg3.get_capture(9)
8937 ipfix = IPFIXDecoder()
8938 # first load template
8940 self.assertTrue(p.haslayer(IPFIX))
8941 self.assertEqual(p[IP].src, self.pg3.local_ip4)
8942 self.assertEqual(p[IP].dst, self.pg3.remote_ip4)
8943 self.assertEqual(p[UDP].sport, self.ipfix_src_port)
8944 self.assertEqual(p[UDP].dport, 4739)
8945 self.assertEqual(p[IPFIX].observationDomainID,
8946 self.ipfix_domain_id)
8947 if p.haslayer(Template):
8948 ipfix.add_template(p.getlayer(Template))
8949 # verify events in data set
8951 if p.haslayer(Data):
8952 data = ipfix.decode_data_set(p.getlayer(Set))
8953 self.verify_ipfix_max_sessions(data, max_sessions)
8955 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
8956 IPv6(src=self.pg0.remote_ip6, dst=remote_host_ip6) /
8957 TCP(sport=12345, dport=80))
8958 self.pg0.add_stream(p)
8959 self.pg_enable_capture(self.pg_interfaces)
8961 self.pg1.assert_nothing_captured()
8963 self.vapi.ipfix_flush()
8964 capture = self.pg3.get_capture(1)
8965 # verify events in data set
8967 self.assertTrue(p.haslayer(IPFIX))
8968 self.assertEqual(p[IP].src, self.pg3.local_ip4)
8969 self.assertEqual(p[IP].dst, self.pg3.remote_ip4)
8970 self.assertEqual(p[UDP].sport, self.ipfix_src_port)
8971 self.assertEqual(p[UDP].dport, 4739)
8972 self.assertEqual(p[IPFIX].observationDomainID,
8973 self.ipfix_domain_id)
8974 if p.haslayer(Data):
8975 data = ipfix.decode_data_set(p.getlayer(Set))
8976 self.verify_ipfix_max_bibs(data, max_bibs)
8978 def test_ipfix_max_frags(self):
8979 """ IPFIX logging maximum fragments pending reassembly exceeded """
8980 self.vapi.nat64_add_del_pool_addr_range(start_addr=self.nat_addr,
8981 end_addr=self.nat_addr,
8984 flags = self.config_flags.NAT_IS_INSIDE
8985 self.vapi.nat64_add_del_interface(is_add=1, flags=flags,
8986 sw_if_index=self.pg0.sw_if_index)
8987 self.vapi.nat64_add_del_interface(is_add=1, flags=0,
8988 sw_if_index=self.pg1.sw_if_index)
8989 self.vapi.nat_set_reass(timeout=2, max_reass=1024, max_frag=1,
8990 drop_frag=0, is_ip6=1)
8991 self.vapi.set_ipfix_exporter(collector_address=self.pg3.remote_ip4n,
8992 src_address=self.pg3.local_ip4n,
8994 template_interval=10)
8995 self.vapi.nat_ipfix_enable_disable(domain_id=self.ipfix_domain_id,
8996 src_port=self.ipfix_src_port,
9000 pkts = self.create_stream_frag_ip6(self.pg0, self.pg1.remote_ip4,
9001 self.tcp_port_in, 20, data)
9003 self.pg0.add_stream(pkts)
9004 self.pg_enable_capture(self.pg_interfaces)
9006 self.pg1.assert_nothing_captured()
9008 self.vapi.ipfix_flush()
9009 capture = self.pg3.get_capture(9)
9010 ipfix = IPFIXDecoder()
9011 # first load template
9013 self.assertTrue(p.haslayer(IPFIX))
9014 self.assertEqual(p[IP].src, self.pg3.local_ip4)
9015 self.assertEqual(p[IP].dst, self.pg3.remote_ip4)
9016 self.assertEqual(p[UDP].sport, self.ipfix_src_port)
9017 self.assertEqual(p[UDP].dport, 4739)
9018 self.assertEqual(p[IPFIX].observationDomainID,
9019 self.ipfix_domain_id)
9020 if p.haslayer(Template):
9021 ipfix.add_template(p.getlayer(Template))
9022 # verify events in data set
9024 if p.haslayer(Data):
9025 data = ipfix.decode_data_set(p.getlayer(Set))
9026 self.verify_ipfix_max_fragments_ip6(data, 1,
9027 self.pg0.remote_ip6n)
9029 def test_ipfix_bib_ses(self):
9030 """ IPFIX logging NAT64 BIB/session create and delete events """
9031 self.tcp_port_in = random.randint(1025, 65535)
9032 remote_host_ip6 = self.compose_ip6(self.pg1.remote_ip4,
9036 self.vapi.nat64_add_del_pool_addr_range(start_addr=self.nat_addr,
9037 end_addr=self.nat_addr,
9040 flags = self.config_flags.NAT_IS_INSIDE
9041 self.vapi.nat64_add_del_interface(is_add=1, flags=flags,
9042 sw_if_index=self.pg0.sw_if_index)
9043 self.vapi.nat64_add_del_interface(is_add=1, flags=0,
9044 sw_if_index=self.pg1.sw_if_index)
9045 self.vapi.set_ipfix_exporter(collector_address=self.pg3.remote_ip4n,
9046 src_address=self.pg3.local_ip4n,
9048 template_interval=10)
9049 self.vapi.nat_ipfix_enable_disable(domain_id=self.ipfix_domain_id,
9050 src_port=self.ipfix_src_port,
9054 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
9055 IPv6(src=self.pg0.remote_ip6, dst=remote_host_ip6) /
9056 TCP(sport=self.tcp_port_in, dport=25))
9057 self.pg0.add_stream(p)
9058 self.pg_enable_capture(self.pg_interfaces)
9060 p = self.pg1.get_capture(1)
9061 self.tcp_port_out = p[0][TCP].sport
9062 self.vapi.ipfix_flush()
9063 capture = self.pg3.get_capture(10)
9064 ipfix = IPFIXDecoder()
9065 # first load template
9067 self.assertTrue(p.haslayer(IPFIX))
9068 self.assertEqual(p[IP].src, self.pg3.local_ip4)
9069 self.assertEqual(p[IP].dst, self.pg3.remote_ip4)
9070 self.assertEqual(p[UDP].sport, self.ipfix_src_port)
9071 self.assertEqual(p[UDP].dport, 4739)
9072 self.assertEqual(p[IPFIX].observationDomainID,
9073 self.ipfix_domain_id)
9074 if p.haslayer(Template):
9075 ipfix.add_template(p.getlayer(Template))
9076 # verify events in data set
9078 if p.haslayer(Data):
9079 data = ipfix.decode_data_set(p.getlayer(Set))
9080 if scapy.compat.orb(data[0][230]) == 10:
9081 self.verify_ipfix_bib(data, 1, self.pg0.remote_ip6n)
9082 elif scapy.compat.orb(data[0][230]) == 6:
9083 self.verify_ipfix_nat64_ses(data,
9085 self.pg0.remote_ip6n,
9086 self.pg1.remote_ip4,
9089 self.logger.error(ppp("Unexpected or invalid packet: ", p))
9092 self.pg_enable_capture(self.pg_interfaces)
9093 self.vapi.nat64_add_del_pool_addr_range(start_addr=self.nat_addr,
9094 end_addr=self.nat_addr,
9097 self.vapi.ipfix_flush()
9098 capture = self.pg3.get_capture(2)
9099 # verify events in data set
9101 self.assertTrue(p.haslayer(IPFIX))
9102 self.assertEqual(p[IP].src, self.pg3.local_ip4)
9103 self.assertEqual(p[IP].dst, self.pg3.remote_ip4)
9104 self.assertEqual(p[UDP].sport, self.ipfix_src_port)
9105 self.assertEqual(p[UDP].dport, 4739)
9106 self.assertEqual(p[IPFIX].observationDomainID,
9107 self.ipfix_domain_id)
9108 if p.haslayer(Data):
9109 data = ipfix.decode_data_set(p.getlayer(Set))
9110 if scapy.compat.orb(data[0][230]) == 11:
9111 self.verify_ipfix_bib(data, 0, self.pg0.remote_ip6n)
9112 elif scapy.compat.orb(data[0][230]) == 7:
9113 self.verify_ipfix_nat64_ses(data,
9115 self.pg0.remote_ip6n,
9116 self.pg1.remote_ip4,
9119 self.logger.error(ppp("Unexpected or invalid packet: ", p))
9121 def test_syslog_sess(self):
9122 """ Test syslog session creation and deletion """
9123 self.tcp_port_in = random.randint(1025, 65535)
9124 remote_host_ip6 = self.compose_ip6(self.pg1.remote_ip4,
9128 self.vapi.nat64_add_del_pool_addr_range(start_addr=self.nat_addr,
9129 end_addr=self.nat_addr,
9132 flags = self.config_flags.NAT_IS_INSIDE
9133 self.vapi.nat64_add_del_interface(is_add=1, flags=flags,
9134 sw_if_index=self.pg0.sw_if_index)
9135 self.vapi.nat64_add_del_interface(is_add=1, flags=0,
9136 sw_if_index=self.pg1.sw_if_index)
9137 self.vapi.syslog_set_filter(
9138 self.SYSLOG_SEVERITY.SYSLOG_API_SEVERITY_INFO)
9139 self.vapi.syslog_set_sender(self.pg3.local_ip4n, self.pg3.remote_ip4n)
9141 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
9142 IPv6(src=self.pg0.remote_ip6, dst=remote_host_ip6) /
9143 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port))
9144 self.pg0.add_stream(p)
9145 self.pg_enable_capture(self.pg_interfaces)
9147 p = self.pg1.get_capture(1)
9148 self.tcp_port_out = p[0][TCP].sport
9149 capture = self.pg3.get_capture(1)
9150 self.verify_syslog_sess(capture[0][Raw].load, is_ip6=True)
9152 self.pg_enable_capture(self.pg_interfaces)
9154 self.vapi.nat64_add_del_pool_addr_range(start_addr=self.nat_addr,
9155 end_addr=self.nat_addr,
9158 capture = self.pg3.get_capture(1)
9159 self.verify_syslog_sess(capture[0][Raw].load, False, True)
9161 def nat64_get_ses_num(self):
9163 Return number of active NAT64 sessions.
9165 st = self.vapi.nat64_st_dump(proto=255)
9168 def clear_nat64(self):
9170 Clear NAT64 configuration.
9172 self.vapi.nat_ipfix_enable_disable(domain_id=self.ipfix_domain_id,
9173 src_port=self.ipfix_src_port,
9175 self.ipfix_src_port = 4739
9176 self.ipfix_domain_id = 1
9178 self.vapi.syslog_set_filter(
9179 self.SYSLOG_SEVERITY.SYSLOG_API_SEVERITY_EMERG)
9181 self.vapi.nat_set_timeouts(udp=300, tcp_established=7440,
9182 tcp_transitory=240, icmp=60)
9184 interfaces = self.vapi.nat64_interface_dump()
9185 for intf in interfaces:
9186 self.vapi.nat64_add_del_interface(is_add=0, flags=intf.flags,
9187 sw_if_index=intf.sw_if_index)
9189 bib = self.vapi.nat64_bib_dump(proto=255)
9191 if bibe.flags & self.config_flags.NAT_IS_STATIC:
9192 self.vapi.nat64_add_del_static_bib(i_addr=bibe.i_addr,
9200 adresses = self.vapi.nat64_pool_addr_dump()
9201 for addr in adresses:
9202 self.vapi.nat64_add_del_pool_addr_range(start_addr=addr.address,
9203 end_addr=addr.address,
9207 prefixes = self.vapi.nat64_prefix_dump()
9208 for prefix in prefixes:
9209 self.vapi.nat64_add_del_prefix(prefix=str(prefix.prefix),
9210 vrf_id=prefix.vrf_id, is_add=0)
9212 bibs = self.statistics.get_counter('/nat64/total-bibs')
9213 self.assertEqual(bibs[0][0], 0)
9214 sessions = self.statistics.get_counter('/nat64/total-sessions')
9215 self.assertEqual(sessions[0][0], 0)
9218 super(TestNAT64, self).tearDown()
9219 if not self.vpp_dead:
9222 def show_commands_at_teardown(self):
9223 self.logger.info(self.vapi.cli("show nat64 pool"))
9224 self.logger.info(self.vapi.cli("show nat64 interfaces"))
9225 self.logger.info(self.vapi.cli("show nat64 prefix"))
9226 self.logger.info(self.vapi.cli("show nat64 bib all"))
9227 self.logger.info(self.vapi.cli("show nat64 session table all"))
9228 self.logger.info(self.vapi.cli("show nat virtual-reassembly"))
9231 class TestDSlite(MethodHolder):
9232 """ DS-Lite Test Cases """
9235 def setUpClass(cls):
9236 super(TestDSlite, cls).setUpClass()
9239 cls.nat_addr = '10.0.0.3'
9241 cls.create_pg_interfaces(range(3))
9243 cls.pg0.config_ip4()
9244 cls.pg0.resolve_arp()
9246 cls.pg1.config_ip6()
9247 cls.pg1.generate_remote_hosts(2)
9248 cls.pg1.configure_ipv6_neighbors()
9250 cls.pg2.config_ip4()
9251 cls.pg2.resolve_arp()
9254 super(TestDSlite, cls).tearDownClass()
9258 def tearDownClass(cls):
9259 super(TestDSlite, cls).tearDownClass()
9261 def verify_syslog_apmadd(self, data, isaddr, isport, xsaddr, xsport,
9263 message = data.decode('utf-8')
9265 message = SyslogMessage.parse(message)
9266 except ParseError as e:
9267 self.logger.error(e)
9269 self.assertEqual(message.severity, SyslogSeverity.info)
9270 self.assertEqual(message.appname, 'NAT')
9271 self.assertEqual(message.msgid, 'APMADD')
9272 sd_params = message.sd.get('napmap')
9273 self.assertTrue(sd_params is not None)
9274 self.assertEqual(sd_params.get('IATYP'), 'IPv4')
9275 self.assertEqual(sd_params.get('ISADDR'), isaddr)
9276 self.assertEqual(sd_params.get('ISPORT'), "%d" % isport)
9277 self.assertEqual(sd_params.get('XATYP'), 'IPv4')
9278 self.assertEqual(sd_params.get('XSADDR'), xsaddr)
9279 self.assertEqual(sd_params.get('XSPORT'), "%d" % xsport)
9280 self.assertEqual(sd_params.get('PROTO'), "%d" % proto)
9281 self.assertTrue(sd_params.get('SSUBIX') is not None)
9282 self.assertEqual(sd_params.get('SV6ENC'), sv6enc)
9284 def test_dslite(self):
9285 """ Test DS-Lite """
9286 nat_config = self.vapi.nat_show_config()
9287 self.assertEqual(0, nat_config.dslite_ce)
9289 self.vapi.dslite_add_del_pool_addr_range(start_addr=self.nat_addr,
9290 end_addr=self.nat_addr,
9292 aftr_ip4 = '192.0.0.1'
9293 aftr_ip6 = '2001:db8:85a3::8a2e:370:1'
9294 self.vapi.dslite_set_aftr_addr(ip4_addr=aftr_ip4, ip6_addr=aftr_ip6)
9295 self.vapi.syslog_set_sender(self.pg2.local_ip4n, self.pg2.remote_ip4n)
9298 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
9299 IPv6(dst=aftr_ip6, src=self.pg1.remote_hosts[0].ip6) /
9300 IP(dst=self.pg0.remote_ip4, src='192.168.1.1') /
9301 UDP(sport=20000, dport=10000))
9302 self.pg1.add_stream(p)
9303 self.pg_enable_capture(self.pg_interfaces)
9305 capture = self.pg0.get_capture(1)
9306 capture = capture[0]
9307 self.assertFalse(capture.haslayer(IPv6))
9308 self.assertEqual(capture[IP].src, self.nat_addr)
9309 self.assertEqual(capture[IP].dst, self.pg0.remote_ip4)
9310 self.assertNotEqual(capture[UDP].sport, 20000)
9311 self.assertEqual(capture[UDP].dport, 10000)
9312 self.assert_packet_checksums_valid(capture)
9313 out_port = capture[UDP].sport
9314 capture = self.pg2.get_capture(1)
9315 self.verify_syslog_apmadd(capture[0][Raw].load, '192.168.1.1',
9316 20000, self.nat_addr, out_port,
9317 self.pg1.remote_hosts[0].ip6, IP_PROTOS.udp)
9319 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
9320 IP(dst=self.nat_addr, src=self.pg0.remote_ip4) /
9321 UDP(sport=10000, dport=out_port))
9322 self.pg0.add_stream(p)
9323 self.pg_enable_capture(self.pg_interfaces)
9325 capture = self.pg1.get_capture(1)
9326 capture = capture[0]
9327 self.assertEqual(capture[IPv6].src, aftr_ip6)
9328 self.assertEqual(capture[IPv6].dst, self.pg1.remote_hosts[0].ip6)
9329 self.assertEqual(capture[IP].src, self.pg0.remote_ip4)
9330 self.assertEqual(capture[IP].dst, '192.168.1.1')
9331 self.assertEqual(capture[UDP].sport, 10000)
9332 self.assertEqual(capture[UDP].dport, 20000)
9333 self.assert_packet_checksums_valid(capture)
9336 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
9337 IPv6(dst=aftr_ip6, src=self.pg1.remote_hosts[1].ip6) /
9338 IP(dst=self.pg0.remote_ip4, src='192.168.1.1') /
9339 TCP(sport=20001, dport=10001))
9340 self.pg1.add_stream(p)
9341 self.pg_enable_capture(self.pg_interfaces)
9343 capture = self.pg0.get_capture(1)
9344 capture = capture[0]
9345 self.assertFalse(capture.haslayer(IPv6))
9346 self.assertEqual(capture[IP].src, self.nat_addr)
9347 self.assertEqual(capture[IP].dst, self.pg0.remote_ip4)
9348 self.assertNotEqual(capture[TCP].sport, 20001)
9349 self.assertEqual(capture[TCP].dport, 10001)
9350 self.assert_packet_checksums_valid(capture)
9351 out_port = capture[TCP].sport
9353 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
9354 IP(dst=self.nat_addr, src=self.pg0.remote_ip4) /
9355 TCP(sport=10001, dport=out_port))
9356 self.pg0.add_stream(p)
9357 self.pg_enable_capture(self.pg_interfaces)
9359 capture = self.pg1.get_capture(1)
9360 capture = capture[0]
9361 self.assertEqual(capture[IPv6].src, aftr_ip6)
9362 self.assertEqual(capture[IPv6].dst, self.pg1.remote_hosts[1].ip6)
9363 self.assertEqual(capture[IP].src, self.pg0.remote_ip4)
9364 self.assertEqual(capture[IP].dst, '192.168.1.1')
9365 self.assertEqual(capture[TCP].sport, 10001)
9366 self.assertEqual(capture[TCP].dport, 20001)
9367 self.assert_packet_checksums_valid(capture)
9370 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
9371 IPv6(dst=aftr_ip6, src=self.pg1.remote_hosts[1].ip6) /
9372 IP(dst=self.pg0.remote_ip4, src='192.168.1.1') /
9373 ICMP(id=4000, type='echo-request'))
9374 self.pg1.add_stream(p)
9375 self.pg_enable_capture(self.pg_interfaces)
9377 capture = self.pg0.get_capture(1)
9378 capture = capture[0]
9379 self.assertFalse(capture.haslayer(IPv6))
9380 self.assertEqual(capture[IP].src, self.nat_addr)
9381 self.assertEqual(capture[IP].dst, self.pg0.remote_ip4)
9382 self.assertNotEqual(capture[ICMP].id, 4000)
9383 self.assert_packet_checksums_valid(capture)
9384 out_id = capture[ICMP].id
9386 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
9387 IP(dst=self.nat_addr, src=self.pg0.remote_ip4) /
9388 ICMP(id=out_id, type='echo-reply'))
9389 self.pg0.add_stream(p)
9390 self.pg_enable_capture(self.pg_interfaces)
9392 capture = self.pg1.get_capture(1)
9393 capture = capture[0]
9394 self.assertEqual(capture[IPv6].src, aftr_ip6)
9395 self.assertEqual(capture[IPv6].dst, self.pg1.remote_hosts[1].ip6)
9396 self.assertEqual(capture[IP].src, self.pg0.remote_ip4)
9397 self.assertEqual(capture[IP].dst, '192.168.1.1')
9398 self.assertEqual(capture[ICMP].id, 4000)
9399 self.assert_packet_checksums_valid(capture)
9401 # ping DS-Lite AFTR tunnel endpoint address
9402 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
9403 IPv6(src=self.pg1.remote_hosts[1].ip6, dst=aftr_ip6) /
9404 ICMPv6EchoRequest())
9405 self.pg1.add_stream(p)
9406 self.pg_enable_capture(self.pg_interfaces)
9408 capture = self.pg1.get_capture(1)
9409 capture = capture[0]
9410 self.assertEqual(capture[IPv6].src, aftr_ip6)
9411 self.assertEqual(capture[IPv6].dst, self.pg1.remote_hosts[1].ip6)
9412 self.assertTrue(capture.haslayer(ICMPv6EchoReply))
9414 b4s = self.statistics.get_counter('/dslite/total-b4s')
9415 self.assertEqual(b4s[0][0], 2)
9416 sessions = self.statistics.get_counter('/dslite/total-sessions')
9417 self.assertEqual(sessions[0][0], 3)
9420 super(TestDSlite, self).tearDown()
9422 def show_commands_at_teardown(self):
9423 self.logger.info(self.vapi.cli("show dslite pool"))
9425 self.vapi.cli("show dslite aftr-tunnel-endpoint-address"))
9426 self.logger.info(self.vapi.cli("show dslite sessions"))
9429 class TestDSliteCE(MethodHolder):
9430 """ DS-Lite CE Test Cases """
9433 def setUpConstants(cls):
9434 super(TestDSliteCE, cls).setUpConstants()
9435 cls.vpp_cmdline.extend(["nat", "{", "dslite ce", "}"])
9438 def setUpClass(cls):
9439 super(TestDSliteCE, cls).setUpClass()
9442 cls.create_pg_interfaces(range(2))
9444 cls.pg0.config_ip4()
9445 cls.pg0.resolve_arp()
9447 cls.pg1.config_ip6()
9448 cls.pg1.generate_remote_hosts(1)
9449 cls.pg1.configure_ipv6_neighbors()
9452 super(TestDSliteCE, cls).tearDownClass()
9456 def tearDownClass(cls):
9457 super(TestDSliteCE, cls).tearDownClass()
9459 def test_dslite_ce(self):
9460 """ Test DS-Lite CE """
9462 nat_config = self.vapi.nat_show_config()
9463 self.assertEqual(1, nat_config.dslite_ce)
9465 b4_ip4 = '192.0.0.2'
9466 b4_ip6 = '2001:db8:62aa::375e:f4c1:1'
9467 self.vapi.dslite_set_b4_addr(ip4_addr=b4_ip4, ip6_addr=b4_ip6)
9469 aftr_ip4 = '192.0.0.1'
9470 aftr_ip6 = '2001:db8:85a3::8a2e:370:1'
9471 aftr_ip6_n = socket.inet_pton(socket.AF_INET6, aftr_ip6)
9472 self.vapi.dslite_set_aftr_addr(ip4_addr=aftr_ip4, ip6_addr=aftr_ip6)
9474 r1 = VppIpRoute(self, aftr_ip6, 128,
9475 [VppRoutePath(self.pg1.remote_ip6,
9476 self.pg1.sw_if_index)])
9480 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
9481 IP(dst=self.pg1.remote_ip4, src=self.pg0.remote_ip4) /
9482 UDP(sport=10000, dport=20000))
9483 self.pg0.add_stream(p)
9484 self.pg_enable_capture(self.pg_interfaces)
9486 capture = self.pg1.get_capture(1)
9487 capture = capture[0]
9488 self.assertEqual(capture[IPv6].src, b4_ip6)
9489 self.assertEqual(capture[IPv6].dst, aftr_ip6)
9490 self.assertEqual(capture[IP].src, self.pg0.remote_ip4)
9491 self.assertEqual(capture[IP].dst, self.pg1.remote_ip4)
9492 self.assertEqual(capture[UDP].sport, 10000)
9493 self.assertEqual(capture[UDP].dport, 20000)
9494 self.assert_packet_checksums_valid(capture)
9497 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
9498 IPv6(dst=b4_ip6, src=aftr_ip6) /
9499 IP(dst=self.pg0.remote_ip4, src=self.pg1.remote_ip4) /
9500 UDP(sport=20000, dport=10000))
9501 self.pg1.add_stream(p)
9502 self.pg_enable_capture(self.pg_interfaces)
9504 capture = self.pg0.get_capture(1)
9505 capture = capture[0]
9506 self.assertFalse(capture.haslayer(IPv6))
9507 self.assertEqual(capture[IP].src, self.pg1.remote_ip4)
9508 self.assertEqual(capture[IP].dst, self.pg0.remote_ip4)
9509 self.assertEqual(capture[UDP].sport, 20000)
9510 self.assertEqual(capture[UDP].dport, 10000)
9511 self.assert_packet_checksums_valid(capture)
9513 # ping DS-Lite B4 tunnel endpoint address
9514 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
9515 IPv6(src=self.pg1.remote_hosts[0].ip6, dst=b4_ip6) /
9516 ICMPv6EchoRequest())
9517 self.pg1.add_stream(p)
9518 self.pg_enable_capture(self.pg_interfaces)
9520 capture = self.pg1.get_capture(1)
9521 capture = capture[0]
9522 self.assertEqual(capture[IPv6].src, b4_ip6)
9523 self.assertEqual(capture[IPv6].dst, self.pg1.remote_hosts[0].ip6)
9524 self.assertTrue(capture.haslayer(ICMPv6EchoReply))
9527 super(TestDSliteCE, self).tearDown()
9529 def show_commands_at_teardown(self):
9531 self.vapi.cli("show dslite aftr-tunnel-endpoint-address"))
9533 self.vapi.cli("show dslite b4-tunnel-endpoint-address"))
9536 class TestNAT66(MethodHolder):
9537 """ NAT66 Test Cases """
9540 def setUpClass(cls):
9541 super(TestNAT66, cls).setUpClass()
9544 cls.nat_addr = 'fd01:ff::2'
9546 cls.create_pg_interfaces(range(2))
9547 cls.interfaces = list(cls.pg_interfaces)
9549 for i in cls.interfaces:
9552 i.configure_ipv6_neighbors()
9555 super(TestNAT66, cls).tearDownClass()
9559 def tearDownClass(cls):
9560 super(TestNAT66, cls).tearDownClass()
9562 def test_static(self):
9563 """ 1:1 NAT66 test """
9564 flags = self.config_flags.NAT_IS_INSIDE
9565 self.vapi.nat66_add_del_interface(is_add=1, flags=flags,
9566 sw_if_index=self.pg0.sw_if_index)
9567 self.vapi.nat66_add_del_interface(is_add=1,
9568 sw_if_index=self.pg1.sw_if_index)
9569 self.vapi.nat66_add_del_static_mapping(
9570 local_ip_address=self.pg0.remote_ip6n,
9571 external_ip_address=self.nat_addr,
9576 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
9577 IPv6(src=self.pg0.remote_ip6, dst=self.pg1.remote_ip6) /
9580 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
9581 IPv6(src=self.pg0.remote_ip6, dst=self.pg1.remote_ip6) /
9584 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
9585 IPv6(src=self.pg0.remote_ip6, dst=self.pg1.remote_ip6) /
9586 ICMPv6EchoRequest())
9588 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
9589 IPv6(src=self.pg0.remote_ip6, dst=self.pg1.remote_ip6) /
9590 GRE() / IP() / TCP())
9592 self.pg0.add_stream(pkts)
9593 self.pg_enable_capture(self.pg_interfaces)
9595 capture = self.pg1.get_capture(len(pkts))
9596 for packet in capture:
9598 self.assertEqual(packet[IPv6].src, self.nat_addr)
9599 self.assertEqual(packet[IPv6].dst, self.pg1.remote_ip6)
9600 self.assert_packet_checksums_valid(packet)
9602 self.logger.error(ppp("Unexpected or invalid packet:", packet))
9607 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
9608 IPv6(src=self.pg1.remote_ip6, dst=self.nat_addr) /
9611 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
9612 IPv6(src=self.pg1.remote_ip6, dst=self.nat_addr) /
9615 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
9616 IPv6(src=self.pg1.remote_ip6, dst=self.nat_addr) /
9619 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
9620 IPv6(src=self.pg1.remote_ip6, dst=self.nat_addr) /
9621 GRE() / IP() / TCP())
9623 self.pg1.add_stream(pkts)
9624 self.pg_enable_capture(self.pg_interfaces)
9626 capture = self.pg0.get_capture(len(pkts))
9627 for packet in capture:
9629 self.assertEqual(packet[IPv6].src, self.pg1.remote_ip6)
9630 self.assertEqual(packet[IPv6].dst, self.pg0.remote_ip6)
9631 self.assert_packet_checksums_valid(packet)
9633 self.logger.error(ppp("Unexpected or invalid packet:", packet))
9636 sm = self.vapi.nat66_static_mapping_dump()
9637 self.assertEqual(len(sm), 1)
9638 self.assertEqual(sm[0].total_pkts, 8)
9640 def test_check_no_translate(self):
9641 """ NAT66 translate only when egress interface is outside interface """
9642 flags = self.config_flags.NAT_IS_INSIDE
9643 self.vapi.nat66_add_del_interface(is_add=1, flags=flags,
9644 sw_if_index=self.pg0.sw_if_index)
9645 self.vapi.nat66_add_del_interface(is_add=1, flags=flags,
9646 sw_if_index=self.pg1.sw_if_index)
9647 self.vapi.nat66_add_del_static_mapping(
9648 local_ip_address=self.pg0.remote_ip6n,
9649 external_ip_address=self.nat_addr,
9653 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
9654 IPv6(src=self.pg0.remote_ip6, dst=self.pg1.remote_ip6) /
9656 self.pg0.add_stream([p])
9657 self.pg_enable_capture(self.pg_interfaces)
9659 capture = self.pg1.get_capture(1)
9662 self.assertEqual(packet[IPv6].src, self.pg0.remote_ip6)
9663 self.assertEqual(packet[IPv6].dst, self.pg1.remote_ip6)
9665 self.logger.error(ppp("Unexpected or invalid packet:", packet))
9668 def clear_nat66(self):
9670 Clear NAT66 configuration.
9672 interfaces = self.vapi.nat66_interface_dump()
9673 for intf in interfaces:
9674 self.vapi.nat66_add_del_interface(is_add=0, flags=intf.flags,
9675 sw_if_index=intf.sw_if_index)
9677 static_mappings = self.vapi.nat66_static_mapping_dump()
9678 for sm in static_mappings:
9679 self.vapi.nat66_add_del_static_mapping(
9680 local_ip_address=sm.local_ip_address,
9681 external_ip_address=sm.external_ip_address, vrf_id=sm.vrf_id,
9685 super(TestNAT66, self).tearDown()
9688 def show_commands_at_teardown(self):
9689 self.logger.info(self.vapi.cli("show nat66 interfaces"))
9690 self.logger.info(self.vapi.cli("show nat66 static mappings"))
9693 if __name__ == '__main__':
9694 unittest.main(testRunner=VppTestRunner)