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 vpp_papi_provider import SYSLOG_SEVERITY
27 from io import BytesIO
28 from vpp_papi import VppEnum
29 from scapy.all import bind_layers, Packet, ByteEnumField, ShortField, \
30 IPField, IntField, LongField, XByteField, FlagsField, FieldLenField, \
32 from ipaddress import IPv6Network
35 # NAT HA protocol event data
38 fields_desc = [ByteEnumField("event_type", None,
39 {1: "add", 2: "del", 3: "refresh"}),
40 ByteEnumField("protocol", None,
41 {0: "udp", 1: "tcp", 2: "icmp"}),
42 ShortField("flags", 0),
43 IPField("in_addr", None),
44 IPField("out_addr", None),
45 ShortField("in_port", None),
46 ShortField("out_port", None),
47 IPField("eh_addr", None),
48 IPField("ehn_addr", None),
49 ShortField("eh_port", None),
50 ShortField("ehn_port", None),
51 IntField("fib_index", None),
52 IntField("total_pkts", 0),
53 LongField("total_bytes", 0)]
55 def extract_padding(self, s):
59 # NAT HA protocol header
60 class HANATStateSync(Packet):
61 name = "HA NAT state sync"
62 fields_desc = [XByteField("version", 1),
63 FlagsField("flags", 0, 8, ['ACK']),
64 FieldLenField("count", None, count_of="events"),
65 IntField("sequence_number", 1),
66 IntField("thread_index", 0),
67 PacketListField("events", [], Event,
68 count_from=lambda pkt: pkt.count)]
71 class MethodHolder(VppTestCase):
72 """ NAT create capture and verify method holder """
75 def config_flags(self):
76 return VppEnum.vl_api_nat_config_flags_t
78 def clear_nat44(self):
80 Clear NAT44 configuration.
82 if hasattr(self, 'pg7') and hasattr(self, 'pg8'):
83 # I found no elegant way to do this
84 self.vapi.ip_add_del_route(
85 dst_address=self.pg7.remote_ip4n,
86 dst_address_length=32,
87 next_hop_address=self.pg7.remote_ip4n,
88 next_hop_sw_if_index=self.pg7.sw_if_index,
90 self.vapi.ip_add_del_route(
91 dst_address=self.pg8.remote_ip4n,
92 dst_address_length=32,
93 next_hop_address=self.pg8.remote_ip4n,
94 next_hop_sw_if_index=self.pg8.sw_if_index,
97 for intf in [self.pg7, self.pg8]:
98 self.vapi.ip_neighbor_add_del(
102 flags=(VppEnum.vl_api_ip_neighbor_flags_t.
103 IP_API_NEIGHBOR_FLAG_STATIC),
106 if self.pg7.has_ip4_config:
107 self.pg7.unconfig_ip4()
109 self.vapi.nat44_forwarding_enable_disable(enable=0)
111 interfaces = self.vapi.nat44_interface_addr_dump()
112 for intf in interfaces:
113 self.vapi.nat44_add_del_interface_addr(
115 sw_if_index=intf.sw_if_index,
118 self.vapi.nat_ipfix_enable_disable(domain_id=self.ipfix_domain_id,
119 src_port=self.ipfix_src_port,
121 self.ipfix_src_port = 4739
122 self.ipfix_domain_id = 1
124 self.vapi.syslog_set_filter(SYSLOG_SEVERITY.EMERG)
126 self.vapi.nat_ha_set_listener(ip_address='0.0.0.0', port=0,
128 self.vapi.nat_ha_set_failover(ip_address='0.0.0.0', port=0,
129 session_refresh_interval=10)
131 interfaces = self.vapi.nat44_interface_dump()
132 for intf in interfaces:
133 if intf.flags & self.config_flags.NAT_IS_INSIDE and \
134 intf.flags & self.config_flags.NAT_IS_OUTSIDE:
135 self.vapi.nat44_interface_add_del_feature(
136 sw_if_index=intf.sw_if_index)
137 self.vapi.nat44_interface_add_del_feature(
138 sw_if_index=intf.sw_if_index,
141 interfaces = self.vapi.nat44_interface_output_feature_dump()
142 for intf in interfaces:
143 self.vapi.nat44_interface_add_del_output_feature(
146 sw_if_index=intf.sw_if_index)
147 static_mappings = self.vapi.nat44_static_mapping_dump()
148 for sm in static_mappings:
149 self.vapi.nat44_add_del_static_mapping(
151 local_ip_address=sm.local_ip_address,
152 external_ip_address=sm.external_ip_address,
153 external_sw_if_index=sm.external_sw_if_index,
154 local_port=sm.local_port,
155 external_port=sm.external_port,
157 protocol=sm.protocol,
158 flags=sm.flags, tag=sm.tag)
160 lb_static_mappings = self.vapi.nat44_lb_static_mapping_dump()
161 for lb_sm in lb_static_mappings:
162 self.vapi.nat44_add_del_lb_static_mapping(
165 external_addr=lb_sm.external_addr,
166 external_port=lb_sm.external_port,
167 protocol=lb_sm.protocol,
168 local_num=0, locals=[],
171 identity_mappings = self.vapi.nat44_identity_mapping_dump()
172 for id_m in identity_mappings:
173 self.vapi.nat44_add_del_identity_mapping(
174 ip_address=id_m.ip_address,
175 sw_if_index=id_m.sw_if_index,
179 protocol=id_m.protocol)
181 addresses = self.vapi.nat44_address_dump()
182 for addr in addresses:
183 self.vapi.nat44_add_del_address_range(
184 first_ip_address=addr.ip_address,
185 last_ip_address=addr.ip_address,
186 vrf_id=0xFFFFFFFF, flags=addr.flags)
188 self.vapi.nat_set_reass(timeout=2, max_reass=1024, max_frag=5,
190 self.vapi.nat_set_reass(timeout=2, max_reass=1024, max_frag=5,
191 drop_frag=0, is_ip6=1)
192 self.verify_no_nat44_user()
193 self.vapi.nat_set_timeouts(udp=300, tcp_established=7440,
194 tcp_transitory=240, icmp=60)
195 self.vapi.nat_set_addr_and_port_alloc_alg()
196 self.vapi.nat_set_mss_clamping(enable=0, mss_value=1500)
198 def nat44_add_static_mapping(self, local_ip, external_ip='0.0.0.0',
199 local_port=0, external_port=0, vrf_id=0,
200 is_add=1, external_sw_if_index=0xFFFFFFFF,
201 proto=0, tag="", flags=0):
203 Add/delete NAT44 static mapping
205 :param local_ip: Local IP address
206 :param external_ip: External IP address
207 :param local_port: Local port number (Optional)
208 :param external_port: External port number (Optional)
209 :param vrf_id: VRF ID (Default 0)
210 :param is_add: 1 if add, 0 if delete (Default add)
211 :param external_sw_if_index: External interface instead of IP address
212 :param proto: IP protocol (Mandatory if port specified)
213 :param tag: Opaque string tag
214 :param flags: NAT configuration flags
217 if not (local_port and external_port):
218 flags |= self.config_flags.NAT_IS_ADDR_ONLY
220 self.vapi.nat44_add_del_static_mapping(
222 local_ip_address=local_ip,
223 external_ip_address=external_ip,
224 external_sw_if_index=external_sw_if_index,
225 local_port=local_port,
226 external_port=external_port,
227 vrf_id=vrf_id, protocol=proto,
231 def nat44_add_address(self, ip, is_add=1, vrf_id=0xFFFFFFFF, twice_nat=0):
233 Add/delete NAT44 address
235 :param ip: IP address
236 :param is_add: 1 if add, 0 if delete (Default add)
237 :param twice_nat: twice NAT address for external hosts
239 flags = self.config_flags.NAT_IS_TWICE_NAT if twice_nat else 0
240 self.vapi.nat44_add_del_address_range(first_ip_address=ip,
246 def create_stream_in(self, in_if, out_if, dst_ip=None, ttl=64):
248 Create packet stream for inside network
250 :param in_if: Inside interface
251 :param out_if: Outside interface
252 :param dst_ip: Destination address
253 :param ttl: TTL of generated packets
256 dst_ip = out_if.remote_ip4
260 p = (Ether(dst=in_if.local_mac, src=in_if.remote_mac) /
261 IP(src=in_if.remote_ip4, dst=dst_ip, ttl=ttl) /
262 TCP(sport=self.tcp_port_in, dport=20))
266 p = (Ether(dst=in_if.local_mac, src=in_if.remote_mac) /
267 IP(src=in_if.remote_ip4, dst=dst_ip, ttl=ttl) /
268 UDP(sport=self.udp_port_in, dport=20))
272 p = (Ether(dst=in_if.local_mac, src=in_if.remote_mac) /
273 IP(src=in_if.remote_ip4, dst=dst_ip, ttl=ttl) /
274 ICMP(id=self.icmp_id_in, type='echo-request'))
279 def compose_ip6(self, ip4, pref, plen):
281 Compose IPv4-embedded IPv6 addresses
283 :param ip4: IPv4 address
284 :param pref: IPv6 prefix
285 :param plen: IPv6 prefix length
286 :returns: IPv4-embedded IPv6 addresses
288 pref_n = list(socket.inet_pton(socket.AF_INET6, pref))
289 ip4_n = list(socket.inet_pton(socket.AF_INET, ip4))
304 pref_n[10] = ip4_n[3]
308 pref_n[10] = ip4_n[2]
309 pref_n[11] = ip4_n[3]
312 pref_n[10] = ip4_n[1]
313 pref_n[11] = ip4_n[2]
314 pref_n[12] = ip4_n[3]
316 pref_n[12] = ip4_n[0]
317 pref_n[13] = ip4_n[1]
318 pref_n[14] = ip4_n[2]
319 pref_n[15] = ip4_n[3]
320 packed_pref_n = b''.join([scapy.compat.chb(x) for x in pref_n])
321 return socket.inet_ntop(socket.AF_INET6, packed_pref_n)
323 def extract_ip4(self, ip6, plen):
325 Extract IPv4 address embedded in IPv6 addresses
327 :param ip6: IPv6 address
328 :param plen: IPv6 prefix length
329 :returns: extracted IPv4 address
331 ip6_n = list(socket.inet_pton(socket.AF_INET6, ip6))
363 return socket.inet_ntop(socket.AF_INET, ''.join(ip4_n))
365 def create_stream_in_ip6(self, in_if, out_if, hlim=64, pref=None, plen=0):
367 Create IPv6 packet stream for inside network
369 :param in_if: Inside interface
370 :param out_if: Outside interface
371 :param ttl: Hop Limit of generated packets
372 :param pref: NAT64 prefix
373 :param plen: NAT64 prefix length
377 dst = ''.join(['64:ff9b::', out_if.remote_ip4])
379 dst = self.compose_ip6(out_if.remote_ip4, pref, plen)
382 p = (Ether(dst=in_if.local_mac, src=in_if.remote_mac) /
383 IPv6(src=in_if.remote_ip6, dst=dst, hlim=hlim) /
384 TCP(sport=self.tcp_port_in, dport=20))
388 p = (Ether(dst=in_if.local_mac, src=in_if.remote_mac) /
389 IPv6(src=in_if.remote_ip6, dst=dst, hlim=hlim) /
390 UDP(sport=self.udp_port_in, dport=20))
394 p = (Ether(dst=in_if.local_mac, src=in_if.remote_mac) /
395 IPv6(src=in_if.remote_ip6, dst=dst, hlim=hlim) /
396 ICMPv6EchoRequest(id=self.icmp_id_in))
401 def create_stream_out(self, out_if, dst_ip=None, ttl=64,
402 use_inside_ports=False):
404 Create packet stream for outside network
406 :param out_if: Outside interface
407 :param dst_ip: Destination IP address (Default use global NAT address)
408 :param ttl: TTL of generated packets
409 :param use_inside_ports: Use inside NAT ports as destination ports
410 instead of outside ports
413 dst_ip = self.nat_addr
414 if not use_inside_ports:
415 tcp_port = self.tcp_port_out
416 udp_port = self.udp_port_out
417 icmp_id = self.icmp_id_out
419 tcp_port = self.tcp_port_in
420 udp_port = self.udp_port_in
421 icmp_id = self.icmp_id_in
424 p = (Ether(dst=out_if.local_mac, src=out_if.remote_mac) /
425 IP(src=out_if.remote_ip4, dst=dst_ip, ttl=ttl) /
426 TCP(dport=tcp_port, sport=20))
430 p = (Ether(dst=out_if.local_mac, src=out_if.remote_mac) /
431 IP(src=out_if.remote_ip4, dst=dst_ip, ttl=ttl) /
432 UDP(dport=udp_port, sport=20))
436 p = (Ether(dst=out_if.local_mac, src=out_if.remote_mac) /
437 IP(src=out_if.remote_ip4, dst=dst_ip, ttl=ttl) /
438 ICMP(id=icmp_id, type='echo-reply'))
443 def create_stream_out_ip6(self, out_if, src_ip, dst_ip, hl=64):
445 Create packet stream for outside network
447 :param out_if: Outside interface
448 :param dst_ip: Destination IP address (Default use global NAT address)
449 :param hl: HL of generated packets
453 p = (Ether(dst=out_if.local_mac, src=out_if.remote_mac) /
454 IPv6(src=src_ip, dst=dst_ip, hlim=hl) /
455 TCP(dport=self.tcp_port_out, sport=20))
459 p = (Ether(dst=out_if.local_mac, src=out_if.remote_mac) /
460 IPv6(src=src_ip, dst=dst_ip, hlim=hl) /
461 UDP(dport=self.udp_port_out, sport=20))
465 p = (Ether(dst=out_if.local_mac, src=out_if.remote_mac) /
466 IPv6(src=src_ip, dst=dst_ip, hlim=hl) /
467 ICMPv6EchoReply(id=self.icmp_id_out))
472 def verify_capture_out(self, capture, nat_ip=None, same_port=False,
473 dst_ip=None, is_ip6=False):
475 Verify captured packets on outside network
477 :param capture: Captured packets
478 :param nat_ip: Translated IP address (Default use global NAT address)
479 :param same_port: Source port number is not translated (Default False)
480 :param dst_ip: Destination IP address (Default do not verify)
481 :param is_ip6: If L3 protocol is IPv6 (Default False)
485 ICMP46 = ICMPv6EchoRequest
490 nat_ip = self.nat_addr
491 for packet in capture:
494 self.assert_packet_checksums_valid(packet)
495 self.assertEqual(packet[IP46].src, nat_ip)
496 if dst_ip is not None:
497 self.assertEqual(packet[IP46].dst, dst_ip)
498 if packet.haslayer(TCP):
500 self.assertEqual(packet[TCP].sport, self.tcp_port_in)
503 packet[TCP].sport, self.tcp_port_in)
504 self.tcp_port_out = packet[TCP].sport
505 self.assert_packet_checksums_valid(packet)
506 elif packet.haslayer(UDP):
508 self.assertEqual(packet[UDP].sport, self.udp_port_in)
511 packet[UDP].sport, self.udp_port_in)
512 self.udp_port_out = packet[UDP].sport
515 self.assertEqual(packet[ICMP46].id, self.icmp_id_in)
517 self.assertNotEqual(packet[ICMP46].id, self.icmp_id_in)
518 self.icmp_id_out = packet[ICMP46].id
519 self.assert_packet_checksums_valid(packet)
521 self.logger.error(ppp("Unexpected or invalid packet "
522 "(outside network):", packet))
525 def verify_capture_out_ip6(self, capture, nat_ip, same_port=False,
528 Verify captured packets on outside network
530 :param capture: Captured packets
531 :param nat_ip: Translated IP address
532 :param same_port: Source port number is not translated (Default False)
533 :param dst_ip: Destination IP address (Default do not verify)
535 return self.verify_capture_out(capture, nat_ip, same_port, dst_ip,
538 def verify_capture_in(self, capture, in_if):
540 Verify captured packets on inside network
542 :param capture: Captured packets
543 :param in_if: Inside interface
545 for packet in capture:
547 self.assert_packet_checksums_valid(packet)
548 self.assertEqual(packet[IP].dst, in_if.remote_ip4)
549 if packet.haslayer(TCP):
550 self.assertEqual(packet[TCP].dport, self.tcp_port_in)
551 elif packet.haslayer(UDP):
552 self.assertEqual(packet[UDP].dport, self.udp_port_in)
554 self.assertEqual(packet[ICMP].id, self.icmp_id_in)
556 self.logger.error(ppp("Unexpected or invalid packet "
557 "(inside network):", packet))
560 def verify_capture_in_ip6(self, capture, src_ip, dst_ip):
562 Verify captured IPv6 packets on inside network
564 :param capture: Captured packets
565 :param src_ip: Source IP
566 :param dst_ip: Destination IP address
568 for packet in capture:
570 self.assertEqual(packet[IPv6].src, src_ip)
571 self.assertEqual(packet[IPv6].dst, dst_ip)
572 self.assert_packet_checksums_valid(packet)
573 if packet.haslayer(TCP):
574 self.assertEqual(packet[TCP].dport, self.tcp_port_in)
575 elif packet.haslayer(UDP):
576 self.assertEqual(packet[UDP].dport, self.udp_port_in)
578 self.assertEqual(packet[ICMPv6EchoReply].id,
581 self.logger.error(ppp("Unexpected or invalid packet "
582 "(inside network):", packet))
585 def verify_capture_no_translation(self, capture, ingress_if, egress_if):
587 Verify captured packet that don't have to be translated
589 :param capture: Captured packets
590 :param ingress_if: Ingress interface
591 :param egress_if: Egress interface
593 for packet in capture:
595 self.assertEqual(packet[IP].src, ingress_if.remote_ip4)
596 self.assertEqual(packet[IP].dst, egress_if.remote_ip4)
597 if packet.haslayer(TCP):
598 self.assertEqual(packet[TCP].sport, self.tcp_port_in)
599 elif packet.haslayer(UDP):
600 self.assertEqual(packet[UDP].sport, self.udp_port_in)
602 self.assertEqual(packet[ICMP].id, self.icmp_id_in)
604 self.logger.error(ppp("Unexpected or invalid packet "
605 "(inside network):", packet))
608 def verify_capture_out_with_icmp_errors(self, capture, src_ip=None,
611 Verify captured packets with ICMP errors on outside network
613 :param capture: Captured packets
614 :param src_ip: Translated IP address or IP address of VPP
615 (Default use global NAT address)
616 :param icmp_type: Type of error ICMP packet
617 we are expecting (Default 11)
620 src_ip = self.nat_addr
621 for packet in capture:
623 self.assertEqual(packet[IP].src, src_ip)
624 self.assertEqual(packet.haslayer(ICMP), 1)
626 self.assertEqual(icmp.type, icmp_type)
627 self.assertTrue(icmp.haslayer(IPerror))
628 inner_ip = icmp[IPerror]
629 if inner_ip.haslayer(TCPerror):
630 self.assertEqual(inner_ip[TCPerror].dport,
632 elif inner_ip.haslayer(UDPerror):
633 self.assertEqual(inner_ip[UDPerror].dport,
636 self.assertEqual(inner_ip[ICMPerror].id, self.icmp_id_out)
638 self.logger.error(ppp("Unexpected or invalid packet "
639 "(outside network):", packet))
642 def verify_capture_in_with_icmp_errors(self, capture, in_if, icmp_type=11):
644 Verify captured packets with ICMP errors on inside network
646 :param capture: Captured packets
647 :param in_if: Inside interface
648 :param icmp_type: Type of error ICMP packet
649 we are expecting (Default 11)
651 for packet in capture:
653 self.assertEqual(packet[IP].dst, in_if.remote_ip4)
654 self.assertEqual(packet.haslayer(ICMP), 1)
656 self.assertEqual(icmp.type, icmp_type)
657 self.assertTrue(icmp.haslayer(IPerror))
658 inner_ip = icmp[IPerror]
659 if inner_ip.haslayer(TCPerror):
660 self.assertEqual(inner_ip[TCPerror].sport,
662 elif inner_ip.haslayer(UDPerror):
663 self.assertEqual(inner_ip[UDPerror].sport,
666 self.assertEqual(inner_ip[ICMPerror].id, self.icmp_id_in)
668 self.logger.error(ppp("Unexpected or invalid packet "
669 "(inside network):", packet))
672 def create_stream_frag(self, src_if, dst, sport, dport, data,
673 proto=IP_PROTOS.tcp, echo_reply=False):
675 Create fragmented packet stream
677 :param src_if: Source interface
678 :param dst: Destination IPv4 address
679 :param sport: Source port
680 :param dport: Destination port
681 :param data: Payload data
682 :param proto: protocol (TCP, UDP, ICMP)
683 :param echo_reply: use echo_reply if protocol is ICMP
686 if proto == IP_PROTOS.tcp:
687 p = (IP(src=src_if.remote_ip4, dst=dst) /
688 TCP(sport=sport, dport=dport) /
690 p = p.__class__(scapy.compat.raw(p))
691 chksum = p[TCP].chksum
692 proto_header = TCP(sport=sport, dport=dport, chksum=chksum)
693 elif proto == IP_PROTOS.udp:
694 proto_header = UDP(sport=sport, dport=dport)
695 elif proto == IP_PROTOS.icmp:
697 proto_header = ICMP(id=sport, type='echo-request')
699 proto_header = ICMP(id=sport, type='echo-reply')
701 raise Exception("Unsupported protocol")
702 id = random.randint(0, 65535)
704 if proto == IP_PROTOS.tcp:
707 raw = Raw(data[0:16])
708 p = (Ether(src=src_if.remote_mac, dst=src_if.local_mac) /
709 IP(src=src_if.remote_ip4, dst=dst, flags="MF", frag=0, id=id) /
713 if proto == IP_PROTOS.tcp:
714 raw = Raw(data[4:20])
716 raw = Raw(data[16:32])
717 p = (Ether(src=src_if.remote_mac, dst=src_if.local_mac) /
718 IP(src=src_if.remote_ip4, dst=dst, flags="MF", frag=3, id=id,
722 if proto == IP_PROTOS.tcp:
726 p = (Ether(src=src_if.remote_mac, dst=src_if.local_mac) /
727 IP(src=src_if.remote_ip4, dst=dst, frag=5, proto=proto,
733 def create_stream_frag_ip6(self, src_if, dst, sport, dport, data,
734 pref=None, plen=0, frag_size=128):
736 Create fragmented packet stream
738 :param src_if: Source interface
739 :param dst: Destination IPv4 address
740 :param sport: Source TCP port
741 :param dport: Destination TCP port
742 :param data: Payload data
743 :param pref: NAT64 prefix
744 :param plen: NAT64 prefix length
745 :param fragsize: size of fragments
749 dst_ip6 = ''.join(['64:ff9b::', dst])
751 dst_ip6 = self.compose_ip6(dst, pref, plen)
753 p = (Ether(dst=src_if.local_mac, src=src_if.remote_mac) /
754 IPv6(src=src_if.remote_ip6, dst=dst_ip6) /
755 IPv6ExtHdrFragment(id=random.randint(0, 65535)) /
756 TCP(sport=sport, dport=dport) /
759 return fragment6(p, frag_size)
761 def reass_frags_and_verify(self, frags, src, dst):
763 Reassemble and verify fragmented packet
765 :param frags: Captured fragments
766 :param src: Source IPv4 address to verify
767 :param dst: Destination IPv4 address to verify
769 :returns: Reassembled IPv4 packet
773 self.assertEqual(p[IP].src, src)
774 self.assertEqual(p[IP].dst, dst)
775 self.assert_ip_checksum_valid(p)
776 buffer.seek(p[IP].frag * 8)
777 buffer.write(bytes(p[IP].payload))
778 ip = IP(src=frags[0][IP].src, dst=frags[0][IP].dst,
779 proto=frags[0][IP].proto)
780 if ip.proto == IP_PROTOS.tcp:
781 p = (ip / TCP(buffer.getvalue()))
782 self.assert_tcp_checksum_valid(p)
783 elif ip.proto == IP_PROTOS.udp:
784 p = (ip / UDP(buffer.getvalue()[:8]) /
785 Raw(buffer.getvalue()[8:]))
786 elif ip.proto == IP_PROTOS.icmp:
787 p = (ip / ICMP(buffer.getvalue()))
790 def reass_frags_and_verify_ip6(self, frags, src, dst):
792 Reassemble and verify fragmented packet
794 :param frags: Captured fragments
795 :param src: Source IPv6 address to verify
796 :param dst: Destination IPv6 address to verify
798 :returns: Reassembled IPv6 packet
802 self.assertEqual(p[IPv6].src, src)
803 self.assertEqual(p[IPv6].dst, dst)
804 buffer.seek(p[IPv6ExtHdrFragment].offset * 8)
805 buffer.write(bytes(p[IPv6ExtHdrFragment].payload))
806 ip = IPv6(src=frags[0][IPv6].src, dst=frags[0][IPv6].dst,
807 nh=frags[0][IPv6ExtHdrFragment].nh)
808 if ip.nh == IP_PROTOS.tcp:
809 p = (ip / TCP(buffer.getvalue()))
810 elif ip.nh == IP_PROTOS.udp:
811 p = (ip / UDP(buffer.getvalue()))
812 self.assert_packet_checksums_valid(p)
815 def initiate_tcp_session(self, in_if, out_if):
817 Initiates TCP session
819 :param in_if: Inside interface
820 :param out_if: Outside interface
824 p = (Ether(src=in_if.remote_mac, dst=in_if.local_mac) /
825 IP(src=in_if.remote_ip4, dst=out_if.remote_ip4) /
826 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
829 self.pg_enable_capture(self.pg_interfaces)
831 capture = out_if.get_capture(1)
833 self.tcp_port_out = p[TCP].sport
835 # SYN + ACK packet out->in
836 p = (Ether(src=out_if.remote_mac, dst=out_if.local_mac) /
837 IP(src=out_if.remote_ip4, dst=self.nat_addr) /
838 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
841 self.pg_enable_capture(self.pg_interfaces)
846 p = (Ether(src=in_if.remote_mac, dst=in_if.local_mac) /
847 IP(src=in_if.remote_ip4, dst=out_if.remote_ip4) /
848 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
851 self.pg_enable_capture(self.pg_interfaces)
853 out_if.get_capture(1)
856 self.logger.error("TCP 3 way handshake failed")
859 def verify_ipfix_nat44_ses(self, data):
861 Verify IPFIX NAT44 session create/delete event
863 :param data: Decoded IPFIX data records
865 nat44_ses_create_num = 0
866 nat44_ses_delete_num = 0
867 self.assertEqual(6, len(data))
870 self.assertIn(scapy.compat.orb(record[230]), [4, 5])
871 if scapy.compat.orb(record[230]) == 4:
872 nat44_ses_create_num += 1
874 nat44_ses_delete_num += 1
876 self.assertEqual(self.pg0.remote_ip4n, record[8])
877 # postNATSourceIPv4Address
878 self.assertEqual(socket.inet_pton(socket.AF_INET, self.nat_addr),
881 self.assertEqual(struct.pack("!I", 0), record[234])
882 # protocolIdentifier/sourceTransportPort
883 # /postNAPTSourceTransportPort
884 if IP_PROTOS.icmp == scapy.compat.orb(record[4]):
885 self.assertEqual(struct.pack("!H", self.icmp_id_in), record[7])
886 self.assertEqual(struct.pack("!H", self.icmp_id_out),
888 elif IP_PROTOS.tcp == scapy.compat.orb(record[4]):
889 self.assertEqual(struct.pack("!H", self.tcp_port_in),
891 self.assertEqual(struct.pack("!H", self.tcp_port_out),
893 elif IP_PROTOS.udp == scapy.compat.orb(record[4]):
894 self.assertEqual(struct.pack("!H", self.udp_port_in),
896 self.assertEqual(struct.pack("!H", self.udp_port_out),
899 self.fail("Invalid protocol")
900 self.assertEqual(3, nat44_ses_create_num)
901 self.assertEqual(3, nat44_ses_delete_num)
903 def verify_ipfix_addr_exhausted(self, data):
905 Verify IPFIX NAT addresses event
907 :param data: Decoded IPFIX data records
909 self.assertEqual(1, len(data))
912 self.assertEqual(scapy.compat.orb(record[230]), 3)
914 self.assertEqual(struct.pack("!I", 0), record[283])
916 def verify_ipfix_max_sessions(self, data, limit):
918 Verify IPFIX maximum session entries exceeded event
920 :param data: Decoded IPFIX data records
921 :param limit: Number of maximum session 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", 1), record[466])
930 self.assertEqual(struct.pack("I", limit), record[471])
932 def verify_ipfix_max_bibs(self, data, limit):
934 Verify IPFIX maximum BIB entries exceeded event
936 :param data: Decoded IPFIX data records
937 :param limit: Number of maximum BIB entries that can be created.
939 self.assertEqual(1, len(data))
942 self.assertEqual(scapy.compat.orb(record[230]), 13)
943 # natQuotaExceededEvent
944 self.assertEqual(struct.pack("I", 2), record[466])
946 self.assertEqual(struct.pack("I", limit), record[472])
948 def verify_ipfix_max_fragments_ip6(self, data, limit, src_addr):
950 Verify IPFIX maximum IPv6 fragments pending reassembly exceeded event
952 :param data: Decoded IPFIX data records
953 :param limit: Number of maximum fragments pending reassembly
954 :param src_addr: IPv6 source address
956 self.assertEqual(1, len(data))
959 self.assertEqual(scapy.compat.orb(record[230]), 13)
960 # natQuotaExceededEvent
961 self.assertEqual(struct.pack("I", 5), record[466])
962 # maxFragmentsPendingReassembly
963 self.assertEqual(struct.pack("I", limit), record[475])
965 self.assertEqual(src_addr, record[27])
967 def verify_ipfix_max_fragments_ip4(self, data, limit, src_addr):
969 Verify IPFIX maximum IPv4 fragments pending reassembly exceeded event
971 :param data: Decoded IPFIX data records
972 :param limit: Number of maximum fragments pending reassembly
973 :param src_addr: IPv4 source address
975 self.assertEqual(1, len(data))
978 self.assertEqual(scapy.compat.orb(record[230]), 13)
979 # natQuotaExceededEvent
980 self.assertEqual(struct.pack("I", 5), record[466])
981 # maxFragmentsPendingReassembly
982 self.assertEqual(struct.pack("I", limit), record[475])
984 self.assertEqual(src_addr, record[8])
986 def verify_ipfix_bib(self, data, is_create, src_addr):
988 Verify IPFIX NAT64 BIB create and delete events
990 :param data: Decoded IPFIX data records
991 :param is_create: Create event if nonzero value otherwise delete event
992 :param src_addr: IPv6 source address
994 self.assertEqual(1, len(data))
998 self.assertEqual(scapy.compat.orb(record[230]), 10)
1000 self.assertEqual(scapy.compat.orb(record[230]), 11)
1002 self.assertEqual(src_addr, record[27])
1003 # postNATSourceIPv4Address
1004 self.assertEqual(self.nat_addr_n, record[225])
1005 # protocolIdentifier
1006 self.assertEqual(IP_PROTOS.tcp, scapy.compat.orb(record[4]))
1008 self.assertEqual(struct.pack("!I", 0), record[234])
1009 # sourceTransportPort
1010 self.assertEqual(struct.pack("!H", self.tcp_port_in), record[7])
1011 # postNAPTSourceTransportPort
1012 self.assertEqual(struct.pack("!H", self.tcp_port_out), record[227])
1014 def verify_ipfix_nat64_ses(self, data, is_create, src_addr, dst_addr,
1017 Verify IPFIX NAT64 session create and delete events
1019 :param data: Decoded IPFIX data records
1020 :param is_create: Create event if nonzero value otherwise delete event
1021 :param src_addr: IPv6 source address
1022 :param dst_addr: IPv4 destination address
1023 :param dst_port: destination TCP port
1025 self.assertEqual(1, len(data))
1029 self.assertEqual(scapy.compat.orb(record[230]), 6)
1031 self.assertEqual(scapy.compat.orb(record[230]), 7)
1033 self.assertEqual(src_addr, record[27])
1034 # destinationIPv6Address
1035 self.assertEqual(socket.inet_pton(socket.AF_INET6,
1036 self.compose_ip6(dst_addr,
1040 # postNATSourceIPv4Address
1041 self.assertEqual(self.nat_addr_n, record[225])
1042 # postNATDestinationIPv4Address
1043 self.assertEqual(socket.inet_pton(socket.AF_INET, dst_addr),
1045 # protocolIdentifier
1046 self.assertEqual(IP_PROTOS.tcp, scapy.compat.orb(record[4]))
1048 self.assertEqual(struct.pack("!I", 0), record[234])
1049 # sourceTransportPort
1050 self.assertEqual(struct.pack("!H", self.tcp_port_in), record[7])
1051 # postNAPTSourceTransportPort
1052 self.assertEqual(struct.pack("!H", self.tcp_port_out), record[227])
1053 # destinationTransportPort
1054 self.assertEqual(struct.pack("!H", dst_port), record[11])
1055 # postNAPTDestinationTransportPort
1056 self.assertEqual(struct.pack("!H", dst_port), record[228])
1058 def verify_no_nat44_user(self):
1059 """ Verify that there is no NAT44 user """
1060 users = self.vapi.nat44_user_dump()
1061 self.assertEqual(len(users), 0)
1062 users = self.statistics.get_counter('/nat44/total-users')
1063 self.assertEqual(users[0][0], 0)
1064 sessions = self.statistics.get_counter('/nat44/total-sessions')
1065 self.assertEqual(sessions[0][0], 0)
1067 def verify_ipfix_max_entries_per_user(self, data, limit, src_addr):
1069 Verify IPFIX maximum entries per user exceeded event
1071 :param data: Decoded IPFIX data records
1072 :param limit: Number of maximum entries per user
1073 :param src_addr: IPv4 source address
1075 self.assertEqual(1, len(data))
1078 self.assertEqual(scapy.compat.orb(record[230]), 13)
1079 # natQuotaExceededEvent
1080 self.assertEqual(struct.pack("I", 3), record[466])
1082 self.assertEqual(struct.pack("I", limit), record[473])
1084 self.assertEqual(src_addr, record[8])
1086 def verify_syslog_apmap(self, data, is_add=True):
1087 message = data.decode('utf-8')
1089 message = SyslogMessage.parse(message)
1090 except ParseError as e:
1091 self.logger.error(e)
1094 self.assertEqual(message.severity, SyslogSeverity.info)
1095 self.assertEqual(message.appname, 'NAT')
1096 self.assertEqual(message.msgid, 'APMADD' if is_add else 'APMDEL')
1097 sd_params = message.sd.get('napmap')
1098 self.assertTrue(sd_params is not None)
1099 self.assertEqual(sd_params.get('IATYP'), 'IPv4')
1100 self.assertEqual(sd_params.get('ISADDR'), self.pg0.remote_ip4)
1101 self.assertEqual(sd_params.get('ISPORT'), "%d" % self.tcp_port_in)
1102 self.assertEqual(sd_params.get('XATYP'), 'IPv4')
1103 self.assertEqual(sd_params.get('XSADDR'), self.nat_addr)
1104 self.assertEqual(sd_params.get('XSPORT'), "%d" % self.tcp_port_out)
1105 self.assertEqual(sd_params.get('PROTO'), "%d" % IP_PROTOS.tcp)
1106 self.assertTrue(sd_params.get('SSUBIX') is not None)
1107 self.assertEqual(sd_params.get('SVLAN'), '0')
1109 def verify_syslog_sess(self, data, is_add=True, is_ip6=False):
1110 message = data.decode('utf-8')
1112 message = SyslogMessage.parse(message)
1113 except ParseError as e:
1114 self.logger.error(e)
1117 self.assertEqual(message.severity, SyslogSeverity.info)
1118 self.assertEqual(message.appname, 'NAT')
1119 self.assertEqual(message.msgid, 'SADD' if is_add else 'SDEL')
1120 sd_params = message.sd.get('nsess')
1121 self.assertTrue(sd_params is not None)
1123 self.assertEqual(sd_params.get('IATYP'), 'IPv6')
1124 self.assertEqual(sd_params.get('ISADDR'), self.pg0.remote_ip6)
1126 self.assertEqual(sd_params.get('IATYP'), 'IPv4')
1127 self.assertEqual(sd_params.get('ISADDR'), self.pg0.remote_ip4)
1128 self.assertTrue(sd_params.get('SSUBIX') is not None)
1129 self.assertEqual(sd_params.get('ISPORT'), "%d" % self.tcp_port_in)
1130 self.assertEqual(sd_params.get('XATYP'), 'IPv4')
1131 self.assertEqual(sd_params.get('XSADDR'), self.nat_addr)
1132 self.assertEqual(sd_params.get('XSPORT'), "%d" % self.tcp_port_out)
1133 self.assertEqual(sd_params.get('PROTO'), "%d" % IP_PROTOS.tcp)
1134 self.assertEqual(sd_params.get('SVLAN'), '0')
1135 self.assertEqual(sd_params.get('XDADDR'), self.pg1.remote_ip4)
1136 self.assertEqual(sd_params.get('XDPORT'),
1137 "%d" % self.tcp_external_port)
1139 def verify_mss_value(self, pkt, mss):
1141 Verify TCP MSS value
1146 if not pkt.haslayer(IP) or not pkt.haslayer(TCP):
1147 raise TypeError("Not a TCP/IP packet")
1149 for option in pkt[TCP].options:
1150 if option[0] == 'MSS':
1151 self.assertEqual(option[1], mss)
1152 self.assert_tcp_checksum_valid(pkt)
1155 def proto2layer(proto):
1156 if proto == IP_PROTOS.tcp:
1158 elif proto == IP_PROTOS.udp:
1160 elif proto == IP_PROTOS.icmp:
1163 raise Exception("Unsupported protocol")
1165 def frag_in_order(self, proto=IP_PROTOS.tcp, dont_translate=False):
1166 layer = self.proto2layer(proto)
1168 if proto == IP_PROTOS.tcp:
1169 data = b"A" * 4 + b"B" * 16 + b"C" * 3
1171 data = b"A" * 16 + b"B" * 16 + b"C" * 3
1172 self.port_in = random.randint(1025, 65535)
1174 reass = self.vapi.nat_reass_dump()
1175 reass_n_start = len(reass)
1178 pkts = self.create_stream_frag(self.pg0,
1179 self.pg1.remote_ip4,
1184 self.pg0.add_stream(pkts)
1185 self.pg_enable_capture(self.pg_interfaces)
1187 frags = self.pg1.get_capture(len(pkts))
1188 if not dont_translate:
1189 p = self.reass_frags_and_verify(frags,
1191 self.pg1.remote_ip4)
1193 p = self.reass_frags_and_verify(frags,
1194 self.pg0.remote_ip4,
1195 self.pg1.remote_ip4)
1196 if proto != IP_PROTOS.icmp:
1197 if not dont_translate:
1198 self.assertEqual(p[layer].dport, 20)
1199 self.assertNotEqual(p[layer].sport, self.port_in)
1201 self.assertEqual(p[layer].sport, self.port_in)
1203 if not dont_translate:
1204 self.assertNotEqual(p[layer].id, self.port_in)
1206 self.assertEqual(p[layer].id, self.port_in)
1207 self.assertEqual(data, p[Raw].load)
1210 if not dont_translate:
1211 dst_addr = self.nat_addr
1213 dst_addr = self.pg0.remote_ip4
1214 if proto != IP_PROTOS.icmp:
1216 dport = p[layer].sport
1220 pkts = self.create_stream_frag(self.pg1,
1227 self.pg1.add_stream(pkts)
1228 self.pg_enable_capture(self.pg_interfaces)
1230 frags = self.pg0.get_capture(len(pkts))
1231 p = self.reass_frags_and_verify(frags,
1232 self.pg1.remote_ip4,
1233 self.pg0.remote_ip4)
1234 if proto != IP_PROTOS.icmp:
1235 self.assertEqual(p[layer].sport, 20)
1236 self.assertEqual(p[layer].dport, self.port_in)
1238 self.assertEqual(p[layer].id, self.port_in)
1239 self.assertEqual(data, p[Raw].load)
1241 reass = self.vapi.nat_reass_dump()
1242 reass_n_end = len(reass)
1244 self.assertEqual(reass_n_end - reass_n_start, 2)
1246 def frag_in_order_in_plus_out(self, proto=IP_PROTOS.tcp):
1247 layer = self.proto2layer(proto)
1249 if proto == IP_PROTOS.tcp:
1250 data = b"A" * 4 + b"B" * 16 + b"C" * 3
1252 data = b"A" * 16 + b"B" * 16 + b"C" * 3
1253 self.port_in = random.randint(1025, 65535)
1256 reass = self.vapi.nat_reass_dump()
1257 reass_n_start = len(reass)
1260 pkts = self.create_stream_frag(self.pg0,
1261 self.server_out_addr,
1263 self.server_out_port,
1266 self.pg0.add_stream(pkts)
1267 self.pg_enable_capture(self.pg_interfaces)
1269 frags = self.pg1.get_capture(len(pkts))
1270 p = self.reass_frags_and_verify(frags,
1271 self.pg0.remote_ip4,
1272 self.server_in_addr)
1273 if proto != IP_PROTOS.icmp:
1274 self.assertEqual(p[layer].sport, self.port_in)
1275 self.assertEqual(p[layer].dport, self.server_in_port)
1277 self.assertEqual(p[layer].id, self.port_in)
1278 self.assertEqual(data, p[Raw].load)
1281 if proto != IP_PROTOS.icmp:
1282 pkts = self.create_stream_frag(self.pg1,
1283 self.pg0.remote_ip4,
1284 self.server_in_port,
1289 pkts = self.create_stream_frag(self.pg1,
1290 self.pg0.remote_ip4,
1296 self.pg1.add_stream(pkts)
1297 self.pg_enable_capture(self.pg_interfaces)
1299 frags = self.pg0.get_capture(len(pkts))
1300 p = self.reass_frags_and_verify(frags,
1301 self.server_out_addr,
1302 self.pg0.remote_ip4)
1303 if proto != IP_PROTOS.icmp:
1304 self.assertEqual(p[layer].sport, self.server_out_port)
1305 self.assertEqual(p[layer].dport, self.port_in)
1307 self.assertEqual(p[layer].id, self.port_in)
1308 self.assertEqual(data, p[Raw].load)
1310 reass = self.vapi.nat_reass_dump()
1311 reass_n_end = len(reass)
1313 self.assertEqual(reass_n_end - reass_n_start, 2)
1315 def reass_hairpinning(self, proto=IP_PROTOS.tcp):
1316 layer = self.proto2layer(proto)
1318 if proto == IP_PROTOS.tcp:
1319 data = b"A" * 4 + b"B" * 16 + b"C" * 3
1321 data = b"A" * 16 + b"B" * 16 + b"C" * 3
1323 # send packet from host to server
1324 pkts = self.create_stream_frag(self.pg0,
1327 self.server_out_port,
1330 self.pg0.add_stream(pkts)
1331 self.pg_enable_capture(self.pg_interfaces)
1333 frags = self.pg0.get_capture(len(pkts))
1334 p = self.reass_frags_and_verify(frags,
1337 if proto != IP_PROTOS.icmp:
1338 self.assertNotEqual(p[layer].sport, self.host_in_port)
1339 self.assertEqual(p[layer].dport, self.server_in_port)
1341 self.assertNotEqual(p[layer].id, self.host_in_port)
1342 self.assertEqual(data, p[Raw].load)
1344 def frag_out_of_order(self, proto=IP_PROTOS.tcp, dont_translate=False):
1345 layer = self.proto2layer(proto)
1347 if proto == IP_PROTOS.tcp:
1348 data = b"A" * 4 + b"B" * 16 + b"C" * 3
1350 data = b"A" * 16 + b"B" * 16 + b"C" * 3
1351 self.port_in = random.randint(1025, 65535)
1355 pkts = self.create_stream_frag(self.pg0,
1356 self.pg1.remote_ip4,
1362 self.pg0.add_stream(pkts)
1363 self.pg_enable_capture(self.pg_interfaces)
1365 frags = self.pg1.get_capture(len(pkts))
1366 if not dont_translate:
1367 p = self.reass_frags_and_verify(frags,
1369 self.pg1.remote_ip4)
1371 p = self.reass_frags_and_verify(frags,
1372 self.pg0.remote_ip4,
1373 self.pg1.remote_ip4)
1374 if proto != IP_PROTOS.icmp:
1375 if not dont_translate:
1376 self.assertEqual(p[layer].dport, 20)
1377 self.assertNotEqual(p[layer].sport, self.port_in)
1379 self.assertEqual(p[layer].sport, self.port_in)
1381 if not dont_translate:
1382 self.assertNotEqual(p[layer].id, self.port_in)
1384 self.assertEqual(p[layer].id, self.port_in)
1385 self.assertEqual(data, p[Raw].load)
1388 if not dont_translate:
1389 dst_addr = self.nat_addr
1391 dst_addr = self.pg0.remote_ip4
1392 if proto != IP_PROTOS.icmp:
1394 dport = p[layer].sport
1398 pkts = self.create_stream_frag(self.pg1,
1406 self.pg1.add_stream(pkts)
1407 self.pg_enable_capture(self.pg_interfaces)
1409 frags = self.pg0.get_capture(len(pkts))
1410 p = self.reass_frags_and_verify(frags,
1411 self.pg1.remote_ip4,
1412 self.pg0.remote_ip4)
1413 if proto != IP_PROTOS.icmp:
1414 self.assertEqual(p[layer].sport, 20)
1415 self.assertEqual(p[layer].dport, self.port_in)
1417 self.assertEqual(p[layer].id, self.port_in)
1418 self.assertEqual(data, p[Raw].load)
1420 def frag_out_of_order_in_plus_out(self, proto=IP_PROTOS.tcp):
1421 layer = self.proto2layer(proto)
1423 if proto == IP_PROTOS.tcp:
1424 data = b"A" * 4 + b"B" * 16 + b"C" * 3
1426 data = b"A" * 16 + b"B" * 16 + b"C" * 3
1427 self.port_in = random.randint(1025, 65535)
1431 pkts = self.create_stream_frag(self.pg0,
1432 self.server_out_addr,
1434 self.server_out_port,
1438 self.pg0.add_stream(pkts)
1439 self.pg_enable_capture(self.pg_interfaces)
1441 frags = self.pg1.get_capture(len(pkts))
1442 p = self.reass_frags_and_verify(frags,
1443 self.pg0.remote_ip4,
1444 self.server_in_addr)
1445 if proto != IP_PROTOS.icmp:
1446 self.assertEqual(p[layer].dport, self.server_in_port)
1447 self.assertEqual(p[layer].sport, self.port_in)
1448 self.assertEqual(p[layer].dport, self.server_in_port)
1450 self.assertEqual(p[layer].id, self.port_in)
1451 self.assertEqual(data, p[Raw].load)
1454 if proto != IP_PROTOS.icmp:
1455 pkts = self.create_stream_frag(self.pg1,
1456 self.pg0.remote_ip4,
1457 self.server_in_port,
1462 pkts = self.create_stream_frag(self.pg1,
1463 self.pg0.remote_ip4,
1470 self.pg1.add_stream(pkts)
1471 self.pg_enable_capture(self.pg_interfaces)
1473 frags = self.pg0.get_capture(len(pkts))
1474 p = self.reass_frags_and_verify(frags,
1475 self.server_out_addr,
1476 self.pg0.remote_ip4)
1477 if proto != IP_PROTOS.icmp:
1478 self.assertEqual(p[layer].sport, self.server_out_port)
1479 self.assertEqual(p[layer].dport, self.port_in)
1481 self.assertEqual(p[layer].id, self.port_in)
1482 self.assertEqual(data, p[Raw].load)
1485 class TestNAT44(MethodHolder):
1486 """ NAT44 Test Cases """
1489 def setUpClass(cls):
1490 super(TestNAT44, cls).setUpClass()
1491 cls.vapi.cli("set log class nat level debug")
1494 cls.tcp_port_in = 6303
1495 cls.tcp_port_out = 6303
1496 cls.udp_port_in = 6304
1497 cls.udp_port_out = 6304
1498 cls.icmp_id_in = 6305
1499 cls.icmp_id_out = 6305
1500 cls.nat_addr = '10.0.0.3'
1501 cls.ipfix_src_port = 4739
1502 cls.ipfix_domain_id = 1
1503 cls.tcp_external_port = 80
1504 cls.udp_external_port = 69
1506 cls.create_pg_interfaces(range(10))
1507 cls.interfaces = list(cls.pg_interfaces[0:4])
1509 for i in cls.interfaces:
1514 cls.pg0.generate_remote_hosts(3)
1515 cls.pg0.configure_ipv4_neighbors()
1517 cls.pg1.generate_remote_hosts(1)
1518 cls.pg1.configure_ipv4_neighbors()
1520 cls.overlapping_interfaces = list(list(cls.pg_interfaces[4:7]))
1521 cls.vapi.ip_table_add_del(is_add=1, table_id=10)
1522 cls.vapi.ip_table_add_del(is_add=1, table_id=20)
1524 cls.pg4._local_ip4 = "172.16.255.1"
1525 cls.pg4._local_ip4n = socket.inet_pton(socket.AF_INET, i.local_ip4)
1526 cls.pg4._remote_hosts[0]._ip4 = "172.16.255.2"
1527 cls.pg4.set_table_ip4(10)
1528 cls.pg5._local_ip4 = "172.17.255.3"
1529 cls.pg5._local_ip4n = socket.inet_pton(socket.AF_INET, i.local_ip4)
1530 cls.pg5._remote_hosts[0]._ip4 = "172.17.255.4"
1531 cls.pg5.set_table_ip4(10)
1532 cls.pg6._local_ip4 = "172.16.255.1"
1533 cls.pg6._local_ip4n = socket.inet_pton(socket.AF_INET, i.local_ip4)
1534 cls.pg6._remote_hosts[0]._ip4 = "172.16.255.2"
1535 cls.pg6.set_table_ip4(20)
1536 for i in cls.overlapping_interfaces:
1544 cls.pg9.generate_remote_hosts(2)
1545 cls.pg9.config_ip4()
1546 ip_addr_n = socket.inet_pton(socket.AF_INET, "10.0.0.1")
1547 cls.vapi.sw_interface_add_del_address(
1548 sw_if_index=cls.pg9.sw_if_index, address=ip_addr_n,
1551 cls.pg9.resolve_arp()
1552 cls.pg9._remote_hosts[1]._ip4 = cls.pg9._remote_hosts[0]._ip4
1553 cls.pg4._remote_ip4 = cls.pg9._remote_hosts[0]._ip4 = "10.0.0.2"
1554 cls.pg9.resolve_arp()
1557 super(TestNAT44, cls).tearDownClass()
1561 def tearDownClass(cls):
1562 super(TestNAT44, cls).tearDownClass()
1564 def test_dynamic(self):
1565 """ NAT44 dynamic translation test """
1566 self.nat44_add_address(self.nat_addr)
1567 flags = self.config_flags.NAT_IS_INSIDE
1568 self.vapi.nat44_interface_add_del_feature(
1569 sw_if_index=self.pg0.sw_if_index,
1570 flags=flags, is_add=1)
1571 self.vapi.nat44_interface_add_del_feature(
1572 sw_if_index=self.pg1.sw_if_index,
1576 tcpn = self.statistics.get_counter(
1577 '/err/nat44-in2out-slowpath/TCP packets')
1578 udpn = self.statistics.get_counter(
1579 '/err/nat44-in2out-slowpath/UDP packets')
1580 icmpn = self.statistics.get_counter(
1581 '/err/nat44-in2out-slowpath/ICMP packets')
1582 totaln = self.statistics.get_counter(
1583 '/err/nat44-in2out-slowpath/good in2out packets processed')
1585 pkts = self.create_stream_in(self.pg0, self.pg1)
1586 self.pg0.add_stream(pkts)
1587 self.pg_enable_capture(self.pg_interfaces)
1589 capture = self.pg1.get_capture(len(pkts))
1590 self.verify_capture_out(capture)
1592 err = self.statistics.get_counter(
1593 '/err/nat44-in2out-slowpath/TCP packets')
1594 self.assertEqual(err - tcpn, 1)
1595 err = self.statistics.get_counter(
1596 '/err/nat44-in2out-slowpath/UDP packets')
1597 self.assertEqual(err - udpn, 1)
1598 err = self.statistics.get_counter(
1599 '/err/nat44-in2out-slowpath/ICMP packets')
1600 self.assertEqual(err - icmpn, 1)
1601 err = self.statistics.get_counter(
1602 '/err/nat44-in2out-slowpath/good in2out packets processed')
1603 self.assertEqual(err - totaln, 3)
1606 tcpn = self.statistics.get_counter('/err/nat44-out2in/TCP packets')
1607 udpn = self.statistics.get_counter('/err/nat44-out2in/UDP packets')
1608 icmpn = self.statistics.get_counter('/err/nat44-out2in/ICMP packets')
1609 totaln = self.statistics.get_counter(
1610 '/err/nat44-out2in/good out2in packets processed')
1612 pkts = self.create_stream_out(self.pg1)
1613 self.pg1.add_stream(pkts)
1614 self.pg_enable_capture(self.pg_interfaces)
1616 capture = self.pg0.get_capture(len(pkts))
1617 self.verify_capture_in(capture, self.pg0)
1619 err = self.statistics.get_counter('/err/nat44-out2in/TCP packets')
1620 self.assertEqual(err - tcpn, 1)
1621 err = self.statistics.get_counter('/err/nat44-out2in/UDP packets')
1622 self.assertEqual(err - udpn, 1)
1623 err = self.statistics.get_counter('/err/nat44-out2in/ICMP packets')
1624 self.assertEqual(err - icmpn, 1)
1625 err = self.statistics.get_counter(
1626 '/err/nat44-out2in/good out2in packets processed')
1627 self.assertEqual(err - totaln, 3)
1629 users = self.statistics.get_counter('/nat44/total-users')
1630 self.assertEqual(users[0][0], 1)
1631 sessions = self.statistics.get_counter('/nat44/total-sessions')
1632 self.assertEqual(sessions[0][0], 3)
1634 def test_dynamic_icmp_errors_in2out_ttl_1(self):
1635 """ NAT44 handling of client packets with TTL=1 """
1637 self.nat44_add_address(self.nat_addr)
1638 flags = self.config_flags.NAT_IS_INSIDE
1639 self.vapi.nat44_interface_add_del_feature(
1640 sw_if_index=self.pg0.sw_if_index,
1641 flags=flags, is_add=1)
1642 self.vapi.nat44_interface_add_del_feature(
1643 sw_if_index=self.pg1.sw_if_index,
1646 # Client side - generate traffic
1647 pkts = self.create_stream_in(self.pg0, self.pg1, ttl=1)
1648 self.pg0.add_stream(pkts)
1649 self.pg_enable_capture(self.pg_interfaces)
1652 # Client side - verify ICMP type 11 packets
1653 capture = self.pg0.get_capture(len(pkts))
1654 self.verify_capture_in_with_icmp_errors(capture, self.pg0)
1656 def test_dynamic_icmp_errors_out2in_ttl_1(self):
1657 """ NAT44 handling of server packets with TTL=1 """
1659 self.nat44_add_address(self.nat_addr)
1660 flags = self.config_flags.NAT_IS_INSIDE
1661 self.vapi.nat44_interface_add_del_feature(
1662 sw_if_index=self.pg0.sw_if_index,
1663 flags=flags, is_add=1)
1664 self.vapi.nat44_interface_add_del_feature(
1665 sw_if_index=self.pg1.sw_if_index,
1668 # Client side - create sessions
1669 pkts = self.create_stream_in(self.pg0, self.pg1)
1670 self.pg0.add_stream(pkts)
1671 self.pg_enable_capture(self.pg_interfaces)
1674 # Server side - generate traffic
1675 capture = self.pg1.get_capture(len(pkts))
1676 self.verify_capture_out(capture)
1677 pkts = self.create_stream_out(self.pg1, ttl=1)
1678 self.pg1.add_stream(pkts)
1679 self.pg_enable_capture(self.pg_interfaces)
1682 # Server side - verify ICMP type 11 packets
1683 capture = self.pg1.get_capture(len(pkts))
1684 self.verify_capture_out_with_icmp_errors(capture,
1685 src_ip=self.pg1.local_ip4)
1687 def test_dynamic_icmp_errors_in2out_ttl_2(self):
1688 """ NAT44 handling of error responses to client packets with TTL=2 """
1690 self.nat44_add_address(self.nat_addr)
1691 flags = self.config_flags.NAT_IS_INSIDE
1692 self.vapi.nat44_interface_add_del_feature(
1693 sw_if_index=self.pg0.sw_if_index,
1694 flags=flags, is_add=1)
1695 self.vapi.nat44_interface_add_del_feature(
1696 sw_if_index=self.pg1.sw_if_index,
1699 # Client side - generate traffic
1700 pkts = self.create_stream_in(self.pg0, self.pg1, ttl=2)
1701 self.pg0.add_stream(pkts)
1702 self.pg_enable_capture(self.pg_interfaces)
1705 # Server side - simulate ICMP type 11 response
1706 capture = self.pg1.get_capture(len(pkts))
1707 pkts = [Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
1708 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
1709 ICMP(type=11) / packet[IP] for packet in capture]
1710 self.pg1.add_stream(pkts)
1711 self.pg_enable_capture(self.pg_interfaces)
1714 # Client side - verify ICMP type 11 packets
1715 capture = self.pg0.get_capture(len(pkts))
1716 self.verify_capture_in_with_icmp_errors(capture, self.pg0)
1718 def test_dynamic_icmp_errors_out2in_ttl_2(self):
1719 """ NAT44 handling of error responses to server packets with TTL=2 """
1721 self.nat44_add_address(self.nat_addr)
1722 flags = self.config_flags.NAT_IS_INSIDE
1723 self.vapi.nat44_interface_add_del_feature(
1724 sw_if_index=self.pg0.sw_if_index,
1725 flags=flags, is_add=1)
1726 self.vapi.nat44_interface_add_del_feature(
1727 sw_if_index=self.pg1.sw_if_index,
1730 # Client side - create sessions
1731 pkts = self.create_stream_in(self.pg0, self.pg1)
1732 self.pg0.add_stream(pkts)
1733 self.pg_enable_capture(self.pg_interfaces)
1736 # Server side - generate traffic
1737 capture = self.pg1.get_capture(len(pkts))
1738 self.verify_capture_out(capture)
1739 pkts = self.create_stream_out(self.pg1, ttl=2)
1740 self.pg1.add_stream(pkts)
1741 self.pg_enable_capture(self.pg_interfaces)
1744 # Client side - simulate ICMP type 11 response
1745 capture = self.pg0.get_capture(len(pkts))
1746 pkts = [Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
1747 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
1748 ICMP(type=11) / packet[IP] for packet in capture]
1749 self.pg0.add_stream(pkts)
1750 self.pg_enable_capture(self.pg_interfaces)
1753 # Server side - verify ICMP type 11 packets
1754 capture = self.pg1.get_capture(len(pkts))
1755 self.verify_capture_out_with_icmp_errors(capture)
1757 def test_ping_out_interface_from_outside(self):
1758 """ Ping NAT44 out interface from outside network """
1760 self.nat44_add_address(self.nat_addr)
1761 flags = self.config_flags.NAT_IS_INSIDE
1762 self.vapi.nat44_interface_add_del_feature(
1763 sw_if_index=self.pg0.sw_if_index,
1764 flags=flags, is_add=1)
1765 self.vapi.nat44_interface_add_del_feature(
1766 sw_if_index=self.pg1.sw_if_index,
1769 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
1770 IP(src=self.pg1.remote_ip4, dst=self.pg1.local_ip4) /
1771 ICMP(id=self.icmp_id_out, type='echo-request'))
1773 self.pg1.add_stream(pkts)
1774 self.pg_enable_capture(self.pg_interfaces)
1776 capture = self.pg1.get_capture(len(pkts))
1779 self.assertEqual(packet[IP].src, self.pg1.local_ip4)
1780 self.assertEqual(packet[IP].dst, self.pg1.remote_ip4)
1781 self.assertEqual(packet[ICMP].id, self.icmp_id_in)
1782 self.assertEqual(packet[ICMP].type, 0) # echo reply
1784 self.logger.error(ppp("Unexpected or invalid packet "
1785 "(outside network):", packet))
1788 def test_ping_internal_host_from_outside(self):
1789 """ Ping internal host from outside network """
1791 self.nat44_add_static_mapping(self.pg0.remote_ip4, self.nat_addr)
1792 flags = self.config_flags.NAT_IS_INSIDE
1793 self.vapi.nat44_interface_add_del_feature(
1794 sw_if_index=self.pg0.sw_if_index,
1795 flags=flags, is_add=1)
1796 self.vapi.nat44_interface_add_del_feature(
1797 sw_if_index=self.pg1.sw_if_index,
1801 pkt = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
1802 IP(src=self.pg1.remote_ip4, dst=self.nat_addr, ttl=64) /
1803 ICMP(id=self.icmp_id_out, type='echo-request'))
1804 self.pg1.add_stream(pkt)
1805 self.pg_enable_capture(self.pg_interfaces)
1807 capture = self.pg0.get_capture(1)
1808 self.verify_capture_in(capture, self.pg0)
1809 self.assert_equal(capture[0][IP].proto, IP_PROTOS.icmp)
1812 pkt = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
1813 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4, ttl=64) /
1814 ICMP(id=self.icmp_id_in, type='echo-reply'))
1815 self.pg0.add_stream(pkt)
1816 self.pg_enable_capture(self.pg_interfaces)
1818 capture = self.pg1.get_capture(1)
1819 self.verify_capture_out(capture, same_port=True)
1820 self.assert_equal(capture[0][IP].proto, IP_PROTOS.icmp)
1822 def test_forwarding(self):
1823 """ NAT44 forwarding test """
1825 flags = self.config_flags.NAT_IS_INSIDE
1826 self.vapi.nat44_interface_add_del_feature(
1827 sw_if_index=self.pg0.sw_if_index,
1828 flags=flags, is_add=1)
1829 self.vapi.nat44_interface_add_del_feature(
1830 sw_if_index=self.pg1.sw_if_index,
1832 self.vapi.nat44_forwarding_enable_disable(enable=1)
1834 real_ip = self.pg0.remote_ip4n
1835 alias_ip = self.nat_addr
1836 flags = self.config_flags.NAT_IS_ADDR_ONLY
1837 self.vapi.nat44_add_del_static_mapping(is_add=1,
1838 local_ip_address=real_ip,
1839 external_ip_address=alias_ip,
1840 external_sw_if_index=0xFFFFFFFF,
1844 # static mapping match
1846 pkts = self.create_stream_out(self.pg1)
1847 self.pg1.add_stream(pkts)
1848 self.pg_enable_capture(self.pg_interfaces)
1850 capture = self.pg0.get_capture(len(pkts))
1851 self.verify_capture_in(capture, self.pg0)
1853 pkts = self.create_stream_in(self.pg0, self.pg1)
1854 self.pg0.add_stream(pkts)
1855 self.pg_enable_capture(self.pg_interfaces)
1857 capture = self.pg1.get_capture(len(pkts))
1858 self.verify_capture_out(capture, same_port=True)
1860 # no static mapping match
1862 host0 = self.pg0.remote_hosts[0]
1863 self.pg0.remote_hosts[0] = self.pg0.remote_hosts[1]
1865 pkts = self.create_stream_out(self.pg1,
1866 dst_ip=self.pg0.remote_ip4,
1867 use_inside_ports=True)
1868 self.pg1.add_stream(pkts)
1869 self.pg_enable_capture(self.pg_interfaces)
1871 capture = self.pg0.get_capture(len(pkts))
1872 self.verify_capture_in(capture, self.pg0)
1874 pkts = self.create_stream_in(self.pg0, self.pg1)
1875 self.pg0.add_stream(pkts)
1876 self.pg_enable_capture(self.pg_interfaces)
1878 capture = self.pg1.get_capture(len(pkts))
1879 self.verify_capture_out(capture, nat_ip=self.pg0.remote_ip4,
1882 self.pg0.remote_hosts[0] = host0
1885 self.vapi.nat44_forwarding_enable_disable(enable=0)
1886 flags = self.config_flags.NAT_IS_ADDR_ONLY
1887 self.vapi.nat44_add_del_static_mapping(
1889 local_ip_address=real_ip,
1890 external_ip_address=alias_ip,
1891 external_sw_if_index=0xFFFFFFFF,
1894 def test_static_in(self):
1895 """ 1:1 NAT initialized from inside network """
1897 nat_ip = "10.0.0.10"
1898 self.tcp_port_out = 6303
1899 self.udp_port_out = 6304
1900 self.icmp_id_out = 6305
1902 self.nat44_add_static_mapping(self.pg0.remote_ip4, nat_ip)
1903 flags = self.config_flags.NAT_IS_INSIDE
1904 self.vapi.nat44_interface_add_del_feature(
1905 sw_if_index=self.pg0.sw_if_index,
1906 flags=flags, is_add=1)
1907 self.vapi.nat44_interface_add_del_feature(
1908 sw_if_index=self.pg1.sw_if_index,
1910 sm = self.vapi.nat44_static_mapping_dump()
1911 self.assertEqual(len(sm), 1)
1912 self.assertEqual((sm[0].tag).split(b'\0', 1)[0], b'')
1913 self.assertEqual(sm[0].protocol, 0)
1914 self.assertEqual(sm[0].local_port, 0)
1915 self.assertEqual(sm[0].external_port, 0)
1918 pkts = self.create_stream_in(self.pg0, self.pg1)
1919 self.pg0.add_stream(pkts)
1920 self.pg_enable_capture(self.pg_interfaces)
1922 capture = self.pg1.get_capture(len(pkts))
1923 self.verify_capture_out(capture, nat_ip, True)
1926 pkts = self.create_stream_out(self.pg1, nat_ip)
1927 self.pg1.add_stream(pkts)
1928 self.pg_enable_capture(self.pg_interfaces)
1930 capture = self.pg0.get_capture(len(pkts))
1931 self.verify_capture_in(capture, self.pg0)
1933 def test_static_out(self):
1934 """ 1:1 NAT initialized from outside network """
1936 nat_ip = "10.0.0.20"
1937 self.tcp_port_out = 6303
1938 self.udp_port_out = 6304
1939 self.icmp_id_out = 6305
1942 self.nat44_add_static_mapping(self.pg0.remote_ip4, nat_ip, tag=tag)
1943 flags = self.config_flags.NAT_IS_INSIDE
1944 self.vapi.nat44_interface_add_del_feature(
1945 sw_if_index=self.pg0.sw_if_index,
1946 flags=flags, is_add=1)
1947 self.vapi.nat44_interface_add_del_feature(
1948 sw_if_index=self.pg1.sw_if_index,
1950 sm = self.vapi.nat44_static_mapping_dump()
1951 self.assertEqual(len(sm), 1)
1952 self.assertEqual((sm[0].tag).split(b'\0', 1)[0], tag)
1955 pkts = self.create_stream_out(self.pg1, nat_ip)
1956 self.pg1.add_stream(pkts)
1957 self.pg_enable_capture(self.pg_interfaces)
1959 capture = self.pg0.get_capture(len(pkts))
1960 self.verify_capture_in(capture, self.pg0)
1963 pkts = self.create_stream_in(self.pg0, self.pg1)
1964 self.pg0.add_stream(pkts)
1965 self.pg_enable_capture(self.pg_interfaces)
1967 capture = self.pg1.get_capture(len(pkts))
1968 self.verify_capture_out(capture, nat_ip, True)
1970 def test_static_with_port_in(self):
1971 """ 1:1 NAPT initialized from inside network """
1973 self.tcp_port_out = 3606
1974 self.udp_port_out = 3607
1975 self.icmp_id_out = 3608
1977 self.nat44_add_address(self.nat_addr)
1978 self.nat44_add_static_mapping(self.pg0.remote_ip4, self.nat_addr,
1979 self.tcp_port_in, self.tcp_port_out,
1980 proto=IP_PROTOS.tcp)
1981 self.nat44_add_static_mapping(self.pg0.remote_ip4, self.nat_addr,
1982 self.udp_port_in, self.udp_port_out,
1983 proto=IP_PROTOS.udp)
1984 self.nat44_add_static_mapping(self.pg0.remote_ip4, self.nat_addr,
1985 self.icmp_id_in, self.icmp_id_out,
1986 proto=IP_PROTOS.icmp)
1987 flags = self.config_flags.NAT_IS_INSIDE
1988 self.vapi.nat44_interface_add_del_feature(
1989 sw_if_index=self.pg0.sw_if_index,
1990 flags=flags, is_add=1)
1991 self.vapi.nat44_interface_add_del_feature(
1992 sw_if_index=self.pg1.sw_if_index,
1996 pkts = self.create_stream_in(self.pg0, self.pg1)
1997 self.pg0.add_stream(pkts)
1998 self.pg_enable_capture(self.pg_interfaces)
2000 capture = self.pg1.get_capture(len(pkts))
2001 self.verify_capture_out(capture)
2004 pkts = self.create_stream_out(self.pg1)
2005 self.pg1.add_stream(pkts)
2006 self.pg_enable_capture(self.pg_interfaces)
2008 capture = self.pg0.get_capture(len(pkts))
2009 self.verify_capture_in(capture, self.pg0)
2011 def test_static_with_port_out(self):
2012 """ 1:1 NAPT initialized from outside network """
2014 self.tcp_port_out = 30606
2015 self.udp_port_out = 30607
2016 self.icmp_id_out = 30608
2018 self.nat44_add_address(self.nat_addr)
2019 self.nat44_add_static_mapping(self.pg0.remote_ip4, self.nat_addr,
2020 self.tcp_port_in, self.tcp_port_out,
2021 proto=IP_PROTOS.tcp)
2022 self.nat44_add_static_mapping(self.pg0.remote_ip4, self.nat_addr,
2023 self.udp_port_in, self.udp_port_out,
2024 proto=IP_PROTOS.udp)
2025 self.nat44_add_static_mapping(self.pg0.remote_ip4, self.nat_addr,
2026 self.icmp_id_in, self.icmp_id_out,
2027 proto=IP_PROTOS.icmp)
2028 flags = self.config_flags.NAT_IS_INSIDE
2029 self.vapi.nat44_interface_add_del_feature(
2030 sw_if_index=self.pg0.sw_if_index,
2031 flags=flags, is_add=1)
2032 self.vapi.nat44_interface_add_del_feature(
2033 sw_if_index=self.pg1.sw_if_index,
2037 pkts = self.create_stream_out(self.pg1)
2038 self.pg1.add_stream(pkts)
2039 self.pg_enable_capture(self.pg_interfaces)
2041 capture = self.pg0.get_capture(len(pkts))
2042 self.verify_capture_in(capture, self.pg0)
2045 pkts = self.create_stream_in(self.pg0, self.pg1)
2046 self.pg0.add_stream(pkts)
2047 self.pg_enable_capture(self.pg_interfaces)
2049 capture = self.pg1.get_capture(len(pkts))
2050 self.verify_capture_out(capture)
2052 def test_static_vrf_aware(self):
2053 """ 1:1 NAT VRF awareness """
2055 nat_ip1 = "10.0.0.30"
2056 nat_ip2 = "10.0.0.40"
2057 self.tcp_port_out = 6303
2058 self.udp_port_out = 6304
2059 self.icmp_id_out = 6305
2061 self.nat44_add_static_mapping(self.pg4.remote_ip4, nat_ip1,
2063 self.nat44_add_static_mapping(self.pg0.remote_ip4, nat_ip2,
2065 flags = self.config_flags.NAT_IS_INSIDE
2066 self.vapi.nat44_interface_add_del_feature(
2067 sw_if_index=self.pg3.sw_if_index,
2069 self.vapi.nat44_interface_add_del_feature(
2070 sw_if_index=self.pg0.sw_if_index,
2071 flags=flags, is_add=1)
2072 self.vapi.nat44_interface_add_del_feature(
2073 sw_if_index=self.pg4.sw_if_index,
2074 flags=flags, is_add=1)
2076 # inside interface VRF match NAT44 static mapping VRF
2077 pkts = self.create_stream_in(self.pg4, self.pg3)
2078 self.pg4.add_stream(pkts)
2079 self.pg_enable_capture(self.pg_interfaces)
2081 capture = self.pg3.get_capture(len(pkts))
2082 self.verify_capture_out(capture, nat_ip1, True)
2084 # inside interface VRF don't match NAT44 static mapping VRF (packets
2086 pkts = self.create_stream_in(self.pg0, self.pg3)
2087 self.pg0.add_stream(pkts)
2088 self.pg_enable_capture(self.pg_interfaces)
2090 self.pg3.assert_nothing_captured()
2092 def test_dynamic_to_static(self):
2093 """ Switch from dynamic translation to 1:1NAT """
2094 nat_ip = "10.0.0.10"
2095 self.tcp_port_out = 6303
2096 self.udp_port_out = 6304
2097 self.icmp_id_out = 6305
2099 self.nat44_add_address(self.nat_addr)
2100 flags = self.config_flags.NAT_IS_INSIDE
2101 self.vapi.nat44_interface_add_del_feature(
2102 sw_if_index=self.pg0.sw_if_index,
2103 flags=flags, is_add=1)
2104 self.vapi.nat44_interface_add_del_feature(
2105 sw_if_index=self.pg1.sw_if_index,
2109 pkts = self.create_stream_in(self.pg0, self.pg1)
2110 self.pg0.add_stream(pkts)
2111 self.pg_enable_capture(self.pg_interfaces)
2113 capture = self.pg1.get_capture(len(pkts))
2114 self.verify_capture_out(capture)
2117 self.nat44_add_static_mapping(self.pg0.remote_ip4, nat_ip)
2118 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4n, 0)
2119 self.assertEqual(len(sessions), 0)
2120 pkts = self.create_stream_in(self.pg0, self.pg1)
2121 self.pg0.add_stream(pkts)
2122 self.pg_enable_capture(self.pg_interfaces)
2124 capture = self.pg1.get_capture(len(pkts))
2125 self.verify_capture_out(capture, nat_ip, True)
2127 def test_identity_nat(self):
2128 """ Identity NAT """
2129 flags = self.config_flags.NAT_IS_ADDR_ONLY
2130 self.vapi.nat44_add_del_identity_mapping(
2131 ip_address=self.pg0.remote_ip4n, sw_if_index=0xFFFFFFFF,
2132 flags=flags, is_add=1)
2133 flags = self.config_flags.NAT_IS_INSIDE
2134 self.vapi.nat44_interface_add_del_feature(
2135 sw_if_index=self.pg0.sw_if_index,
2136 flags=flags, is_add=1)
2137 self.vapi.nat44_interface_add_del_feature(
2138 sw_if_index=self.pg1.sw_if_index,
2141 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
2142 IP(src=self.pg1.remote_ip4, dst=self.pg0.remote_ip4) /
2143 TCP(sport=12345, dport=56789))
2144 self.pg1.add_stream(p)
2145 self.pg_enable_capture(self.pg_interfaces)
2147 capture = self.pg0.get_capture(1)
2152 self.assertEqual(ip.dst, self.pg0.remote_ip4)
2153 self.assertEqual(ip.src, self.pg1.remote_ip4)
2154 self.assertEqual(tcp.dport, 56789)
2155 self.assertEqual(tcp.sport, 12345)
2156 self.assert_packet_checksums_valid(p)
2158 self.logger.error(ppp("Unexpected or invalid packet:", p))
2161 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4n, 0)
2162 self.assertEqual(len(sessions), 0)
2163 flags = self.config_flags.NAT_IS_ADDR_ONLY
2164 self.vapi.nat44_add_del_identity_mapping(
2165 ip_address=self.pg0.remote_ip4n, sw_if_index=0xFFFFFFFF,
2166 flags=flags, vrf_id=1, is_add=1)
2167 identity_mappings = self.vapi.nat44_identity_mapping_dump()
2168 self.assertEqual(len(identity_mappings), 2)
2170 def test_multiple_inside_interfaces(self):
2171 """ NAT44 multiple non-overlapping address space inside interfaces """
2173 self.nat44_add_address(self.nat_addr)
2174 flags = self.config_flags.NAT_IS_INSIDE
2175 self.vapi.nat44_interface_add_del_feature(
2176 sw_if_index=self.pg0.sw_if_index,
2177 flags=flags, is_add=1)
2178 self.vapi.nat44_interface_add_del_feature(
2179 sw_if_index=self.pg1.sw_if_index,
2180 flags=flags, is_add=1)
2181 self.vapi.nat44_interface_add_del_feature(
2182 sw_if_index=self.pg3.sw_if_index,
2185 # between two NAT44 inside interfaces (no translation)
2186 pkts = self.create_stream_in(self.pg0, self.pg1)
2187 self.pg0.add_stream(pkts)
2188 self.pg_enable_capture(self.pg_interfaces)
2190 capture = self.pg1.get_capture(len(pkts))
2191 self.verify_capture_no_translation(capture, self.pg0, self.pg1)
2193 # from NAT44 inside to interface without NAT44 feature (no translation)
2194 pkts = self.create_stream_in(self.pg0, self.pg2)
2195 self.pg0.add_stream(pkts)
2196 self.pg_enable_capture(self.pg_interfaces)
2198 capture = self.pg2.get_capture(len(pkts))
2199 self.verify_capture_no_translation(capture, self.pg0, self.pg2)
2201 # in2out 1st interface
2202 pkts = self.create_stream_in(self.pg0, self.pg3)
2203 self.pg0.add_stream(pkts)
2204 self.pg_enable_capture(self.pg_interfaces)
2206 capture = self.pg3.get_capture(len(pkts))
2207 self.verify_capture_out(capture)
2209 # out2in 1st interface
2210 pkts = self.create_stream_out(self.pg3)
2211 self.pg3.add_stream(pkts)
2212 self.pg_enable_capture(self.pg_interfaces)
2214 capture = self.pg0.get_capture(len(pkts))
2215 self.verify_capture_in(capture, self.pg0)
2217 # in2out 2nd interface
2218 pkts = self.create_stream_in(self.pg1, self.pg3)
2219 self.pg1.add_stream(pkts)
2220 self.pg_enable_capture(self.pg_interfaces)
2222 capture = self.pg3.get_capture(len(pkts))
2223 self.verify_capture_out(capture)
2225 # out2in 2nd interface
2226 pkts = self.create_stream_out(self.pg3)
2227 self.pg3.add_stream(pkts)
2228 self.pg_enable_capture(self.pg_interfaces)
2230 capture = self.pg1.get_capture(len(pkts))
2231 self.verify_capture_in(capture, self.pg1)
2233 def test_inside_overlapping_interfaces(self):
2234 """ NAT44 multiple inside interfaces with overlapping address space """
2236 static_nat_ip = "10.0.0.10"
2237 self.nat44_add_address(self.nat_addr)
2238 flags = self.config_flags.NAT_IS_INSIDE
2239 self.vapi.nat44_interface_add_del_feature(
2240 sw_if_index=self.pg3.sw_if_index,
2242 self.vapi.nat44_interface_add_del_feature(
2243 sw_if_index=self.pg4.sw_if_index,
2244 flags=flags, is_add=1)
2245 self.vapi.nat44_interface_add_del_feature(
2246 sw_if_index=self.pg5.sw_if_index,
2247 flags=flags, is_add=1)
2248 self.vapi.nat44_interface_add_del_feature(
2249 sw_if_index=self.pg6.sw_if_index,
2250 flags=flags, is_add=1)
2251 self.nat44_add_static_mapping(self.pg6.remote_ip4, static_nat_ip,
2254 # between NAT44 inside interfaces with same VRF (no translation)
2255 pkts = self.create_stream_in(self.pg4, self.pg5)
2256 self.pg4.add_stream(pkts)
2257 self.pg_enable_capture(self.pg_interfaces)
2259 capture = self.pg5.get_capture(len(pkts))
2260 self.verify_capture_no_translation(capture, self.pg4, self.pg5)
2262 # between NAT44 inside interfaces with different VRF (hairpinning)
2263 p = (Ether(src=self.pg4.remote_mac, dst=self.pg4.local_mac) /
2264 IP(src=self.pg4.remote_ip4, dst=static_nat_ip) /
2265 TCP(sport=1234, dport=5678))
2266 self.pg4.add_stream(p)
2267 self.pg_enable_capture(self.pg_interfaces)
2269 capture = self.pg6.get_capture(1)
2274 self.assertEqual(ip.src, self.nat_addr)
2275 self.assertEqual(ip.dst, self.pg6.remote_ip4)
2276 self.assertNotEqual(tcp.sport, 1234)
2277 self.assertEqual(tcp.dport, 5678)
2279 self.logger.error(ppp("Unexpected or invalid packet:", p))
2282 # in2out 1st interface
2283 pkts = self.create_stream_in(self.pg4, self.pg3)
2284 self.pg4.add_stream(pkts)
2285 self.pg_enable_capture(self.pg_interfaces)
2287 capture = self.pg3.get_capture(len(pkts))
2288 self.verify_capture_out(capture)
2290 # out2in 1st interface
2291 pkts = self.create_stream_out(self.pg3)
2292 self.pg3.add_stream(pkts)
2293 self.pg_enable_capture(self.pg_interfaces)
2295 capture = self.pg4.get_capture(len(pkts))
2296 self.verify_capture_in(capture, self.pg4)
2298 # in2out 2nd interface
2299 pkts = self.create_stream_in(self.pg5, self.pg3)
2300 self.pg5.add_stream(pkts)
2301 self.pg_enable_capture(self.pg_interfaces)
2303 capture = self.pg3.get_capture(len(pkts))
2304 self.verify_capture_out(capture)
2306 # out2in 2nd interface
2307 pkts = self.create_stream_out(self.pg3)
2308 self.pg3.add_stream(pkts)
2309 self.pg_enable_capture(self.pg_interfaces)
2311 capture = self.pg5.get_capture(len(pkts))
2312 self.verify_capture_in(capture, self.pg5)
2315 addresses = self.vapi.nat44_address_dump()
2316 self.assertEqual(len(addresses), 1)
2317 sessions = self.vapi.nat44_user_session_dump(self.pg5.remote_ip4n, 10)
2318 self.assertEqual(len(sessions), 3)
2319 for session in sessions:
2320 self.assertFalse(session.flags & self.config_flags.NAT_IS_STATIC)
2321 self.assertEqual(str(session.inside_ip_address),
2322 self.pg5.remote_ip4)
2323 self.assertEqual(session.outside_ip_address,
2324 addresses[0].ip_address)
2325 self.assertEqual(sessions[0].protocol, IP_PROTOS.tcp)
2326 self.assertEqual(sessions[1].protocol, IP_PROTOS.udp)
2327 self.assertEqual(sessions[2].protocol, IP_PROTOS.icmp)
2328 self.assertEqual(sessions[0].inside_port, self.tcp_port_in)
2329 self.assertEqual(sessions[1].inside_port, self.udp_port_in)
2330 self.assertEqual(sessions[2].inside_port, self.icmp_id_in)
2331 self.assertEqual(sessions[0].outside_port, self.tcp_port_out)
2332 self.assertEqual(sessions[1].outside_port, self.udp_port_out)
2333 self.assertEqual(sessions[2].outside_port, self.icmp_id_out)
2335 # in2out 3rd interface
2336 pkts = self.create_stream_in(self.pg6, self.pg3)
2337 self.pg6.add_stream(pkts)
2338 self.pg_enable_capture(self.pg_interfaces)
2340 capture = self.pg3.get_capture(len(pkts))
2341 self.verify_capture_out(capture, static_nat_ip, True)
2343 # out2in 3rd interface
2344 pkts = self.create_stream_out(self.pg3, static_nat_ip)
2345 self.pg3.add_stream(pkts)
2346 self.pg_enable_capture(self.pg_interfaces)
2348 capture = self.pg6.get_capture(len(pkts))
2349 self.verify_capture_in(capture, self.pg6)
2351 # general user and session dump verifications
2352 users = self.vapi.nat44_user_dump()
2353 self.assertGreaterEqual(len(users), 3)
2354 addresses = self.vapi.nat44_address_dump()
2355 self.assertEqual(len(addresses), 1)
2357 sessions = self.vapi.nat44_user_session_dump(user.ip_address,
2359 for session in sessions:
2360 self.assertEqual(user.ip_address, session.inside_ip_address)
2361 self.assertTrue(session.total_bytes > session.total_pkts > 0)
2362 self.assertTrue(session.protocol in
2363 [IP_PROTOS.tcp, IP_PROTOS.udp,
2365 self.assertFalse(session.flags &
2366 self.config_flags.NAT_IS_EXT_HOST_VALID)
2369 sessions = self.vapi.nat44_user_session_dump(self.pg4.remote_ip4n, 10)
2370 self.assertGreaterEqual(len(sessions), 4)
2371 for session in sessions:
2372 self.assertFalse(session.flags & self.config_flags.NAT_IS_STATIC)
2373 self.assertEqual(str(session.inside_ip_address),
2374 self.pg4.remote_ip4)
2375 self.assertEqual(session.outside_ip_address,
2376 addresses[0].ip_address)
2379 sessions = self.vapi.nat44_user_session_dump(self.pg6.remote_ip4n, 20)
2380 self.assertGreaterEqual(len(sessions), 3)
2381 for session in sessions:
2382 self.assertTrue(session.flags & self.config_flags.NAT_IS_STATIC)
2383 self.assertEqual(str(session.inside_ip_address),
2384 self.pg6.remote_ip4)
2385 self.assertEqual(str(session.outside_ip_address),
2387 self.assertTrue(session.inside_port in
2388 [self.tcp_port_in, self.udp_port_in,
2391 def test_hairpinning(self):
2392 """ NAT44 hairpinning - 1:1 NAPT """
2394 host = self.pg0.remote_hosts[0]
2395 server = self.pg0.remote_hosts[1]
2398 server_in_port = 5678
2399 server_out_port = 8765
2401 self.nat44_add_address(self.nat_addr)
2402 flags = self.config_flags.NAT_IS_INSIDE
2403 self.vapi.nat44_interface_add_del_feature(
2404 sw_if_index=self.pg0.sw_if_index,
2405 flags=flags, is_add=1)
2406 self.vapi.nat44_interface_add_del_feature(
2407 sw_if_index=self.pg1.sw_if_index,
2410 # add static mapping for server
2411 self.nat44_add_static_mapping(server.ip4, self.nat_addr,
2412 server_in_port, server_out_port,
2413 proto=IP_PROTOS.tcp)
2415 # send packet from host to server
2416 p = (Ether(src=host.mac, dst=self.pg0.local_mac) /
2417 IP(src=host.ip4, dst=self.nat_addr) /
2418 TCP(sport=host_in_port, dport=server_out_port))
2419 self.pg0.add_stream(p)
2420 self.pg_enable_capture(self.pg_interfaces)
2422 capture = self.pg0.get_capture(1)
2427 self.assertEqual(ip.src, self.nat_addr)
2428 self.assertEqual(ip.dst, server.ip4)
2429 self.assertNotEqual(tcp.sport, host_in_port)
2430 self.assertEqual(tcp.dport, server_in_port)
2431 self.assert_packet_checksums_valid(p)
2432 host_out_port = tcp.sport
2434 self.logger.error(ppp("Unexpected or invalid packet:", p))
2437 # send reply from server to host
2438 p = (Ether(src=server.mac, dst=self.pg0.local_mac) /
2439 IP(src=server.ip4, dst=self.nat_addr) /
2440 TCP(sport=server_in_port, dport=host_out_port))
2441 self.pg0.add_stream(p)
2442 self.pg_enable_capture(self.pg_interfaces)
2444 capture = self.pg0.get_capture(1)
2449 self.assertEqual(ip.src, self.nat_addr)
2450 self.assertEqual(ip.dst, host.ip4)
2451 self.assertEqual(tcp.sport, server_out_port)
2452 self.assertEqual(tcp.dport, host_in_port)
2453 self.assert_packet_checksums_valid(p)
2455 self.logger.error(ppp("Unexpected or invalid packet:", p))
2458 def test_hairpinning2(self):
2459 """ NAT44 hairpinning - 1:1 NAT"""
2461 server1_nat_ip = "10.0.0.10"
2462 server2_nat_ip = "10.0.0.11"
2463 host = self.pg0.remote_hosts[0]
2464 server1 = self.pg0.remote_hosts[1]
2465 server2 = self.pg0.remote_hosts[2]
2466 server_tcp_port = 22
2467 server_udp_port = 20
2469 self.nat44_add_address(self.nat_addr)
2470 flags = self.config_flags.NAT_IS_INSIDE
2471 self.vapi.nat44_interface_add_del_feature(
2472 sw_if_index=self.pg0.sw_if_index,
2473 flags=flags, is_add=1)
2474 self.vapi.nat44_interface_add_del_feature(
2475 sw_if_index=self.pg1.sw_if_index,
2478 # add static mapping for servers
2479 self.nat44_add_static_mapping(server1.ip4, server1_nat_ip)
2480 self.nat44_add_static_mapping(server2.ip4, server2_nat_ip)
2484 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2485 IP(src=host.ip4, dst=server1_nat_ip) /
2486 TCP(sport=self.tcp_port_in, dport=server_tcp_port))
2488 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2489 IP(src=host.ip4, dst=server1_nat_ip) /
2490 UDP(sport=self.udp_port_in, dport=server_udp_port))
2492 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2493 IP(src=host.ip4, dst=server1_nat_ip) /
2494 ICMP(id=self.icmp_id_in, type='echo-request'))
2496 self.pg0.add_stream(pkts)
2497 self.pg_enable_capture(self.pg_interfaces)
2499 capture = self.pg0.get_capture(len(pkts))
2500 for packet in capture:
2502 self.assertEqual(packet[IP].src, self.nat_addr)
2503 self.assertEqual(packet[IP].dst, server1.ip4)
2504 if packet.haslayer(TCP):
2505 self.assertNotEqual(packet[TCP].sport, self.tcp_port_in)
2506 self.assertEqual(packet[TCP].dport, server_tcp_port)
2507 self.tcp_port_out = packet[TCP].sport
2508 self.assert_packet_checksums_valid(packet)
2509 elif packet.haslayer(UDP):
2510 self.assertNotEqual(packet[UDP].sport, self.udp_port_in)
2511 self.assertEqual(packet[UDP].dport, server_udp_port)
2512 self.udp_port_out = packet[UDP].sport
2514 self.assertNotEqual(packet[ICMP].id, self.icmp_id_in)
2515 self.icmp_id_out = packet[ICMP].id
2517 self.logger.error(ppp("Unexpected or invalid packet:", packet))
2522 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2523 IP(src=server1.ip4, dst=self.nat_addr) /
2524 TCP(sport=server_tcp_port, dport=self.tcp_port_out))
2526 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2527 IP(src=server1.ip4, dst=self.nat_addr) /
2528 UDP(sport=server_udp_port, dport=self.udp_port_out))
2530 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2531 IP(src=server1.ip4, dst=self.nat_addr) /
2532 ICMP(id=self.icmp_id_out, type='echo-reply'))
2534 self.pg0.add_stream(pkts)
2535 self.pg_enable_capture(self.pg_interfaces)
2537 capture = self.pg0.get_capture(len(pkts))
2538 for packet in capture:
2540 self.assertEqual(packet[IP].src, server1_nat_ip)
2541 self.assertEqual(packet[IP].dst, host.ip4)
2542 if packet.haslayer(TCP):
2543 self.assertEqual(packet[TCP].dport, self.tcp_port_in)
2544 self.assertEqual(packet[TCP].sport, server_tcp_port)
2545 self.assert_packet_checksums_valid(packet)
2546 elif packet.haslayer(UDP):
2547 self.assertEqual(packet[UDP].dport, self.udp_port_in)
2548 self.assertEqual(packet[UDP].sport, server_udp_port)
2550 self.assertEqual(packet[ICMP].id, self.icmp_id_in)
2552 self.logger.error(ppp("Unexpected or invalid packet:", packet))
2555 # server2 to server1
2557 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2558 IP(src=server2.ip4, dst=server1_nat_ip) /
2559 TCP(sport=self.tcp_port_in, dport=server_tcp_port))
2561 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2562 IP(src=server2.ip4, dst=server1_nat_ip) /
2563 UDP(sport=self.udp_port_in, dport=server_udp_port))
2565 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2566 IP(src=server2.ip4, dst=server1_nat_ip) /
2567 ICMP(id=self.icmp_id_in, type='echo-request'))
2569 self.pg0.add_stream(pkts)
2570 self.pg_enable_capture(self.pg_interfaces)
2572 capture = self.pg0.get_capture(len(pkts))
2573 for packet in capture:
2575 self.assertEqual(packet[IP].src, server2_nat_ip)
2576 self.assertEqual(packet[IP].dst, server1.ip4)
2577 if packet.haslayer(TCP):
2578 self.assertEqual(packet[TCP].sport, self.tcp_port_in)
2579 self.assertEqual(packet[TCP].dport, server_tcp_port)
2580 self.tcp_port_out = packet[TCP].sport
2581 self.assert_packet_checksums_valid(packet)
2582 elif packet.haslayer(UDP):
2583 self.assertEqual(packet[UDP].sport, self.udp_port_in)
2584 self.assertEqual(packet[UDP].dport, server_udp_port)
2585 self.udp_port_out = packet[UDP].sport
2587 self.assertEqual(packet[ICMP].id, self.icmp_id_in)
2588 self.icmp_id_out = packet[ICMP].id
2590 self.logger.error(ppp("Unexpected or invalid packet:", packet))
2593 # server1 to server2
2595 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2596 IP(src=server1.ip4, dst=server2_nat_ip) /
2597 TCP(sport=server_tcp_port, dport=self.tcp_port_out))
2599 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2600 IP(src=server1.ip4, dst=server2_nat_ip) /
2601 UDP(sport=server_udp_port, dport=self.udp_port_out))
2603 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2604 IP(src=server1.ip4, dst=server2_nat_ip) /
2605 ICMP(id=self.icmp_id_out, type='echo-reply'))
2607 self.pg0.add_stream(pkts)
2608 self.pg_enable_capture(self.pg_interfaces)
2610 capture = self.pg0.get_capture(len(pkts))
2611 for packet in capture:
2613 self.assertEqual(packet[IP].src, server1_nat_ip)
2614 self.assertEqual(packet[IP].dst, server2.ip4)
2615 if packet.haslayer(TCP):
2616 self.assertEqual(packet[TCP].dport, self.tcp_port_in)
2617 self.assertEqual(packet[TCP].sport, server_tcp_port)
2618 self.assert_packet_checksums_valid(packet)
2619 elif packet.haslayer(UDP):
2620 self.assertEqual(packet[UDP].dport, self.udp_port_in)
2621 self.assertEqual(packet[UDP].sport, server_udp_port)
2623 self.assertEqual(packet[ICMP].id, self.icmp_id_in)
2625 self.logger.error(ppp("Unexpected or invalid packet:", packet))
2628 def test_max_translations_per_user(self):
2629 """ MAX translations per user - recycle the least recently used """
2631 self.nat44_add_address(self.nat_addr)
2632 flags = self.config_flags.NAT_IS_INSIDE
2633 self.vapi.nat44_interface_add_del_feature(
2634 sw_if_index=self.pg0.sw_if_index,
2635 flags=flags, is_add=1)
2636 self.vapi.nat44_interface_add_del_feature(
2637 sw_if_index=self.pg1.sw_if_index,
2640 # get maximum number of translations per user
2641 nat44_config = self.vapi.nat_show_config()
2643 # send more than maximum number of translations per user packets
2644 pkts_num = nat44_config.max_translations_per_user + 5
2646 for port in range(0, pkts_num):
2647 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2648 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
2649 TCP(sport=1025 + port))
2651 self.pg0.add_stream(pkts)
2652 self.pg_enable_capture(self.pg_interfaces)
2655 # verify number of translated packet
2656 self.pg1.get_capture(pkts_num)
2658 users = self.vapi.nat44_user_dump()
2660 if user.ip_address == self.pg0.remote_ip4n:
2661 self.assertEqual(user.nsessions,
2662 nat44_config.max_translations_per_user)
2663 self.assertEqual(user.nstaticsessions, 0)
2666 self.nat44_add_static_mapping(self.pg0.remote_ip4, self.nat_addr,
2668 proto=IP_PROTOS.tcp)
2669 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2670 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
2671 TCP(sport=tcp_port))
2672 self.pg0.add_stream(p)
2673 self.pg_enable_capture(self.pg_interfaces)
2675 self.pg1.get_capture(1)
2676 users = self.vapi.nat44_user_dump()
2678 if user.ip_address == self.pg0.remote_ip4n:
2679 self.assertEqual(user.nsessions,
2680 nat44_config.max_translations_per_user - 1)
2681 self.assertEqual(user.nstaticsessions, 1)
2683 def test_interface_addr(self):
2684 """ Acquire NAT44 addresses from interface """
2685 self.vapi.nat44_add_del_interface_addr(
2687 sw_if_index=self.pg7.sw_if_index)
2689 # no address in NAT pool
2690 addresses = self.vapi.nat44_address_dump()
2691 self.assertEqual(0, len(addresses))
2693 # configure interface address and check NAT address pool
2694 self.pg7.config_ip4()
2695 addresses = self.vapi.nat44_address_dump()
2696 self.assertEqual(1, len(addresses))
2697 self.assertEqual(str(addresses[0].ip_address), self.pg7.local_ip4)
2699 # remove interface address and check NAT address pool
2700 self.pg7.unconfig_ip4()
2701 addresses = self.vapi.nat44_address_dump()
2702 self.assertEqual(0, len(addresses))
2704 def test_interface_addr_static_mapping(self):
2705 """ Static mapping with addresses from interface """
2708 self.vapi.nat44_add_del_interface_addr(
2710 sw_if_index=self.pg7.sw_if_index)
2711 self.nat44_add_static_mapping(
2713 external_sw_if_index=self.pg7.sw_if_index,
2716 # static mappings with external interface
2717 static_mappings = self.vapi.nat44_static_mapping_dump()
2718 self.assertEqual(1, len(static_mappings))
2719 self.assertEqual(self.pg7.sw_if_index,
2720 static_mappings[0].external_sw_if_index)
2721 self.assertEqual((static_mappings[0].tag).split(b'\0', 1)[0], tag)
2723 # configure interface address and check static mappings
2724 self.pg7.config_ip4()
2725 static_mappings = self.vapi.nat44_static_mapping_dump()
2726 self.assertEqual(2, len(static_mappings))
2728 for sm in static_mappings:
2729 if sm.external_sw_if_index == 0xFFFFFFFF:
2730 self.assertEqual(str(sm.external_ip_address),
2732 self.assertEqual((sm.tag).split(b'\0', 1)[0], tag)
2734 self.assertTrue(resolved)
2736 # remove interface address and check static mappings
2737 self.pg7.unconfig_ip4()
2738 static_mappings = self.vapi.nat44_static_mapping_dump()
2739 self.assertEqual(1, len(static_mappings))
2740 self.assertEqual(self.pg7.sw_if_index,
2741 static_mappings[0].external_sw_if_index)
2742 self.assertEqual((static_mappings[0].tag).split(b'\0', 1)[0], tag)
2744 # configure interface address again and check static mappings
2745 self.pg7.config_ip4()
2746 static_mappings = self.vapi.nat44_static_mapping_dump()
2747 self.assertEqual(2, len(static_mappings))
2749 for sm in static_mappings:
2750 if sm.external_sw_if_index == 0xFFFFFFFF:
2751 self.assertEqual(str(sm.external_ip_address),
2753 self.assertEqual((sm.tag).split(b'\0', 1)[0], tag)
2755 self.assertTrue(resolved)
2757 # remove static mapping
2758 self.nat44_add_static_mapping(
2760 external_sw_if_index=self.pg7.sw_if_index,
2763 static_mappings = self.vapi.nat44_static_mapping_dump()
2764 self.assertEqual(0, len(static_mappings))
2766 def test_interface_addr_identity_nat(self):
2767 """ Identity NAT with addresses from interface """
2770 self.vapi.nat44_add_del_interface_addr(
2772 sw_if_index=self.pg7.sw_if_index)
2773 self.vapi.nat44_add_del_identity_mapping(
2775 sw_if_index=self.pg7.sw_if_index,
2777 protocol=IP_PROTOS.tcp,
2780 # identity mappings with external interface
2781 identity_mappings = self.vapi.nat44_identity_mapping_dump()
2782 self.assertEqual(1, len(identity_mappings))
2783 self.assertEqual(self.pg7.sw_if_index,
2784 identity_mappings[0].sw_if_index)
2786 # configure interface address and check identity mappings
2787 self.pg7.config_ip4()
2788 identity_mappings = self.vapi.nat44_identity_mapping_dump()
2790 self.assertEqual(2, len(identity_mappings))
2791 for sm in identity_mappings:
2792 if sm.sw_if_index == 0xFFFFFFFF:
2793 self.assertEqual(str(identity_mappings[0].ip_address),
2795 self.assertEqual(port, identity_mappings[0].port)
2796 self.assertEqual(IP_PROTOS.tcp, identity_mappings[0].protocol)
2798 self.assertTrue(resolved)
2800 # remove interface address and check identity mappings
2801 self.pg7.unconfig_ip4()
2802 identity_mappings = self.vapi.nat44_identity_mapping_dump()
2803 self.assertEqual(1, len(identity_mappings))
2804 self.assertEqual(self.pg7.sw_if_index,
2805 identity_mappings[0].sw_if_index)
2807 def test_ipfix_nat44_sess(self):
2808 """ IPFIX logging NAT44 session created/deleted """
2809 self.ipfix_domain_id = 10
2810 self.ipfix_src_port = 20202
2811 collector_port = 30303
2812 bind_layers(UDP, IPFIX, dport=30303)
2813 self.nat44_add_address(self.nat_addr)
2814 flags = self.config_flags.NAT_IS_INSIDE
2815 self.vapi.nat44_interface_add_del_feature(
2816 sw_if_index=self.pg0.sw_if_index,
2817 flags=flags, is_add=1)
2818 self.vapi.nat44_interface_add_del_feature(
2819 sw_if_index=self.pg1.sw_if_index,
2821 self.vapi.set_ipfix_exporter(collector_address=self.pg3.remote_ip4n,
2822 src_address=self.pg3.local_ip4n,
2824 template_interval=10,
2825 collector_port=collector_port)
2826 self.vapi.nat_ipfix_enable_disable(domain_id=self.ipfix_domain_id,
2827 src_port=self.ipfix_src_port,
2830 pkts = self.create_stream_in(self.pg0, self.pg1)
2831 self.pg0.add_stream(pkts)
2832 self.pg_enable_capture(self.pg_interfaces)
2834 capture = self.pg1.get_capture(len(pkts))
2835 self.verify_capture_out(capture)
2836 self.nat44_add_address(self.nat_addr, is_add=0)
2837 self.vapi.cli("ipfix flush") # FIXME this should be an API call
2838 capture = self.pg3.get_capture(9)
2839 ipfix = IPFIXDecoder()
2840 # first load template
2842 self.assertTrue(p.haslayer(IPFIX))
2843 self.assertEqual(p[IP].src, self.pg3.local_ip4)
2844 self.assertEqual(p[IP].dst, self.pg3.remote_ip4)
2845 self.assertEqual(p[UDP].sport, self.ipfix_src_port)
2846 self.assertEqual(p[UDP].dport, collector_port)
2847 self.assertEqual(p[IPFIX].observationDomainID,
2848 self.ipfix_domain_id)
2849 if p.haslayer(Template):
2850 ipfix.add_template(p.getlayer(Template))
2851 # verify events in data set
2853 if p.haslayer(Data):
2854 data = ipfix.decode_data_set(p.getlayer(Set))
2855 self.verify_ipfix_nat44_ses(data)
2857 def test_ipfix_addr_exhausted(self):
2858 """ IPFIX logging NAT addresses exhausted """
2859 flags = self.config_flags.NAT_IS_INSIDE
2860 self.vapi.nat44_interface_add_del_feature(
2861 sw_if_index=self.pg0.sw_if_index,
2862 flags=flags, is_add=1)
2863 self.vapi.nat44_interface_add_del_feature(
2864 sw_if_index=self.pg1.sw_if_index,
2866 self.vapi.set_ipfix_exporter(collector_address=self.pg3.remote_ip4n,
2867 src_address=self.pg3.local_ip4n,
2869 template_interval=10)
2870 self.vapi.nat_ipfix_enable_disable(domain_id=self.ipfix_domain_id,
2871 src_port=self.ipfix_src_port,
2874 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
2875 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
2877 self.pg0.add_stream(p)
2878 self.pg_enable_capture(self.pg_interfaces)
2880 self.pg1.assert_nothing_captured()
2882 self.vapi.cli("ipfix flush") # FIXME this should be an API call
2883 capture = self.pg3.get_capture(9)
2884 ipfix = IPFIXDecoder()
2885 # first load template
2887 self.assertTrue(p.haslayer(IPFIX))
2888 self.assertEqual(p[IP].src, self.pg3.local_ip4)
2889 self.assertEqual(p[IP].dst, self.pg3.remote_ip4)
2890 self.assertEqual(p[UDP].sport, self.ipfix_src_port)
2891 self.assertEqual(p[UDP].dport, 4739)
2892 self.assertEqual(p[IPFIX].observationDomainID,
2893 self.ipfix_domain_id)
2894 if p.haslayer(Template):
2895 ipfix.add_template(p.getlayer(Template))
2896 # verify events in data set
2898 if p.haslayer(Data):
2899 data = ipfix.decode_data_set(p.getlayer(Set))
2900 self.verify_ipfix_addr_exhausted(data)
2902 @unittest.skipUnless(running_extended_tests, "part of extended tests")
2903 def test_ipfix_max_sessions(self):
2904 """ IPFIX logging maximum session entries exceeded """
2905 self.nat44_add_address(self.nat_addr)
2906 flags = self.config_flags.NAT_IS_INSIDE
2907 self.vapi.nat44_interface_add_del_feature(
2908 sw_if_index=self.pg0.sw_if_index,
2909 flags=flags, is_add=1)
2910 self.vapi.nat44_interface_add_del_feature(
2911 sw_if_index=self.pg1.sw_if_index,
2914 nat44_config = self.vapi.nat_show_config()
2915 max_sessions = 10 * nat44_config.translation_buckets
2918 for i in range(0, max_sessions):
2919 src = "10.10.%u.%u" % ((i & 0xFF00) >> 8, i & 0xFF)
2920 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2921 IP(src=src, dst=self.pg1.remote_ip4) /
2924 self.pg0.add_stream(pkts)
2925 self.pg_enable_capture(self.pg_interfaces)
2928 self.pg1.get_capture(max_sessions)
2929 self.vapi.set_ipfix_exporter(collector_address=self.pg3.remote_ip4n,
2930 src_address=self.pg3.local_ip4n,
2932 template_interval=10)
2933 self.vapi.nat_ipfix_enable_disable(domain_id=self.ipfix_domain_id,
2934 src_port=self.ipfix_src_port,
2937 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2938 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
2940 self.pg0.add_stream(p)
2941 self.pg_enable_capture(self.pg_interfaces)
2943 self.pg1.assert_nothing_captured()
2945 self.vapi.cli("ipfix flush") # FIXME this should be an API call
2946 capture = self.pg3.get_capture(9)
2947 ipfix = IPFIXDecoder()
2948 # first load template
2950 self.assertTrue(p.haslayer(IPFIX))
2951 self.assertEqual(p[IP].src, self.pg3.local_ip4)
2952 self.assertEqual(p[IP].dst, self.pg3.remote_ip4)
2953 self.assertEqual(p[UDP].sport, self.ipfix_src_port)
2954 self.assertEqual(p[UDP].dport, 4739)
2955 self.assertEqual(p[IPFIX].observationDomainID,
2956 self.ipfix_domain_id)
2957 if p.haslayer(Template):
2958 ipfix.add_template(p.getlayer(Template))
2959 # verify events in data set
2961 if p.haslayer(Data):
2962 data = ipfix.decode_data_set(p.getlayer(Set))
2963 self.verify_ipfix_max_sessions(data, max_sessions)
2965 def test_syslog_apmap(self):
2966 """ Test syslog address and port mapping creation and deletion """
2967 self.vapi.syslog_set_filter(SYSLOG_SEVERITY.INFO)
2968 self.vapi.syslog_set_sender(self.pg3.local_ip4n, self.pg3.remote_ip4n)
2969 self.nat44_add_address(self.nat_addr)
2970 flags = self.config_flags.NAT_IS_INSIDE
2971 self.vapi.nat44_interface_add_del_feature(
2972 sw_if_index=self.pg0.sw_if_index,
2973 flags=flags, is_add=1)
2974 self.vapi.nat44_interface_add_del_feature(
2975 sw_if_index=self.pg1.sw_if_index,
2978 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2979 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
2980 TCP(sport=self.tcp_port_in, dport=20))
2981 self.pg0.add_stream(p)
2982 self.pg_enable_capture(self.pg_interfaces)
2984 capture = self.pg1.get_capture(1)
2985 self.tcp_port_out = capture[0][TCP].sport
2986 capture = self.pg3.get_capture(1)
2987 self.verify_syslog_apmap(capture[0][Raw].load)
2989 self.pg_enable_capture(self.pg_interfaces)
2991 self.nat44_add_address(self.nat_addr, is_add=0)
2992 capture = self.pg3.get_capture(1)
2993 self.verify_syslog_apmap(capture[0][Raw].load, False)
2995 def test_pool_addr_fib(self):
2996 """ NAT44 add pool addresses to FIB """
2997 static_addr = '10.0.0.10'
2998 self.nat44_add_address(self.nat_addr)
2999 flags = self.config_flags.NAT_IS_INSIDE
3000 self.vapi.nat44_interface_add_del_feature(
3001 sw_if_index=self.pg0.sw_if_index,
3002 flags=flags, is_add=1)
3003 self.vapi.nat44_interface_add_del_feature(
3004 sw_if_index=self.pg1.sw_if_index,
3006 self.nat44_add_static_mapping(self.pg0.remote_ip4, static_addr)
3009 p = (Ether(src=self.pg1.remote_mac, dst='ff:ff:ff:ff:ff:ff') /
3010 ARP(op=ARP.who_has, pdst=self.nat_addr,
3011 psrc=self.pg1.remote_ip4, hwsrc=self.pg1.remote_mac))
3012 self.pg1.add_stream(p)
3013 self.pg_enable_capture(self.pg_interfaces)
3015 capture = self.pg1.get_capture(1)
3016 self.assertTrue(capture[0].haslayer(ARP))
3017 self.assertTrue(capture[0][ARP].op, ARP.is_at)
3020 p = (Ether(src=self.pg1.remote_mac, dst='ff:ff:ff:ff:ff:ff') /
3021 ARP(op=ARP.who_has, pdst=static_addr,
3022 psrc=self.pg1.remote_ip4, hwsrc=self.pg1.remote_mac))
3023 self.pg1.add_stream(p)
3024 self.pg_enable_capture(self.pg_interfaces)
3026 capture = self.pg1.get_capture(1)
3027 self.assertTrue(capture[0].haslayer(ARP))
3028 self.assertTrue(capture[0][ARP].op, ARP.is_at)
3030 # send ARP to non-NAT44 interface
3031 p = (Ether(src=self.pg2.remote_mac, dst='ff:ff:ff:ff:ff:ff') /
3032 ARP(op=ARP.who_has, pdst=self.nat_addr,
3033 psrc=self.pg2.remote_ip4, hwsrc=self.pg2.remote_mac))
3034 self.pg2.add_stream(p)
3035 self.pg_enable_capture(self.pg_interfaces)
3037 self.pg1.assert_nothing_captured()
3039 # remove addresses and verify
3040 self.nat44_add_address(self.nat_addr, is_add=0)
3041 self.nat44_add_static_mapping(self.pg0.remote_ip4, static_addr,
3044 p = (Ether(src=self.pg1.remote_mac, dst='ff:ff:ff:ff:ff:ff') /
3045 ARP(op=ARP.who_has, pdst=self.nat_addr,
3046 psrc=self.pg1.remote_ip4, hwsrc=self.pg1.remote_mac))
3047 self.pg1.add_stream(p)
3048 self.pg_enable_capture(self.pg_interfaces)
3050 self.pg1.assert_nothing_captured()
3052 p = (Ether(src=self.pg1.remote_mac, dst='ff:ff:ff:ff:ff:ff') /
3053 ARP(op=ARP.who_has, pdst=static_addr,
3054 psrc=self.pg1.remote_ip4, hwsrc=self.pg1.remote_mac))
3055 self.pg1.add_stream(p)
3056 self.pg_enable_capture(self.pg_interfaces)
3058 self.pg1.assert_nothing_captured()
3060 def test_vrf_mode(self):
3061 """ NAT44 tenant VRF aware address pool mode """
3065 nat_ip1 = "10.0.0.10"
3066 nat_ip2 = "10.0.0.11"
3068 self.pg0.unconfig_ip4()
3069 self.pg1.unconfig_ip4()
3070 self.vapi.ip_table_add_del(is_add=1, table_id=vrf_id1)
3071 self.vapi.ip_table_add_del(is_add=1, table_id=vrf_id2)
3072 self.pg0.set_table_ip4(vrf_id1)
3073 self.pg1.set_table_ip4(vrf_id2)
3074 self.pg0.config_ip4()
3075 self.pg1.config_ip4()
3076 self.pg0.resolve_arp()
3077 self.pg1.resolve_arp()
3079 self.nat44_add_address(nat_ip1, vrf_id=vrf_id1)
3080 self.nat44_add_address(nat_ip2, vrf_id=vrf_id2)
3081 flags = self.config_flags.NAT_IS_INSIDE
3082 self.vapi.nat44_interface_add_del_feature(
3083 sw_if_index=self.pg0.sw_if_index,
3084 flags=flags, is_add=1)
3085 self.vapi.nat44_interface_add_del_feature(
3086 sw_if_index=self.pg1.sw_if_index,
3087 flags=flags, is_add=1)
3088 self.vapi.nat44_interface_add_del_feature(
3089 sw_if_index=self.pg2.sw_if_index,
3094 pkts = self.create_stream_in(self.pg0, self.pg2)
3095 self.pg0.add_stream(pkts)
3096 self.pg_enable_capture(self.pg_interfaces)
3098 capture = self.pg2.get_capture(len(pkts))
3099 self.verify_capture_out(capture, nat_ip1)
3102 pkts = self.create_stream_in(self.pg1, self.pg2)
3103 self.pg1.add_stream(pkts)
3104 self.pg_enable_capture(self.pg_interfaces)
3106 capture = self.pg2.get_capture(len(pkts))
3107 self.verify_capture_out(capture, nat_ip2)
3110 self.pg0.unconfig_ip4()
3111 self.pg1.unconfig_ip4()
3112 self.pg0.set_table_ip4(0)
3113 self.pg1.set_table_ip4(0)
3114 self.pg0.config_ip4()
3115 self.pg1.config_ip4()
3116 self.pg0.resolve_arp()
3117 self.pg1.resolve_arp()
3118 self.vapi.ip_table_add_del(is_add=0, table_id=vrf_id1)
3119 self.vapi.ip_table_add_del(is_add=0, table_id=vrf_id2)
3121 def test_vrf_feature_independent(self):
3122 """ NAT44 tenant VRF independent address pool mode """
3124 nat_ip1 = "10.0.0.10"
3125 nat_ip2 = "10.0.0.11"
3127 self.nat44_add_address(nat_ip1)
3128 self.nat44_add_address(nat_ip2, vrf_id=99)
3129 flags = self.config_flags.NAT_IS_INSIDE
3130 self.vapi.nat44_interface_add_del_feature(
3131 sw_if_index=self.pg0.sw_if_index,
3132 flags=flags, is_add=1)
3133 self.vapi.nat44_interface_add_del_feature(
3134 sw_if_index=self.pg1.sw_if_index,
3135 flags=flags, is_add=1)
3136 self.vapi.nat44_interface_add_del_feature(
3137 sw_if_index=self.pg2.sw_if_index,
3141 pkts = self.create_stream_in(self.pg0, self.pg2)
3142 self.pg0.add_stream(pkts)
3143 self.pg_enable_capture(self.pg_interfaces)
3145 capture = self.pg2.get_capture(len(pkts))
3146 self.verify_capture_out(capture, nat_ip1)
3149 pkts = self.create_stream_in(self.pg1, self.pg2)
3150 self.pg1.add_stream(pkts)
3151 self.pg_enable_capture(self.pg_interfaces)
3153 capture = self.pg2.get_capture(len(pkts))
3154 self.verify_capture_out(capture, nat_ip1)
3156 def test_dynamic_ipless_interfaces(self):
3157 """ NAT44 interfaces without configured IP address """
3159 self.vapi.ip_neighbor_add_del(
3160 self.pg7.sw_if_index,
3161 self.pg7.remote_mac,
3162 self.pg7.remote_ip4,
3163 flags=(VppEnum.vl_api_ip_neighbor_flags_t.
3164 IP_API_NEIGHBOR_FLAG_STATIC))
3165 self.vapi.ip_neighbor_add_del(
3166 self.pg8.sw_if_index,
3167 self.pg8.remote_mac,
3168 self.pg8.remote_ip4,
3169 flags=(VppEnum.vl_api_ip_neighbor_flags_t.
3170 IP_API_NEIGHBOR_FLAG_STATIC))
3172 self.vapi.ip_add_del_route(dst_address=self.pg7.remote_ip4n,
3173 dst_address_length=32,
3174 next_hop_address=self.pg7.remote_ip4n,
3175 next_hop_sw_if_index=self.pg7.sw_if_index)
3176 self.vapi.ip_add_del_route(dst_address=self.pg8.remote_ip4n,
3177 dst_address_length=32,
3178 next_hop_address=self.pg8.remote_ip4n,
3179 next_hop_sw_if_index=self.pg8.sw_if_index)
3181 self.nat44_add_address(self.nat_addr)
3182 flags = self.config_flags.NAT_IS_INSIDE
3183 self.vapi.nat44_interface_add_del_feature(
3184 sw_if_index=self.pg7.sw_if_index,
3185 flags=flags, is_add=1)
3186 self.vapi.nat44_interface_add_del_feature(
3187 sw_if_index=self.pg8.sw_if_index,
3191 pkts = self.create_stream_in(self.pg7, self.pg8)
3192 self.pg7.add_stream(pkts)
3193 self.pg_enable_capture(self.pg_interfaces)
3195 capture = self.pg8.get_capture(len(pkts))
3196 self.verify_capture_out(capture)
3199 pkts = self.create_stream_out(self.pg8, self.nat_addr)
3200 self.pg8.add_stream(pkts)
3201 self.pg_enable_capture(self.pg_interfaces)
3203 capture = self.pg7.get_capture(len(pkts))
3204 self.verify_capture_in(capture, self.pg7)
3206 def test_static_ipless_interfaces(self):
3207 """ NAT44 interfaces without configured IP address - 1:1 NAT """
3209 self.vapi.ip_neighbor_add_del(
3210 self.pg7.sw_if_index,
3211 self.pg7.remote_mac,
3212 self.pg7.remote_ip4,
3213 flags=(VppEnum.vl_api_ip_neighbor_flags_t.
3214 IP_API_NEIGHBOR_FLAG_STATIC))
3215 self.vapi.ip_neighbor_add_del(
3216 self.pg8.sw_if_index,
3217 self.pg8.remote_mac,
3218 self.pg8.remote_ip4,
3219 flags=(VppEnum.vl_api_ip_neighbor_flags_t.
3220 IP_API_NEIGHBOR_FLAG_STATIC))
3222 self.vapi.ip_add_del_route(dst_address=self.pg7.remote_ip4n,
3223 dst_address_length=32,
3224 next_hop_address=self.pg7.remote_ip4n,
3225 next_hop_sw_if_index=self.pg7.sw_if_index)
3226 self.vapi.ip_add_del_route(dst_address=self.pg8.remote_ip4n,
3227 dst_address_length=32,
3228 next_hop_address=self.pg8.remote_ip4n,
3229 next_hop_sw_if_index=self.pg8.sw_if_index)
3231 self.nat44_add_static_mapping(self.pg7.remote_ip4, self.nat_addr)
3232 flags = self.config_flags.NAT_IS_INSIDE
3233 self.vapi.nat44_interface_add_del_feature(
3234 sw_if_index=self.pg7.sw_if_index,
3235 flags=flags, is_add=1)
3236 self.vapi.nat44_interface_add_del_feature(
3237 sw_if_index=self.pg8.sw_if_index,
3241 pkts = self.create_stream_out(self.pg8)
3242 self.pg8.add_stream(pkts)
3243 self.pg_enable_capture(self.pg_interfaces)
3245 capture = self.pg7.get_capture(len(pkts))
3246 self.verify_capture_in(capture, self.pg7)
3249 pkts = self.create_stream_in(self.pg7, self.pg8)
3250 self.pg7.add_stream(pkts)
3251 self.pg_enable_capture(self.pg_interfaces)
3253 capture = self.pg8.get_capture(len(pkts))
3254 self.verify_capture_out(capture, self.nat_addr, True)
3256 def test_static_with_port_ipless_interfaces(self):
3257 """ NAT44 interfaces without configured IP address - 1:1 NAPT """
3259 self.tcp_port_out = 30606
3260 self.udp_port_out = 30607
3261 self.icmp_id_out = 30608
3263 self.vapi.ip_neighbor_add_del(
3264 self.pg7.sw_if_index,
3265 self.pg7.remote_mac,
3266 self.pg7.remote_ip4,
3267 flags=(VppEnum.vl_api_ip_neighbor_flags_t.
3268 IP_API_NEIGHBOR_FLAG_STATIC))
3269 self.vapi.ip_neighbor_add_del(
3270 self.pg8.sw_if_index,
3271 self.pg8.remote_mac,
3272 self.pg8.remote_ip4,
3273 flags=(VppEnum.vl_api_ip_neighbor_flags_t.
3274 IP_API_NEIGHBOR_FLAG_STATIC))
3276 self.vapi.ip_add_del_route(dst_address=self.pg7.remote_ip4n,
3277 dst_address_length=32,
3278 next_hop_address=self.pg7.remote_ip4n,
3279 next_hop_sw_if_index=self.pg7.sw_if_index)
3280 self.vapi.ip_add_del_route(dst_address=self.pg8.remote_ip4n,
3281 dst_address_length=32,
3282 next_hop_address=self.pg8.remote_ip4n,
3283 next_hop_sw_if_index=self.pg8.sw_if_index)
3285 self.nat44_add_address(self.nat_addr)
3286 self.nat44_add_static_mapping(self.pg7.remote_ip4, self.nat_addr,
3287 self.tcp_port_in, self.tcp_port_out,
3288 proto=IP_PROTOS.tcp)
3289 self.nat44_add_static_mapping(self.pg7.remote_ip4, self.nat_addr,
3290 self.udp_port_in, self.udp_port_out,
3291 proto=IP_PROTOS.udp)
3292 self.nat44_add_static_mapping(self.pg7.remote_ip4, self.nat_addr,
3293 self.icmp_id_in, self.icmp_id_out,
3294 proto=IP_PROTOS.icmp)
3295 flags = self.config_flags.NAT_IS_INSIDE
3296 self.vapi.nat44_interface_add_del_feature(
3297 sw_if_index=self.pg7.sw_if_index,
3298 flags=flags, is_add=1)
3299 self.vapi.nat44_interface_add_del_feature(
3300 sw_if_index=self.pg8.sw_if_index,
3304 pkts = self.create_stream_out(self.pg8)
3305 self.pg8.add_stream(pkts)
3306 self.pg_enable_capture(self.pg_interfaces)
3308 capture = self.pg7.get_capture(len(pkts))
3309 self.verify_capture_in(capture, self.pg7)
3312 pkts = self.create_stream_in(self.pg7, self.pg8)
3313 self.pg7.add_stream(pkts)
3314 self.pg_enable_capture(self.pg_interfaces)
3316 capture = self.pg8.get_capture(len(pkts))
3317 self.verify_capture_out(capture)
3319 def test_static_unknown_proto(self):
3320 """ 1:1 NAT translate packet with unknown protocol """
3321 nat_ip = "10.0.0.10"
3322 self.nat44_add_static_mapping(self.pg0.remote_ip4, nat_ip)
3323 flags = self.config_flags.NAT_IS_INSIDE
3324 self.vapi.nat44_interface_add_del_feature(
3325 sw_if_index=self.pg0.sw_if_index,
3326 flags=flags, is_add=1)
3327 self.vapi.nat44_interface_add_del_feature(
3328 sw_if_index=self.pg1.sw_if_index,
3332 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
3333 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
3335 IP(src=self.pg2.remote_ip4, dst=self.pg3.remote_ip4) /
3336 TCP(sport=1234, dport=1234))
3337 self.pg0.add_stream(p)
3338 self.pg_enable_capture(self.pg_interfaces)
3340 p = self.pg1.get_capture(1)
3343 self.assertEqual(packet[IP].src, nat_ip)
3344 self.assertEqual(packet[IP].dst, self.pg1.remote_ip4)
3345 self.assertEqual(packet.haslayer(GRE), 1)
3346 self.assert_packet_checksums_valid(packet)
3348 self.logger.error(ppp("Unexpected or invalid packet:", packet))
3352 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
3353 IP(src=self.pg1.remote_ip4, dst=nat_ip) /
3355 IP(src=self.pg3.remote_ip4, dst=self.pg2.remote_ip4) /
3356 TCP(sport=1234, dport=1234))
3357 self.pg1.add_stream(p)
3358 self.pg_enable_capture(self.pg_interfaces)
3360 p = self.pg0.get_capture(1)
3363 self.assertEqual(packet[IP].src, self.pg1.remote_ip4)
3364 self.assertEqual(packet[IP].dst, self.pg0.remote_ip4)
3365 self.assertEqual(packet.haslayer(GRE), 1)
3366 self.assert_packet_checksums_valid(packet)
3368 self.logger.error(ppp("Unexpected or invalid packet:", packet))
3371 def test_hairpinning_static_unknown_proto(self):
3372 """ 1:1 NAT translate packet with unknown protocol - hairpinning """
3374 host = self.pg0.remote_hosts[0]
3375 server = self.pg0.remote_hosts[1]
3377 host_nat_ip = "10.0.0.10"
3378 server_nat_ip = "10.0.0.11"
3380 self.nat44_add_static_mapping(host.ip4, host_nat_ip)
3381 self.nat44_add_static_mapping(server.ip4, server_nat_ip)
3382 flags = self.config_flags.NAT_IS_INSIDE
3383 self.vapi.nat44_interface_add_del_feature(
3384 sw_if_index=self.pg0.sw_if_index,
3385 flags=flags, is_add=1)
3386 self.vapi.nat44_interface_add_del_feature(
3387 sw_if_index=self.pg1.sw_if_index,
3391 p = (Ether(dst=self.pg0.local_mac, src=host.mac) /
3392 IP(src=host.ip4, dst=server_nat_ip) /
3394 IP(src=self.pg2.remote_ip4, dst=self.pg3.remote_ip4) /
3395 TCP(sport=1234, dport=1234))
3396 self.pg0.add_stream(p)
3397 self.pg_enable_capture(self.pg_interfaces)
3399 p = self.pg0.get_capture(1)
3402 self.assertEqual(packet[IP].src, host_nat_ip)
3403 self.assertEqual(packet[IP].dst, server.ip4)
3404 self.assertEqual(packet.haslayer(GRE), 1)
3405 self.assert_packet_checksums_valid(packet)
3407 self.logger.error(ppp("Unexpected or invalid packet:", packet))
3411 p = (Ether(dst=self.pg0.local_mac, src=server.mac) /
3412 IP(src=server.ip4, dst=host_nat_ip) /
3414 IP(src=self.pg3.remote_ip4, dst=self.pg2.remote_ip4) /
3415 TCP(sport=1234, dport=1234))
3416 self.pg0.add_stream(p)
3417 self.pg_enable_capture(self.pg_interfaces)
3419 p = self.pg0.get_capture(1)
3422 self.assertEqual(packet[IP].src, server_nat_ip)
3423 self.assertEqual(packet[IP].dst, host.ip4)
3424 self.assertEqual(packet.haslayer(GRE), 1)
3425 self.assert_packet_checksums_valid(packet)
3427 self.logger.error(ppp("Unexpected or invalid packet:", packet))
3430 def test_output_feature(self):
3431 """ NAT44 interface output feature (in2out postrouting) """
3432 self.nat44_add_address(self.nat_addr)
3433 flags = self.config_flags.NAT_IS_INSIDE
3434 self.vapi.nat44_interface_add_del_output_feature(
3435 is_add=1, flags=flags,
3436 sw_if_index=self.pg0.sw_if_index)
3437 self.vapi.nat44_interface_add_del_output_feature(
3438 is_add=1, flags=flags,
3439 sw_if_index=self.pg1.sw_if_index)
3440 self.vapi.nat44_interface_add_del_output_feature(
3442 sw_if_index=self.pg3.sw_if_index)
3445 pkts = self.create_stream_in(self.pg0, self.pg3)
3446 self.pg0.add_stream(pkts)
3447 self.pg_enable_capture(self.pg_interfaces)
3449 capture = self.pg3.get_capture(len(pkts))
3450 self.verify_capture_out(capture)
3453 pkts = self.create_stream_out(self.pg3)
3454 self.pg3.add_stream(pkts)
3455 self.pg_enable_capture(self.pg_interfaces)
3457 capture = self.pg0.get_capture(len(pkts))
3458 self.verify_capture_in(capture, self.pg0)
3460 # from non-NAT interface to NAT inside interface
3461 pkts = self.create_stream_in(self.pg2, self.pg0)
3462 self.pg2.add_stream(pkts)
3463 self.pg_enable_capture(self.pg_interfaces)
3465 capture = self.pg0.get_capture(len(pkts))
3466 self.verify_capture_no_translation(capture, self.pg2, self.pg0)
3468 def test_output_feature_vrf_aware(self):
3469 """ NAT44 interface output feature VRF aware (in2out postrouting) """
3470 nat_ip_vrf10 = "10.0.0.10"
3471 nat_ip_vrf20 = "10.0.0.20"
3473 self.vapi.ip_add_del_route(dst_address=self.pg3.remote_ip4n,
3474 dst_address_length=32,
3475 next_hop_address=self.pg3.remote_ip4n,
3476 next_hop_sw_if_index=self.pg3.sw_if_index,
3478 self.vapi.ip_add_del_route(dst_address=self.pg3.remote_ip4n,
3479 dst_address_length=32,
3480 next_hop_address=self.pg3.remote_ip4n,
3481 next_hop_sw_if_index=self.pg3.sw_if_index,
3484 self.nat44_add_address(nat_ip_vrf10, vrf_id=10)
3485 self.nat44_add_address(nat_ip_vrf20, vrf_id=20)
3486 flags = self.config_flags.NAT_IS_INSIDE
3487 self.vapi.nat44_interface_add_del_output_feature(
3488 is_add=1, flags=flags,
3489 sw_if_index=self.pg4.sw_if_index)
3490 self.vapi.nat44_interface_add_del_output_feature(
3491 is_add=1, flags=flags,
3492 sw_if_index=self.pg6.sw_if_index)
3493 self.vapi.nat44_interface_add_del_output_feature(
3495 sw_if_index=self.pg3.sw_if_index)
3498 pkts = self.create_stream_in(self.pg4, self.pg3)
3499 self.pg4.add_stream(pkts)
3500 self.pg_enable_capture(self.pg_interfaces)
3502 capture = self.pg3.get_capture(len(pkts))
3503 self.verify_capture_out(capture, nat_ip=nat_ip_vrf10)
3506 pkts = self.create_stream_out(self.pg3, dst_ip=nat_ip_vrf10)
3507 self.pg3.add_stream(pkts)
3508 self.pg_enable_capture(self.pg_interfaces)
3510 capture = self.pg4.get_capture(len(pkts))
3511 self.verify_capture_in(capture, self.pg4)
3514 pkts = self.create_stream_in(self.pg6, self.pg3)
3515 self.pg6.add_stream(pkts)
3516 self.pg_enable_capture(self.pg_interfaces)
3518 capture = self.pg3.get_capture(len(pkts))
3519 self.verify_capture_out(capture, nat_ip=nat_ip_vrf20)
3522 pkts = self.create_stream_out(self.pg3, dst_ip=nat_ip_vrf20)
3523 self.pg3.add_stream(pkts)
3524 self.pg_enable_capture(self.pg_interfaces)
3526 capture = self.pg6.get_capture(len(pkts))
3527 self.verify_capture_in(capture, self.pg6)
3529 def test_output_feature_hairpinning(self):
3530 """ NAT44 interface output feature hairpinning (in2out postrouting) """
3531 host = self.pg0.remote_hosts[0]
3532 server = self.pg0.remote_hosts[1]
3535 server_in_port = 5678
3536 server_out_port = 8765
3538 self.nat44_add_address(self.nat_addr)
3539 flags = self.config_flags.NAT_IS_INSIDE
3540 self.vapi.nat44_interface_add_del_output_feature(
3541 is_add=1, flags=flags,
3542 sw_if_index=self.pg0.sw_if_index)
3543 self.vapi.nat44_interface_add_del_output_feature(
3545 sw_if_index=self.pg1.sw_if_index)
3547 # add static mapping for server
3548 self.nat44_add_static_mapping(server.ip4, self.nat_addr,
3549 server_in_port, server_out_port,
3550 proto=IP_PROTOS.tcp)
3552 # send packet from host to server
3553 p = (Ether(src=host.mac, dst=self.pg0.local_mac) /
3554 IP(src=host.ip4, dst=self.nat_addr) /
3555 TCP(sport=host_in_port, dport=server_out_port))
3556 self.pg0.add_stream(p)
3557 self.pg_enable_capture(self.pg_interfaces)
3559 capture = self.pg0.get_capture(1)
3564 self.assertEqual(ip.src, self.nat_addr)
3565 self.assertEqual(ip.dst, server.ip4)
3566 self.assertNotEqual(tcp.sport, host_in_port)
3567 self.assertEqual(tcp.dport, server_in_port)
3568 self.assert_packet_checksums_valid(p)
3569 host_out_port = tcp.sport
3571 self.logger.error(ppp("Unexpected or invalid packet:", p))
3574 # send reply from server to host
3575 p = (Ether(src=server.mac, dst=self.pg0.local_mac) /
3576 IP(src=server.ip4, dst=self.nat_addr) /
3577 TCP(sport=server_in_port, dport=host_out_port))
3578 self.pg0.add_stream(p)
3579 self.pg_enable_capture(self.pg_interfaces)
3581 capture = self.pg0.get_capture(1)
3586 self.assertEqual(ip.src, self.nat_addr)
3587 self.assertEqual(ip.dst, host.ip4)
3588 self.assertEqual(tcp.sport, server_out_port)
3589 self.assertEqual(tcp.dport, host_in_port)
3590 self.assert_packet_checksums_valid(p)
3592 self.logger.error(ppp("Unexpected or invalid packet:", p))
3595 def test_one_armed_nat44(self):
3596 """ One armed NAT44 """
3597 remote_host = self.pg9.remote_hosts[0]
3598 local_host = self.pg9.remote_hosts[1]
3601 self.nat44_add_address(self.nat_addr)
3602 flags = self.config_flags.NAT_IS_INSIDE
3603 self.vapi.nat44_interface_add_del_feature(
3604 sw_if_index=self.pg9.sw_if_index,
3606 self.vapi.nat44_interface_add_del_feature(
3607 sw_if_index=self.pg9.sw_if_index,
3608 flags=flags, is_add=1)
3611 p = (Ether(src=self.pg9.remote_mac, dst=self.pg9.local_mac) /
3612 IP(src=local_host.ip4, dst=remote_host.ip4) /
3613 TCP(sport=12345, dport=80))
3614 self.pg9.add_stream(p)
3615 self.pg_enable_capture(self.pg_interfaces)
3617 capture = self.pg9.get_capture(1)
3622 self.assertEqual(ip.src, self.nat_addr)
3623 self.assertEqual(ip.dst, remote_host.ip4)
3624 self.assertNotEqual(tcp.sport, 12345)
3625 external_port = tcp.sport
3626 self.assertEqual(tcp.dport, 80)
3627 self.assert_packet_checksums_valid(p)
3629 self.logger.error(ppp("Unexpected or invalid packet:", p))
3633 p = (Ether(src=self.pg9.remote_mac, dst=self.pg9.local_mac) /
3634 IP(src=remote_host.ip4, dst=self.nat_addr) /
3635 TCP(sport=80, dport=external_port))
3636 self.pg9.add_stream(p)
3637 self.pg_enable_capture(self.pg_interfaces)
3639 capture = self.pg9.get_capture(1)
3644 self.assertEqual(ip.src, remote_host.ip4)
3645 self.assertEqual(ip.dst, local_host.ip4)
3646 self.assertEqual(tcp.sport, 80)
3647 self.assertEqual(tcp.dport, 12345)
3648 self.assert_packet_checksums_valid(p)
3650 self.logger.error(ppp("Unexpected or invalid packet:", p))
3653 err = self.statistics.get_counter('/err/nat44-classify/next in2out')
3654 self.assertEqual(err, 1)
3655 err = self.statistics.get_counter('/err/nat44-classify/next out2in')
3656 self.assertEqual(err, 1)
3658 def test_del_session(self):
3659 """ Delete NAT44 session """
3660 self.nat44_add_address(self.nat_addr)
3661 flags = self.config_flags.NAT_IS_INSIDE
3662 self.vapi.nat44_interface_add_del_feature(
3663 sw_if_index=self.pg0.sw_if_index,
3664 flags=flags, is_add=1)
3665 self.vapi.nat44_interface_add_del_feature(
3666 sw_if_index=self.pg1.sw_if_index,
3669 pkts = self.create_stream_in(self.pg0, self.pg1)
3670 self.pg0.add_stream(pkts)
3671 self.pg_enable_capture(self.pg_interfaces)
3673 self.pg1.get_capture(len(pkts))
3675 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4n, 0)
3676 nsessions = len(sessions)
3678 self.vapi.nat44_del_session(address=sessions[0].inside_ip_address,
3679 port=sessions[0].inside_port,
3680 protocol=sessions[0].protocol,
3681 flags=self.config_flags.NAT_IS_INSIDE)
3682 self.vapi.nat44_del_session(address=sessions[1].outside_ip_address,
3683 port=sessions[1].outside_port,
3684 protocol=sessions[1].protocol)
3686 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4n, 0)
3687 self.assertEqual(nsessions - len(sessions), 2)
3689 self.vapi.nat44_del_session(address=sessions[0].inside_ip_address,
3690 port=sessions[0].inside_port,
3691 protocol=sessions[0].protocol,
3692 flags=self.config_flags.NAT_IS_INSIDE)
3694 self.verify_no_nat44_user()
3696 def test_set_get_reass(self):
3697 """ NAT44 set/get virtual fragmentation reassembly """
3698 reas_cfg1 = self.vapi.nat_get_reass()
3700 self.vapi.nat_set_reass(timeout=reas_cfg1.ip4_timeout + 5,
3701 max_reass=reas_cfg1.ip4_max_reass * 2,
3702 max_frag=reas_cfg1.ip4_max_frag * 2,
3705 reas_cfg2 = self.vapi.nat_get_reass()
3707 self.assertEqual(reas_cfg1.ip4_timeout + 5, reas_cfg2.ip4_timeout)
3708 self.assertEqual(reas_cfg1.ip4_max_reass * 2, reas_cfg2.ip4_max_reass)
3709 self.assertEqual(reas_cfg1.ip4_max_frag * 2, reas_cfg2.ip4_max_frag)
3711 self.vapi.nat_set_reass(timeout=2, max_reass=1024, max_frag=5,
3713 self.assertTrue(self.vapi.nat_get_reass().ip4_drop_frag)
3715 def test_frag_in_order(self):
3716 """ NAT44 translate fragments arriving in order """
3718 self.nat44_add_address(self.nat_addr)
3719 flags = self.config_flags.NAT_IS_INSIDE
3720 self.vapi.nat44_interface_add_del_feature(
3721 sw_if_index=self.pg0.sw_if_index,
3722 flags=flags, is_add=1)
3723 self.vapi.nat44_interface_add_del_feature(
3724 sw_if_index=self.pg1.sw_if_index,
3727 self.frag_in_order(proto=IP_PROTOS.tcp)
3728 self.frag_in_order(proto=IP_PROTOS.udp)
3729 self.frag_in_order(proto=IP_PROTOS.icmp)
3731 def test_frag_forwarding(self):
3732 """ NAT44 forwarding fragment test """
3733 self.vapi.nat44_add_del_interface_addr(
3735 sw_if_index=self.pg1.sw_if_index)
3736 flags = self.config_flags.NAT_IS_INSIDE
3737 self.vapi.nat44_interface_add_del_feature(
3738 sw_if_index=self.pg0.sw_if_index,
3739 flags=flags, is_add=1)
3740 self.vapi.nat44_interface_add_del_feature(
3741 sw_if_index=self.pg1.sw_if_index,
3743 self.vapi.nat44_forwarding_enable_disable(enable=1)
3745 data = b"A" * 16 + b"B" * 16 + b"C" * 3
3746 pkts = self.create_stream_frag(self.pg1,
3747 self.pg0.remote_ip4,
3751 proto=IP_PROTOS.udp)
3752 self.pg1.add_stream(pkts)
3753 self.pg_enable_capture(self.pg_interfaces)
3755 frags = self.pg0.get_capture(len(pkts))
3756 p = self.reass_frags_and_verify(frags,
3757 self.pg1.remote_ip4,
3758 self.pg0.remote_ip4)
3759 self.assertEqual(p[UDP].sport, 4789)
3760 self.assertEqual(p[UDP].dport, 4789)
3761 self.assertEqual(data, p[Raw].load)
3763 def test_reass_hairpinning(self):
3764 """ NAT44 fragments hairpinning """
3766 self.server = self.pg0.remote_hosts[1]
3767 self.host_in_port = random.randint(1025, 65535)
3768 self.server_in_port = random.randint(1025, 65535)
3769 self.server_out_port = random.randint(1025, 65535)
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 # add static mapping for server
3780 self.nat44_add_static_mapping(self.server.ip4, self.nat_addr,
3781 self.server_in_port,
3782 self.server_out_port,
3783 proto=IP_PROTOS.tcp)
3784 self.nat44_add_static_mapping(self.server.ip4, self.nat_addr,
3785 self.server_in_port,
3786 self.server_out_port,
3787 proto=IP_PROTOS.udp)
3788 self.nat44_add_static_mapping(self.server.ip4, self.nat_addr)
3790 self.reass_hairpinning(proto=IP_PROTOS.tcp)
3791 self.reass_hairpinning(proto=IP_PROTOS.udp)
3792 self.reass_hairpinning(proto=IP_PROTOS.icmp)
3794 def test_frag_out_of_order(self):
3795 """ NAT44 translate fragments arriving out of order """
3797 self.nat44_add_address(self.nat_addr)
3798 flags = self.config_flags.NAT_IS_INSIDE
3799 self.vapi.nat44_interface_add_del_feature(
3800 sw_if_index=self.pg0.sw_if_index,
3801 flags=flags, is_add=1)
3802 self.vapi.nat44_interface_add_del_feature(
3803 sw_if_index=self.pg1.sw_if_index,
3806 self.frag_out_of_order(proto=IP_PROTOS.tcp)
3807 self.frag_out_of_order(proto=IP_PROTOS.udp)
3808 self.frag_out_of_order(proto=IP_PROTOS.icmp)
3810 def test_port_restricted(self):
3811 """ Port restricted NAT44 (MAP-E CE) """
3812 self.nat44_add_address(self.nat_addr)
3813 flags = self.config_flags.NAT_IS_INSIDE
3814 self.vapi.nat44_interface_add_del_feature(
3815 sw_if_index=self.pg0.sw_if_index,
3816 flags=flags, is_add=1)
3817 self.vapi.nat44_interface_add_del_feature(
3818 sw_if_index=self.pg1.sw_if_index,
3820 self.vapi.nat_set_addr_and_port_alloc_alg(alg=1,
3825 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
3826 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
3827 TCP(sport=4567, dport=22))
3828 self.pg0.add_stream(p)
3829 self.pg_enable_capture(self.pg_interfaces)
3831 capture = self.pg1.get_capture(1)
3836 self.assertEqual(ip.dst, self.pg1.remote_ip4)
3837 self.assertEqual(ip.src, self.nat_addr)
3838 self.assertEqual(tcp.dport, 22)
3839 self.assertNotEqual(tcp.sport, 4567)
3840 self.assertEqual((tcp.sport >> 6) & 63, 10)
3841 self.assert_packet_checksums_valid(p)
3843 self.logger.error(ppp("Unexpected or invalid packet:", p))
3846 def test_port_range(self):
3847 """ External address port range """
3848 self.nat44_add_address(self.nat_addr)
3849 flags = self.config_flags.NAT_IS_INSIDE
3850 self.vapi.nat44_interface_add_del_feature(
3851 sw_if_index=self.pg0.sw_if_index,
3852 flags=flags, is_add=1)
3853 self.vapi.nat44_interface_add_del_feature(
3854 sw_if_index=self.pg1.sw_if_index,
3856 self.vapi.nat_set_addr_and_port_alloc_alg(alg=2,
3861 for port in range(0, 5):
3862 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
3863 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
3864 TCP(sport=1125 + port))
3866 self.pg0.add_stream(pkts)
3867 self.pg_enable_capture(self.pg_interfaces)
3869 capture = self.pg1.get_capture(3)
3872 self.assertGreaterEqual(tcp.sport, 1025)
3873 self.assertLessEqual(tcp.sport, 1027)
3875 def test_ipfix_max_frags(self):
3876 """ IPFIX logging maximum fragments pending reassembly exceeded """
3877 self.nat44_add_address(self.nat_addr)
3878 flags = self.config_flags.NAT_IS_INSIDE
3879 self.vapi.nat44_interface_add_del_feature(
3880 sw_if_index=self.pg0.sw_if_index,
3881 flags=flags, is_add=1)
3882 self.vapi.nat44_interface_add_del_feature(
3883 sw_if_index=self.pg1.sw_if_index,
3885 self.vapi.nat_set_reass(timeout=2, max_reass=1024, max_frag=1,
3887 self.vapi.set_ipfix_exporter(collector_address=self.pg3.remote_ip4n,
3888 src_address=self.pg3.local_ip4n,
3890 template_interval=10)
3891 self.vapi.nat_ipfix_enable_disable(domain_id=self.ipfix_domain_id,
3892 src_port=self.ipfix_src_port,
3895 data = b"A" * 4 + b"B" * 16 + b"C" * 3
3896 self.tcp_port_in = random.randint(1025, 65535)
3897 pkts = self.create_stream_frag(self.pg0,
3898 self.pg1.remote_ip4,
3903 self.pg0.add_stream(pkts)
3904 self.pg_enable_capture(self.pg_interfaces)
3906 self.pg1.assert_nothing_captured()
3908 self.vapi.cli("ipfix flush") # FIXME this should be an API call
3909 capture = self.pg3.get_capture(9)
3910 ipfix = IPFIXDecoder()
3911 # first load template
3913 self.assertTrue(p.haslayer(IPFIX))
3914 self.assertEqual(p[IP].src, self.pg3.local_ip4)
3915 self.assertEqual(p[IP].dst, self.pg3.remote_ip4)
3916 self.assertEqual(p[UDP].sport, self.ipfix_src_port)
3917 self.assertEqual(p[UDP].dport, 4739)
3918 self.assertEqual(p[IPFIX].observationDomainID,
3919 self.ipfix_domain_id)
3920 if p.haslayer(Template):
3921 ipfix.add_template(p.getlayer(Template))
3922 # verify events in data set
3924 if p.haslayer(Data):
3925 data = ipfix.decode_data_set(p.getlayer(Set))
3926 self.verify_ipfix_max_fragments_ip4(data, 1,
3927 self.pg0.remote_ip4n)
3929 def test_multiple_outside_vrf(self):
3930 """ Multiple outside VRF """
3934 self.pg1.unconfig_ip4()
3935 self.pg2.unconfig_ip4()
3936 self.vapi.ip_table_add_del(is_add=1, table_id=vrf_id1)
3937 self.vapi.ip_table_add_del(is_add=1, table_id=vrf_id2)
3938 self.pg1.set_table_ip4(vrf_id1)
3939 self.pg2.set_table_ip4(vrf_id2)
3940 self.pg1.config_ip4()
3941 self.pg2.config_ip4()
3942 self.pg1.resolve_arp()
3943 self.pg2.resolve_arp()
3945 self.nat44_add_address(self.nat_addr)
3946 flags = self.config_flags.NAT_IS_INSIDE
3947 self.vapi.nat44_interface_add_del_feature(
3948 sw_if_index=self.pg0.sw_if_index,
3949 flags=flags, is_add=1)
3950 self.vapi.nat44_interface_add_del_feature(
3951 sw_if_index=self.pg1.sw_if_index,
3953 self.vapi.nat44_interface_add_del_feature(
3954 sw_if_index=self.pg2.sw_if_index,
3959 pkts = self.create_stream_in(self.pg0, self.pg1)
3960 self.pg0.add_stream(pkts)
3961 self.pg_enable_capture(self.pg_interfaces)
3963 capture = self.pg1.get_capture(len(pkts))
3964 self.verify_capture_out(capture, self.nat_addr)
3966 pkts = self.create_stream_out(self.pg1, self.nat_addr)
3967 self.pg1.add_stream(pkts)
3968 self.pg_enable_capture(self.pg_interfaces)
3970 capture = self.pg0.get_capture(len(pkts))
3971 self.verify_capture_in(capture, self.pg0)
3973 self.tcp_port_in = 60303
3974 self.udp_port_in = 60304
3975 self.icmp_id_in = 60305
3978 pkts = self.create_stream_in(self.pg0, self.pg2)
3979 self.pg0.add_stream(pkts)
3980 self.pg_enable_capture(self.pg_interfaces)
3982 capture = self.pg2.get_capture(len(pkts))
3983 self.verify_capture_out(capture, self.nat_addr)
3985 pkts = self.create_stream_out(self.pg2, self.nat_addr)
3986 self.pg2.add_stream(pkts)
3987 self.pg_enable_capture(self.pg_interfaces)
3989 capture = self.pg0.get_capture(len(pkts))
3990 self.verify_capture_in(capture, self.pg0)
3993 self.pg1.unconfig_ip4()
3994 self.pg2.unconfig_ip4()
3995 self.pg1.set_table_ip4(0)
3996 self.pg2.set_table_ip4(0)
3997 self.pg1.config_ip4()
3998 self.pg2.config_ip4()
3999 self.pg1.resolve_arp()
4000 self.pg2.resolve_arp()
4002 @unittest.skipUnless(running_extended_tests, "part of extended tests")
4003 def test_session_timeout(self):
4004 """ NAT44 session timeouts """
4005 self.nat44_add_address(self.nat_addr)
4006 flags = self.config_flags.NAT_IS_INSIDE
4007 self.vapi.nat44_interface_add_del_feature(
4008 sw_if_index=self.pg0.sw_if_index,
4009 flags=flags, is_add=1)
4010 self.vapi.nat44_interface_add_del_feature(
4011 sw_if_index=self.pg1.sw_if_index,
4013 self.vapi.nat_set_timeouts(udp=5, tcp_established=7440,
4014 tcp_transitory=240, icmp=60)
4018 for i in range(0, max_sessions):
4019 src = "10.10.%u.%u" % ((i & 0xFF00) >> 8, i & 0xFF)
4020 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
4021 IP(src=src, dst=self.pg1.remote_ip4) /
4022 UDP(sport=1025, dport=53))
4024 self.pg0.add_stream(pkts)
4025 self.pg_enable_capture(self.pg_interfaces)
4027 self.pg1.get_capture(max_sessions)
4032 for i in range(0, max_sessions):
4033 src = "10.10.%u.%u" % ((i & 0xFF00) >> 8, i & 0xFF)
4034 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
4035 IP(src=src, dst=self.pg1.remote_ip4) /
4036 UDP(sport=1026, dport=53))
4038 self.pg0.add_stream(pkts)
4039 self.pg_enable_capture(self.pg_interfaces)
4041 self.pg1.get_capture(max_sessions)
4044 users = self.vapi.nat44_user_dump()
4046 nsessions = nsessions + user.nsessions
4047 self.assertLess(nsessions, 2 * max_sessions)
4049 def test_mss_clamping(self):
4050 """ TCP MSS clamping """
4051 self.nat44_add_address(self.nat_addr)
4052 flags = self.config_flags.NAT_IS_INSIDE
4053 self.vapi.nat44_interface_add_del_feature(
4054 sw_if_index=self.pg0.sw_if_index,
4055 flags=flags, is_add=1)
4056 self.vapi.nat44_interface_add_del_feature(
4057 sw_if_index=self.pg1.sw_if_index,
4060 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
4061 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
4062 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
4063 flags="S", options=[('MSS', 1400)]))
4065 self.vapi.nat_set_mss_clamping(enable=1, mss_value=1000)
4066 self.pg0.add_stream(p)
4067 self.pg_enable_capture(self.pg_interfaces)
4069 capture = self.pg1.get_capture(1)
4070 # Negotiated MSS value greater than configured - changed
4071 self.verify_mss_value(capture[0], 1000)
4073 self.vapi.nat_set_mss_clamping(enable=0, mss_value=1500)
4074 self.pg0.add_stream(p)
4075 self.pg_enable_capture(self.pg_interfaces)
4077 capture = self.pg1.get_capture(1)
4078 # MSS clamping disabled - negotiated MSS unchanged
4079 self.verify_mss_value(capture[0], 1400)
4081 self.vapi.nat_set_mss_clamping(enable=1, mss_value=1500)
4082 self.pg0.add_stream(p)
4083 self.pg_enable_capture(self.pg_interfaces)
4085 capture = self.pg1.get_capture(1)
4086 # Negotiated MSS value smaller than configured - unchanged
4087 self.verify_mss_value(capture[0], 1400)
4089 @unittest.skipUnless(running_extended_tests, "part of extended tests")
4090 def test_ha_send(self):
4091 """ Send HA session synchronization events (active) """
4092 self.nat44_add_address(self.nat_addr)
4093 flags = self.config_flags.NAT_IS_INSIDE
4094 self.vapi.nat44_interface_add_del_feature(
4095 sw_if_index=self.pg0.sw_if_index,
4096 flags=flags, is_add=1)
4097 self.vapi.nat44_interface_add_del_feature(
4098 sw_if_index=self.pg1.sw_if_index,
4100 self.vapi.nat_ha_set_listener(ip_address=self.pg3.local_ip4,
4103 self.vapi.nat_ha_set_failover(ip_address=self.pg3.remote_ip4,
4104 port=12346, session_refresh_interval=10)
4105 bind_layers(UDP, HANATStateSync, sport=12345)
4108 pkts = self.create_stream_in(self.pg0, self.pg1)
4109 self.pg0.add_stream(pkts)
4110 self.pg_enable_capture(self.pg_interfaces)
4112 capture = self.pg1.get_capture(len(pkts))
4113 self.verify_capture_out(capture)
4114 # active send HA events
4115 self.vapi.nat_ha_flush()
4116 stats = self.statistics.get_counter('/nat44/ha/add-event-send')
4117 self.assertEqual(stats[0][0], 3)
4118 capture = self.pg3.get_capture(1)
4120 self.assert_packet_checksums_valid(p)
4124 hanat = p[HANATStateSync]
4126 self.logger.error(ppp("Invalid packet:", p))
4129 self.assertEqual(ip.src, self.pg3.local_ip4)
4130 self.assertEqual(ip.dst, self.pg3.remote_ip4)
4131 self.assertEqual(udp.sport, 12345)
4132 self.assertEqual(udp.dport, 12346)
4133 self.assertEqual(hanat.version, 1)
4134 self.assertEqual(hanat.thread_index, 0)
4135 self.assertEqual(hanat.count, 3)
4136 seq = hanat.sequence_number
4137 for event in hanat.events:
4138 self.assertEqual(event.event_type, 1)
4139 self.assertEqual(event.in_addr, self.pg0.remote_ip4)
4140 self.assertEqual(event.out_addr, self.nat_addr)
4141 self.assertEqual(event.fib_index, 0)
4143 # ACK received events
4144 ack = (Ether(dst=self.pg3.local_mac, src=self.pg3.remote_mac) /
4145 IP(src=self.pg3.remote_ip4, dst=self.pg3.local_ip4) /
4146 UDP(sport=12346, dport=12345) /
4147 HANATStateSync(sequence_number=seq, flags='ACK'))
4148 self.pg3.add_stream(ack)
4150 stats = self.statistics.get_counter('/nat44/ha/ack-recv')
4151 self.assertEqual(stats[0][0], 1)
4153 # delete one session
4154 self.pg_enable_capture(self.pg_interfaces)
4155 self.vapi.nat44_del_session(address=self.pg0.remote_ip4n,
4156 port=self.tcp_port_in,
4157 protocol=IP_PROTOS.tcp,
4158 flags=self.config_flags.NAT_IS_INSIDE)
4159 self.vapi.nat_ha_flush()
4160 stats = self.statistics.get_counter('/nat44/ha/del-event-send')
4161 self.assertEqual(stats[0][0], 1)
4162 capture = self.pg3.get_capture(1)
4165 hanat = p[HANATStateSync]
4167 self.logger.error(ppp("Invalid packet:", p))
4170 self.assertGreater(hanat.sequence_number, seq)
4172 # do not send ACK, active retry send HA event again
4173 self.pg_enable_capture(self.pg_interfaces)
4175 stats = self.statistics.get_counter('/nat44/ha/retry-count')
4176 self.assertEqual(stats[0][0], 3)
4177 stats = self.statistics.get_counter('/nat44/ha/missed-count')
4178 self.assertEqual(stats[0][0], 1)
4179 capture = self.pg3.get_capture(3)
4180 for packet in capture:
4181 self.assertEqual(packet, p)
4183 # session counters refresh
4184 pkts = self.create_stream_out(self.pg1)
4185 self.pg1.add_stream(pkts)
4186 self.pg_enable_capture(self.pg_interfaces)
4188 self.pg0.get_capture(2)
4189 self.vapi.nat_ha_flush()
4190 stats = self.statistics.get_counter('/nat44/ha/refresh-event-send')
4191 self.assertEqual(stats[0][0], 2)
4192 capture = self.pg3.get_capture(1)
4194 self.assert_packet_checksums_valid(p)
4198 hanat = p[HANATStateSync]
4200 self.logger.error(ppp("Invalid packet:", p))
4203 self.assertEqual(ip.src, self.pg3.local_ip4)
4204 self.assertEqual(ip.dst, self.pg3.remote_ip4)
4205 self.assertEqual(udp.sport, 12345)
4206 self.assertEqual(udp.dport, 12346)
4207 self.assertEqual(hanat.version, 1)
4208 self.assertEqual(hanat.count, 2)
4209 seq = hanat.sequence_number
4210 for event in hanat.events:
4211 self.assertEqual(event.event_type, 3)
4212 self.assertEqual(event.out_addr, self.nat_addr)
4213 self.assertEqual(event.fib_index, 0)
4214 self.assertEqual(event.total_pkts, 2)
4215 self.assertGreater(event.total_bytes, 0)
4217 ack = (Ether(dst=self.pg3.local_mac, src=self.pg3.remote_mac) /
4218 IP(src=self.pg3.remote_ip4, dst=self.pg3.local_ip4) /
4219 UDP(sport=12346, dport=12345) /
4220 HANATStateSync(sequence_number=seq, flags='ACK'))
4221 self.pg3.add_stream(ack)
4223 stats = self.statistics.get_counter('/nat44/ha/ack-recv')
4224 self.assertEqual(stats[0][0], 2)
4226 def test_ha_recv(self):
4227 """ Receive HA session synchronization events (passive) """
4228 self.nat44_add_address(self.nat_addr)
4229 flags = self.config_flags.NAT_IS_INSIDE
4230 self.vapi.nat44_interface_add_del_feature(
4231 sw_if_index=self.pg0.sw_if_index,
4232 flags=flags, is_add=1)
4233 self.vapi.nat44_interface_add_del_feature(
4234 sw_if_index=self.pg1.sw_if_index,
4236 self.vapi.nat_ha_set_listener(ip_address=self.pg3.local_ip4,
4239 bind_layers(UDP, HANATStateSync, sport=12345)
4241 self.tcp_port_out = random.randint(1025, 65535)
4242 self.udp_port_out = random.randint(1025, 65535)
4244 # send HA session add events to failover/passive
4245 p = (Ether(dst=self.pg3.local_mac, src=self.pg3.remote_mac) /
4246 IP(src=self.pg3.remote_ip4, dst=self.pg3.local_ip4) /
4247 UDP(sport=12346, dport=12345) /
4248 HANATStateSync(sequence_number=1, events=[
4249 Event(event_type='add', protocol='tcp',
4250 in_addr=self.pg0.remote_ip4, out_addr=self.nat_addr,
4251 in_port=self.tcp_port_in, out_port=self.tcp_port_out,
4252 eh_addr=self.pg1.remote_ip4,
4253 ehn_addr=self.pg1.remote_ip4,
4254 eh_port=self.tcp_external_port,
4255 ehn_port=self.tcp_external_port, fib_index=0),
4256 Event(event_type='add', protocol='udp',
4257 in_addr=self.pg0.remote_ip4, out_addr=self.nat_addr,
4258 in_port=self.udp_port_in, out_port=self.udp_port_out,
4259 eh_addr=self.pg1.remote_ip4,
4260 ehn_addr=self.pg1.remote_ip4,
4261 eh_port=self.udp_external_port,
4262 ehn_port=self.udp_external_port, fib_index=0)]))
4264 self.pg3.add_stream(p)
4265 self.pg_enable_capture(self.pg_interfaces)
4268 capture = self.pg3.get_capture(1)
4271 hanat = p[HANATStateSync]
4273 self.logger.error(ppp("Invalid packet:", p))
4276 self.assertEqual(hanat.sequence_number, 1)
4277 self.assertEqual(hanat.flags, 'ACK')
4278 self.assertEqual(hanat.version, 1)
4279 self.assertEqual(hanat.thread_index, 0)
4280 stats = self.statistics.get_counter('/nat44/ha/ack-send')
4281 self.assertEqual(stats[0][0], 1)
4282 stats = self.statistics.get_counter('/nat44/ha/add-event-recv')
4283 self.assertEqual(stats[0][0], 2)
4284 users = self.statistics.get_counter('/nat44/total-users')
4285 self.assertEqual(users[0][0], 1)
4286 sessions = self.statistics.get_counter('/nat44/total-sessions')
4287 self.assertEqual(sessions[0][0], 2)
4288 users = self.vapi.nat44_user_dump()
4289 self.assertEqual(len(users), 1)
4290 self.assertEqual(str(users[0].ip_address),
4291 self.pg0.remote_ip4)
4292 # there should be 2 sessions created by HA
4293 sessions = self.vapi.nat44_user_session_dump(users[0].ip_address,
4295 self.assertEqual(len(sessions), 2)
4296 for session in sessions:
4297 self.assertEqual(str(session.inside_ip_address),
4298 self.pg0.remote_ip4)
4299 self.assertEqual(str(session.outside_ip_address),
4301 self.assertIn(session.inside_port,
4302 [self.tcp_port_in, self.udp_port_in])
4303 self.assertIn(session.outside_port,
4304 [self.tcp_port_out, self.udp_port_out])
4305 self.assertIn(session.protocol, [IP_PROTOS.tcp, IP_PROTOS.udp])
4307 # send HA session delete event to failover/passive
4308 p = (Ether(dst=self.pg3.local_mac, src=self.pg3.remote_mac) /
4309 IP(src=self.pg3.remote_ip4, dst=self.pg3.local_ip4) /
4310 UDP(sport=12346, dport=12345) /
4311 HANATStateSync(sequence_number=2, events=[
4312 Event(event_type='del', protocol='udp',
4313 in_addr=self.pg0.remote_ip4, out_addr=self.nat_addr,
4314 in_port=self.udp_port_in, out_port=self.udp_port_out,
4315 eh_addr=self.pg1.remote_ip4,
4316 ehn_addr=self.pg1.remote_ip4,
4317 eh_port=self.udp_external_port,
4318 ehn_port=self.udp_external_port, fib_index=0)]))
4320 self.pg3.add_stream(p)
4321 self.pg_enable_capture(self.pg_interfaces)
4324 capture = self.pg3.get_capture(1)
4327 hanat = p[HANATStateSync]
4329 self.logger.error(ppp("Invalid packet:", p))
4332 self.assertEqual(hanat.sequence_number, 2)
4333 self.assertEqual(hanat.flags, 'ACK')
4334 self.assertEqual(hanat.version, 1)
4335 users = self.vapi.nat44_user_dump()
4336 self.assertEqual(len(users), 1)
4337 self.assertEqual(str(users[0].ip_address),
4338 self.pg0.remote_ip4)
4339 # now we should have only 1 session, 1 deleted by HA
4340 sessions = self.vapi.nat44_user_session_dump(users[0].ip_address,
4342 self.assertEqual(len(sessions), 1)
4343 stats = self.statistics.get_counter('/nat44/ha/del-event-recv')
4344 self.assertEqual(stats[0][0], 1)
4346 stats = self.statistics.get_counter('/err/nat-ha/pkts-processed')
4347 self.assertEqual(stats, 2)
4349 # send HA session refresh event to failover/passive
4350 p = (Ether(dst=self.pg3.local_mac, src=self.pg3.remote_mac) /
4351 IP(src=self.pg3.remote_ip4, dst=self.pg3.local_ip4) /
4352 UDP(sport=12346, dport=12345) /
4353 HANATStateSync(sequence_number=3, events=[
4354 Event(event_type='refresh', protocol='tcp',
4355 in_addr=self.pg0.remote_ip4, out_addr=self.nat_addr,
4356 in_port=self.tcp_port_in, out_port=self.tcp_port_out,
4357 eh_addr=self.pg1.remote_ip4,
4358 ehn_addr=self.pg1.remote_ip4,
4359 eh_port=self.tcp_external_port,
4360 ehn_port=self.tcp_external_port, fib_index=0,
4361 total_bytes=1024, total_pkts=2)]))
4362 self.pg3.add_stream(p)
4363 self.pg_enable_capture(self.pg_interfaces)
4366 capture = self.pg3.get_capture(1)
4369 hanat = p[HANATStateSync]
4371 self.logger.error(ppp("Invalid packet:", p))
4374 self.assertEqual(hanat.sequence_number, 3)
4375 self.assertEqual(hanat.flags, 'ACK')
4376 self.assertEqual(hanat.version, 1)
4377 users = self.vapi.nat44_user_dump()
4378 self.assertEqual(len(users), 1)
4379 self.assertEqual(str(users[0].ip_address),
4380 self.pg0.remote_ip4)
4381 sessions = self.vapi.nat44_user_session_dump(users[0].ip_address,
4383 self.assertEqual(len(sessions), 1)
4384 session = sessions[0]
4385 self.assertEqual(session.total_bytes, 1024)
4386 self.assertEqual(session.total_pkts, 2)
4387 stats = self.statistics.get_counter('/nat44/ha/refresh-event-recv')
4388 self.assertEqual(stats[0][0], 1)
4390 stats = self.statistics.get_counter('/err/nat-ha/pkts-processed')
4391 self.assertEqual(stats, 3)
4393 # send packet to test session created by HA
4394 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
4395 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
4396 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out))
4397 self.pg1.add_stream(p)
4398 self.pg_enable_capture(self.pg_interfaces)
4400 capture = self.pg0.get_capture(1)
4406 self.logger.error(ppp("Invalid packet:", p))
4409 self.assertEqual(ip.src, self.pg1.remote_ip4)
4410 self.assertEqual(ip.dst, self.pg0.remote_ip4)
4411 self.assertEqual(tcp.sport, self.tcp_external_port)
4412 self.assertEqual(tcp.dport, self.tcp_port_in)
4415 super(TestNAT44, self).tearDown()
4417 self.vapi.cli("clear logging")
4419 def show_commands_at_teardown(self):
4420 self.logger.info(self.vapi.cli("show nat44 addresses"))
4421 self.logger.info(self.vapi.cli("show nat44 interfaces"))
4422 self.logger.info(self.vapi.cli("show nat44 static mappings"))
4423 self.logger.info(self.vapi.cli("show nat44 interface address"))
4424 self.logger.info(self.vapi.cli("show nat44 sessions detail"))
4425 self.logger.info(self.vapi.cli("show nat virtual-reassembly"))
4426 self.logger.info(self.vapi.cli("show nat44 hash tables detail"))
4427 self.logger.info(self.vapi.cli("show nat timeouts"))
4429 self.vapi.cli("show nat addr-port-assignment-alg"))
4430 self.logger.info(self.vapi.cli("show nat ha"))
4433 class TestNAT44EndpointDependent(MethodHolder):
4434 """ Endpoint-Dependent mapping and filtering test cases """
4437 def setUpConstants(cls):
4438 super(TestNAT44EndpointDependent, cls).setUpConstants()
4439 cls.vpp_cmdline.extend(["nat", "{", "endpoint-dependent", "}"])
4442 def setUpClass(cls):
4443 super(TestNAT44EndpointDependent, cls).setUpClass()
4444 cls.vapi.cli("set log class nat level debug")
4446 cls.tcp_port_in = 6303
4447 cls.tcp_port_out = 6303
4448 cls.udp_port_in = 6304
4449 cls.udp_port_out = 6304
4450 cls.icmp_id_in = 6305
4451 cls.icmp_id_out = 6305
4452 cls.nat_addr = '10.0.0.3'
4453 cls.ipfix_src_port = 4739
4454 cls.ipfix_domain_id = 1
4455 cls.tcp_external_port = 80
4457 cls.create_pg_interfaces(range(7))
4458 cls.interfaces = list(cls.pg_interfaces[0:3])
4460 for i in cls.interfaces:
4465 cls.pg0.generate_remote_hosts(3)
4466 cls.pg0.configure_ipv4_neighbors()
4470 cls.pg4.generate_remote_hosts(2)
4471 cls.pg4.config_ip4()
4472 ip_addr_n = socket.inet_pton(socket.AF_INET, "10.0.0.1")
4473 cls.vapi.sw_interface_add_del_address(
4474 sw_if_index=cls.pg4.sw_if_index, address=ip_addr_n,
4477 cls.pg4.resolve_arp()
4478 cls.pg4._remote_hosts[1]._ip4 = cls.pg4._remote_hosts[0]._ip4
4479 cls.pg4.resolve_arp()
4481 zero_ip4n = socket.inet_pton(socket.AF_INET, "0.0.0.0")
4482 cls.vapi.ip_table_add_del(is_add=1, table_id=1)
4484 cls.pg5._local_ip4 = "10.1.1.1"
4485 cls.pg5._local_ip4n = socket.inet_pton(socket.AF_INET,
4487 cls.pg5._remote_hosts[0]._ip4 = "10.1.1.2"
4488 cls.pg5._remote_hosts[0]._ip4n = socket.inet_pton(
4489 socket.AF_INET, cls.pg5.remote_ip4)
4490 cls.pg5.set_table_ip4(1)
4491 cls.pg5.config_ip4()
4493 cls.vapi.ip_add_del_route(dst_address=cls.pg5.remote_ip4n,
4494 dst_address_length=32,
4495 next_hop_address=zero_ip4n,
4496 next_hop_sw_if_index=cls.pg5.sw_if_index,
4499 cls.pg6._local_ip4 = "10.1.2.1"
4500 cls.pg6._local_ip4n = socket.inet_pton(socket.AF_INET,
4502 cls.pg6._remote_hosts[0]._ip4 = "10.1.2.2"
4503 cls.pg6._remote_hosts[0]._ip4n = socket.inet_pton(
4504 socket.AF_INET, cls.pg6.remote_ip4)
4505 cls.pg6.set_table_ip4(1)
4506 cls.pg6.config_ip4()
4508 cls.vapi.ip_add_del_route(dst_address=cls.pg6.remote_ip4n,
4509 dst_address_length=32,
4510 next_hop_address=zero_ip4n,
4511 next_hop_sw_if_index=cls.pg6.sw_if_index,
4514 cls.vapi.ip_add_del_route(dst_address=cls.pg6.remote_ip4n,
4515 dst_address_length=16,
4516 next_hop_address=zero_ip4n, table_id=0,
4517 next_hop_table_id=1)
4518 cls.vapi.ip_add_del_route(dst_address=zero_ip4n,
4519 dst_address_length=0,
4520 next_hop_address=zero_ip4n, table_id=1,
4521 next_hop_table_id=0)
4522 cls.vapi.ip_add_del_route(dst_address=zero_ip4n,
4523 dst_address_length=0,
4524 next_hop_address=cls.pg1.local_ip4n,
4525 next_hop_sw_if_index=cls.pg1.sw_if_index,
4528 cls.pg5.resolve_arp()
4529 cls.pg6.resolve_arp()
4532 super(TestNAT44EndpointDependent, cls).tearDownClass()
4536 def tearDownClass(cls):
4537 super(TestNAT44EndpointDependent, cls).tearDownClass()
4539 def test_frag_in_order(self):
4540 """ NAT44 translate fragments arriving in order """
4541 self.nat44_add_address(self.nat_addr)
4542 flags = self.config_flags.NAT_IS_INSIDE
4543 self.vapi.nat44_interface_add_del_feature(
4544 sw_if_index=self.pg0.sw_if_index,
4545 flags=flags, is_add=1)
4546 self.vapi.nat44_interface_add_del_feature(
4547 sw_if_index=self.pg1.sw_if_index,
4549 self.frag_in_order(proto=IP_PROTOS.tcp)
4550 self.frag_in_order(proto=IP_PROTOS.udp)
4551 self.frag_in_order(proto=IP_PROTOS.icmp)
4553 def test_frag_in_order_dont_translate(self):
4554 """ NAT44 don't translate fragments arriving in order """
4555 flags = self.config_flags.NAT_IS_INSIDE
4556 self.vapi.nat44_interface_add_del_feature(
4557 sw_if_index=self.pg0.sw_if_index,
4558 flags=flags, is_add=1)
4559 self.vapi.nat44_interface_add_del_feature(
4560 sw_if_index=self.pg1.sw_if_index,
4562 self.vapi.nat44_forwarding_enable_disable(enable=True)
4563 self.frag_in_order(proto=IP_PROTOS.tcp, dont_translate=True)
4565 def test_frag_out_of_order(self):
4566 """ NAT44 translate fragments arriving out of order """
4567 self.nat44_add_address(self.nat_addr)
4568 flags = self.config_flags.NAT_IS_INSIDE
4569 self.vapi.nat44_interface_add_del_feature(
4570 sw_if_index=self.pg0.sw_if_index,
4571 flags=flags, is_add=1)
4572 self.vapi.nat44_interface_add_del_feature(
4573 sw_if_index=self.pg1.sw_if_index,
4575 self.frag_out_of_order(proto=IP_PROTOS.tcp)
4576 self.frag_out_of_order(proto=IP_PROTOS.udp)
4577 self.frag_out_of_order(proto=IP_PROTOS.icmp)
4579 def test_frag_out_of_order_dont_translate(self):
4580 """ NAT44 don't translate fragments arriving out of order """
4581 flags = self.config_flags.NAT_IS_INSIDE
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_forwarding_enable_disable(enable=True)
4589 self.frag_out_of_order(proto=IP_PROTOS.tcp, dont_translate=True)
4591 def test_frag_in_order_in_plus_out(self):
4592 """ in+out interface fragments in order """
4593 flags = self.config_flags.NAT_IS_INSIDE
4594 self.vapi.nat44_interface_add_del_feature(
4595 sw_if_index=self.pg0.sw_if_index,
4597 self.vapi.nat44_interface_add_del_feature(
4598 sw_if_index=self.pg0.sw_if_index,
4599 flags=flags, is_add=1)
4600 self.vapi.nat44_interface_add_del_feature(
4601 sw_if_index=self.pg1.sw_if_index,
4603 self.vapi.nat44_interface_add_del_feature(
4604 sw_if_index=self.pg1.sw_if_index,
4605 flags=flags, is_add=1)
4607 self.server = self.pg1.remote_hosts[0]
4609 self.server_in_addr = self.server.ip4
4610 self.server_out_addr = '11.11.11.11'
4611 self.server_in_port = random.randint(1025, 65535)
4612 self.server_out_port = random.randint(1025, 65535)
4614 self.nat44_add_address(self.server_out_addr)
4616 # add static mappings for server
4617 self.nat44_add_static_mapping(self.server_in_addr,
4618 self.server_out_addr,
4619 self.server_in_port,
4620 self.server_out_port,
4621 proto=IP_PROTOS.tcp)
4622 self.nat44_add_static_mapping(self.server_in_addr,
4623 self.server_out_addr,
4624 self.server_in_port,
4625 self.server_out_port,
4626 proto=IP_PROTOS.udp)
4627 self.nat44_add_static_mapping(self.server_in_addr,
4628 self.server_out_addr,
4629 proto=IP_PROTOS.icmp)
4631 self.vapi.nat_set_reass(timeout=10, max_reass=1024, max_frag=5,
4634 self.frag_in_order_in_plus_out(proto=IP_PROTOS.tcp)
4635 self.frag_in_order_in_plus_out(proto=IP_PROTOS.udp)
4636 self.frag_in_order_in_plus_out(proto=IP_PROTOS.icmp)
4638 def test_frag_out_of_order_in_plus_out(self):
4639 """ in+out interface fragments out of order """
4640 flags = self.config_flags.NAT_IS_INSIDE
4641 self.vapi.nat44_interface_add_del_feature(
4642 sw_if_index=self.pg0.sw_if_index,
4644 self.vapi.nat44_interface_add_del_feature(
4645 sw_if_index=self.pg0.sw_if_index,
4646 flags=flags, is_add=1)
4647 self.vapi.nat44_interface_add_del_feature(
4648 sw_if_index=self.pg1.sw_if_index,
4650 self.vapi.nat44_interface_add_del_feature(
4651 sw_if_index=self.pg1.sw_if_index,
4652 flags=flags, is_add=1)
4654 self.server = self.pg1.remote_hosts[0]
4656 self.server_in_addr = self.server.ip4
4657 self.server_out_addr = '11.11.11.11'
4658 self.server_in_port = random.randint(1025, 65535)
4659 self.server_out_port = random.randint(1025, 65535)
4661 self.nat44_add_address(self.server_out_addr)
4663 # add static mappings for server
4664 self.nat44_add_static_mapping(self.server_in_addr,
4665 self.server_out_addr,
4666 self.server_in_port,
4667 self.server_out_port,
4668 proto=IP_PROTOS.tcp)
4669 self.nat44_add_static_mapping(self.server_in_addr,
4670 self.server_out_addr,
4671 self.server_in_port,
4672 self.server_out_port,
4673 proto=IP_PROTOS.udp)
4674 self.nat44_add_static_mapping(self.server_in_addr,
4675 self.server_out_addr,
4676 proto=IP_PROTOS.icmp)
4678 self.vapi.nat_set_reass(timeout=10, max_reass=1024, max_frag=5,
4681 self.frag_out_of_order_in_plus_out(proto=IP_PROTOS.tcp)
4682 self.frag_out_of_order_in_plus_out(proto=IP_PROTOS.udp)
4683 self.frag_out_of_order_in_plus_out(proto=IP_PROTOS.icmp)
4685 def test_reass_hairpinning(self):
4686 """ NAT44 fragments hairpinning """
4687 self.server = self.pg0.remote_hosts[1]
4688 self.host_in_port = random.randint(1025, 65535)
4689 self.server_in_port = random.randint(1025, 65535)
4690 self.server_out_port = random.randint(1025, 65535)
4692 self.nat44_add_address(self.nat_addr)
4693 flags = self.config_flags.NAT_IS_INSIDE
4694 self.vapi.nat44_interface_add_del_feature(
4695 sw_if_index=self.pg0.sw_if_index,
4696 flags=flags, is_add=1)
4697 self.vapi.nat44_interface_add_del_feature(
4698 sw_if_index=self.pg1.sw_if_index,
4700 # add static mapping for server
4701 self.nat44_add_static_mapping(self.server.ip4, self.nat_addr,
4702 self.server_in_port,
4703 self.server_out_port,
4704 proto=IP_PROTOS.tcp)
4705 self.nat44_add_static_mapping(self.server.ip4, self.nat_addr,
4706 self.server_in_port,
4707 self.server_out_port,
4708 proto=IP_PROTOS.udp)
4709 self.nat44_add_static_mapping(self.server.ip4, self.nat_addr)
4711 self.reass_hairpinning(proto=IP_PROTOS.tcp)
4712 self.reass_hairpinning(proto=IP_PROTOS.udp)
4713 self.reass_hairpinning(proto=IP_PROTOS.icmp)
4715 def test_dynamic(self):
4716 """ NAT44 dynamic translation test """
4718 self.nat44_add_address(self.nat_addr)
4719 flags = self.config_flags.NAT_IS_INSIDE
4720 self.vapi.nat44_interface_add_del_feature(
4721 sw_if_index=self.pg0.sw_if_index,
4722 flags=flags, is_add=1)
4723 self.vapi.nat44_interface_add_del_feature(
4724 sw_if_index=self.pg1.sw_if_index,
4727 nat_config = self.vapi.nat_show_config()
4728 self.assertEqual(1, nat_config.endpoint_dependent)
4731 tcpn = self.statistics.get_counter(
4732 '/err/nat44-ed-in2out-slowpath/TCP packets')
4733 udpn = self.statistics.get_counter(
4734 '/err/nat44-ed-in2out-slowpath/UDP packets')
4735 icmpn = self.statistics.get_counter(
4736 '/err/nat44-ed-in2out-slowpath/ICMP packets')
4737 totaln = self.statistics.get_counter(
4738 '/err/nat44-ed-in2out-slowpath/good in2out packets processed')
4740 pkts = self.create_stream_in(self.pg0, self.pg1)
4741 self.pg0.add_stream(pkts)
4742 self.pg_enable_capture(self.pg_interfaces)
4744 capture = self.pg1.get_capture(len(pkts))
4745 self.verify_capture_out(capture)
4747 err = self.statistics.get_counter(
4748 '/err/nat44-ed-in2out-slowpath/TCP packets')
4749 self.assertEqual(err - tcpn, 1)
4750 err = self.statistics.get_counter(
4751 '/err/nat44-ed-in2out-slowpath/UDP packets')
4752 self.assertEqual(err - udpn, 1)
4753 err = self.statistics.get_counter(
4754 '/err/nat44-ed-in2out-slowpath/ICMP packets')
4755 self.assertEqual(err - icmpn, 1)
4756 err = self.statistics.get_counter(
4757 '/err/nat44-ed-in2out-slowpath/good in2out packets processed')
4758 self.assertEqual(err - totaln, 3)
4761 tcpn = self.statistics.get_counter('/err/nat44-ed-out2in/TCP packets')
4762 udpn = self.statistics.get_counter('/err/nat44-ed-out2in/UDP packets')
4763 icmpn = self.statistics.get_counter(
4764 '/err/nat44-ed-out2in-slowpath/ICMP packets')
4765 totaln = self.statistics.get_counter(
4766 '/err/nat44-ed-out2in/good out2in packets processed')
4768 pkts = self.create_stream_out(self.pg1)
4769 self.pg1.add_stream(pkts)
4770 self.pg_enable_capture(self.pg_interfaces)
4772 capture = self.pg0.get_capture(len(pkts))
4773 self.verify_capture_in(capture, self.pg0)
4775 err = self.statistics.get_counter('/err/nat44-ed-out2in/TCP packets')
4776 self.assertEqual(err - tcpn, 1)
4777 err = self.statistics.get_counter('/err/nat44-ed-out2in/UDP packets')
4778 self.assertEqual(err - udpn, 1)
4779 err = self.statistics.get_counter(
4780 '/err/nat44-ed-out2in-slowpath/ICMP packets')
4781 self.assertEqual(err - icmpn, 1)
4782 err = self.statistics.get_counter(
4783 '/err/nat44-ed-out2in/good out2in packets processed')
4784 self.assertEqual(err - totaln, 2)
4786 users = self.statistics.get_counter('/nat44/total-users')
4787 self.assertEqual(users[0][0], 1)
4788 sessions = self.statistics.get_counter('/nat44/total-sessions')
4789 self.assertEqual(sessions[0][0], 3)
4791 def test_forwarding(self):
4792 """ NAT44 forwarding test """
4794 flags = self.config_flags.NAT_IS_INSIDE
4795 self.vapi.nat44_interface_add_del_feature(
4796 sw_if_index=self.pg0.sw_if_index,
4797 flags=flags, is_add=1)
4798 self.vapi.nat44_interface_add_del_feature(
4799 sw_if_index=self.pg1.sw_if_index,
4801 self.vapi.nat44_forwarding_enable_disable(enable=1)
4803 real_ip = self.pg0.remote_ip4
4804 alias_ip = self.nat_addr
4805 flags = self.config_flags.NAT_IS_ADDR_ONLY
4806 self.vapi.nat44_add_del_static_mapping(is_add=1,
4807 local_ip_address=real_ip,
4808 external_ip_address=alias_ip,
4809 external_sw_if_index=0xFFFFFFFF,
4813 # in2out - static mapping match
4815 pkts = self.create_stream_out(self.pg1)
4816 self.pg1.add_stream(pkts)
4817 self.pg_enable_capture(self.pg_interfaces)
4819 capture = self.pg0.get_capture(len(pkts))
4820 self.verify_capture_in(capture, self.pg0)
4822 pkts = self.create_stream_in(self.pg0, self.pg1)
4823 self.pg0.add_stream(pkts)
4824 self.pg_enable_capture(self.pg_interfaces)
4826 capture = self.pg1.get_capture(len(pkts))
4827 self.verify_capture_out(capture, same_port=True)
4829 # in2out - no static mapping match
4831 host0 = self.pg0.remote_hosts[0]
4832 self.pg0.remote_hosts[0] = self.pg0.remote_hosts[1]
4834 pkts = self.create_stream_out(self.pg1,
4835 dst_ip=self.pg0.remote_ip4,
4836 use_inside_ports=True)
4837 self.pg1.add_stream(pkts)
4838 self.pg_enable_capture(self.pg_interfaces)
4840 capture = self.pg0.get_capture(len(pkts))
4841 self.verify_capture_in(capture, self.pg0)
4843 pkts = self.create_stream_in(self.pg0, self.pg1)
4844 self.pg0.add_stream(pkts)
4845 self.pg_enable_capture(self.pg_interfaces)
4847 capture = self.pg1.get_capture(len(pkts))
4848 self.verify_capture_out(capture, nat_ip=self.pg0.remote_ip4,
4851 self.pg0.remote_hosts[0] = host0
4853 user = self.pg0.remote_hosts[1]
4854 sessions = self.vapi.nat44_user_session_dump(user.ip4n, 0)
4855 self.assertEqual(len(sessions), 3)
4856 self.assertTrue(sessions[0].flags &
4857 self.config_flags.NAT_IS_EXT_HOST_VALID)
4858 self.vapi.nat44_del_session(
4859 address=sessions[0].inside_ip_address,
4860 port=sessions[0].inside_port,
4861 protocol=sessions[0].protocol,
4862 flags=(self.config_flags.NAT_IS_INSIDE |
4863 self.config_flags.NAT_IS_EXT_HOST_VALID),
4864 ext_host_address=sessions[0].ext_host_address,
4865 ext_host_port=sessions[0].ext_host_port)
4866 sessions = self.vapi.nat44_user_session_dump(user.ip4n, 0)
4867 self.assertEqual(len(sessions), 2)
4870 self.vapi.nat44_forwarding_enable_disable(enable=0)
4871 flags = self.config_flags.NAT_IS_ADDR_ONLY
4872 self.vapi.nat44_add_del_static_mapping(
4874 local_ip_address=real_ip,
4875 external_ip_address=alias_ip,
4876 external_sw_if_index=0xFFFFFFFF,
4879 def test_static_lb(self):
4880 """ NAT44 local service load balancing """
4881 external_addr_n = self.nat_addr
4884 server1 = self.pg0.remote_hosts[0]
4885 server2 = self.pg0.remote_hosts[1]
4887 locals = [{'addr': server1.ip4n,
4891 {'addr': server2.ip4n,
4896 self.nat44_add_address(self.nat_addr)
4897 self.vapi.nat44_add_del_lb_static_mapping(
4899 external_addr=external_addr_n,
4900 external_port=external_port,
4901 protocol=IP_PROTOS.tcp,
4902 local_num=len(locals),
4904 flags = self.config_flags.NAT_IS_INSIDE
4905 self.vapi.nat44_interface_add_del_feature(
4906 sw_if_index=self.pg0.sw_if_index,
4907 flags=flags, is_add=1)
4908 self.vapi.nat44_interface_add_del_feature(
4909 sw_if_index=self.pg1.sw_if_index,
4912 # from client to service
4913 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
4914 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
4915 TCP(sport=12345, dport=external_port))
4916 self.pg1.add_stream(p)
4917 self.pg_enable_capture(self.pg_interfaces)
4919 capture = self.pg0.get_capture(1)
4925 self.assertIn(ip.dst, [server1.ip4, server2.ip4])
4926 if ip.dst == server1.ip4:
4930 self.assertEqual(tcp.dport, local_port)
4931 self.assert_packet_checksums_valid(p)
4933 self.logger.error(ppp("Unexpected or invalid packet:", p))
4936 # from service back to client
4937 p = (Ether(src=server.mac, dst=self.pg0.local_mac) /
4938 IP(src=server.ip4, dst=self.pg1.remote_ip4) /
4939 TCP(sport=local_port, dport=12345))
4940 self.pg0.add_stream(p)
4941 self.pg_enable_capture(self.pg_interfaces)
4943 capture = self.pg1.get_capture(1)
4948 self.assertEqual(ip.src, self.nat_addr)
4949 self.assertEqual(tcp.sport, external_port)
4950 self.assert_packet_checksums_valid(p)
4952 self.logger.error(ppp("Unexpected or invalid packet:", p))
4955 sessions = self.vapi.nat44_user_session_dump(server.ip4n, 0)
4956 self.assertEqual(len(sessions), 1)
4957 self.assertTrue(sessions[0].flags &
4958 self.config_flags.NAT_IS_EXT_HOST_VALID)
4959 self.vapi.nat44_del_session(
4960 address=sessions[0].inside_ip_address,
4961 port=sessions[0].inside_port,
4962 protocol=sessions[0].protocol,
4963 flags=(self.config_flags.NAT_IS_INSIDE |
4964 self.config_flags.NAT_IS_EXT_HOST_VALID),
4965 ext_host_address=sessions[0].ext_host_address,
4966 ext_host_port=sessions[0].ext_host_port)
4967 sessions = self.vapi.nat44_user_session_dump(server.ip4n, 0)
4968 self.assertEqual(len(sessions), 0)
4970 @unittest.skipUnless(running_extended_tests, "part of extended tests")
4971 def test_static_lb_multi_clients(self):
4972 """ NAT44 local service load balancing - multiple clients"""
4974 external_addr = self.nat_addr
4977 server1 = self.pg0.remote_hosts[0]
4978 server2 = self.pg0.remote_hosts[1]
4979 server3 = self.pg0.remote_hosts[2]
4981 locals = [{'addr': server1.ip4n,
4985 {'addr': server2.ip4n,
4990 self.nat44_add_address(self.nat_addr)
4991 self.vapi.nat44_add_del_lb_static_mapping(is_add=1,
4992 external_addr=external_addr,
4993 external_port=external_port,
4994 protocol=IP_PROTOS.tcp,
4995 local_num=len(locals),
4997 flags = self.config_flags.NAT_IS_INSIDE
4998 self.vapi.nat44_interface_add_del_feature(
4999 sw_if_index=self.pg0.sw_if_index,
5000 flags=flags, is_add=1)
5001 self.vapi.nat44_interface_add_del_feature(
5002 sw_if_index=self.pg1.sw_if_index,
5007 clients = ip4_range(self.pg1.remote_ip4, 10, 50)
5009 for client in clients:
5010 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
5011 IP(src=client, dst=self.nat_addr) /
5012 TCP(sport=12345, dport=external_port))
5014 self.pg1.add_stream(pkts)
5015 self.pg_enable_capture(self.pg_interfaces)
5017 capture = self.pg0.get_capture(len(pkts))
5019 if p[IP].dst == server1.ip4:
5023 self.assertGreater(server1_n, server2_n)
5026 'addr': server3.ip4n,
5033 self.vapi.nat44_lb_static_mapping_add_del_local(
5035 external_addr=external_addr,
5036 external_port=external_port,
5038 protocol=IP_PROTOS.tcp)
5042 clients = ip4_range(self.pg1.remote_ip4, 60, 110)
5044 for client in clients:
5045 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
5046 IP(src=client, dst=self.nat_addr) /
5047 TCP(sport=12346, dport=external_port))
5049 self.assertGreater(len(pkts), 0)
5050 self.pg1.add_stream(pkts)
5051 self.pg_enable_capture(self.pg_interfaces)
5053 capture = self.pg0.get_capture(len(pkts))
5055 if p[IP].dst == server1.ip4:
5057 elif p[IP].dst == server2.ip4:
5061 self.assertGreater(server1_n, 0)
5062 self.assertGreater(server2_n, 0)
5063 self.assertGreater(server3_n, 0)
5066 'addr': server2.ip4n,
5072 # remove one back-end
5073 self.vapi.nat44_lb_static_mapping_add_del_local(
5075 external_addr=external_addr,
5076 external_port=external_port,
5078 protocol=IP_PROTOS.tcp)
5082 self.pg1.add_stream(pkts)
5083 self.pg_enable_capture(self.pg_interfaces)
5085 capture = self.pg0.get_capture(len(pkts))
5087 if p[IP].dst == server1.ip4:
5089 elif p[IP].dst == server2.ip4:
5093 self.assertGreater(server1_n, 0)
5094 self.assertEqual(server2_n, 0)
5095 self.assertGreater(server3_n, 0)
5097 def test_static_lb_2(self):
5098 """ NAT44 local service load balancing (asymmetrical rule) """
5099 external_addr = self.nat_addr
5102 server1 = self.pg0.remote_hosts[0]
5103 server2 = self.pg0.remote_hosts[1]
5105 locals = [{'addr': server1.ip4n,
5109 {'addr': server2.ip4n,
5114 self.vapi.nat44_forwarding_enable_disable(enable=1)
5115 flags = self.config_flags.NAT_IS_OUT2IN_ONLY
5116 self.vapi.nat44_add_del_lb_static_mapping(is_add=1, flags=flags,
5117 external_addr=external_addr,
5118 external_port=external_port,
5119 protocol=IP_PROTOS.tcp,
5120 local_num=len(locals),
5122 flags = self.config_flags.NAT_IS_INSIDE
5123 self.vapi.nat44_interface_add_del_feature(
5124 sw_if_index=self.pg0.sw_if_index,
5125 flags=flags, is_add=1)
5126 self.vapi.nat44_interface_add_del_feature(
5127 sw_if_index=self.pg1.sw_if_index,
5130 # from client to service
5131 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
5132 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
5133 TCP(sport=12345, dport=external_port))
5134 self.pg1.add_stream(p)
5135 self.pg_enable_capture(self.pg_interfaces)
5137 capture = self.pg0.get_capture(1)
5143 self.assertIn(ip.dst, [server1.ip4, server2.ip4])
5144 if ip.dst == server1.ip4:
5148 self.assertEqual(tcp.dport, local_port)
5149 self.assert_packet_checksums_valid(p)
5151 self.logger.error(ppp("Unexpected or invalid packet:", p))
5154 # from service back to client
5155 p = (Ether(src=server.mac, dst=self.pg0.local_mac) /
5156 IP(src=server.ip4, dst=self.pg1.remote_ip4) /
5157 TCP(sport=local_port, dport=12345))
5158 self.pg0.add_stream(p)
5159 self.pg_enable_capture(self.pg_interfaces)
5161 capture = self.pg1.get_capture(1)
5166 self.assertEqual(ip.src, self.nat_addr)
5167 self.assertEqual(tcp.sport, external_port)
5168 self.assert_packet_checksums_valid(p)
5170 self.logger.error(ppp("Unexpected or invalid packet:", p))
5173 # from client to server (no translation)
5174 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
5175 IP(src=self.pg1.remote_ip4, dst=server1.ip4) /
5176 TCP(sport=12346, dport=local_port))
5177 self.pg1.add_stream(p)
5178 self.pg_enable_capture(self.pg_interfaces)
5180 capture = self.pg0.get_capture(1)
5186 self.assertEqual(ip.dst, server1.ip4)
5187 self.assertEqual(tcp.dport, local_port)
5188 self.assert_packet_checksums_valid(p)
5190 self.logger.error(ppp("Unexpected or invalid packet:", p))
5193 # from service back to client (no translation)
5194 p = (Ether(src=server1.mac, dst=self.pg0.local_mac) /
5195 IP(src=server1.ip4, dst=self.pg1.remote_ip4) /
5196 TCP(sport=local_port, dport=12346))
5197 self.pg0.add_stream(p)
5198 self.pg_enable_capture(self.pg_interfaces)
5200 capture = self.pg1.get_capture(1)
5205 self.assertEqual(ip.src, server1.ip4)
5206 self.assertEqual(tcp.sport, local_port)
5207 self.assert_packet_checksums_valid(p)
5209 self.logger.error(ppp("Unexpected or invalid packet:", p))
5212 def test_lb_affinity(self):
5213 """ NAT44 local service load balancing affinity """
5214 external_addr = self.nat_addr
5217 server1 = self.pg0.remote_hosts[0]
5218 server2 = self.pg0.remote_hosts[1]
5220 locals = [{'addr': server1.ip4n,
5224 {'addr': server2.ip4n,
5229 self.nat44_add_address(self.nat_addr)
5230 self.vapi.nat44_add_del_lb_static_mapping(is_add=1,
5231 external_addr=external_addr,
5232 external_port=external_port,
5233 protocol=IP_PROTOS.tcp,
5235 local_num=len(locals),
5237 flags = self.config_flags.NAT_IS_INSIDE
5238 self.vapi.nat44_interface_add_del_feature(
5239 sw_if_index=self.pg0.sw_if_index,
5240 flags=flags, is_add=1)
5241 self.vapi.nat44_interface_add_del_feature(
5242 sw_if_index=self.pg1.sw_if_index,
5245 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
5246 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
5247 TCP(sport=1025, dport=external_port))
5248 self.pg1.add_stream(p)
5249 self.pg_enable_capture(self.pg_interfaces)
5251 capture = self.pg0.get_capture(1)
5252 backend = capture[0][IP].dst
5254 sessions = self.vapi.nat44_user_session_dump(backend, 0)
5255 self.assertEqual(len(sessions), 1)
5256 self.assertTrue(sessions[0].flags &
5257 self.config_flags.NAT_IS_EXT_HOST_VALID)
5258 self.vapi.nat44_del_session(
5259 address=sessions[0].inside_ip_address,
5260 port=sessions[0].inside_port,
5261 protocol=sessions[0].protocol,
5262 flags=(self.config_flags.NAT_IS_INSIDE |
5263 self.config_flags.NAT_IS_EXT_HOST_VALID),
5264 ext_host_address=sessions[0].ext_host_address,
5265 ext_host_port=sessions[0].ext_host_port)
5268 for port in range(1030, 1100):
5269 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
5270 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
5271 TCP(sport=port, dport=external_port))
5273 self.pg1.add_stream(pkts)
5274 self.pg_enable_capture(self.pg_interfaces)
5276 capture = self.pg0.get_capture(len(pkts))
5278 self.assertEqual(p[IP].dst, backend)
5280 def test_unknown_proto(self):
5281 """ NAT44 translate packet with unknown protocol """
5282 self.nat44_add_address(self.nat_addr)
5283 flags = self.config_flags.NAT_IS_INSIDE
5284 self.vapi.nat44_interface_add_del_feature(
5285 sw_if_index=self.pg0.sw_if_index,
5286 flags=flags, is_add=1)
5287 self.vapi.nat44_interface_add_del_feature(
5288 sw_if_index=self.pg1.sw_if_index,
5292 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
5293 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
5294 TCP(sport=self.tcp_port_in, dport=20))
5295 self.pg0.add_stream(p)
5296 self.pg_enable_capture(self.pg_interfaces)
5298 p = self.pg1.get_capture(1)
5300 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
5301 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
5303 IP(src=self.pg2.remote_ip4, dst=self.pg2.remote_ip4) /
5304 TCP(sport=1234, dport=1234))
5305 self.pg0.add_stream(p)
5306 self.pg_enable_capture(self.pg_interfaces)
5308 p = self.pg1.get_capture(1)
5311 self.assertEqual(packet[IP].src, self.nat_addr)
5312 self.assertEqual(packet[IP].dst, self.pg1.remote_ip4)
5313 self.assertEqual(packet.haslayer(GRE), 1)
5314 self.assert_packet_checksums_valid(packet)
5316 self.logger.error(ppp("Unexpected or invalid packet:", packet))
5320 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
5321 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
5323 IP(src=self.pg2.remote_ip4, dst=self.pg2.remote_ip4) /
5324 TCP(sport=1234, dport=1234))
5325 self.pg1.add_stream(p)
5326 self.pg_enable_capture(self.pg_interfaces)
5328 p = self.pg0.get_capture(1)
5331 self.assertEqual(packet[IP].src, self.pg1.remote_ip4)
5332 self.assertEqual(packet[IP].dst, self.pg0.remote_ip4)
5333 self.assertEqual(packet.haslayer(GRE), 1)
5334 self.assert_packet_checksums_valid(packet)
5336 self.logger.error(ppp("Unexpected or invalid packet:", packet))
5339 def test_hairpinning_unknown_proto(self):
5340 """ NAT44 translate packet with unknown protocol - hairpinning """
5341 host = self.pg0.remote_hosts[0]
5342 server = self.pg0.remote_hosts[1]
5344 server_out_port = 8765
5345 server_nat_ip = "10.0.0.11"
5347 self.nat44_add_address(self.nat_addr)
5348 flags = self.config_flags.NAT_IS_INSIDE
5349 self.vapi.nat44_interface_add_del_feature(
5350 sw_if_index=self.pg0.sw_if_index,
5351 flags=flags, is_add=1)
5352 self.vapi.nat44_interface_add_del_feature(
5353 sw_if_index=self.pg1.sw_if_index,
5356 # add static mapping for server
5357 self.nat44_add_static_mapping(server.ip4, server_nat_ip)
5360 p = (Ether(src=host.mac, dst=self.pg0.local_mac) /
5361 IP(src=host.ip4, dst=server_nat_ip) /
5362 TCP(sport=host_in_port, dport=server_out_port))
5363 self.pg0.add_stream(p)
5364 self.pg_enable_capture(self.pg_interfaces)
5366 self.pg0.get_capture(1)
5368 p = (Ether(dst=self.pg0.local_mac, src=host.mac) /
5369 IP(src=host.ip4, dst=server_nat_ip) /
5371 IP(src=self.pg2.remote_ip4, dst=self.pg2.remote_ip4) /
5372 TCP(sport=1234, dport=1234))
5373 self.pg0.add_stream(p)
5374 self.pg_enable_capture(self.pg_interfaces)
5376 p = self.pg0.get_capture(1)
5379 self.assertEqual(packet[IP].src, self.nat_addr)
5380 self.assertEqual(packet[IP].dst, server.ip4)
5381 self.assertEqual(packet.haslayer(GRE), 1)
5382 self.assert_packet_checksums_valid(packet)
5384 self.logger.error(ppp("Unexpected or invalid packet:", packet))
5388 p = (Ether(dst=self.pg0.local_mac, src=server.mac) /
5389 IP(src=server.ip4, dst=self.nat_addr) /
5391 IP(src=self.pg2.remote_ip4, dst=self.pg2.remote_ip4) /
5392 TCP(sport=1234, dport=1234))
5393 self.pg0.add_stream(p)
5394 self.pg_enable_capture(self.pg_interfaces)
5396 p = self.pg0.get_capture(1)
5399 self.assertEqual(packet[IP].src, server_nat_ip)
5400 self.assertEqual(packet[IP].dst, host.ip4)
5401 self.assertEqual(packet.haslayer(GRE), 1)
5402 self.assert_packet_checksums_valid(packet)
5404 self.logger.error(ppp("Unexpected or invalid packet:", packet))
5407 def test_output_feature_and_service(self):
5408 """ NAT44 interface output feature and services """
5409 external_addr = '1.2.3.4'
5413 self.vapi.nat44_forwarding_enable_disable(enable=1)
5414 self.nat44_add_address(self.nat_addr)
5415 flags = self.config_flags.NAT_IS_ADDR_ONLY
5416 self.vapi.nat44_add_del_identity_mapping(
5417 ip_address=self.pg1.remote_ip4n, sw_if_index=0xFFFFFFFF,
5418 flags=flags, is_add=1)
5419 flags = self.config_flags.NAT_IS_OUT2IN_ONLY
5420 self.nat44_add_static_mapping(self.pg0.remote_ip4, external_addr,
5421 local_port, external_port,
5422 proto=IP_PROTOS.tcp, flags=flags)
5423 flags = self.config_flags.NAT_IS_INSIDE
5424 self.vapi.nat44_interface_add_del_feature(
5425 sw_if_index=self.pg0.sw_if_index,
5427 self.vapi.nat44_interface_add_del_feature(
5428 sw_if_index=self.pg0.sw_if_index,
5429 flags=flags, is_add=1)
5430 self.vapi.nat44_interface_add_del_output_feature(
5432 sw_if_index=self.pg1.sw_if_index)
5434 # from client to service
5435 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
5436 IP(src=self.pg1.remote_ip4, dst=external_addr) /
5437 TCP(sport=12345, dport=external_port))
5438 self.pg1.add_stream(p)
5439 self.pg_enable_capture(self.pg_interfaces)
5441 capture = self.pg0.get_capture(1)
5446 self.assertEqual(ip.dst, self.pg0.remote_ip4)
5447 self.assertEqual(tcp.dport, local_port)
5448 self.assert_packet_checksums_valid(p)
5450 self.logger.error(ppp("Unexpected or invalid packet:", p))
5453 # from service back to client
5454 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5455 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
5456 TCP(sport=local_port, dport=12345))
5457 self.pg0.add_stream(p)
5458 self.pg_enable_capture(self.pg_interfaces)
5460 capture = self.pg1.get_capture(1)
5465 self.assertEqual(ip.src, external_addr)
5466 self.assertEqual(tcp.sport, external_port)
5467 self.assert_packet_checksums_valid(p)
5469 self.logger.error(ppp("Unexpected or invalid packet:", p))
5472 # from local network host to external network
5473 pkts = self.create_stream_in(self.pg0, self.pg1)
5474 self.pg0.add_stream(pkts)
5475 self.pg_enable_capture(self.pg_interfaces)
5477 capture = self.pg1.get_capture(len(pkts))
5478 self.verify_capture_out(capture)
5479 pkts = self.create_stream_in(self.pg0, self.pg1)
5480 self.pg0.add_stream(pkts)
5481 self.pg_enable_capture(self.pg_interfaces)
5483 capture = self.pg1.get_capture(len(pkts))
5484 self.verify_capture_out(capture)
5486 # from external network back to local network host
5487 pkts = self.create_stream_out(self.pg1)
5488 self.pg1.add_stream(pkts)
5489 self.pg_enable_capture(self.pg_interfaces)
5491 capture = self.pg0.get_capture(len(pkts))
5492 self.verify_capture_in(capture, self.pg0)
5494 def test_output_feature_and_service2(self):
5495 """ NAT44 interface output feature and service host direct access """
5496 self.vapi.nat44_forwarding_enable_disable(enable=1)
5497 self.nat44_add_address(self.nat_addr)
5498 self.vapi.nat44_interface_add_del_output_feature(
5500 sw_if_index=self.pg1.sw_if_index)
5502 # session initiated from service host - translate
5503 pkts = self.create_stream_in(self.pg0, self.pg1)
5504 self.pg0.add_stream(pkts)
5505 self.pg_enable_capture(self.pg_interfaces)
5507 capture = self.pg1.get_capture(len(pkts))
5508 self.verify_capture_out(capture)
5510 pkts = self.create_stream_out(self.pg1)
5511 self.pg1.add_stream(pkts)
5512 self.pg_enable_capture(self.pg_interfaces)
5514 capture = self.pg0.get_capture(len(pkts))
5515 self.verify_capture_in(capture, self.pg0)
5517 # session initiated from remote host - do not translate
5518 self.tcp_port_in = 60303
5519 self.udp_port_in = 60304
5520 self.icmp_id_in = 60305
5521 pkts = self.create_stream_out(self.pg1,
5522 self.pg0.remote_ip4,
5523 use_inside_ports=True)
5524 self.pg1.add_stream(pkts)
5525 self.pg_enable_capture(self.pg_interfaces)
5527 capture = self.pg0.get_capture(len(pkts))
5528 self.verify_capture_in(capture, self.pg0)
5530 pkts = self.create_stream_in(self.pg0, self.pg1)
5531 self.pg0.add_stream(pkts)
5532 self.pg_enable_capture(self.pg_interfaces)
5534 capture = self.pg1.get_capture(len(pkts))
5535 self.verify_capture_out(capture, nat_ip=self.pg0.remote_ip4,
5538 def test_output_feature_and_service3(self):
5539 """ NAT44 interface output feature and DST NAT """
5540 external_addr = '1.2.3.4'
5544 self.vapi.nat44_forwarding_enable_disable(enable=1)
5545 self.nat44_add_address(self.nat_addr)
5546 flags = self.config_flags.NAT_IS_OUT2IN_ONLY
5547 self.nat44_add_static_mapping(self.pg1.remote_ip4, external_addr,
5548 local_port, external_port,
5549 proto=IP_PROTOS.tcp, flags=flags)
5550 flags = self.config_flags.NAT_IS_INSIDE
5551 self.vapi.nat44_interface_add_del_feature(
5552 sw_if_index=self.pg0.sw_if_index,
5554 self.vapi.nat44_interface_add_del_feature(
5555 sw_if_index=self.pg0.sw_if_index,
5556 flags=flags, is_add=1)
5557 self.vapi.nat44_interface_add_del_output_feature(
5559 sw_if_index=self.pg1.sw_if_index)
5561 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5562 IP(src=self.pg0.remote_ip4, dst=external_addr) /
5563 TCP(sport=12345, dport=external_port))
5564 self.pg0.add_stream(p)
5565 self.pg_enable_capture(self.pg_interfaces)
5567 capture = self.pg1.get_capture(1)
5572 self.assertEqual(ip.src, self.pg0.remote_ip4)
5573 self.assertEqual(tcp.sport, 12345)
5574 self.assertEqual(ip.dst, self.pg1.remote_ip4)
5575 self.assertEqual(tcp.dport, local_port)
5576 self.assert_packet_checksums_valid(p)
5578 self.logger.error(ppp("Unexpected or invalid packet:", p))
5581 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
5582 IP(src=self.pg1.remote_ip4, dst=self.pg0.remote_ip4) /
5583 TCP(sport=local_port, dport=12345))
5584 self.pg1.add_stream(p)
5585 self.pg_enable_capture(self.pg_interfaces)
5587 capture = self.pg0.get_capture(1)
5592 self.assertEqual(ip.src, external_addr)
5593 self.assertEqual(tcp.sport, external_port)
5594 self.assertEqual(ip.dst, self.pg0.remote_ip4)
5595 self.assertEqual(tcp.dport, 12345)
5596 self.assert_packet_checksums_valid(p)
5598 self.logger.error(ppp("Unexpected or invalid packet:", p))
5601 def test_next_src_nat(self):
5602 """ On way back forward packet to nat44-in2out node. """
5603 twice_nat_addr = '10.0.1.3'
5606 post_twice_nat_port = 0
5608 self.vapi.nat44_forwarding_enable_disable(enable=1)
5609 self.nat44_add_address(twice_nat_addr, twice_nat=1)
5610 flags = (self.config_flags.NAT_IS_OUT2IN_ONLY |
5611 self.config_flags.NAT_IS_SELF_TWICE_NAT)
5612 self.nat44_add_static_mapping(self.pg6.remote_ip4, self.pg1.remote_ip4,
5613 local_port, external_port,
5614 proto=IP_PROTOS.tcp, vrf_id=1,
5616 self.vapi.nat44_interface_add_del_feature(
5617 sw_if_index=self.pg6.sw_if_index,
5620 p = (Ether(src=self.pg6.remote_mac, dst=self.pg6.local_mac) /
5621 IP(src=self.pg6.remote_ip4, dst=self.pg1.remote_ip4) /
5622 TCP(sport=12345, dport=external_port))
5623 self.pg6.add_stream(p)
5624 self.pg_enable_capture(self.pg_interfaces)
5626 capture = self.pg6.get_capture(1)
5631 self.assertEqual(ip.src, twice_nat_addr)
5632 self.assertNotEqual(tcp.sport, 12345)
5633 post_twice_nat_port = tcp.sport
5634 self.assertEqual(ip.dst, self.pg6.remote_ip4)
5635 self.assertEqual(tcp.dport, local_port)
5636 self.assert_packet_checksums_valid(p)
5638 self.logger.error(ppp("Unexpected or invalid packet:", p))
5641 p = (Ether(src=self.pg6.remote_mac, dst=self.pg6.local_mac) /
5642 IP(src=self.pg6.remote_ip4, dst=twice_nat_addr) /
5643 TCP(sport=local_port, dport=post_twice_nat_port))
5644 self.pg6.add_stream(p)
5645 self.pg_enable_capture(self.pg_interfaces)
5647 capture = self.pg6.get_capture(1)
5652 self.assertEqual(ip.src, self.pg1.remote_ip4)
5653 self.assertEqual(tcp.sport, external_port)
5654 self.assertEqual(ip.dst, self.pg6.remote_ip4)
5655 self.assertEqual(tcp.dport, 12345)
5656 self.assert_packet_checksums_valid(p)
5658 self.logger.error(ppp("Unexpected or invalid packet:", p))
5661 def twice_nat_common(self, self_twice_nat=False, same_pg=False, lb=False,
5663 twice_nat_addr = '10.0.1.3'
5671 port_in1 = port_in + 1
5672 port_in2 = port_in + 2
5677 server1 = self.pg0.remote_hosts[0]
5678 server2 = self.pg0.remote_hosts[1]
5690 eh_translate = ((not self_twice_nat) or (not lb and same_pg) or
5693 self.nat44_add_address(self.nat_addr)
5694 self.nat44_add_address(twice_nat_addr, twice_nat=1)
5698 flags |= self.config_flags.NAT_IS_SELF_TWICE_NAT
5700 flags |= self.config_flags.NAT_IS_TWICE_NAT
5703 self.nat44_add_static_mapping(pg0.remote_ip4, self.nat_addr,
5705 proto=IP_PROTOS.tcp,
5708 locals = [{'addr': server1.ip4n,
5712 {'addr': server2.ip4n,
5716 out_addr = self.nat_addr
5718 self.vapi.nat44_add_del_lb_static_mapping(is_add=1, flags=flags,
5719 external_addr=out_addr,
5720 external_port=port_out,
5721 protocol=IP_PROTOS.tcp,
5722 local_num=len(locals),
5724 flags = self.config_flags.NAT_IS_INSIDE
5725 self.vapi.nat44_interface_add_del_feature(
5726 sw_if_index=pg0.sw_if_index,
5727 flags=flags, is_add=1)
5728 self.vapi.nat44_interface_add_del_feature(
5729 sw_if_index=pg1.sw_if_index,
5736 assert client_id is not None
5738 client = self.pg0.remote_hosts[0]
5739 elif client_id == 2:
5740 client = self.pg0.remote_hosts[1]
5742 client = pg1.remote_hosts[0]
5743 p = (Ether(src=pg1.remote_mac, dst=pg1.local_mac) /
5744 IP(src=client.ip4, dst=self.nat_addr) /
5745 TCP(sport=eh_port_out, dport=port_out))
5747 self.pg_enable_capture(self.pg_interfaces)
5749 capture = pg0.get_capture(1)
5755 if ip.dst == server1.ip4:
5761 self.assertEqual(ip.dst, server.ip4)
5763 self.assertIn(tcp.dport, [port_in1, port_in2])
5765 self.assertEqual(tcp.dport, port_in)
5767 self.assertEqual(ip.src, twice_nat_addr)
5768 self.assertNotEqual(tcp.sport, eh_port_out)
5770 self.assertEqual(ip.src, client.ip4)
5771 self.assertEqual(tcp.sport, eh_port_out)
5773 eh_port_in = tcp.sport
5774 saved_port_in = tcp.dport
5775 self.assert_packet_checksums_valid(p)
5777 self.logger.error(ppp("Unexpected or invalid packet:", p))
5780 p = (Ether(src=server.mac, dst=pg0.local_mac) /
5781 IP(src=server.ip4, dst=eh_addr_in) /
5782 TCP(sport=saved_port_in, dport=eh_port_in))
5784 self.pg_enable_capture(self.pg_interfaces)
5786 capture = pg1.get_capture(1)
5791 self.assertEqual(ip.dst, client.ip4)
5792 self.assertEqual(ip.src, self.nat_addr)
5793 self.assertEqual(tcp.dport, eh_port_out)
5794 self.assertEqual(tcp.sport, port_out)
5795 self.assert_packet_checksums_valid(p)
5797 self.logger.error(ppp("Unexpected or invalid packet:", p))
5801 sessions = self.vapi.nat44_user_session_dump(server.ip4n, 0)
5802 self.assertEqual(len(sessions), 1)
5803 self.assertTrue(sessions[0].flags &
5804 self.config_flags.NAT_IS_EXT_HOST_VALID)
5805 self.assertTrue(sessions[0].flags &
5806 self.config_flags.NAT_IS_TWICE_NAT)
5807 self.logger.error(self.vapi.cli("show nat44 sessions detail"))
5808 self.vapi.nat44_del_session(
5809 address=sessions[0].inside_ip_address,
5810 port=sessions[0].inside_port,
5811 protocol=sessions[0].protocol,
5812 flags=(self.config_flags.NAT_IS_INSIDE |
5813 self.config_flags.NAT_IS_EXT_HOST_VALID),
5814 ext_host_address=sessions[0].ext_host_nat_address,
5815 ext_host_port=sessions[0].ext_host_nat_port)
5816 sessions = self.vapi.nat44_user_session_dump(server.ip4n, 0)
5817 self.assertEqual(len(sessions), 0)
5819 def test_twice_nat(self):
5821 self.twice_nat_common()
5823 def test_self_twice_nat_positive(self):
5824 """ Self Twice NAT44 (positive test) """
5825 self.twice_nat_common(self_twice_nat=True, same_pg=True)
5827 def test_self_twice_nat_negative(self):
5828 """ Self Twice NAT44 (negative test) """
5829 self.twice_nat_common(self_twice_nat=True)
5831 def test_twice_nat_lb(self):
5832 """ Twice NAT44 local service load balancing """
5833 self.twice_nat_common(lb=True)
5835 def test_self_twice_nat_lb_positive(self):
5836 """ Self Twice NAT44 local service load balancing (positive test) """
5837 self.twice_nat_common(lb=True, self_twice_nat=True, same_pg=True,
5840 def test_self_twice_nat_lb_negative(self):
5841 """ Self Twice NAT44 local service load balancing (negative test) """
5842 self.twice_nat_common(lb=True, self_twice_nat=True, same_pg=True,
5845 def test_twice_nat_interface_addr(self):
5846 """ Acquire twice NAT44 addresses from interface """
5847 flags = self.config_flags.NAT_IS_TWICE_NAT
5848 self.vapi.nat44_add_del_interface_addr(
5850 sw_if_index=self.pg3.sw_if_index,
5853 # no address in NAT pool
5854 adresses = self.vapi.nat44_address_dump()
5855 self.assertEqual(0, len(adresses))
5857 # configure interface address and check NAT address pool
5858 self.pg3.config_ip4()
5859 adresses = self.vapi.nat44_address_dump()
5860 self.assertEqual(1, len(adresses))
5861 self.assertEqual(str(adresses[0].ip_address),
5863 self.assertEqual(adresses[0].flags, flags)
5865 # remove interface address and check NAT address pool
5866 self.pg3.unconfig_ip4()
5867 adresses = self.vapi.nat44_address_dump()
5868 self.assertEqual(0, len(adresses))
5870 def test_tcp_close(self):
5871 """ Close TCP session from inside network - output feature """
5872 self.vapi.nat44_forwarding_enable_disable(enable=1)
5873 self.nat44_add_address(self.pg1.local_ip4)
5874 twice_nat_addr = '10.0.1.3'
5875 service_ip = '192.168.16.150'
5876 self.nat44_add_address(twice_nat_addr, twice_nat=1)
5877 flags = self.config_flags.NAT_IS_INSIDE
5878 self.vapi.nat44_interface_add_del_feature(
5879 sw_if_index=self.pg0.sw_if_index,
5881 self.vapi.nat44_interface_add_del_feature(
5882 sw_if_index=self.pg0.sw_if_index,
5883 flags=flags, is_add=1)
5884 self.vapi.nat44_interface_add_del_output_feature(
5886 sw_if_index=self.pg1.sw_if_index)
5887 flags = (self.config_flags.NAT_IS_OUT2IN_ONLY |
5888 self.config_flags.NAT_IS_TWICE_NAT)
5889 self.nat44_add_static_mapping(self.pg0.remote_ip4,
5893 proto=IP_PROTOS.tcp,
5895 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4n, 0)
5896 start_sessnum = len(sessions)
5898 # SYN packet out->in
5899 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
5900 IP(src=self.pg1.remote_ip4, dst=service_ip) /
5901 TCP(sport=33898, dport=80, flags="S"))
5902 self.pg1.add_stream(p)
5903 self.pg_enable_capture(self.pg_interfaces)
5905 capture = self.pg0.get_capture(1)
5907 tcp_port = p[TCP].sport
5909 # SYN + ACK packet in->out
5910 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5911 IP(src=self.pg0.remote_ip4, dst=twice_nat_addr) /
5912 TCP(sport=80, dport=tcp_port, flags="SA"))
5913 self.pg0.add_stream(p)
5914 self.pg_enable_capture(self.pg_interfaces)
5916 self.pg1.get_capture(1)
5918 # ACK packet out->in
5919 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
5920 IP(src=self.pg1.remote_ip4, dst=service_ip) /
5921 TCP(sport=33898, dport=80, flags="A"))
5922 self.pg1.add_stream(p)
5923 self.pg_enable_capture(self.pg_interfaces)
5925 self.pg0.get_capture(1)
5927 # FIN packet in -> out
5928 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5929 IP(src=self.pg0.remote_ip4, dst=twice_nat_addr) /
5930 TCP(sport=80, dport=tcp_port, flags="FA", seq=100, ack=300))
5931 self.pg0.add_stream(p)
5932 self.pg_enable_capture(self.pg_interfaces)
5934 self.pg1.get_capture(1)
5936 # FIN+ACK packet out -> in
5937 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
5938 IP(src=self.pg1.remote_ip4, dst=service_ip) /
5939 TCP(sport=33898, dport=80, flags="FA", seq=300, ack=101))
5940 self.pg1.add_stream(p)
5941 self.pg_enable_capture(self.pg_interfaces)
5943 self.pg0.get_capture(1)
5945 # ACK packet in -> out
5946 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5947 IP(src=self.pg0.remote_ip4, dst=twice_nat_addr) /
5948 TCP(sport=80, dport=tcp_port, flags="A", seq=101, ack=301))
5949 self.pg0.add_stream(p)
5950 self.pg_enable_capture(self.pg_interfaces)
5952 self.pg1.get_capture(1)
5954 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4n,
5956 self.assertEqual(len(sessions) - start_sessnum, 0)
5958 def test_tcp_session_close_in(self):
5959 """ Close TCP session from inside network """
5960 self.tcp_port_out = 10505
5961 self.nat44_add_address(self.nat_addr)
5962 flags = self.config_flags.NAT_IS_TWICE_NAT
5963 self.nat44_add_static_mapping(self.pg0.remote_ip4,
5967 proto=IP_PROTOS.tcp,
5969 flags = self.config_flags.NAT_IS_INSIDE
5970 self.vapi.nat44_interface_add_del_feature(
5971 sw_if_index=self.pg0.sw_if_index,
5972 flags=flags, is_add=1)
5973 self.vapi.nat44_interface_add_del_feature(
5974 sw_if_index=self.pg1.sw_if_index,
5977 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4n, 0)
5978 start_sessnum = len(sessions)
5980 self.initiate_tcp_session(self.pg0, self.pg1)
5982 # FIN packet in -> out
5983 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5984 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
5985 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
5986 flags="FA", seq=100, ack=300))
5987 self.pg0.add_stream(p)
5988 self.pg_enable_capture(self.pg_interfaces)
5990 self.pg1.get_capture(1)
5994 # ACK packet out -> in
5995 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
5996 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
5997 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
5998 flags="A", seq=300, ack=101))
6001 # FIN packet out -> in
6002 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
6003 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
6004 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
6005 flags="FA", seq=300, ack=101))
6008 self.pg1.add_stream(pkts)
6009 self.pg_enable_capture(self.pg_interfaces)
6011 self.pg0.get_capture(2)
6013 # ACK packet in -> out
6014 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6015 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6016 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
6017 flags="A", seq=101, ack=301))
6018 self.pg0.add_stream(p)
6019 self.pg_enable_capture(self.pg_interfaces)
6021 self.pg1.get_capture(1)
6023 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4n,
6025 self.assertEqual(len(sessions) - start_sessnum, 0)
6027 def test_tcp_session_close_out(self):
6028 """ Close TCP session from outside network """
6029 self.tcp_port_out = 10505
6030 self.nat44_add_address(self.nat_addr)
6031 flags = self.config_flags.NAT_IS_TWICE_NAT
6032 self.nat44_add_static_mapping(self.pg0.remote_ip4,
6036 proto=IP_PROTOS.tcp,
6038 flags = self.config_flags.NAT_IS_INSIDE
6039 self.vapi.nat44_interface_add_del_feature(
6040 sw_if_index=self.pg0.sw_if_index,
6041 flags=flags, is_add=1)
6042 self.vapi.nat44_interface_add_del_feature(
6043 sw_if_index=self.pg1.sw_if_index,
6046 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4n, 0)
6047 start_sessnum = len(sessions)
6049 self.initiate_tcp_session(self.pg0, self.pg1)
6051 # FIN packet out -> in
6052 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
6053 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
6054 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
6055 flags="FA", seq=100, ack=300))
6056 self.pg1.add_stream(p)
6057 self.pg_enable_capture(self.pg_interfaces)
6059 self.pg0.get_capture(1)
6061 # FIN+ACK packet in -> out
6062 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6063 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6064 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
6065 flags="FA", seq=300, ack=101))
6067 self.pg0.add_stream(p)
6068 self.pg_enable_capture(self.pg_interfaces)
6070 self.pg1.get_capture(1)
6072 # ACK packet out -> in
6073 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
6074 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
6075 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
6076 flags="A", seq=101, ack=301))
6077 self.pg1.add_stream(p)
6078 self.pg_enable_capture(self.pg_interfaces)
6080 self.pg0.get_capture(1)
6082 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4n,
6084 self.assertEqual(len(sessions) - start_sessnum, 0)
6086 def test_tcp_session_close_simultaneous(self):
6087 """ Close TCP session from inside network """
6088 self.tcp_port_out = 10505
6089 self.nat44_add_address(self.nat_addr)
6090 flags = self.config_flags.NAT_IS_TWICE_NAT
6091 self.nat44_add_static_mapping(self.pg0.remote_ip4,
6095 proto=IP_PROTOS.tcp,
6097 flags = self.config_flags.NAT_IS_INSIDE
6098 self.vapi.nat44_interface_add_del_feature(
6099 sw_if_index=self.pg0.sw_if_index,
6100 flags=flags, is_add=1)
6101 self.vapi.nat44_interface_add_del_feature(
6102 sw_if_index=self.pg1.sw_if_index,
6105 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4n, 0)
6106 start_sessnum = len(sessions)
6108 self.initiate_tcp_session(self.pg0, self.pg1)
6110 # FIN packet in -> out
6111 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6112 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6113 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
6114 flags="FA", seq=100, ack=300))
6115 self.pg0.add_stream(p)
6116 self.pg_enable_capture(self.pg_interfaces)
6118 self.pg1.get_capture(1)
6120 # FIN packet out -> in
6121 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
6122 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
6123 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
6124 flags="FA", seq=300, ack=100))
6125 self.pg1.add_stream(p)
6126 self.pg_enable_capture(self.pg_interfaces)
6128 self.pg0.get_capture(1)
6130 # ACK packet in -> out
6131 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6132 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6133 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
6134 flags="A", seq=101, ack=301))
6135 self.pg0.add_stream(p)
6136 self.pg_enable_capture(self.pg_interfaces)
6138 self.pg1.get_capture(1)
6140 # ACK packet out -> in
6141 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
6142 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
6143 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
6144 flags="A", seq=301, ack=101))
6145 self.pg1.add_stream(p)
6146 self.pg_enable_capture(self.pg_interfaces)
6148 self.pg0.get_capture(1)
6150 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4n,
6152 self.assertEqual(len(sessions) - start_sessnum, 0)
6154 def test_one_armed_nat44_static(self):
6155 """ One armed NAT44 and 1:1 NAPT asymmetrical rule """
6156 remote_host = self.pg4.remote_hosts[0]
6157 local_host = self.pg4.remote_hosts[1]
6162 self.vapi.nat44_forwarding_enable_disable(enable=1)
6163 self.nat44_add_address(self.nat_addr, twice_nat=1)
6164 flags = (self.config_flags.NAT_IS_OUT2IN_ONLY |
6165 self.config_flags.NAT_IS_TWICE_NAT)
6166 self.nat44_add_static_mapping(local_host.ip4, self.nat_addr,
6167 local_port, external_port,
6168 proto=IP_PROTOS.tcp, flags=flags)
6169 flags = self.config_flags.NAT_IS_INSIDE
6170 self.vapi.nat44_interface_add_del_feature(
6171 sw_if_index=self.pg4.sw_if_index,
6173 self.vapi.nat44_interface_add_del_feature(
6174 sw_if_index=self.pg4.sw_if_index,
6175 flags=flags, is_add=1)
6177 # from client to service
6178 p = (Ether(src=self.pg4.remote_mac, dst=self.pg4.local_mac) /
6179 IP(src=remote_host.ip4, dst=self.nat_addr) /
6180 TCP(sport=12345, dport=external_port))
6181 self.pg4.add_stream(p)
6182 self.pg_enable_capture(self.pg_interfaces)
6184 capture = self.pg4.get_capture(1)
6189 self.assertEqual(ip.dst, local_host.ip4)
6190 self.assertEqual(ip.src, self.nat_addr)
6191 self.assertEqual(tcp.dport, local_port)
6192 self.assertNotEqual(tcp.sport, 12345)
6193 eh_port_in = tcp.sport
6194 self.assert_packet_checksums_valid(p)
6196 self.logger.error(ppp("Unexpected or invalid packet:", p))
6199 # from service back to client
6200 p = (Ether(src=self.pg4.remote_mac, dst=self.pg4.local_mac) /
6201 IP(src=local_host.ip4, dst=self.nat_addr) /
6202 TCP(sport=local_port, dport=eh_port_in))
6203 self.pg4.add_stream(p)
6204 self.pg_enable_capture(self.pg_interfaces)
6206 capture = self.pg4.get_capture(1)
6211 self.assertEqual(ip.src, self.nat_addr)
6212 self.assertEqual(ip.dst, remote_host.ip4)
6213 self.assertEqual(tcp.sport, external_port)
6214 self.assertEqual(tcp.dport, 12345)
6215 self.assert_packet_checksums_valid(p)
6217 self.logger.error(ppp("Unexpected or invalid packet:", p))
6220 def test_static_with_port_out2(self):
6221 """ 1:1 NAPT asymmetrical rule """
6226 self.vapi.nat44_forwarding_enable_disable(enable=1)
6227 flags = self.config_flags.NAT_IS_OUT2IN_ONLY
6228 self.nat44_add_static_mapping(self.pg0.remote_ip4, self.nat_addr,
6229 local_port, external_port,
6230 proto=IP_PROTOS.tcp, flags=flags)
6231 flags = self.config_flags.NAT_IS_INSIDE
6232 self.vapi.nat44_interface_add_del_feature(
6233 sw_if_index=self.pg0.sw_if_index,
6234 flags=flags, is_add=1)
6235 self.vapi.nat44_interface_add_del_feature(
6236 sw_if_index=self.pg1.sw_if_index,
6239 # from client to service
6240 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
6241 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
6242 TCP(sport=12345, dport=external_port))
6243 self.pg1.add_stream(p)
6244 self.pg_enable_capture(self.pg_interfaces)
6246 capture = self.pg0.get_capture(1)
6251 self.assertEqual(ip.dst, self.pg0.remote_ip4)
6252 self.assertEqual(tcp.dport, local_port)
6253 self.assert_packet_checksums_valid(p)
6255 self.logger.error(ppp("Unexpected or invalid packet:", p))
6259 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
6260 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6261 ICMP(type=11) / capture[0][IP])
6262 self.pg0.add_stream(p)
6263 self.pg_enable_capture(self.pg_interfaces)
6265 capture = self.pg1.get_capture(1)
6268 self.assertEqual(p[IP].src, self.nat_addr)
6270 self.assertEqual(inner.dst, self.nat_addr)
6271 self.assertEqual(inner[TCPerror].dport, external_port)
6273 self.logger.error(ppp("Unexpected or invalid packet:", p))
6276 # from service back to client
6277 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6278 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6279 TCP(sport=local_port, dport=12345))
6280 self.pg0.add_stream(p)
6281 self.pg_enable_capture(self.pg_interfaces)
6283 capture = self.pg1.get_capture(1)
6288 self.assertEqual(ip.src, self.nat_addr)
6289 self.assertEqual(tcp.sport, external_port)
6290 self.assert_packet_checksums_valid(p)
6292 self.logger.error(ppp("Unexpected or invalid packet:", p))
6296 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
6297 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
6298 ICMP(type=11) / capture[0][IP])
6299 self.pg1.add_stream(p)
6300 self.pg_enable_capture(self.pg_interfaces)
6302 capture = self.pg0.get_capture(1)
6305 self.assertEqual(p[IP].dst, self.pg0.remote_ip4)
6307 self.assertEqual(inner.src, self.pg0.remote_ip4)
6308 self.assertEqual(inner[TCPerror].sport, local_port)
6310 self.logger.error(ppp("Unexpected or invalid packet:", p))
6313 # from client to server (no translation)
6314 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
6315 IP(src=self.pg1.remote_ip4, dst=self.pg0.remote_ip4) /
6316 TCP(sport=12346, dport=local_port))
6317 self.pg1.add_stream(p)
6318 self.pg_enable_capture(self.pg_interfaces)
6320 capture = self.pg0.get_capture(1)
6325 self.assertEqual(ip.dst, self.pg0.remote_ip4)
6326 self.assertEqual(tcp.dport, local_port)
6327 self.assert_packet_checksums_valid(p)
6329 self.logger.error(ppp("Unexpected or invalid packet:", p))
6332 # from service back to client (no translation)
6333 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6334 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6335 TCP(sport=local_port, dport=12346))
6336 self.pg0.add_stream(p)
6337 self.pg_enable_capture(self.pg_interfaces)
6339 capture = self.pg1.get_capture(1)
6344 self.assertEqual(ip.src, self.pg0.remote_ip4)
6345 self.assertEqual(tcp.sport, local_port)
6346 self.assert_packet_checksums_valid(p)
6348 self.logger.error(ppp("Unexpected or invalid packet:", p))
6351 def test_output_feature(self):
6352 """ NAT44 interface output feature (in2out postrouting) """
6353 self.vapi.nat44_forwarding_enable_disable(enable=1)
6354 self.nat44_add_address(self.nat_addr)
6355 self.vapi.nat44_interface_add_del_feature(
6356 sw_if_index=self.pg0.sw_if_index,
6358 self.vapi.nat44_interface_add_del_output_feature(
6360 sw_if_index=self.pg1.sw_if_index)
6363 pkts = self.create_stream_in(self.pg0, self.pg1)
6364 self.pg0.add_stream(pkts)
6365 self.pg_enable_capture(self.pg_interfaces)
6367 capture = self.pg1.get_capture(len(pkts))
6368 self.verify_capture_out(capture)
6371 pkts = self.create_stream_out(self.pg1)
6372 self.pg1.add_stream(pkts)
6373 self.pg_enable_capture(self.pg_interfaces)
6375 capture = self.pg0.get_capture(len(pkts))
6376 self.verify_capture_in(capture, self.pg0)
6378 def test_multiple_vrf(self):
6379 """ Multiple VRF setup """
6380 external_addr = '1.2.3.4'
6385 self.vapi.nat44_forwarding_enable_disable(enable=1)
6386 self.nat44_add_address(self.nat_addr)
6387 flags = self.config_flags.NAT_IS_INSIDE
6388 self.vapi.nat44_interface_add_del_feature(
6389 sw_if_index=self.pg0.sw_if_index,
6391 self.vapi.nat44_interface_add_del_feature(
6392 sw_if_index=self.pg0.sw_if_index,
6393 flags=flags, is_add=1)
6394 self.vapi.nat44_interface_add_del_output_feature(
6396 sw_if_index=self.pg1.sw_if_index)
6397 self.vapi.nat44_interface_add_del_feature(
6398 sw_if_index=self.pg5.sw_if_index,
6400 self.vapi.nat44_interface_add_del_feature(
6401 sw_if_index=self.pg5.sw_if_index,
6402 flags=flags, is_add=1)
6403 self.vapi.nat44_interface_add_del_feature(
6404 sw_if_index=self.pg6.sw_if_index,
6406 flags = self.config_flags.NAT_IS_OUT2IN_ONLY
6407 self.nat44_add_static_mapping(self.pg5.remote_ip4, external_addr,
6408 local_port, external_port, vrf_id=1,
6409 proto=IP_PROTOS.tcp, flags=flags)
6410 self.nat44_add_static_mapping(
6411 self.pg0.remote_ip4,
6412 external_sw_if_index=self.pg0.sw_if_index,
6413 local_port=local_port,
6415 external_port=external_port,
6416 proto=IP_PROTOS.tcp,
6420 # from client to service (both VRF1)
6421 p = (Ether(src=self.pg6.remote_mac, dst=self.pg6.local_mac) /
6422 IP(src=self.pg6.remote_ip4, dst=external_addr) /
6423 TCP(sport=12345, dport=external_port))
6424 self.pg6.add_stream(p)
6425 self.pg_enable_capture(self.pg_interfaces)
6427 capture = self.pg5.get_capture(1)
6432 self.assertEqual(ip.dst, self.pg5.remote_ip4)
6433 self.assertEqual(tcp.dport, local_port)
6434 self.assert_packet_checksums_valid(p)
6436 self.logger.error(ppp("Unexpected or invalid packet:", p))
6439 # from service back to client (both VRF1)
6440 p = (Ether(src=self.pg5.remote_mac, dst=self.pg5.local_mac) /
6441 IP(src=self.pg5.remote_ip4, dst=self.pg6.remote_ip4) /
6442 TCP(sport=local_port, dport=12345))
6443 self.pg5.add_stream(p)
6444 self.pg_enable_capture(self.pg_interfaces)
6446 capture = self.pg6.get_capture(1)
6451 self.assertEqual(ip.src, external_addr)
6452 self.assertEqual(tcp.sport, external_port)
6453 self.assert_packet_checksums_valid(p)
6455 self.logger.error(ppp("Unexpected or invalid packet:", p))
6458 # dynamic NAT from VRF1 to VRF0 (output-feature)
6459 p = (Ether(src=self.pg5.remote_mac, dst=self.pg5.local_mac) /
6460 IP(src=self.pg5.remote_ip4, dst=self.pg1.remote_ip4) /
6461 TCP(sport=2345, dport=22))
6462 self.pg5.add_stream(p)
6463 self.pg_enable_capture(self.pg_interfaces)
6465 capture = self.pg1.get_capture(1)
6470 self.assertEqual(ip.src, self.nat_addr)
6471 self.assertNotEqual(tcp.sport, 2345)
6472 self.assert_packet_checksums_valid(p)
6475 self.logger.error(ppp("Unexpected or invalid packet:", p))
6478 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
6479 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
6480 TCP(sport=22, dport=port))
6481 self.pg1.add_stream(p)
6482 self.pg_enable_capture(self.pg_interfaces)
6484 capture = self.pg5.get_capture(1)
6489 self.assertEqual(ip.dst, self.pg5.remote_ip4)
6490 self.assertEqual(tcp.dport, 2345)
6491 self.assert_packet_checksums_valid(p)
6493 self.logger.error(ppp("Unexpected or invalid packet:", p))
6496 # from client VRF1 to service VRF0
6497 p = (Ether(src=self.pg6.remote_mac, dst=self.pg6.local_mac) /
6498 IP(src=self.pg6.remote_ip4, dst=self.pg0.local_ip4) /
6499 TCP(sport=12346, dport=external_port))
6500 self.pg6.add_stream(p)
6501 self.pg_enable_capture(self.pg_interfaces)
6503 capture = self.pg0.get_capture(1)
6508 self.assertEqual(ip.dst, self.pg0.remote_ip4)
6509 self.assertEqual(tcp.dport, local_port)
6510 self.assert_packet_checksums_valid(p)
6512 self.logger.error(ppp("Unexpected or invalid packet:", p))
6515 # from service VRF0 back to client VRF1
6516 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6517 IP(src=self.pg0.remote_ip4, dst=self.pg6.remote_ip4) /
6518 TCP(sport=local_port, dport=12346))
6519 self.pg0.add_stream(p)
6520 self.pg_enable_capture(self.pg_interfaces)
6522 capture = self.pg6.get_capture(1)
6527 self.assertEqual(ip.src, self.pg0.local_ip4)
6528 self.assertEqual(tcp.sport, external_port)
6529 self.assert_packet_checksums_valid(p)
6531 self.logger.error(ppp("Unexpected or invalid packet:", p))
6534 # from client VRF0 to service VRF1
6535 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6536 IP(src=self.pg0.remote_ip4, dst=external_addr) /
6537 TCP(sport=12347, dport=external_port))
6538 self.pg0.add_stream(p)
6539 self.pg_enable_capture(self.pg_interfaces)
6541 capture = self.pg5.get_capture(1)
6546 self.assertEqual(ip.dst, self.pg5.remote_ip4)
6547 self.assertEqual(tcp.dport, local_port)
6548 self.assert_packet_checksums_valid(p)
6550 self.logger.error(ppp("Unexpected or invalid packet:", p))
6553 # from service VRF1 back to client VRF0
6554 p = (Ether(src=self.pg5.remote_mac, dst=self.pg5.local_mac) /
6555 IP(src=self.pg5.remote_ip4, dst=self.pg0.remote_ip4) /
6556 TCP(sport=local_port, dport=12347))
6557 self.pg5.add_stream(p)
6558 self.pg_enable_capture(self.pg_interfaces)
6560 capture = self.pg0.get_capture(1)
6565 self.assertEqual(ip.src, external_addr)
6566 self.assertEqual(tcp.sport, external_port)
6567 self.assert_packet_checksums_valid(p)
6569 self.logger.error(ppp("Unexpected or invalid packet:", p))
6572 # from client to server (both VRF1, no translation)
6573 p = (Ether(src=self.pg6.remote_mac, dst=self.pg6.local_mac) /
6574 IP(src=self.pg6.remote_ip4, dst=self.pg5.remote_ip4) /
6575 TCP(sport=12348, dport=local_port))
6576 self.pg6.add_stream(p)
6577 self.pg_enable_capture(self.pg_interfaces)
6579 capture = self.pg5.get_capture(1)
6584 self.assertEqual(ip.dst, self.pg5.remote_ip4)
6585 self.assertEqual(tcp.dport, local_port)
6586 self.assert_packet_checksums_valid(p)
6588 self.logger.error(ppp("Unexpected or invalid packet:", p))
6591 # from server back to client (both VRF1, no translation)
6592 p = (Ether(src=self.pg5.remote_mac, dst=self.pg5.local_mac) /
6593 IP(src=self.pg5.remote_ip4, dst=self.pg6.remote_ip4) /
6594 TCP(sport=local_port, dport=12348))
6595 self.pg5.add_stream(p)
6596 self.pg_enable_capture(self.pg_interfaces)
6598 capture = self.pg6.get_capture(1)
6603 self.assertEqual(ip.src, self.pg5.remote_ip4)
6604 self.assertEqual(tcp.sport, local_port)
6605 self.assert_packet_checksums_valid(p)
6607 self.logger.error(ppp("Unexpected or invalid packet:", p))
6610 # from client VRF1 to server VRF0 (no translation)
6611 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6612 IP(src=self.pg0.remote_ip4, dst=self.pg6.remote_ip4) /
6613 TCP(sport=local_port, dport=12349))
6614 self.pg0.add_stream(p)
6615 self.pg_enable_capture(self.pg_interfaces)
6617 capture = self.pg6.get_capture(1)
6622 self.assertEqual(ip.src, self.pg0.remote_ip4)
6623 self.assertEqual(tcp.sport, local_port)
6624 self.assert_packet_checksums_valid(p)
6626 self.logger.error(ppp("Unexpected or invalid packet:", p))
6629 # from server VRF0 back to client VRF1 (no translation)
6630 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6631 IP(src=self.pg0.remote_ip4, dst=self.pg6.remote_ip4) /
6632 TCP(sport=local_port, dport=12349))
6633 self.pg0.add_stream(p)
6634 self.pg_enable_capture(self.pg_interfaces)
6636 capture = self.pg6.get_capture(1)
6641 self.assertEqual(ip.src, self.pg0.remote_ip4)
6642 self.assertEqual(tcp.sport, local_port)
6643 self.assert_packet_checksums_valid(p)
6645 self.logger.error(ppp("Unexpected or invalid packet:", p))
6648 # from client VRF0 to server VRF1 (no translation)
6649 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6650 IP(src=self.pg0.remote_ip4, dst=self.pg5.remote_ip4) /
6651 TCP(sport=12344, dport=local_port))
6652 self.pg0.add_stream(p)
6653 self.pg_enable_capture(self.pg_interfaces)
6655 capture = self.pg5.get_capture(1)
6660 self.assertEqual(ip.dst, self.pg5.remote_ip4)
6661 self.assertEqual(tcp.dport, local_port)
6662 self.assert_packet_checksums_valid(p)
6664 self.logger.error(ppp("Unexpected or invalid packet:", p))
6667 # from server VRF1 back to client VRF0 (no translation)
6668 p = (Ether(src=self.pg5.remote_mac, dst=self.pg5.local_mac) /
6669 IP(src=self.pg5.remote_ip4, dst=self.pg0.remote_ip4) /
6670 TCP(sport=local_port, dport=12344))
6671 self.pg5.add_stream(p)
6672 self.pg_enable_capture(self.pg_interfaces)
6674 capture = self.pg0.get_capture(1)
6679 self.assertEqual(ip.src, self.pg5.remote_ip4)
6680 self.assertEqual(tcp.sport, local_port)
6681 self.assert_packet_checksums_valid(p)
6683 self.logger.error(ppp("Unexpected or invalid packet:", p))
6686 @unittest.skipUnless(running_extended_tests, "part of extended tests")
6687 def test_session_timeout(self):
6688 """ NAT44 session timeouts """
6689 self.nat44_add_address(self.nat_addr)
6690 flags = self.config_flags.NAT_IS_INSIDE
6691 self.vapi.nat44_interface_add_del_feature(
6692 sw_if_index=self.pg0.sw_if_index,
6693 flags=flags, is_add=1)
6694 self.vapi.nat44_interface_add_del_feature(
6695 sw_if_index=self.pg1.sw_if_index,
6697 self.vapi.nat_set_timeouts(udp=300, tcp_established=7440,
6698 tcp_transitory=240, icmp=5)
6702 for i in range(0, max_sessions):
6703 src = "10.10.%u.%u" % ((i & 0xFF00) >> 8, i & 0xFF)
6704 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
6705 IP(src=src, dst=self.pg1.remote_ip4) /
6706 ICMP(id=1025, type='echo-request'))
6708 self.pg0.add_stream(pkts)
6709 self.pg_enable_capture(self.pg_interfaces)
6711 self.pg1.get_capture(max_sessions)
6716 for i in range(0, max_sessions):
6717 src = "10.11.%u.%u" % ((i & 0xFF00) >> 8, i & 0xFF)
6718 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
6719 IP(src=src, dst=self.pg1.remote_ip4) /
6720 ICMP(id=1026, type='echo-request'))
6722 self.pg0.add_stream(pkts)
6723 self.pg_enable_capture(self.pg_interfaces)
6725 self.pg1.get_capture(max_sessions)
6728 users = self.vapi.nat44_user_dump()
6730 nsessions = nsessions + user.nsessions
6731 self.assertLess(nsessions, 2 * max_sessions)
6733 @unittest.skipUnless(running_extended_tests, "part of extended tests")
6734 def test_session_rst_timeout(self):
6735 """ NAT44 session RST timeouts """
6736 self.nat44_add_address(self.nat_addr)
6737 flags = self.config_flags.NAT_IS_INSIDE
6738 self.vapi.nat44_interface_add_del_feature(
6739 sw_if_index=self.pg0.sw_if_index,
6740 flags=flags, is_add=1)
6741 self.vapi.nat44_interface_add_del_feature(
6742 sw_if_index=self.pg1.sw_if_index,
6744 self.vapi.nat_set_timeouts(udp=300, tcp_established=7440,
6745 tcp_transitory=5, icmp=60)
6747 self.initiate_tcp_session(self.pg0, self.pg1)
6748 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6749 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6750 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
6752 self.pg0.add_stream(p)
6753 self.pg_enable_capture(self.pg_interfaces)
6755 self.pg1.get_capture(1)
6759 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6760 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6761 TCP(sport=self.tcp_port_in + 1, dport=self.tcp_external_port + 1,
6763 self.pg0.add_stream(p)
6764 self.pg_enable_capture(self.pg_interfaces)
6766 self.pg1.get_capture(1)
6769 users = self.vapi.nat44_user_dump()
6770 self.assertEqual(len(users), 1)
6771 self.assertEqual(str(users[0].ip_address),
6772 self.pg0.remote_ip4)
6773 self.assertEqual(users[0].nsessions, 1)
6775 @unittest.skipUnless(running_extended_tests, "part of extended tests")
6776 def test_session_limit_per_user(self):
6777 """ Maximum sessions per user limit """
6778 self.nat44_add_address(self.nat_addr)
6779 flags = self.config_flags.NAT_IS_INSIDE
6780 self.vapi.nat44_interface_add_del_feature(
6781 sw_if_index=self.pg0.sw_if_index,
6782 flags=flags, is_add=1)
6783 self.vapi.nat44_interface_add_del_feature(
6784 sw_if_index=self.pg1.sw_if_index,
6786 self.vapi.set_ipfix_exporter(collector_address=self.pg2.remote_ip4n,
6787 src_address=self.pg2.local_ip4n,
6789 template_interval=10)
6790 self.vapi.nat_set_timeouts(udp=5, tcp_established=7440,
6791 tcp_transitory=240, icmp=60)
6793 # get maximum number of translations per user
6794 nat44_config = self.vapi.nat_show_config()
6797 for port in range(0, nat44_config.max_translations_per_user):
6798 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6799 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6800 UDP(sport=1025 + port, dport=1025 + port))
6803 self.pg0.add_stream(pkts)
6804 self.pg_enable_capture(self.pg_interfaces)
6806 capture = self.pg1.get_capture(len(pkts))
6808 self.vapi.nat_ipfix_enable_disable(domain_id=self.ipfix_domain_id,
6809 src_port=self.ipfix_src_port,
6812 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6813 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6814 UDP(sport=3001, dport=3002))
6815 self.pg0.add_stream(p)
6816 self.pg_enable_capture(self.pg_interfaces)
6818 capture = self.pg1.assert_nothing_captured()
6820 # verify IPFIX logging
6821 self.vapi.cli("ipfix flush") # FIXME this should be an API call
6823 capture = self.pg2.get_capture(10)
6824 ipfix = IPFIXDecoder()
6825 # first load template
6827 self.assertTrue(p.haslayer(IPFIX))
6828 if p.haslayer(Template):
6829 ipfix.add_template(p.getlayer(Template))
6830 # verify events in data set
6832 if p.haslayer(Data):
6833 data = ipfix.decode_data_set(p.getlayer(Set))
6834 self.verify_ipfix_max_entries_per_user(
6836 nat44_config.max_translations_per_user,
6837 self.pg0.remote_ip4n)
6840 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6841 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6842 UDP(sport=3001, dport=3002))
6843 self.pg0.add_stream(p)
6844 self.pg_enable_capture(self.pg_interfaces)
6846 self.pg1.get_capture(1)
6848 def test_syslog_sess(self):
6849 """ Test syslog session creation and deletion """
6850 self.vapi.syslog_set_filter(SYSLOG_SEVERITY.INFO)
6851 self.vapi.syslog_set_sender(self.pg2.local_ip4n, self.pg2.remote_ip4n)
6852 self.nat44_add_address(self.nat_addr)
6853 flags = self.config_flags.NAT_IS_INSIDE
6854 self.vapi.nat44_interface_add_del_feature(
6855 sw_if_index=self.pg0.sw_if_index,
6856 flags=flags, is_add=1)
6857 self.vapi.nat44_interface_add_del_feature(
6858 sw_if_index=self.pg1.sw_if_index,
6861 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
6862 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6863 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port))
6864 self.pg0.add_stream(p)
6865 self.pg_enable_capture(self.pg_interfaces)
6867 capture = self.pg1.get_capture(1)
6868 self.tcp_port_out = capture[0][TCP].sport
6869 capture = self.pg2.get_capture(1)
6870 self.verify_syslog_sess(capture[0][Raw].load)
6872 self.pg_enable_capture(self.pg_interfaces)
6874 self.nat44_add_address(self.nat_addr, is_add=0)
6875 capture = self.pg2.get_capture(1)
6876 self.verify_syslog_sess(capture[0][Raw].load, False)
6879 super(TestNAT44EndpointDependent, self).tearDown()
6880 if not self.vpp_dead:
6882 self.vapi.cli("clear logging")
6884 def show_commands_at_teardown(self):
6885 self.logger.info(self.vapi.cli("show nat44 addresses"))
6886 self.logger.info(self.vapi.cli("show nat44 interfaces"))
6887 self.logger.info(self.vapi.cli("show nat44 static mappings"))
6888 self.logger.info(self.vapi.cli("show nat44 interface address"))
6889 self.logger.info(self.vapi.cli("show nat44 sessions detail"))
6890 self.logger.info(self.vapi.cli("show nat44 hash tables detail"))
6891 self.logger.info(self.vapi.cli("show nat timeouts"))
6894 class TestNAT44Out2InDPO(MethodHolder):
6895 """ NAT44 Test Cases using out2in DPO """
6898 def setUpConstants(cls):
6899 super(TestNAT44Out2InDPO, cls).setUpConstants()
6900 cls.vpp_cmdline.extend(["nat", "{", "out2in dpo", "}"])
6903 def setUpClass(cls):
6904 super(TestNAT44Out2InDPO, cls).setUpClass()
6905 cls.vapi.cli("set log class nat level debug")
6908 cls.tcp_port_in = 6303
6909 cls.tcp_port_out = 6303
6910 cls.udp_port_in = 6304
6911 cls.udp_port_out = 6304
6912 cls.icmp_id_in = 6305
6913 cls.icmp_id_out = 6305
6914 cls.nat_addr = '10.0.0.3'
6915 cls.dst_ip4 = '192.168.70.1'
6917 cls.create_pg_interfaces(range(2))
6920 cls.pg0.config_ip4()
6921 cls.pg0.resolve_arp()
6924 cls.pg1.config_ip6()
6925 cls.pg1.resolve_ndp()
6927 cls.vapi.ip_add_del_route(dst_address=b'\x00' * 16,
6928 dst_address_length=0,
6929 next_hop_address=cls.pg1.remote_ip6n,
6930 next_hop_sw_if_index=cls.pg1.sw_if_index,
6934 super(TestNAT44Out2InDPO, cls).tearDownClass()
6938 def tearDownClass(cls):
6939 super(TestNAT44Out2InDPO, cls).tearDownClass()
6941 def configure_xlat(self):
6942 self.dst_ip6_pfx = '1:2:3::'
6943 self.dst_ip6_pfx_n = socket.inet_pton(socket.AF_INET6,
6945 self.dst_ip6_pfx_len = 96
6946 self.src_ip6_pfx = '4:5:6::'
6947 self.src_ip6_pfx_n = socket.inet_pton(socket.AF_INET6,
6949 self.src_ip6_pfx_len = 96
6950 self.vapi.map_add_domain(self.dst_ip6_pfx_n, self.dst_ip6_pfx_len,
6951 self.src_ip6_pfx_n, self.src_ip6_pfx_len,
6952 '\x00\x00\x00\x00', 0)
6954 @unittest.skip('Temporary disabled')
6955 def test_464xlat_ce(self):
6956 """ Test 464XLAT CE with NAT44 """
6958 nat_config = self.vapi.nat_show_config()
6959 self.assertEqual(1, nat_config.out2in_dpo)
6961 self.configure_xlat()
6963 flags = self.config_flags.NAT_IS_INSIDE
6964 self.vapi.nat44_interface_add_del_feature(
6965 sw_if_index=self.pg0.sw_if_index,
6966 flags=flags, is_add=1)
6967 self.vapi.nat44_add_del_address_range(first_ip_address=self.nat_addr_n,
6968 last_ip_address=self.nat_addr_n,
6969 vrf_id=0xFFFFFFFF, is_add=1)
6971 out_src_ip6 = self.compose_ip6(self.dst_ip4, self.dst_ip6_pfx,
6972 self.dst_ip6_pfx_len)
6973 out_dst_ip6 = self.compose_ip6(self.nat_addr, self.src_ip6_pfx,
6974 self.src_ip6_pfx_len)
6977 pkts = self.create_stream_in(self.pg0, self.pg1, self.dst_ip4)
6978 self.pg0.add_stream(pkts)
6979 self.pg_enable_capture(self.pg_interfaces)
6981 capture = self.pg1.get_capture(len(pkts))
6982 self.verify_capture_out_ip6(capture, nat_ip=out_dst_ip6,
6985 pkts = self.create_stream_out_ip6(self.pg1, out_src_ip6,
6987 self.pg1.add_stream(pkts)
6988 self.pg_enable_capture(self.pg_interfaces)
6990 capture = self.pg0.get_capture(len(pkts))
6991 self.verify_capture_in(capture, self.pg0)
6993 self.vapi.nat44_interface_add_del_feature(
6994 sw_if_index=self.pg0.sw_if_index,
6996 self.vapi.nat44_add_del_address_range(
6997 first_ip_address=self.nat_addr_n,
6998 last_ip_address=self.nat_addr_n,
7001 @unittest.skip('Temporary disabled')
7002 def test_464xlat_ce_no_nat(self):
7003 """ Test 464XLAT CE without NAT44 """
7005 self.configure_xlat()
7007 out_src_ip6 = self.compose_ip6(self.dst_ip4, self.dst_ip6_pfx,
7008 self.dst_ip6_pfx_len)
7009 out_dst_ip6 = self.compose_ip6(self.pg0.remote_ip4, self.src_ip6_pfx,
7010 self.src_ip6_pfx_len)
7012 pkts = self.create_stream_in(self.pg0, self.pg1, self.dst_ip4)
7013 self.pg0.add_stream(pkts)
7014 self.pg_enable_capture(self.pg_interfaces)
7016 capture = self.pg1.get_capture(len(pkts))
7017 self.verify_capture_out_ip6(capture, dst_ip=out_src_ip6,
7018 nat_ip=out_dst_ip6, same_port=True)
7020 pkts = self.create_stream_out_ip6(self.pg1, out_src_ip6, out_dst_ip6)
7021 self.pg1.add_stream(pkts)
7022 self.pg_enable_capture(self.pg_interfaces)
7024 capture = self.pg0.get_capture(len(pkts))
7025 self.verify_capture_in(capture, self.pg0)
7028 class TestDeterministicNAT(MethodHolder):
7029 """ Deterministic NAT Test Cases """
7032 def setUpConstants(cls):
7033 super(TestDeterministicNAT, cls).setUpConstants()
7034 cls.vpp_cmdline.extend(["nat", "{", "deterministic", "}"])
7037 def setUpClass(cls):
7038 super(TestDeterministicNAT, cls).setUpClass()
7039 cls.vapi.cli("set log class nat level debug")
7042 cls.tcp_port_in = 6303
7043 cls.tcp_external_port = 6303
7044 cls.udp_port_in = 6304
7045 cls.udp_external_port = 6304
7046 cls.icmp_id_in = 6305
7047 cls.nat_addr = '10.0.0.3'
7049 cls.create_pg_interfaces(range(3))
7050 cls.interfaces = list(cls.pg_interfaces)
7052 for i in cls.interfaces:
7057 cls.pg0.generate_remote_hosts(2)
7058 cls.pg0.configure_ipv4_neighbors()
7061 super(TestDeterministicNAT, cls).tearDownClass()
7065 def tearDownClass(cls):
7066 super(TestDeterministicNAT, cls).tearDownClass()
7068 def create_stream_in(self, in_if, out_if, ttl=64):
7070 Create packet stream for inside network
7072 :param in_if: Inside interface
7073 :param out_if: Outside interface
7074 :param ttl: TTL of generated packets
7078 p = (Ether(dst=in_if.local_mac, src=in_if.remote_mac) /
7079 IP(src=in_if.remote_ip4, dst=out_if.remote_ip4, ttl=ttl) /
7080 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port))
7084 p = (Ether(dst=in_if.local_mac, src=in_if.remote_mac) /
7085 IP(src=in_if.remote_ip4, dst=out_if.remote_ip4, ttl=ttl) /
7086 UDP(sport=self.udp_port_in, dport=self.udp_external_port))
7090 p = (Ether(dst=in_if.local_mac, src=in_if.remote_mac) /
7091 IP(src=in_if.remote_ip4, dst=out_if.remote_ip4, ttl=ttl) /
7092 ICMP(id=self.icmp_id_in, type='echo-request'))
7097 def create_stream_out(self, out_if, dst_ip=None, ttl=64):
7099 Create packet stream for outside network
7101 :param out_if: Outside interface
7102 :param dst_ip: Destination IP address (Default use global NAT address)
7103 :param ttl: TTL of generated packets
7106 dst_ip = self.nat_addr
7109 p = (Ether(dst=out_if.local_mac, src=out_if.remote_mac) /
7110 IP(src=out_if.remote_ip4, dst=dst_ip, ttl=ttl) /
7111 TCP(dport=self.tcp_port_out, sport=self.tcp_external_port))
7115 p = (Ether(dst=out_if.local_mac, src=out_if.remote_mac) /
7116 IP(src=out_if.remote_ip4, dst=dst_ip, ttl=ttl) /
7117 UDP(dport=self.udp_port_out, sport=self.udp_external_port))
7121 p = (Ether(dst=out_if.local_mac, src=out_if.remote_mac) /
7122 IP(src=out_if.remote_ip4, dst=dst_ip, ttl=ttl) /
7123 ICMP(id=self.icmp_external_id, type='echo-reply'))
7128 def verify_capture_out(self, capture, nat_ip=None):
7130 Verify captured packets on outside network
7132 :param capture: Captured packets
7133 :param nat_ip: Translated IP address (Default use global NAT address)
7134 :param same_port: Source port number is not translated (Default False)
7137 nat_ip = self.nat_addr
7138 for packet in capture:
7140 self.assertEqual(packet[IP].src, nat_ip)
7141 if packet.haslayer(TCP):
7142 self.tcp_port_out = packet[TCP].sport
7143 elif packet.haslayer(UDP):
7144 self.udp_port_out = packet[UDP].sport
7146 self.icmp_external_id = packet[ICMP].id
7148 self.logger.error(ppp("Unexpected or invalid packet "
7149 "(outside network):", packet))
7152 def test_deterministic_mode(self):
7153 """ NAT plugin run deterministic mode """
7154 in_addr = '172.16.255.0'
7155 out_addr = '172.17.255.50'
7156 in_addr_t = '172.16.255.20'
7160 nat_config = self.vapi.nat_show_config()
7161 self.assertEqual(1, nat_config.deterministic)
7163 self.vapi.nat_det_add_del_map(is_add=1, in_addr=in_addr,
7164 in_plen=in_plen, out_addr=out_addr,
7167 rep1 = self.vapi.nat_det_forward(in_addr_t)
7168 self.assertEqual(str(rep1.out_addr), out_addr)
7169 rep2 = self.vapi.nat_det_reverse(rep1.out_port_hi, out_addr)
7171 self.assertEqual(str(rep2.in_addr), in_addr_t)
7173 deterministic_mappings = self.vapi.nat_det_map_dump()
7174 self.assertEqual(len(deterministic_mappings), 1)
7175 dsm = deterministic_mappings[0]
7176 self.assertEqual(in_addr, str(dsm.in_addr))
7177 self.assertEqual(in_plen, dsm.in_plen)
7178 self.assertEqual(out_addr, str(dsm.out_addr))
7179 self.assertEqual(out_plen, dsm.out_plen)
7181 self.clear_nat_det()
7182 deterministic_mappings = self.vapi.nat_det_map_dump()
7183 self.assertEqual(len(deterministic_mappings), 0)
7185 def test_set_timeouts(self):
7186 """ Set deterministic NAT timeouts """
7187 timeouts_before = self.vapi.nat_get_timeouts()
7189 self.vapi.nat_set_timeouts(
7190 udp=timeouts_before.udp + 10,
7191 tcp_established=timeouts_before.tcp_established + 10,
7192 tcp_transitory=timeouts_before.tcp_transitory + 10,
7193 icmp=timeouts_before.icmp + 10)
7195 timeouts_after = self.vapi.nat_get_timeouts()
7197 self.assertNotEqual(timeouts_before.udp, timeouts_after.udp)
7198 self.assertNotEqual(timeouts_before.icmp, timeouts_after.icmp)
7199 self.assertNotEqual(timeouts_before.tcp_established,
7200 timeouts_after.tcp_established)
7201 self.assertNotEqual(timeouts_before.tcp_transitory,
7202 timeouts_after.tcp_transitory)
7204 def test_det_in(self):
7205 """ Deterministic NAT translation test (TCP, UDP, ICMP) """
7207 nat_ip = "10.0.0.10"
7209 self.vapi.nat_det_add_del_map(is_add=1, in_addr=self.pg0.remote_ip4n,
7211 out_addr=socket.inet_aton(nat_ip),
7214 flags = self.config_flags.NAT_IS_INSIDE
7215 self.vapi.nat44_interface_add_del_feature(
7216 sw_if_index=self.pg0.sw_if_index,
7217 flags=flags, is_add=1)
7218 self.vapi.nat44_interface_add_del_feature(
7219 sw_if_index=self.pg1.sw_if_index,
7223 pkts = self.create_stream_in(self.pg0, self.pg1)
7224 self.pg0.add_stream(pkts)
7225 self.pg_enable_capture(self.pg_interfaces)
7227 capture = self.pg1.get_capture(len(pkts))
7228 self.verify_capture_out(capture, nat_ip)
7231 pkts = self.create_stream_out(self.pg1, nat_ip)
7232 self.pg1.add_stream(pkts)
7233 self.pg_enable_capture(self.pg_interfaces)
7235 capture = self.pg0.get_capture(len(pkts))
7236 self.verify_capture_in(capture, self.pg0)
7239 sessions = self.vapi.nat_det_session_dump(self.pg0.remote_ip4n)
7240 self.assertEqual(len(sessions), 3)
7244 self.assertEqual(str(s.ext_addr), self.pg1.remote_ip4)
7245 self.assertEqual(s.in_port, self.tcp_port_in)
7246 self.assertEqual(s.out_port, self.tcp_port_out)
7247 self.assertEqual(s.ext_port, self.tcp_external_port)
7251 self.assertEqual(str(s.ext_addr), self.pg1.remote_ip4)
7252 self.assertEqual(s.in_port, self.udp_port_in)
7253 self.assertEqual(s.out_port, self.udp_port_out)
7254 self.assertEqual(s.ext_port, self.udp_external_port)
7258 self.assertEqual(str(s.ext_addr), self.pg1.remote_ip4)
7259 self.assertEqual(s.in_port, self.icmp_id_in)
7260 self.assertEqual(s.out_port, self.icmp_external_id)
7262 def test_multiple_users(self):
7263 """ Deterministic NAT multiple users """
7265 nat_ip = "10.0.0.10"
7267 external_port = 6303
7269 host0 = self.pg0.remote_hosts[0]
7270 host1 = self.pg0.remote_hosts[1]
7272 self.vapi.nat_det_add_del_map(is_add=1, in_addr=host0.ip4n, in_plen=24,
7273 out_addr=socket.inet_aton(nat_ip),
7275 flags = self.config_flags.NAT_IS_INSIDE
7276 self.vapi.nat44_interface_add_del_feature(
7277 sw_if_index=self.pg0.sw_if_index,
7278 flags=flags, is_add=1)
7279 self.vapi.nat44_interface_add_del_feature(
7280 sw_if_index=self.pg1.sw_if_index,
7284 p = (Ether(src=host0.mac, dst=self.pg0.local_mac) /
7285 IP(src=host0.ip4, dst=self.pg1.remote_ip4) /
7286 TCP(sport=port_in, dport=external_port))
7287 self.pg0.add_stream(p)
7288 self.pg_enable_capture(self.pg_interfaces)
7290 capture = self.pg1.get_capture(1)
7295 self.assertEqual(ip.src, nat_ip)
7296 self.assertEqual(ip.dst, self.pg1.remote_ip4)
7297 self.assertEqual(tcp.dport, external_port)
7298 port_out0 = tcp.sport
7300 self.logger.error(ppp("Unexpected or invalid packet:", p))
7304 p = (Ether(src=host1.mac, dst=self.pg0.local_mac) /
7305 IP(src=host1.ip4, dst=self.pg1.remote_ip4) /
7306 TCP(sport=port_in, dport=external_port))
7307 self.pg0.add_stream(p)
7308 self.pg_enable_capture(self.pg_interfaces)
7310 capture = self.pg1.get_capture(1)
7315 self.assertEqual(ip.src, nat_ip)
7316 self.assertEqual(ip.dst, self.pg1.remote_ip4)
7317 self.assertEqual(tcp.dport, external_port)
7318 port_out1 = tcp.sport
7320 self.logger.error(ppp("Unexpected or invalid packet:", p))
7323 dms = self.vapi.nat_det_map_dump()
7324 self.assertEqual(1, len(dms))
7325 self.assertEqual(2, dms[0].ses_num)
7328 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
7329 IP(src=self.pg1.remote_ip4, dst=nat_ip) /
7330 TCP(sport=external_port, dport=port_out0))
7331 self.pg1.add_stream(p)
7332 self.pg_enable_capture(self.pg_interfaces)
7334 capture = self.pg0.get_capture(1)
7339 self.assertEqual(ip.src, self.pg1.remote_ip4)
7340 self.assertEqual(ip.dst, host0.ip4)
7341 self.assertEqual(tcp.dport, port_in)
7342 self.assertEqual(tcp.sport, external_port)
7344 self.logger.error(ppp("Unexpected or invalid packet:", p))
7348 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
7349 IP(src=self.pg1.remote_ip4, dst=nat_ip) /
7350 TCP(sport=external_port, dport=port_out1))
7351 self.pg1.add_stream(p)
7352 self.pg_enable_capture(self.pg_interfaces)
7354 capture = self.pg0.get_capture(1)
7359 self.assertEqual(ip.src, self.pg1.remote_ip4)
7360 self.assertEqual(ip.dst, host1.ip4)
7361 self.assertEqual(tcp.dport, port_in)
7362 self.assertEqual(tcp.sport, external_port)
7364 self.logger.error(ppp("Unexpected or invalid packet", p))
7367 # session close api test
7368 self.vapi.nat_det_close_session_out(socket.inet_aton(nat_ip),
7370 self.pg1.remote_ip4n,
7372 dms = self.vapi.nat_det_map_dump()
7373 self.assertEqual(dms[0].ses_num, 1)
7375 self.vapi.nat_det_close_session_in(host0.ip4n,
7377 self.pg1.remote_ip4n,
7379 dms = self.vapi.nat_det_map_dump()
7380 self.assertEqual(dms[0].ses_num, 0)
7382 def test_tcp_session_close_detection_in(self):
7383 """ Deterministic NAT TCP session close from inside network """
7384 self.vapi.nat_det_add_del_map(is_add=1, in_addr=self.pg0.remote_ip4n,
7386 out_addr=socket.inet_aton(self.nat_addr),
7388 flags = self.config_flags.NAT_IS_INSIDE
7389 self.vapi.nat44_interface_add_del_feature(
7390 sw_if_index=self.pg0.sw_if_index,
7391 flags=flags, is_add=1)
7392 self.vapi.nat44_interface_add_del_feature(
7393 sw_if_index=self.pg1.sw_if_index,
7396 self.initiate_tcp_session(self.pg0, self.pg1)
7398 # close the session from inside
7400 # FIN packet in -> out
7401 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
7402 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
7403 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
7405 self.pg0.add_stream(p)
7406 self.pg_enable_capture(self.pg_interfaces)
7408 self.pg1.get_capture(1)
7412 # ACK packet out -> in
7413 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
7414 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
7415 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
7419 # FIN packet out -> in
7420 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
7421 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
7422 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
7426 self.pg1.add_stream(pkts)
7427 self.pg_enable_capture(self.pg_interfaces)
7429 self.pg0.get_capture(2)
7431 # ACK packet in -> out
7432 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
7433 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
7434 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
7436 self.pg0.add_stream(p)
7437 self.pg_enable_capture(self.pg_interfaces)
7439 self.pg1.get_capture(1)
7441 # Check if deterministic NAT44 closed the session
7442 dms = self.vapi.nat_det_map_dump()
7443 self.assertEqual(0, dms[0].ses_num)
7445 self.logger.error("TCP session termination failed")
7448 def test_tcp_session_close_detection_out(self):
7449 """ Deterministic NAT TCP session close from outside network """
7450 self.vapi.nat_det_add_del_map(is_add=1, in_addr=self.pg0.remote_ip4n,
7452 out_addr=socket.inet_aton(self.nat_addr),
7454 flags = self.config_flags.NAT_IS_INSIDE
7455 self.vapi.nat44_interface_add_del_feature(
7456 sw_if_index=self.pg0.sw_if_index,
7457 flags=flags, is_add=1)
7458 self.vapi.nat44_interface_add_del_feature(
7459 sw_if_index=self.pg1.sw_if_index,
7462 self.initiate_tcp_session(self.pg0, self.pg1)
7464 # close the session from outside
7466 # FIN packet out -> in
7467 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
7468 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
7469 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
7471 self.pg1.add_stream(p)
7472 self.pg_enable_capture(self.pg_interfaces)
7474 self.pg0.get_capture(1)
7478 # ACK packet in -> out
7479 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
7480 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
7481 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
7485 # ACK packet in -> out
7486 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
7487 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
7488 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
7492 self.pg0.add_stream(pkts)
7493 self.pg_enable_capture(self.pg_interfaces)
7495 self.pg1.get_capture(2)
7497 # ACK packet out -> in
7498 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
7499 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
7500 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
7502 self.pg1.add_stream(p)
7503 self.pg_enable_capture(self.pg_interfaces)
7505 self.pg0.get_capture(1)
7507 # Check if deterministic NAT44 closed the session
7508 dms = self.vapi.nat_det_map_dump()
7509 self.assertEqual(0, dms[0].ses_num)
7511 self.logger.error("TCP session termination failed")
7514 @unittest.skipUnless(running_extended_tests, "part of extended tests")
7515 def test_session_timeout(self):
7516 """ Deterministic NAT session timeouts """
7517 self.vapi.nat_det_add_del_map(is_add=1, in_addr=self.pg0.remote_ip4n,
7519 out_addr=socket.inet_aton(self.nat_addr),
7521 flags = self.config_flags.NAT_IS_INSIDE
7522 self.vapi.nat44_interface_add_del_feature(
7523 sw_if_index=self.pg0.sw_if_index,
7524 flags=flags, is_add=1)
7525 self.vapi.nat44_interface_add_del_feature(
7526 sw_if_index=self.pg1.sw_if_index,
7529 self.initiate_tcp_session(self.pg0, self.pg1)
7530 self.vapi.nat_set_timeouts(udp=5, tcp_established=5, tcp_transitory=5,
7532 pkts = self.create_stream_in(self.pg0, self.pg1)
7533 self.pg0.add_stream(pkts)
7534 self.pg_enable_capture(self.pg_interfaces)
7536 capture = self.pg1.get_capture(len(pkts))
7539 dms = self.vapi.nat_det_map_dump()
7540 self.assertEqual(0, dms[0].ses_num)
7542 @unittest.skipUnless(running_extended_tests, "part of extended tests")
7543 def test_session_limit_per_user(self):
7544 """ Deterministic NAT maximum sessions per user limit """
7545 self.vapi.nat_det_add_del_map(is_add=1, in_addr=self.pg0.remote_ip4n,
7547 out_addr=socket.inet_aton(self.nat_addr),
7549 flags = self.config_flags.NAT_IS_INSIDE
7550 self.vapi.nat44_interface_add_del_feature(
7551 sw_if_index=self.pg0.sw_if_index,
7552 flags=flags, is_add=1)
7553 self.vapi.nat44_interface_add_del_feature(
7554 sw_if_index=self.pg1.sw_if_index,
7556 self.vapi.set_ipfix_exporter(collector_address=self.pg2.remote_ip4n,
7557 src_address=self.pg2.local_ip4n,
7559 template_interval=10)
7560 self.vapi.nat_ipfix_enable_disable(domain_id=1, src_port=4739,
7564 for port in range(1025, 2025):
7565 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
7566 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
7567 UDP(sport=port, dport=port))
7570 self.pg0.add_stream(pkts)
7571 self.pg_enable_capture(self.pg_interfaces)
7573 capture = self.pg1.get_capture(len(pkts))
7575 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
7576 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
7577 UDP(sport=3001, dport=3002))
7578 self.pg0.add_stream(p)
7579 self.pg_enable_capture(self.pg_interfaces)
7581 capture = self.pg1.assert_nothing_captured()
7583 # verify ICMP error packet
7584 capture = self.pg0.get_capture(1)
7586 self.assertTrue(p.haslayer(ICMP))
7588 self.assertEqual(icmp.type, 3)
7589 self.assertEqual(icmp.code, 1)
7590 self.assertTrue(icmp.haslayer(IPerror))
7591 inner_ip = icmp[IPerror]
7592 self.assertEqual(inner_ip[UDPerror].sport, 3001)
7593 self.assertEqual(inner_ip[UDPerror].dport, 3002)
7595 dms = self.vapi.nat_det_map_dump()
7597 self.assertEqual(1000, dms[0].ses_num)
7599 # verify IPFIX logging
7600 self.vapi.cli("ipfix flush") # FIXME this should be an API call
7602 capture = self.pg2.get_capture(2)
7603 ipfix = IPFIXDecoder()
7604 # first load template
7606 self.assertTrue(p.haslayer(IPFIX))
7607 if p.haslayer(Template):
7608 ipfix.add_template(p.getlayer(Template))
7609 # verify events in data set
7611 if p.haslayer(Data):
7612 data = ipfix.decode_data_set(p.getlayer(Set))
7613 self.verify_ipfix_max_entries_per_user(data,
7615 self.pg0.remote_ip4n)
7617 def clear_nat_det(self):
7619 Clear deterministic NAT configuration.
7621 self.vapi.nat_ipfix_enable_disable(domain_id=1, src_port=4739,
7623 self.vapi.nat_set_timeouts(udp=300, tcp_established=7440,
7624 tcp_transitory=240, icmp=60)
7625 deterministic_mappings = self.vapi.nat_det_map_dump()
7626 for dsm in deterministic_mappings:
7627 self.vapi.nat_det_add_del_map(is_add=0, in_addr=dsm.in_addr,
7628 in_plen=dsm.in_plen,
7629 out_addr=dsm.out_addr,
7630 out_plen=dsm.out_plen)
7632 interfaces = self.vapi.nat44_interface_dump()
7633 for intf in interfaces:
7634 self.vapi.nat44_interface_add_del_feature(
7635 sw_if_index=intf.sw_if_index,
7639 super(TestDeterministicNAT, self).tearDown()
7640 if not self.vpp_dead:
7641 self.clear_nat_det()
7643 def show_commands_at_teardown(self):
7644 self.logger.info(self.vapi.cli("show nat44 interfaces"))
7645 self.logger.info(self.vapi.cli("show nat timeouts"))
7647 self.vapi.cli("show nat44 deterministic mappings"))
7649 self.vapi.cli("show nat44 deterministic sessions"))
7652 class TestNAT64(MethodHolder):
7653 """ NAT64 Test Cases """
7656 def setUpConstants(cls):
7657 super(TestNAT64, cls).setUpConstants()
7658 cls.vpp_cmdline.extend(["nat", "{", "nat64 bib hash buckets 128",
7659 "nat64 st hash buckets 256", "}"])
7662 def setUpClass(cls):
7663 super(TestNAT64, cls).setUpClass()
7666 cls.tcp_port_in = 6303
7667 cls.tcp_port_out = 6303
7668 cls.udp_port_in = 6304
7669 cls.udp_port_out = 6304
7670 cls.icmp_id_in = 6305
7671 cls.icmp_id_out = 6305
7672 cls.tcp_external_port = 80
7673 cls.nat_addr = '10.0.0.3'
7674 cls.nat_addr_n = socket.inet_pton(socket.AF_INET, cls.nat_addr)
7676 cls.vrf1_nat_addr = '10.0.10.3'
7677 cls.ipfix_src_port = 4739
7678 cls.ipfix_domain_id = 1
7680 cls.create_pg_interfaces(range(6))
7681 cls.ip6_interfaces = list(cls.pg_interfaces[0:1])
7682 cls.ip6_interfaces.append(cls.pg_interfaces[2])
7683 cls.ip4_interfaces = list(cls.pg_interfaces[1:2])
7685 cls.vapi.ip_table_add_del(is_ipv6=1, is_add=1,
7686 table_id=cls.vrf1_id)
7688 cls.pg_interfaces[2].set_table_ip6(cls.vrf1_id)
7690 cls.pg0.generate_remote_hosts(2)
7692 for i in cls.ip6_interfaces:
7695 i.configure_ipv6_neighbors()
7697 for i in cls.ip4_interfaces:
7703 cls.pg3.config_ip4()
7704 cls.pg3.resolve_arp()
7705 cls.pg3.config_ip6()
7706 cls.pg3.configure_ipv6_neighbors()
7709 cls.pg5.config_ip6()
7712 super(TestNAT64, cls).tearDownClass()
7716 def tearDownClass(cls):
7717 super(TestNAT64, cls).tearDownClass()
7719 def test_nat64_inside_interface_handles_neighbor_advertisement(self):
7720 """ NAT64 inside interface handles Neighbor Advertisement """
7722 flags = self.config_flags.NAT_IS_INSIDE
7723 self.vapi.nat64_add_del_interface(is_add=1, flags=flags,
7724 sw_if_index=self.pg5.sw_if_index)
7727 ping = (Ether(dst=self.pg5.local_mac, src=self.pg5.remote_mac) /
7728 IPv6(src=self.pg5.remote_ip6, dst=self.pg5.local_ip6) /
7729 ICMPv6EchoRequest())
7731 self.pg5.add_stream(pkts)
7732 self.pg_enable_capture(self.pg_interfaces)
7735 # Wait for Neighbor Solicitation
7736 capture = self.pg5.get_capture(len(pkts))
7739 self.assertEqual(packet[IPv6].src, self.pg5.local_ip6)
7740 self.assertEqual(packet.haslayer(ICMPv6ND_NS), 1)
7741 tgt = packet[ICMPv6ND_NS].tgt
7743 self.logger.error(ppp("Unexpected or invalid packet:", packet))
7746 # Send Neighbor Advertisement
7747 p = (Ether(dst=self.pg5.local_mac, src=self.pg5.remote_mac) /
7748 IPv6(src=self.pg5.remote_ip6, dst=self.pg5.local_ip6) /
7749 ICMPv6ND_NA(tgt=tgt) /
7750 ICMPv6NDOptDstLLAddr(lladdr=self.pg5.remote_mac))
7752 self.pg5.add_stream(pkts)
7753 self.pg_enable_capture(self.pg_interfaces)
7756 # Try to send ping again
7758 self.pg5.add_stream(pkts)
7759 self.pg_enable_capture(self.pg_interfaces)
7762 # Wait for ping reply
7763 capture = self.pg5.get_capture(len(pkts))
7766 self.assertEqual(packet[IPv6].src, self.pg5.local_ip6)
7767 self.assertEqual(packet[IPv6].dst, self.pg5.remote_ip6)
7768 self.assertEqual(packet.haslayer(ICMPv6EchoReply), 1)
7770 self.logger.error(ppp("Unexpected or invalid packet:", packet))
7773 def test_pool(self):
7774 """ Add/delete address to NAT64 pool """
7775 nat_addr = '1.2.3.4'
7777 self.vapi.nat64_add_del_pool_addr_range(start_addr=nat_addr,
7779 vrf_id=0xFFFFFFFF, is_add=1)
7781 addresses = self.vapi.nat64_pool_addr_dump()
7782 self.assertEqual(len(addresses), 1)
7783 self.assertEqual(str(addresses[0].address), nat_addr)
7785 self.vapi.nat64_add_del_pool_addr_range(start_addr=nat_addr,
7787 vrf_id=0xFFFFFFFF, is_add=0)
7789 addresses = self.vapi.nat64_pool_addr_dump()
7790 self.assertEqual(len(addresses), 0)
7792 def test_interface(self):
7793 """ Enable/disable NAT64 feature on the interface """
7794 flags = self.config_flags.NAT_IS_INSIDE
7795 self.vapi.nat64_add_del_interface(is_add=1, flags=flags,
7796 sw_if_index=self.pg0.sw_if_index)
7797 self.vapi.nat64_add_del_interface(is_add=1, flags=0,
7798 sw_if_index=self.pg1.sw_if_index)
7800 interfaces = self.vapi.nat64_interface_dump()
7801 self.assertEqual(len(interfaces), 2)
7804 for intf in interfaces:
7805 if intf.sw_if_index == self.pg0.sw_if_index:
7806 self.assertEqual(intf.flags, self.config_flags.NAT_IS_INSIDE)
7808 elif intf.sw_if_index == self.pg1.sw_if_index:
7809 self.assertEqual(intf.flags, self.config_flags.NAT_IS_OUTSIDE)
7811 self.assertTrue(pg0_found)
7812 self.assertTrue(pg1_found)
7814 features = self.vapi.cli("show interface features pg0")
7815 self.assertIn('nat64-in2out', features)
7816 features = self.vapi.cli("show interface features pg1")
7817 self.assertIn('nat64-out2in', features)
7819 self.vapi.nat64_add_del_interface(is_add=0, flags=flags,
7820 sw_if_index=self.pg0.sw_if_index)
7821 self.vapi.nat64_add_del_interface(is_add=0, flags=flags,
7822 sw_if_index=self.pg1.sw_if_index)
7824 interfaces = self.vapi.nat64_interface_dump()
7825 self.assertEqual(len(interfaces), 0)
7827 def test_static_bib(self):
7828 """ Add/delete static BIB entry """
7829 in_addr = '2001:db8:85a3::8a2e:370:7334'
7830 out_addr = '10.1.1.3'
7833 proto = IP_PROTOS.tcp
7835 self.vapi.nat64_add_del_static_bib(i_addr=in_addr, o_addr=out_addr,
7836 i_port=in_port, o_port=out_port,
7837 proto=proto, vrf_id=0, is_add=1)
7838 bib = self.vapi.nat64_bib_dump(proto=IP_PROTOS.tcp)
7841 if bibe.flags & self.config_flags.NAT_IS_STATIC:
7843 self.assertEqual(str(bibe.i_addr), in_addr)
7844 self.assertEqual(str(bibe.o_addr), out_addr)
7845 self.assertEqual(bibe.i_port, in_port)
7846 self.assertEqual(bibe.o_port, out_port)
7847 self.assertEqual(static_bib_num, 1)
7848 bibs = self.statistics.get_counter('/nat64/total-bibs')
7849 self.assertEqual(bibs[0][0], 1)
7851 self.vapi.nat64_add_del_static_bib(i_addr=in_addr, o_addr=out_addr,
7852 i_port=in_port, o_port=out_port,
7853 proto=proto, vrf_id=0, is_add=0)
7854 bib = self.vapi.nat64_bib_dump(proto=IP_PROTOS.tcp)
7857 if bibe.flags & self.config_flags.NAT_IS_STATIC:
7859 self.assertEqual(static_bib_num, 0)
7860 bibs = self.statistics.get_counter('/nat64/total-bibs')
7861 self.assertEqual(bibs[0][0], 0)
7863 def test_set_timeouts(self):
7864 """ Set NAT64 timeouts """
7865 # verify default values
7866 timeouts = self.vapi.nat_get_timeouts()
7867 self.assertEqual(timeouts.udp, 300)
7868 self.assertEqual(timeouts.icmp, 60)
7869 self.assertEqual(timeouts.tcp_transitory, 240)
7870 self.assertEqual(timeouts.tcp_established, 7440)
7872 # set and verify custom values
7873 self.vapi.nat_set_timeouts(udp=200, tcp_established=7450,
7874 tcp_transitory=250, icmp=30)
7875 timeouts = self.vapi.nat_get_timeouts()
7876 self.assertEqual(timeouts.udp, 200)
7877 self.assertEqual(timeouts.icmp, 30)
7878 self.assertEqual(timeouts.tcp_transitory, 250)
7879 self.assertEqual(timeouts.tcp_established, 7450)
7881 def test_dynamic(self):
7882 """ NAT64 dynamic translation test """
7883 self.tcp_port_in = 6303
7884 self.udp_port_in = 6304
7885 self.icmp_id_in = 6305
7887 ses_num_start = self.nat64_get_ses_num()
7889 self.vapi.nat64_add_del_pool_addr_range(start_addr=self.nat_addr,
7890 end_addr=self.nat_addr,
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)
7900 tcpn = self.statistics.get_counter('/err/nat64-in2out/TCP packets')
7901 udpn = self.statistics.get_counter('/err/nat64-in2out/UDP packets')
7902 icmpn = self.statistics.get_counter('/err/nat64-in2out/ICMP packets')
7903 totaln = self.statistics.get_counter(
7904 '/err/nat64-in2out/good in2out packets processed')
7906 pkts = self.create_stream_in_ip6(self.pg0, self.pg1)
7907 self.pg0.add_stream(pkts)
7908 self.pg_enable_capture(self.pg_interfaces)
7910 capture = self.pg1.get_capture(len(pkts))
7911 self.verify_capture_out(capture, nat_ip=self.nat_addr,
7912 dst_ip=self.pg1.remote_ip4)
7914 err = self.statistics.get_counter('/err/nat64-in2out/TCP packets')
7915 self.assertEqual(err - tcpn, 1)
7916 err = self.statistics.get_counter('/err/nat64-in2out/UDP packets')
7917 self.assertEqual(err - udpn, 1)
7918 err = self.statistics.get_counter('/err/nat64-in2out/ICMP packets')
7919 self.assertEqual(err - icmpn, 1)
7920 err = self.statistics.get_counter(
7921 '/err/nat64-in2out/good in2out packets processed')
7922 self.assertEqual(err - totaln, 3)
7925 tcpn = self.statistics.get_counter('/err/nat64-out2in/TCP packets')
7926 udpn = self.statistics.get_counter('/err/nat64-out2in/UDP packets')
7927 icmpn = self.statistics.get_counter('/err/nat64-out2in/ICMP packets')
7928 totaln = self.statistics.get_counter(
7929 '/err/nat64-out2in/good out2in packets processed')
7931 pkts = self.create_stream_out(self.pg1, dst_ip=self.nat_addr)
7932 self.pg1.add_stream(pkts)
7933 self.pg_enable_capture(self.pg_interfaces)
7935 capture = self.pg0.get_capture(len(pkts))
7936 ip = IPv6(src=''.join(['64:ff9b::', self.pg1.remote_ip4]))
7937 self.verify_capture_in_ip6(capture, ip[IPv6].src, self.pg0.remote_ip6)
7939 err = self.statistics.get_counter('/err/nat64-out2in/TCP packets')
7940 self.assertEqual(err - tcpn, 1)
7941 err = self.statistics.get_counter('/err/nat64-out2in/UDP packets')
7942 self.assertEqual(err - udpn, 1)
7943 err = self.statistics.get_counter('/err/nat64-out2in/ICMP packets')
7944 self.assertEqual(err - icmpn, 1)
7945 err = self.statistics.get_counter(
7946 '/err/nat64-out2in/good out2in packets processed')
7947 self.assertEqual(err - totaln, 3)
7949 bibs = self.statistics.get_counter('/nat64/total-bibs')
7950 self.assertEqual(bibs[0][0], 3)
7951 sessions = self.statistics.get_counter('/nat64/total-sessions')
7952 self.assertEqual(sessions[0][0], 3)
7955 pkts = self.create_stream_in_ip6(self.pg0, self.pg1)
7956 self.pg0.add_stream(pkts)
7957 self.pg_enable_capture(self.pg_interfaces)
7959 capture = self.pg1.get_capture(len(pkts))
7960 self.verify_capture_out(capture, nat_ip=self.nat_addr,
7961 dst_ip=self.pg1.remote_ip4)
7964 pkts = self.create_stream_out(self.pg1, dst_ip=self.nat_addr)
7965 self.pg1.add_stream(pkts)
7966 self.pg_enable_capture(self.pg_interfaces)
7968 capture = self.pg0.get_capture(len(pkts))
7969 self.verify_capture_in_ip6(capture, ip[IPv6].src, self.pg0.remote_ip6)
7971 ses_num_end = self.nat64_get_ses_num()
7973 self.assertEqual(ses_num_end - ses_num_start, 3)
7975 # tenant with specific VRF
7976 self.vapi.nat64_add_del_pool_addr_range(start_addr=self.vrf1_nat_addr,
7977 end_addr=self.vrf1_nat_addr,
7978 vrf_id=self.vrf1_id, is_add=1)
7979 flags = self.config_flags.NAT_IS_INSIDE
7980 self.vapi.nat64_add_del_interface(is_add=1, flags=flags,
7981 sw_if_index=self.pg2.sw_if_index)
7983 pkts = self.create_stream_in_ip6(self.pg2, self.pg1)
7984 self.pg2.add_stream(pkts)
7985 self.pg_enable_capture(self.pg_interfaces)
7987 capture = self.pg1.get_capture(len(pkts))
7988 self.verify_capture_out(capture, nat_ip=self.vrf1_nat_addr,
7989 dst_ip=self.pg1.remote_ip4)
7991 pkts = self.create_stream_out(self.pg1, dst_ip=self.vrf1_nat_addr)
7992 self.pg1.add_stream(pkts)
7993 self.pg_enable_capture(self.pg_interfaces)
7995 capture = self.pg2.get_capture(len(pkts))
7996 self.verify_capture_in_ip6(capture, ip[IPv6].src, self.pg2.remote_ip6)
7998 def test_static(self):
7999 """ NAT64 static translation test """
8000 self.tcp_port_in = 60303
8001 self.udp_port_in = 60304
8002 self.icmp_id_in = 60305
8003 self.tcp_port_out = 60303
8004 self.udp_port_out = 60304
8005 self.icmp_id_out = 60305
8007 ses_num_start = self.nat64_get_ses_num()
8009 self.vapi.nat64_add_del_pool_addr_range(start_addr=self.nat_addr,
8010 end_addr=self.nat_addr,
8013 flags = self.config_flags.NAT_IS_INSIDE
8014 self.vapi.nat64_add_del_interface(is_add=1, flags=flags,
8015 sw_if_index=self.pg0.sw_if_index)
8016 self.vapi.nat64_add_del_interface(is_add=1, flags=0,
8017 sw_if_index=self.pg1.sw_if_index)
8019 self.vapi.nat64_add_del_static_bib(i_addr=self.pg0.remote_ip6n,
8020 o_addr=self.nat_addr,
8021 i_port=self.tcp_port_in,
8022 o_port=self.tcp_port_out,
8023 proto=IP_PROTOS.tcp, vrf_id=0,
8025 self.vapi.nat64_add_del_static_bib(i_addr=self.pg0.remote_ip6n,
8026 o_addr=self.nat_addr,
8027 i_port=self.udp_port_in,
8028 o_port=self.udp_port_out,
8029 proto=IP_PROTOS.udp, vrf_id=0,
8031 self.vapi.nat64_add_del_static_bib(i_addr=self.pg0.remote_ip6n,
8032 o_addr=self.nat_addr,
8033 i_port=self.icmp_id_in,
8034 o_port=self.icmp_id_out,
8035 proto=IP_PROTOS.icmp, vrf_id=0,
8039 pkts = self.create_stream_in_ip6(self.pg0, self.pg1)
8040 self.pg0.add_stream(pkts)
8041 self.pg_enable_capture(self.pg_interfaces)
8043 capture = self.pg1.get_capture(len(pkts))
8044 self.verify_capture_out(capture, nat_ip=self.nat_addr,
8045 dst_ip=self.pg1.remote_ip4, same_port=True)
8048 pkts = self.create_stream_out(self.pg1, dst_ip=self.nat_addr)
8049 self.pg1.add_stream(pkts)
8050 self.pg_enable_capture(self.pg_interfaces)
8052 capture = self.pg0.get_capture(len(pkts))
8053 ip = IPv6(src=''.join(['64:ff9b::', self.pg1.remote_ip4]))
8054 self.verify_capture_in_ip6(capture, ip[IPv6].src, self.pg0.remote_ip6)
8056 ses_num_end = self.nat64_get_ses_num()
8058 self.assertEqual(ses_num_end - ses_num_start, 3)
8060 @unittest.skipUnless(running_extended_tests, "part of extended tests")
8061 def test_session_timeout(self):
8062 """ NAT64 session timeout """
8063 self.icmp_id_in = 1234
8064 self.vapi.nat64_add_del_pool_addr_range(start_addr=self.nat_addr,
8065 end_addr=self.nat_addr,
8068 flags = self.config_flags.NAT_IS_INSIDE
8069 self.vapi.nat64_add_del_interface(is_add=1, flags=flags,
8070 sw_if_index=self.pg0.sw_if_index)
8071 self.vapi.nat64_add_del_interface(is_add=1, flags=0,
8072 sw_if_index=self.pg1.sw_if_index)
8073 self.vapi.nat_set_timeouts(udp=300, tcp_established=5,
8077 pkts = self.create_stream_in_ip6(self.pg0, self.pg1)
8078 self.pg0.add_stream(pkts)
8079 self.pg_enable_capture(self.pg_interfaces)
8081 capture = self.pg1.get_capture(len(pkts))
8083 ses_num_before_timeout = self.nat64_get_ses_num()
8087 # ICMP and TCP session after timeout
8088 ses_num_after_timeout = self.nat64_get_ses_num()
8089 self.assertEqual(ses_num_before_timeout - ses_num_after_timeout, 2)
8091 def test_icmp_error(self):
8092 """ NAT64 ICMP Error message translation """
8093 self.tcp_port_in = 6303
8094 self.udp_port_in = 6304
8095 self.icmp_id_in = 6305
8097 self.vapi.nat64_add_del_pool_addr_range(start_addr=self.nat_addr,
8098 end_addr=self.nat_addr,
8101 flags = self.config_flags.NAT_IS_INSIDE
8102 self.vapi.nat64_add_del_interface(is_add=1, flags=flags,
8103 sw_if_index=self.pg0.sw_if_index)
8104 self.vapi.nat64_add_del_interface(is_add=1, flags=0,
8105 sw_if_index=self.pg1.sw_if_index)
8107 # send some packets to create sessions
8108 pkts = self.create_stream_in_ip6(self.pg0, self.pg1)
8109 self.pg0.add_stream(pkts)
8110 self.pg_enable_capture(self.pg_interfaces)
8112 capture_ip4 = self.pg1.get_capture(len(pkts))
8113 self.verify_capture_out(capture_ip4,
8114 nat_ip=self.nat_addr,
8115 dst_ip=self.pg1.remote_ip4)
8117 pkts = self.create_stream_out(self.pg1, dst_ip=self.nat_addr)
8118 self.pg1.add_stream(pkts)
8119 self.pg_enable_capture(self.pg_interfaces)
8121 capture_ip6 = self.pg0.get_capture(len(pkts))
8122 ip = IPv6(src=''.join(['64:ff9b::', self.pg1.remote_ip4]))
8123 self.verify_capture_in_ip6(capture_ip6, ip[IPv6].src,
8124 self.pg0.remote_ip6)
8127 pkts = [Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
8128 IPv6(src=self.pg0.remote_ip6, dst=ip[IPv6].src) /
8129 ICMPv6DestUnreach(code=1) /
8130 packet[IPv6] for packet in capture_ip6]
8131 self.pg0.add_stream(pkts)
8132 self.pg_enable_capture(self.pg_interfaces)
8134 capture = self.pg1.get_capture(len(pkts))
8135 for packet in capture:
8137 self.assertEqual(packet[IP].src, self.nat_addr)
8138 self.assertEqual(packet[IP].dst, self.pg1.remote_ip4)
8139 self.assertEqual(packet[ICMP].type, 3)
8140 self.assertEqual(packet[ICMP].code, 13)
8141 inner = packet[IPerror]
8142 self.assertEqual(inner.src, self.pg1.remote_ip4)
8143 self.assertEqual(inner.dst, self.nat_addr)
8144 self.assert_packet_checksums_valid(packet)
8145 if inner.haslayer(TCPerror):
8146 self.assertEqual(inner[TCPerror].dport, self.tcp_port_out)
8147 elif inner.haslayer(UDPerror):
8148 self.assertEqual(inner[UDPerror].dport, self.udp_port_out)
8150 self.assertEqual(inner[ICMPerror].id, self.icmp_id_out)
8152 self.logger.error(ppp("Unexpected or invalid packet:", packet))
8156 pkts = [Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
8157 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
8158 ICMP(type=3, code=13) /
8159 packet[IP] for packet in capture_ip4]
8160 self.pg1.add_stream(pkts)
8161 self.pg_enable_capture(self.pg_interfaces)
8163 capture = self.pg0.get_capture(len(pkts))
8164 for packet in capture:
8166 self.assertEqual(packet[IPv6].src, ip.src)
8167 self.assertEqual(packet[IPv6].dst, self.pg0.remote_ip6)
8168 icmp = packet[ICMPv6DestUnreach]
8169 self.assertEqual(icmp.code, 1)
8170 inner = icmp[IPerror6]
8171 self.assertEqual(inner.src, self.pg0.remote_ip6)
8172 self.assertEqual(inner.dst, ip.src)
8173 self.assert_icmpv6_checksum_valid(packet)
8174 if inner.haslayer(TCPerror):
8175 self.assertEqual(inner[TCPerror].sport, self.tcp_port_in)
8176 elif inner.haslayer(UDPerror):
8177 self.assertEqual(inner[UDPerror].sport, self.udp_port_in)
8179 self.assertEqual(inner[ICMPv6EchoRequest].id,
8182 self.logger.error(ppp("Unexpected or invalid packet:", packet))
8185 def test_hairpinning(self):
8186 """ NAT64 hairpinning """
8188 client = self.pg0.remote_hosts[0]
8189 server = self.pg0.remote_hosts[1]
8190 server_tcp_in_port = 22
8191 server_tcp_out_port = 4022
8192 server_udp_in_port = 23
8193 server_udp_out_port = 4023
8194 client_tcp_in_port = 1234
8195 client_udp_in_port = 1235
8196 client_tcp_out_port = 0
8197 client_udp_out_port = 0
8198 ip = IPv6(src=''.join(['64:ff9b::', self.nat_addr]))
8199 nat_addr_ip6 = ip.src
8201 self.vapi.nat64_add_del_pool_addr_range(start_addr=self.nat_addr,
8202 end_addr=self.nat_addr,
8205 flags = self.config_flags.NAT_IS_INSIDE
8206 self.vapi.nat64_add_del_interface(is_add=1, flags=flags,
8207 sw_if_index=self.pg0.sw_if_index)
8208 self.vapi.nat64_add_del_interface(is_add=1, flags=0,
8209 sw_if_index=self.pg1.sw_if_index)
8211 self.vapi.nat64_add_del_static_bib(i_addr=server.ip6n,
8212 o_addr=self.nat_addr,
8213 i_port=server_tcp_in_port,
8214 o_port=server_tcp_out_port,
8215 proto=IP_PROTOS.tcp, vrf_id=0,
8217 self.vapi.nat64_add_del_static_bib(i_addr=server.ip6n,
8218 o_addr=self.nat_addr,
8219 i_port=server_udp_in_port,
8220 o_port=server_udp_out_port,
8221 proto=IP_PROTOS.udp, vrf_id=0,
8226 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
8227 IPv6(src=client.ip6, dst=nat_addr_ip6) /
8228 TCP(sport=client_tcp_in_port, dport=server_tcp_out_port))
8230 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
8231 IPv6(src=client.ip6, dst=nat_addr_ip6) /
8232 UDP(sport=client_udp_in_port, dport=server_udp_out_port))
8234 self.pg0.add_stream(pkts)
8235 self.pg_enable_capture(self.pg_interfaces)
8237 capture = self.pg0.get_capture(len(pkts))
8238 for packet in capture:
8240 self.assertEqual(packet[IPv6].src, nat_addr_ip6)
8241 self.assertEqual(packet[IPv6].dst, server.ip6)
8242 self.assert_packet_checksums_valid(packet)
8243 if packet.haslayer(TCP):
8244 self.assertNotEqual(packet[TCP].sport, client_tcp_in_port)
8245 self.assertEqual(packet[TCP].dport, server_tcp_in_port)
8246 client_tcp_out_port = packet[TCP].sport
8248 self.assertNotEqual(packet[UDP].sport, client_udp_in_port)
8249 self.assertEqual(packet[UDP].dport, server_udp_in_port)
8250 client_udp_out_port = packet[UDP].sport
8252 self.logger.error(ppp("Unexpected or invalid packet:", packet))
8257 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
8258 IPv6(src=server.ip6, dst=nat_addr_ip6) /
8259 TCP(sport=server_tcp_in_port, dport=client_tcp_out_port))
8261 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
8262 IPv6(src=server.ip6, dst=nat_addr_ip6) /
8263 UDP(sport=server_udp_in_port, dport=client_udp_out_port))
8265 self.pg0.add_stream(pkts)
8266 self.pg_enable_capture(self.pg_interfaces)
8268 capture = self.pg0.get_capture(len(pkts))
8269 for packet in capture:
8271 self.assertEqual(packet[IPv6].src, nat_addr_ip6)
8272 self.assertEqual(packet[IPv6].dst, client.ip6)
8273 self.assert_packet_checksums_valid(packet)
8274 if packet.haslayer(TCP):
8275 self.assertEqual(packet[TCP].sport, server_tcp_out_port)
8276 self.assertEqual(packet[TCP].dport, client_tcp_in_port)
8278 self.assertEqual(packet[UDP].sport, server_udp_out_port)
8279 self.assertEqual(packet[UDP].dport, client_udp_in_port)
8281 self.logger.error(ppp("Unexpected or invalid packet:", packet))
8286 pkts = [Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
8287 IPv6(src=client.ip6, dst=nat_addr_ip6) /
8288 ICMPv6DestUnreach(code=1) /
8289 packet[IPv6] for packet in capture]
8290 self.pg0.add_stream(pkts)
8291 self.pg_enable_capture(self.pg_interfaces)
8293 capture = self.pg0.get_capture(len(pkts))
8294 for packet in capture:
8296 self.assertEqual(packet[IPv6].src, nat_addr_ip6)
8297 self.assertEqual(packet[IPv6].dst, server.ip6)
8298 icmp = packet[ICMPv6DestUnreach]
8299 self.assertEqual(icmp.code, 1)
8300 inner = icmp[IPerror6]
8301 self.assertEqual(inner.src, server.ip6)
8302 self.assertEqual(inner.dst, nat_addr_ip6)
8303 self.assert_packet_checksums_valid(packet)
8304 if inner.haslayer(TCPerror):
8305 self.assertEqual(inner[TCPerror].sport, server_tcp_in_port)
8306 self.assertEqual(inner[TCPerror].dport,
8307 client_tcp_out_port)
8309 self.assertEqual(inner[UDPerror].sport, server_udp_in_port)
8310 self.assertEqual(inner[UDPerror].dport,
8311 client_udp_out_port)
8313 self.logger.error(ppp("Unexpected or invalid packet:", packet))
8316 def test_prefix(self):
8317 """ NAT64 Network-Specific Prefix """
8319 self.vapi.nat64_add_del_pool_addr_range(start_addr=self.nat_addr,
8320 end_addr=self.nat_addr,
8323 flags = self.config_flags.NAT_IS_INSIDE
8324 self.vapi.nat64_add_del_interface(is_add=1, flags=flags,
8325 sw_if_index=self.pg0.sw_if_index)
8326 self.vapi.nat64_add_del_interface(is_add=1, flags=0,
8327 sw_if_index=self.pg1.sw_if_index)
8328 self.vapi.nat64_add_del_pool_addr_range(start_addr=self.vrf1_nat_addr,
8329 end_addr=self.vrf1_nat_addr,
8330 vrf_id=self.vrf1_id, is_add=1)
8331 self.vapi.nat64_add_del_interface(is_add=1, flags=flags,
8332 sw_if_index=self.pg2.sw_if_index)
8335 global_pref64 = "2001:db8::"
8336 global_pref64_len = 32
8337 global_pref64_str = "{}/{}".format(global_pref64, global_pref64_len)
8338 self.vapi.nat64_add_del_prefix(prefix=global_pref64_str, vrf_id=0,
8341 prefix = self.vapi.nat64_prefix_dump()
8342 self.assertEqual(len(prefix), 1)
8343 self.assertEqual(prefix[0].prefix,
8344 IPv6Network(unicode(global_pref64_str)))
8345 self.assertEqual(prefix[0].vrf_id, 0)
8347 # Add tenant specific prefix
8348 vrf1_pref64 = "2001:db8:122:300::"
8349 vrf1_pref64_len = 56
8350 vrf1_pref64_str = "{}/{}".format(vrf1_pref64, vrf1_pref64_len)
8351 self.vapi.nat64_add_del_prefix(prefix=vrf1_pref64_str,
8352 vrf_id=self.vrf1_id, is_add=1)
8354 prefix = self.vapi.nat64_prefix_dump()
8355 self.assertEqual(len(prefix), 2)
8358 pkts = self.create_stream_in_ip6(self.pg0,
8361 plen=global_pref64_len)
8362 self.pg0.add_stream(pkts)
8363 self.pg_enable_capture(self.pg_interfaces)
8365 capture = self.pg1.get_capture(len(pkts))
8366 self.verify_capture_out(capture, nat_ip=self.nat_addr,
8367 dst_ip=self.pg1.remote_ip4)
8369 pkts = self.create_stream_out(self.pg1, dst_ip=self.nat_addr)
8370 self.pg1.add_stream(pkts)
8371 self.pg_enable_capture(self.pg_interfaces)
8373 capture = self.pg0.get_capture(len(pkts))
8374 dst_ip = self.compose_ip6(self.pg1.remote_ip4,
8377 self.verify_capture_in_ip6(capture, dst_ip, self.pg0.remote_ip6)
8379 # Tenant specific prefix
8380 pkts = self.create_stream_in_ip6(self.pg2,
8383 plen=vrf1_pref64_len)
8384 self.pg2.add_stream(pkts)
8385 self.pg_enable_capture(self.pg_interfaces)
8387 capture = self.pg1.get_capture(len(pkts))
8388 self.verify_capture_out(capture, nat_ip=self.vrf1_nat_addr,
8389 dst_ip=self.pg1.remote_ip4)
8391 pkts = self.create_stream_out(self.pg1, dst_ip=self.vrf1_nat_addr)
8392 self.pg1.add_stream(pkts)
8393 self.pg_enable_capture(self.pg_interfaces)
8395 capture = self.pg2.get_capture(len(pkts))
8396 dst_ip = self.compose_ip6(self.pg1.remote_ip4,
8399 self.verify_capture_in_ip6(capture, dst_ip, self.pg2.remote_ip6)
8401 def test_unknown_proto(self):
8402 """ NAT64 translate packet with unknown protocol """
8404 self.vapi.nat64_add_del_pool_addr_range(start_addr=self.nat_addr,
8405 end_addr=self.nat_addr,
8408 flags = self.config_flags.NAT_IS_INSIDE
8409 self.vapi.nat64_add_del_interface(is_add=1, flags=flags,
8410 sw_if_index=self.pg0.sw_if_index)
8411 self.vapi.nat64_add_del_interface(is_add=1, flags=0,
8412 sw_if_index=self.pg1.sw_if_index)
8413 remote_ip6 = self.compose_ip6(self.pg1.remote_ip4, '64:ff9b::', 96)
8416 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
8417 IPv6(src=self.pg0.remote_ip6, dst=remote_ip6) /
8418 TCP(sport=self.tcp_port_in, dport=20))
8419 self.pg0.add_stream(p)
8420 self.pg_enable_capture(self.pg_interfaces)
8422 p = self.pg1.get_capture(1)
8424 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
8425 IPv6(src=self.pg0.remote_ip6, dst=remote_ip6, nh=47) /
8427 IP(src=self.pg2.local_ip4, dst=self.pg2.remote_ip4) /
8428 TCP(sport=1234, dport=1234))
8429 self.pg0.add_stream(p)
8430 self.pg_enable_capture(self.pg_interfaces)
8432 p = self.pg1.get_capture(1)
8435 self.assertEqual(packet[IP].src, self.nat_addr)
8436 self.assertEqual(packet[IP].dst, self.pg1.remote_ip4)
8437 self.assertEqual(packet.haslayer(GRE), 1)
8438 self.assert_packet_checksums_valid(packet)
8440 self.logger.error(ppp("Unexpected or invalid packet:", packet))
8444 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
8445 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
8447 IP(src=self.pg2.remote_ip4, dst=self.pg2.local_ip4) /
8448 TCP(sport=1234, dport=1234))
8449 self.pg1.add_stream(p)
8450 self.pg_enable_capture(self.pg_interfaces)
8452 p = self.pg0.get_capture(1)
8455 self.assertEqual(packet[IPv6].src, remote_ip6)
8456 self.assertEqual(packet[IPv6].dst, self.pg0.remote_ip6)
8457 self.assertEqual(packet[IPv6].nh, 47)
8459 self.logger.error(ppp("Unexpected or invalid packet:", packet))
8462 def test_hairpinning_unknown_proto(self):
8463 """ NAT64 translate packet with unknown protocol - hairpinning """
8465 client = self.pg0.remote_hosts[0]
8466 server = self.pg0.remote_hosts[1]
8467 server_tcp_in_port = 22
8468 server_tcp_out_port = 4022
8469 client_tcp_in_port = 1234
8470 client_tcp_out_port = 1235
8471 server_nat_ip = "10.0.0.100"
8472 client_nat_ip = "10.0.0.110"
8473 server_nat_ip6 = self.compose_ip6(server_nat_ip, '64:ff9b::', 96)
8474 client_nat_ip6 = self.compose_ip6(client_nat_ip, '64:ff9b::', 96)
8476 self.vapi.nat64_add_del_pool_addr_range(start_addr=server_nat_ip,
8477 end_addr=client_nat_ip,
8480 flags = self.config_flags.NAT_IS_INSIDE
8481 self.vapi.nat64_add_del_interface(is_add=1, flags=flags,
8482 sw_if_index=self.pg0.sw_if_index)
8483 self.vapi.nat64_add_del_interface(is_add=1, flags=0,
8484 sw_if_index=self.pg1.sw_if_index)
8486 self.vapi.nat64_add_del_static_bib(i_addr=server.ip6n,
8487 o_addr=server_nat_ip,
8488 i_port=server_tcp_in_port,
8489 o_port=server_tcp_out_port,
8490 proto=IP_PROTOS.tcp, vrf_id=0,
8493 self.vapi.nat64_add_del_static_bib(i_addr=server.ip6n,
8494 o_addr=server_nat_ip, i_port=0,
8496 proto=IP_PROTOS.gre, vrf_id=0,
8499 self.vapi.nat64_add_del_static_bib(i_addr=client.ip6n,
8500 o_addr=client_nat_ip,
8501 i_port=client_tcp_in_port,
8502 o_port=client_tcp_out_port,
8503 proto=IP_PROTOS.tcp, vrf_id=0,
8507 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
8508 IPv6(src=client.ip6, dst=server_nat_ip6) /
8509 TCP(sport=client_tcp_in_port, dport=server_tcp_out_port))
8510 self.pg0.add_stream(p)
8511 self.pg_enable_capture(self.pg_interfaces)
8513 p = self.pg0.get_capture(1)
8515 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
8516 IPv6(src=client.ip6, dst=server_nat_ip6, nh=IP_PROTOS.gre) /
8518 IP(src=self.pg2.local_ip4, dst=self.pg2.remote_ip4) /
8519 TCP(sport=1234, dport=1234))
8520 self.pg0.add_stream(p)
8521 self.pg_enable_capture(self.pg_interfaces)
8523 p = self.pg0.get_capture(1)
8526 self.assertEqual(packet[IPv6].src, client_nat_ip6)
8527 self.assertEqual(packet[IPv6].dst, server.ip6)
8528 self.assertEqual(packet[IPv6].nh, IP_PROTOS.gre)
8530 self.logger.error(ppp("Unexpected or invalid packet:", packet))
8534 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
8535 IPv6(src=server.ip6, dst=client_nat_ip6, nh=IP_PROTOS.gre) /
8537 IP(src=self.pg2.remote_ip4, dst=self.pg2.local_ip4) /
8538 TCP(sport=1234, dport=1234))
8539 self.pg0.add_stream(p)
8540 self.pg_enable_capture(self.pg_interfaces)
8542 p = self.pg0.get_capture(1)
8545 self.assertEqual(packet[IPv6].src, server_nat_ip6)
8546 self.assertEqual(packet[IPv6].dst, client.ip6)
8547 self.assertEqual(packet[IPv6].nh, IP_PROTOS.gre)
8549 self.logger.error(ppp("Unexpected or invalid packet:", packet))
8552 def test_one_armed_nat64(self):
8553 """ One armed NAT64 """
8555 remote_host_ip6 = self.compose_ip6(self.pg3.remote_ip4,
8559 self.vapi.nat64_add_del_pool_addr_range(start_addr=self.nat_addr,
8560 end_addr=self.nat_addr,
8563 flags = self.config_flags.NAT_IS_INSIDE
8564 self.vapi.nat64_add_del_interface(is_add=1, flags=flags,
8565 sw_if_index=self.pg3.sw_if_index)
8566 self.vapi.nat64_add_del_interface(is_add=1, flags=0,
8567 sw_if_index=self.pg3.sw_if_index)
8570 p = (Ether(src=self.pg3.remote_mac, dst=self.pg3.local_mac) /
8571 IPv6(src=self.pg3.remote_ip6, dst=remote_host_ip6) /
8572 TCP(sport=12345, dport=80))
8573 self.pg3.add_stream(p)
8574 self.pg_enable_capture(self.pg_interfaces)
8576 capture = self.pg3.get_capture(1)
8581 self.assertEqual(ip.src, self.nat_addr)
8582 self.assertEqual(ip.dst, self.pg3.remote_ip4)
8583 self.assertNotEqual(tcp.sport, 12345)
8584 external_port = tcp.sport
8585 self.assertEqual(tcp.dport, 80)
8586 self.assert_packet_checksums_valid(p)
8588 self.logger.error(ppp("Unexpected or invalid packet:", p))
8592 p = (Ether(src=self.pg3.remote_mac, dst=self.pg3.local_mac) /
8593 IP(src=self.pg3.remote_ip4, dst=self.nat_addr) /
8594 TCP(sport=80, dport=external_port))
8595 self.pg3.add_stream(p)
8596 self.pg_enable_capture(self.pg_interfaces)
8598 capture = self.pg3.get_capture(1)
8603 self.assertEqual(ip.src, remote_host_ip6)
8604 self.assertEqual(ip.dst, self.pg3.remote_ip6)
8605 self.assertEqual(tcp.sport, 80)
8606 self.assertEqual(tcp.dport, 12345)
8607 self.assert_packet_checksums_valid(p)
8609 self.logger.error(ppp("Unexpected or invalid packet:", p))
8612 def test_frag_in_order(self):
8613 """ NAT64 translate fragments arriving in order """
8614 self.tcp_port_in = random.randint(1025, 65535)
8616 self.vapi.nat64_add_del_pool_addr_range(start_addr=self.nat_addr,
8617 end_addr=self.nat_addr,
8620 flags = self.config_flags.NAT_IS_INSIDE
8621 self.vapi.nat64_add_del_interface(is_add=1, flags=flags,
8622 sw_if_index=self.pg0.sw_if_index)
8623 self.vapi.nat64_add_del_interface(is_add=1, flags=0,
8624 sw_if_index=self.pg1.sw_if_index)
8626 reass = self.vapi.nat_reass_dump()
8627 reass_n_start = len(reass)
8631 pkts = self.create_stream_frag_ip6(self.pg0, self.pg1.remote_ip4,
8632 self.tcp_port_in, 20, data)
8633 self.pg0.add_stream(pkts)
8634 self.pg_enable_capture(self.pg_interfaces)
8636 frags = self.pg1.get_capture(len(pkts))
8637 p = self.reass_frags_and_verify(frags,
8639 self.pg1.remote_ip4)
8640 self.assertEqual(p[TCP].dport, 20)
8641 self.assertNotEqual(p[TCP].sport, self.tcp_port_in)
8642 self.tcp_port_out = p[TCP].sport
8643 self.assertEqual(data, p[Raw].load)
8646 data = b"A" * 4 + b"b" * 16 + b"C" * 3
8647 pkts = self.create_stream_frag(self.pg1,
8652 self.pg1.add_stream(pkts)
8653 self.pg_enable_capture(self.pg_interfaces)
8655 frags = self.pg0.get_capture(len(pkts))
8656 src = self.compose_ip6(self.pg1.remote_ip4, '64:ff9b::', 96)
8657 p = self.reass_frags_and_verify_ip6(frags, src, self.pg0.remote_ip6)
8658 self.assertEqual(p[TCP].sport, 20)
8659 self.assertEqual(p[TCP].dport, self.tcp_port_in)
8660 self.assertEqual(data, p[Raw].load)
8662 reass = self.vapi.nat_reass_dump()
8663 reass_n_end = len(reass)
8665 self.assertEqual(reass_n_end - reass_n_start, 2)
8667 def test_reass_hairpinning(self):
8668 """ NAT64 fragments hairpinning """
8670 server = self.pg0.remote_hosts[1]
8671 server_in_port = random.randint(1025, 65535)
8672 server_out_port = random.randint(1025, 65535)
8673 client_in_port = random.randint(1025, 65535)
8674 ip = IPv6(src=''.join(['64:ff9b::', self.nat_addr]))
8675 nat_addr_ip6 = ip.src
8677 self.vapi.nat64_add_del_pool_addr_range(start_addr=self.nat_addr,
8678 end_addr=self.nat_addr,
8681 flags = self.config_flags.NAT_IS_INSIDE
8682 self.vapi.nat64_add_del_interface(is_add=1, flags=flags,
8683 sw_if_index=self.pg0.sw_if_index)
8684 self.vapi.nat64_add_del_interface(is_add=1, flags=0,
8685 sw_if_index=self.pg1.sw_if_index)
8687 # add static BIB entry for server
8688 self.vapi.nat64_add_del_static_bib(i_addr=server.ip6n,
8689 o_addr=self.nat_addr,
8690 i_port=server_in_port,
8691 o_port=server_out_port,
8692 proto=IP_PROTOS.tcp, vrf_id=0,
8695 # send packet from host to server
8696 pkts = self.create_stream_frag_ip6(self.pg0,
8701 self.pg0.add_stream(pkts)
8702 self.pg_enable_capture(self.pg_interfaces)
8704 frags = self.pg0.get_capture(len(pkts))
8705 p = self.reass_frags_and_verify_ip6(frags, nat_addr_ip6, server.ip6)
8706 self.assertNotEqual(p[TCP].sport, client_in_port)
8707 self.assertEqual(p[TCP].dport, server_in_port)
8708 self.assertEqual(data, p[Raw].load)
8710 def test_frag_out_of_order(self):
8711 """ NAT64 translate fragments arriving out of order """
8712 self.tcp_port_in = random.randint(1025, 65535)
8714 self.vapi.nat64_add_del_pool_addr_range(start_addr=self.nat_addr,
8715 end_addr=self.nat_addr,
8718 flags = self.config_flags.NAT_IS_INSIDE
8719 self.vapi.nat64_add_del_interface(is_add=1, flags=flags,
8720 sw_if_index=self.pg0.sw_if_index)
8721 self.vapi.nat64_add_del_interface(is_add=1, flags=0,
8722 sw_if_index=self.pg1.sw_if_index)
8726 pkts = self.create_stream_frag_ip6(self.pg0, self.pg1.remote_ip4,
8727 self.tcp_port_in, 20, data)
8729 self.pg0.add_stream(pkts)
8730 self.pg_enable_capture(self.pg_interfaces)
8732 frags = self.pg1.get_capture(len(pkts))
8733 p = self.reass_frags_and_verify(frags,
8735 self.pg1.remote_ip4)
8736 self.assertEqual(p[TCP].dport, 20)
8737 self.assertNotEqual(p[TCP].sport, self.tcp_port_in)
8738 self.tcp_port_out = p[TCP].sport
8739 self.assertEqual(data, p[Raw].load)
8742 data = b"A" * 4 + b"B" * 16 + b"C" * 3
8743 pkts = self.create_stream_frag(self.pg1,
8749 self.pg1.add_stream(pkts)
8750 self.pg_enable_capture(self.pg_interfaces)
8752 frags = self.pg0.get_capture(len(pkts))
8753 src = self.compose_ip6(self.pg1.remote_ip4, '64:ff9b::', 96)
8754 p = self.reass_frags_and_verify_ip6(frags, src, self.pg0.remote_ip6)
8755 self.assertEqual(p[TCP].sport, 20)
8756 self.assertEqual(p[TCP].dport, self.tcp_port_in)
8757 self.assertEqual(data, p[Raw].load)
8759 def test_interface_addr(self):
8760 """ Acquire NAT64 pool addresses from interface """
8761 self.vapi.nat64_add_del_interface_addr(
8763 sw_if_index=self.pg4.sw_if_index)
8765 # no address in NAT64 pool
8766 addresses = self.vapi.nat44_address_dump()
8767 self.assertEqual(0, len(addresses))
8769 # configure interface address and check NAT64 address pool
8770 self.pg4.config_ip4()
8771 addresses = self.vapi.nat64_pool_addr_dump()
8772 self.assertEqual(len(addresses), 1)
8774 self.assertEqual(str(addresses[0].address),
8777 # remove interface address and check NAT64 address pool
8778 self.pg4.unconfig_ip4()
8779 addresses = self.vapi.nat64_pool_addr_dump()
8780 self.assertEqual(0, len(addresses))
8782 @unittest.skipUnless(running_extended_tests, "part of extended tests")
8783 def test_ipfix_max_bibs_sessions(self):
8784 """ IPFIX logging maximum session and BIB entries exceeded """
8787 remote_host_ip6 = self.compose_ip6(self.pg1.remote_ip4,
8791 self.vapi.nat64_add_del_pool_addr_range(start_addr=self.nat_addr,
8792 end_addr=self.nat_addr,
8795 flags = self.config_flags.NAT_IS_INSIDE
8796 self.vapi.nat64_add_del_interface(is_add=1, flags=flags,
8797 sw_if_index=self.pg0.sw_if_index)
8798 self.vapi.nat64_add_del_interface(is_add=1, flags=0,
8799 sw_if_index=self.pg1.sw_if_index)
8803 for i in range(0, max_bibs):
8804 src = "fd01:aa::%x" % (i)
8805 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
8806 IPv6(src=src, dst=remote_host_ip6) /
8807 TCP(sport=12345, dport=80))
8809 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
8810 IPv6(src=src, dst=remote_host_ip6) /
8811 TCP(sport=12345, dport=22))
8813 self.pg0.add_stream(pkts)
8814 self.pg_enable_capture(self.pg_interfaces)
8816 self.pg1.get_capture(max_sessions)
8818 self.vapi.set_ipfix_exporter(collector_address=self.pg3.remote_ip4n,
8819 src_address=self.pg3.local_ip4n,
8821 template_interval=10)
8822 self.vapi.nat_ipfix_enable_disable(domain_id=self.ipfix_domain_id,
8823 src_port=self.ipfix_src_port,
8826 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
8827 IPv6(src=src, dst=remote_host_ip6) /
8828 TCP(sport=12345, dport=25))
8829 self.pg0.add_stream(p)
8830 self.pg_enable_capture(self.pg_interfaces)
8832 self.pg1.assert_nothing_captured()
8834 self.vapi.cli("ipfix flush") # FIXME this should be an API call
8835 capture = self.pg3.get_capture(9)
8836 ipfix = IPFIXDecoder()
8837 # first load template
8839 self.assertTrue(p.haslayer(IPFIX))
8840 self.assertEqual(p[IP].src, self.pg3.local_ip4)
8841 self.assertEqual(p[IP].dst, self.pg3.remote_ip4)
8842 self.assertEqual(p[UDP].sport, self.ipfix_src_port)
8843 self.assertEqual(p[UDP].dport, 4739)
8844 self.assertEqual(p[IPFIX].observationDomainID,
8845 self.ipfix_domain_id)
8846 if p.haslayer(Template):
8847 ipfix.add_template(p.getlayer(Template))
8848 # verify events in data set
8850 if p.haslayer(Data):
8851 data = ipfix.decode_data_set(p.getlayer(Set))
8852 self.verify_ipfix_max_sessions(data, max_sessions)
8854 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
8855 IPv6(src=self.pg0.remote_ip6, dst=remote_host_ip6) /
8856 TCP(sport=12345, dport=80))
8857 self.pg0.add_stream(p)
8858 self.pg_enable_capture(self.pg_interfaces)
8860 self.pg1.assert_nothing_captured()
8862 self.vapi.cli("ipfix flush") # FIXME this should be an API call
8863 capture = self.pg3.get_capture(1)
8864 # verify events in data set
8866 self.assertTrue(p.haslayer(IPFIX))
8867 self.assertEqual(p[IP].src, self.pg3.local_ip4)
8868 self.assertEqual(p[IP].dst, self.pg3.remote_ip4)
8869 self.assertEqual(p[UDP].sport, self.ipfix_src_port)
8870 self.assertEqual(p[UDP].dport, 4739)
8871 self.assertEqual(p[IPFIX].observationDomainID,
8872 self.ipfix_domain_id)
8873 if p.haslayer(Data):
8874 data = ipfix.decode_data_set(p.getlayer(Set))
8875 self.verify_ipfix_max_bibs(data, max_bibs)
8877 def test_ipfix_max_frags(self):
8878 """ IPFIX logging maximum fragments pending reassembly exceeded """
8879 self.vapi.nat64_add_del_pool_addr_range(start_addr=self.nat_addr,
8880 end_addr=self.nat_addr,
8883 flags = self.config_flags.NAT_IS_INSIDE
8884 self.vapi.nat64_add_del_interface(is_add=1, flags=flags,
8885 sw_if_index=self.pg0.sw_if_index)
8886 self.vapi.nat64_add_del_interface(is_add=1, flags=0,
8887 sw_if_index=self.pg1.sw_if_index)
8888 self.vapi.nat_set_reass(timeout=2, max_reass=1024, max_frag=1,
8889 drop_frag=0, is_ip6=1)
8890 self.vapi.set_ipfix_exporter(collector_address=self.pg3.remote_ip4n,
8891 src_address=self.pg3.local_ip4n,
8893 template_interval=10)
8894 self.vapi.nat_ipfix_enable_disable(domain_id=self.ipfix_domain_id,
8895 src_port=self.ipfix_src_port,
8899 pkts = self.create_stream_frag_ip6(self.pg0, self.pg1.remote_ip4,
8900 self.tcp_port_in, 20, data)
8902 self.pg0.add_stream(pkts)
8903 self.pg_enable_capture(self.pg_interfaces)
8905 self.pg1.assert_nothing_captured()
8907 self.vapi.cli("ipfix flush") # FIXME this should be an API call
8908 capture = self.pg3.get_capture(9)
8909 ipfix = IPFIXDecoder()
8910 # first load template
8912 self.assertTrue(p.haslayer(IPFIX))
8913 self.assertEqual(p[IP].src, self.pg3.local_ip4)
8914 self.assertEqual(p[IP].dst, self.pg3.remote_ip4)
8915 self.assertEqual(p[UDP].sport, self.ipfix_src_port)
8916 self.assertEqual(p[UDP].dport, 4739)
8917 self.assertEqual(p[IPFIX].observationDomainID,
8918 self.ipfix_domain_id)
8919 if p.haslayer(Template):
8920 ipfix.add_template(p.getlayer(Template))
8921 # verify events in data set
8923 if p.haslayer(Data):
8924 data = ipfix.decode_data_set(p.getlayer(Set))
8925 self.verify_ipfix_max_fragments_ip6(data, 1,
8926 self.pg0.remote_ip6n)
8928 def test_ipfix_bib_ses(self):
8929 """ IPFIX logging NAT64 BIB/session create and delete events """
8930 self.tcp_port_in = random.randint(1025, 65535)
8931 remote_host_ip6 = self.compose_ip6(self.pg1.remote_ip4,
8935 self.vapi.nat64_add_del_pool_addr_range(start_addr=self.nat_addr,
8936 end_addr=self.nat_addr,
8939 flags = self.config_flags.NAT_IS_INSIDE
8940 self.vapi.nat64_add_del_interface(is_add=1, flags=flags,
8941 sw_if_index=self.pg0.sw_if_index)
8942 self.vapi.nat64_add_del_interface(is_add=1, flags=0,
8943 sw_if_index=self.pg1.sw_if_index)
8944 self.vapi.set_ipfix_exporter(collector_address=self.pg3.remote_ip4n,
8945 src_address=self.pg3.local_ip4n,
8947 template_interval=10)
8948 self.vapi.nat_ipfix_enable_disable(domain_id=self.ipfix_domain_id,
8949 src_port=self.ipfix_src_port,
8953 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
8954 IPv6(src=self.pg0.remote_ip6, dst=remote_host_ip6) /
8955 TCP(sport=self.tcp_port_in, dport=25))
8956 self.pg0.add_stream(p)
8957 self.pg_enable_capture(self.pg_interfaces)
8959 p = self.pg1.get_capture(1)
8960 self.tcp_port_out = p[0][TCP].sport
8961 self.vapi.cli("ipfix flush") # FIXME this should be an API call
8962 capture = self.pg3.get_capture(10)
8963 ipfix = IPFIXDecoder()
8964 # first load template
8966 self.assertTrue(p.haslayer(IPFIX))
8967 self.assertEqual(p[IP].src, self.pg3.local_ip4)
8968 self.assertEqual(p[IP].dst, self.pg3.remote_ip4)
8969 self.assertEqual(p[UDP].sport, self.ipfix_src_port)
8970 self.assertEqual(p[UDP].dport, 4739)
8971 self.assertEqual(p[IPFIX].observationDomainID,
8972 self.ipfix_domain_id)
8973 if p.haslayer(Template):
8974 ipfix.add_template(p.getlayer(Template))
8975 # verify events in data set
8977 if p.haslayer(Data):
8978 data = ipfix.decode_data_set(p.getlayer(Set))
8979 if scapy.compat.orb(data[0][230]) == 10:
8980 self.verify_ipfix_bib(data, 1, self.pg0.remote_ip6n)
8981 elif scapy.compat.orb(data[0][230]) == 6:
8982 self.verify_ipfix_nat64_ses(data,
8984 self.pg0.remote_ip6n,
8985 self.pg1.remote_ip4,
8988 self.logger.error(ppp("Unexpected or invalid packet: ", p))
8991 self.pg_enable_capture(self.pg_interfaces)
8992 self.vapi.nat64_add_del_pool_addr_range(start_addr=self.nat_addr,
8993 end_addr=self.nat_addr,
8996 self.vapi.cli("ipfix flush") # FIXME this should be an API call
8997 capture = self.pg3.get_capture(2)
8998 # verify events in data set
9000 self.assertTrue(p.haslayer(IPFIX))
9001 self.assertEqual(p[IP].src, self.pg3.local_ip4)
9002 self.assertEqual(p[IP].dst, self.pg3.remote_ip4)
9003 self.assertEqual(p[UDP].sport, self.ipfix_src_port)
9004 self.assertEqual(p[UDP].dport, 4739)
9005 self.assertEqual(p[IPFIX].observationDomainID,
9006 self.ipfix_domain_id)
9007 if p.haslayer(Data):
9008 data = ipfix.decode_data_set(p.getlayer(Set))
9009 if scapy.compat.orb(data[0][230]) == 11:
9010 self.verify_ipfix_bib(data, 0, self.pg0.remote_ip6n)
9011 elif scapy.compat.orb(data[0][230]) == 7:
9012 self.verify_ipfix_nat64_ses(data,
9014 self.pg0.remote_ip6n,
9015 self.pg1.remote_ip4,
9018 self.logger.error(ppp("Unexpected or invalid packet: ", p))
9020 def test_syslog_sess(self):
9021 """ Test syslog session creation and deletion """
9022 self.tcp_port_in = random.randint(1025, 65535)
9023 remote_host_ip6 = self.compose_ip6(self.pg1.remote_ip4,
9027 self.vapi.nat64_add_del_pool_addr_range(start_addr=self.nat_addr,
9028 end_addr=self.nat_addr,
9031 flags = self.config_flags.NAT_IS_INSIDE
9032 self.vapi.nat64_add_del_interface(is_add=1, flags=flags,
9033 sw_if_index=self.pg0.sw_if_index)
9034 self.vapi.nat64_add_del_interface(is_add=1, flags=0,
9035 sw_if_index=self.pg1.sw_if_index)
9036 self.vapi.syslog_set_filter(SYSLOG_SEVERITY.INFO)
9037 self.vapi.syslog_set_sender(self.pg3.local_ip4n, self.pg3.remote_ip4n)
9039 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
9040 IPv6(src=self.pg0.remote_ip6, dst=remote_host_ip6) /
9041 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port))
9042 self.pg0.add_stream(p)
9043 self.pg_enable_capture(self.pg_interfaces)
9045 p = self.pg1.get_capture(1)
9046 self.tcp_port_out = p[0][TCP].sport
9047 capture = self.pg3.get_capture(1)
9048 self.verify_syslog_sess(capture[0][Raw].load, is_ip6=True)
9050 self.pg_enable_capture(self.pg_interfaces)
9052 self.vapi.nat64_add_del_pool_addr_range(start_addr=self.nat_addr,
9053 end_addr=self.nat_addr,
9056 capture = self.pg3.get_capture(1)
9057 self.verify_syslog_sess(capture[0][Raw].load, False, True)
9059 def nat64_get_ses_num(self):
9061 Return number of active NAT64 sessions.
9063 st = self.vapi.nat64_st_dump(proto=255)
9066 def clear_nat64(self):
9068 Clear NAT64 configuration.
9070 self.vapi.nat_ipfix_enable_disable(domain_id=self.ipfix_domain_id,
9071 src_port=self.ipfix_src_port,
9073 self.ipfix_src_port = 4739
9074 self.ipfix_domain_id = 1
9076 self.vapi.syslog_set_filter(SYSLOG_SEVERITY.EMERG)
9078 self.vapi.nat_set_timeouts(udp=300, tcp_established=7440,
9079 tcp_transitory=240, icmp=60)
9081 interfaces = self.vapi.nat64_interface_dump()
9082 for intf in interfaces:
9083 self.vapi.nat64_add_del_interface(is_add=0, flags=intf.flags,
9084 sw_if_index=intf.sw_if_index)
9086 bib = self.vapi.nat64_bib_dump(proto=255)
9088 if bibe.flags & self.config_flags.NAT_IS_STATIC:
9089 self.vapi.nat64_add_del_static_bib(i_addr=bibe.i_addr,
9097 adresses = self.vapi.nat64_pool_addr_dump()
9098 for addr in adresses:
9099 self.vapi.nat64_add_del_pool_addr_range(start_addr=addr.address,
9100 end_addr=addr.address,
9104 prefixes = self.vapi.nat64_prefix_dump()
9105 for prefix in prefixes:
9106 self.vapi.nat64_add_del_prefix(prefix=str(prefix.prefix),
9107 vrf_id=prefix.vrf_id, is_add=0)
9109 bibs = self.statistics.get_counter('/nat64/total-bibs')
9110 self.assertEqual(bibs[0][0], 0)
9111 sessions = self.statistics.get_counter('/nat64/total-sessions')
9112 self.assertEqual(sessions[0][0], 0)
9115 super(TestNAT64, self).tearDown()
9116 if not self.vpp_dead:
9119 def show_commands_at_teardown(self):
9120 self.logger.info(self.vapi.cli("show nat64 pool"))
9121 self.logger.info(self.vapi.cli("show nat64 interfaces"))
9122 self.logger.info(self.vapi.cli("show nat64 prefix"))
9123 self.logger.info(self.vapi.cli("show nat64 bib all"))
9124 self.logger.info(self.vapi.cli("show nat64 session table all"))
9125 self.logger.info(self.vapi.cli("show nat virtual-reassembly"))
9128 class TestDSlite(MethodHolder):
9129 """ DS-Lite Test Cases """
9132 def setUpClass(cls):
9133 super(TestDSlite, cls).setUpClass()
9136 cls.nat_addr = '10.0.0.3'
9138 cls.create_pg_interfaces(range(3))
9140 cls.pg0.config_ip4()
9141 cls.pg0.resolve_arp()
9143 cls.pg1.config_ip6()
9144 cls.pg1.generate_remote_hosts(2)
9145 cls.pg1.configure_ipv6_neighbors()
9147 cls.pg2.config_ip4()
9148 cls.pg2.resolve_arp()
9151 super(TestDSlite, cls).tearDownClass()
9155 def tearDownClass(cls):
9156 super(TestDSlite, cls).tearDownClass()
9158 def verify_syslog_apmadd(self, data, isaddr, isport, xsaddr, xsport,
9160 message = data.decode('utf-8')
9162 message = SyslogMessage.parse(message)
9163 except ParseError as e:
9164 self.logger.error(e)
9166 self.assertEqual(message.severity, SyslogSeverity.info)
9167 self.assertEqual(message.appname, 'NAT')
9168 self.assertEqual(message.msgid, 'APMADD')
9169 sd_params = message.sd.get('napmap')
9170 self.assertTrue(sd_params is not None)
9171 self.assertEqual(sd_params.get('IATYP'), 'IPv4')
9172 self.assertEqual(sd_params.get('ISADDR'), isaddr)
9173 self.assertEqual(sd_params.get('ISPORT'), "%d" % isport)
9174 self.assertEqual(sd_params.get('XATYP'), 'IPv4')
9175 self.assertEqual(sd_params.get('XSADDR'), xsaddr)
9176 self.assertEqual(sd_params.get('XSPORT'), "%d" % xsport)
9177 self.assertEqual(sd_params.get('PROTO'), "%d" % proto)
9178 self.assertTrue(sd_params.get('SSUBIX') is not None)
9179 self.assertEqual(sd_params.get('SV6ENC'), sv6enc)
9181 def test_dslite(self):
9182 """ Test DS-Lite """
9183 nat_config = self.vapi.nat_show_config()
9184 self.assertEqual(0, nat_config.dslite_ce)
9186 self.vapi.dslite_add_del_pool_addr_range(start_addr=self.nat_addr,
9187 end_addr=self.nat_addr,
9189 aftr_ip4 = '192.0.0.1'
9190 aftr_ip6 = '2001:db8:85a3::8a2e:370:1'
9191 self.vapi.dslite_set_aftr_addr(ip4_addr=aftr_ip4, ip6_addr=aftr_ip6)
9192 self.vapi.syslog_set_sender(self.pg2.local_ip4n, self.pg2.remote_ip4n)
9195 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
9196 IPv6(dst=aftr_ip6, src=self.pg1.remote_hosts[0].ip6) /
9197 IP(dst=self.pg0.remote_ip4, src='192.168.1.1') /
9198 UDP(sport=20000, dport=10000))
9199 self.pg1.add_stream(p)
9200 self.pg_enable_capture(self.pg_interfaces)
9202 capture = self.pg0.get_capture(1)
9203 capture = capture[0]
9204 self.assertFalse(capture.haslayer(IPv6))
9205 self.assertEqual(capture[IP].src, self.nat_addr)
9206 self.assertEqual(capture[IP].dst, self.pg0.remote_ip4)
9207 self.assertNotEqual(capture[UDP].sport, 20000)
9208 self.assertEqual(capture[UDP].dport, 10000)
9209 self.assert_packet_checksums_valid(capture)
9210 out_port = capture[UDP].sport
9211 capture = self.pg2.get_capture(1)
9212 self.verify_syslog_apmadd(capture[0][Raw].load, '192.168.1.1',
9213 20000, self.nat_addr, out_port,
9214 self.pg1.remote_hosts[0].ip6, IP_PROTOS.udp)
9216 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
9217 IP(dst=self.nat_addr, src=self.pg0.remote_ip4) /
9218 UDP(sport=10000, dport=out_port))
9219 self.pg0.add_stream(p)
9220 self.pg_enable_capture(self.pg_interfaces)
9222 capture = self.pg1.get_capture(1)
9223 capture = capture[0]
9224 self.assertEqual(capture[IPv6].src, aftr_ip6)
9225 self.assertEqual(capture[IPv6].dst, self.pg1.remote_hosts[0].ip6)
9226 self.assertEqual(capture[IP].src, self.pg0.remote_ip4)
9227 self.assertEqual(capture[IP].dst, '192.168.1.1')
9228 self.assertEqual(capture[UDP].sport, 10000)
9229 self.assertEqual(capture[UDP].dport, 20000)
9230 self.assert_packet_checksums_valid(capture)
9233 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
9234 IPv6(dst=aftr_ip6, src=self.pg1.remote_hosts[1].ip6) /
9235 IP(dst=self.pg0.remote_ip4, src='192.168.1.1') /
9236 TCP(sport=20001, dport=10001))
9237 self.pg1.add_stream(p)
9238 self.pg_enable_capture(self.pg_interfaces)
9240 capture = self.pg0.get_capture(1)
9241 capture = capture[0]
9242 self.assertFalse(capture.haslayer(IPv6))
9243 self.assertEqual(capture[IP].src, self.nat_addr)
9244 self.assertEqual(capture[IP].dst, self.pg0.remote_ip4)
9245 self.assertNotEqual(capture[TCP].sport, 20001)
9246 self.assertEqual(capture[TCP].dport, 10001)
9247 self.assert_packet_checksums_valid(capture)
9248 out_port = capture[TCP].sport
9250 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
9251 IP(dst=self.nat_addr, src=self.pg0.remote_ip4) /
9252 TCP(sport=10001, dport=out_port))
9253 self.pg0.add_stream(p)
9254 self.pg_enable_capture(self.pg_interfaces)
9256 capture = self.pg1.get_capture(1)
9257 capture = capture[0]
9258 self.assertEqual(capture[IPv6].src, aftr_ip6)
9259 self.assertEqual(capture[IPv6].dst, self.pg1.remote_hosts[1].ip6)
9260 self.assertEqual(capture[IP].src, self.pg0.remote_ip4)
9261 self.assertEqual(capture[IP].dst, '192.168.1.1')
9262 self.assertEqual(capture[TCP].sport, 10001)
9263 self.assertEqual(capture[TCP].dport, 20001)
9264 self.assert_packet_checksums_valid(capture)
9267 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
9268 IPv6(dst=aftr_ip6, src=self.pg1.remote_hosts[1].ip6) /
9269 IP(dst=self.pg0.remote_ip4, src='192.168.1.1') /
9270 ICMP(id=4000, type='echo-request'))
9271 self.pg1.add_stream(p)
9272 self.pg_enable_capture(self.pg_interfaces)
9274 capture = self.pg0.get_capture(1)
9275 capture = capture[0]
9276 self.assertFalse(capture.haslayer(IPv6))
9277 self.assertEqual(capture[IP].src, self.nat_addr)
9278 self.assertEqual(capture[IP].dst, self.pg0.remote_ip4)
9279 self.assertNotEqual(capture[ICMP].id, 4000)
9280 self.assert_packet_checksums_valid(capture)
9281 out_id = capture[ICMP].id
9283 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
9284 IP(dst=self.nat_addr, src=self.pg0.remote_ip4) /
9285 ICMP(id=out_id, type='echo-reply'))
9286 self.pg0.add_stream(p)
9287 self.pg_enable_capture(self.pg_interfaces)
9289 capture = self.pg1.get_capture(1)
9290 capture = capture[0]
9291 self.assertEqual(capture[IPv6].src, aftr_ip6)
9292 self.assertEqual(capture[IPv6].dst, self.pg1.remote_hosts[1].ip6)
9293 self.assertEqual(capture[IP].src, self.pg0.remote_ip4)
9294 self.assertEqual(capture[IP].dst, '192.168.1.1')
9295 self.assertEqual(capture[ICMP].id, 4000)
9296 self.assert_packet_checksums_valid(capture)
9298 # ping DS-Lite AFTR tunnel endpoint address
9299 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
9300 IPv6(src=self.pg1.remote_hosts[1].ip6, dst=aftr_ip6) /
9301 ICMPv6EchoRequest())
9302 self.pg1.add_stream(p)
9303 self.pg_enable_capture(self.pg_interfaces)
9305 capture = self.pg1.get_capture(1)
9306 capture = capture[0]
9307 self.assertEqual(capture[IPv6].src, aftr_ip6)
9308 self.assertEqual(capture[IPv6].dst, self.pg1.remote_hosts[1].ip6)
9309 self.assertTrue(capture.haslayer(ICMPv6EchoReply))
9311 b4s = self.statistics.get_counter('/dslite/total-b4s')
9312 self.assertEqual(b4s[0][0], 2)
9313 sessions = self.statistics.get_counter('/dslite/total-sessions')
9314 self.assertEqual(sessions[0][0], 3)
9317 super(TestDSlite, self).tearDown()
9319 def show_commands_at_teardown(self):
9320 self.logger.info(self.vapi.cli("show dslite pool"))
9322 self.vapi.cli("show dslite aftr-tunnel-endpoint-address"))
9323 self.logger.info(self.vapi.cli("show dslite sessions"))
9326 class TestDSliteCE(MethodHolder):
9327 """ DS-Lite CE Test Cases """
9330 def setUpConstants(cls):
9331 super(TestDSliteCE, cls).setUpConstants()
9332 cls.vpp_cmdline.extend(["nat", "{", "dslite ce", "}"])
9335 def setUpClass(cls):
9336 super(TestDSliteCE, cls).setUpClass()
9339 cls.create_pg_interfaces(range(2))
9341 cls.pg0.config_ip4()
9342 cls.pg0.resolve_arp()
9344 cls.pg1.config_ip6()
9345 cls.pg1.generate_remote_hosts(1)
9346 cls.pg1.configure_ipv6_neighbors()
9349 super(TestDSliteCE, cls).tearDownClass()
9353 def tearDownClass(cls):
9354 super(TestDSliteCE, cls).tearDownClass()
9356 def test_dslite_ce(self):
9357 """ Test DS-Lite CE """
9359 nat_config = self.vapi.nat_show_config()
9360 self.assertEqual(1, nat_config.dslite_ce)
9362 b4_ip4 = '192.0.0.2'
9363 b4_ip6 = '2001:db8:62aa::375e:f4c1:1'
9364 self.vapi.dslite_set_b4_addr(ip4_addr=b4_ip4, ip6_addr=b4_ip6)
9366 aftr_ip4 = '192.0.0.1'
9367 aftr_ip6 = '2001:db8:85a3::8a2e:370:1'
9368 aftr_ip6_n = socket.inet_pton(socket.AF_INET6, aftr_ip6)
9369 self.vapi.dslite_set_aftr_addr(ip4_addr=aftr_ip4, ip6_addr=aftr_ip6)
9371 self.vapi.ip_add_del_route(dst_address=aftr_ip6_n,
9372 dst_address_length=128,
9373 next_hop_address=self.pg1.remote_ip6n,
9374 next_hop_sw_if_index=self.pg1.sw_if_index,
9378 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
9379 IP(dst=self.pg1.remote_ip4, src=self.pg0.remote_ip4) /
9380 UDP(sport=10000, dport=20000))
9381 self.pg0.add_stream(p)
9382 self.pg_enable_capture(self.pg_interfaces)
9384 capture = self.pg1.get_capture(1)
9385 capture = capture[0]
9386 self.assertEqual(capture[IPv6].src, b4_ip6)
9387 self.assertEqual(capture[IPv6].dst, aftr_ip6)
9388 self.assertEqual(capture[IP].src, self.pg0.remote_ip4)
9389 self.assertEqual(capture[IP].dst, self.pg1.remote_ip4)
9390 self.assertEqual(capture[UDP].sport, 10000)
9391 self.assertEqual(capture[UDP].dport, 20000)
9392 self.assert_packet_checksums_valid(capture)
9395 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
9396 IPv6(dst=b4_ip6, src=aftr_ip6) /
9397 IP(dst=self.pg0.remote_ip4, src=self.pg1.remote_ip4) /
9398 UDP(sport=20000, dport=10000))
9399 self.pg1.add_stream(p)
9400 self.pg_enable_capture(self.pg_interfaces)
9402 capture = self.pg0.get_capture(1)
9403 capture = capture[0]
9404 self.assertFalse(capture.haslayer(IPv6))
9405 self.assertEqual(capture[IP].src, self.pg1.remote_ip4)
9406 self.assertEqual(capture[IP].dst, self.pg0.remote_ip4)
9407 self.assertEqual(capture[UDP].sport, 20000)
9408 self.assertEqual(capture[UDP].dport, 10000)
9409 self.assert_packet_checksums_valid(capture)
9411 # ping DS-Lite B4 tunnel endpoint address
9412 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
9413 IPv6(src=self.pg1.remote_hosts[0].ip6, dst=b4_ip6) /
9414 ICMPv6EchoRequest())
9415 self.pg1.add_stream(p)
9416 self.pg_enable_capture(self.pg_interfaces)
9418 capture = self.pg1.get_capture(1)
9419 capture = capture[0]
9420 self.assertEqual(capture[IPv6].src, b4_ip6)
9421 self.assertEqual(capture[IPv6].dst, self.pg1.remote_hosts[0].ip6)
9422 self.assertTrue(capture.haslayer(ICMPv6EchoReply))
9425 super(TestDSliteCE, self).tearDown()
9427 def show_commands_at_teardown(self):
9429 self.vapi.cli("show dslite aftr-tunnel-endpoint-address"))
9431 self.vapi.cli("show dslite b4-tunnel-endpoint-address"))
9434 class TestNAT66(MethodHolder):
9435 """ NAT66 Test Cases """
9438 def setUpClass(cls):
9439 super(TestNAT66, cls).setUpClass()
9442 cls.nat_addr = 'fd01:ff::2'
9444 cls.create_pg_interfaces(range(2))
9445 cls.interfaces = list(cls.pg_interfaces)
9447 for i in cls.interfaces:
9450 i.configure_ipv6_neighbors()
9453 super(TestNAT66, cls).tearDownClass()
9457 def tearDownClass(cls):
9458 super(TestNAT66, cls).tearDownClass()
9460 def test_static(self):
9461 """ 1:1 NAT66 test """
9462 flags = self.config_flags.NAT_IS_INSIDE
9463 self.vapi.nat66_add_del_interface(is_add=1, flags=flags,
9464 sw_if_index=self.pg0.sw_if_index)
9465 self.vapi.nat66_add_del_interface(is_add=1,
9466 sw_if_index=self.pg1.sw_if_index)
9467 self.vapi.nat66_add_del_static_mapping(
9468 local_ip_address=self.pg0.remote_ip6n,
9469 external_ip_address=self.nat_addr,
9474 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
9475 IPv6(src=self.pg0.remote_ip6, dst=self.pg1.remote_ip6) /
9478 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
9479 IPv6(src=self.pg0.remote_ip6, dst=self.pg1.remote_ip6) /
9482 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
9483 IPv6(src=self.pg0.remote_ip6, dst=self.pg1.remote_ip6) /
9484 ICMPv6EchoRequest())
9486 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
9487 IPv6(src=self.pg0.remote_ip6, dst=self.pg1.remote_ip6) /
9488 GRE() / IP() / TCP())
9490 self.pg0.add_stream(pkts)
9491 self.pg_enable_capture(self.pg_interfaces)
9493 capture = self.pg1.get_capture(len(pkts))
9494 for packet in capture:
9496 self.assertEqual(packet[IPv6].src, self.nat_addr)
9497 self.assertEqual(packet[IPv6].dst, self.pg1.remote_ip6)
9498 self.assert_packet_checksums_valid(packet)
9500 self.logger.error(ppp("Unexpected or invalid packet:", packet))
9505 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
9506 IPv6(src=self.pg1.remote_ip6, dst=self.nat_addr) /
9509 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
9510 IPv6(src=self.pg1.remote_ip6, dst=self.nat_addr) /
9513 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
9514 IPv6(src=self.pg1.remote_ip6, dst=self.nat_addr) /
9517 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
9518 IPv6(src=self.pg1.remote_ip6, dst=self.nat_addr) /
9519 GRE() / IP() / TCP())
9521 self.pg1.add_stream(pkts)
9522 self.pg_enable_capture(self.pg_interfaces)
9524 capture = self.pg0.get_capture(len(pkts))
9525 for packet in capture:
9527 self.assertEqual(packet[IPv6].src, self.pg1.remote_ip6)
9528 self.assertEqual(packet[IPv6].dst, self.pg0.remote_ip6)
9529 self.assert_packet_checksums_valid(packet)
9531 self.logger.error(ppp("Unexpected or invalid packet:", packet))
9534 sm = self.vapi.nat66_static_mapping_dump()
9535 self.assertEqual(len(sm), 1)
9536 self.assertEqual(sm[0].total_pkts, 8)
9538 def test_check_no_translate(self):
9539 """ NAT66 translate only when egress interface is outside interface """
9540 flags = self.config_flags.NAT_IS_INSIDE
9541 self.vapi.nat66_add_del_interface(is_add=1, flags=flags,
9542 sw_if_index=self.pg0.sw_if_index)
9543 self.vapi.nat66_add_del_interface(is_add=1, flags=flags,
9544 sw_if_index=self.pg1.sw_if_index)
9545 self.vapi.nat66_add_del_static_mapping(
9546 local_ip_address=self.pg0.remote_ip6n,
9547 external_ip_address=self.nat_addr,
9551 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
9552 IPv6(src=self.pg0.remote_ip6, dst=self.pg1.remote_ip6) /
9554 self.pg0.add_stream([p])
9555 self.pg_enable_capture(self.pg_interfaces)
9557 capture = self.pg1.get_capture(1)
9560 self.assertEqual(packet[IPv6].src, self.pg0.remote_ip6)
9561 self.assertEqual(packet[IPv6].dst, self.pg1.remote_ip6)
9563 self.logger.error(ppp("Unexpected or invalid packet:", packet))
9566 def clear_nat66(self):
9568 Clear NAT66 configuration.
9570 interfaces = self.vapi.nat66_interface_dump()
9571 for intf in interfaces:
9572 self.vapi.nat66_add_del_interface(is_add=0, flags=intf.flags,
9573 sw_if_index=intf.sw_if_index)
9575 static_mappings = self.vapi.nat66_static_mapping_dump()
9576 for sm in static_mappings:
9577 self.vapi.nat66_add_del_static_mapping(
9578 local_ip_address=sm.local_ip_address,
9579 external_ip_address=sm.external_ip_address, vrf_id=sm.vrf_id,
9583 super(TestNAT66, self).tearDown()
9586 def show_commands_at_teardown(self):
9587 self.logger.info(self.vapi.cli("show nat66 interfaces"))
9588 self.logger.info(self.vapi.cli("show nat66 static mappings"))
9591 if __name__ == '__main__':
9592 unittest.main(testRunner=VppTestRunner)