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.nat44_add_address(self.nat_addr, is_add=0)
3994 self.pg1.unconfig_ip4()
3995 self.pg2.unconfig_ip4()
3996 self.pg1.set_table_ip4(0)
3997 self.pg2.set_table_ip4(0)
3998 self.pg1.config_ip4()
3999 self.pg2.config_ip4()
4000 self.pg1.resolve_arp()
4001 self.pg2.resolve_arp()
4003 @unittest.skipUnless(running_extended_tests, "part of extended tests")
4004 def test_session_timeout(self):
4005 """ NAT44 session timeouts """
4006 self.nat44_add_address(self.nat_addr)
4007 flags = self.config_flags.NAT_IS_INSIDE
4008 self.vapi.nat44_interface_add_del_feature(
4009 sw_if_index=self.pg0.sw_if_index,
4010 flags=flags, is_add=1)
4011 self.vapi.nat44_interface_add_del_feature(
4012 sw_if_index=self.pg1.sw_if_index,
4014 self.vapi.nat_set_timeouts(udp=5, tcp_established=7440,
4015 tcp_transitory=240, icmp=60)
4019 for i in range(0, max_sessions):
4020 src = "10.10.%u.%u" % ((i & 0xFF00) >> 8, i & 0xFF)
4021 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
4022 IP(src=src, dst=self.pg1.remote_ip4) /
4023 UDP(sport=1025, dport=53))
4025 self.pg0.add_stream(pkts)
4026 self.pg_enable_capture(self.pg_interfaces)
4028 self.pg1.get_capture(max_sessions)
4033 for i in range(0, max_sessions):
4034 src = "10.10.%u.%u" % ((i & 0xFF00) >> 8, i & 0xFF)
4035 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
4036 IP(src=src, dst=self.pg1.remote_ip4) /
4037 UDP(sport=1026, dport=53))
4039 self.pg0.add_stream(pkts)
4040 self.pg_enable_capture(self.pg_interfaces)
4042 self.pg1.get_capture(max_sessions)
4045 users = self.vapi.nat44_user_dump()
4047 nsessions = nsessions + user.nsessions
4048 self.assertLess(nsessions, 2 * max_sessions)
4050 def test_mss_clamping(self):
4051 """ TCP MSS clamping """
4052 self.nat44_add_address(self.nat_addr)
4053 flags = self.config_flags.NAT_IS_INSIDE
4054 self.vapi.nat44_interface_add_del_feature(
4055 sw_if_index=self.pg0.sw_if_index,
4056 flags=flags, is_add=1)
4057 self.vapi.nat44_interface_add_del_feature(
4058 sw_if_index=self.pg1.sw_if_index,
4061 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
4062 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
4063 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
4064 flags="S", options=[('MSS', 1400)]))
4066 self.vapi.nat_set_mss_clamping(enable=1, mss_value=1000)
4067 self.pg0.add_stream(p)
4068 self.pg_enable_capture(self.pg_interfaces)
4070 capture = self.pg1.get_capture(1)
4071 # Negotiated MSS value greater than configured - changed
4072 self.verify_mss_value(capture[0], 1000)
4074 self.vapi.nat_set_mss_clamping(enable=0, mss_value=1500)
4075 self.pg0.add_stream(p)
4076 self.pg_enable_capture(self.pg_interfaces)
4078 capture = self.pg1.get_capture(1)
4079 # MSS clamping disabled - negotiated MSS unchanged
4080 self.verify_mss_value(capture[0], 1400)
4082 self.vapi.nat_set_mss_clamping(enable=1, mss_value=1500)
4083 self.pg0.add_stream(p)
4084 self.pg_enable_capture(self.pg_interfaces)
4086 capture = self.pg1.get_capture(1)
4087 # Negotiated MSS value smaller than configured - unchanged
4088 self.verify_mss_value(capture[0], 1400)
4090 @unittest.skipUnless(running_extended_tests, "part of extended tests")
4091 def test_ha_send(self):
4092 """ Send HA session synchronization events (active) """
4093 self.nat44_add_address(self.nat_addr)
4094 flags = self.config_flags.NAT_IS_INSIDE
4095 self.vapi.nat44_interface_add_del_feature(
4096 sw_if_index=self.pg0.sw_if_index,
4097 flags=flags, is_add=1)
4098 self.vapi.nat44_interface_add_del_feature(
4099 sw_if_index=self.pg1.sw_if_index,
4101 self.vapi.nat_ha_set_listener(ip_address=self.pg3.local_ip4,
4104 self.vapi.nat_ha_set_failover(ip_address=self.pg3.remote_ip4,
4105 port=12346, session_refresh_interval=10)
4106 bind_layers(UDP, HANATStateSync, sport=12345)
4109 pkts = self.create_stream_in(self.pg0, self.pg1)
4110 self.pg0.add_stream(pkts)
4111 self.pg_enable_capture(self.pg_interfaces)
4113 capture = self.pg1.get_capture(len(pkts))
4114 self.verify_capture_out(capture)
4115 # active send HA events
4116 self.vapi.nat_ha_flush()
4117 stats = self.statistics.get_counter('/nat44/ha/add-event-send')
4118 self.assertEqual(stats[0][0], 3)
4119 capture = self.pg3.get_capture(1)
4121 self.assert_packet_checksums_valid(p)
4125 hanat = p[HANATStateSync]
4127 self.logger.error(ppp("Invalid packet:", p))
4130 self.assertEqual(ip.src, self.pg3.local_ip4)
4131 self.assertEqual(ip.dst, self.pg3.remote_ip4)
4132 self.assertEqual(udp.sport, 12345)
4133 self.assertEqual(udp.dport, 12346)
4134 self.assertEqual(hanat.version, 1)
4135 self.assertEqual(hanat.thread_index, 0)
4136 self.assertEqual(hanat.count, 3)
4137 seq = hanat.sequence_number
4138 for event in hanat.events:
4139 self.assertEqual(event.event_type, 1)
4140 self.assertEqual(event.in_addr, self.pg0.remote_ip4)
4141 self.assertEqual(event.out_addr, self.nat_addr)
4142 self.assertEqual(event.fib_index, 0)
4144 # ACK received events
4145 ack = (Ether(dst=self.pg3.local_mac, src=self.pg3.remote_mac) /
4146 IP(src=self.pg3.remote_ip4, dst=self.pg3.local_ip4) /
4147 UDP(sport=12346, dport=12345) /
4148 HANATStateSync(sequence_number=seq, flags='ACK'))
4149 self.pg3.add_stream(ack)
4151 stats = self.statistics.get_counter('/nat44/ha/ack-recv')
4152 self.assertEqual(stats[0][0], 1)
4154 # delete one session
4155 self.pg_enable_capture(self.pg_interfaces)
4156 self.vapi.nat44_del_session(address=self.pg0.remote_ip4n,
4157 port=self.tcp_port_in,
4158 protocol=IP_PROTOS.tcp,
4159 flags=self.config_flags.NAT_IS_INSIDE)
4160 self.vapi.nat_ha_flush()
4161 stats = self.statistics.get_counter('/nat44/ha/del-event-send')
4162 self.assertEqual(stats[0][0], 1)
4163 capture = self.pg3.get_capture(1)
4166 hanat = p[HANATStateSync]
4168 self.logger.error(ppp("Invalid packet:", p))
4171 self.assertGreater(hanat.sequence_number, seq)
4173 # do not send ACK, active retry send HA event again
4174 self.pg_enable_capture(self.pg_interfaces)
4176 stats = self.statistics.get_counter('/nat44/ha/retry-count')
4177 self.assertEqual(stats[0][0], 3)
4178 stats = self.statistics.get_counter('/nat44/ha/missed-count')
4179 self.assertEqual(stats[0][0], 1)
4180 capture = self.pg3.get_capture(3)
4181 for packet in capture:
4182 self.assertEqual(packet, p)
4184 # session counters refresh
4185 pkts = self.create_stream_out(self.pg1)
4186 self.pg1.add_stream(pkts)
4187 self.pg_enable_capture(self.pg_interfaces)
4189 self.pg0.get_capture(2)
4190 self.vapi.nat_ha_flush()
4191 stats = self.statistics.get_counter('/nat44/ha/refresh-event-send')
4192 self.assertEqual(stats[0][0], 2)
4193 capture = self.pg3.get_capture(1)
4195 self.assert_packet_checksums_valid(p)
4199 hanat = p[HANATStateSync]
4201 self.logger.error(ppp("Invalid packet:", p))
4204 self.assertEqual(ip.src, self.pg3.local_ip4)
4205 self.assertEqual(ip.dst, self.pg3.remote_ip4)
4206 self.assertEqual(udp.sport, 12345)
4207 self.assertEqual(udp.dport, 12346)
4208 self.assertEqual(hanat.version, 1)
4209 self.assertEqual(hanat.count, 2)
4210 seq = hanat.sequence_number
4211 for event in hanat.events:
4212 self.assertEqual(event.event_type, 3)
4213 self.assertEqual(event.out_addr, self.nat_addr)
4214 self.assertEqual(event.fib_index, 0)
4215 self.assertEqual(event.total_pkts, 2)
4216 self.assertGreater(event.total_bytes, 0)
4218 ack = (Ether(dst=self.pg3.local_mac, src=self.pg3.remote_mac) /
4219 IP(src=self.pg3.remote_ip4, dst=self.pg3.local_ip4) /
4220 UDP(sport=12346, dport=12345) /
4221 HANATStateSync(sequence_number=seq, flags='ACK'))
4222 self.pg3.add_stream(ack)
4224 stats = self.statistics.get_counter('/nat44/ha/ack-recv')
4225 self.assertEqual(stats[0][0], 2)
4227 def test_ha_recv(self):
4228 """ Receive HA session synchronization events (passive) """
4229 self.nat44_add_address(self.nat_addr)
4230 flags = self.config_flags.NAT_IS_INSIDE
4231 self.vapi.nat44_interface_add_del_feature(
4232 sw_if_index=self.pg0.sw_if_index,
4233 flags=flags, is_add=1)
4234 self.vapi.nat44_interface_add_del_feature(
4235 sw_if_index=self.pg1.sw_if_index,
4237 self.vapi.nat_ha_set_listener(ip_address=self.pg3.local_ip4,
4240 bind_layers(UDP, HANATStateSync, sport=12345)
4242 self.tcp_port_out = random.randint(1025, 65535)
4243 self.udp_port_out = random.randint(1025, 65535)
4245 # send HA session add events to failover/passive
4246 p = (Ether(dst=self.pg3.local_mac, src=self.pg3.remote_mac) /
4247 IP(src=self.pg3.remote_ip4, dst=self.pg3.local_ip4) /
4248 UDP(sport=12346, dport=12345) /
4249 HANATStateSync(sequence_number=1, events=[
4250 Event(event_type='add', protocol='tcp',
4251 in_addr=self.pg0.remote_ip4, out_addr=self.nat_addr,
4252 in_port=self.tcp_port_in, out_port=self.tcp_port_out,
4253 eh_addr=self.pg1.remote_ip4,
4254 ehn_addr=self.pg1.remote_ip4,
4255 eh_port=self.tcp_external_port,
4256 ehn_port=self.tcp_external_port, fib_index=0),
4257 Event(event_type='add', protocol='udp',
4258 in_addr=self.pg0.remote_ip4, out_addr=self.nat_addr,
4259 in_port=self.udp_port_in, out_port=self.udp_port_out,
4260 eh_addr=self.pg1.remote_ip4,
4261 ehn_addr=self.pg1.remote_ip4,
4262 eh_port=self.udp_external_port,
4263 ehn_port=self.udp_external_port, fib_index=0)]))
4265 self.pg3.add_stream(p)
4266 self.pg_enable_capture(self.pg_interfaces)
4269 capture = self.pg3.get_capture(1)
4272 hanat = p[HANATStateSync]
4274 self.logger.error(ppp("Invalid packet:", p))
4277 self.assertEqual(hanat.sequence_number, 1)
4278 self.assertEqual(hanat.flags, 'ACK')
4279 self.assertEqual(hanat.version, 1)
4280 self.assertEqual(hanat.thread_index, 0)
4281 stats = self.statistics.get_counter('/nat44/ha/ack-send')
4282 self.assertEqual(stats[0][0], 1)
4283 stats = self.statistics.get_counter('/nat44/ha/add-event-recv')
4284 self.assertEqual(stats[0][0], 2)
4285 users = self.statistics.get_counter('/nat44/total-users')
4286 self.assertEqual(users[0][0], 1)
4287 sessions = self.statistics.get_counter('/nat44/total-sessions')
4288 self.assertEqual(sessions[0][0], 2)
4289 users = self.vapi.nat44_user_dump()
4290 self.assertEqual(len(users), 1)
4291 self.assertEqual(str(users[0].ip_address),
4292 self.pg0.remote_ip4)
4293 # there should be 2 sessions created by HA
4294 sessions = self.vapi.nat44_user_session_dump(users[0].ip_address,
4296 self.assertEqual(len(sessions), 2)
4297 for session in sessions:
4298 self.assertEqual(str(session.inside_ip_address),
4299 self.pg0.remote_ip4)
4300 self.assertEqual(str(session.outside_ip_address),
4302 self.assertIn(session.inside_port,
4303 [self.tcp_port_in, self.udp_port_in])
4304 self.assertIn(session.outside_port,
4305 [self.tcp_port_out, self.udp_port_out])
4306 self.assertIn(session.protocol, [IP_PROTOS.tcp, IP_PROTOS.udp])
4308 # send HA session delete event to failover/passive
4309 p = (Ether(dst=self.pg3.local_mac, src=self.pg3.remote_mac) /
4310 IP(src=self.pg3.remote_ip4, dst=self.pg3.local_ip4) /
4311 UDP(sport=12346, dport=12345) /
4312 HANATStateSync(sequence_number=2, events=[
4313 Event(event_type='del', protocol='udp',
4314 in_addr=self.pg0.remote_ip4, out_addr=self.nat_addr,
4315 in_port=self.udp_port_in, out_port=self.udp_port_out,
4316 eh_addr=self.pg1.remote_ip4,
4317 ehn_addr=self.pg1.remote_ip4,
4318 eh_port=self.udp_external_port,
4319 ehn_port=self.udp_external_port, fib_index=0)]))
4321 self.pg3.add_stream(p)
4322 self.pg_enable_capture(self.pg_interfaces)
4325 capture = self.pg3.get_capture(1)
4328 hanat = p[HANATStateSync]
4330 self.logger.error(ppp("Invalid packet:", p))
4333 self.assertEqual(hanat.sequence_number, 2)
4334 self.assertEqual(hanat.flags, 'ACK')
4335 self.assertEqual(hanat.version, 1)
4336 users = self.vapi.nat44_user_dump()
4337 self.assertEqual(len(users), 1)
4338 self.assertEqual(str(users[0].ip_address),
4339 self.pg0.remote_ip4)
4340 # now we should have only 1 session, 1 deleted by HA
4341 sessions = self.vapi.nat44_user_session_dump(users[0].ip_address,
4343 self.assertEqual(len(sessions), 1)
4344 stats = self.statistics.get_counter('/nat44/ha/del-event-recv')
4345 self.assertEqual(stats[0][0], 1)
4347 stats = self.statistics.get_counter('/err/nat-ha/pkts-processed')
4348 self.assertEqual(stats, 2)
4350 # send HA session refresh event to failover/passive
4351 p = (Ether(dst=self.pg3.local_mac, src=self.pg3.remote_mac) /
4352 IP(src=self.pg3.remote_ip4, dst=self.pg3.local_ip4) /
4353 UDP(sport=12346, dport=12345) /
4354 HANATStateSync(sequence_number=3, events=[
4355 Event(event_type='refresh', protocol='tcp',
4356 in_addr=self.pg0.remote_ip4, out_addr=self.nat_addr,
4357 in_port=self.tcp_port_in, out_port=self.tcp_port_out,
4358 eh_addr=self.pg1.remote_ip4,
4359 ehn_addr=self.pg1.remote_ip4,
4360 eh_port=self.tcp_external_port,
4361 ehn_port=self.tcp_external_port, fib_index=0,
4362 total_bytes=1024, total_pkts=2)]))
4363 self.pg3.add_stream(p)
4364 self.pg_enable_capture(self.pg_interfaces)
4367 capture = self.pg3.get_capture(1)
4370 hanat = p[HANATStateSync]
4372 self.logger.error(ppp("Invalid packet:", p))
4375 self.assertEqual(hanat.sequence_number, 3)
4376 self.assertEqual(hanat.flags, 'ACK')
4377 self.assertEqual(hanat.version, 1)
4378 users = self.vapi.nat44_user_dump()
4379 self.assertEqual(len(users), 1)
4380 self.assertEqual(str(users[0].ip_address),
4381 self.pg0.remote_ip4)
4382 sessions = self.vapi.nat44_user_session_dump(users[0].ip_address,
4384 self.assertEqual(len(sessions), 1)
4385 session = sessions[0]
4386 self.assertEqual(session.total_bytes, 1024)
4387 self.assertEqual(session.total_pkts, 2)
4388 stats = self.statistics.get_counter('/nat44/ha/refresh-event-recv')
4389 self.assertEqual(stats[0][0], 1)
4391 stats = self.statistics.get_counter('/err/nat-ha/pkts-processed')
4392 self.assertEqual(stats, 3)
4394 # send packet to test session created by HA
4395 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
4396 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
4397 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out))
4398 self.pg1.add_stream(p)
4399 self.pg_enable_capture(self.pg_interfaces)
4401 capture = self.pg0.get_capture(1)
4407 self.logger.error(ppp("Invalid packet:", p))
4410 self.assertEqual(ip.src, self.pg1.remote_ip4)
4411 self.assertEqual(ip.dst, self.pg0.remote_ip4)
4412 self.assertEqual(tcp.sport, self.tcp_external_port)
4413 self.assertEqual(tcp.dport, self.tcp_port_in)
4416 super(TestNAT44, self).tearDown()
4418 self.vapi.cli("clear logging")
4420 def show_commands_at_teardown(self):
4421 self.logger.info(self.vapi.cli("show nat44 addresses"))
4422 self.logger.info(self.vapi.cli("show nat44 interfaces"))
4423 self.logger.info(self.vapi.cli("show nat44 static mappings"))
4424 self.logger.info(self.vapi.cli("show nat44 interface address"))
4425 self.logger.info(self.vapi.cli("show nat44 sessions detail"))
4426 self.logger.info(self.vapi.cli("show nat virtual-reassembly"))
4427 self.logger.info(self.vapi.cli("show nat44 hash tables detail"))
4428 self.logger.info(self.vapi.cli("show nat timeouts"))
4430 self.vapi.cli("show nat addr-port-assignment-alg"))
4431 self.logger.info(self.vapi.cli("show nat ha"))
4434 class TestNAT44EndpointDependent(MethodHolder):
4435 """ Endpoint-Dependent mapping and filtering test cases """
4438 def setUpConstants(cls):
4439 super(TestNAT44EndpointDependent, cls).setUpConstants()
4440 cls.vpp_cmdline.extend(["nat", "{", "endpoint-dependent", "}"])
4443 def setUpClass(cls):
4444 super(TestNAT44EndpointDependent, cls).setUpClass()
4445 cls.vapi.cli("set log class nat level debug")
4447 cls.tcp_port_in = 6303
4448 cls.tcp_port_out = 6303
4449 cls.udp_port_in = 6304
4450 cls.udp_port_out = 6304
4451 cls.icmp_id_in = 6305
4452 cls.icmp_id_out = 6305
4453 cls.nat_addr = '10.0.0.3'
4454 cls.ipfix_src_port = 4739
4455 cls.ipfix_domain_id = 1
4456 cls.tcp_external_port = 80
4458 cls.create_pg_interfaces(range(7))
4459 cls.interfaces = list(cls.pg_interfaces[0:3])
4461 for i in cls.interfaces:
4466 cls.pg0.generate_remote_hosts(3)
4467 cls.pg0.configure_ipv4_neighbors()
4471 cls.pg4.generate_remote_hosts(2)
4472 cls.pg4.config_ip4()
4473 ip_addr_n = socket.inet_pton(socket.AF_INET, "10.0.0.1")
4474 cls.vapi.sw_interface_add_del_address(
4475 sw_if_index=cls.pg4.sw_if_index, address=ip_addr_n,
4478 cls.pg4.resolve_arp()
4479 cls.pg4._remote_hosts[1]._ip4 = cls.pg4._remote_hosts[0]._ip4
4480 cls.pg4.resolve_arp()
4482 zero_ip4n = socket.inet_pton(socket.AF_INET, "0.0.0.0")
4483 cls.vapi.ip_table_add_del(is_add=1, table_id=1)
4485 cls.pg5._local_ip4 = "10.1.1.1"
4486 cls.pg5._local_ip4n = socket.inet_pton(socket.AF_INET,
4488 cls.pg5._remote_hosts[0]._ip4 = "10.1.1.2"
4489 cls.pg5._remote_hosts[0]._ip4n = socket.inet_pton(
4490 socket.AF_INET, cls.pg5.remote_ip4)
4491 cls.pg5.set_table_ip4(1)
4492 cls.pg5.config_ip4()
4494 cls.vapi.ip_add_del_route(dst_address=cls.pg5.remote_ip4n,
4495 dst_address_length=32,
4496 next_hop_address=zero_ip4n,
4497 next_hop_sw_if_index=cls.pg5.sw_if_index,
4500 cls.pg6._local_ip4 = "10.1.2.1"
4501 cls.pg6._local_ip4n = socket.inet_pton(socket.AF_INET,
4503 cls.pg6._remote_hosts[0]._ip4 = "10.1.2.2"
4504 cls.pg6._remote_hosts[0]._ip4n = socket.inet_pton(
4505 socket.AF_INET, cls.pg6.remote_ip4)
4506 cls.pg6.set_table_ip4(1)
4507 cls.pg6.config_ip4()
4509 cls.vapi.ip_add_del_route(dst_address=cls.pg6.remote_ip4n,
4510 dst_address_length=32,
4511 next_hop_address=zero_ip4n,
4512 next_hop_sw_if_index=cls.pg6.sw_if_index,
4515 cls.vapi.ip_add_del_route(dst_address=cls.pg6.remote_ip4n,
4516 dst_address_length=16,
4517 next_hop_address=zero_ip4n, table_id=0,
4518 next_hop_table_id=1)
4519 cls.vapi.ip_add_del_route(dst_address=zero_ip4n,
4520 dst_address_length=0,
4521 next_hop_address=zero_ip4n, table_id=1,
4522 next_hop_table_id=0)
4523 cls.vapi.ip_add_del_route(dst_address=zero_ip4n,
4524 dst_address_length=0,
4525 next_hop_address=cls.pg1.local_ip4n,
4526 next_hop_sw_if_index=cls.pg1.sw_if_index,
4529 cls.pg5.resolve_arp()
4530 cls.pg6.resolve_arp()
4533 super(TestNAT44EndpointDependent, cls).tearDownClass()
4537 def tearDownClass(cls):
4538 super(TestNAT44EndpointDependent, cls).tearDownClass()
4540 def test_frag_in_order(self):
4541 """ NAT44 translate fragments arriving in order """
4542 self.nat44_add_address(self.nat_addr)
4543 flags = self.config_flags.NAT_IS_INSIDE
4544 self.vapi.nat44_interface_add_del_feature(
4545 sw_if_index=self.pg0.sw_if_index,
4546 flags=flags, is_add=1)
4547 self.vapi.nat44_interface_add_del_feature(
4548 sw_if_index=self.pg1.sw_if_index,
4550 self.frag_in_order(proto=IP_PROTOS.tcp)
4551 self.frag_in_order(proto=IP_PROTOS.udp)
4552 self.frag_in_order(proto=IP_PROTOS.icmp)
4554 def test_frag_in_order_dont_translate(self):
4555 """ NAT44 don't translate fragments arriving in order """
4556 flags = self.config_flags.NAT_IS_INSIDE
4557 self.vapi.nat44_interface_add_del_feature(
4558 sw_if_index=self.pg0.sw_if_index,
4559 flags=flags, is_add=1)
4560 self.vapi.nat44_interface_add_del_feature(
4561 sw_if_index=self.pg1.sw_if_index,
4563 self.vapi.nat44_forwarding_enable_disable(enable=True)
4564 self.frag_in_order(proto=IP_PROTOS.tcp, dont_translate=True)
4566 def test_frag_out_of_order(self):
4567 """ NAT44 translate fragments arriving out of order """
4568 self.nat44_add_address(self.nat_addr)
4569 flags = self.config_flags.NAT_IS_INSIDE
4570 self.vapi.nat44_interface_add_del_feature(
4571 sw_if_index=self.pg0.sw_if_index,
4572 flags=flags, is_add=1)
4573 self.vapi.nat44_interface_add_del_feature(
4574 sw_if_index=self.pg1.sw_if_index,
4576 self.frag_out_of_order(proto=IP_PROTOS.tcp)
4577 self.frag_out_of_order(proto=IP_PROTOS.udp)
4578 self.frag_out_of_order(proto=IP_PROTOS.icmp)
4580 def test_frag_out_of_order_dont_translate(self):
4581 """ NAT44 don't translate fragments arriving out of order """
4582 flags = self.config_flags.NAT_IS_INSIDE
4583 self.vapi.nat44_interface_add_del_feature(
4584 sw_if_index=self.pg0.sw_if_index,
4585 flags=flags, is_add=1)
4586 self.vapi.nat44_interface_add_del_feature(
4587 sw_if_index=self.pg1.sw_if_index,
4589 self.vapi.nat44_forwarding_enable_disable(enable=True)
4590 self.frag_out_of_order(proto=IP_PROTOS.tcp, dont_translate=True)
4592 def test_frag_in_order_in_plus_out(self):
4593 """ in+out interface fragments in order """
4594 flags = self.config_flags.NAT_IS_INSIDE
4595 self.vapi.nat44_interface_add_del_feature(
4596 sw_if_index=self.pg0.sw_if_index,
4598 self.vapi.nat44_interface_add_del_feature(
4599 sw_if_index=self.pg0.sw_if_index,
4600 flags=flags, is_add=1)
4601 self.vapi.nat44_interface_add_del_feature(
4602 sw_if_index=self.pg1.sw_if_index,
4604 self.vapi.nat44_interface_add_del_feature(
4605 sw_if_index=self.pg1.sw_if_index,
4606 flags=flags, is_add=1)
4608 self.server = self.pg1.remote_hosts[0]
4610 self.server_in_addr = self.server.ip4
4611 self.server_out_addr = '11.11.11.11'
4612 self.server_in_port = random.randint(1025, 65535)
4613 self.server_out_port = random.randint(1025, 65535)
4615 self.nat44_add_address(self.server_out_addr)
4617 # add static mappings for server
4618 self.nat44_add_static_mapping(self.server_in_addr,
4619 self.server_out_addr,
4620 self.server_in_port,
4621 self.server_out_port,
4622 proto=IP_PROTOS.tcp)
4623 self.nat44_add_static_mapping(self.server_in_addr,
4624 self.server_out_addr,
4625 self.server_in_port,
4626 self.server_out_port,
4627 proto=IP_PROTOS.udp)
4628 self.nat44_add_static_mapping(self.server_in_addr,
4629 self.server_out_addr,
4630 proto=IP_PROTOS.icmp)
4632 self.vapi.nat_set_reass(timeout=10, max_reass=1024, max_frag=5,
4635 self.frag_in_order_in_plus_out(proto=IP_PROTOS.tcp)
4636 self.frag_in_order_in_plus_out(proto=IP_PROTOS.udp)
4637 self.frag_in_order_in_plus_out(proto=IP_PROTOS.icmp)
4639 def test_frag_out_of_order_in_plus_out(self):
4640 """ in+out interface fragments out of order """
4641 flags = self.config_flags.NAT_IS_INSIDE
4642 self.vapi.nat44_interface_add_del_feature(
4643 sw_if_index=self.pg0.sw_if_index,
4645 self.vapi.nat44_interface_add_del_feature(
4646 sw_if_index=self.pg0.sw_if_index,
4647 flags=flags, is_add=1)
4648 self.vapi.nat44_interface_add_del_feature(
4649 sw_if_index=self.pg1.sw_if_index,
4651 self.vapi.nat44_interface_add_del_feature(
4652 sw_if_index=self.pg1.sw_if_index,
4653 flags=flags, is_add=1)
4655 self.server = self.pg1.remote_hosts[0]
4657 self.server_in_addr = self.server.ip4
4658 self.server_out_addr = '11.11.11.11'
4659 self.server_in_port = random.randint(1025, 65535)
4660 self.server_out_port = random.randint(1025, 65535)
4662 self.nat44_add_address(self.server_out_addr)
4664 # add static mappings for server
4665 self.nat44_add_static_mapping(self.server_in_addr,
4666 self.server_out_addr,
4667 self.server_in_port,
4668 self.server_out_port,
4669 proto=IP_PROTOS.tcp)
4670 self.nat44_add_static_mapping(self.server_in_addr,
4671 self.server_out_addr,
4672 self.server_in_port,
4673 self.server_out_port,
4674 proto=IP_PROTOS.udp)
4675 self.nat44_add_static_mapping(self.server_in_addr,
4676 self.server_out_addr,
4677 proto=IP_PROTOS.icmp)
4679 self.vapi.nat_set_reass(timeout=10, max_reass=1024, max_frag=5,
4682 self.frag_out_of_order_in_plus_out(proto=IP_PROTOS.tcp)
4683 self.frag_out_of_order_in_plus_out(proto=IP_PROTOS.udp)
4684 self.frag_out_of_order_in_plus_out(proto=IP_PROTOS.icmp)
4686 def test_reass_hairpinning(self):
4687 """ NAT44 fragments hairpinning """
4688 self.server = self.pg0.remote_hosts[1]
4689 self.host_in_port = random.randint(1025, 65535)
4690 self.server_in_port = random.randint(1025, 65535)
4691 self.server_out_port = random.randint(1025, 65535)
4693 self.nat44_add_address(self.nat_addr)
4694 flags = self.config_flags.NAT_IS_INSIDE
4695 self.vapi.nat44_interface_add_del_feature(
4696 sw_if_index=self.pg0.sw_if_index,
4697 flags=flags, is_add=1)
4698 self.vapi.nat44_interface_add_del_feature(
4699 sw_if_index=self.pg1.sw_if_index,
4701 # add static mapping for server
4702 self.nat44_add_static_mapping(self.server.ip4, self.nat_addr,
4703 self.server_in_port,
4704 self.server_out_port,
4705 proto=IP_PROTOS.tcp)
4706 self.nat44_add_static_mapping(self.server.ip4, self.nat_addr,
4707 self.server_in_port,
4708 self.server_out_port,
4709 proto=IP_PROTOS.udp)
4710 self.nat44_add_static_mapping(self.server.ip4, self.nat_addr)
4712 self.reass_hairpinning(proto=IP_PROTOS.tcp)
4713 self.reass_hairpinning(proto=IP_PROTOS.udp)
4714 self.reass_hairpinning(proto=IP_PROTOS.icmp)
4716 def test_dynamic(self):
4717 """ NAT44 dynamic translation test """
4719 self.nat44_add_address(self.nat_addr)
4720 flags = self.config_flags.NAT_IS_INSIDE
4721 self.vapi.nat44_interface_add_del_feature(
4722 sw_if_index=self.pg0.sw_if_index,
4723 flags=flags, is_add=1)
4724 self.vapi.nat44_interface_add_del_feature(
4725 sw_if_index=self.pg1.sw_if_index,
4728 nat_config = self.vapi.nat_show_config()
4729 self.assertEqual(1, nat_config.endpoint_dependent)
4732 tcpn = self.statistics.get_counter(
4733 '/err/nat44-ed-in2out-slowpath/TCP packets')
4734 udpn = self.statistics.get_counter(
4735 '/err/nat44-ed-in2out-slowpath/UDP packets')
4736 icmpn = self.statistics.get_counter(
4737 '/err/nat44-ed-in2out-slowpath/ICMP packets')
4738 totaln = self.statistics.get_counter(
4739 '/err/nat44-ed-in2out-slowpath/good in2out packets processed')
4741 pkts = self.create_stream_in(self.pg0, self.pg1)
4742 self.pg0.add_stream(pkts)
4743 self.pg_enable_capture(self.pg_interfaces)
4745 capture = self.pg1.get_capture(len(pkts))
4746 self.verify_capture_out(capture)
4748 err = self.statistics.get_counter(
4749 '/err/nat44-ed-in2out-slowpath/TCP packets')
4750 self.assertEqual(err - tcpn, 1)
4751 err = self.statistics.get_counter(
4752 '/err/nat44-ed-in2out-slowpath/UDP packets')
4753 self.assertEqual(err - udpn, 1)
4754 err = self.statistics.get_counter(
4755 '/err/nat44-ed-in2out-slowpath/ICMP packets')
4756 self.assertEqual(err - icmpn, 1)
4757 err = self.statistics.get_counter(
4758 '/err/nat44-ed-in2out-slowpath/good in2out packets processed')
4759 self.assertEqual(err - totaln, 3)
4762 tcpn = self.statistics.get_counter('/err/nat44-ed-out2in/TCP packets')
4763 udpn = self.statistics.get_counter('/err/nat44-ed-out2in/UDP packets')
4764 icmpn = self.statistics.get_counter(
4765 '/err/nat44-ed-out2in-slowpath/ICMP packets')
4766 totaln = self.statistics.get_counter(
4767 '/err/nat44-ed-out2in/good out2in packets processed')
4769 pkts = self.create_stream_out(self.pg1)
4770 self.pg1.add_stream(pkts)
4771 self.pg_enable_capture(self.pg_interfaces)
4773 capture = self.pg0.get_capture(len(pkts))
4774 self.verify_capture_in(capture, self.pg0)
4776 err = self.statistics.get_counter('/err/nat44-ed-out2in/TCP packets')
4777 self.assertEqual(err - tcpn, 1)
4778 err = self.statistics.get_counter('/err/nat44-ed-out2in/UDP packets')
4779 self.assertEqual(err - udpn, 1)
4780 err = self.statistics.get_counter(
4781 '/err/nat44-ed-out2in-slowpath/ICMP packets')
4782 self.assertEqual(err - icmpn, 1)
4783 err = self.statistics.get_counter(
4784 '/err/nat44-ed-out2in/good out2in packets processed')
4785 self.assertEqual(err - totaln, 2)
4787 users = self.statistics.get_counter('/nat44/total-users')
4788 self.assertEqual(users[0][0], 1)
4789 sessions = self.statistics.get_counter('/nat44/total-sessions')
4790 self.assertEqual(sessions[0][0], 3)
4792 def test_forwarding(self):
4793 """ NAT44 forwarding test """
4795 flags = self.config_flags.NAT_IS_INSIDE
4796 self.vapi.nat44_interface_add_del_feature(
4797 sw_if_index=self.pg0.sw_if_index,
4798 flags=flags, is_add=1)
4799 self.vapi.nat44_interface_add_del_feature(
4800 sw_if_index=self.pg1.sw_if_index,
4802 self.vapi.nat44_forwarding_enable_disable(enable=1)
4804 real_ip = self.pg0.remote_ip4
4805 alias_ip = self.nat_addr
4806 flags = self.config_flags.NAT_IS_ADDR_ONLY
4807 self.vapi.nat44_add_del_static_mapping(is_add=1,
4808 local_ip_address=real_ip,
4809 external_ip_address=alias_ip,
4810 external_sw_if_index=0xFFFFFFFF,
4814 # in2out - static mapping match
4816 pkts = self.create_stream_out(self.pg1)
4817 self.pg1.add_stream(pkts)
4818 self.pg_enable_capture(self.pg_interfaces)
4820 capture = self.pg0.get_capture(len(pkts))
4821 self.verify_capture_in(capture, self.pg0)
4823 pkts = self.create_stream_in(self.pg0, self.pg1)
4824 self.pg0.add_stream(pkts)
4825 self.pg_enable_capture(self.pg_interfaces)
4827 capture = self.pg1.get_capture(len(pkts))
4828 self.verify_capture_out(capture, same_port=True)
4830 # in2out - no static mapping match
4832 host0 = self.pg0.remote_hosts[0]
4833 self.pg0.remote_hosts[0] = self.pg0.remote_hosts[1]
4835 pkts = self.create_stream_out(self.pg1,
4836 dst_ip=self.pg0.remote_ip4,
4837 use_inside_ports=True)
4838 self.pg1.add_stream(pkts)
4839 self.pg_enable_capture(self.pg_interfaces)
4841 capture = self.pg0.get_capture(len(pkts))
4842 self.verify_capture_in(capture, self.pg0)
4844 pkts = self.create_stream_in(self.pg0, self.pg1)
4845 self.pg0.add_stream(pkts)
4846 self.pg_enable_capture(self.pg_interfaces)
4848 capture = self.pg1.get_capture(len(pkts))
4849 self.verify_capture_out(capture, nat_ip=self.pg0.remote_ip4,
4852 self.pg0.remote_hosts[0] = host0
4854 user = self.pg0.remote_hosts[1]
4855 sessions = self.vapi.nat44_user_session_dump(user.ip4n, 0)
4856 self.assertEqual(len(sessions), 3)
4857 self.assertTrue(sessions[0].flags &
4858 self.config_flags.NAT_IS_EXT_HOST_VALID)
4859 self.vapi.nat44_del_session(
4860 address=sessions[0].inside_ip_address,
4861 port=sessions[0].inside_port,
4862 protocol=sessions[0].protocol,
4863 flags=(self.config_flags.NAT_IS_INSIDE |
4864 self.config_flags.NAT_IS_EXT_HOST_VALID),
4865 ext_host_address=sessions[0].ext_host_address,
4866 ext_host_port=sessions[0].ext_host_port)
4867 sessions = self.vapi.nat44_user_session_dump(user.ip4n, 0)
4868 self.assertEqual(len(sessions), 2)
4871 self.vapi.nat44_forwarding_enable_disable(enable=0)
4872 flags = self.config_flags.NAT_IS_ADDR_ONLY
4873 self.vapi.nat44_add_del_static_mapping(
4875 local_ip_address=real_ip,
4876 external_ip_address=alias_ip,
4877 external_sw_if_index=0xFFFFFFFF,
4880 def test_static_lb(self):
4881 """ NAT44 local service load balancing """
4882 external_addr_n = self.nat_addr
4885 server1 = self.pg0.remote_hosts[0]
4886 server2 = self.pg0.remote_hosts[1]
4888 locals = [{'addr': server1.ip4n,
4892 {'addr': server2.ip4n,
4897 self.nat44_add_address(self.nat_addr)
4898 self.vapi.nat44_add_del_lb_static_mapping(
4900 external_addr=external_addr_n,
4901 external_port=external_port,
4902 protocol=IP_PROTOS.tcp,
4903 local_num=len(locals),
4905 flags = self.config_flags.NAT_IS_INSIDE
4906 self.vapi.nat44_interface_add_del_feature(
4907 sw_if_index=self.pg0.sw_if_index,
4908 flags=flags, is_add=1)
4909 self.vapi.nat44_interface_add_del_feature(
4910 sw_if_index=self.pg1.sw_if_index,
4913 # from client to service
4914 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
4915 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
4916 TCP(sport=12345, dport=external_port))
4917 self.pg1.add_stream(p)
4918 self.pg_enable_capture(self.pg_interfaces)
4920 capture = self.pg0.get_capture(1)
4926 self.assertIn(ip.dst, [server1.ip4, server2.ip4])
4927 if ip.dst == server1.ip4:
4931 self.assertEqual(tcp.dport, local_port)
4932 self.assert_packet_checksums_valid(p)
4934 self.logger.error(ppp("Unexpected or invalid packet:", p))
4937 # from service back to client
4938 p = (Ether(src=server.mac, dst=self.pg0.local_mac) /
4939 IP(src=server.ip4, dst=self.pg1.remote_ip4) /
4940 TCP(sport=local_port, dport=12345))
4941 self.pg0.add_stream(p)
4942 self.pg_enable_capture(self.pg_interfaces)
4944 capture = self.pg1.get_capture(1)
4949 self.assertEqual(ip.src, self.nat_addr)
4950 self.assertEqual(tcp.sport, external_port)
4951 self.assert_packet_checksums_valid(p)
4953 self.logger.error(ppp("Unexpected or invalid packet:", p))
4956 sessions = self.vapi.nat44_user_session_dump(server.ip4n, 0)
4957 self.assertEqual(len(sessions), 1)
4958 self.assertTrue(sessions[0].flags &
4959 self.config_flags.NAT_IS_EXT_HOST_VALID)
4960 self.vapi.nat44_del_session(
4961 address=sessions[0].inside_ip_address,
4962 port=sessions[0].inside_port,
4963 protocol=sessions[0].protocol,
4964 flags=(self.config_flags.NAT_IS_INSIDE |
4965 self.config_flags.NAT_IS_EXT_HOST_VALID),
4966 ext_host_address=sessions[0].ext_host_address,
4967 ext_host_port=sessions[0].ext_host_port)
4968 sessions = self.vapi.nat44_user_session_dump(server.ip4n, 0)
4969 self.assertEqual(len(sessions), 0)
4971 @unittest.skipUnless(running_extended_tests, "part of extended tests")
4972 def test_static_lb_multi_clients(self):
4973 """ NAT44 local service load balancing - multiple clients"""
4975 external_addr = self.nat_addr
4978 server1 = self.pg0.remote_hosts[0]
4979 server2 = self.pg0.remote_hosts[1]
4980 server3 = self.pg0.remote_hosts[2]
4982 locals = [{'addr': server1.ip4n,
4986 {'addr': server2.ip4n,
4991 self.nat44_add_address(self.nat_addr)
4992 self.vapi.nat44_add_del_lb_static_mapping(is_add=1,
4993 external_addr=external_addr,
4994 external_port=external_port,
4995 protocol=IP_PROTOS.tcp,
4996 local_num=len(locals),
4998 flags = self.config_flags.NAT_IS_INSIDE
4999 self.vapi.nat44_interface_add_del_feature(
5000 sw_if_index=self.pg0.sw_if_index,
5001 flags=flags, is_add=1)
5002 self.vapi.nat44_interface_add_del_feature(
5003 sw_if_index=self.pg1.sw_if_index,
5008 clients = ip4_range(self.pg1.remote_ip4, 10, 50)
5010 for client in clients:
5011 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
5012 IP(src=client, dst=self.nat_addr) /
5013 TCP(sport=12345, dport=external_port))
5015 self.pg1.add_stream(pkts)
5016 self.pg_enable_capture(self.pg_interfaces)
5018 capture = self.pg0.get_capture(len(pkts))
5020 if p[IP].dst == server1.ip4:
5024 self.assertGreater(server1_n, server2_n)
5027 'addr': server3.ip4n,
5034 self.vapi.nat44_lb_static_mapping_add_del_local(
5036 external_addr=external_addr,
5037 external_port=external_port,
5039 protocol=IP_PROTOS.tcp)
5043 clients = ip4_range(self.pg1.remote_ip4, 60, 110)
5045 for client in clients:
5046 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
5047 IP(src=client, dst=self.nat_addr) /
5048 TCP(sport=12346, dport=external_port))
5050 self.assertGreater(len(pkts), 0)
5051 self.pg1.add_stream(pkts)
5052 self.pg_enable_capture(self.pg_interfaces)
5054 capture = self.pg0.get_capture(len(pkts))
5056 if p[IP].dst == server1.ip4:
5058 elif p[IP].dst == server2.ip4:
5062 self.assertGreater(server1_n, 0)
5063 self.assertGreater(server2_n, 0)
5064 self.assertGreater(server3_n, 0)
5067 'addr': server2.ip4n,
5073 # remove one back-end
5074 self.vapi.nat44_lb_static_mapping_add_del_local(
5076 external_addr=external_addr,
5077 external_port=external_port,
5079 protocol=IP_PROTOS.tcp)
5083 self.pg1.add_stream(pkts)
5084 self.pg_enable_capture(self.pg_interfaces)
5086 capture = self.pg0.get_capture(len(pkts))
5088 if p[IP].dst == server1.ip4:
5090 elif p[IP].dst == server2.ip4:
5094 self.assertGreater(server1_n, 0)
5095 self.assertEqual(server2_n, 0)
5096 self.assertGreater(server3_n, 0)
5098 def test_static_lb_2(self):
5099 """ NAT44 local service load balancing (asymmetrical rule) """
5100 external_addr = self.nat_addr
5103 server1 = self.pg0.remote_hosts[0]
5104 server2 = self.pg0.remote_hosts[1]
5106 locals = [{'addr': server1.ip4n,
5110 {'addr': server2.ip4n,
5115 self.vapi.nat44_forwarding_enable_disable(enable=1)
5116 flags = self.config_flags.NAT_IS_OUT2IN_ONLY
5117 self.vapi.nat44_add_del_lb_static_mapping(is_add=1, flags=flags,
5118 external_addr=external_addr,
5119 external_port=external_port,
5120 protocol=IP_PROTOS.tcp,
5121 local_num=len(locals),
5123 flags = self.config_flags.NAT_IS_INSIDE
5124 self.vapi.nat44_interface_add_del_feature(
5125 sw_if_index=self.pg0.sw_if_index,
5126 flags=flags, is_add=1)
5127 self.vapi.nat44_interface_add_del_feature(
5128 sw_if_index=self.pg1.sw_if_index,
5131 # from client to service
5132 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
5133 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
5134 TCP(sport=12345, dport=external_port))
5135 self.pg1.add_stream(p)
5136 self.pg_enable_capture(self.pg_interfaces)
5138 capture = self.pg0.get_capture(1)
5144 self.assertIn(ip.dst, [server1.ip4, server2.ip4])
5145 if ip.dst == server1.ip4:
5149 self.assertEqual(tcp.dport, local_port)
5150 self.assert_packet_checksums_valid(p)
5152 self.logger.error(ppp("Unexpected or invalid packet:", p))
5155 # from service back to client
5156 p = (Ether(src=server.mac, dst=self.pg0.local_mac) /
5157 IP(src=server.ip4, dst=self.pg1.remote_ip4) /
5158 TCP(sport=local_port, dport=12345))
5159 self.pg0.add_stream(p)
5160 self.pg_enable_capture(self.pg_interfaces)
5162 capture = self.pg1.get_capture(1)
5167 self.assertEqual(ip.src, self.nat_addr)
5168 self.assertEqual(tcp.sport, external_port)
5169 self.assert_packet_checksums_valid(p)
5171 self.logger.error(ppp("Unexpected or invalid packet:", p))
5174 # from client to server (no translation)
5175 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
5176 IP(src=self.pg1.remote_ip4, dst=server1.ip4) /
5177 TCP(sport=12346, dport=local_port))
5178 self.pg1.add_stream(p)
5179 self.pg_enable_capture(self.pg_interfaces)
5181 capture = self.pg0.get_capture(1)
5187 self.assertEqual(ip.dst, server1.ip4)
5188 self.assertEqual(tcp.dport, local_port)
5189 self.assert_packet_checksums_valid(p)
5191 self.logger.error(ppp("Unexpected or invalid packet:", p))
5194 # from service back to client (no translation)
5195 p = (Ether(src=server1.mac, dst=self.pg0.local_mac) /
5196 IP(src=server1.ip4, dst=self.pg1.remote_ip4) /
5197 TCP(sport=local_port, dport=12346))
5198 self.pg0.add_stream(p)
5199 self.pg_enable_capture(self.pg_interfaces)
5201 capture = self.pg1.get_capture(1)
5206 self.assertEqual(ip.src, server1.ip4)
5207 self.assertEqual(tcp.sport, local_port)
5208 self.assert_packet_checksums_valid(p)
5210 self.logger.error(ppp("Unexpected or invalid packet:", p))
5213 def test_lb_affinity(self):
5214 """ NAT44 local service load balancing affinity """
5215 external_addr = self.nat_addr
5218 server1 = self.pg0.remote_hosts[0]
5219 server2 = self.pg0.remote_hosts[1]
5221 locals = [{'addr': server1.ip4n,
5225 {'addr': server2.ip4n,
5230 self.nat44_add_address(self.nat_addr)
5231 self.vapi.nat44_add_del_lb_static_mapping(is_add=1,
5232 external_addr=external_addr,
5233 external_port=external_port,
5234 protocol=IP_PROTOS.tcp,
5236 local_num=len(locals),
5238 flags = self.config_flags.NAT_IS_INSIDE
5239 self.vapi.nat44_interface_add_del_feature(
5240 sw_if_index=self.pg0.sw_if_index,
5241 flags=flags, is_add=1)
5242 self.vapi.nat44_interface_add_del_feature(
5243 sw_if_index=self.pg1.sw_if_index,
5246 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
5247 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
5248 TCP(sport=1025, dport=external_port))
5249 self.pg1.add_stream(p)
5250 self.pg_enable_capture(self.pg_interfaces)
5252 capture = self.pg0.get_capture(1)
5253 backend = capture[0][IP].dst
5255 sessions = self.vapi.nat44_user_session_dump(backend, 0)
5256 self.assertEqual(len(sessions), 1)
5257 self.assertTrue(sessions[0].flags &
5258 self.config_flags.NAT_IS_EXT_HOST_VALID)
5259 self.vapi.nat44_del_session(
5260 address=sessions[0].inside_ip_address,
5261 port=sessions[0].inside_port,
5262 protocol=sessions[0].protocol,
5263 flags=(self.config_flags.NAT_IS_INSIDE |
5264 self.config_flags.NAT_IS_EXT_HOST_VALID),
5265 ext_host_address=sessions[0].ext_host_address,
5266 ext_host_port=sessions[0].ext_host_port)
5269 for port in range(1030, 1100):
5270 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
5271 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
5272 TCP(sport=port, dport=external_port))
5274 self.pg1.add_stream(pkts)
5275 self.pg_enable_capture(self.pg_interfaces)
5277 capture = self.pg0.get_capture(len(pkts))
5279 self.assertEqual(p[IP].dst, backend)
5281 def test_unknown_proto(self):
5282 """ NAT44 translate packet with unknown protocol """
5283 self.nat44_add_address(self.nat_addr)
5284 flags = self.config_flags.NAT_IS_INSIDE
5285 self.vapi.nat44_interface_add_del_feature(
5286 sw_if_index=self.pg0.sw_if_index,
5287 flags=flags, is_add=1)
5288 self.vapi.nat44_interface_add_del_feature(
5289 sw_if_index=self.pg1.sw_if_index,
5293 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
5294 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
5295 TCP(sport=self.tcp_port_in, dport=20))
5296 self.pg0.add_stream(p)
5297 self.pg_enable_capture(self.pg_interfaces)
5299 p = self.pg1.get_capture(1)
5301 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
5302 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
5304 IP(src=self.pg2.remote_ip4, dst=self.pg2.remote_ip4) /
5305 TCP(sport=1234, dport=1234))
5306 self.pg0.add_stream(p)
5307 self.pg_enable_capture(self.pg_interfaces)
5309 p = self.pg1.get_capture(1)
5312 self.assertEqual(packet[IP].src, self.nat_addr)
5313 self.assertEqual(packet[IP].dst, self.pg1.remote_ip4)
5314 self.assertEqual(packet.haslayer(GRE), 1)
5315 self.assert_packet_checksums_valid(packet)
5317 self.logger.error(ppp("Unexpected or invalid packet:", packet))
5321 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
5322 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
5324 IP(src=self.pg2.remote_ip4, dst=self.pg2.remote_ip4) /
5325 TCP(sport=1234, dport=1234))
5326 self.pg1.add_stream(p)
5327 self.pg_enable_capture(self.pg_interfaces)
5329 p = self.pg0.get_capture(1)
5332 self.assertEqual(packet[IP].src, self.pg1.remote_ip4)
5333 self.assertEqual(packet[IP].dst, self.pg0.remote_ip4)
5334 self.assertEqual(packet.haslayer(GRE), 1)
5335 self.assert_packet_checksums_valid(packet)
5337 self.logger.error(ppp("Unexpected or invalid packet:", packet))
5340 def test_hairpinning_unknown_proto(self):
5341 """ NAT44 translate packet with unknown protocol - hairpinning """
5342 host = self.pg0.remote_hosts[0]
5343 server = self.pg0.remote_hosts[1]
5345 server_out_port = 8765
5346 server_nat_ip = "10.0.0.11"
5348 self.nat44_add_address(self.nat_addr)
5349 flags = self.config_flags.NAT_IS_INSIDE
5350 self.vapi.nat44_interface_add_del_feature(
5351 sw_if_index=self.pg0.sw_if_index,
5352 flags=flags, is_add=1)
5353 self.vapi.nat44_interface_add_del_feature(
5354 sw_if_index=self.pg1.sw_if_index,
5357 # add static mapping for server
5358 self.nat44_add_static_mapping(server.ip4, server_nat_ip)
5361 p = (Ether(src=host.mac, dst=self.pg0.local_mac) /
5362 IP(src=host.ip4, dst=server_nat_ip) /
5363 TCP(sport=host_in_port, dport=server_out_port))
5364 self.pg0.add_stream(p)
5365 self.pg_enable_capture(self.pg_interfaces)
5367 self.pg0.get_capture(1)
5369 p = (Ether(dst=self.pg0.local_mac, src=host.mac) /
5370 IP(src=host.ip4, dst=server_nat_ip) /
5372 IP(src=self.pg2.remote_ip4, dst=self.pg2.remote_ip4) /
5373 TCP(sport=1234, dport=1234))
5374 self.pg0.add_stream(p)
5375 self.pg_enable_capture(self.pg_interfaces)
5377 p = self.pg0.get_capture(1)
5380 self.assertEqual(packet[IP].src, self.nat_addr)
5381 self.assertEqual(packet[IP].dst, server.ip4)
5382 self.assertEqual(packet.haslayer(GRE), 1)
5383 self.assert_packet_checksums_valid(packet)
5385 self.logger.error(ppp("Unexpected or invalid packet:", packet))
5389 p = (Ether(dst=self.pg0.local_mac, src=server.mac) /
5390 IP(src=server.ip4, dst=self.nat_addr) /
5392 IP(src=self.pg2.remote_ip4, dst=self.pg2.remote_ip4) /
5393 TCP(sport=1234, dport=1234))
5394 self.pg0.add_stream(p)
5395 self.pg_enable_capture(self.pg_interfaces)
5397 p = self.pg0.get_capture(1)
5400 self.assertEqual(packet[IP].src, server_nat_ip)
5401 self.assertEqual(packet[IP].dst, host.ip4)
5402 self.assertEqual(packet.haslayer(GRE), 1)
5403 self.assert_packet_checksums_valid(packet)
5405 self.logger.error(ppp("Unexpected or invalid packet:", packet))
5408 def test_output_feature_and_service(self):
5409 """ NAT44 interface output feature and services """
5410 external_addr = '1.2.3.4'
5414 self.vapi.nat44_forwarding_enable_disable(enable=1)
5415 self.nat44_add_address(self.nat_addr)
5416 flags = self.config_flags.NAT_IS_ADDR_ONLY
5417 self.vapi.nat44_add_del_identity_mapping(
5418 ip_address=self.pg1.remote_ip4n, sw_if_index=0xFFFFFFFF,
5419 flags=flags, is_add=1)
5420 flags = self.config_flags.NAT_IS_OUT2IN_ONLY
5421 self.nat44_add_static_mapping(self.pg0.remote_ip4, external_addr,
5422 local_port, external_port,
5423 proto=IP_PROTOS.tcp, flags=flags)
5424 flags = self.config_flags.NAT_IS_INSIDE
5425 self.vapi.nat44_interface_add_del_feature(
5426 sw_if_index=self.pg0.sw_if_index,
5428 self.vapi.nat44_interface_add_del_feature(
5429 sw_if_index=self.pg0.sw_if_index,
5430 flags=flags, is_add=1)
5431 self.vapi.nat44_interface_add_del_output_feature(
5433 sw_if_index=self.pg1.sw_if_index)
5435 # from client to service
5436 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
5437 IP(src=self.pg1.remote_ip4, dst=external_addr) /
5438 TCP(sport=12345, dport=external_port))
5439 self.pg1.add_stream(p)
5440 self.pg_enable_capture(self.pg_interfaces)
5442 capture = self.pg0.get_capture(1)
5447 self.assertEqual(ip.dst, self.pg0.remote_ip4)
5448 self.assertEqual(tcp.dport, local_port)
5449 self.assert_packet_checksums_valid(p)
5451 self.logger.error(ppp("Unexpected or invalid packet:", p))
5454 # from service back to client
5455 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5456 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
5457 TCP(sport=local_port, dport=12345))
5458 self.pg0.add_stream(p)
5459 self.pg_enable_capture(self.pg_interfaces)
5461 capture = self.pg1.get_capture(1)
5466 self.assertEqual(ip.src, external_addr)
5467 self.assertEqual(tcp.sport, external_port)
5468 self.assert_packet_checksums_valid(p)
5470 self.logger.error(ppp("Unexpected or invalid packet:", p))
5473 # from local network host to external network
5474 pkts = self.create_stream_in(self.pg0, self.pg1)
5475 self.pg0.add_stream(pkts)
5476 self.pg_enable_capture(self.pg_interfaces)
5478 capture = self.pg1.get_capture(len(pkts))
5479 self.verify_capture_out(capture)
5480 pkts = self.create_stream_in(self.pg0, self.pg1)
5481 self.pg0.add_stream(pkts)
5482 self.pg_enable_capture(self.pg_interfaces)
5484 capture = self.pg1.get_capture(len(pkts))
5485 self.verify_capture_out(capture)
5487 # from external network back to local network host
5488 pkts = self.create_stream_out(self.pg1)
5489 self.pg1.add_stream(pkts)
5490 self.pg_enable_capture(self.pg_interfaces)
5492 capture = self.pg0.get_capture(len(pkts))
5493 self.verify_capture_in(capture, self.pg0)
5495 def test_output_feature_and_service2(self):
5496 """ NAT44 interface output feature and service host direct access """
5497 self.vapi.nat44_forwarding_enable_disable(enable=1)
5498 self.nat44_add_address(self.nat_addr)
5499 self.vapi.nat44_interface_add_del_output_feature(
5501 sw_if_index=self.pg1.sw_if_index)
5503 # session initiated from service host - translate
5504 pkts = self.create_stream_in(self.pg0, self.pg1)
5505 self.pg0.add_stream(pkts)
5506 self.pg_enable_capture(self.pg_interfaces)
5508 capture = self.pg1.get_capture(len(pkts))
5509 self.verify_capture_out(capture)
5511 pkts = self.create_stream_out(self.pg1)
5512 self.pg1.add_stream(pkts)
5513 self.pg_enable_capture(self.pg_interfaces)
5515 capture = self.pg0.get_capture(len(pkts))
5516 self.verify_capture_in(capture, self.pg0)
5518 # session initiated from remote host - do not translate
5519 self.tcp_port_in = 60303
5520 self.udp_port_in = 60304
5521 self.icmp_id_in = 60305
5522 pkts = self.create_stream_out(self.pg1,
5523 self.pg0.remote_ip4,
5524 use_inside_ports=True)
5525 self.pg1.add_stream(pkts)
5526 self.pg_enable_capture(self.pg_interfaces)
5528 capture = self.pg0.get_capture(len(pkts))
5529 self.verify_capture_in(capture, self.pg0)
5531 pkts = self.create_stream_in(self.pg0, self.pg1)
5532 self.pg0.add_stream(pkts)
5533 self.pg_enable_capture(self.pg_interfaces)
5535 capture = self.pg1.get_capture(len(pkts))
5536 self.verify_capture_out(capture, nat_ip=self.pg0.remote_ip4,
5539 def test_output_feature_and_service3(self):
5540 """ NAT44 interface output feature and DST NAT """
5541 external_addr = '1.2.3.4'
5545 self.vapi.nat44_forwarding_enable_disable(enable=1)
5546 self.nat44_add_address(self.nat_addr)
5547 flags = self.config_flags.NAT_IS_OUT2IN_ONLY
5548 self.nat44_add_static_mapping(self.pg1.remote_ip4, external_addr,
5549 local_port, external_port,
5550 proto=IP_PROTOS.tcp, flags=flags)
5551 flags = self.config_flags.NAT_IS_INSIDE
5552 self.vapi.nat44_interface_add_del_feature(
5553 sw_if_index=self.pg0.sw_if_index,
5555 self.vapi.nat44_interface_add_del_feature(
5556 sw_if_index=self.pg0.sw_if_index,
5557 flags=flags, is_add=1)
5558 self.vapi.nat44_interface_add_del_output_feature(
5560 sw_if_index=self.pg1.sw_if_index)
5562 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5563 IP(src=self.pg0.remote_ip4, dst=external_addr) /
5564 TCP(sport=12345, dport=external_port))
5565 self.pg0.add_stream(p)
5566 self.pg_enable_capture(self.pg_interfaces)
5568 capture = self.pg1.get_capture(1)
5573 self.assertEqual(ip.src, self.pg0.remote_ip4)
5574 self.assertEqual(tcp.sport, 12345)
5575 self.assertEqual(ip.dst, self.pg1.remote_ip4)
5576 self.assertEqual(tcp.dport, local_port)
5577 self.assert_packet_checksums_valid(p)
5579 self.logger.error(ppp("Unexpected or invalid packet:", p))
5582 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
5583 IP(src=self.pg1.remote_ip4, dst=self.pg0.remote_ip4) /
5584 TCP(sport=local_port, dport=12345))
5585 self.pg1.add_stream(p)
5586 self.pg_enable_capture(self.pg_interfaces)
5588 capture = self.pg0.get_capture(1)
5593 self.assertEqual(ip.src, external_addr)
5594 self.assertEqual(tcp.sport, external_port)
5595 self.assertEqual(ip.dst, self.pg0.remote_ip4)
5596 self.assertEqual(tcp.dport, 12345)
5597 self.assert_packet_checksums_valid(p)
5599 self.logger.error(ppp("Unexpected or invalid packet:", p))
5602 def test_next_src_nat(self):
5603 """ On way back forward packet to nat44-in2out node. """
5604 twice_nat_addr = '10.0.1.3'
5607 post_twice_nat_port = 0
5609 self.vapi.nat44_forwarding_enable_disable(enable=1)
5610 self.nat44_add_address(twice_nat_addr, twice_nat=1)
5611 flags = (self.config_flags.NAT_IS_OUT2IN_ONLY |
5612 self.config_flags.NAT_IS_SELF_TWICE_NAT)
5613 self.nat44_add_static_mapping(self.pg6.remote_ip4, self.pg1.remote_ip4,
5614 local_port, external_port,
5615 proto=IP_PROTOS.tcp, vrf_id=1,
5617 self.vapi.nat44_interface_add_del_feature(
5618 sw_if_index=self.pg6.sw_if_index,
5621 p = (Ether(src=self.pg6.remote_mac, dst=self.pg6.local_mac) /
5622 IP(src=self.pg6.remote_ip4, dst=self.pg1.remote_ip4) /
5623 TCP(sport=12345, dport=external_port))
5624 self.pg6.add_stream(p)
5625 self.pg_enable_capture(self.pg_interfaces)
5627 capture = self.pg6.get_capture(1)
5632 self.assertEqual(ip.src, twice_nat_addr)
5633 self.assertNotEqual(tcp.sport, 12345)
5634 post_twice_nat_port = tcp.sport
5635 self.assertEqual(ip.dst, self.pg6.remote_ip4)
5636 self.assertEqual(tcp.dport, local_port)
5637 self.assert_packet_checksums_valid(p)
5639 self.logger.error(ppp("Unexpected or invalid packet:", p))
5642 p = (Ether(src=self.pg6.remote_mac, dst=self.pg6.local_mac) /
5643 IP(src=self.pg6.remote_ip4, dst=twice_nat_addr) /
5644 TCP(sport=local_port, dport=post_twice_nat_port))
5645 self.pg6.add_stream(p)
5646 self.pg_enable_capture(self.pg_interfaces)
5648 capture = self.pg6.get_capture(1)
5653 self.assertEqual(ip.src, self.pg1.remote_ip4)
5654 self.assertEqual(tcp.sport, external_port)
5655 self.assertEqual(ip.dst, self.pg6.remote_ip4)
5656 self.assertEqual(tcp.dport, 12345)
5657 self.assert_packet_checksums_valid(p)
5659 self.logger.error(ppp("Unexpected or invalid packet:", p))
5662 def twice_nat_common(self, self_twice_nat=False, same_pg=False, lb=False,
5664 twice_nat_addr = '10.0.1.3'
5672 port_in1 = port_in + 1
5673 port_in2 = port_in + 2
5678 server1 = self.pg0.remote_hosts[0]
5679 server2 = self.pg0.remote_hosts[1]
5691 eh_translate = ((not self_twice_nat) or (not lb and same_pg) or
5694 self.nat44_add_address(self.nat_addr)
5695 self.nat44_add_address(twice_nat_addr, twice_nat=1)
5699 flags |= self.config_flags.NAT_IS_SELF_TWICE_NAT
5701 flags |= self.config_flags.NAT_IS_TWICE_NAT
5704 self.nat44_add_static_mapping(pg0.remote_ip4, self.nat_addr,
5706 proto=IP_PROTOS.tcp,
5709 locals = [{'addr': server1.ip4n,
5713 {'addr': server2.ip4n,
5717 out_addr = self.nat_addr
5719 self.vapi.nat44_add_del_lb_static_mapping(is_add=1, flags=flags,
5720 external_addr=out_addr,
5721 external_port=port_out,
5722 protocol=IP_PROTOS.tcp,
5723 local_num=len(locals),
5725 flags = self.config_flags.NAT_IS_INSIDE
5726 self.vapi.nat44_interface_add_del_feature(
5727 sw_if_index=pg0.sw_if_index,
5728 flags=flags, is_add=1)
5729 self.vapi.nat44_interface_add_del_feature(
5730 sw_if_index=pg1.sw_if_index,
5737 assert client_id is not None
5739 client = self.pg0.remote_hosts[0]
5740 elif client_id == 2:
5741 client = self.pg0.remote_hosts[1]
5743 client = pg1.remote_hosts[0]
5744 p = (Ether(src=pg1.remote_mac, dst=pg1.local_mac) /
5745 IP(src=client.ip4, dst=self.nat_addr) /
5746 TCP(sport=eh_port_out, dport=port_out))
5748 self.pg_enable_capture(self.pg_interfaces)
5750 capture = pg0.get_capture(1)
5756 if ip.dst == server1.ip4:
5762 self.assertEqual(ip.dst, server.ip4)
5764 self.assertIn(tcp.dport, [port_in1, port_in2])
5766 self.assertEqual(tcp.dport, port_in)
5768 self.assertEqual(ip.src, twice_nat_addr)
5769 self.assertNotEqual(tcp.sport, eh_port_out)
5771 self.assertEqual(ip.src, client.ip4)
5772 self.assertEqual(tcp.sport, eh_port_out)
5774 eh_port_in = tcp.sport
5775 saved_port_in = tcp.dport
5776 self.assert_packet_checksums_valid(p)
5778 self.logger.error(ppp("Unexpected or invalid packet:", p))
5781 p = (Ether(src=server.mac, dst=pg0.local_mac) /
5782 IP(src=server.ip4, dst=eh_addr_in) /
5783 TCP(sport=saved_port_in, dport=eh_port_in))
5785 self.pg_enable_capture(self.pg_interfaces)
5787 capture = pg1.get_capture(1)
5792 self.assertEqual(ip.dst, client.ip4)
5793 self.assertEqual(ip.src, self.nat_addr)
5794 self.assertEqual(tcp.dport, eh_port_out)
5795 self.assertEqual(tcp.sport, port_out)
5796 self.assert_packet_checksums_valid(p)
5798 self.logger.error(ppp("Unexpected or invalid packet:", p))
5802 sessions = self.vapi.nat44_user_session_dump(server.ip4n, 0)
5803 self.assertEqual(len(sessions), 1)
5804 self.assertTrue(sessions[0].flags &
5805 self.config_flags.NAT_IS_EXT_HOST_VALID)
5806 self.assertTrue(sessions[0].flags &
5807 self.config_flags.NAT_IS_TWICE_NAT)
5808 self.logger.error(self.vapi.cli("show nat44 sessions detail"))
5809 self.vapi.nat44_del_session(
5810 address=sessions[0].inside_ip_address,
5811 port=sessions[0].inside_port,
5812 protocol=sessions[0].protocol,
5813 flags=(self.config_flags.NAT_IS_INSIDE |
5814 self.config_flags.NAT_IS_EXT_HOST_VALID),
5815 ext_host_address=sessions[0].ext_host_nat_address,
5816 ext_host_port=sessions[0].ext_host_nat_port)
5817 sessions = self.vapi.nat44_user_session_dump(server.ip4n, 0)
5818 self.assertEqual(len(sessions), 0)
5820 def test_twice_nat(self):
5822 self.twice_nat_common()
5824 def test_self_twice_nat_positive(self):
5825 """ Self Twice NAT44 (positive test) """
5826 self.twice_nat_common(self_twice_nat=True, same_pg=True)
5828 def test_self_twice_nat_negative(self):
5829 """ Self Twice NAT44 (negative test) """
5830 self.twice_nat_common(self_twice_nat=True)
5832 def test_twice_nat_lb(self):
5833 """ Twice NAT44 local service load balancing """
5834 self.twice_nat_common(lb=True)
5836 def test_self_twice_nat_lb_positive(self):
5837 """ Self Twice NAT44 local service load balancing (positive test) """
5838 self.twice_nat_common(lb=True, self_twice_nat=True, same_pg=True,
5841 def test_self_twice_nat_lb_negative(self):
5842 """ Self Twice NAT44 local service load balancing (negative test) """
5843 self.twice_nat_common(lb=True, self_twice_nat=True, same_pg=True,
5846 def test_twice_nat_interface_addr(self):
5847 """ Acquire twice NAT44 addresses from interface """
5848 flags = self.config_flags.NAT_IS_TWICE_NAT
5849 self.vapi.nat44_add_del_interface_addr(
5851 sw_if_index=self.pg3.sw_if_index,
5854 # no address in NAT pool
5855 adresses = self.vapi.nat44_address_dump()
5856 self.assertEqual(0, len(adresses))
5858 # configure interface address and check NAT address pool
5859 self.pg3.config_ip4()
5860 adresses = self.vapi.nat44_address_dump()
5861 self.assertEqual(1, len(adresses))
5862 self.assertEqual(str(adresses[0].ip_address),
5864 self.assertEqual(adresses[0].flags, flags)
5866 # remove interface address and check NAT address pool
5867 self.pg3.unconfig_ip4()
5868 adresses = self.vapi.nat44_address_dump()
5869 self.assertEqual(0, len(adresses))
5871 def test_tcp_close(self):
5872 """ Close TCP session from inside network - output feature """
5873 self.vapi.nat44_forwarding_enable_disable(enable=1)
5874 self.nat44_add_address(self.pg1.local_ip4)
5875 twice_nat_addr = '10.0.1.3'
5876 service_ip = '192.168.16.150'
5877 self.nat44_add_address(twice_nat_addr, twice_nat=1)
5878 flags = self.config_flags.NAT_IS_INSIDE
5879 self.vapi.nat44_interface_add_del_feature(
5880 sw_if_index=self.pg0.sw_if_index,
5882 self.vapi.nat44_interface_add_del_feature(
5883 sw_if_index=self.pg0.sw_if_index,
5884 flags=flags, is_add=1)
5885 self.vapi.nat44_interface_add_del_output_feature(
5887 sw_if_index=self.pg1.sw_if_index)
5888 flags = (self.config_flags.NAT_IS_OUT2IN_ONLY |
5889 self.config_flags.NAT_IS_TWICE_NAT)
5890 self.nat44_add_static_mapping(self.pg0.remote_ip4,
5894 proto=IP_PROTOS.tcp,
5896 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4n, 0)
5897 start_sessnum = len(sessions)
5899 # SYN packet out->in
5900 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
5901 IP(src=self.pg1.remote_ip4, dst=service_ip) /
5902 TCP(sport=33898, dport=80, flags="S"))
5903 self.pg1.add_stream(p)
5904 self.pg_enable_capture(self.pg_interfaces)
5906 capture = self.pg0.get_capture(1)
5908 tcp_port = p[TCP].sport
5910 # SYN + ACK packet in->out
5911 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5912 IP(src=self.pg0.remote_ip4, dst=twice_nat_addr) /
5913 TCP(sport=80, dport=tcp_port, flags="SA"))
5914 self.pg0.add_stream(p)
5915 self.pg_enable_capture(self.pg_interfaces)
5917 self.pg1.get_capture(1)
5919 # ACK packet out->in
5920 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
5921 IP(src=self.pg1.remote_ip4, dst=service_ip) /
5922 TCP(sport=33898, dport=80, flags="A"))
5923 self.pg1.add_stream(p)
5924 self.pg_enable_capture(self.pg_interfaces)
5926 self.pg0.get_capture(1)
5928 # FIN packet in -> out
5929 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5930 IP(src=self.pg0.remote_ip4, dst=twice_nat_addr) /
5931 TCP(sport=80, dport=tcp_port, flags="FA", seq=100, ack=300))
5932 self.pg0.add_stream(p)
5933 self.pg_enable_capture(self.pg_interfaces)
5935 self.pg1.get_capture(1)
5937 # FIN+ACK packet out -> in
5938 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
5939 IP(src=self.pg1.remote_ip4, dst=service_ip) /
5940 TCP(sport=33898, dport=80, flags="FA", seq=300, ack=101))
5941 self.pg1.add_stream(p)
5942 self.pg_enable_capture(self.pg_interfaces)
5944 self.pg0.get_capture(1)
5946 # ACK packet in -> out
5947 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5948 IP(src=self.pg0.remote_ip4, dst=twice_nat_addr) /
5949 TCP(sport=80, dport=tcp_port, flags="A", seq=101, ack=301))
5950 self.pg0.add_stream(p)
5951 self.pg_enable_capture(self.pg_interfaces)
5953 self.pg1.get_capture(1)
5955 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4n,
5957 self.assertEqual(len(sessions) - start_sessnum, 0)
5959 def test_tcp_session_close_in(self):
5960 """ Close TCP session from inside network """
5961 self.tcp_port_out = 10505
5962 self.nat44_add_address(self.nat_addr)
5963 flags = self.config_flags.NAT_IS_TWICE_NAT
5964 self.nat44_add_static_mapping(self.pg0.remote_ip4,
5968 proto=IP_PROTOS.tcp,
5970 flags = self.config_flags.NAT_IS_INSIDE
5971 self.vapi.nat44_interface_add_del_feature(
5972 sw_if_index=self.pg0.sw_if_index,
5973 flags=flags, is_add=1)
5974 self.vapi.nat44_interface_add_del_feature(
5975 sw_if_index=self.pg1.sw_if_index,
5978 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4n, 0)
5979 start_sessnum = len(sessions)
5981 self.initiate_tcp_session(self.pg0, self.pg1)
5983 # FIN packet in -> out
5984 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5985 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
5986 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
5987 flags="FA", seq=100, ack=300))
5988 self.pg0.add_stream(p)
5989 self.pg_enable_capture(self.pg_interfaces)
5991 self.pg1.get_capture(1)
5995 # ACK packet out -> in
5996 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
5997 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
5998 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
5999 flags="A", seq=300, ack=101))
6002 # FIN packet out -> in
6003 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
6004 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
6005 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
6006 flags="FA", seq=300, ack=101))
6009 self.pg1.add_stream(pkts)
6010 self.pg_enable_capture(self.pg_interfaces)
6012 self.pg0.get_capture(2)
6014 # ACK packet in -> out
6015 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6016 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6017 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
6018 flags="A", seq=101, ack=301))
6019 self.pg0.add_stream(p)
6020 self.pg_enable_capture(self.pg_interfaces)
6022 self.pg1.get_capture(1)
6024 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4n,
6026 self.assertEqual(len(sessions) - start_sessnum, 0)
6028 def test_tcp_session_close_out(self):
6029 """ Close TCP session from outside network """
6030 self.tcp_port_out = 10505
6031 self.nat44_add_address(self.nat_addr)
6032 flags = self.config_flags.NAT_IS_TWICE_NAT
6033 self.nat44_add_static_mapping(self.pg0.remote_ip4,
6037 proto=IP_PROTOS.tcp,
6039 flags = self.config_flags.NAT_IS_INSIDE
6040 self.vapi.nat44_interface_add_del_feature(
6041 sw_if_index=self.pg0.sw_if_index,
6042 flags=flags, is_add=1)
6043 self.vapi.nat44_interface_add_del_feature(
6044 sw_if_index=self.pg1.sw_if_index,
6047 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4n, 0)
6048 start_sessnum = len(sessions)
6050 self.initiate_tcp_session(self.pg0, self.pg1)
6052 # FIN packet out -> in
6053 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
6054 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
6055 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
6056 flags="FA", seq=100, ack=300))
6057 self.pg1.add_stream(p)
6058 self.pg_enable_capture(self.pg_interfaces)
6060 self.pg0.get_capture(1)
6062 # FIN+ACK packet in -> out
6063 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6064 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6065 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
6066 flags="FA", seq=300, ack=101))
6068 self.pg0.add_stream(p)
6069 self.pg_enable_capture(self.pg_interfaces)
6071 self.pg1.get_capture(1)
6073 # ACK packet out -> in
6074 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
6075 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
6076 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
6077 flags="A", seq=101, ack=301))
6078 self.pg1.add_stream(p)
6079 self.pg_enable_capture(self.pg_interfaces)
6081 self.pg0.get_capture(1)
6083 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4n,
6085 self.assertEqual(len(sessions) - start_sessnum, 0)
6087 def test_tcp_session_close_simultaneous(self):
6088 """ Close TCP session from inside network """
6089 self.tcp_port_out = 10505
6090 self.nat44_add_address(self.nat_addr)
6091 flags = self.config_flags.NAT_IS_TWICE_NAT
6092 self.nat44_add_static_mapping(self.pg0.remote_ip4,
6096 proto=IP_PROTOS.tcp,
6098 flags = self.config_flags.NAT_IS_INSIDE
6099 self.vapi.nat44_interface_add_del_feature(
6100 sw_if_index=self.pg0.sw_if_index,
6101 flags=flags, is_add=1)
6102 self.vapi.nat44_interface_add_del_feature(
6103 sw_if_index=self.pg1.sw_if_index,
6106 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4n, 0)
6107 start_sessnum = len(sessions)
6109 self.initiate_tcp_session(self.pg0, self.pg1)
6111 # FIN packet in -> out
6112 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6113 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6114 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
6115 flags="FA", seq=100, ack=300))
6116 self.pg0.add_stream(p)
6117 self.pg_enable_capture(self.pg_interfaces)
6119 self.pg1.get_capture(1)
6121 # FIN packet out -> in
6122 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
6123 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
6124 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
6125 flags="FA", seq=300, ack=100))
6126 self.pg1.add_stream(p)
6127 self.pg_enable_capture(self.pg_interfaces)
6129 self.pg0.get_capture(1)
6131 # ACK packet in -> out
6132 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6133 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6134 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
6135 flags="A", seq=101, ack=301))
6136 self.pg0.add_stream(p)
6137 self.pg_enable_capture(self.pg_interfaces)
6139 self.pg1.get_capture(1)
6141 # ACK packet out -> in
6142 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
6143 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
6144 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
6145 flags="A", seq=301, ack=101))
6146 self.pg1.add_stream(p)
6147 self.pg_enable_capture(self.pg_interfaces)
6149 self.pg0.get_capture(1)
6151 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4n,
6153 self.assertEqual(len(sessions) - start_sessnum, 0)
6155 def test_one_armed_nat44_static(self):
6156 """ One armed NAT44 and 1:1 NAPT asymmetrical rule """
6157 remote_host = self.pg4.remote_hosts[0]
6158 local_host = self.pg4.remote_hosts[1]
6163 self.vapi.nat44_forwarding_enable_disable(enable=1)
6164 self.nat44_add_address(self.nat_addr, twice_nat=1)
6165 flags = (self.config_flags.NAT_IS_OUT2IN_ONLY |
6166 self.config_flags.NAT_IS_TWICE_NAT)
6167 self.nat44_add_static_mapping(local_host.ip4, self.nat_addr,
6168 local_port, external_port,
6169 proto=IP_PROTOS.tcp, flags=flags)
6170 flags = self.config_flags.NAT_IS_INSIDE
6171 self.vapi.nat44_interface_add_del_feature(
6172 sw_if_index=self.pg4.sw_if_index,
6174 self.vapi.nat44_interface_add_del_feature(
6175 sw_if_index=self.pg4.sw_if_index,
6176 flags=flags, is_add=1)
6178 # from client to service
6179 p = (Ether(src=self.pg4.remote_mac, dst=self.pg4.local_mac) /
6180 IP(src=remote_host.ip4, dst=self.nat_addr) /
6181 TCP(sport=12345, dport=external_port))
6182 self.pg4.add_stream(p)
6183 self.pg_enable_capture(self.pg_interfaces)
6185 capture = self.pg4.get_capture(1)
6190 self.assertEqual(ip.dst, local_host.ip4)
6191 self.assertEqual(ip.src, self.nat_addr)
6192 self.assertEqual(tcp.dport, local_port)
6193 self.assertNotEqual(tcp.sport, 12345)
6194 eh_port_in = tcp.sport
6195 self.assert_packet_checksums_valid(p)
6197 self.logger.error(ppp("Unexpected or invalid packet:", p))
6200 # from service back to client
6201 p = (Ether(src=self.pg4.remote_mac, dst=self.pg4.local_mac) /
6202 IP(src=local_host.ip4, dst=self.nat_addr) /
6203 TCP(sport=local_port, dport=eh_port_in))
6204 self.pg4.add_stream(p)
6205 self.pg_enable_capture(self.pg_interfaces)
6207 capture = self.pg4.get_capture(1)
6212 self.assertEqual(ip.src, self.nat_addr)
6213 self.assertEqual(ip.dst, remote_host.ip4)
6214 self.assertEqual(tcp.sport, external_port)
6215 self.assertEqual(tcp.dport, 12345)
6216 self.assert_packet_checksums_valid(p)
6218 self.logger.error(ppp("Unexpected or invalid packet:", p))
6221 def test_static_with_port_out2(self):
6222 """ 1:1 NAPT asymmetrical rule """
6227 self.vapi.nat44_forwarding_enable_disable(enable=1)
6228 flags = self.config_flags.NAT_IS_OUT2IN_ONLY
6229 self.nat44_add_static_mapping(self.pg0.remote_ip4, self.nat_addr,
6230 local_port, external_port,
6231 proto=IP_PROTOS.tcp, flags=flags)
6232 flags = self.config_flags.NAT_IS_INSIDE
6233 self.vapi.nat44_interface_add_del_feature(
6234 sw_if_index=self.pg0.sw_if_index,
6235 flags=flags, is_add=1)
6236 self.vapi.nat44_interface_add_del_feature(
6237 sw_if_index=self.pg1.sw_if_index,
6240 # from client to service
6241 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
6242 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
6243 TCP(sport=12345, dport=external_port))
6244 self.pg1.add_stream(p)
6245 self.pg_enable_capture(self.pg_interfaces)
6247 capture = self.pg0.get_capture(1)
6252 self.assertEqual(ip.dst, self.pg0.remote_ip4)
6253 self.assertEqual(tcp.dport, local_port)
6254 self.assert_packet_checksums_valid(p)
6256 self.logger.error(ppp("Unexpected or invalid packet:", p))
6260 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
6261 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6262 ICMP(type=11) / capture[0][IP])
6263 self.pg0.add_stream(p)
6264 self.pg_enable_capture(self.pg_interfaces)
6266 capture = self.pg1.get_capture(1)
6269 self.assertEqual(p[IP].src, self.nat_addr)
6271 self.assertEqual(inner.dst, self.nat_addr)
6272 self.assertEqual(inner[TCPerror].dport, external_port)
6274 self.logger.error(ppp("Unexpected or invalid packet:", p))
6277 # from service back to client
6278 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6279 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6280 TCP(sport=local_port, dport=12345))
6281 self.pg0.add_stream(p)
6282 self.pg_enable_capture(self.pg_interfaces)
6284 capture = self.pg1.get_capture(1)
6289 self.assertEqual(ip.src, self.nat_addr)
6290 self.assertEqual(tcp.sport, external_port)
6291 self.assert_packet_checksums_valid(p)
6293 self.logger.error(ppp("Unexpected or invalid packet:", p))
6297 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
6298 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
6299 ICMP(type=11) / capture[0][IP])
6300 self.pg1.add_stream(p)
6301 self.pg_enable_capture(self.pg_interfaces)
6303 capture = self.pg0.get_capture(1)
6306 self.assertEqual(p[IP].dst, self.pg0.remote_ip4)
6308 self.assertEqual(inner.src, self.pg0.remote_ip4)
6309 self.assertEqual(inner[TCPerror].sport, local_port)
6311 self.logger.error(ppp("Unexpected or invalid packet:", p))
6314 # from client to server (no translation)
6315 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
6316 IP(src=self.pg1.remote_ip4, dst=self.pg0.remote_ip4) /
6317 TCP(sport=12346, dport=local_port))
6318 self.pg1.add_stream(p)
6319 self.pg_enable_capture(self.pg_interfaces)
6321 capture = self.pg0.get_capture(1)
6326 self.assertEqual(ip.dst, self.pg0.remote_ip4)
6327 self.assertEqual(tcp.dport, local_port)
6328 self.assert_packet_checksums_valid(p)
6330 self.logger.error(ppp("Unexpected or invalid packet:", p))
6333 # from service back to client (no translation)
6334 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6335 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6336 TCP(sport=local_port, dport=12346))
6337 self.pg0.add_stream(p)
6338 self.pg_enable_capture(self.pg_interfaces)
6340 capture = self.pg1.get_capture(1)
6345 self.assertEqual(ip.src, self.pg0.remote_ip4)
6346 self.assertEqual(tcp.sport, local_port)
6347 self.assert_packet_checksums_valid(p)
6349 self.logger.error(ppp("Unexpected or invalid packet:", p))
6352 def test_output_feature(self):
6353 """ NAT44 interface output feature (in2out postrouting) """
6354 self.vapi.nat44_forwarding_enable_disable(enable=1)
6355 self.nat44_add_address(self.nat_addr)
6356 self.vapi.nat44_interface_add_del_feature(
6357 sw_if_index=self.pg0.sw_if_index,
6359 self.vapi.nat44_interface_add_del_output_feature(
6361 sw_if_index=self.pg1.sw_if_index)
6364 pkts = self.create_stream_in(self.pg0, self.pg1)
6365 self.pg0.add_stream(pkts)
6366 self.pg_enable_capture(self.pg_interfaces)
6368 capture = self.pg1.get_capture(len(pkts))
6369 self.verify_capture_out(capture)
6372 pkts = self.create_stream_out(self.pg1)
6373 self.pg1.add_stream(pkts)
6374 self.pg_enable_capture(self.pg_interfaces)
6376 capture = self.pg0.get_capture(len(pkts))
6377 self.verify_capture_in(capture, self.pg0)
6379 def test_multiple_vrf(self):
6380 """ Multiple VRF setup """
6381 external_addr = '1.2.3.4'
6386 self.vapi.nat44_forwarding_enable_disable(enable=1)
6387 self.nat44_add_address(self.nat_addr)
6388 flags = self.config_flags.NAT_IS_INSIDE
6389 self.vapi.nat44_interface_add_del_feature(
6390 sw_if_index=self.pg0.sw_if_index,
6392 self.vapi.nat44_interface_add_del_feature(
6393 sw_if_index=self.pg0.sw_if_index,
6394 flags=flags, is_add=1)
6395 self.vapi.nat44_interface_add_del_output_feature(
6397 sw_if_index=self.pg1.sw_if_index)
6398 self.vapi.nat44_interface_add_del_feature(
6399 sw_if_index=self.pg5.sw_if_index,
6401 self.vapi.nat44_interface_add_del_feature(
6402 sw_if_index=self.pg5.sw_if_index,
6403 flags=flags, is_add=1)
6404 self.vapi.nat44_interface_add_del_feature(
6405 sw_if_index=self.pg6.sw_if_index,
6407 flags = self.config_flags.NAT_IS_OUT2IN_ONLY
6408 self.nat44_add_static_mapping(self.pg5.remote_ip4, external_addr,
6409 local_port, external_port, vrf_id=1,
6410 proto=IP_PROTOS.tcp, flags=flags)
6411 self.nat44_add_static_mapping(
6412 self.pg0.remote_ip4,
6413 external_sw_if_index=self.pg0.sw_if_index,
6414 local_port=local_port,
6416 external_port=external_port,
6417 proto=IP_PROTOS.tcp,
6421 # from client to service (both VRF1)
6422 p = (Ether(src=self.pg6.remote_mac, dst=self.pg6.local_mac) /
6423 IP(src=self.pg6.remote_ip4, dst=external_addr) /
6424 TCP(sport=12345, dport=external_port))
6425 self.pg6.add_stream(p)
6426 self.pg_enable_capture(self.pg_interfaces)
6428 capture = self.pg5.get_capture(1)
6433 self.assertEqual(ip.dst, self.pg5.remote_ip4)
6434 self.assertEqual(tcp.dport, local_port)
6435 self.assert_packet_checksums_valid(p)
6437 self.logger.error(ppp("Unexpected or invalid packet:", p))
6440 # from service back to client (both VRF1)
6441 p = (Ether(src=self.pg5.remote_mac, dst=self.pg5.local_mac) /
6442 IP(src=self.pg5.remote_ip4, dst=self.pg6.remote_ip4) /
6443 TCP(sport=local_port, dport=12345))
6444 self.pg5.add_stream(p)
6445 self.pg_enable_capture(self.pg_interfaces)
6447 capture = self.pg6.get_capture(1)
6452 self.assertEqual(ip.src, external_addr)
6453 self.assertEqual(tcp.sport, external_port)
6454 self.assert_packet_checksums_valid(p)
6456 self.logger.error(ppp("Unexpected or invalid packet:", p))
6459 # dynamic NAT from VRF1 to VRF0 (output-feature)
6460 p = (Ether(src=self.pg5.remote_mac, dst=self.pg5.local_mac) /
6461 IP(src=self.pg5.remote_ip4, dst=self.pg1.remote_ip4) /
6462 TCP(sport=2345, dport=22))
6463 self.pg5.add_stream(p)
6464 self.pg_enable_capture(self.pg_interfaces)
6466 capture = self.pg1.get_capture(1)
6471 self.assertEqual(ip.src, self.nat_addr)
6472 self.assertNotEqual(tcp.sport, 2345)
6473 self.assert_packet_checksums_valid(p)
6476 self.logger.error(ppp("Unexpected or invalid packet:", p))
6479 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
6480 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
6481 TCP(sport=22, dport=port))
6482 self.pg1.add_stream(p)
6483 self.pg_enable_capture(self.pg_interfaces)
6485 capture = self.pg5.get_capture(1)
6490 self.assertEqual(ip.dst, self.pg5.remote_ip4)
6491 self.assertEqual(tcp.dport, 2345)
6492 self.assert_packet_checksums_valid(p)
6494 self.logger.error(ppp("Unexpected or invalid packet:", p))
6497 # from client VRF1 to service VRF0
6498 p = (Ether(src=self.pg6.remote_mac, dst=self.pg6.local_mac) /
6499 IP(src=self.pg6.remote_ip4, dst=self.pg0.local_ip4) /
6500 TCP(sport=12346, dport=external_port))
6501 self.pg6.add_stream(p)
6502 self.pg_enable_capture(self.pg_interfaces)
6504 capture = self.pg0.get_capture(1)
6509 self.assertEqual(ip.dst, self.pg0.remote_ip4)
6510 self.assertEqual(tcp.dport, local_port)
6511 self.assert_packet_checksums_valid(p)
6513 self.logger.error(ppp("Unexpected or invalid packet:", p))
6516 # from service VRF0 back to client VRF1
6517 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6518 IP(src=self.pg0.remote_ip4, dst=self.pg6.remote_ip4) /
6519 TCP(sport=local_port, dport=12346))
6520 self.pg0.add_stream(p)
6521 self.pg_enable_capture(self.pg_interfaces)
6523 capture = self.pg6.get_capture(1)
6528 self.assertEqual(ip.src, self.pg0.local_ip4)
6529 self.assertEqual(tcp.sport, external_port)
6530 self.assert_packet_checksums_valid(p)
6532 self.logger.error(ppp("Unexpected or invalid packet:", p))
6535 # from client VRF0 to service VRF1
6536 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6537 IP(src=self.pg0.remote_ip4, dst=external_addr) /
6538 TCP(sport=12347, dport=external_port))
6539 self.pg0.add_stream(p)
6540 self.pg_enable_capture(self.pg_interfaces)
6542 capture = self.pg5.get_capture(1)
6547 self.assertEqual(ip.dst, self.pg5.remote_ip4)
6548 self.assertEqual(tcp.dport, local_port)
6549 self.assert_packet_checksums_valid(p)
6551 self.logger.error(ppp("Unexpected or invalid packet:", p))
6554 # from service VRF1 back to client VRF0
6555 p = (Ether(src=self.pg5.remote_mac, dst=self.pg5.local_mac) /
6556 IP(src=self.pg5.remote_ip4, dst=self.pg0.remote_ip4) /
6557 TCP(sport=local_port, dport=12347))
6558 self.pg5.add_stream(p)
6559 self.pg_enable_capture(self.pg_interfaces)
6561 capture = self.pg0.get_capture(1)
6566 self.assertEqual(ip.src, external_addr)
6567 self.assertEqual(tcp.sport, external_port)
6568 self.assert_packet_checksums_valid(p)
6570 self.logger.error(ppp("Unexpected or invalid packet:", p))
6573 # from client to server (both VRF1, no translation)
6574 p = (Ether(src=self.pg6.remote_mac, dst=self.pg6.local_mac) /
6575 IP(src=self.pg6.remote_ip4, dst=self.pg5.remote_ip4) /
6576 TCP(sport=12348, dport=local_port))
6577 self.pg6.add_stream(p)
6578 self.pg_enable_capture(self.pg_interfaces)
6580 capture = self.pg5.get_capture(1)
6585 self.assertEqual(ip.dst, self.pg5.remote_ip4)
6586 self.assertEqual(tcp.dport, local_port)
6587 self.assert_packet_checksums_valid(p)
6589 self.logger.error(ppp("Unexpected or invalid packet:", p))
6592 # from server back to client (both VRF1, no translation)
6593 p = (Ether(src=self.pg5.remote_mac, dst=self.pg5.local_mac) /
6594 IP(src=self.pg5.remote_ip4, dst=self.pg6.remote_ip4) /
6595 TCP(sport=local_port, dport=12348))
6596 self.pg5.add_stream(p)
6597 self.pg_enable_capture(self.pg_interfaces)
6599 capture = self.pg6.get_capture(1)
6604 self.assertEqual(ip.src, self.pg5.remote_ip4)
6605 self.assertEqual(tcp.sport, local_port)
6606 self.assert_packet_checksums_valid(p)
6608 self.logger.error(ppp("Unexpected or invalid packet:", p))
6611 # from client VRF1 to server VRF0 (no translation)
6612 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6613 IP(src=self.pg0.remote_ip4, dst=self.pg6.remote_ip4) /
6614 TCP(sport=local_port, dport=12349))
6615 self.pg0.add_stream(p)
6616 self.pg_enable_capture(self.pg_interfaces)
6618 capture = self.pg6.get_capture(1)
6623 self.assertEqual(ip.src, self.pg0.remote_ip4)
6624 self.assertEqual(tcp.sport, local_port)
6625 self.assert_packet_checksums_valid(p)
6627 self.logger.error(ppp("Unexpected or invalid packet:", p))
6630 # from server VRF0 back to client VRF1 (no translation)
6631 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6632 IP(src=self.pg0.remote_ip4, dst=self.pg6.remote_ip4) /
6633 TCP(sport=local_port, dport=12349))
6634 self.pg0.add_stream(p)
6635 self.pg_enable_capture(self.pg_interfaces)
6637 capture = self.pg6.get_capture(1)
6642 self.assertEqual(ip.src, self.pg0.remote_ip4)
6643 self.assertEqual(tcp.sport, local_port)
6644 self.assert_packet_checksums_valid(p)
6646 self.logger.error(ppp("Unexpected or invalid packet:", p))
6649 # from client VRF0 to server VRF1 (no translation)
6650 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6651 IP(src=self.pg0.remote_ip4, dst=self.pg5.remote_ip4) /
6652 TCP(sport=12344, dport=local_port))
6653 self.pg0.add_stream(p)
6654 self.pg_enable_capture(self.pg_interfaces)
6656 capture = self.pg5.get_capture(1)
6661 self.assertEqual(ip.dst, self.pg5.remote_ip4)
6662 self.assertEqual(tcp.dport, local_port)
6663 self.assert_packet_checksums_valid(p)
6665 self.logger.error(ppp("Unexpected or invalid packet:", p))
6668 # from server VRF1 back to client VRF0 (no translation)
6669 p = (Ether(src=self.pg5.remote_mac, dst=self.pg5.local_mac) /
6670 IP(src=self.pg5.remote_ip4, dst=self.pg0.remote_ip4) /
6671 TCP(sport=local_port, dport=12344))
6672 self.pg5.add_stream(p)
6673 self.pg_enable_capture(self.pg_interfaces)
6675 capture = self.pg0.get_capture(1)
6680 self.assertEqual(ip.src, self.pg5.remote_ip4)
6681 self.assertEqual(tcp.sport, local_port)
6682 self.assert_packet_checksums_valid(p)
6684 self.logger.error(ppp("Unexpected or invalid packet:", p))
6687 @unittest.skipUnless(running_extended_tests, "part of extended tests")
6688 def test_session_timeout(self):
6689 """ NAT44 session timeouts """
6690 self.nat44_add_address(self.nat_addr)
6691 flags = self.config_flags.NAT_IS_INSIDE
6692 self.vapi.nat44_interface_add_del_feature(
6693 sw_if_index=self.pg0.sw_if_index,
6694 flags=flags, is_add=1)
6695 self.vapi.nat44_interface_add_del_feature(
6696 sw_if_index=self.pg1.sw_if_index,
6698 self.vapi.nat_set_timeouts(udp=300, tcp_established=7440,
6699 tcp_transitory=240, icmp=5)
6703 for i in range(0, max_sessions):
6704 src = "10.10.%u.%u" % ((i & 0xFF00) >> 8, i & 0xFF)
6705 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
6706 IP(src=src, dst=self.pg1.remote_ip4) /
6707 ICMP(id=1025, type='echo-request'))
6709 self.pg0.add_stream(pkts)
6710 self.pg_enable_capture(self.pg_interfaces)
6712 self.pg1.get_capture(max_sessions)
6717 for i in range(0, max_sessions):
6718 src = "10.11.%u.%u" % ((i & 0xFF00) >> 8, i & 0xFF)
6719 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
6720 IP(src=src, dst=self.pg1.remote_ip4) /
6721 ICMP(id=1026, type='echo-request'))
6723 self.pg0.add_stream(pkts)
6724 self.pg_enable_capture(self.pg_interfaces)
6726 self.pg1.get_capture(max_sessions)
6729 users = self.vapi.nat44_user_dump()
6731 nsessions = nsessions + user.nsessions
6732 self.assertLess(nsessions, 2 * max_sessions)
6734 @unittest.skipUnless(running_extended_tests, "part of extended tests")
6735 def test_session_rst_timeout(self):
6736 """ NAT44 session RST timeouts """
6737 self.nat44_add_address(self.nat_addr)
6738 flags = self.config_flags.NAT_IS_INSIDE
6739 self.vapi.nat44_interface_add_del_feature(
6740 sw_if_index=self.pg0.sw_if_index,
6741 flags=flags, is_add=1)
6742 self.vapi.nat44_interface_add_del_feature(
6743 sw_if_index=self.pg1.sw_if_index,
6745 self.vapi.nat_set_timeouts(udp=300, tcp_established=7440,
6746 tcp_transitory=5, icmp=60)
6748 self.initiate_tcp_session(self.pg0, self.pg1)
6749 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6750 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6751 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
6753 self.pg0.add_stream(p)
6754 self.pg_enable_capture(self.pg_interfaces)
6756 self.pg1.get_capture(1)
6760 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6761 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6762 TCP(sport=self.tcp_port_in + 1, dport=self.tcp_external_port + 1,
6764 self.pg0.add_stream(p)
6765 self.pg_enable_capture(self.pg_interfaces)
6767 self.pg1.get_capture(1)
6770 users = self.vapi.nat44_user_dump()
6771 self.assertEqual(len(users), 1)
6772 self.assertEqual(str(users[0].ip_address),
6773 self.pg0.remote_ip4)
6774 self.assertEqual(users[0].nsessions, 1)
6776 @unittest.skipUnless(running_extended_tests, "part of extended tests")
6777 def test_session_limit_per_user(self):
6778 """ Maximum sessions per user limit """
6779 self.nat44_add_address(self.nat_addr)
6780 flags = self.config_flags.NAT_IS_INSIDE
6781 self.vapi.nat44_interface_add_del_feature(
6782 sw_if_index=self.pg0.sw_if_index,
6783 flags=flags, is_add=1)
6784 self.vapi.nat44_interface_add_del_feature(
6785 sw_if_index=self.pg1.sw_if_index,
6787 self.vapi.set_ipfix_exporter(collector_address=self.pg2.remote_ip4n,
6788 src_address=self.pg2.local_ip4n,
6790 template_interval=10)
6791 self.vapi.nat_set_timeouts(udp=5, tcp_established=7440,
6792 tcp_transitory=240, icmp=60)
6794 # get maximum number of translations per user
6795 nat44_config = self.vapi.nat_show_config()
6798 for port in range(0, nat44_config.max_translations_per_user):
6799 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6800 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6801 UDP(sport=1025 + port, dport=1025 + port))
6804 self.pg0.add_stream(pkts)
6805 self.pg_enable_capture(self.pg_interfaces)
6807 capture = self.pg1.get_capture(len(pkts))
6809 self.vapi.nat_ipfix_enable_disable(domain_id=self.ipfix_domain_id,
6810 src_port=self.ipfix_src_port,
6813 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6814 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6815 UDP(sport=3001, dport=3002))
6816 self.pg0.add_stream(p)
6817 self.pg_enable_capture(self.pg_interfaces)
6819 capture = self.pg1.assert_nothing_captured()
6821 # verify IPFIX logging
6822 self.vapi.cli("ipfix flush") # FIXME this should be an API call
6824 capture = self.pg2.get_capture(10)
6825 ipfix = IPFIXDecoder()
6826 # first load template
6828 self.assertTrue(p.haslayer(IPFIX))
6829 if p.haslayer(Template):
6830 ipfix.add_template(p.getlayer(Template))
6831 # verify events in data set
6833 if p.haslayer(Data):
6834 data = ipfix.decode_data_set(p.getlayer(Set))
6835 self.verify_ipfix_max_entries_per_user(
6837 nat44_config.max_translations_per_user,
6838 self.pg0.remote_ip4n)
6841 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6842 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6843 UDP(sport=3001, dport=3002))
6844 self.pg0.add_stream(p)
6845 self.pg_enable_capture(self.pg_interfaces)
6847 self.pg1.get_capture(1)
6849 def test_syslog_sess(self):
6850 """ Test syslog session creation and deletion """
6851 self.vapi.syslog_set_filter(SYSLOG_SEVERITY.INFO)
6852 self.vapi.syslog_set_sender(self.pg2.local_ip4n, self.pg2.remote_ip4n)
6853 self.nat44_add_address(self.nat_addr)
6854 flags = self.config_flags.NAT_IS_INSIDE
6855 self.vapi.nat44_interface_add_del_feature(
6856 sw_if_index=self.pg0.sw_if_index,
6857 flags=flags, is_add=1)
6858 self.vapi.nat44_interface_add_del_feature(
6859 sw_if_index=self.pg1.sw_if_index,
6862 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
6863 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6864 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port))
6865 self.pg0.add_stream(p)
6866 self.pg_enable_capture(self.pg_interfaces)
6868 capture = self.pg1.get_capture(1)
6869 self.tcp_port_out = capture[0][TCP].sport
6870 capture = self.pg2.get_capture(1)
6871 self.verify_syslog_sess(capture[0][Raw].load)
6873 self.pg_enable_capture(self.pg_interfaces)
6875 self.nat44_add_address(self.nat_addr, is_add=0)
6876 capture = self.pg2.get_capture(1)
6877 self.verify_syslog_sess(capture[0][Raw].load, False)
6880 super(TestNAT44EndpointDependent, self).tearDown()
6881 if not self.vpp_dead:
6883 self.vapi.cli("clear logging")
6885 def show_commands_at_teardown(self):
6886 self.logger.info(self.vapi.cli("show nat44 addresses"))
6887 self.logger.info(self.vapi.cli("show nat44 interfaces"))
6888 self.logger.info(self.vapi.cli("show nat44 static mappings"))
6889 self.logger.info(self.vapi.cli("show nat44 interface address"))
6890 self.logger.info(self.vapi.cli("show nat44 sessions detail"))
6891 self.logger.info(self.vapi.cli("show nat44 hash tables detail"))
6892 self.logger.info(self.vapi.cli("show nat timeouts"))
6895 class TestNAT44Out2InDPO(MethodHolder):
6896 """ NAT44 Test Cases using out2in DPO """
6899 def setUpConstants(cls):
6900 super(TestNAT44Out2InDPO, cls).setUpConstants()
6901 cls.vpp_cmdline.extend(["nat", "{", "out2in dpo", "}"])
6904 def setUpClass(cls):
6905 super(TestNAT44Out2InDPO, cls).setUpClass()
6906 cls.vapi.cli("set log class nat level debug")
6909 cls.tcp_port_in = 6303
6910 cls.tcp_port_out = 6303
6911 cls.udp_port_in = 6304
6912 cls.udp_port_out = 6304
6913 cls.icmp_id_in = 6305
6914 cls.icmp_id_out = 6305
6915 cls.nat_addr = '10.0.0.3'
6916 cls.dst_ip4 = '192.168.70.1'
6918 cls.create_pg_interfaces(range(2))
6921 cls.pg0.config_ip4()
6922 cls.pg0.resolve_arp()
6925 cls.pg1.config_ip6()
6926 cls.pg1.resolve_ndp()
6928 cls.vapi.ip_add_del_route(dst_address=b'\x00' * 16,
6929 dst_address_length=0,
6930 next_hop_address=cls.pg1.remote_ip6n,
6931 next_hop_sw_if_index=cls.pg1.sw_if_index,
6935 super(TestNAT44Out2InDPO, cls).tearDownClass()
6939 def tearDownClass(cls):
6940 super(TestNAT44Out2InDPO, cls).tearDownClass()
6942 def configure_xlat(self):
6943 self.dst_ip6_pfx = '1:2:3::'
6944 self.dst_ip6_pfx_n = socket.inet_pton(socket.AF_INET6,
6946 self.dst_ip6_pfx_len = 96
6947 self.src_ip6_pfx = '4:5:6::'
6948 self.src_ip6_pfx_n = socket.inet_pton(socket.AF_INET6,
6950 self.src_ip6_pfx_len = 96
6951 self.vapi.map_add_domain(self.dst_ip6_pfx_n, self.dst_ip6_pfx_len,
6952 self.src_ip6_pfx_n, self.src_ip6_pfx_len,
6953 '\x00\x00\x00\x00', 0)
6955 @unittest.skip('Temporary disabled')
6956 def test_464xlat_ce(self):
6957 """ Test 464XLAT CE with NAT44 """
6959 nat_config = self.vapi.nat_show_config()
6960 self.assertEqual(1, nat_config.out2in_dpo)
6962 self.configure_xlat()
6964 flags = self.config_flags.NAT_IS_INSIDE
6965 self.vapi.nat44_interface_add_del_feature(
6966 sw_if_index=self.pg0.sw_if_index,
6967 flags=flags, is_add=1)
6968 self.vapi.nat44_add_del_address_range(first_ip_address=self.nat_addr_n,
6969 last_ip_address=self.nat_addr_n,
6970 vrf_id=0xFFFFFFFF, is_add=1)
6972 out_src_ip6 = self.compose_ip6(self.dst_ip4, self.dst_ip6_pfx,
6973 self.dst_ip6_pfx_len)
6974 out_dst_ip6 = self.compose_ip6(self.nat_addr, self.src_ip6_pfx,
6975 self.src_ip6_pfx_len)
6978 pkts = self.create_stream_in(self.pg0, self.pg1, self.dst_ip4)
6979 self.pg0.add_stream(pkts)
6980 self.pg_enable_capture(self.pg_interfaces)
6982 capture = self.pg1.get_capture(len(pkts))
6983 self.verify_capture_out_ip6(capture, nat_ip=out_dst_ip6,
6986 pkts = self.create_stream_out_ip6(self.pg1, out_src_ip6,
6988 self.pg1.add_stream(pkts)
6989 self.pg_enable_capture(self.pg_interfaces)
6991 capture = self.pg0.get_capture(len(pkts))
6992 self.verify_capture_in(capture, self.pg0)
6994 self.vapi.nat44_interface_add_del_feature(
6995 sw_if_index=self.pg0.sw_if_index,
6997 self.vapi.nat44_add_del_address_range(
6998 first_ip_address=self.nat_addr_n,
6999 last_ip_address=self.nat_addr_n,
7002 @unittest.skip('Temporary disabled')
7003 def test_464xlat_ce_no_nat(self):
7004 """ Test 464XLAT CE without NAT44 """
7006 self.configure_xlat()
7008 out_src_ip6 = self.compose_ip6(self.dst_ip4, self.dst_ip6_pfx,
7009 self.dst_ip6_pfx_len)
7010 out_dst_ip6 = self.compose_ip6(self.pg0.remote_ip4, self.src_ip6_pfx,
7011 self.src_ip6_pfx_len)
7013 pkts = self.create_stream_in(self.pg0, self.pg1, self.dst_ip4)
7014 self.pg0.add_stream(pkts)
7015 self.pg_enable_capture(self.pg_interfaces)
7017 capture = self.pg1.get_capture(len(pkts))
7018 self.verify_capture_out_ip6(capture, dst_ip=out_src_ip6,
7019 nat_ip=out_dst_ip6, same_port=True)
7021 pkts = self.create_stream_out_ip6(self.pg1, out_src_ip6, out_dst_ip6)
7022 self.pg1.add_stream(pkts)
7023 self.pg_enable_capture(self.pg_interfaces)
7025 capture = self.pg0.get_capture(len(pkts))
7026 self.verify_capture_in(capture, self.pg0)
7029 class TestDeterministicNAT(MethodHolder):
7030 """ Deterministic NAT Test Cases """
7033 def setUpConstants(cls):
7034 super(TestDeterministicNAT, cls).setUpConstants()
7035 cls.vpp_cmdline.extend(["nat", "{", "deterministic", "}"])
7038 def setUpClass(cls):
7039 super(TestDeterministicNAT, cls).setUpClass()
7040 cls.vapi.cli("set log class nat level debug")
7043 cls.tcp_port_in = 6303
7044 cls.tcp_external_port = 6303
7045 cls.udp_port_in = 6304
7046 cls.udp_external_port = 6304
7047 cls.icmp_id_in = 6305
7048 cls.nat_addr = '10.0.0.3'
7050 cls.create_pg_interfaces(range(3))
7051 cls.interfaces = list(cls.pg_interfaces)
7053 for i in cls.interfaces:
7058 cls.pg0.generate_remote_hosts(2)
7059 cls.pg0.configure_ipv4_neighbors()
7062 super(TestDeterministicNAT, cls).tearDownClass()
7066 def tearDownClass(cls):
7067 super(TestDeterministicNAT, cls).tearDownClass()
7069 def create_stream_in(self, in_if, out_if, ttl=64):
7071 Create packet stream for inside network
7073 :param in_if: Inside interface
7074 :param out_if: Outside interface
7075 :param ttl: TTL of generated packets
7079 p = (Ether(dst=in_if.local_mac, src=in_if.remote_mac) /
7080 IP(src=in_if.remote_ip4, dst=out_if.remote_ip4, ttl=ttl) /
7081 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port))
7085 p = (Ether(dst=in_if.local_mac, src=in_if.remote_mac) /
7086 IP(src=in_if.remote_ip4, dst=out_if.remote_ip4, ttl=ttl) /
7087 UDP(sport=self.udp_port_in, dport=self.udp_external_port))
7091 p = (Ether(dst=in_if.local_mac, src=in_if.remote_mac) /
7092 IP(src=in_if.remote_ip4, dst=out_if.remote_ip4, ttl=ttl) /
7093 ICMP(id=self.icmp_id_in, type='echo-request'))
7098 def create_stream_out(self, out_if, dst_ip=None, ttl=64):
7100 Create packet stream for outside network
7102 :param out_if: Outside interface
7103 :param dst_ip: Destination IP address (Default use global NAT address)
7104 :param ttl: TTL of generated packets
7107 dst_ip = self.nat_addr
7110 p = (Ether(dst=out_if.local_mac, src=out_if.remote_mac) /
7111 IP(src=out_if.remote_ip4, dst=dst_ip, ttl=ttl) /
7112 TCP(dport=self.tcp_port_out, sport=self.tcp_external_port))
7116 p = (Ether(dst=out_if.local_mac, src=out_if.remote_mac) /
7117 IP(src=out_if.remote_ip4, dst=dst_ip, ttl=ttl) /
7118 UDP(dport=self.udp_port_out, sport=self.udp_external_port))
7122 p = (Ether(dst=out_if.local_mac, src=out_if.remote_mac) /
7123 IP(src=out_if.remote_ip4, dst=dst_ip, ttl=ttl) /
7124 ICMP(id=self.icmp_external_id, type='echo-reply'))
7129 def verify_capture_out(self, capture, nat_ip=None):
7131 Verify captured packets on outside network
7133 :param capture: Captured packets
7134 :param nat_ip: Translated IP address (Default use global NAT address)
7135 :param same_port: Source port number is not translated (Default False)
7138 nat_ip = self.nat_addr
7139 for packet in capture:
7141 self.assertEqual(packet[IP].src, nat_ip)
7142 if packet.haslayer(TCP):
7143 self.tcp_port_out = packet[TCP].sport
7144 elif packet.haslayer(UDP):
7145 self.udp_port_out = packet[UDP].sport
7147 self.icmp_external_id = packet[ICMP].id
7149 self.logger.error(ppp("Unexpected or invalid packet "
7150 "(outside network):", packet))
7153 def test_deterministic_mode(self):
7154 """ NAT plugin run deterministic mode """
7155 in_addr = '172.16.255.0'
7156 out_addr = '172.17.255.50'
7157 in_addr_t = '172.16.255.20'
7161 nat_config = self.vapi.nat_show_config()
7162 self.assertEqual(1, nat_config.deterministic)
7164 self.vapi.nat_det_add_del_map(is_add=1, in_addr=in_addr,
7165 in_plen=in_plen, out_addr=out_addr,
7168 rep1 = self.vapi.nat_det_forward(in_addr_t)
7169 self.assertEqual(str(rep1.out_addr), out_addr)
7170 rep2 = self.vapi.nat_det_reverse(rep1.out_port_hi, out_addr)
7172 self.assertEqual(str(rep2.in_addr), in_addr_t)
7174 deterministic_mappings = self.vapi.nat_det_map_dump()
7175 self.assertEqual(len(deterministic_mappings), 1)
7176 dsm = deterministic_mappings[0]
7177 self.assertEqual(in_addr, str(dsm.in_addr))
7178 self.assertEqual(in_plen, dsm.in_plen)
7179 self.assertEqual(out_addr, str(dsm.out_addr))
7180 self.assertEqual(out_plen, dsm.out_plen)
7182 self.clear_nat_det()
7183 deterministic_mappings = self.vapi.nat_det_map_dump()
7184 self.assertEqual(len(deterministic_mappings), 0)
7186 def test_set_timeouts(self):
7187 """ Set deterministic NAT timeouts """
7188 timeouts_before = self.vapi.nat_get_timeouts()
7190 self.vapi.nat_set_timeouts(
7191 udp=timeouts_before.udp + 10,
7192 tcp_established=timeouts_before.tcp_established + 10,
7193 tcp_transitory=timeouts_before.tcp_transitory + 10,
7194 icmp=timeouts_before.icmp + 10)
7196 timeouts_after = self.vapi.nat_get_timeouts()
7198 self.assertNotEqual(timeouts_before.udp, timeouts_after.udp)
7199 self.assertNotEqual(timeouts_before.icmp, timeouts_after.icmp)
7200 self.assertNotEqual(timeouts_before.tcp_established,
7201 timeouts_after.tcp_established)
7202 self.assertNotEqual(timeouts_before.tcp_transitory,
7203 timeouts_after.tcp_transitory)
7205 def test_det_in(self):
7206 """ Deterministic NAT translation test (TCP, UDP, ICMP) """
7208 nat_ip = "10.0.0.10"
7210 self.vapi.nat_det_add_del_map(is_add=1, in_addr=self.pg0.remote_ip4n,
7212 out_addr=socket.inet_aton(nat_ip),
7215 flags = self.config_flags.NAT_IS_INSIDE
7216 self.vapi.nat44_interface_add_del_feature(
7217 sw_if_index=self.pg0.sw_if_index,
7218 flags=flags, is_add=1)
7219 self.vapi.nat44_interface_add_del_feature(
7220 sw_if_index=self.pg1.sw_if_index,
7224 pkts = self.create_stream_in(self.pg0, self.pg1)
7225 self.pg0.add_stream(pkts)
7226 self.pg_enable_capture(self.pg_interfaces)
7228 capture = self.pg1.get_capture(len(pkts))
7229 self.verify_capture_out(capture, nat_ip)
7232 pkts = self.create_stream_out(self.pg1, nat_ip)
7233 self.pg1.add_stream(pkts)
7234 self.pg_enable_capture(self.pg_interfaces)
7236 capture = self.pg0.get_capture(len(pkts))
7237 self.verify_capture_in(capture, self.pg0)
7240 sessions = self.vapi.nat_det_session_dump(self.pg0.remote_ip4n)
7241 self.assertEqual(len(sessions), 3)
7245 self.assertEqual(str(s.ext_addr), self.pg1.remote_ip4)
7246 self.assertEqual(s.in_port, self.tcp_port_in)
7247 self.assertEqual(s.out_port, self.tcp_port_out)
7248 self.assertEqual(s.ext_port, self.tcp_external_port)
7252 self.assertEqual(str(s.ext_addr), self.pg1.remote_ip4)
7253 self.assertEqual(s.in_port, self.udp_port_in)
7254 self.assertEqual(s.out_port, self.udp_port_out)
7255 self.assertEqual(s.ext_port, self.udp_external_port)
7259 self.assertEqual(str(s.ext_addr), self.pg1.remote_ip4)
7260 self.assertEqual(s.in_port, self.icmp_id_in)
7261 self.assertEqual(s.out_port, self.icmp_external_id)
7263 def test_multiple_users(self):
7264 """ Deterministic NAT multiple users """
7266 nat_ip = "10.0.0.10"
7268 external_port = 6303
7270 host0 = self.pg0.remote_hosts[0]
7271 host1 = self.pg0.remote_hosts[1]
7273 self.vapi.nat_det_add_del_map(is_add=1, in_addr=host0.ip4n, in_plen=24,
7274 out_addr=socket.inet_aton(nat_ip),
7276 flags = self.config_flags.NAT_IS_INSIDE
7277 self.vapi.nat44_interface_add_del_feature(
7278 sw_if_index=self.pg0.sw_if_index,
7279 flags=flags, is_add=1)
7280 self.vapi.nat44_interface_add_del_feature(
7281 sw_if_index=self.pg1.sw_if_index,
7285 p = (Ether(src=host0.mac, dst=self.pg0.local_mac) /
7286 IP(src=host0.ip4, dst=self.pg1.remote_ip4) /
7287 TCP(sport=port_in, dport=external_port))
7288 self.pg0.add_stream(p)
7289 self.pg_enable_capture(self.pg_interfaces)
7291 capture = self.pg1.get_capture(1)
7296 self.assertEqual(ip.src, nat_ip)
7297 self.assertEqual(ip.dst, self.pg1.remote_ip4)
7298 self.assertEqual(tcp.dport, external_port)
7299 port_out0 = tcp.sport
7301 self.logger.error(ppp("Unexpected or invalid packet:", p))
7305 p = (Ether(src=host1.mac, dst=self.pg0.local_mac) /
7306 IP(src=host1.ip4, dst=self.pg1.remote_ip4) /
7307 TCP(sport=port_in, dport=external_port))
7308 self.pg0.add_stream(p)
7309 self.pg_enable_capture(self.pg_interfaces)
7311 capture = self.pg1.get_capture(1)
7316 self.assertEqual(ip.src, nat_ip)
7317 self.assertEqual(ip.dst, self.pg1.remote_ip4)
7318 self.assertEqual(tcp.dport, external_port)
7319 port_out1 = tcp.sport
7321 self.logger.error(ppp("Unexpected or invalid packet:", p))
7324 dms = self.vapi.nat_det_map_dump()
7325 self.assertEqual(1, len(dms))
7326 self.assertEqual(2, dms[0].ses_num)
7329 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
7330 IP(src=self.pg1.remote_ip4, dst=nat_ip) /
7331 TCP(sport=external_port, dport=port_out0))
7332 self.pg1.add_stream(p)
7333 self.pg_enable_capture(self.pg_interfaces)
7335 capture = self.pg0.get_capture(1)
7340 self.assertEqual(ip.src, self.pg1.remote_ip4)
7341 self.assertEqual(ip.dst, host0.ip4)
7342 self.assertEqual(tcp.dport, port_in)
7343 self.assertEqual(tcp.sport, external_port)
7345 self.logger.error(ppp("Unexpected or invalid packet:", p))
7349 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
7350 IP(src=self.pg1.remote_ip4, dst=nat_ip) /
7351 TCP(sport=external_port, dport=port_out1))
7352 self.pg1.add_stream(p)
7353 self.pg_enable_capture(self.pg_interfaces)
7355 capture = self.pg0.get_capture(1)
7360 self.assertEqual(ip.src, self.pg1.remote_ip4)
7361 self.assertEqual(ip.dst, host1.ip4)
7362 self.assertEqual(tcp.dport, port_in)
7363 self.assertEqual(tcp.sport, external_port)
7365 self.logger.error(ppp("Unexpected or invalid packet", p))
7368 # session close api test
7369 self.vapi.nat_det_close_session_out(socket.inet_aton(nat_ip),
7371 self.pg1.remote_ip4n,
7373 dms = self.vapi.nat_det_map_dump()
7374 self.assertEqual(dms[0].ses_num, 1)
7376 self.vapi.nat_det_close_session_in(host0.ip4n,
7378 self.pg1.remote_ip4n,
7380 dms = self.vapi.nat_det_map_dump()
7381 self.assertEqual(dms[0].ses_num, 0)
7383 def test_tcp_session_close_detection_in(self):
7384 """ Deterministic NAT TCP session close from inside network """
7385 self.vapi.nat_det_add_del_map(is_add=1, in_addr=self.pg0.remote_ip4n,
7387 out_addr=socket.inet_aton(self.nat_addr),
7389 flags = self.config_flags.NAT_IS_INSIDE
7390 self.vapi.nat44_interface_add_del_feature(
7391 sw_if_index=self.pg0.sw_if_index,
7392 flags=flags, is_add=1)
7393 self.vapi.nat44_interface_add_del_feature(
7394 sw_if_index=self.pg1.sw_if_index,
7397 self.initiate_tcp_session(self.pg0, self.pg1)
7399 # close the session from inside
7401 # FIN packet in -> out
7402 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
7403 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
7404 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
7406 self.pg0.add_stream(p)
7407 self.pg_enable_capture(self.pg_interfaces)
7409 self.pg1.get_capture(1)
7413 # ACK packet out -> in
7414 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
7415 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
7416 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
7420 # FIN packet out -> in
7421 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
7422 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
7423 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
7427 self.pg1.add_stream(pkts)
7428 self.pg_enable_capture(self.pg_interfaces)
7430 self.pg0.get_capture(2)
7432 # ACK packet in -> out
7433 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
7434 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
7435 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
7437 self.pg0.add_stream(p)
7438 self.pg_enable_capture(self.pg_interfaces)
7440 self.pg1.get_capture(1)
7442 # Check if deterministic NAT44 closed the session
7443 dms = self.vapi.nat_det_map_dump()
7444 self.assertEqual(0, dms[0].ses_num)
7446 self.logger.error("TCP session termination failed")
7449 def test_tcp_session_close_detection_out(self):
7450 """ Deterministic NAT TCP session close from outside network """
7451 self.vapi.nat_det_add_del_map(is_add=1, in_addr=self.pg0.remote_ip4n,
7453 out_addr=socket.inet_aton(self.nat_addr),
7455 flags = self.config_flags.NAT_IS_INSIDE
7456 self.vapi.nat44_interface_add_del_feature(
7457 sw_if_index=self.pg0.sw_if_index,
7458 flags=flags, is_add=1)
7459 self.vapi.nat44_interface_add_del_feature(
7460 sw_if_index=self.pg1.sw_if_index,
7463 self.initiate_tcp_session(self.pg0, self.pg1)
7465 # close the session from outside
7467 # FIN packet out -> in
7468 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
7469 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
7470 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
7472 self.pg1.add_stream(p)
7473 self.pg_enable_capture(self.pg_interfaces)
7475 self.pg0.get_capture(1)
7479 # ACK packet in -> out
7480 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
7481 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
7482 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
7486 # ACK packet in -> out
7487 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
7488 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
7489 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
7493 self.pg0.add_stream(pkts)
7494 self.pg_enable_capture(self.pg_interfaces)
7496 self.pg1.get_capture(2)
7498 # ACK packet out -> in
7499 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
7500 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
7501 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
7503 self.pg1.add_stream(p)
7504 self.pg_enable_capture(self.pg_interfaces)
7506 self.pg0.get_capture(1)
7508 # Check if deterministic NAT44 closed the session
7509 dms = self.vapi.nat_det_map_dump()
7510 self.assertEqual(0, dms[0].ses_num)
7512 self.logger.error("TCP session termination failed")
7515 @unittest.skipUnless(running_extended_tests, "part of extended tests")
7516 def test_session_timeout(self):
7517 """ Deterministic NAT session timeouts """
7518 self.vapi.nat_det_add_del_map(is_add=1, in_addr=self.pg0.remote_ip4n,
7520 out_addr=socket.inet_aton(self.nat_addr),
7522 flags = self.config_flags.NAT_IS_INSIDE
7523 self.vapi.nat44_interface_add_del_feature(
7524 sw_if_index=self.pg0.sw_if_index,
7525 flags=flags, is_add=1)
7526 self.vapi.nat44_interface_add_del_feature(
7527 sw_if_index=self.pg1.sw_if_index,
7530 self.initiate_tcp_session(self.pg0, self.pg1)
7531 self.vapi.nat_set_timeouts(udp=5, tcp_established=5, tcp_transitory=5,
7533 pkts = self.create_stream_in(self.pg0, self.pg1)
7534 self.pg0.add_stream(pkts)
7535 self.pg_enable_capture(self.pg_interfaces)
7537 capture = self.pg1.get_capture(len(pkts))
7540 dms = self.vapi.nat_det_map_dump()
7541 self.assertEqual(0, dms[0].ses_num)
7543 @unittest.skipUnless(running_extended_tests, "part of extended tests")
7544 def test_session_limit_per_user(self):
7545 """ Deterministic NAT maximum sessions per user limit """
7546 self.vapi.nat_det_add_del_map(is_add=1, in_addr=self.pg0.remote_ip4n,
7548 out_addr=socket.inet_aton(self.nat_addr),
7550 flags = self.config_flags.NAT_IS_INSIDE
7551 self.vapi.nat44_interface_add_del_feature(
7552 sw_if_index=self.pg0.sw_if_index,
7553 flags=flags, is_add=1)
7554 self.vapi.nat44_interface_add_del_feature(
7555 sw_if_index=self.pg1.sw_if_index,
7557 self.vapi.set_ipfix_exporter(collector_address=self.pg2.remote_ip4n,
7558 src_address=self.pg2.local_ip4n,
7560 template_interval=10)
7561 self.vapi.nat_ipfix_enable_disable(domain_id=1, src_port=4739,
7565 for port in range(1025, 2025):
7566 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
7567 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
7568 UDP(sport=port, dport=port))
7571 self.pg0.add_stream(pkts)
7572 self.pg_enable_capture(self.pg_interfaces)
7574 capture = self.pg1.get_capture(len(pkts))
7576 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
7577 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
7578 UDP(sport=3001, dport=3002))
7579 self.pg0.add_stream(p)
7580 self.pg_enable_capture(self.pg_interfaces)
7582 capture = self.pg1.assert_nothing_captured()
7584 # verify ICMP error packet
7585 capture = self.pg0.get_capture(1)
7587 self.assertTrue(p.haslayer(ICMP))
7589 self.assertEqual(icmp.type, 3)
7590 self.assertEqual(icmp.code, 1)
7591 self.assertTrue(icmp.haslayer(IPerror))
7592 inner_ip = icmp[IPerror]
7593 self.assertEqual(inner_ip[UDPerror].sport, 3001)
7594 self.assertEqual(inner_ip[UDPerror].dport, 3002)
7596 dms = self.vapi.nat_det_map_dump()
7598 self.assertEqual(1000, dms[0].ses_num)
7600 # verify IPFIX logging
7601 self.vapi.cli("ipfix flush") # FIXME this should be an API call
7603 capture = self.pg2.get_capture(2)
7604 ipfix = IPFIXDecoder()
7605 # first load template
7607 self.assertTrue(p.haslayer(IPFIX))
7608 if p.haslayer(Template):
7609 ipfix.add_template(p.getlayer(Template))
7610 # verify events in data set
7612 if p.haslayer(Data):
7613 data = ipfix.decode_data_set(p.getlayer(Set))
7614 self.verify_ipfix_max_entries_per_user(data,
7616 self.pg0.remote_ip4n)
7618 def clear_nat_det(self):
7620 Clear deterministic NAT configuration.
7622 self.vapi.nat_ipfix_enable_disable(domain_id=1, src_port=4739,
7624 self.vapi.nat_set_timeouts(udp=300, tcp_established=7440,
7625 tcp_transitory=240, icmp=60)
7626 deterministic_mappings = self.vapi.nat_det_map_dump()
7627 for dsm in deterministic_mappings:
7628 self.vapi.nat_det_add_del_map(is_add=0, in_addr=dsm.in_addr,
7629 in_plen=dsm.in_plen,
7630 out_addr=dsm.out_addr,
7631 out_plen=dsm.out_plen)
7633 interfaces = self.vapi.nat44_interface_dump()
7634 for intf in interfaces:
7635 self.vapi.nat44_interface_add_del_feature(
7636 sw_if_index=intf.sw_if_index,
7640 super(TestDeterministicNAT, self).tearDown()
7641 if not self.vpp_dead:
7642 self.clear_nat_det()
7644 def show_commands_at_teardown(self):
7645 self.logger.info(self.vapi.cli("show nat44 interfaces"))
7646 self.logger.info(self.vapi.cli("show nat timeouts"))
7648 self.vapi.cli("show nat44 deterministic mappings"))
7650 self.vapi.cli("show nat44 deterministic sessions"))
7653 class TestNAT64(MethodHolder):
7654 """ NAT64 Test Cases """
7657 def setUpConstants(cls):
7658 super(TestNAT64, cls).setUpConstants()
7659 cls.vpp_cmdline.extend(["nat", "{", "nat64 bib hash buckets 128",
7660 "nat64 st hash buckets 256", "}"])
7663 def setUpClass(cls):
7664 super(TestNAT64, cls).setUpClass()
7667 cls.tcp_port_in = 6303
7668 cls.tcp_port_out = 6303
7669 cls.udp_port_in = 6304
7670 cls.udp_port_out = 6304
7671 cls.icmp_id_in = 6305
7672 cls.icmp_id_out = 6305
7673 cls.tcp_external_port = 80
7674 cls.nat_addr = '10.0.0.3'
7675 cls.nat_addr_n = socket.inet_pton(socket.AF_INET, cls.nat_addr)
7677 cls.vrf1_nat_addr = '10.0.10.3'
7678 cls.ipfix_src_port = 4739
7679 cls.ipfix_domain_id = 1
7681 cls.create_pg_interfaces(range(6))
7682 cls.ip6_interfaces = list(cls.pg_interfaces[0:1])
7683 cls.ip6_interfaces.append(cls.pg_interfaces[2])
7684 cls.ip4_interfaces = list(cls.pg_interfaces[1:2])
7686 cls.vapi.ip_table_add_del(is_ipv6=1, is_add=1,
7687 table_id=cls.vrf1_id)
7689 cls.pg_interfaces[2].set_table_ip6(cls.vrf1_id)
7691 cls.pg0.generate_remote_hosts(2)
7693 for i in cls.ip6_interfaces:
7696 i.configure_ipv6_neighbors()
7698 for i in cls.ip4_interfaces:
7704 cls.pg3.config_ip4()
7705 cls.pg3.resolve_arp()
7706 cls.pg3.config_ip6()
7707 cls.pg3.configure_ipv6_neighbors()
7710 cls.pg5.config_ip6()
7713 super(TestNAT64, cls).tearDownClass()
7717 def tearDownClass(cls):
7718 super(TestNAT64, cls).tearDownClass()
7720 def test_nat64_inside_interface_handles_neighbor_advertisement(self):
7721 """ NAT64 inside interface handles Neighbor Advertisement """
7723 flags = self.config_flags.NAT_IS_INSIDE
7724 self.vapi.nat64_add_del_interface(is_add=1, flags=flags,
7725 sw_if_index=self.pg5.sw_if_index)
7728 ping = (Ether(dst=self.pg5.local_mac, src=self.pg5.remote_mac) /
7729 IPv6(src=self.pg5.remote_ip6, dst=self.pg5.local_ip6) /
7730 ICMPv6EchoRequest())
7732 self.pg5.add_stream(pkts)
7733 self.pg_enable_capture(self.pg_interfaces)
7736 # Wait for Neighbor Solicitation
7737 capture = self.pg5.get_capture(len(pkts))
7740 self.assertEqual(packet[IPv6].src, self.pg5.local_ip6)
7741 self.assertEqual(packet.haslayer(ICMPv6ND_NS), 1)
7742 tgt = packet[ICMPv6ND_NS].tgt
7744 self.logger.error(ppp("Unexpected or invalid packet:", packet))
7747 # Send Neighbor Advertisement
7748 p = (Ether(dst=self.pg5.local_mac, src=self.pg5.remote_mac) /
7749 IPv6(src=self.pg5.remote_ip6, dst=self.pg5.local_ip6) /
7750 ICMPv6ND_NA(tgt=tgt) /
7751 ICMPv6NDOptDstLLAddr(lladdr=self.pg5.remote_mac))
7753 self.pg5.add_stream(pkts)
7754 self.pg_enable_capture(self.pg_interfaces)
7757 # Try to send ping again
7759 self.pg5.add_stream(pkts)
7760 self.pg_enable_capture(self.pg_interfaces)
7763 # Wait for ping reply
7764 capture = self.pg5.get_capture(len(pkts))
7767 self.assertEqual(packet[IPv6].src, self.pg5.local_ip6)
7768 self.assertEqual(packet[IPv6].dst, self.pg5.remote_ip6)
7769 self.assertEqual(packet.haslayer(ICMPv6EchoReply), 1)
7771 self.logger.error(ppp("Unexpected or invalid packet:", packet))
7774 def test_pool(self):
7775 """ Add/delete address to NAT64 pool """
7776 nat_addr = '1.2.3.4'
7778 self.vapi.nat64_add_del_pool_addr_range(start_addr=nat_addr,
7780 vrf_id=0xFFFFFFFF, is_add=1)
7782 addresses = self.vapi.nat64_pool_addr_dump()
7783 self.assertEqual(len(addresses), 1)
7784 self.assertEqual(str(addresses[0].address), nat_addr)
7786 self.vapi.nat64_add_del_pool_addr_range(start_addr=nat_addr,
7788 vrf_id=0xFFFFFFFF, is_add=0)
7790 addresses = self.vapi.nat64_pool_addr_dump()
7791 self.assertEqual(len(addresses), 0)
7793 def test_interface(self):
7794 """ Enable/disable NAT64 feature on the interface """
7795 flags = self.config_flags.NAT_IS_INSIDE
7796 self.vapi.nat64_add_del_interface(is_add=1, flags=flags,
7797 sw_if_index=self.pg0.sw_if_index)
7798 self.vapi.nat64_add_del_interface(is_add=1, flags=0,
7799 sw_if_index=self.pg1.sw_if_index)
7801 interfaces = self.vapi.nat64_interface_dump()
7802 self.assertEqual(len(interfaces), 2)
7805 for intf in interfaces:
7806 if intf.sw_if_index == self.pg0.sw_if_index:
7807 self.assertEqual(intf.flags, self.config_flags.NAT_IS_INSIDE)
7809 elif intf.sw_if_index == self.pg1.sw_if_index:
7810 self.assertEqual(intf.flags, self.config_flags.NAT_IS_OUTSIDE)
7812 self.assertTrue(pg0_found)
7813 self.assertTrue(pg1_found)
7815 features = self.vapi.cli("show interface features pg0")
7816 self.assertIn('nat64-in2out', features)
7817 features = self.vapi.cli("show interface features pg1")
7818 self.assertIn('nat64-out2in', features)
7820 self.vapi.nat64_add_del_interface(is_add=0, flags=flags,
7821 sw_if_index=self.pg0.sw_if_index)
7822 self.vapi.nat64_add_del_interface(is_add=0, flags=flags,
7823 sw_if_index=self.pg1.sw_if_index)
7825 interfaces = self.vapi.nat64_interface_dump()
7826 self.assertEqual(len(interfaces), 0)
7828 def test_static_bib(self):
7829 """ Add/delete static BIB entry """
7830 in_addr = '2001:db8:85a3::8a2e:370:7334'
7831 out_addr = '10.1.1.3'
7834 proto = IP_PROTOS.tcp
7836 self.vapi.nat64_add_del_static_bib(i_addr=in_addr, o_addr=out_addr,
7837 i_port=in_port, o_port=out_port,
7838 proto=proto, vrf_id=0, is_add=1)
7839 bib = self.vapi.nat64_bib_dump(proto=IP_PROTOS.tcp)
7842 if bibe.flags & self.config_flags.NAT_IS_STATIC:
7844 self.assertEqual(str(bibe.i_addr), in_addr)
7845 self.assertEqual(str(bibe.o_addr), out_addr)
7846 self.assertEqual(bibe.i_port, in_port)
7847 self.assertEqual(bibe.o_port, out_port)
7848 self.assertEqual(static_bib_num, 1)
7849 bibs = self.statistics.get_counter('/nat64/total-bibs')
7850 self.assertEqual(bibs[0][0], 1)
7852 self.vapi.nat64_add_del_static_bib(i_addr=in_addr, o_addr=out_addr,
7853 i_port=in_port, o_port=out_port,
7854 proto=proto, vrf_id=0, is_add=0)
7855 bib = self.vapi.nat64_bib_dump(proto=IP_PROTOS.tcp)
7858 if bibe.flags & self.config_flags.NAT_IS_STATIC:
7860 self.assertEqual(static_bib_num, 0)
7861 bibs = self.statistics.get_counter('/nat64/total-bibs')
7862 self.assertEqual(bibs[0][0], 0)
7864 def test_set_timeouts(self):
7865 """ Set NAT64 timeouts """
7866 # verify default values
7867 timeouts = self.vapi.nat_get_timeouts()
7868 self.assertEqual(timeouts.udp, 300)
7869 self.assertEqual(timeouts.icmp, 60)
7870 self.assertEqual(timeouts.tcp_transitory, 240)
7871 self.assertEqual(timeouts.tcp_established, 7440)
7873 # set and verify custom values
7874 self.vapi.nat_set_timeouts(udp=200, tcp_established=7450,
7875 tcp_transitory=250, icmp=30)
7876 timeouts = self.vapi.nat_get_timeouts()
7877 self.assertEqual(timeouts.udp, 200)
7878 self.assertEqual(timeouts.icmp, 30)
7879 self.assertEqual(timeouts.tcp_transitory, 250)
7880 self.assertEqual(timeouts.tcp_established, 7450)
7882 def test_dynamic(self):
7883 """ NAT64 dynamic translation test """
7884 self.tcp_port_in = 6303
7885 self.udp_port_in = 6304
7886 self.icmp_id_in = 6305
7888 ses_num_start = self.nat64_get_ses_num()
7890 self.vapi.nat64_add_del_pool_addr_range(start_addr=self.nat_addr,
7891 end_addr=self.nat_addr,
7894 flags = self.config_flags.NAT_IS_INSIDE
7895 self.vapi.nat64_add_del_interface(is_add=1, flags=flags,
7896 sw_if_index=self.pg0.sw_if_index)
7897 self.vapi.nat64_add_del_interface(is_add=1, flags=0,
7898 sw_if_index=self.pg1.sw_if_index)
7901 tcpn = self.statistics.get_counter('/err/nat64-in2out/TCP packets')
7902 udpn = self.statistics.get_counter('/err/nat64-in2out/UDP packets')
7903 icmpn = self.statistics.get_counter('/err/nat64-in2out/ICMP packets')
7904 totaln = self.statistics.get_counter(
7905 '/err/nat64-in2out/good in2out packets processed')
7907 pkts = self.create_stream_in_ip6(self.pg0, self.pg1)
7908 self.pg0.add_stream(pkts)
7909 self.pg_enable_capture(self.pg_interfaces)
7911 capture = self.pg1.get_capture(len(pkts))
7912 self.verify_capture_out(capture, nat_ip=self.nat_addr,
7913 dst_ip=self.pg1.remote_ip4)
7915 err = self.statistics.get_counter('/err/nat64-in2out/TCP packets')
7916 self.assertEqual(err - tcpn, 1)
7917 err = self.statistics.get_counter('/err/nat64-in2out/UDP packets')
7918 self.assertEqual(err - udpn, 1)
7919 err = self.statistics.get_counter('/err/nat64-in2out/ICMP packets')
7920 self.assertEqual(err - icmpn, 1)
7921 err = self.statistics.get_counter(
7922 '/err/nat64-in2out/good in2out packets processed')
7923 self.assertEqual(err - totaln, 3)
7926 tcpn = self.statistics.get_counter('/err/nat64-out2in/TCP packets')
7927 udpn = self.statistics.get_counter('/err/nat64-out2in/UDP packets')
7928 icmpn = self.statistics.get_counter('/err/nat64-out2in/ICMP packets')
7929 totaln = self.statistics.get_counter(
7930 '/err/nat64-out2in/good out2in packets processed')
7932 pkts = self.create_stream_out(self.pg1, dst_ip=self.nat_addr)
7933 self.pg1.add_stream(pkts)
7934 self.pg_enable_capture(self.pg_interfaces)
7936 capture = self.pg0.get_capture(len(pkts))
7937 ip = IPv6(src=''.join(['64:ff9b::', self.pg1.remote_ip4]))
7938 self.verify_capture_in_ip6(capture, ip[IPv6].src, self.pg0.remote_ip6)
7940 err = self.statistics.get_counter('/err/nat64-out2in/TCP packets')
7941 self.assertEqual(err - tcpn, 1)
7942 err = self.statistics.get_counter('/err/nat64-out2in/UDP packets')
7943 self.assertEqual(err - udpn, 1)
7944 err = self.statistics.get_counter('/err/nat64-out2in/ICMP packets')
7945 self.assertEqual(err - icmpn, 1)
7946 err = self.statistics.get_counter(
7947 '/err/nat64-out2in/good out2in packets processed')
7948 self.assertEqual(err - totaln, 3)
7950 bibs = self.statistics.get_counter('/nat64/total-bibs')
7951 self.assertEqual(bibs[0][0], 3)
7952 sessions = self.statistics.get_counter('/nat64/total-sessions')
7953 self.assertEqual(sessions[0][0], 3)
7956 pkts = self.create_stream_in_ip6(self.pg0, self.pg1)
7957 self.pg0.add_stream(pkts)
7958 self.pg_enable_capture(self.pg_interfaces)
7960 capture = self.pg1.get_capture(len(pkts))
7961 self.verify_capture_out(capture, nat_ip=self.nat_addr,
7962 dst_ip=self.pg1.remote_ip4)
7965 pkts = self.create_stream_out(self.pg1, dst_ip=self.nat_addr)
7966 self.pg1.add_stream(pkts)
7967 self.pg_enable_capture(self.pg_interfaces)
7969 capture = self.pg0.get_capture(len(pkts))
7970 self.verify_capture_in_ip6(capture, ip[IPv6].src, self.pg0.remote_ip6)
7972 ses_num_end = self.nat64_get_ses_num()
7974 self.assertEqual(ses_num_end - ses_num_start, 3)
7976 # tenant with specific VRF
7977 self.vapi.nat64_add_del_pool_addr_range(start_addr=self.vrf1_nat_addr,
7978 end_addr=self.vrf1_nat_addr,
7979 vrf_id=self.vrf1_id, is_add=1)
7980 flags = self.config_flags.NAT_IS_INSIDE
7981 self.vapi.nat64_add_del_interface(is_add=1, flags=flags,
7982 sw_if_index=self.pg2.sw_if_index)
7984 pkts = self.create_stream_in_ip6(self.pg2, self.pg1)
7985 self.pg2.add_stream(pkts)
7986 self.pg_enable_capture(self.pg_interfaces)
7988 capture = self.pg1.get_capture(len(pkts))
7989 self.verify_capture_out(capture, nat_ip=self.vrf1_nat_addr,
7990 dst_ip=self.pg1.remote_ip4)
7992 pkts = self.create_stream_out(self.pg1, dst_ip=self.vrf1_nat_addr)
7993 self.pg1.add_stream(pkts)
7994 self.pg_enable_capture(self.pg_interfaces)
7996 capture = self.pg2.get_capture(len(pkts))
7997 self.verify_capture_in_ip6(capture, ip[IPv6].src, self.pg2.remote_ip6)
7999 def test_static(self):
8000 """ NAT64 static translation test """
8001 self.tcp_port_in = 60303
8002 self.udp_port_in = 60304
8003 self.icmp_id_in = 60305
8004 self.tcp_port_out = 60303
8005 self.udp_port_out = 60304
8006 self.icmp_id_out = 60305
8008 ses_num_start = self.nat64_get_ses_num()
8010 self.vapi.nat64_add_del_pool_addr_range(start_addr=self.nat_addr,
8011 end_addr=self.nat_addr,
8014 flags = self.config_flags.NAT_IS_INSIDE
8015 self.vapi.nat64_add_del_interface(is_add=1, flags=flags,
8016 sw_if_index=self.pg0.sw_if_index)
8017 self.vapi.nat64_add_del_interface(is_add=1, flags=0,
8018 sw_if_index=self.pg1.sw_if_index)
8020 self.vapi.nat64_add_del_static_bib(i_addr=self.pg0.remote_ip6n,
8021 o_addr=self.nat_addr,
8022 i_port=self.tcp_port_in,
8023 o_port=self.tcp_port_out,
8024 proto=IP_PROTOS.tcp, vrf_id=0,
8026 self.vapi.nat64_add_del_static_bib(i_addr=self.pg0.remote_ip6n,
8027 o_addr=self.nat_addr,
8028 i_port=self.udp_port_in,
8029 o_port=self.udp_port_out,
8030 proto=IP_PROTOS.udp, vrf_id=0,
8032 self.vapi.nat64_add_del_static_bib(i_addr=self.pg0.remote_ip6n,
8033 o_addr=self.nat_addr,
8034 i_port=self.icmp_id_in,
8035 o_port=self.icmp_id_out,
8036 proto=IP_PROTOS.icmp, vrf_id=0,
8040 pkts = self.create_stream_in_ip6(self.pg0, self.pg1)
8041 self.pg0.add_stream(pkts)
8042 self.pg_enable_capture(self.pg_interfaces)
8044 capture = self.pg1.get_capture(len(pkts))
8045 self.verify_capture_out(capture, nat_ip=self.nat_addr,
8046 dst_ip=self.pg1.remote_ip4, same_port=True)
8049 pkts = self.create_stream_out(self.pg1, dst_ip=self.nat_addr)
8050 self.pg1.add_stream(pkts)
8051 self.pg_enable_capture(self.pg_interfaces)
8053 capture = self.pg0.get_capture(len(pkts))
8054 ip = IPv6(src=''.join(['64:ff9b::', self.pg1.remote_ip4]))
8055 self.verify_capture_in_ip6(capture, ip[IPv6].src, self.pg0.remote_ip6)
8057 ses_num_end = self.nat64_get_ses_num()
8059 self.assertEqual(ses_num_end - ses_num_start, 3)
8061 @unittest.skipUnless(running_extended_tests, "part of extended tests")
8062 def test_session_timeout(self):
8063 """ NAT64 session timeout """
8064 self.icmp_id_in = 1234
8065 self.vapi.nat64_add_del_pool_addr_range(start_addr=self.nat_addr,
8066 end_addr=self.nat_addr,
8069 flags = self.config_flags.NAT_IS_INSIDE
8070 self.vapi.nat64_add_del_interface(is_add=1, flags=flags,
8071 sw_if_index=self.pg0.sw_if_index)
8072 self.vapi.nat64_add_del_interface(is_add=1, flags=0,
8073 sw_if_index=self.pg1.sw_if_index)
8074 self.vapi.nat_set_timeouts(udp=300, tcp_established=5,
8078 pkts = self.create_stream_in_ip6(self.pg0, self.pg1)
8079 self.pg0.add_stream(pkts)
8080 self.pg_enable_capture(self.pg_interfaces)
8082 capture = self.pg1.get_capture(len(pkts))
8084 ses_num_before_timeout = self.nat64_get_ses_num()
8088 # ICMP and TCP session after timeout
8089 ses_num_after_timeout = self.nat64_get_ses_num()
8090 self.assertEqual(ses_num_before_timeout - ses_num_after_timeout, 2)
8092 def test_icmp_error(self):
8093 """ NAT64 ICMP Error message translation """
8094 self.tcp_port_in = 6303
8095 self.udp_port_in = 6304
8096 self.icmp_id_in = 6305
8098 self.vapi.nat64_add_del_pool_addr_range(start_addr=self.nat_addr,
8099 end_addr=self.nat_addr,
8102 flags = self.config_flags.NAT_IS_INSIDE
8103 self.vapi.nat64_add_del_interface(is_add=1, flags=flags,
8104 sw_if_index=self.pg0.sw_if_index)
8105 self.vapi.nat64_add_del_interface(is_add=1, flags=0,
8106 sw_if_index=self.pg1.sw_if_index)
8108 # send some packets to create sessions
8109 pkts = self.create_stream_in_ip6(self.pg0, self.pg1)
8110 self.pg0.add_stream(pkts)
8111 self.pg_enable_capture(self.pg_interfaces)
8113 capture_ip4 = self.pg1.get_capture(len(pkts))
8114 self.verify_capture_out(capture_ip4,
8115 nat_ip=self.nat_addr,
8116 dst_ip=self.pg1.remote_ip4)
8118 pkts = self.create_stream_out(self.pg1, dst_ip=self.nat_addr)
8119 self.pg1.add_stream(pkts)
8120 self.pg_enable_capture(self.pg_interfaces)
8122 capture_ip6 = self.pg0.get_capture(len(pkts))
8123 ip = IPv6(src=''.join(['64:ff9b::', self.pg1.remote_ip4]))
8124 self.verify_capture_in_ip6(capture_ip6, ip[IPv6].src,
8125 self.pg0.remote_ip6)
8128 pkts = [Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
8129 IPv6(src=self.pg0.remote_ip6, dst=ip[IPv6].src) /
8130 ICMPv6DestUnreach(code=1) /
8131 packet[IPv6] for packet in capture_ip6]
8132 self.pg0.add_stream(pkts)
8133 self.pg_enable_capture(self.pg_interfaces)
8135 capture = self.pg1.get_capture(len(pkts))
8136 for packet in capture:
8138 self.assertEqual(packet[IP].src, self.nat_addr)
8139 self.assertEqual(packet[IP].dst, self.pg1.remote_ip4)
8140 self.assertEqual(packet[ICMP].type, 3)
8141 self.assertEqual(packet[ICMP].code, 13)
8142 inner = packet[IPerror]
8143 self.assertEqual(inner.src, self.pg1.remote_ip4)
8144 self.assertEqual(inner.dst, self.nat_addr)
8145 self.assert_packet_checksums_valid(packet)
8146 if inner.haslayer(TCPerror):
8147 self.assertEqual(inner[TCPerror].dport, self.tcp_port_out)
8148 elif inner.haslayer(UDPerror):
8149 self.assertEqual(inner[UDPerror].dport, self.udp_port_out)
8151 self.assertEqual(inner[ICMPerror].id, self.icmp_id_out)
8153 self.logger.error(ppp("Unexpected or invalid packet:", packet))
8157 pkts = [Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
8158 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
8159 ICMP(type=3, code=13) /
8160 packet[IP] for packet in capture_ip4]
8161 self.pg1.add_stream(pkts)
8162 self.pg_enable_capture(self.pg_interfaces)
8164 capture = self.pg0.get_capture(len(pkts))
8165 for packet in capture:
8167 self.assertEqual(packet[IPv6].src, ip.src)
8168 self.assertEqual(packet[IPv6].dst, self.pg0.remote_ip6)
8169 icmp = packet[ICMPv6DestUnreach]
8170 self.assertEqual(icmp.code, 1)
8171 inner = icmp[IPerror6]
8172 self.assertEqual(inner.src, self.pg0.remote_ip6)
8173 self.assertEqual(inner.dst, ip.src)
8174 self.assert_icmpv6_checksum_valid(packet)
8175 if inner.haslayer(TCPerror):
8176 self.assertEqual(inner[TCPerror].sport, self.tcp_port_in)
8177 elif inner.haslayer(UDPerror):
8178 self.assertEqual(inner[UDPerror].sport, self.udp_port_in)
8180 self.assertEqual(inner[ICMPv6EchoRequest].id,
8183 self.logger.error(ppp("Unexpected or invalid packet:", packet))
8186 def test_hairpinning(self):
8187 """ NAT64 hairpinning """
8189 client = self.pg0.remote_hosts[0]
8190 server = self.pg0.remote_hosts[1]
8191 server_tcp_in_port = 22
8192 server_tcp_out_port = 4022
8193 server_udp_in_port = 23
8194 server_udp_out_port = 4023
8195 client_tcp_in_port = 1234
8196 client_udp_in_port = 1235
8197 client_tcp_out_port = 0
8198 client_udp_out_port = 0
8199 ip = IPv6(src=''.join(['64:ff9b::', self.nat_addr]))
8200 nat_addr_ip6 = ip.src
8202 self.vapi.nat64_add_del_pool_addr_range(start_addr=self.nat_addr,
8203 end_addr=self.nat_addr,
8206 flags = self.config_flags.NAT_IS_INSIDE
8207 self.vapi.nat64_add_del_interface(is_add=1, flags=flags,
8208 sw_if_index=self.pg0.sw_if_index)
8209 self.vapi.nat64_add_del_interface(is_add=1, flags=0,
8210 sw_if_index=self.pg1.sw_if_index)
8212 self.vapi.nat64_add_del_static_bib(i_addr=server.ip6n,
8213 o_addr=self.nat_addr,
8214 i_port=server_tcp_in_port,
8215 o_port=server_tcp_out_port,
8216 proto=IP_PROTOS.tcp, vrf_id=0,
8218 self.vapi.nat64_add_del_static_bib(i_addr=server.ip6n,
8219 o_addr=self.nat_addr,
8220 i_port=server_udp_in_port,
8221 o_port=server_udp_out_port,
8222 proto=IP_PROTOS.udp, vrf_id=0,
8227 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
8228 IPv6(src=client.ip6, dst=nat_addr_ip6) /
8229 TCP(sport=client_tcp_in_port, dport=server_tcp_out_port))
8231 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
8232 IPv6(src=client.ip6, dst=nat_addr_ip6) /
8233 UDP(sport=client_udp_in_port, dport=server_udp_out_port))
8235 self.pg0.add_stream(pkts)
8236 self.pg_enable_capture(self.pg_interfaces)
8238 capture = self.pg0.get_capture(len(pkts))
8239 for packet in capture:
8241 self.assertEqual(packet[IPv6].src, nat_addr_ip6)
8242 self.assertEqual(packet[IPv6].dst, server.ip6)
8243 self.assert_packet_checksums_valid(packet)
8244 if packet.haslayer(TCP):
8245 self.assertNotEqual(packet[TCP].sport, client_tcp_in_port)
8246 self.assertEqual(packet[TCP].dport, server_tcp_in_port)
8247 client_tcp_out_port = packet[TCP].sport
8249 self.assertNotEqual(packet[UDP].sport, client_udp_in_port)
8250 self.assertEqual(packet[UDP].dport, server_udp_in_port)
8251 client_udp_out_port = packet[UDP].sport
8253 self.logger.error(ppp("Unexpected or invalid packet:", packet))
8258 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
8259 IPv6(src=server.ip6, dst=nat_addr_ip6) /
8260 TCP(sport=server_tcp_in_port, dport=client_tcp_out_port))
8262 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
8263 IPv6(src=server.ip6, dst=nat_addr_ip6) /
8264 UDP(sport=server_udp_in_port, dport=client_udp_out_port))
8266 self.pg0.add_stream(pkts)
8267 self.pg_enable_capture(self.pg_interfaces)
8269 capture = self.pg0.get_capture(len(pkts))
8270 for packet in capture:
8272 self.assertEqual(packet[IPv6].src, nat_addr_ip6)
8273 self.assertEqual(packet[IPv6].dst, client.ip6)
8274 self.assert_packet_checksums_valid(packet)
8275 if packet.haslayer(TCP):
8276 self.assertEqual(packet[TCP].sport, server_tcp_out_port)
8277 self.assertEqual(packet[TCP].dport, client_tcp_in_port)
8279 self.assertEqual(packet[UDP].sport, server_udp_out_port)
8280 self.assertEqual(packet[UDP].dport, client_udp_in_port)
8282 self.logger.error(ppp("Unexpected or invalid packet:", packet))
8287 pkts = [Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
8288 IPv6(src=client.ip6, dst=nat_addr_ip6) /
8289 ICMPv6DestUnreach(code=1) /
8290 packet[IPv6] for packet in capture]
8291 self.pg0.add_stream(pkts)
8292 self.pg_enable_capture(self.pg_interfaces)
8294 capture = self.pg0.get_capture(len(pkts))
8295 for packet in capture:
8297 self.assertEqual(packet[IPv6].src, nat_addr_ip6)
8298 self.assertEqual(packet[IPv6].dst, server.ip6)
8299 icmp = packet[ICMPv6DestUnreach]
8300 self.assertEqual(icmp.code, 1)
8301 inner = icmp[IPerror6]
8302 self.assertEqual(inner.src, server.ip6)
8303 self.assertEqual(inner.dst, nat_addr_ip6)
8304 self.assert_packet_checksums_valid(packet)
8305 if inner.haslayer(TCPerror):
8306 self.assertEqual(inner[TCPerror].sport, server_tcp_in_port)
8307 self.assertEqual(inner[TCPerror].dport,
8308 client_tcp_out_port)
8310 self.assertEqual(inner[UDPerror].sport, server_udp_in_port)
8311 self.assertEqual(inner[UDPerror].dport,
8312 client_udp_out_port)
8314 self.logger.error(ppp("Unexpected or invalid packet:", packet))
8317 def test_prefix(self):
8318 """ NAT64 Network-Specific Prefix """
8320 self.vapi.nat64_add_del_pool_addr_range(start_addr=self.nat_addr,
8321 end_addr=self.nat_addr,
8324 flags = self.config_flags.NAT_IS_INSIDE
8325 self.vapi.nat64_add_del_interface(is_add=1, flags=flags,
8326 sw_if_index=self.pg0.sw_if_index)
8327 self.vapi.nat64_add_del_interface(is_add=1, flags=0,
8328 sw_if_index=self.pg1.sw_if_index)
8329 self.vapi.nat64_add_del_pool_addr_range(start_addr=self.vrf1_nat_addr,
8330 end_addr=self.vrf1_nat_addr,
8331 vrf_id=self.vrf1_id, is_add=1)
8332 self.vapi.nat64_add_del_interface(is_add=1, flags=flags,
8333 sw_if_index=self.pg2.sw_if_index)
8336 global_pref64 = "2001:db8::"
8337 global_pref64_len = 32
8338 global_pref64_str = "{}/{}".format(global_pref64, global_pref64_len)
8339 self.vapi.nat64_add_del_prefix(prefix=global_pref64_str, vrf_id=0,
8342 prefix = self.vapi.nat64_prefix_dump()
8343 self.assertEqual(len(prefix), 1)
8344 self.assertEqual(prefix[0].prefix,
8345 IPv6Network(unicode(global_pref64_str)))
8346 self.assertEqual(prefix[0].vrf_id, 0)
8348 # Add tenant specific prefix
8349 vrf1_pref64 = "2001:db8:122:300::"
8350 vrf1_pref64_len = 56
8351 vrf1_pref64_str = "{}/{}".format(vrf1_pref64, vrf1_pref64_len)
8352 self.vapi.nat64_add_del_prefix(prefix=vrf1_pref64_str,
8353 vrf_id=self.vrf1_id, is_add=1)
8355 prefix = self.vapi.nat64_prefix_dump()
8356 self.assertEqual(len(prefix), 2)
8359 pkts = self.create_stream_in_ip6(self.pg0,
8362 plen=global_pref64_len)
8363 self.pg0.add_stream(pkts)
8364 self.pg_enable_capture(self.pg_interfaces)
8366 capture = self.pg1.get_capture(len(pkts))
8367 self.verify_capture_out(capture, nat_ip=self.nat_addr,
8368 dst_ip=self.pg1.remote_ip4)
8370 pkts = self.create_stream_out(self.pg1, dst_ip=self.nat_addr)
8371 self.pg1.add_stream(pkts)
8372 self.pg_enable_capture(self.pg_interfaces)
8374 capture = self.pg0.get_capture(len(pkts))
8375 dst_ip = self.compose_ip6(self.pg1.remote_ip4,
8378 self.verify_capture_in_ip6(capture, dst_ip, self.pg0.remote_ip6)
8380 # Tenant specific prefix
8381 pkts = self.create_stream_in_ip6(self.pg2,
8384 plen=vrf1_pref64_len)
8385 self.pg2.add_stream(pkts)
8386 self.pg_enable_capture(self.pg_interfaces)
8388 capture = self.pg1.get_capture(len(pkts))
8389 self.verify_capture_out(capture, nat_ip=self.vrf1_nat_addr,
8390 dst_ip=self.pg1.remote_ip4)
8392 pkts = self.create_stream_out(self.pg1, dst_ip=self.vrf1_nat_addr)
8393 self.pg1.add_stream(pkts)
8394 self.pg_enable_capture(self.pg_interfaces)
8396 capture = self.pg2.get_capture(len(pkts))
8397 dst_ip = self.compose_ip6(self.pg1.remote_ip4,
8400 self.verify_capture_in_ip6(capture, dst_ip, self.pg2.remote_ip6)
8402 def test_unknown_proto(self):
8403 """ NAT64 translate packet with unknown protocol """
8405 self.vapi.nat64_add_del_pool_addr_range(start_addr=self.nat_addr,
8406 end_addr=self.nat_addr,
8409 flags = self.config_flags.NAT_IS_INSIDE
8410 self.vapi.nat64_add_del_interface(is_add=1, flags=flags,
8411 sw_if_index=self.pg0.sw_if_index)
8412 self.vapi.nat64_add_del_interface(is_add=1, flags=0,
8413 sw_if_index=self.pg1.sw_if_index)
8414 remote_ip6 = self.compose_ip6(self.pg1.remote_ip4, '64:ff9b::', 96)
8417 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
8418 IPv6(src=self.pg0.remote_ip6, dst=remote_ip6) /
8419 TCP(sport=self.tcp_port_in, dport=20))
8420 self.pg0.add_stream(p)
8421 self.pg_enable_capture(self.pg_interfaces)
8423 p = self.pg1.get_capture(1)
8425 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
8426 IPv6(src=self.pg0.remote_ip6, dst=remote_ip6, nh=47) /
8428 IP(src=self.pg2.local_ip4, dst=self.pg2.remote_ip4) /
8429 TCP(sport=1234, dport=1234))
8430 self.pg0.add_stream(p)
8431 self.pg_enable_capture(self.pg_interfaces)
8433 p = self.pg1.get_capture(1)
8436 self.assertEqual(packet[IP].src, self.nat_addr)
8437 self.assertEqual(packet[IP].dst, self.pg1.remote_ip4)
8438 self.assertEqual(packet.haslayer(GRE), 1)
8439 self.assert_packet_checksums_valid(packet)
8441 self.logger.error(ppp("Unexpected or invalid packet:", packet))
8445 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
8446 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
8448 IP(src=self.pg2.remote_ip4, dst=self.pg2.local_ip4) /
8449 TCP(sport=1234, dport=1234))
8450 self.pg1.add_stream(p)
8451 self.pg_enable_capture(self.pg_interfaces)
8453 p = self.pg0.get_capture(1)
8456 self.assertEqual(packet[IPv6].src, remote_ip6)
8457 self.assertEqual(packet[IPv6].dst, self.pg0.remote_ip6)
8458 self.assertEqual(packet[IPv6].nh, 47)
8460 self.logger.error(ppp("Unexpected or invalid packet:", packet))
8463 def test_hairpinning_unknown_proto(self):
8464 """ NAT64 translate packet with unknown protocol - hairpinning """
8466 client = self.pg0.remote_hosts[0]
8467 server = self.pg0.remote_hosts[1]
8468 server_tcp_in_port = 22
8469 server_tcp_out_port = 4022
8470 client_tcp_in_port = 1234
8471 client_tcp_out_port = 1235
8472 server_nat_ip = "10.0.0.100"
8473 client_nat_ip = "10.0.0.110"
8474 server_nat_ip6 = self.compose_ip6(server_nat_ip, '64:ff9b::', 96)
8475 client_nat_ip6 = self.compose_ip6(client_nat_ip, '64:ff9b::', 96)
8477 self.vapi.nat64_add_del_pool_addr_range(start_addr=server_nat_ip,
8478 end_addr=client_nat_ip,
8481 flags = self.config_flags.NAT_IS_INSIDE
8482 self.vapi.nat64_add_del_interface(is_add=1, flags=flags,
8483 sw_if_index=self.pg0.sw_if_index)
8484 self.vapi.nat64_add_del_interface(is_add=1, flags=0,
8485 sw_if_index=self.pg1.sw_if_index)
8487 self.vapi.nat64_add_del_static_bib(i_addr=server.ip6n,
8488 o_addr=server_nat_ip,
8489 i_port=server_tcp_in_port,
8490 o_port=server_tcp_out_port,
8491 proto=IP_PROTOS.tcp, vrf_id=0,
8494 self.vapi.nat64_add_del_static_bib(i_addr=server.ip6n,
8495 o_addr=server_nat_ip, i_port=0,
8497 proto=IP_PROTOS.gre, vrf_id=0,
8500 self.vapi.nat64_add_del_static_bib(i_addr=client.ip6n,
8501 o_addr=client_nat_ip,
8502 i_port=client_tcp_in_port,
8503 o_port=client_tcp_out_port,
8504 proto=IP_PROTOS.tcp, vrf_id=0,
8508 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
8509 IPv6(src=client.ip6, dst=server_nat_ip6) /
8510 TCP(sport=client_tcp_in_port, dport=server_tcp_out_port))
8511 self.pg0.add_stream(p)
8512 self.pg_enable_capture(self.pg_interfaces)
8514 p = self.pg0.get_capture(1)
8516 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
8517 IPv6(src=client.ip6, dst=server_nat_ip6, nh=IP_PROTOS.gre) /
8519 IP(src=self.pg2.local_ip4, dst=self.pg2.remote_ip4) /
8520 TCP(sport=1234, dport=1234))
8521 self.pg0.add_stream(p)
8522 self.pg_enable_capture(self.pg_interfaces)
8524 p = self.pg0.get_capture(1)
8527 self.assertEqual(packet[IPv6].src, client_nat_ip6)
8528 self.assertEqual(packet[IPv6].dst, server.ip6)
8529 self.assertEqual(packet[IPv6].nh, IP_PROTOS.gre)
8531 self.logger.error(ppp("Unexpected or invalid packet:", packet))
8535 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
8536 IPv6(src=server.ip6, dst=client_nat_ip6, nh=IP_PROTOS.gre) /
8538 IP(src=self.pg2.remote_ip4, dst=self.pg2.local_ip4) /
8539 TCP(sport=1234, dport=1234))
8540 self.pg0.add_stream(p)
8541 self.pg_enable_capture(self.pg_interfaces)
8543 p = self.pg0.get_capture(1)
8546 self.assertEqual(packet[IPv6].src, server_nat_ip6)
8547 self.assertEqual(packet[IPv6].dst, client.ip6)
8548 self.assertEqual(packet[IPv6].nh, IP_PROTOS.gre)
8550 self.logger.error(ppp("Unexpected or invalid packet:", packet))
8553 def test_one_armed_nat64(self):
8554 """ One armed NAT64 """
8556 remote_host_ip6 = self.compose_ip6(self.pg3.remote_ip4,
8560 self.vapi.nat64_add_del_pool_addr_range(start_addr=self.nat_addr,
8561 end_addr=self.nat_addr,
8564 flags = self.config_flags.NAT_IS_INSIDE
8565 self.vapi.nat64_add_del_interface(is_add=1, flags=flags,
8566 sw_if_index=self.pg3.sw_if_index)
8567 self.vapi.nat64_add_del_interface(is_add=1, flags=0,
8568 sw_if_index=self.pg3.sw_if_index)
8571 p = (Ether(src=self.pg3.remote_mac, dst=self.pg3.local_mac) /
8572 IPv6(src=self.pg3.remote_ip6, dst=remote_host_ip6) /
8573 TCP(sport=12345, dport=80))
8574 self.pg3.add_stream(p)
8575 self.pg_enable_capture(self.pg_interfaces)
8577 capture = self.pg3.get_capture(1)
8582 self.assertEqual(ip.src, self.nat_addr)
8583 self.assertEqual(ip.dst, self.pg3.remote_ip4)
8584 self.assertNotEqual(tcp.sport, 12345)
8585 external_port = tcp.sport
8586 self.assertEqual(tcp.dport, 80)
8587 self.assert_packet_checksums_valid(p)
8589 self.logger.error(ppp("Unexpected or invalid packet:", p))
8593 p = (Ether(src=self.pg3.remote_mac, dst=self.pg3.local_mac) /
8594 IP(src=self.pg3.remote_ip4, dst=self.nat_addr) /
8595 TCP(sport=80, dport=external_port))
8596 self.pg3.add_stream(p)
8597 self.pg_enable_capture(self.pg_interfaces)
8599 capture = self.pg3.get_capture(1)
8604 self.assertEqual(ip.src, remote_host_ip6)
8605 self.assertEqual(ip.dst, self.pg3.remote_ip6)
8606 self.assertEqual(tcp.sport, 80)
8607 self.assertEqual(tcp.dport, 12345)
8608 self.assert_packet_checksums_valid(p)
8610 self.logger.error(ppp("Unexpected or invalid packet:", p))
8613 def test_frag_in_order(self):
8614 """ NAT64 translate fragments arriving in order """
8615 self.tcp_port_in = random.randint(1025, 65535)
8617 self.vapi.nat64_add_del_pool_addr_range(start_addr=self.nat_addr,
8618 end_addr=self.nat_addr,
8621 flags = self.config_flags.NAT_IS_INSIDE
8622 self.vapi.nat64_add_del_interface(is_add=1, flags=flags,
8623 sw_if_index=self.pg0.sw_if_index)
8624 self.vapi.nat64_add_del_interface(is_add=1, flags=0,
8625 sw_if_index=self.pg1.sw_if_index)
8627 reass = self.vapi.nat_reass_dump()
8628 reass_n_start = len(reass)
8632 pkts = self.create_stream_frag_ip6(self.pg0, self.pg1.remote_ip4,
8633 self.tcp_port_in, 20, data)
8634 self.pg0.add_stream(pkts)
8635 self.pg_enable_capture(self.pg_interfaces)
8637 frags = self.pg1.get_capture(len(pkts))
8638 p = self.reass_frags_and_verify(frags,
8640 self.pg1.remote_ip4)
8641 self.assertEqual(p[TCP].dport, 20)
8642 self.assertNotEqual(p[TCP].sport, self.tcp_port_in)
8643 self.tcp_port_out = p[TCP].sport
8644 self.assertEqual(data, p[Raw].load)
8647 data = b"A" * 4 + b"b" * 16 + b"C" * 3
8648 pkts = self.create_stream_frag(self.pg1,
8653 self.pg1.add_stream(pkts)
8654 self.pg_enable_capture(self.pg_interfaces)
8656 frags = self.pg0.get_capture(len(pkts))
8657 src = self.compose_ip6(self.pg1.remote_ip4, '64:ff9b::', 96)
8658 p = self.reass_frags_and_verify_ip6(frags, src, self.pg0.remote_ip6)
8659 self.assertEqual(p[TCP].sport, 20)
8660 self.assertEqual(p[TCP].dport, self.tcp_port_in)
8661 self.assertEqual(data, p[Raw].load)
8663 reass = self.vapi.nat_reass_dump()
8664 reass_n_end = len(reass)
8666 self.assertEqual(reass_n_end - reass_n_start, 2)
8668 def test_reass_hairpinning(self):
8669 """ NAT64 fragments hairpinning """
8671 server = self.pg0.remote_hosts[1]
8672 server_in_port = random.randint(1025, 65535)
8673 server_out_port = random.randint(1025, 65535)
8674 client_in_port = random.randint(1025, 65535)
8675 ip = IPv6(src=''.join(['64:ff9b::', self.nat_addr]))
8676 nat_addr_ip6 = ip.src
8678 self.vapi.nat64_add_del_pool_addr_range(start_addr=self.nat_addr,
8679 end_addr=self.nat_addr,
8682 flags = self.config_flags.NAT_IS_INSIDE
8683 self.vapi.nat64_add_del_interface(is_add=1, flags=flags,
8684 sw_if_index=self.pg0.sw_if_index)
8685 self.vapi.nat64_add_del_interface(is_add=1, flags=0,
8686 sw_if_index=self.pg1.sw_if_index)
8688 # add static BIB entry for server
8689 self.vapi.nat64_add_del_static_bib(i_addr=server.ip6n,
8690 o_addr=self.nat_addr,
8691 i_port=server_in_port,
8692 o_port=server_out_port,
8693 proto=IP_PROTOS.tcp, vrf_id=0,
8696 # send packet from host to server
8697 pkts = self.create_stream_frag_ip6(self.pg0,
8702 self.pg0.add_stream(pkts)
8703 self.pg_enable_capture(self.pg_interfaces)
8705 frags = self.pg0.get_capture(len(pkts))
8706 p = self.reass_frags_and_verify_ip6(frags, nat_addr_ip6, server.ip6)
8707 self.assertNotEqual(p[TCP].sport, client_in_port)
8708 self.assertEqual(p[TCP].dport, server_in_port)
8709 self.assertEqual(data, p[Raw].load)
8711 def test_frag_out_of_order(self):
8712 """ NAT64 translate fragments arriving out of order """
8713 self.tcp_port_in = random.randint(1025, 65535)
8715 self.vapi.nat64_add_del_pool_addr_range(start_addr=self.nat_addr,
8716 end_addr=self.nat_addr,
8719 flags = self.config_flags.NAT_IS_INSIDE
8720 self.vapi.nat64_add_del_interface(is_add=1, flags=flags,
8721 sw_if_index=self.pg0.sw_if_index)
8722 self.vapi.nat64_add_del_interface(is_add=1, flags=0,
8723 sw_if_index=self.pg1.sw_if_index)
8727 pkts = self.create_stream_frag_ip6(self.pg0, self.pg1.remote_ip4,
8728 self.tcp_port_in, 20, data)
8730 self.pg0.add_stream(pkts)
8731 self.pg_enable_capture(self.pg_interfaces)
8733 frags = self.pg1.get_capture(len(pkts))
8734 p = self.reass_frags_and_verify(frags,
8736 self.pg1.remote_ip4)
8737 self.assertEqual(p[TCP].dport, 20)
8738 self.assertNotEqual(p[TCP].sport, self.tcp_port_in)
8739 self.tcp_port_out = p[TCP].sport
8740 self.assertEqual(data, p[Raw].load)
8743 data = b"A" * 4 + b"B" * 16 + b"C" * 3
8744 pkts = self.create_stream_frag(self.pg1,
8750 self.pg1.add_stream(pkts)
8751 self.pg_enable_capture(self.pg_interfaces)
8753 frags = self.pg0.get_capture(len(pkts))
8754 src = self.compose_ip6(self.pg1.remote_ip4, '64:ff9b::', 96)
8755 p = self.reass_frags_and_verify_ip6(frags, src, self.pg0.remote_ip6)
8756 self.assertEqual(p[TCP].sport, 20)
8757 self.assertEqual(p[TCP].dport, self.tcp_port_in)
8758 self.assertEqual(data, p[Raw].load)
8760 def test_interface_addr(self):
8761 """ Acquire NAT64 pool addresses from interface """
8762 self.vapi.nat64_add_del_interface_addr(
8764 sw_if_index=self.pg4.sw_if_index)
8766 # no address in NAT64 pool
8767 addresses = self.vapi.nat44_address_dump()
8768 self.assertEqual(0, len(addresses))
8770 # configure interface address and check NAT64 address pool
8771 self.pg4.config_ip4()
8772 addresses = self.vapi.nat64_pool_addr_dump()
8773 self.assertEqual(len(addresses), 1)
8775 self.assertEqual(str(addresses[0].address),
8778 # remove interface address and check NAT64 address pool
8779 self.pg4.unconfig_ip4()
8780 addresses = self.vapi.nat64_pool_addr_dump()
8781 self.assertEqual(0, len(addresses))
8783 @unittest.skipUnless(running_extended_tests, "part of extended tests")
8784 def test_ipfix_max_bibs_sessions(self):
8785 """ IPFIX logging maximum session and BIB entries exceeded """
8788 remote_host_ip6 = self.compose_ip6(self.pg1.remote_ip4,
8792 self.vapi.nat64_add_del_pool_addr_range(start_addr=self.nat_addr,
8793 end_addr=self.nat_addr,
8796 flags = self.config_flags.NAT_IS_INSIDE
8797 self.vapi.nat64_add_del_interface(is_add=1, flags=flags,
8798 sw_if_index=self.pg0.sw_if_index)
8799 self.vapi.nat64_add_del_interface(is_add=1, flags=0,
8800 sw_if_index=self.pg1.sw_if_index)
8804 for i in range(0, max_bibs):
8805 src = "fd01:aa::%x" % (i)
8806 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
8807 IPv6(src=src, dst=remote_host_ip6) /
8808 TCP(sport=12345, dport=80))
8810 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
8811 IPv6(src=src, dst=remote_host_ip6) /
8812 TCP(sport=12345, dport=22))
8814 self.pg0.add_stream(pkts)
8815 self.pg_enable_capture(self.pg_interfaces)
8817 self.pg1.get_capture(max_sessions)
8819 self.vapi.set_ipfix_exporter(collector_address=self.pg3.remote_ip4n,
8820 src_address=self.pg3.local_ip4n,
8822 template_interval=10)
8823 self.vapi.nat_ipfix_enable_disable(domain_id=self.ipfix_domain_id,
8824 src_port=self.ipfix_src_port,
8827 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
8828 IPv6(src=src, dst=remote_host_ip6) /
8829 TCP(sport=12345, dport=25))
8830 self.pg0.add_stream(p)
8831 self.pg_enable_capture(self.pg_interfaces)
8833 self.pg1.assert_nothing_captured()
8835 self.vapi.cli("ipfix flush") # FIXME this should be an API call
8836 capture = self.pg3.get_capture(9)
8837 ipfix = IPFIXDecoder()
8838 # first load template
8840 self.assertTrue(p.haslayer(IPFIX))
8841 self.assertEqual(p[IP].src, self.pg3.local_ip4)
8842 self.assertEqual(p[IP].dst, self.pg3.remote_ip4)
8843 self.assertEqual(p[UDP].sport, self.ipfix_src_port)
8844 self.assertEqual(p[UDP].dport, 4739)
8845 self.assertEqual(p[IPFIX].observationDomainID,
8846 self.ipfix_domain_id)
8847 if p.haslayer(Template):
8848 ipfix.add_template(p.getlayer(Template))
8849 # verify events in data set
8851 if p.haslayer(Data):
8852 data = ipfix.decode_data_set(p.getlayer(Set))
8853 self.verify_ipfix_max_sessions(data, max_sessions)
8855 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
8856 IPv6(src=self.pg0.remote_ip6, dst=remote_host_ip6) /
8857 TCP(sport=12345, dport=80))
8858 self.pg0.add_stream(p)
8859 self.pg_enable_capture(self.pg_interfaces)
8861 self.pg1.assert_nothing_captured()
8863 self.vapi.cli("ipfix flush") # FIXME this should be an API call
8864 capture = self.pg3.get_capture(1)
8865 # verify events in data set
8867 self.assertTrue(p.haslayer(IPFIX))
8868 self.assertEqual(p[IP].src, self.pg3.local_ip4)
8869 self.assertEqual(p[IP].dst, self.pg3.remote_ip4)
8870 self.assertEqual(p[UDP].sport, self.ipfix_src_port)
8871 self.assertEqual(p[UDP].dport, 4739)
8872 self.assertEqual(p[IPFIX].observationDomainID,
8873 self.ipfix_domain_id)
8874 if p.haslayer(Data):
8875 data = ipfix.decode_data_set(p.getlayer(Set))
8876 self.verify_ipfix_max_bibs(data, max_bibs)
8878 def test_ipfix_max_frags(self):
8879 """ IPFIX logging maximum fragments pending reassembly exceeded """
8880 self.vapi.nat64_add_del_pool_addr_range(start_addr=self.nat_addr,
8881 end_addr=self.nat_addr,
8884 flags = self.config_flags.NAT_IS_INSIDE
8885 self.vapi.nat64_add_del_interface(is_add=1, flags=flags,
8886 sw_if_index=self.pg0.sw_if_index)
8887 self.vapi.nat64_add_del_interface(is_add=1, flags=0,
8888 sw_if_index=self.pg1.sw_if_index)
8889 self.vapi.nat_set_reass(timeout=2, max_reass=1024, max_frag=1,
8890 drop_frag=0, is_ip6=1)
8891 self.vapi.set_ipfix_exporter(collector_address=self.pg3.remote_ip4n,
8892 src_address=self.pg3.local_ip4n,
8894 template_interval=10)
8895 self.vapi.nat_ipfix_enable_disable(domain_id=self.ipfix_domain_id,
8896 src_port=self.ipfix_src_port,
8900 pkts = self.create_stream_frag_ip6(self.pg0, self.pg1.remote_ip4,
8901 self.tcp_port_in, 20, data)
8903 self.pg0.add_stream(pkts)
8904 self.pg_enable_capture(self.pg_interfaces)
8906 self.pg1.assert_nothing_captured()
8908 self.vapi.cli("ipfix flush") # FIXME this should be an API call
8909 capture = self.pg3.get_capture(9)
8910 ipfix = IPFIXDecoder()
8911 # first load template
8913 self.assertTrue(p.haslayer(IPFIX))
8914 self.assertEqual(p[IP].src, self.pg3.local_ip4)
8915 self.assertEqual(p[IP].dst, self.pg3.remote_ip4)
8916 self.assertEqual(p[UDP].sport, self.ipfix_src_port)
8917 self.assertEqual(p[UDP].dport, 4739)
8918 self.assertEqual(p[IPFIX].observationDomainID,
8919 self.ipfix_domain_id)
8920 if p.haslayer(Template):
8921 ipfix.add_template(p.getlayer(Template))
8922 # verify events in data set
8924 if p.haslayer(Data):
8925 data = ipfix.decode_data_set(p.getlayer(Set))
8926 self.verify_ipfix_max_fragments_ip6(data, 1,
8927 self.pg0.remote_ip6n)
8929 def test_ipfix_bib_ses(self):
8930 """ IPFIX logging NAT64 BIB/session create and delete events """
8931 self.tcp_port_in = random.randint(1025, 65535)
8932 remote_host_ip6 = self.compose_ip6(self.pg1.remote_ip4,
8936 self.vapi.nat64_add_del_pool_addr_range(start_addr=self.nat_addr,
8937 end_addr=self.nat_addr,
8940 flags = self.config_flags.NAT_IS_INSIDE
8941 self.vapi.nat64_add_del_interface(is_add=1, flags=flags,
8942 sw_if_index=self.pg0.sw_if_index)
8943 self.vapi.nat64_add_del_interface(is_add=1, flags=0,
8944 sw_if_index=self.pg1.sw_if_index)
8945 self.vapi.set_ipfix_exporter(collector_address=self.pg3.remote_ip4n,
8946 src_address=self.pg3.local_ip4n,
8948 template_interval=10)
8949 self.vapi.nat_ipfix_enable_disable(domain_id=self.ipfix_domain_id,
8950 src_port=self.ipfix_src_port,
8954 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
8955 IPv6(src=self.pg0.remote_ip6, dst=remote_host_ip6) /
8956 TCP(sport=self.tcp_port_in, dport=25))
8957 self.pg0.add_stream(p)
8958 self.pg_enable_capture(self.pg_interfaces)
8960 p = self.pg1.get_capture(1)
8961 self.tcp_port_out = p[0][TCP].sport
8962 self.vapi.cli("ipfix flush") # FIXME this should be an API call
8963 capture = self.pg3.get_capture(10)
8964 ipfix = IPFIXDecoder()
8965 # first load template
8967 self.assertTrue(p.haslayer(IPFIX))
8968 self.assertEqual(p[IP].src, self.pg3.local_ip4)
8969 self.assertEqual(p[IP].dst, self.pg3.remote_ip4)
8970 self.assertEqual(p[UDP].sport, self.ipfix_src_port)
8971 self.assertEqual(p[UDP].dport, 4739)
8972 self.assertEqual(p[IPFIX].observationDomainID,
8973 self.ipfix_domain_id)
8974 if p.haslayer(Template):
8975 ipfix.add_template(p.getlayer(Template))
8976 # verify events in data set
8978 if p.haslayer(Data):
8979 data = ipfix.decode_data_set(p.getlayer(Set))
8980 if scapy.compat.orb(data[0][230]) == 10:
8981 self.verify_ipfix_bib(data, 1, self.pg0.remote_ip6n)
8982 elif scapy.compat.orb(data[0][230]) == 6:
8983 self.verify_ipfix_nat64_ses(data,
8985 self.pg0.remote_ip6n,
8986 self.pg1.remote_ip4,
8989 self.logger.error(ppp("Unexpected or invalid packet: ", p))
8992 self.pg_enable_capture(self.pg_interfaces)
8993 self.vapi.nat64_add_del_pool_addr_range(start_addr=self.nat_addr,
8994 end_addr=self.nat_addr,
8997 self.vapi.cli("ipfix flush") # FIXME this should be an API call
8998 capture = self.pg3.get_capture(2)
8999 # verify events in data set
9001 self.assertTrue(p.haslayer(IPFIX))
9002 self.assertEqual(p[IP].src, self.pg3.local_ip4)
9003 self.assertEqual(p[IP].dst, self.pg3.remote_ip4)
9004 self.assertEqual(p[UDP].sport, self.ipfix_src_port)
9005 self.assertEqual(p[UDP].dport, 4739)
9006 self.assertEqual(p[IPFIX].observationDomainID,
9007 self.ipfix_domain_id)
9008 if p.haslayer(Data):
9009 data = ipfix.decode_data_set(p.getlayer(Set))
9010 if scapy.compat.orb(data[0][230]) == 11:
9011 self.verify_ipfix_bib(data, 0, self.pg0.remote_ip6n)
9012 elif scapy.compat.orb(data[0][230]) == 7:
9013 self.verify_ipfix_nat64_ses(data,
9015 self.pg0.remote_ip6n,
9016 self.pg1.remote_ip4,
9019 self.logger.error(ppp("Unexpected or invalid packet: ", p))
9021 def test_syslog_sess(self):
9022 """ Test syslog session creation and deletion """
9023 self.tcp_port_in = random.randint(1025, 65535)
9024 remote_host_ip6 = self.compose_ip6(self.pg1.remote_ip4,
9028 self.vapi.nat64_add_del_pool_addr_range(start_addr=self.nat_addr,
9029 end_addr=self.nat_addr,
9032 flags = self.config_flags.NAT_IS_INSIDE
9033 self.vapi.nat64_add_del_interface(is_add=1, flags=flags,
9034 sw_if_index=self.pg0.sw_if_index)
9035 self.vapi.nat64_add_del_interface(is_add=1, flags=0,
9036 sw_if_index=self.pg1.sw_if_index)
9037 self.vapi.syslog_set_filter(SYSLOG_SEVERITY.INFO)
9038 self.vapi.syslog_set_sender(self.pg3.local_ip4n, self.pg3.remote_ip4n)
9040 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
9041 IPv6(src=self.pg0.remote_ip6, dst=remote_host_ip6) /
9042 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port))
9043 self.pg0.add_stream(p)
9044 self.pg_enable_capture(self.pg_interfaces)
9046 p = self.pg1.get_capture(1)
9047 self.tcp_port_out = p[0][TCP].sport
9048 capture = self.pg3.get_capture(1)
9049 self.verify_syslog_sess(capture[0][Raw].load, is_ip6=True)
9051 self.pg_enable_capture(self.pg_interfaces)
9053 self.vapi.nat64_add_del_pool_addr_range(start_addr=self.nat_addr,
9054 end_addr=self.nat_addr,
9057 capture = self.pg3.get_capture(1)
9058 self.verify_syslog_sess(capture[0][Raw].load, False, True)
9060 def nat64_get_ses_num(self):
9062 Return number of active NAT64 sessions.
9064 st = self.vapi.nat64_st_dump(proto=255)
9067 def clear_nat64(self):
9069 Clear NAT64 configuration.
9071 self.vapi.nat_ipfix_enable_disable(domain_id=self.ipfix_domain_id,
9072 src_port=self.ipfix_src_port,
9074 self.ipfix_src_port = 4739
9075 self.ipfix_domain_id = 1
9077 self.vapi.syslog_set_filter(SYSLOG_SEVERITY.EMERG)
9079 self.vapi.nat_set_timeouts(udp=300, tcp_established=7440,
9080 tcp_transitory=240, icmp=60)
9082 interfaces = self.vapi.nat64_interface_dump()
9083 for intf in interfaces:
9084 self.vapi.nat64_add_del_interface(is_add=0, flags=intf.flags,
9085 sw_if_index=intf.sw_if_index)
9087 bib = self.vapi.nat64_bib_dump(proto=255)
9089 if bibe.flags & self.config_flags.NAT_IS_STATIC:
9090 self.vapi.nat64_add_del_static_bib(i_addr=bibe.i_addr,
9098 adresses = self.vapi.nat64_pool_addr_dump()
9099 for addr in adresses:
9100 self.vapi.nat64_add_del_pool_addr_range(start_addr=addr.address,
9101 end_addr=addr.address,
9105 prefixes = self.vapi.nat64_prefix_dump()
9106 for prefix in prefixes:
9107 self.vapi.nat64_add_del_prefix(prefix=str(prefix.prefix),
9108 vrf_id=prefix.vrf_id, is_add=0)
9110 bibs = self.statistics.get_counter('/nat64/total-bibs')
9111 self.assertEqual(bibs[0][0], 0)
9112 sessions = self.statistics.get_counter('/nat64/total-sessions')
9113 self.assertEqual(sessions[0][0], 0)
9116 super(TestNAT64, self).tearDown()
9117 if not self.vpp_dead:
9120 def show_commands_at_teardown(self):
9121 self.logger.info(self.vapi.cli("show nat64 pool"))
9122 self.logger.info(self.vapi.cli("show nat64 interfaces"))
9123 self.logger.info(self.vapi.cli("show nat64 prefix"))
9124 self.logger.info(self.vapi.cli("show nat64 bib all"))
9125 self.logger.info(self.vapi.cli("show nat64 session table all"))
9126 self.logger.info(self.vapi.cli("show nat virtual-reassembly"))
9129 class TestDSlite(MethodHolder):
9130 """ DS-Lite Test Cases """
9133 def setUpClass(cls):
9134 super(TestDSlite, cls).setUpClass()
9137 cls.nat_addr = '10.0.0.3'
9139 cls.create_pg_interfaces(range(3))
9141 cls.pg0.config_ip4()
9142 cls.pg0.resolve_arp()
9144 cls.pg1.config_ip6()
9145 cls.pg1.generate_remote_hosts(2)
9146 cls.pg1.configure_ipv6_neighbors()
9148 cls.pg2.config_ip4()
9149 cls.pg2.resolve_arp()
9152 super(TestDSlite, cls).tearDownClass()
9156 def tearDownClass(cls):
9157 super(TestDSlite, cls).tearDownClass()
9159 def verify_syslog_apmadd(self, data, isaddr, isport, xsaddr, xsport,
9161 message = data.decode('utf-8')
9163 message = SyslogMessage.parse(message)
9164 except ParseError as e:
9165 self.logger.error(e)
9167 self.assertEqual(message.severity, SyslogSeverity.info)
9168 self.assertEqual(message.appname, 'NAT')
9169 self.assertEqual(message.msgid, 'APMADD')
9170 sd_params = message.sd.get('napmap')
9171 self.assertTrue(sd_params is not None)
9172 self.assertEqual(sd_params.get('IATYP'), 'IPv4')
9173 self.assertEqual(sd_params.get('ISADDR'), isaddr)
9174 self.assertEqual(sd_params.get('ISPORT'), "%d" % isport)
9175 self.assertEqual(sd_params.get('XATYP'), 'IPv4')
9176 self.assertEqual(sd_params.get('XSADDR'), xsaddr)
9177 self.assertEqual(sd_params.get('XSPORT'), "%d" % xsport)
9178 self.assertEqual(sd_params.get('PROTO'), "%d" % proto)
9179 self.assertTrue(sd_params.get('SSUBIX') is not None)
9180 self.assertEqual(sd_params.get('SV6ENC'), sv6enc)
9182 def test_dslite(self):
9183 """ Test DS-Lite """
9184 nat_config = self.vapi.nat_show_config()
9185 self.assertEqual(0, nat_config.dslite_ce)
9187 self.vapi.dslite_add_del_pool_addr_range(start_addr=self.nat_addr,
9188 end_addr=self.nat_addr,
9190 aftr_ip4 = '192.0.0.1'
9191 aftr_ip6 = '2001:db8:85a3::8a2e:370:1'
9192 self.vapi.dslite_set_aftr_addr(ip4_addr=aftr_ip4, ip6_addr=aftr_ip6)
9193 self.vapi.syslog_set_sender(self.pg2.local_ip4n, self.pg2.remote_ip4n)
9196 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
9197 IPv6(dst=aftr_ip6, src=self.pg1.remote_hosts[0].ip6) /
9198 IP(dst=self.pg0.remote_ip4, src='192.168.1.1') /
9199 UDP(sport=20000, dport=10000))
9200 self.pg1.add_stream(p)
9201 self.pg_enable_capture(self.pg_interfaces)
9203 capture = self.pg0.get_capture(1)
9204 capture = capture[0]
9205 self.assertFalse(capture.haslayer(IPv6))
9206 self.assertEqual(capture[IP].src, self.nat_addr)
9207 self.assertEqual(capture[IP].dst, self.pg0.remote_ip4)
9208 self.assertNotEqual(capture[UDP].sport, 20000)
9209 self.assertEqual(capture[UDP].dport, 10000)
9210 self.assert_packet_checksums_valid(capture)
9211 out_port = capture[UDP].sport
9212 capture = self.pg2.get_capture(1)
9213 self.verify_syslog_apmadd(capture[0][Raw].load, '192.168.1.1',
9214 20000, self.nat_addr, out_port,
9215 self.pg1.remote_hosts[0].ip6, IP_PROTOS.udp)
9217 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
9218 IP(dst=self.nat_addr, src=self.pg0.remote_ip4) /
9219 UDP(sport=10000, dport=out_port))
9220 self.pg0.add_stream(p)
9221 self.pg_enable_capture(self.pg_interfaces)
9223 capture = self.pg1.get_capture(1)
9224 capture = capture[0]
9225 self.assertEqual(capture[IPv6].src, aftr_ip6)
9226 self.assertEqual(capture[IPv6].dst, self.pg1.remote_hosts[0].ip6)
9227 self.assertEqual(capture[IP].src, self.pg0.remote_ip4)
9228 self.assertEqual(capture[IP].dst, '192.168.1.1')
9229 self.assertEqual(capture[UDP].sport, 10000)
9230 self.assertEqual(capture[UDP].dport, 20000)
9231 self.assert_packet_checksums_valid(capture)
9234 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
9235 IPv6(dst=aftr_ip6, src=self.pg1.remote_hosts[1].ip6) /
9236 IP(dst=self.pg0.remote_ip4, src='192.168.1.1') /
9237 TCP(sport=20001, dport=10001))
9238 self.pg1.add_stream(p)
9239 self.pg_enable_capture(self.pg_interfaces)
9241 capture = self.pg0.get_capture(1)
9242 capture = capture[0]
9243 self.assertFalse(capture.haslayer(IPv6))
9244 self.assertEqual(capture[IP].src, self.nat_addr)
9245 self.assertEqual(capture[IP].dst, self.pg0.remote_ip4)
9246 self.assertNotEqual(capture[TCP].sport, 20001)
9247 self.assertEqual(capture[TCP].dport, 10001)
9248 self.assert_packet_checksums_valid(capture)
9249 out_port = capture[TCP].sport
9251 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
9252 IP(dst=self.nat_addr, src=self.pg0.remote_ip4) /
9253 TCP(sport=10001, dport=out_port))
9254 self.pg0.add_stream(p)
9255 self.pg_enable_capture(self.pg_interfaces)
9257 capture = self.pg1.get_capture(1)
9258 capture = capture[0]
9259 self.assertEqual(capture[IPv6].src, aftr_ip6)
9260 self.assertEqual(capture[IPv6].dst, self.pg1.remote_hosts[1].ip6)
9261 self.assertEqual(capture[IP].src, self.pg0.remote_ip4)
9262 self.assertEqual(capture[IP].dst, '192.168.1.1')
9263 self.assertEqual(capture[TCP].sport, 10001)
9264 self.assertEqual(capture[TCP].dport, 20001)
9265 self.assert_packet_checksums_valid(capture)
9268 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
9269 IPv6(dst=aftr_ip6, src=self.pg1.remote_hosts[1].ip6) /
9270 IP(dst=self.pg0.remote_ip4, src='192.168.1.1') /
9271 ICMP(id=4000, type='echo-request'))
9272 self.pg1.add_stream(p)
9273 self.pg_enable_capture(self.pg_interfaces)
9275 capture = self.pg0.get_capture(1)
9276 capture = capture[0]
9277 self.assertFalse(capture.haslayer(IPv6))
9278 self.assertEqual(capture[IP].src, self.nat_addr)
9279 self.assertEqual(capture[IP].dst, self.pg0.remote_ip4)
9280 self.assertNotEqual(capture[ICMP].id, 4000)
9281 self.assert_packet_checksums_valid(capture)
9282 out_id = capture[ICMP].id
9284 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
9285 IP(dst=self.nat_addr, src=self.pg0.remote_ip4) /
9286 ICMP(id=out_id, type='echo-reply'))
9287 self.pg0.add_stream(p)
9288 self.pg_enable_capture(self.pg_interfaces)
9290 capture = self.pg1.get_capture(1)
9291 capture = capture[0]
9292 self.assertEqual(capture[IPv6].src, aftr_ip6)
9293 self.assertEqual(capture[IPv6].dst, self.pg1.remote_hosts[1].ip6)
9294 self.assertEqual(capture[IP].src, self.pg0.remote_ip4)
9295 self.assertEqual(capture[IP].dst, '192.168.1.1')
9296 self.assertEqual(capture[ICMP].id, 4000)
9297 self.assert_packet_checksums_valid(capture)
9299 # ping DS-Lite AFTR tunnel endpoint address
9300 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
9301 IPv6(src=self.pg1.remote_hosts[1].ip6, dst=aftr_ip6) /
9302 ICMPv6EchoRequest())
9303 self.pg1.add_stream(p)
9304 self.pg_enable_capture(self.pg_interfaces)
9306 capture = self.pg1.get_capture(1)
9307 capture = capture[0]
9308 self.assertEqual(capture[IPv6].src, aftr_ip6)
9309 self.assertEqual(capture[IPv6].dst, self.pg1.remote_hosts[1].ip6)
9310 self.assertTrue(capture.haslayer(ICMPv6EchoReply))
9312 b4s = self.statistics.get_counter('/dslite/total-b4s')
9313 self.assertEqual(b4s[0][0], 2)
9314 sessions = self.statistics.get_counter('/dslite/total-sessions')
9315 self.assertEqual(sessions[0][0], 3)
9318 super(TestDSlite, self).tearDown()
9320 def show_commands_at_teardown(self):
9321 self.logger.info(self.vapi.cli("show dslite pool"))
9323 self.vapi.cli("show dslite aftr-tunnel-endpoint-address"))
9324 self.logger.info(self.vapi.cli("show dslite sessions"))
9327 class TestDSliteCE(MethodHolder):
9328 """ DS-Lite CE Test Cases """
9331 def setUpConstants(cls):
9332 super(TestDSliteCE, cls).setUpConstants()
9333 cls.vpp_cmdline.extend(["nat", "{", "dslite ce", "}"])
9336 def setUpClass(cls):
9337 super(TestDSliteCE, cls).setUpClass()
9340 cls.create_pg_interfaces(range(2))
9342 cls.pg0.config_ip4()
9343 cls.pg0.resolve_arp()
9345 cls.pg1.config_ip6()
9346 cls.pg1.generate_remote_hosts(1)
9347 cls.pg1.configure_ipv6_neighbors()
9350 super(TestDSliteCE, cls).tearDownClass()
9354 def tearDownClass(cls):
9355 super(TestDSliteCE, cls).tearDownClass()
9357 def test_dslite_ce(self):
9358 """ Test DS-Lite CE """
9360 nat_config = self.vapi.nat_show_config()
9361 self.assertEqual(1, nat_config.dslite_ce)
9363 b4_ip4 = '192.0.0.2'
9364 b4_ip6 = '2001:db8:62aa::375e:f4c1:1'
9365 self.vapi.dslite_set_b4_addr(ip4_addr=b4_ip4, ip6_addr=b4_ip6)
9367 aftr_ip4 = '192.0.0.1'
9368 aftr_ip6 = '2001:db8:85a3::8a2e:370:1'
9369 aftr_ip6_n = socket.inet_pton(socket.AF_INET6, aftr_ip6)
9370 self.vapi.dslite_set_aftr_addr(ip4_addr=aftr_ip4, ip6_addr=aftr_ip6)
9372 self.vapi.ip_add_del_route(dst_address=aftr_ip6_n,
9373 dst_address_length=128,
9374 next_hop_address=self.pg1.remote_ip6n,
9375 next_hop_sw_if_index=self.pg1.sw_if_index,
9379 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
9380 IP(dst=self.pg1.remote_ip4, src=self.pg0.remote_ip4) /
9381 UDP(sport=10000, dport=20000))
9382 self.pg0.add_stream(p)
9383 self.pg_enable_capture(self.pg_interfaces)
9385 capture = self.pg1.get_capture(1)
9386 capture = capture[0]
9387 self.assertEqual(capture[IPv6].src, b4_ip6)
9388 self.assertEqual(capture[IPv6].dst, aftr_ip6)
9389 self.assertEqual(capture[IP].src, self.pg0.remote_ip4)
9390 self.assertEqual(capture[IP].dst, self.pg1.remote_ip4)
9391 self.assertEqual(capture[UDP].sport, 10000)
9392 self.assertEqual(capture[UDP].dport, 20000)
9393 self.assert_packet_checksums_valid(capture)
9396 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
9397 IPv6(dst=b4_ip6, src=aftr_ip6) /
9398 IP(dst=self.pg0.remote_ip4, src=self.pg1.remote_ip4) /
9399 UDP(sport=20000, dport=10000))
9400 self.pg1.add_stream(p)
9401 self.pg_enable_capture(self.pg_interfaces)
9403 capture = self.pg0.get_capture(1)
9404 capture = capture[0]
9405 self.assertFalse(capture.haslayer(IPv6))
9406 self.assertEqual(capture[IP].src, self.pg1.remote_ip4)
9407 self.assertEqual(capture[IP].dst, self.pg0.remote_ip4)
9408 self.assertEqual(capture[UDP].sport, 20000)
9409 self.assertEqual(capture[UDP].dport, 10000)
9410 self.assert_packet_checksums_valid(capture)
9412 # ping DS-Lite B4 tunnel endpoint address
9413 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
9414 IPv6(src=self.pg1.remote_hosts[0].ip6, dst=b4_ip6) /
9415 ICMPv6EchoRequest())
9416 self.pg1.add_stream(p)
9417 self.pg_enable_capture(self.pg_interfaces)
9419 capture = self.pg1.get_capture(1)
9420 capture = capture[0]
9421 self.assertEqual(capture[IPv6].src, b4_ip6)
9422 self.assertEqual(capture[IPv6].dst, self.pg1.remote_hosts[0].ip6)
9423 self.assertTrue(capture.haslayer(ICMPv6EchoReply))
9426 super(TestDSliteCE, self).tearDown()
9428 def show_commands_at_teardown(self):
9430 self.vapi.cli("show dslite aftr-tunnel-endpoint-address"))
9432 self.vapi.cli("show dslite b4-tunnel-endpoint-address"))
9435 class TestNAT66(MethodHolder):
9436 """ NAT66 Test Cases """
9439 def setUpClass(cls):
9440 super(TestNAT66, cls).setUpClass()
9443 cls.nat_addr = 'fd01:ff::2'
9445 cls.create_pg_interfaces(range(2))
9446 cls.interfaces = list(cls.pg_interfaces)
9448 for i in cls.interfaces:
9451 i.configure_ipv6_neighbors()
9454 super(TestNAT66, cls).tearDownClass()
9458 def tearDownClass(cls):
9459 super(TestNAT66, cls).tearDownClass()
9461 def test_static(self):
9462 """ 1:1 NAT66 test """
9463 flags = self.config_flags.NAT_IS_INSIDE
9464 self.vapi.nat66_add_del_interface(is_add=1, flags=flags,
9465 sw_if_index=self.pg0.sw_if_index)
9466 self.vapi.nat66_add_del_interface(is_add=1,
9467 sw_if_index=self.pg1.sw_if_index)
9468 self.vapi.nat66_add_del_static_mapping(
9469 local_ip_address=self.pg0.remote_ip6n,
9470 external_ip_address=self.nat_addr,
9475 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
9476 IPv6(src=self.pg0.remote_ip6, dst=self.pg1.remote_ip6) /
9479 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
9480 IPv6(src=self.pg0.remote_ip6, dst=self.pg1.remote_ip6) /
9483 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
9484 IPv6(src=self.pg0.remote_ip6, dst=self.pg1.remote_ip6) /
9485 ICMPv6EchoRequest())
9487 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
9488 IPv6(src=self.pg0.remote_ip6, dst=self.pg1.remote_ip6) /
9489 GRE() / IP() / TCP())
9491 self.pg0.add_stream(pkts)
9492 self.pg_enable_capture(self.pg_interfaces)
9494 capture = self.pg1.get_capture(len(pkts))
9495 for packet in capture:
9497 self.assertEqual(packet[IPv6].src, self.nat_addr)
9498 self.assertEqual(packet[IPv6].dst, self.pg1.remote_ip6)
9499 self.assert_packet_checksums_valid(packet)
9501 self.logger.error(ppp("Unexpected or invalid packet:", packet))
9506 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
9507 IPv6(src=self.pg1.remote_ip6, dst=self.nat_addr) /
9510 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
9511 IPv6(src=self.pg1.remote_ip6, dst=self.nat_addr) /
9514 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
9515 IPv6(src=self.pg1.remote_ip6, dst=self.nat_addr) /
9518 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
9519 IPv6(src=self.pg1.remote_ip6, dst=self.nat_addr) /
9520 GRE() / IP() / TCP())
9522 self.pg1.add_stream(pkts)
9523 self.pg_enable_capture(self.pg_interfaces)
9525 capture = self.pg0.get_capture(len(pkts))
9526 for packet in capture:
9528 self.assertEqual(packet[IPv6].src, self.pg1.remote_ip6)
9529 self.assertEqual(packet[IPv6].dst, self.pg0.remote_ip6)
9530 self.assert_packet_checksums_valid(packet)
9532 self.logger.error(ppp("Unexpected or invalid packet:", packet))
9535 sm = self.vapi.nat66_static_mapping_dump()
9536 self.assertEqual(len(sm), 1)
9537 self.assertEqual(sm[0].total_pkts, 8)
9539 def test_check_no_translate(self):
9540 """ NAT66 translate only when egress interface is outside interface """
9541 flags = self.config_flags.NAT_IS_INSIDE
9542 self.vapi.nat66_add_del_interface(is_add=1, flags=flags,
9543 sw_if_index=self.pg0.sw_if_index)
9544 self.vapi.nat66_add_del_interface(is_add=1, flags=flags,
9545 sw_if_index=self.pg1.sw_if_index)
9546 self.vapi.nat66_add_del_static_mapping(
9547 local_ip_address=self.pg0.remote_ip6n,
9548 external_ip_address=self.nat_addr,
9552 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
9553 IPv6(src=self.pg0.remote_ip6, dst=self.pg1.remote_ip6) /
9555 self.pg0.add_stream([p])
9556 self.pg_enable_capture(self.pg_interfaces)
9558 capture = self.pg1.get_capture(1)
9561 self.assertEqual(packet[IPv6].src, self.pg0.remote_ip6)
9562 self.assertEqual(packet[IPv6].dst, self.pg1.remote_ip6)
9564 self.logger.error(ppp("Unexpected or invalid packet:", packet))
9567 def clear_nat66(self):
9569 Clear NAT66 configuration.
9571 interfaces = self.vapi.nat66_interface_dump()
9572 for intf in interfaces:
9573 self.vapi.nat66_add_del_interface(is_add=0, flags=intf.flags,
9574 sw_if_index=intf.sw_if_index)
9576 static_mappings = self.vapi.nat66_static_mapping_dump()
9577 for sm in static_mappings:
9578 self.vapi.nat66_add_del_static_mapping(
9579 local_ip_address=sm.local_ip_address,
9580 external_ip_address=sm.external_ip_address, vrf_id=sm.vrf_id,
9584 super(TestNAT66, self).tearDown()
9587 def show_commands_at_teardown(self):
9588 self.logger.info(self.vapi.cli("show nat66 interfaces"))
9589 self.logger.info(self.vapi.cli("show nat66 static mappings"))
9592 if __name__ == '__main__':
9593 unittest.main(testRunner=VppTestRunner)