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, \
34 # NAT HA protocol event data
37 fields_desc = [ByteEnumField("event_type", None,
38 {1: "add", 2: "del", 3: "refresh"}),
39 ByteEnumField("protocol", None,
40 {0: "udp", 1: "tcp", 2: "icmp"}),
41 ShortField("flags", 0),
42 IPField("in_addr", None),
43 IPField("out_addr", None),
44 ShortField("in_port", None),
45 ShortField("out_port", None),
46 IPField("eh_addr", None),
47 IPField("ehn_addr", None),
48 ShortField("eh_port", None),
49 ShortField("ehn_port", None),
50 IntField("fib_index", None),
51 IntField("total_pkts", 0),
52 LongField("total_bytes", 0)]
54 def extract_padding(self, s):
58 # NAT HA protocol header
59 class HANATStateSync(Packet):
60 name = "HA NAT state sync"
61 fields_desc = [XByteField("version", 1),
62 FlagsField("flags", 0, 8, ['ACK']),
63 FieldLenField("count", None, count_of="events"),
64 IntField("sequence_number", 1),
65 IntField("thread_index", 0),
66 PacketListField("events", [], Event,
67 count_from=lambda pkt: pkt.count)]
70 class MethodHolder(VppTestCase):
71 """ NAT create capture and verify method holder """
73 def clear_nat44(self):
75 Clear NAT44 configuration.
77 if hasattr(self, 'pg7') and hasattr(self, 'pg8'):
78 # I found no elegant way to do this
79 self.vapi.ip_add_del_route(
80 dst_address=self.pg7.remote_ip4n,
81 dst_address_length=32,
82 next_hop_address=self.pg7.remote_ip4n,
83 next_hop_sw_if_index=self.pg7.sw_if_index,
85 self.vapi.ip_add_del_route(
86 dst_address=self.pg8.remote_ip4n,
87 dst_address_length=32,
88 next_hop_address=self.pg8.remote_ip4n,
89 next_hop_sw_if_index=self.pg8.sw_if_index,
92 for intf in [self.pg7, self.pg8]:
93 self.vapi.ip_neighbor_add_del(
97 flags=(VppEnum.vl_api_ip_neighbor_flags_t.
98 IP_API_NEIGHBOR_FLAG_STATIC),
101 if self.pg7.has_ip4_config:
102 self.pg7.unconfig_ip4()
104 self.vapi.nat44_forwarding_enable_disable(0)
106 interfaces = self.vapi.nat44_interface_addr_dump()
107 for intf in interfaces:
108 self.vapi.nat44_add_del_interface_addr(intf.sw_if_index,
109 twice_nat=intf.twice_nat,
112 self.vapi.nat_ipfix_enable_disable(enable=0,
113 src_port=self.ipfix_src_port,
114 domain_id=self.ipfix_domain_id)
115 self.ipfix_src_port = 4739
116 self.ipfix_domain_id = 1
118 self.vapi.syslog_set_filter(SYSLOG_SEVERITY.EMERG)
120 self.vapi.nat_ha_set_listener('0.0.0.0', 0)
121 self.vapi.nat_ha_set_failover('0.0.0.0', 0)
123 interfaces = self.vapi.nat44_interface_dump()
124 for intf in interfaces:
125 if intf.is_inside > 1:
126 self.vapi.nat44_interface_add_del_feature(intf.sw_if_index,
129 self.vapi.nat44_interface_add_del_feature(intf.sw_if_index,
133 interfaces = self.vapi.nat44_interface_output_feature_dump()
134 for intf in interfaces:
135 self.vapi.nat44_interface_add_del_output_feature(intf.sw_if_index,
139 static_mappings = self.vapi.nat44_static_mapping_dump()
140 for sm in static_mappings:
141 self.vapi.nat44_add_del_static_mapping(
143 sm.external_ip_address,
144 local_port=sm.local_port,
145 external_port=sm.external_port,
146 addr_only=sm.addr_only,
148 protocol=sm.protocol,
149 twice_nat=sm.twice_nat,
150 self_twice_nat=sm.self_twice_nat,
151 out2in_only=sm.out2in_only,
153 external_sw_if_index=sm.external_sw_if_index,
156 lb_static_mappings = self.vapi.nat44_lb_static_mapping_dump()
157 for lb_sm in lb_static_mappings:
158 self.vapi.nat44_add_del_lb_static_mapping(
162 twice_nat=lb_sm.twice_nat,
163 self_twice_nat=lb_sm.self_twice_nat,
164 out2in_only=lb_sm.out2in_only,
170 identity_mappings = self.vapi.nat44_identity_mapping_dump()
171 for id_m in identity_mappings:
172 self.vapi.nat44_add_del_identity_mapping(
173 addr_only=id_m.addr_only,
176 sw_if_index=id_m.sw_if_index,
178 protocol=id_m.protocol,
181 addresses = self.vapi.nat44_address_dump()
182 for addr in addresses:
183 self.vapi.nat44_add_del_address_range(addr.ip_address,
185 twice_nat=addr.twice_nat,
188 self.vapi.nat_set_reass()
189 self.vapi.nat_set_reass(is_ip6=1)
190 self.verify_no_nat44_user()
191 self.vapi.nat_set_timeouts()
192 self.vapi.nat_set_addr_and_port_alloc_alg()
193 self.vapi.nat_set_mss_clamping()
195 def nat44_add_static_mapping(self, local_ip, external_ip='0.0.0.0',
196 local_port=0, external_port=0, vrf_id=0,
197 is_add=1, external_sw_if_index=0xFFFFFFFF,
198 proto=0, twice_nat=0, self_twice_nat=0,
199 out2in_only=0, tag=""):
201 Add/delete NAT44 static mapping
203 :param local_ip: Local IP address
204 :param external_ip: External IP address
205 :param local_port: Local port number (Optional)
206 :param external_port: External port number (Optional)
207 :param vrf_id: VRF ID (Default 0)
208 :param is_add: 1 if add, 0 if delete (Default add)
209 :param external_sw_if_index: External interface instead of IP address
210 :param proto: IP protocol (Mandatory if port specified)
211 :param twice_nat: 1 if translate external host address and port
212 :param self_twice_nat: 1 if translate external host address and port
213 whenever external host address equals
214 local address of internal host
215 :param out2in_only: if 1 rule is matching only out2in direction
216 :param tag: Opaque string tag
219 if local_port and external_port:
221 l_ip = socket.inet_pton(socket.AF_INET, local_ip)
222 e_ip = socket.inet_pton(socket.AF_INET, external_ip)
223 self.vapi.nat44_add_del_static_mapping(
226 external_sw_if_index,
238 def nat44_add_address(self, ip, is_add=1, vrf_id=0xFFFFFFFF, twice_nat=0):
240 Add/delete NAT44 address
242 :param ip: IP address
243 :param is_add: 1 if add, 0 if delete (Default add)
244 :param twice_nat: twice NAT address for external hosts
246 nat_addr = socket.inet_pton(socket.AF_INET, ip)
247 self.vapi.nat44_add_del_address_range(nat_addr, nat_addr, is_add,
251 def create_stream_in(self, in_if, out_if, dst_ip=None, ttl=64):
253 Create packet stream for inside network
255 :param in_if: Inside interface
256 :param out_if: Outside interface
257 :param dst_ip: Destination address
258 :param ttl: TTL of generated packets
261 dst_ip = out_if.remote_ip4
265 p = (Ether(dst=in_if.local_mac, src=in_if.remote_mac) /
266 IP(src=in_if.remote_ip4, dst=dst_ip, ttl=ttl) /
267 TCP(sport=self.tcp_port_in, dport=20))
271 p = (Ether(dst=in_if.local_mac, src=in_if.remote_mac) /
272 IP(src=in_if.remote_ip4, dst=dst_ip, ttl=ttl) /
273 UDP(sport=self.udp_port_in, dport=20))
277 p = (Ether(dst=in_if.local_mac, src=in_if.remote_mac) /
278 IP(src=in_if.remote_ip4, dst=dst_ip, ttl=ttl) /
279 ICMP(id=self.icmp_id_in, type='echo-request'))
284 def compose_ip6(self, ip4, pref, plen):
286 Compose IPv4-embedded IPv6 addresses
288 :param ip4: IPv4 address
289 :param pref: IPv6 prefix
290 :param plen: IPv6 prefix length
291 :returns: IPv4-embedded IPv6 addresses
293 pref_n = list(socket.inet_pton(socket.AF_INET6, pref))
294 ip4_n = list(socket.inet_pton(socket.AF_INET, ip4))
309 pref_n[10] = ip4_n[3]
313 pref_n[10] = ip4_n[2]
314 pref_n[11] = ip4_n[3]
317 pref_n[10] = ip4_n[1]
318 pref_n[11] = ip4_n[2]
319 pref_n[12] = ip4_n[3]
321 pref_n[12] = ip4_n[0]
322 pref_n[13] = ip4_n[1]
323 pref_n[14] = ip4_n[2]
324 pref_n[15] = ip4_n[3]
325 packed_pref_n = b''.join([scapy.compat.chb(x) for x in pref_n])
326 return socket.inet_ntop(socket.AF_INET6, packed_pref_n)
328 def extract_ip4(self, ip6, plen):
330 Extract IPv4 address embedded in IPv6 addresses
332 :param ip6: IPv6 address
333 :param plen: IPv6 prefix length
334 :returns: extracted IPv4 address
336 ip6_n = list(socket.inet_pton(socket.AF_INET6, ip6))
368 return socket.inet_ntop(socket.AF_INET, ''.join(ip4_n))
370 def create_stream_in_ip6(self, in_if, out_if, hlim=64, pref=None, plen=0):
372 Create IPv6 packet stream for inside network
374 :param in_if: Inside interface
375 :param out_if: Outside interface
376 :param ttl: Hop Limit of generated packets
377 :param pref: NAT64 prefix
378 :param plen: NAT64 prefix length
382 dst = ''.join(['64:ff9b::', out_if.remote_ip4])
384 dst = self.compose_ip6(out_if.remote_ip4, pref, plen)
387 p = (Ether(dst=in_if.local_mac, src=in_if.remote_mac) /
388 IPv6(src=in_if.remote_ip6, dst=dst, hlim=hlim) /
389 TCP(sport=self.tcp_port_in, dport=20))
393 p = (Ether(dst=in_if.local_mac, src=in_if.remote_mac) /
394 IPv6(src=in_if.remote_ip6, dst=dst, hlim=hlim) /
395 UDP(sport=self.udp_port_in, dport=20))
399 p = (Ether(dst=in_if.local_mac, src=in_if.remote_mac) /
400 IPv6(src=in_if.remote_ip6, dst=dst, hlim=hlim) /
401 ICMPv6EchoRequest(id=self.icmp_id_in))
406 def create_stream_out(self, out_if, dst_ip=None, ttl=64,
407 use_inside_ports=False):
409 Create packet stream for outside network
411 :param out_if: Outside interface
412 :param dst_ip: Destination IP address (Default use global NAT address)
413 :param ttl: TTL of generated packets
414 :param use_inside_ports: Use inside NAT ports as destination ports
415 instead of outside ports
418 dst_ip = self.nat_addr
419 if not use_inside_ports:
420 tcp_port = self.tcp_port_out
421 udp_port = self.udp_port_out
422 icmp_id = self.icmp_id_out
424 tcp_port = self.tcp_port_in
425 udp_port = self.udp_port_in
426 icmp_id = self.icmp_id_in
429 p = (Ether(dst=out_if.local_mac, src=out_if.remote_mac) /
430 IP(src=out_if.remote_ip4, dst=dst_ip, ttl=ttl) /
431 TCP(dport=tcp_port, sport=20))
435 p = (Ether(dst=out_if.local_mac, src=out_if.remote_mac) /
436 IP(src=out_if.remote_ip4, dst=dst_ip, ttl=ttl) /
437 UDP(dport=udp_port, sport=20))
441 p = (Ether(dst=out_if.local_mac, src=out_if.remote_mac) /
442 IP(src=out_if.remote_ip4, dst=dst_ip, ttl=ttl) /
443 ICMP(id=icmp_id, type='echo-reply'))
448 def create_stream_out_ip6(self, out_if, src_ip, dst_ip, hl=64):
450 Create packet stream for outside network
452 :param out_if: Outside interface
453 :param dst_ip: Destination IP address (Default use global NAT address)
454 :param hl: HL of generated packets
458 p = (Ether(dst=out_if.local_mac, src=out_if.remote_mac) /
459 IPv6(src=src_ip, dst=dst_ip, hlim=hl) /
460 TCP(dport=self.tcp_port_out, sport=20))
464 p = (Ether(dst=out_if.local_mac, src=out_if.remote_mac) /
465 IPv6(src=src_ip, dst=dst_ip, hlim=hl) /
466 UDP(dport=self.udp_port_out, sport=20))
470 p = (Ether(dst=out_if.local_mac, src=out_if.remote_mac) /
471 IPv6(src=src_ip, dst=dst_ip, hlim=hl) /
472 ICMPv6EchoReply(id=self.icmp_id_out))
477 def verify_capture_out(self, capture, nat_ip=None, same_port=False,
478 dst_ip=None, is_ip6=False):
480 Verify captured packets on outside network
482 :param capture: Captured packets
483 :param nat_ip: Translated IP address (Default use global NAT address)
484 :param same_port: Source port number is not translated (Default False)
485 :param dst_ip: Destination IP address (Default do not verify)
486 :param is_ip6: If L3 protocol is IPv6 (Default False)
490 ICMP46 = ICMPv6EchoRequest
495 nat_ip = self.nat_addr
496 for packet in capture:
499 self.assert_packet_checksums_valid(packet)
500 self.assertEqual(packet[IP46].src, nat_ip)
501 if dst_ip is not None:
502 self.assertEqual(packet[IP46].dst, dst_ip)
503 if packet.haslayer(TCP):
505 self.assertEqual(packet[TCP].sport, self.tcp_port_in)
508 packet[TCP].sport, self.tcp_port_in)
509 self.tcp_port_out = packet[TCP].sport
510 self.assert_packet_checksums_valid(packet)
511 elif packet.haslayer(UDP):
513 self.assertEqual(packet[UDP].sport, self.udp_port_in)
516 packet[UDP].sport, self.udp_port_in)
517 self.udp_port_out = packet[UDP].sport
520 self.assertEqual(packet[ICMP46].id, self.icmp_id_in)
522 self.assertNotEqual(packet[ICMP46].id, self.icmp_id_in)
523 self.icmp_id_out = packet[ICMP46].id
524 self.assert_packet_checksums_valid(packet)
526 self.logger.error(ppp("Unexpected or invalid packet "
527 "(outside network):", packet))
530 def verify_capture_out_ip6(self, capture, nat_ip, same_port=False,
533 Verify captured packets on outside network
535 :param capture: Captured packets
536 :param nat_ip: Translated IP address
537 :param same_port: Source port number is not translated (Default False)
538 :param dst_ip: Destination IP address (Default do not verify)
540 return self.verify_capture_out(capture, nat_ip, same_port, dst_ip,
543 def verify_capture_in(self, capture, in_if):
545 Verify captured packets on inside network
547 :param capture: Captured packets
548 :param in_if: Inside interface
550 for packet in capture:
552 self.assert_packet_checksums_valid(packet)
553 self.assertEqual(packet[IP].dst, in_if.remote_ip4)
554 if packet.haslayer(TCP):
555 self.assertEqual(packet[TCP].dport, self.tcp_port_in)
556 elif packet.haslayer(UDP):
557 self.assertEqual(packet[UDP].dport, self.udp_port_in)
559 self.assertEqual(packet[ICMP].id, self.icmp_id_in)
561 self.logger.error(ppp("Unexpected or invalid packet "
562 "(inside network):", packet))
565 def verify_capture_in_ip6(self, capture, src_ip, dst_ip):
567 Verify captured IPv6 packets on inside network
569 :param capture: Captured packets
570 :param src_ip: Source IP
571 :param dst_ip: Destination IP address
573 for packet in capture:
575 self.assertEqual(packet[IPv6].src, src_ip)
576 self.assertEqual(packet[IPv6].dst, dst_ip)
577 self.assert_packet_checksums_valid(packet)
578 if packet.haslayer(TCP):
579 self.assertEqual(packet[TCP].dport, self.tcp_port_in)
580 elif packet.haslayer(UDP):
581 self.assertEqual(packet[UDP].dport, self.udp_port_in)
583 self.assertEqual(packet[ICMPv6EchoReply].id,
586 self.logger.error(ppp("Unexpected or invalid packet "
587 "(inside network):", packet))
590 def verify_capture_no_translation(self, capture, ingress_if, egress_if):
592 Verify captured packet that don't have to be translated
594 :param capture: Captured packets
595 :param ingress_if: Ingress interface
596 :param egress_if: Egress interface
598 for packet in capture:
600 self.assertEqual(packet[IP].src, ingress_if.remote_ip4)
601 self.assertEqual(packet[IP].dst, egress_if.remote_ip4)
602 if packet.haslayer(TCP):
603 self.assertEqual(packet[TCP].sport, self.tcp_port_in)
604 elif packet.haslayer(UDP):
605 self.assertEqual(packet[UDP].sport, self.udp_port_in)
607 self.assertEqual(packet[ICMP].id, self.icmp_id_in)
609 self.logger.error(ppp("Unexpected or invalid packet "
610 "(inside network):", packet))
613 def verify_capture_out_with_icmp_errors(self, capture, src_ip=None,
616 Verify captured packets with ICMP errors on outside network
618 :param capture: Captured packets
619 :param src_ip: Translated IP address or IP address of VPP
620 (Default use global NAT address)
621 :param icmp_type: Type of error ICMP packet
622 we are expecting (Default 11)
625 src_ip = self.nat_addr
626 for packet in capture:
628 self.assertEqual(packet[IP].src, src_ip)
629 self.assertEqual(packet.haslayer(ICMP), 1)
631 self.assertEqual(icmp.type, icmp_type)
632 self.assertTrue(icmp.haslayer(IPerror))
633 inner_ip = icmp[IPerror]
634 if inner_ip.haslayer(TCPerror):
635 self.assertEqual(inner_ip[TCPerror].dport,
637 elif inner_ip.haslayer(UDPerror):
638 self.assertEqual(inner_ip[UDPerror].dport,
641 self.assertEqual(inner_ip[ICMPerror].id, self.icmp_id_out)
643 self.logger.error(ppp("Unexpected or invalid packet "
644 "(outside network):", packet))
647 def verify_capture_in_with_icmp_errors(self, capture, in_if, icmp_type=11):
649 Verify captured packets with ICMP errors on inside network
651 :param capture: Captured packets
652 :param in_if: Inside interface
653 :param icmp_type: Type of error ICMP packet
654 we are expecting (Default 11)
656 for packet in capture:
658 self.assertEqual(packet[IP].dst, in_if.remote_ip4)
659 self.assertEqual(packet.haslayer(ICMP), 1)
661 self.assertEqual(icmp.type, icmp_type)
662 self.assertTrue(icmp.haslayer(IPerror))
663 inner_ip = icmp[IPerror]
664 if inner_ip.haslayer(TCPerror):
665 self.assertEqual(inner_ip[TCPerror].sport,
667 elif inner_ip.haslayer(UDPerror):
668 self.assertEqual(inner_ip[UDPerror].sport,
671 self.assertEqual(inner_ip[ICMPerror].id, self.icmp_id_in)
673 self.logger.error(ppp("Unexpected or invalid packet "
674 "(inside network):", packet))
677 def create_stream_frag(self, src_if, dst, sport, dport, data,
678 proto=IP_PROTOS.tcp, echo_reply=False):
680 Create fragmented packet stream
682 :param src_if: Source interface
683 :param dst: Destination IPv4 address
684 :param sport: Source port
685 :param dport: Destination port
686 :param data: Payload data
687 :param proto: protocol (TCP, UDP, ICMP)
688 :param echo_reply: use echo_reply if protocol is ICMP
691 if proto == IP_PROTOS.tcp:
692 p = (IP(src=src_if.remote_ip4, dst=dst) /
693 TCP(sport=sport, dport=dport) /
695 p = p.__class__(scapy.compat.raw(p))
696 chksum = p[TCP].chksum
697 proto_header = TCP(sport=sport, dport=dport, chksum=chksum)
698 elif proto == IP_PROTOS.udp:
699 proto_header = UDP(sport=sport, dport=dport)
700 elif proto == IP_PROTOS.icmp:
702 proto_header = ICMP(id=sport, type='echo-request')
704 proto_header = ICMP(id=sport, type='echo-reply')
706 raise Exception("Unsupported protocol")
707 id = random.randint(0, 65535)
709 if proto == IP_PROTOS.tcp:
712 raw = Raw(data[0:16])
713 p = (Ether(src=src_if.remote_mac, dst=src_if.local_mac) /
714 IP(src=src_if.remote_ip4, dst=dst, flags="MF", frag=0, id=id) /
718 if proto == IP_PROTOS.tcp:
719 raw = Raw(data[4:20])
721 raw = Raw(data[16:32])
722 p = (Ether(src=src_if.remote_mac, dst=src_if.local_mac) /
723 IP(src=src_if.remote_ip4, dst=dst, flags="MF", frag=3, id=id,
727 if proto == IP_PROTOS.tcp:
731 p = (Ether(src=src_if.remote_mac, dst=src_if.local_mac) /
732 IP(src=src_if.remote_ip4, dst=dst, frag=5, proto=proto,
738 def create_stream_frag_ip6(self, src_if, dst, sport, dport, data,
739 pref=None, plen=0, frag_size=128):
741 Create fragmented packet stream
743 :param src_if: Source interface
744 :param dst: Destination IPv4 address
745 :param sport: Source TCP port
746 :param dport: Destination TCP port
747 :param data: Payload data
748 :param pref: NAT64 prefix
749 :param plen: NAT64 prefix length
750 :param fragsize: size of fragments
754 dst_ip6 = ''.join(['64:ff9b::', dst])
756 dst_ip6 = self.compose_ip6(dst, pref, plen)
758 p = (Ether(dst=src_if.local_mac, src=src_if.remote_mac) /
759 IPv6(src=src_if.remote_ip6, dst=dst_ip6) /
760 IPv6ExtHdrFragment(id=random.randint(0, 65535)) /
761 TCP(sport=sport, dport=dport) /
764 return fragment6(p, frag_size)
766 def reass_frags_and_verify(self, frags, src, dst):
768 Reassemble and verify fragmented packet
770 :param frags: Captured fragments
771 :param src: Source IPv4 address to verify
772 :param dst: Destination IPv4 address to verify
774 :returns: Reassembled IPv4 packet
778 self.assertEqual(p[IP].src, src)
779 self.assertEqual(p[IP].dst, dst)
780 self.assert_ip_checksum_valid(p)
781 buffer.seek(p[IP].frag * 8)
782 buffer.write(bytes(p[IP].payload))
783 ip = IP(src=frags[0][IP].src, dst=frags[0][IP].dst,
784 proto=frags[0][IP].proto)
785 if ip.proto == IP_PROTOS.tcp:
786 p = (ip / TCP(buffer.getvalue()))
787 self.assert_tcp_checksum_valid(p)
788 elif ip.proto == IP_PROTOS.udp:
789 p = (ip / UDP(buffer.getvalue()[:8]) /
790 Raw(buffer.getvalue()[8:]))
791 elif ip.proto == IP_PROTOS.icmp:
792 p = (ip / ICMP(buffer.getvalue()))
795 def reass_frags_and_verify_ip6(self, frags, src, dst):
797 Reassemble and verify fragmented packet
799 :param frags: Captured fragments
800 :param src: Source IPv6 address to verify
801 :param dst: Destination IPv6 address to verify
803 :returns: Reassembled IPv6 packet
807 self.assertEqual(p[IPv6].src, src)
808 self.assertEqual(p[IPv6].dst, dst)
809 buffer.seek(p[IPv6ExtHdrFragment].offset * 8)
810 buffer.write(bytes(p[IPv6ExtHdrFragment].payload))
811 ip = IPv6(src=frags[0][IPv6].src, dst=frags[0][IPv6].dst,
812 nh=frags[0][IPv6ExtHdrFragment].nh)
813 if ip.nh == IP_PROTOS.tcp:
814 p = (ip / TCP(buffer.getvalue()))
815 elif ip.nh == IP_PROTOS.udp:
816 p = (ip / UDP(buffer.getvalue()))
817 self.assert_packet_checksums_valid(p)
820 def initiate_tcp_session(self, in_if, out_if):
822 Initiates TCP session
824 :param in_if: Inside interface
825 :param out_if: Outside interface
829 p = (Ether(src=in_if.remote_mac, dst=in_if.local_mac) /
830 IP(src=in_if.remote_ip4, dst=out_if.remote_ip4) /
831 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
834 self.pg_enable_capture(self.pg_interfaces)
836 capture = out_if.get_capture(1)
838 self.tcp_port_out = p[TCP].sport
840 # SYN + ACK packet out->in
841 p = (Ether(src=out_if.remote_mac, dst=out_if.local_mac) /
842 IP(src=out_if.remote_ip4, dst=self.nat_addr) /
843 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
846 self.pg_enable_capture(self.pg_interfaces)
851 p = (Ether(src=in_if.remote_mac, dst=in_if.local_mac) /
852 IP(src=in_if.remote_ip4, dst=out_if.remote_ip4) /
853 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
856 self.pg_enable_capture(self.pg_interfaces)
858 out_if.get_capture(1)
861 self.logger.error("TCP 3 way handshake failed")
864 def verify_ipfix_nat44_ses(self, data):
866 Verify IPFIX NAT44 session create/delete event
868 :param data: Decoded IPFIX data records
870 nat44_ses_create_num = 0
871 nat44_ses_delete_num = 0
872 self.assertEqual(6, len(data))
875 self.assertIn(scapy.compat.orb(record[230]), [4, 5])
876 if scapy.compat.orb(record[230]) == 4:
877 nat44_ses_create_num += 1
879 nat44_ses_delete_num += 1
881 self.assertEqual(self.pg0.remote_ip4n, record[8])
882 # postNATSourceIPv4Address
883 self.assertEqual(socket.inet_pton(socket.AF_INET, self.nat_addr),
886 self.assertEqual(struct.pack("!I", 0), record[234])
887 # protocolIdentifier/sourceTransportPort/postNAPTSourceTransportPort
888 if IP_PROTOS.icmp == scapy.compat.orb(record[4]):
889 self.assertEqual(struct.pack("!H", self.icmp_id_in), record[7])
890 self.assertEqual(struct.pack("!H", self.icmp_id_out),
892 elif IP_PROTOS.tcp == scapy.compat.orb(record[4]):
893 self.assertEqual(struct.pack("!H", self.tcp_port_in),
895 self.assertEqual(struct.pack("!H", self.tcp_port_out),
897 elif IP_PROTOS.udp == scapy.compat.orb(record[4]):
898 self.assertEqual(struct.pack("!H", self.udp_port_in),
900 self.assertEqual(struct.pack("!H", self.udp_port_out),
903 self.fail("Invalid protocol")
904 self.assertEqual(3, nat44_ses_create_num)
905 self.assertEqual(3, nat44_ses_delete_num)
907 def verify_ipfix_addr_exhausted(self, data):
909 Verify IPFIX NAT addresses event
911 :param data: Decoded IPFIX data records
913 self.assertEqual(1, len(data))
916 self.assertEqual(scapy.compat.orb(record[230]), 3)
918 self.assertEqual(struct.pack("!I", 0), record[283])
920 def verify_ipfix_max_sessions(self, data, limit):
922 Verify IPFIX maximum session entries exceeded event
924 :param data: Decoded IPFIX data records
925 :param limit: Number of maximum session entries that can be created.
927 self.assertEqual(1, len(data))
930 self.assertEqual(scapy.compat.orb(record[230]), 13)
931 # natQuotaExceededEvent
932 self.assertEqual(struct.pack("I", 1), record[466])
934 self.assertEqual(struct.pack("I", limit), record[471])
936 def verify_ipfix_max_bibs(self, data, limit):
938 Verify IPFIX maximum BIB entries exceeded event
940 :param data: Decoded IPFIX data records
941 :param limit: Number of maximum BIB entries that can be created.
943 self.assertEqual(1, len(data))
946 self.assertEqual(scapy.compat.orb(record[230]), 13)
947 # natQuotaExceededEvent
948 self.assertEqual(struct.pack("I", 2), record[466])
950 self.assertEqual(struct.pack("I", limit), record[472])
952 def verify_ipfix_max_fragments_ip6(self, data, limit, src_addr):
954 Verify IPFIX maximum IPv6 fragments pending reassembly exceeded event
956 :param data: Decoded IPFIX data records
957 :param limit: Number of maximum fragments pending reassembly
958 :param src_addr: IPv6 source address
960 self.assertEqual(1, len(data))
963 self.assertEqual(scapy.compat.orb(record[230]), 13)
964 # natQuotaExceededEvent
965 self.assertEqual(struct.pack("I", 5), record[466])
966 # maxFragmentsPendingReassembly
967 self.assertEqual(struct.pack("I", limit), record[475])
969 self.assertEqual(src_addr, record[27])
971 def verify_ipfix_max_fragments_ip4(self, data, limit, src_addr):
973 Verify IPFIX maximum IPv4 fragments pending reassembly exceeded event
975 :param data: Decoded IPFIX data records
976 :param limit: Number of maximum fragments pending reassembly
977 :param src_addr: IPv4 source address
979 self.assertEqual(1, len(data))
982 self.assertEqual(scapy.compat.orb(record[230]), 13)
983 # natQuotaExceededEvent
984 self.assertEqual(struct.pack("I", 5), record[466])
985 # maxFragmentsPendingReassembly
986 self.assertEqual(struct.pack("I", limit), record[475])
988 self.assertEqual(src_addr, record[8])
990 def verify_ipfix_bib(self, data, is_create, src_addr):
992 Verify IPFIX NAT64 BIB create and delete events
994 :param data: Decoded IPFIX data records
995 :param is_create: Create event if nonzero value otherwise delete event
996 :param src_addr: IPv6 source address
998 self.assertEqual(1, len(data))
1002 self.assertEqual(scapy.compat.orb(record[230]), 10)
1004 self.assertEqual(scapy.compat.orb(record[230]), 11)
1006 self.assertEqual(src_addr, record[27])
1007 # postNATSourceIPv4Address
1008 self.assertEqual(self.nat_addr_n, record[225])
1009 # protocolIdentifier
1010 self.assertEqual(IP_PROTOS.tcp, scapy.compat.orb(record[4]))
1012 self.assertEqual(struct.pack("!I", 0), record[234])
1013 # sourceTransportPort
1014 self.assertEqual(struct.pack("!H", self.tcp_port_in), record[7])
1015 # postNAPTSourceTransportPort
1016 self.assertEqual(struct.pack("!H", self.tcp_port_out), record[227])
1018 def verify_ipfix_nat64_ses(self, data, is_create, src_addr, dst_addr,
1021 Verify IPFIX NAT64 session create and delete events
1023 :param data: Decoded IPFIX data records
1024 :param is_create: Create event if nonzero value otherwise delete event
1025 :param src_addr: IPv6 source address
1026 :param dst_addr: IPv4 destination address
1027 :param dst_port: destination TCP port
1029 self.assertEqual(1, len(data))
1033 self.assertEqual(scapy.compat.orb(record[230]), 6)
1035 self.assertEqual(scapy.compat.orb(record[230]), 7)
1037 self.assertEqual(src_addr, record[27])
1038 # destinationIPv6Address
1039 self.assertEqual(socket.inet_pton(socket.AF_INET6,
1040 self.compose_ip6(dst_addr,
1044 # postNATSourceIPv4Address
1045 self.assertEqual(self.nat_addr_n, record[225])
1046 # postNATDestinationIPv4Address
1047 self.assertEqual(socket.inet_pton(socket.AF_INET, dst_addr),
1049 # protocolIdentifier
1050 self.assertEqual(IP_PROTOS.tcp, scapy.compat.orb(record[4]))
1052 self.assertEqual(struct.pack("!I", 0), record[234])
1053 # sourceTransportPort
1054 self.assertEqual(struct.pack("!H", self.tcp_port_in), record[7])
1055 # postNAPTSourceTransportPort
1056 self.assertEqual(struct.pack("!H", self.tcp_port_out), record[227])
1057 # destinationTransportPort
1058 self.assertEqual(struct.pack("!H", dst_port), record[11])
1059 # postNAPTDestinationTransportPort
1060 self.assertEqual(struct.pack("!H", dst_port), record[228])
1062 def verify_no_nat44_user(self):
1063 """ Verify that there is no NAT44 user """
1064 users = self.vapi.nat44_user_dump()
1065 self.assertEqual(len(users), 0)
1066 users = self.statistics.get_counter('/nat44/total-users')
1067 self.assertEqual(users[0][0], 0)
1068 sessions = self.statistics.get_counter('/nat44/total-sessions')
1069 self.assertEqual(sessions[0][0], 0)
1071 def verify_ipfix_max_entries_per_user(self, data, limit, src_addr):
1073 Verify IPFIX maximum entries per user exceeded event
1075 :param data: Decoded IPFIX data records
1076 :param limit: Number of maximum entries per user
1077 :param src_addr: IPv4 source address
1079 self.assertEqual(1, len(data))
1082 self.assertEqual(scapy.compat.orb(record[230]), 13)
1083 # natQuotaExceededEvent
1084 self.assertEqual(struct.pack("I", 3), record[466])
1086 self.assertEqual(struct.pack("I", limit), record[473])
1088 self.assertEqual(src_addr, record[8])
1090 def verify_syslog_apmap(self, data, is_add=True):
1091 message = data.decode('utf-8')
1093 message = SyslogMessage.parse(message)
1094 except ParseError as e:
1095 self.logger.error(e)
1098 self.assertEqual(message.severity, SyslogSeverity.info)
1099 self.assertEqual(message.appname, 'NAT')
1100 self.assertEqual(message.msgid, 'APMADD' if is_add else 'APMDEL')
1101 sd_params = message.sd.get('napmap')
1102 self.assertTrue(sd_params is not None)
1103 self.assertEqual(sd_params.get('IATYP'), 'IPv4')
1104 self.assertEqual(sd_params.get('ISADDR'), self.pg0.remote_ip4)
1105 self.assertEqual(sd_params.get('ISPORT'), "%d" % self.tcp_port_in)
1106 self.assertEqual(sd_params.get('XATYP'), 'IPv4')
1107 self.assertEqual(sd_params.get('XSADDR'), self.nat_addr)
1108 self.assertEqual(sd_params.get('XSPORT'), "%d" % self.tcp_port_out)
1109 self.assertEqual(sd_params.get('PROTO'), "%d" % IP_PROTOS.tcp)
1110 self.assertTrue(sd_params.get('SSUBIX') is not None)
1111 self.assertEqual(sd_params.get('SVLAN'), '0')
1113 def verify_syslog_sess(self, data, is_add=True, is_ip6=False):
1114 message = data.decode('utf-8')
1116 message = SyslogMessage.parse(message)
1117 except ParseError as e:
1118 self.logger.error(e)
1121 self.assertEqual(message.severity, SyslogSeverity.info)
1122 self.assertEqual(message.appname, 'NAT')
1123 self.assertEqual(message.msgid, 'SADD' if is_add else 'SDEL')
1124 sd_params = message.sd.get('nsess')
1125 self.assertTrue(sd_params is not None)
1127 self.assertEqual(sd_params.get('IATYP'), 'IPv6')
1128 self.assertEqual(sd_params.get('ISADDR'), self.pg0.remote_ip6)
1130 self.assertEqual(sd_params.get('IATYP'), 'IPv4')
1131 self.assertEqual(sd_params.get('ISADDR'), self.pg0.remote_ip4)
1132 self.assertTrue(sd_params.get('SSUBIX') is not None)
1133 self.assertEqual(sd_params.get('ISPORT'), "%d" % self.tcp_port_in)
1134 self.assertEqual(sd_params.get('XATYP'), 'IPv4')
1135 self.assertEqual(sd_params.get('XSADDR'), self.nat_addr)
1136 self.assertEqual(sd_params.get('XSPORT'), "%d" % self.tcp_port_out)
1137 self.assertEqual(sd_params.get('PROTO'), "%d" % IP_PROTOS.tcp)
1138 self.assertEqual(sd_params.get('SVLAN'), '0')
1139 self.assertEqual(sd_params.get('XDADDR'), self.pg1.remote_ip4)
1140 self.assertEqual(sd_params.get('XDPORT'),
1141 "%d" % self.tcp_external_port)
1143 def verify_mss_value(self, pkt, mss):
1145 Verify TCP MSS value
1150 if not pkt.haslayer(IP) or not pkt.haslayer(TCP):
1151 raise TypeError("Not a TCP/IP packet")
1153 for option in pkt[TCP].options:
1154 if option[0] == 'MSS':
1155 self.assertEqual(option[1], mss)
1156 self.assert_tcp_checksum_valid(pkt)
1159 def proto2layer(proto):
1160 if proto == IP_PROTOS.tcp:
1162 elif proto == IP_PROTOS.udp:
1164 elif proto == IP_PROTOS.icmp:
1167 raise Exception("Unsupported protocol")
1169 def frag_in_order(self, proto=IP_PROTOS.tcp, dont_translate=False):
1170 layer = self.proto2layer(proto)
1172 if proto == IP_PROTOS.tcp:
1173 data = b"A" * 4 + b"B" * 16 + b"C" * 3
1175 data = b"A" * 16 + b"B" * 16 + b"C" * 3
1176 self.port_in = random.randint(1025, 65535)
1178 reass = self.vapi.nat_reass_dump()
1179 reass_n_start = len(reass)
1182 pkts = self.create_stream_frag(self.pg0,
1183 self.pg1.remote_ip4,
1188 self.pg0.add_stream(pkts)
1189 self.pg_enable_capture(self.pg_interfaces)
1191 frags = self.pg1.get_capture(len(pkts))
1192 if not dont_translate:
1193 p = self.reass_frags_and_verify(frags,
1195 self.pg1.remote_ip4)
1197 p = self.reass_frags_and_verify(frags,
1198 self.pg0.remote_ip4,
1199 self.pg1.remote_ip4)
1200 if proto != IP_PROTOS.icmp:
1201 if not dont_translate:
1202 self.assertEqual(p[layer].dport, 20)
1203 self.assertNotEqual(p[layer].sport, self.port_in)
1205 self.assertEqual(p[layer].sport, self.port_in)
1207 if not dont_translate:
1208 self.assertNotEqual(p[layer].id, self.port_in)
1210 self.assertEqual(p[layer].id, self.port_in)
1211 self.assertEqual(data, p[Raw].load)
1214 if not dont_translate:
1215 dst_addr = self.nat_addr
1217 dst_addr = self.pg0.remote_ip4
1218 if proto != IP_PROTOS.icmp:
1220 dport = p[layer].sport
1224 pkts = self.create_stream_frag(self.pg1,
1231 self.pg1.add_stream(pkts)
1232 self.pg_enable_capture(self.pg_interfaces)
1234 frags = self.pg0.get_capture(len(pkts))
1235 p = self.reass_frags_and_verify(frags,
1236 self.pg1.remote_ip4,
1237 self.pg0.remote_ip4)
1238 if proto != IP_PROTOS.icmp:
1239 self.assertEqual(p[layer].sport, 20)
1240 self.assertEqual(p[layer].dport, self.port_in)
1242 self.assertEqual(p[layer].id, self.port_in)
1243 self.assertEqual(data, p[Raw].load)
1245 reass = self.vapi.nat_reass_dump()
1246 reass_n_end = len(reass)
1248 self.assertEqual(reass_n_end - reass_n_start, 2)
1250 def frag_in_order_in_plus_out(self, proto=IP_PROTOS.tcp):
1251 layer = self.proto2layer(proto)
1253 if proto == IP_PROTOS.tcp:
1254 data = b"A" * 4 + b"B" * 16 + b"C" * 3
1256 data = b"A" * 16 + b"B" * 16 + b"C" * 3
1257 self.port_in = random.randint(1025, 65535)
1260 reass = self.vapi.nat_reass_dump()
1261 reass_n_start = len(reass)
1264 pkts = self.create_stream_frag(self.pg0,
1265 self.server_out_addr,
1267 self.server_out_port,
1270 self.pg0.add_stream(pkts)
1271 self.pg_enable_capture(self.pg_interfaces)
1273 frags = self.pg1.get_capture(len(pkts))
1274 p = self.reass_frags_and_verify(frags,
1275 self.pg0.remote_ip4,
1276 self.server_in_addr)
1277 if proto != IP_PROTOS.icmp:
1278 self.assertEqual(p[layer].sport, self.port_in)
1279 self.assertEqual(p[layer].dport, self.server_in_port)
1281 self.assertEqual(p[layer].id, self.port_in)
1282 self.assertEqual(data, p[Raw].load)
1285 if proto != IP_PROTOS.icmp:
1286 pkts = self.create_stream_frag(self.pg1,
1287 self.pg0.remote_ip4,
1288 self.server_in_port,
1293 pkts = self.create_stream_frag(self.pg1,
1294 self.pg0.remote_ip4,
1300 self.pg1.add_stream(pkts)
1301 self.pg_enable_capture(self.pg_interfaces)
1303 frags = self.pg0.get_capture(len(pkts))
1304 p = self.reass_frags_and_verify(frags,
1305 self.server_out_addr,
1306 self.pg0.remote_ip4)
1307 if proto != IP_PROTOS.icmp:
1308 self.assertEqual(p[layer].sport, self.server_out_port)
1309 self.assertEqual(p[layer].dport, self.port_in)
1311 self.assertEqual(p[layer].id, self.port_in)
1312 self.assertEqual(data, p[Raw].load)
1314 reass = self.vapi.nat_reass_dump()
1315 reass_n_end = len(reass)
1317 self.assertEqual(reass_n_end - reass_n_start, 2)
1319 def reass_hairpinning(self, proto=IP_PROTOS.tcp):
1320 layer = self.proto2layer(proto)
1322 if proto == IP_PROTOS.tcp:
1323 data = b"A" * 4 + b"B" * 16 + b"C" * 3
1325 data = b"A" * 16 + b"B" * 16 + b"C" * 3
1327 # send packet from host to server
1328 pkts = self.create_stream_frag(self.pg0,
1331 self.server_out_port,
1334 self.pg0.add_stream(pkts)
1335 self.pg_enable_capture(self.pg_interfaces)
1337 frags = self.pg0.get_capture(len(pkts))
1338 p = self.reass_frags_and_verify(frags,
1341 if proto != IP_PROTOS.icmp:
1342 self.assertNotEqual(p[layer].sport, self.host_in_port)
1343 self.assertEqual(p[layer].dport, self.server_in_port)
1345 self.assertNotEqual(p[layer].id, self.host_in_port)
1346 self.assertEqual(data, p[Raw].load)
1348 def frag_out_of_order(self, proto=IP_PROTOS.tcp, dont_translate=False):
1349 layer = self.proto2layer(proto)
1351 if proto == IP_PROTOS.tcp:
1352 data = b"A" * 4 + b"B" * 16 + b"C" * 3
1354 data = b"A" * 16 + b"B" * 16 + b"C" * 3
1355 self.port_in = random.randint(1025, 65535)
1359 pkts = self.create_stream_frag(self.pg0,
1360 self.pg1.remote_ip4,
1366 self.pg0.add_stream(pkts)
1367 self.pg_enable_capture(self.pg_interfaces)
1369 frags = self.pg1.get_capture(len(pkts))
1370 if not dont_translate:
1371 p = self.reass_frags_and_verify(frags,
1373 self.pg1.remote_ip4)
1375 p = self.reass_frags_and_verify(frags,
1376 self.pg0.remote_ip4,
1377 self.pg1.remote_ip4)
1378 if proto != IP_PROTOS.icmp:
1379 if not dont_translate:
1380 self.assertEqual(p[layer].dport, 20)
1381 self.assertNotEqual(p[layer].sport, self.port_in)
1383 self.assertEqual(p[layer].sport, self.port_in)
1385 if not dont_translate:
1386 self.assertNotEqual(p[layer].id, self.port_in)
1388 self.assertEqual(p[layer].id, self.port_in)
1389 self.assertEqual(data, p[Raw].load)
1392 if not dont_translate:
1393 dst_addr = self.nat_addr
1395 dst_addr = self.pg0.remote_ip4
1396 if proto != IP_PROTOS.icmp:
1398 dport = p[layer].sport
1402 pkts = self.create_stream_frag(self.pg1,
1410 self.pg1.add_stream(pkts)
1411 self.pg_enable_capture(self.pg_interfaces)
1413 frags = self.pg0.get_capture(len(pkts))
1414 p = self.reass_frags_and_verify(frags,
1415 self.pg1.remote_ip4,
1416 self.pg0.remote_ip4)
1417 if proto != IP_PROTOS.icmp:
1418 self.assertEqual(p[layer].sport, 20)
1419 self.assertEqual(p[layer].dport, self.port_in)
1421 self.assertEqual(p[layer].id, self.port_in)
1422 self.assertEqual(data, p[Raw].load)
1424 def frag_out_of_order_in_plus_out(self, proto=IP_PROTOS.tcp):
1425 layer = self.proto2layer(proto)
1427 if proto == IP_PROTOS.tcp:
1428 data = b"A" * 4 + b"B" * 16 + b"C" * 3
1430 data = b"A" * 16 + b"B" * 16 + b"C" * 3
1431 self.port_in = random.randint(1025, 65535)
1435 pkts = self.create_stream_frag(self.pg0,
1436 self.server_out_addr,
1438 self.server_out_port,
1442 self.pg0.add_stream(pkts)
1443 self.pg_enable_capture(self.pg_interfaces)
1445 frags = self.pg1.get_capture(len(pkts))
1446 p = self.reass_frags_and_verify(frags,
1447 self.pg0.remote_ip4,
1448 self.server_in_addr)
1449 if proto != IP_PROTOS.icmp:
1450 self.assertEqual(p[layer].dport, self.server_in_port)
1451 self.assertEqual(p[layer].sport, self.port_in)
1452 self.assertEqual(p[layer].dport, self.server_in_port)
1454 self.assertEqual(p[layer].id, self.port_in)
1455 self.assertEqual(data, p[Raw].load)
1458 if proto != IP_PROTOS.icmp:
1459 pkts = self.create_stream_frag(self.pg1,
1460 self.pg0.remote_ip4,
1461 self.server_in_port,
1466 pkts = self.create_stream_frag(self.pg1,
1467 self.pg0.remote_ip4,
1474 self.pg1.add_stream(pkts)
1475 self.pg_enable_capture(self.pg_interfaces)
1477 frags = self.pg0.get_capture(len(pkts))
1478 p = self.reass_frags_and_verify(frags,
1479 self.server_out_addr,
1480 self.pg0.remote_ip4)
1481 if proto != IP_PROTOS.icmp:
1482 self.assertEqual(p[layer].sport, self.server_out_port)
1483 self.assertEqual(p[layer].dport, self.port_in)
1485 self.assertEqual(p[layer].id, self.port_in)
1486 self.assertEqual(data, p[Raw].load)
1489 class TestNAT44(MethodHolder):
1490 """ NAT44 Test Cases """
1493 def setUpClass(cls):
1494 super(TestNAT44, cls).setUpClass()
1495 cls.vapi.cli("set log class nat level debug")
1498 cls.tcp_port_in = 6303
1499 cls.tcp_port_out = 6303
1500 cls.udp_port_in = 6304
1501 cls.udp_port_out = 6304
1502 cls.icmp_id_in = 6305
1503 cls.icmp_id_out = 6305
1504 cls.nat_addr = '10.0.0.3'
1505 cls.nat_addr_n = socket.inet_pton(socket.AF_INET, cls.nat_addr)
1506 cls.ipfix_src_port = 4739
1507 cls.ipfix_domain_id = 1
1508 cls.tcp_external_port = 80
1509 cls.udp_external_port = 69
1511 cls.create_pg_interfaces(range(10))
1512 cls.interfaces = list(cls.pg_interfaces[0:4])
1514 for i in cls.interfaces:
1519 cls.pg0.generate_remote_hosts(3)
1520 cls.pg0.configure_ipv4_neighbors()
1522 cls.pg1.generate_remote_hosts(1)
1523 cls.pg1.configure_ipv4_neighbors()
1525 cls.overlapping_interfaces = list(list(cls.pg_interfaces[4:7]))
1526 cls.vapi.ip_table_add_del(is_add=1, table_id=10)
1527 cls.vapi.ip_table_add_del(is_add=1, table_id=20)
1529 cls.pg4._local_ip4 = "172.16.255.1"
1530 cls.pg4._local_ip4n = socket.inet_pton(socket.AF_INET, i.local_ip4)
1531 cls.pg4._remote_hosts[0]._ip4 = "172.16.255.2"
1532 cls.pg4.set_table_ip4(10)
1533 cls.pg5._local_ip4 = "172.17.255.3"
1534 cls.pg5._local_ip4n = socket.inet_pton(socket.AF_INET, i.local_ip4)
1535 cls.pg5._remote_hosts[0]._ip4 = "172.17.255.4"
1536 cls.pg5.set_table_ip4(10)
1537 cls.pg6._local_ip4 = "172.16.255.1"
1538 cls.pg6._local_ip4n = socket.inet_pton(socket.AF_INET, i.local_ip4)
1539 cls.pg6._remote_hosts[0]._ip4 = "172.16.255.2"
1540 cls.pg6.set_table_ip4(20)
1541 for i in cls.overlapping_interfaces:
1549 cls.pg9.generate_remote_hosts(2)
1550 cls.pg9.config_ip4()
1551 ip_addr_n = socket.inet_pton(socket.AF_INET, "10.0.0.1")
1552 cls.vapi.sw_interface_add_del_address(
1553 sw_if_index=cls.pg9.sw_if_index, address=ip_addr_n,
1556 cls.pg9.resolve_arp()
1557 cls.pg9._remote_hosts[1]._ip4 = cls.pg9._remote_hosts[0]._ip4
1558 cls.pg4._remote_ip4 = cls.pg9._remote_hosts[0]._ip4 = "10.0.0.2"
1559 cls.pg9.resolve_arp()
1562 super(TestNAT44, cls).tearDownClass()
1566 def tearDownClass(cls):
1567 super(TestNAT44, cls).tearDownClass()
1569 def test_dynamic(self):
1570 """ NAT44 dynamic translation test """
1571 self.nat44_add_address(self.nat_addr)
1572 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
1573 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
1577 tcpn = self.statistics.get_counter(
1578 '/err/nat44-in2out-slowpath/TCP packets')
1579 udpn = self.statistics.get_counter(
1580 '/err/nat44-in2out-slowpath/UDP packets')
1581 icmpn = self.statistics.get_counter(
1582 '/err/nat44-in2out-slowpath/ICMP packets')
1583 totaln = self.statistics.get_counter(
1584 '/err/nat44-in2out-slowpath/good in2out packets processed')
1586 pkts = self.create_stream_in(self.pg0, self.pg1)
1587 self.pg0.add_stream(pkts)
1588 self.pg_enable_capture(self.pg_interfaces)
1590 capture = self.pg1.get_capture(len(pkts))
1591 self.verify_capture_out(capture)
1593 err = self.statistics.get_counter(
1594 '/err/nat44-in2out-slowpath/TCP packets')
1595 self.assertEqual(err - tcpn, 1)
1596 err = self.statistics.get_counter(
1597 '/err/nat44-in2out-slowpath/UDP packets')
1598 self.assertEqual(err - udpn, 1)
1599 err = self.statistics.get_counter(
1600 '/err/nat44-in2out-slowpath/ICMP packets')
1601 self.assertEqual(err - icmpn, 1)
1602 err = self.statistics.get_counter(
1603 '/err/nat44-in2out-slowpath/good in2out packets processed')
1604 self.assertEqual(err - totaln, 3)
1607 tcpn = self.statistics.get_counter('/err/nat44-out2in/TCP packets')
1608 udpn = self.statistics.get_counter('/err/nat44-out2in/UDP packets')
1609 icmpn = self.statistics.get_counter('/err/nat44-out2in/ICMP packets')
1610 totaln = self.statistics.get_counter(
1611 '/err/nat44-out2in/good out2in packets processed')
1613 pkts = self.create_stream_out(self.pg1)
1614 self.pg1.add_stream(pkts)
1615 self.pg_enable_capture(self.pg_interfaces)
1617 capture = self.pg0.get_capture(len(pkts))
1618 self.verify_capture_in(capture, self.pg0)
1620 err = self.statistics.get_counter('/err/nat44-out2in/TCP packets')
1621 self.assertEqual(err - tcpn, 1)
1622 err = self.statistics.get_counter('/err/nat44-out2in/UDP packets')
1623 self.assertEqual(err - udpn, 1)
1624 err = self.statistics.get_counter('/err/nat44-out2in/ICMP packets')
1625 self.assertEqual(err - icmpn, 1)
1626 err = self.statistics.get_counter(
1627 '/err/nat44-out2in/good out2in packets processed')
1628 self.assertEqual(err - totaln, 3)
1630 users = self.statistics.get_counter('/nat44/total-users')
1631 self.assertEqual(users[0][0], 1)
1632 sessions = self.statistics.get_counter('/nat44/total-sessions')
1633 self.assertEqual(sessions[0][0], 3)
1635 def test_dynamic_icmp_errors_in2out_ttl_1(self):
1636 """ NAT44 handling of client packets with TTL=1 """
1638 self.nat44_add_address(self.nat_addr)
1639 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
1640 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
1643 # Client side - generate traffic
1644 pkts = self.create_stream_in(self.pg0, self.pg1, ttl=1)
1645 self.pg0.add_stream(pkts)
1646 self.pg_enable_capture(self.pg_interfaces)
1649 # Client side - verify ICMP type 11 packets
1650 capture = self.pg0.get_capture(len(pkts))
1651 self.verify_capture_in_with_icmp_errors(capture, self.pg0)
1653 def test_dynamic_icmp_errors_out2in_ttl_1(self):
1654 """ NAT44 handling of server packets with TTL=1 """
1656 self.nat44_add_address(self.nat_addr)
1657 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
1658 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
1661 # Client side - create sessions
1662 pkts = self.create_stream_in(self.pg0, self.pg1)
1663 self.pg0.add_stream(pkts)
1664 self.pg_enable_capture(self.pg_interfaces)
1667 # Server side - generate traffic
1668 capture = self.pg1.get_capture(len(pkts))
1669 self.verify_capture_out(capture)
1670 pkts = self.create_stream_out(self.pg1, ttl=1)
1671 self.pg1.add_stream(pkts)
1672 self.pg_enable_capture(self.pg_interfaces)
1675 # Server side - verify ICMP type 11 packets
1676 capture = self.pg1.get_capture(len(pkts))
1677 self.verify_capture_out_with_icmp_errors(capture,
1678 src_ip=self.pg1.local_ip4)
1680 def test_dynamic_icmp_errors_in2out_ttl_2(self):
1681 """ NAT44 handling of error responses to client packets with TTL=2 """
1683 self.nat44_add_address(self.nat_addr)
1684 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
1685 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
1688 # Client side - generate traffic
1689 pkts = self.create_stream_in(self.pg0, self.pg1, ttl=2)
1690 self.pg0.add_stream(pkts)
1691 self.pg_enable_capture(self.pg_interfaces)
1694 # Server side - simulate ICMP type 11 response
1695 capture = self.pg1.get_capture(len(pkts))
1696 pkts = [Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
1697 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
1698 ICMP(type=11) / packet[IP] for packet in capture]
1699 self.pg1.add_stream(pkts)
1700 self.pg_enable_capture(self.pg_interfaces)
1703 # Client side - verify ICMP type 11 packets
1704 capture = self.pg0.get_capture(len(pkts))
1705 self.verify_capture_in_with_icmp_errors(capture, self.pg0)
1707 def test_dynamic_icmp_errors_out2in_ttl_2(self):
1708 """ NAT44 handling of error responses to server packets with TTL=2 """
1710 self.nat44_add_address(self.nat_addr)
1711 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
1712 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
1715 # Client side - create sessions
1716 pkts = self.create_stream_in(self.pg0, self.pg1)
1717 self.pg0.add_stream(pkts)
1718 self.pg_enable_capture(self.pg_interfaces)
1721 # Server side - generate traffic
1722 capture = self.pg1.get_capture(len(pkts))
1723 self.verify_capture_out(capture)
1724 pkts = self.create_stream_out(self.pg1, ttl=2)
1725 self.pg1.add_stream(pkts)
1726 self.pg_enable_capture(self.pg_interfaces)
1729 # Client side - simulate ICMP type 11 response
1730 capture = self.pg0.get_capture(len(pkts))
1731 pkts = [Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
1732 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
1733 ICMP(type=11) / packet[IP] for packet in capture]
1734 self.pg0.add_stream(pkts)
1735 self.pg_enable_capture(self.pg_interfaces)
1738 # Server side - verify ICMP type 11 packets
1739 capture = self.pg1.get_capture(len(pkts))
1740 self.verify_capture_out_with_icmp_errors(capture)
1742 def test_ping_out_interface_from_outside(self):
1743 """ Ping NAT44 out interface from outside network """
1745 self.nat44_add_address(self.nat_addr)
1746 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
1747 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
1750 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
1751 IP(src=self.pg1.remote_ip4, dst=self.pg1.local_ip4) /
1752 ICMP(id=self.icmp_id_out, type='echo-request'))
1754 self.pg1.add_stream(pkts)
1755 self.pg_enable_capture(self.pg_interfaces)
1757 capture = self.pg1.get_capture(len(pkts))
1760 self.assertEqual(packet[IP].src, self.pg1.local_ip4)
1761 self.assertEqual(packet[IP].dst, self.pg1.remote_ip4)
1762 self.assertEqual(packet[ICMP].id, self.icmp_id_in)
1763 self.assertEqual(packet[ICMP].type, 0) # echo reply
1765 self.logger.error(ppp("Unexpected or invalid packet "
1766 "(outside network):", packet))
1769 def test_ping_internal_host_from_outside(self):
1770 """ Ping internal host from outside network """
1772 self.nat44_add_static_mapping(self.pg0.remote_ip4, self.nat_addr)
1773 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
1774 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
1778 pkt = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
1779 IP(src=self.pg1.remote_ip4, dst=self.nat_addr, ttl=64) /
1780 ICMP(id=self.icmp_id_out, type='echo-request'))
1781 self.pg1.add_stream(pkt)
1782 self.pg_enable_capture(self.pg_interfaces)
1784 capture = self.pg0.get_capture(1)
1785 self.verify_capture_in(capture, self.pg0)
1786 self.assert_equal(capture[0][IP].proto, IP_PROTOS.icmp)
1789 pkt = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
1790 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4, ttl=64) /
1791 ICMP(id=self.icmp_id_in, type='echo-reply'))
1792 self.pg0.add_stream(pkt)
1793 self.pg_enable_capture(self.pg_interfaces)
1795 capture = self.pg1.get_capture(1)
1796 self.verify_capture_out(capture, same_port=True)
1797 self.assert_equal(capture[0][IP].proto, IP_PROTOS.icmp)
1799 def test_forwarding(self):
1800 """ NAT44 forwarding test """
1802 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
1803 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
1805 self.vapi.nat44_forwarding_enable_disable(1)
1807 real_ip = self.pg0.remote_ip4n
1808 alias_ip = self.nat_addr_n
1809 self.vapi.nat44_add_del_static_mapping(local_ip=real_ip,
1810 external_ip=alias_ip)
1813 # static mapping match
1815 pkts = self.create_stream_out(self.pg1)
1816 self.pg1.add_stream(pkts)
1817 self.pg_enable_capture(self.pg_interfaces)
1819 capture = self.pg0.get_capture(len(pkts))
1820 self.verify_capture_in(capture, self.pg0)
1822 pkts = self.create_stream_in(self.pg0, self.pg1)
1823 self.pg0.add_stream(pkts)
1824 self.pg_enable_capture(self.pg_interfaces)
1826 capture = self.pg1.get_capture(len(pkts))
1827 self.verify_capture_out(capture, same_port=True)
1829 # no static mapping match
1831 host0 = self.pg0.remote_hosts[0]
1832 self.pg0.remote_hosts[0] = self.pg0.remote_hosts[1]
1834 pkts = self.create_stream_out(self.pg1,
1835 dst_ip=self.pg0.remote_ip4,
1836 use_inside_ports=True)
1837 self.pg1.add_stream(pkts)
1838 self.pg_enable_capture(self.pg_interfaces)
1840 capture = self.pg0.get_capture(len(pkts))
1841 self.verify_capture_in(capture, self.pg0)
1843 pkts = self.create_stream_in(self.pg0, self.pg1)
1844 self.pg0.add_stream(pkts)
1845 self.pg_enable_capture(self.pg_interfaces)
1847 capture = self.pg1.get_capture(len(pkts))
1848 self.verify_capture_out(capture, nat_ip=self.pg0.remote_ip4,
1851 self.pg0.remote_hosts[0] = host0
1854 self.vapi.nat44_forwarding_enable_disable(0)
1855 self.vapi.nat44_add_del_static_mapping(local_ip=real_ip,
1856 external_ip=alias_ip,
1859 def test_static_in(self):
1860 """ 1:1 NAT initialized from inside network """
1862 nat_ip = "10.0.0.10"
1863 self.tcp_port_out = 6303
1864 self.udp_port_out = 6304
1865 self.icmp_id_out = 6305
1867 self.nat44_add_static_mapping(self.pg0.remote_ip4, nat_ip)
1868 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
1869 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
1871 sm = self.vapi.nat44_static_mapping_dump()
1872 self.assertEqual(len(sm), 1)
1873 self.assertEqual((sm[0].tag).split(b'\0', 1)[0], b'')
1874 self.assertEqual(sm[0].protocol, 0)
1875 self.assertEqual(sm[0].local_port, 0)
1876 self.assertEqual(sm[0].external_port, 0)
1879 pkts = self.create_stream_in(self.pg0, self.pg1)
1880 self.pg0.add_stream(pkts)
1881 self.pg_enable_capture(self.pg_interfaces)
1883 capture = self.pg1.get_capture(len(pkts))
1884 self.verify_capture_out(capture, nat_ip, True)
1887 pkts = self.create_stream_out(self.pg1, nat_ip)
1888 self.pg1.add_stream(pkts)
1889 self.pg_enable_capture(self.pg_interfaces)
1891 capture = self.pg0.get_capture(len(pkts))
1892 self.verify_capture_in(capture, self.pg0)
1894 def test_static_out(self):
1895 """ 1:1 NAT initialized from outside network """
1897 nat_ip = "10.0.0.20"
1898 self.tcp_port_out = 6303
1899 self.udp_port_out = 6304
1900 self.icmp_id_out = 6305
1903 self.nat44_add_static_mapping(self.pg0.remote_ip4, nat_ip, tag=tag)
1904 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
1905 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
1907 sm = self.vapi.nat44_static_mapping_dump()
1908 self.assertEqual(len(sm), 1)
1909 self.assertEqual((sm[0].tag).split(b'\0', 1)[0], tag)
1912 pkts = self.create_stream_out(self.pg1, nat_ip)
1913 self.pg1.add_stream(pkts)
1914 self.pg_enable_capture(self.pg_interfaces)
1916 capture = self.pg0.get_capture(len(pkts))
1917 self.verify_capture_in(capture, self.pg0)
1920 pkts = self.create_stream_in(self.pg0, self.pg1)
1921 self.pg0.add_stream(pkts)
1922 self.pg_enable_capture(self.pg_interfaces)
1924 capture = self.pg1.get_capture(len(pkts))
1925 self.verify_capture_out(capture, nat_ip, True)
1927 def test_static_with_port_in(self):
1928 """ 1:1 NAPT initialized from inside network """
1930 self.tcp_port_out = 3606
1931 self.udp_port_out = 3607
1932 self.icmp_id_out = 3608
1934 self.nat44_add_address(self.nat_addr)
1935 self.nat44_add_static_mapping(self.pg0.remote_ip4, self.nat_addr,
1936 self.tcp_port_in, self.tcp_port_out,
1937 proto=IP_PROTOS.tcp)
1938 self.nat44_add_static_mapping(self.pg0.remote_ip4, self.nat_addr,
1939 self.udp_port_in, self.udp_port_out,
1940 proto=IP_PROTOS.udp)
1941 self.nat44_add_static_mapping(self.pg0.remote_ip4, self.nat_addr,
1942 self.icmp_id_in, self.icmp_id_out,
1943 proto=IP_PROTOS.icmp)
1944 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
1945 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
1949 pkts = self.create_stream_in(self.pg0, self.pg1)
1950 self.pg0.add_stream(pkts)
1951 self.pg_enable_capture(self.pg_interfaces)
1953 capture = self.pg1.get_capture(len(pkts))
1954 self.verify_capture_out(capture)
1957 pkts = self.create_stream_out(self.pg1)
1958 self.pg1.add_stream(pkts)
1959 self.pg_enable_capture(self.pg_interfaces)
1961 capture = self.pg0.get_capture(len(pkts))
1962 self.verify_capture_in(capture, self.pg0)
1964 def test_static_with_port_out(self):
1965 """ 1:1 NAPT initialized from outside network """
1967 self.tcp_port_out = 30606
1968 self.udp_port_out = 30607
1969 self.icmp_id_out = 30608
1971 self.nat44_add_address(self.nat_addr)
1972 self.nat44_add_static_mapping(self.pg0.remote_ip4, self.nat_addr,
1973 self.tcp_port_in, self.tcp_port_out,
1974 proto=IP_PROTOS.tcp)
1975 self.nat44_add_static_mapping(self.pg0.remote_ip4, self.nat_addr,
1976 self.udp_port_in, self.udp_port_out,
1977 proto=IP_PROTOS.udp)
1978 self.nat44_add_static_mapping(self.pg0.remote_ip4, self.nat_addr,
1979 self.icmp_id_in, self.icmp_id_out,
1980 proto=IP_PROTOS.icmp)
1981 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
1982 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
1986 pkts = self.create_stream_out(self.pg1)
1987 self.pg1.add_stream(pkts)
1988 self.pg_enable_capture(self.pg_interfaces)
1990 capture = self.pg0.get_capture(len(pkts))
1991 self.verify_capture_in(capture, self.pg0)
1994 pkts = self.create_stream_in(self.pg0, self.pg1)
1995 self.pg0.add_stream(pkts)
1996 self.pg_enable_capture(self.pg_interfaces)
1998 capture = self.pg1.get_capture(len(pkts))
1999 self.verify_capture_out(capture)
2001 def test_static_vrf_aware(self):
2002 """ 1:1 NAT VRF awareness """
2004 nat_ip1 = "10.0.0.30"
2005 nat_ip2 = "10.0.0.40"
2006 self.tcp_port_out = 6303
2007 self.udp_port_out = 6304
2008 self.icmp_id_out = 6305
2010 self.nat44_add_static_mapping(self.pg4.remote_ip4, nat_ip1,
2012 self.nat44_add_static_mapping(self.pg0.remote_ip4, nat_ip2,
2014 self.vapi.nat44_interface_add_del_feature(self.pg3.sw_if_index,
2016 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
2017 self.vapi.nat44_interface_add_del_feature(self.pg4.sw_if_index)
2019 # inside interface VRF match NAT44 static mapping VRF
2020 pkts = self.create_stream_in(self.pg4, self.pg3)
2021 self.pg4.add_stream(pkts)
2022 self.pg_enable_capture(self.pg_interfaces)
2024 capture = self.pg3.get_capture(len(pkts))
2025 self.verify_capture_out(capture, nat_ip1, True)
2027 # inside interface VRF don't match NAT44 static mapping VRF (packets
2029 pkts = self.create_stream_in(self.pg0, self.pg3)
2030 self.pg0.add_stream(pkts)
2031 self.pg_enable_capture(self.pg_interfaces)
2033 self.pg3.assert_nothing_captured()
2035 def test_dynamic_to_static(self):
2036 """ Switch from dynamic translation to 1:1NAT """
2037 nat_ip = "10.0.0.10"
2038 self.tcp_port_out = 6303
2039 self.udp_port_out = 6304
2040 self.icmp_id_out = 6305
2042 self.nat44_add_address(self.nat_addr)
2043 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
2044 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
2048 pkts = self.create_stream_in(self.pg0, self.pg1)
2049 self.pg0.add_stream(pkts)
2050 self.pg_enable_capture(self.pg_interfaces)
2052 capture = self.pg1.get_capture(len(pkts))
2053 self.verify_capture_out(capture)
2056 self.nat44_add_static_mapping(self.pg0.remote_ip4, nat_ip)
2057 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4n, 0)
2058 self.assertEqual(len(sessions), 0)
2059 pkts = self.create_stream_in(self.pg0, self.pg1)
2060 self.pg0.add_stream(pkts)
2061 self.pg_enable_capture(self.pg_interfaces)
2063 capture = self.pg1.get_capture(len(pkts))
2064 self.verify_capture_out(capture, nat_ip, True)
2066 def test_identity_nat(self):
2067 """ Identity NAT """
2069 self.vapi.nat44_add_del_identity_mapping(ip=self.pg0.remote_ip4n)
2070 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
2071 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
2074 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
2075 IP(src=self.pg1.remote_ip4, dst=self.pg0.remote_ip4) /
2076 TCP(sport=12345, dport=56789))
2077 self.pg1.add_stream(p)
2078 self.pg_enable_capture(self.pg_interfaces)
2080 capture = self.pg0.get_capture(1)
2085 self.assertEqual(ip.dst, self.pg0.remote_ip4)
2086 self.assertEqual(ip.src, self.pg1.remote_ip4)
2087 self.assertEqual(tcp.dport, 56789)
2088 self.assertEqual(tcp.sport, 12345)
2089 self.assert_packet_checksums_valid(p)
2091 self.logger.error(ppp("Unexpected or invalid packet:", p))
2094 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4n, 0)
2095 self.assertEqual(len(sessions), 0)
2096 self.vapi.nat44_add_del_identity_mapping(ip=self.pg0.remote_ip4n,
2098 identity_mappings = self.vapi.nat44_identity_mapping_dump()
2099 self.assertEqual(len(identity_mappings), 2)
2101 def test_multiple_inside_interfaces(self):
2102 """ NAT44 multiple non-overlapping address space inside interfaces """
2104 self.nat44_add_address(self.nat_addr)
2105 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
2106 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index)
2107 self.vapi.nat44_interface_add_del_feature(self.pg3.sw_if_index,
2110 # between two NAT44 inside interfaces (no translation)
2111 pkts = self.create_stream_in(self.pg0, self.pg1)
2112 self.pg0.add_stream(pkts)
2113 self.pg_enable_capture(self.pg_interfaces)
2115 capture = self.pg1.get_capture(len(pkts))
2116 self.verify_capture_no_translation(capture, self.pg0, self.pg1)
2118 # from NAT44 inside to interface without NAT44 feature (no translation)
2119 pkts = self.create_stream_in(self.pg0, self.pg2)
2120 self.pg0.add_stream(pkts)
2121 self.pg_enable_capture(self.pg_interfaces)
2123 capture = self.pg2.get_capture(len(pkts))
2124 self.verify_capture_no_translation(capture, self.pg0, self.pg2)
2126 # in2out 1st interface
2127 pkts = self.create_stream_in(self.pg0, self.pg3)
2128 self.pg0.add_stream(pkts)
2129 self.pg_enable_capture(self.pg_interfaces)
2131 capture = self.pg3.get_capture(len(pkts))
2132 self.verify_capture_out(capture)
2134 # out2in 1st interface
2135 pkts = self.create_stream_out(self.pg3)
2136 self.pg3.add_stream(pkts)
2137 self.pg_enable_capture(self.pg_interfaces)
2139 capture = self.pg0.get_capture(len(pkts))
2140 self.verify_capture_in(capture, self.pg0)
2142 # in2out 2nd interface
2143 pkts = self.create_stream_in(self.pg1, self.pg3)
2144 self.pg1.add_stream(pkts)
2145 self.pg_enable_capture(self.pg_interfaces)
2147 capture = self.pg3.get_capture(len(pkts))
2148 self.verify_capture_out(capture)
2150 # out2in 2nd interface
2151 pkts = self.create_stream_out(self.pg3)
2152 self.pg3.add_stream(pkts)
2153 self.pg_enable_capture(self.pg_interfaces)
2155 capture = self.pg1.get_capture(len(pkts))
2156 self.verify_capture_in(capture, self.pg1)
2158 def test_inside_overlapping_interfaces(self):
2159 """ NAT44 multiple inside interfaces with overlapping address space """
2161 static_nat_ip = "10.0.0.10"
2162 self.nat44_add_address(self.nat_addr)
2163 self.vapi.nat44_interface_add_del_feature(self.pg3.sw_if_index,
2165 self.vapi.nat44_interface_add_del_feature(self.pg4.sw_if_index)
2166 self.vapi.nat44_interface_add_del_feature(self.pg5.sw_if_index)
2167 self.vapi.nat44_interface_add_del_feature(self.pg6.sw_if_index)
2168 self.nat44_add_static_mapping(self.pg6.remote_ip4, static_nat_ip,
2171 # between NAT44 inside interfaces with same VRF (no translation)
2172 pkts = self.create_stream_in(self.pg4, self.pg5)
2173 self.pg4.add_stream(pkts)
2174 self.pg_enable_capture(self.pg_interfaces)
2176 capture = self.pg5.get_capture(len(pkts))
2177 self.verify_capture_no_translation(capture, self.pg4, self.pg5)
2179 # between NAT44 inside interfaces with different VRF (hairpinning)
2180 p = (Ether(src=self.pg4.remote_mac, dst=self.pg4.local_mac) /
2181 IP(src=self.pg4.remote_ip4, dst=static_nat_ip) /
2182 TCP(sport=1234, dport=5678))
2183 self.pg4.add_stream(p)
2184 self.pg_enable_capture(self.pg_interfaces)
2186 capture = self.pg6.get_capture(1)
2191 self.assertEqual(ip.src, self.nat_addr)
2192 self.assertEqual(ip.dst, self.pg6.remote_ip4)
2193 self.assertNotEqual(tcp.sport, 1234)
2194 self.assertEqual(tcp.dport, 5678)
2196 self.logger.error(ppp("Unexpected or invalid packet:", p))
2199 # in2out 1st interface
2200 pkts = self.create_stream_in(self.pg4, self.pg3)
2201 self.pg4.add_stream(pkts)
2202 self.pg_enable_capture(self.pg_interfaces)
2204 capture = self.pg3.get_capture(len(pkts))
2205 self.verify_capture_out(capture)
2207 # out2in 1st interface
2208 pkts = self.create_stream_out(self.pg3)
2209 self.pg3.add_stream(pkts)
2210 self.pg_enable_capture(self.pg_interfaces)
2212 capture = self.pg4.get_capture(len(pkts))
2213 self.verify_capture_in(capture, self.pg4)
2215 # in2out 2nd interface
2216 pkts = self.create_stream_in(self.pg5, self.pg3)
2217 self.pg5.add_stream(pkts)
2218 self.pg_enable_capture(self.pg_interfaces)
2220 capture = self.pg3.get_capture(len(pkts))
2221 self.verify_capture_out(capture)
2223 # out2in 2nd interface
2224 pkts = self.create_stream_out(self.pg3)
2225 self.pg3.add_stream(pkts)
2226 self.pg_enable_capture(self.pg_interfaces)
2228 capture = self.pg5.get_capture(len(pkts))
2229 self.verify_capture_in(capture, self.pg5)
2232 addresses = self.vapi.nat44_address_dump()
2233 self.assertEqual(len(addresses), 1)
2234 sessions = self.vapi.nat44_user_session_dump(self.pg5.remote_ip4n, 10)
2235 self.assertEqual(len(sessions), 3)
2236 for session in sessions:
2237 self.assertFalse(session.is_static)
2238 self.assertEqual(session.inside_ip_address[0:4],
2239 self.pg5.remote_ip4n)
2240 self.assertEqual(session.outside_ip_address,
2241 addresses[0].ip_address)
2242 self.assertEqual(sessions[0].protocol, IP_PROTOS.tcp)
2243 self.assertEqual(sessions[1].protocol, IP_PROTOS.udp)
2244 self.assertEqual(sessions[2].protocol, IP_PROTOS.icmp)
2245 self.assertEqual(sessions[0].inside_port, self.tcp_port_in)
2246 self.assertEqual(sessions[1].inside_port, self.udp_port_in)
2247 self.assertEqual(sessions[2].inside_port, self.icmp_id_in)
2248 self.assertEqual(sessions[0].outside_port, self.tcp_port_out)
2249 self.assertEqual(sessions[1].outside_port, self.udp_port_out)
2250 self.assertEqual(sessions[2].outside_port, self.icmp_id_out)
2252 # in2out 3rd interface
2253 pkts = self.create_stream_in(self.pg6, self.pg3)
2254 self.pg6.add_stream(pkts)
2255 self.pg_enable_capture(self.pg_interfaces)
2257 capture = self.pg3.get_capture(len(pkts))
2258 self.verify_capture_out(capture, static_nat_ip, True)
2260 # out2in 3rd interface
2261 pkts = self.create_stream_out(self.pg3, static_nat_ip)
2262 self.pg3.add_stream(pkts)
2263 self.pg_enable_capture(self.pg_interfaces)
2265 capture = self.pg6.get_capture(len(pkts))
2266 self.verify_capture_in(capture, self.pg6)
2268 # general user and session dump verifications
2269 users = self.vapi.nat44_user_dump()
2270 self.assertGreaterEqual(len(users), 3)
2271 addresses = self.vapi.nat44_address_dump()
2272 self.assertEqual(len(addresses), 1)
2274 sessions = self.vapi.nat44_user_session_dump(user.ip_address,
2276 for session in sessions:
2277 self.assertEqual(user.ip_address, session.inside_ip_address)
2278 self.assertTrue(session.total_bytes > session.total_pkts > 0)
2279 self.assertTrue(session.protocol in
2280 [IP_PROTOS.tcp, IP_PROTOS.udp,
2282 self.assertFalse(session.ext_host_valid)
2285 sessions = self.vapi.nat44_user_session_dump(self.pg4.remote_ip4n, 10)
2286 self.assertGreaterEqual(len(sessions), 4)
2287 for session in sessions:
2288 self.assertFalse(session.is_static)
2289 self.assertEqual(session.inside_ip_address[0:4],
2290 self.pg4.remote_ip4n)
2291 self.assertEqual(session.outside_ip_address,
2292 addresses[0].ip_address)
2295 sessions = self.vapi.nat44_user_session_dump(self.pg6.remote_ip4n, 20)
2296 self.assertGreaterEqual(len(sessions), 3)
2297 for session in sessions:
2298 self.assertTrue(session.is_static)
2299 self.assertEqual(session.inside_ip_address[0:4],
2300 self.pg6.remote_ip4n)
2301 self.assertEqual(session.outside_ip_address,
2302 socket.inet_pton(socket.AF_INET, static_nat_ip))
2303 self.assertTrue(session.inside_port in
2304 [self.tcp_port_in, self.udp_port_in,
2307 def test_hairpinning(self):
2308 """ NAT44 hairpinning - 1:1 NAPT """
2310 host = self.pg0.remote_hosts[0]
2311 server = self.pg0.remote_hosts[1]
2314 server_in_port = 5678
2315 server_out_port = 8765
2317 self.nat44_add_address(self.nat_addr)
2318 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
2319 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
2321 # add static mapping for server
2322 self.nat44_add_static_mapping(server.ip4, self.nat_addr,
2323 server_in_port, server_out_port,
2324 proto=IP_PROTOS.tcp)
2326 # send packet from host to server
2327 p = (Ether(src=host.mac, dst=self.pg0.local_mac) /
2328 IP(src=host.ip4, dst=self.nat_addr) /
2329 TCP(sport=host_in_port, dport=server_out_port))
2330 self.pg0.add_stream(p)
2331 self.pg_enable_capture(self.pg_interfaces)
2333 capture = self.pg0.get_capture(1)
2338 self.assertEqual(ip.src, self.nat_addr)
2339 self.assertEqual(ip.dst, server.ip4)
2340 self.assertNotEqual(tcp.sport, host_in_port)
2341 self.assertEqual(tcp.dport, server_in_port)
2342 self.assert_packet_checksums_valid(p)
2343 host_out_port = tcp.sport
2345 self.logger.error(ppp("Unexpected or invalid packet:", p))
2348 # send reply from server to host
2349 p = (Ether(src=server.mac, dst=self.pg0.local_mac) /
2350 IP(src=server.ip4, dst=self.nat_addr) /
2351 TCP(sport=server_in_port, dport=host_out_port))
2352 self.pg0.add_stream(p)
2353 self.pg_enable_capture(self.pg_interfaces)
2355 capture = self.pg0.get_capture(1)
2360 self.assertEqual(ip.src, self.nat_addr)
2361 self.assertEqual(ip.dst, host.ip4)
2362 self.assertEqual(tcp.sport, server_out_port)
2363 self.assertEqual(tcp.dport, host_in_port)
2364 self.assert_packet_checksums_valid(p)
2366 self.logger.error(ppp("Unexpected or invalid packet:", p))
2369 def test_hairpinning2(self):
2370 """ NAT44 hairpinning - 1:1 NAT"""
2372 server1_nat_ip = "10.0.0.10"
2373 server2_nat_ip = "10.0.0.11"
2374 host = self.pg0.remote_hosts[0]
2375 server1 = self.pg0.remote_hosts[1]
2376 server2 = self.pg0.remote_hosts[2]
2377 server_tcp_port = 22
2378 server_udp_port = 20
2380 self.nat44_add_address(self.nat_addr)
2381 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
2382 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
2385 # add static mapping for servers
2386 self.nat44_add_static_mapping(server1.ip4, server1_nat_ip)
2387 self.nat44_add_static_mapping(server2.ip4, server2_nat_ip)
2391 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2392 IP(src=host.ip4, dst=server1_nat_ip) /
2393 TCP(sport=self.tcp_port_in, dport=server_tcp_port))
2395 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2396 IP(src=host.ip4, dst=server1_nat_ip) /
2397 UDP(sport=self.udp_port_in, dport=server_udp_port))
2399 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2400 IP(src=host.ip4, dst=server1_nat_ip) /
2401 ICMP(id=self.icmp_id_in, type='echo-request'))
2403 self.pg0.add_stream(pkts)
2404 self.pg_enable_capture(self.pg_interfaces)
2406 capture = self.pg0.get_capture(len(pkts))
2407 for packet in capture:
2409 self.assertEqual(packet[IP].src, self.nat_addr)
2410 self.assertEqual(packet[IP].dst, server1.ip4)
2411 if packet.haslayer(TCP):
2412 self.assertNotEqual(packet[TCP].sport, self.tcp_port_in)
2413 self.assertEqual(packet[TCP].dport, server_tcp_port)
2414 self.tcp_port_out = packet[TCP].sport
2415 self.assert_packet_checksums_valid(packet)
2416 elif packet.haslayer(UDP):
2417 self.assertNotEqual(packet[UDP].sport, self.udp_port_in)
2418 self.assertEqual(packet[UDP].dport, server_udp_port)
2419 self.udp_port_out = packet[UDP].sport
2421 self.assertNotEqual(packet[ICMP].id, self.icmp_id_in)
2422 self.icmp_id_out = packet[ICMP].id
2424 self.logger.error(ppp("Unexpected or invalid packet:", packet))
2429 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2430 IP(src=server1.ip4, dst=self.nat_addr) /
2431 TCP(sport=server_tcp_port, dport=self.tcp_port_out))
2433 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2434 IP(src=server1.ip4, dst=self.nat_addr) /
2435 UDP(sport=server_udp_port, dport=self.udp_port_out))
2437 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2438 IP(src=server1.ip4, dst=self.nat_addr) /
2439 ICMP(id=self.icmp_id_out, type='echo-reply'))
2441 self.pg0.add_stream(pkts)
2442 self.pg_enable_capture(self.pg_interfaces)
2444 capture = self.pg0.get_capture(len(pkts))
2445 for packet in capture:
2447 self.assertEqual(packet[IP].src, server1_nat_ip)
2448 self.assertEqual(packet[IP].dst, host.ip4)
2449 if packet.haslayer(TCP):
2450 self.assertEqual(packet[TCP].dport, self.tcp_port_in)
2451 self.assertEqual(packet[TCP].sport, server_tcp_port)
2452 self.assert_packet_checksums_valid(packet)
2453 elif packet.haslayer(UDP):
2454 self.assertEqual(packet[UDP].dport, self.udp_port_in)
2455 self.assertEqual(packet[UDP].sport, server_udp_port)
2457 self.assertEqual(packet[ICMP].id, self.icmp_id_in)
2459 self.logger.error(ppp("Unexpected or invalid packet:", packet))
2462 # server2 to server1
2464 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2465 IP(src=server2.ip4, dst=server1_nat_ip) /
2466 TCP(sport=self.tcp_port_in, dport=server_tcp_port))
2468 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2469 IP(src=server2.ip4, dst=server1_nat_ip) /
2470 UDP(sport=self.udp_port_in, dport=server_udp_port))
2472 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2473 IP(src=server2.ip4, dst=server1_nat_ip) /
2474 ICMP(id=self.icmp_id_in, type='echo-request'))
2476 self.pg0.add_stream(pkts)
2477 self.pg_enable_capture(self.pg_interfaces)
2479 capture = self.pg0.get_capture(len(pkts))
2480 for packet in capture:
2482 self.assertEqual(packet[IP].src, server2_nat_ip)
2483 self.assertEqual(packet[IP].dst, server1.ip4)
2484 if packet.haslayer(TCP):
2485 self.assertEqual(packet[TCP].sport, self.tcp_port_in)
2486 self.assertEqual(packet[TCP].dport, server_tcp_port)
2487 self.tcp_port_out = packet[TCP].sport
2488 self.assert_packet_checksums_valid(packet)
2489 elif packet.haslayer(UDP):
2490 self.assertEqual(packet[UDP].sport, self.udp_port_in)
2491 self.assertEqual(packet[UDP].dport, server_udp_port)
2492 self.udp_port_out = packet[UDP].sport
2494 self.assertEqual(packet[ICMP].id, self.icmp_id_in)
2495 self.icmp_id_out = packet[ICMP].id
2497 self.logger.error(ppp("Unexpected or invalid packet:", packet))
2500 # server1 to server2
2502 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2503 IP(src=server1.ip4, dst=server2_nat_ip) /
2504 TCP(sport=server_tcp_port, dport=self.tcp_port_out))
2506 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2507 IP(src=server1.ip4, dst=server2_nat_ip) /
2508 UDP(sport=server_udp_port, dport=self.udp_port_out))
2510 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2511 IP(src=server1.ip4, dst=server2_nat_ip) /
2512 ICMP(id=self.icmp_id_out, type='echo-reply'))
2514 self.pg0.add_stream(pkts)
2515 self.pg_enable_capture(self.pg_interfaces)
2517 capture = self.pg0.get_capture(len(pkts))
2518 for packet in capture:
2520 self.assertEqual(packet[IP].src, server1_nat_ip)
2521 self.assertEqual(packet[IP].dst, server2.ip4)
2522 if packet.haslayer(TCP):
2523 self.assertEqual(packet[TCP].dport, self.tcp_port_in)
2524 self.assertEqual(packet[TCP].sport, server_tcp_port)
2525 self.assert_packet_checksums_valid(packet)
2526 elif packet.haslayer(UDP):
2527 self.assertEqual(packet[UDP].dport, self.udp_port_in)
2528 self.assertEqual(packet[UDP].sport, server_udp_port)
2530 self.assertEqual(packet[ICMP].id, self.icmp_id_in)
2532 self.logger.error(ppp("Unexpected or invalid packet:", packet))
2535 def test_max_translations_per_user(self):
2536 """ MAX translations per user - recycle the least recently used """
2538 self.nat44_add_address(self.nat_addr)
2539 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
2540 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
2543 # get maximum number of translations per user
2544 nat44_config = self.vapi.nat_show_config()
2546 # send more than maximum number of translations per user packets
2547 pkts_num = nat44_config.max_translations_per_user + 5
2549 for port in range(0, pkts_num):
2550 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2551 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
2552 TCP(sport=1025 + port))
2554 self.pg0.add_stream(pkts)
2555 self.pg_enable_capture(self.pg_interfaces)
2558 # verify number of translated packet
2559 self.pg1.get_capture(pkts_num)
2561 users = self.vapi.nat44_user_dump()
2563 if user.ip_address == self.pg0.remote_ip4n:
2564 self.assertEqual(user.nsessions,
2565 nat44_config.max_translations_per_user)
2566 self.assertEqual(user.nstaticsessions, 0)
2569 self.nat44_add_static_mapping(self.pg0.remote_ip4, self.nat_addr,
2571 proto=IP_PROTOS.tcp)
2572 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2573 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
2574 TCP(sport=tcp_port))
2575 self.pg0.add_stream(p)
2576 self.pg_enable_capture(self.pg_interfaces)
2578 self.pg1.get_capture(1)
2579 users = self.vapi.nat44_user_dump()
2581 if user.ip_address == self.pg0.remote_ip4n:
2582 self.assertEqual(user.nsessions,
2583 nat44_config.max_translations_per_user - 1)
2584 self.assertEqual(user.nstaticsessions, 1)
2586 def test_interface_addr(self):
2587 """ Acquire NAT44 addresses from interface """
2588 self.vapi.nat44_add_del_interface_addr(self.pg7.sw_if_index)
2590 # no address in NAT pool
2591 addresses = self.vapi.nat44_address_dump()
2592 self.assertEqual(0, len(addresses))
2594 # configure interface address and check NAT address pool
2595 self.pg7.config_ip4()
2596 addresses = self.vapi.nat44_address_dump()
2597 self.assertEqual(1, len(addresses))
2598 self.assertEqual(addresses[0].ip_address[0:4], self.pg7.local_ip4n)
2600 # remove interface address and check NAT address pool
2601 self.pg7.unconfig_ip4()
2602 addresses = self.vapi.nat44_address_dump()
2603 self.assertEqual(0, len(addresses))
2605 def test_interface_addr_static_mapping(self):
2606 """ Static mapping with addresses from interface """
2609 self.vapi.nat44_add_del_interface_addr(self.pg7.sw_if_index)
2610 self.nat44_add_static_mapping(
2612 external_sw_if_index=self.pg7.sw_if_index,
2615 # static mappings with external interface
2616 static_mappings = self.vapi.nat44_static_mapping_dump()
2617 self.assertEqual(1, len(static_mappings))
2618 self.assertEqual(self.pg7.sw_if_index,
2619 static_mappings[0].external_sw_if_index)
2620 self.assertEqual((static_mappings[0].tag).split(b'\0', 1)[0], tag)
2622 # configure interface address and check static mappings
2623 self.pg7.config_ip4()
2624 static_mappings = self.vapi.nat44_static_mapping_dump()
2625 self.assertEqual(2, len(static_mappings))
2627 for sm in static_mappings:
2628 if sm.external_sw_if_index == 0xFFFFFFFF:
2629 self.assertEqual(sm.external_ip_address[0:4],
2630 self.pg7.local_ip4n)
2631 self.assertEqual((sm.tag).split(b'\0', 1)[0], tag)
2633 self.assertTrue(resolved)
2635 # remove interface address and check static mappings
2636 self.pg7.unconfig_ip4()
2637 static_mappings = self.vapi.nat44_static_mapping_dump()
2638 self.assertEqual(1, len(static_mappings))
2639 self.assertEqual(self.pg7.sw_if_index,
2640 static_mappings[0].external_sw_if_index)
2641 self.assertEqual((static_mappings[0].tag).split(b'\0', 1)[0], tag)
2643 # configure interface address again and check static mappings
2644 self.pg7.config_ip4()
2645 static_mappings = self.vapi.nat44_static_mapping_dump()
2646 self.assertEqual(2, len(static_mappings))
2648 for sm in static_mappings:
2649 if sm.external_sw_if_index == 0xFFFFFFFF:
2650 self.assertEqual(sm.external_ip_address[0:4],
2651 self.pg7.local_ip4n)
2652 self.assertEqual((sm.tag).split(b'\0', 1)[0], tag)
2654 self.assertTrue(resolved)
2656 # remove static mapping
2657 self.nat44_add_static_mapping(
2659 external_sw_if_index=self.pg7.sw_if_index,
2662 static_mappings = self.vapi.nat44_static_mapping_dump()
2663 self.assertEqual(0, len(static_mappings))
2665 def test_interface_addr_identity_nat(self):
2666 """ Identity NAT with addresses from interface """
2669 self.vapi.nat44_add_del_interface_addr(self.pg7.sw_if_index)
2670 self.vapi.nat44_add_del_identity_mapping(
2671 sw_if_index=self.pg7.sw_if_index,
2673 protocol=IP_PROTOS.tcp,
2676 # identity mappings with external interface
2677 identity_mappings = self.vapi.nat44_identity_mapping_dump()
2678 self.assertEqual(1, len(identity_mappings))
2679 self.assertEqual(self.pg7.sw_if_index,
2680 identity_mappings[0].sw_if_index)
2682 # configure interface address and check identity mappings
2683 self.pg7.config_ip4()
2684 identity_mappings = self.vapi.nat44_identity_mapping_dump()
2686 self.assertEqual(2, len(identity_mappings))
2687 for sm in identity_mappings:
2688 if sm.sw_if_index == 0xFFFFFFFF:
2689 self.assertEqual(identity_mappings[0].ip_address,
2690 self.pg7.local_ip4n)
2691 self.assertEqual(port, identity_mappings[0].port)
2692 self.assertEqual(IP_PROTOS.tcp, identity_mappings[0].protocol)
2694 self.assertTrue(resolved)
2696 # remove interface address and check identity mappings
2697 self.pg7.unconfig_ip4()
2698 identity_mappings = self.vapi.nat44_identity_mapping_dump()
2699 self.assertEqual(1, len(identity_mappings))
2700 self.assertEqual(self.pg7.sw_if_index,
2701 identity_mappings[0].sw_if_index)
2703 def test_ipfix_nat44_sess(self):
2704 """ IPFIX logging NAT44 session created/deleted """
2705 self.ipfix_domain_id = 10
2706 self.ipfix_src_port = 20202
2707 collector_port = 30303
2708 bind_layers(UDP, IPFIX, dport=30303)
2709 self.nat44_add_address(self.nat_addr)
2710 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
2711 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
2713 self.vapi.set_ipfix_exporter(collector_address=self.pg3.remote_ip4n,
2714 src_address=self.pg3.local_ip4n,
2716 template_interval=10,
2717 collector_port=collector_port)
2718 self.vapi.nat_ipfix_enable_disable(domain_id=self.ipfix_domain_id,
2719 src_port=self.ipfix_src_port)
2721 pkts = self.create_stream_in(self.pg0, self.pg1)
2722 self.pg0.add_stream(pkts)
2723 self.pg_enable_capture(self.pg_interfaces)
2725 capture = self.pg1.get_capture(len(pkts))
2726 self.verify_capture_out(capture)
2727 self.nat44_add_address(self.nat_addr, is_add=0)
2728 self.vapi.cli("ipfix flush") # FIXME this should be an API call
2729 capture = self.pg3.get_capture(9)
2730 ipfix = IPFIXDecoder()
2731 # first load template
2733 self.assertTrue(p.haslayer(IPFIX))
2734 self.assertEqual(p[IP].src, self.pg3.local_ip4)
2735 self.assertEqual(p[IP].dst, self.pg3.remote_ip4)
2736 self.assertEqual(p[UDP].sport, self.ipfix_src_port)
2737 self.assertEqual(p[UDP].dport, collector_port)
2738 self.assertEqual(p[IPFIX].observationDomainID,
2739 self.ipfix_domain_id)
2740 if p.haslayer(Template):
2741 ipfix.add_template(p.getlayer(Template))
2742 # verify events in data set
2744 if p.haslayer(Data):
2745 data = ipfix.decode_data_set(p.getlayer(Set))
2746 self.verify_ipfix_nat44_ses(data)
2748 def test_ipfix_addr_exhausted(self):
2749 """ IPFIX logging NAT addresses exhausted """
2750 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
2751 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
2753 self.vapi.set_ipfix_exporter(collector_address=self.pg3.remote_ip4n,
2754 src_address=self.pg3.local_ip4n,
2756 template_interval=10)
2757 self.vapi.nat_ipfix_enable_disable(domain_id=self.ipfix_domain_id,
2758 src_port=self.ipfix_src_port)
2760 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
2761 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
2763 self.pg0.add_stream(p)
2764 self.pg_enable_capture(self.pg_interfaces)
2766 self.pg1.assert_nothing_captured()
2768 self.vapi.cli("ipfix flush") # FIXME this should be an API call
2769 capture = self.pg3.get_capture(9)
2770 ipfix = IPFIXDecoder()
2771 # first load template
2773 self.assertTrue(p.haslayer(IPFIX))
2774 self.assertEqual(p[IP].src, self.pg3.local_ip4)
2775 self.assertEqual(p[IP].dst, self.pg3.remote_ip4)
2776 self.assertEqual(p[UDP].sport, self.ipfix_src_port)
2777 self.assertEqual(p[UDP].dport, 4739)
2778 self.assertEqual(p[IPFIX].observationDomainID,
2779 self.ipfix_domain_id)
2780 if p.haslayer(Template):
2781 ipfix.add_template(p.getlayer(Template))
2782 # verify events in data set
2784 if p.haslayer(Data):
2785 data = ipfix.decode_data_set(p.getlayer(Set))
2786 self.verify_ipfix_addr_exhausted(data)
2788 @unittest.skipUnless(running_extended_tests, "part of extended tests")
2789 def test_ipfix_max_sessions(self):
2790 """ IPFIX logging maximum session entries exceeded """
2791 self.nat44_add_address(self.nat_addr)
2792 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
2793 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
2796 nat44_config = self.vapi.nat_show_config()
2797 max_sessions = 10 * nat44_config.translation_buckets
2800 for i in range(0, max_sessions):
2801 src = "10.10.%u.%u" % ((i & 0xFF00) >> 8, i & 0xFF)
2802 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2803 IP(src=src, dst=self.pg1.remote_ip4) /
2806 self.pg0.add_stream(pkts)
2807 self.pg_enable_capture(self.pg_interfaces)
2810 self.pg1.get_capture(max_sessions)
2811 self.vapi.set_ipfix_exporter(collector_address=self.pg3.remote_ip4n,
2812 src_address=self.pg3.local_ip4n,
2814 template_interval=10)
2815 self.vapi.nat_ipfix_enable_disable(domain_id=self.ipfix_domain_id,
2816 src_port=self.ipfix_src_port)
2818 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2819 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
2821 self.pg0.add_stream(p)
2822 self.pg_enable_capture(self.pg_interfaces)
2824 self.pg1.assert_nothing_captured()
2826 self.vapi.cli("ipfix flush") # FIXME this should be an API call
2827 capture = self.pg3.get_capture(9)
2828 ipfix = IPFIXDecoder()
2829 # first load template
2831 self.assertTrue(p.haslayer(IPFIX))
2832 self.assertEqual(p[IP].src, self.pg3.local_ip4)
2833 self.assertEqual(p[IP].dst, self.pg3.remote_ip4)
2834 self.assertEqual(p[UDP].sport, self.ipfix_src_port)
2835 self.assertEqual(p[UDP].dport, 4739)
2836 self.assertEqual(p[IPFIX].observationDomainID,
2837 self.ipfix_domain_id)
2838 if p.haslayer(Template):
2839 ipfix.add_template(p.getlayer(Template))
2840 # verify events in data set
2842 if p.haslayer(Data):
2843 data = ipfix.decode_data_set(p.getlayer(Set))
2844 self.verify_ipfix_max_sessions(data, max_sessions)
2846 def test_syslog_apmap(self):
2847 """ Test syslog address and port mapping creation and deletion """
2848 self.vapi.syslog_set_filter(SYSLOG_SEVERITY.INFO)
2849 self.vapi.syslog_set_sender(self.pg3.local_ip4n, self.pg3.remote_ip4n)
2850 self.nat44_add_address(self.nat_addr)
2851 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
2852 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
2855 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2856 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
2857 TCP(sport=self.tcp_port_in, dport=20))
2858 self.pg0.add_stream(p)
2859 self.pg_enable_capture(self.pg_interfaces)
2861 capture = self.pg1.get_capture(1)
2862 self.tcp_port_out = capture[0][TCP].sport
2863 capture = self.pg3.get_capture(1)
2864 self.verify_syslog_apmap(capture[0][Raw].load)
2866 self.pg_enable_capture(self.pg_interfaces)
2868 self.nat44_add_address(self.nat_addr, is_add=0)
2869 capture = self.pg3.get_capture(1)
2870 self.verify_syslog_apmap(capture[0][Raw].load, False)
2872 def test_pool_addr_fib(self):
2873 """ NAT44 add pool addresses to FIB """
2874 static_addr = '10.0.0.10'
2875 self.nat44_add_address(self.nat_addr)
2876 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
2877 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
2879 self.nat44_add_static_mapping(self.pg0.remote_ip4, static_addr)
2882 p = (Ether(src=self.pg1.remote_mac, dst='ff:ff:ff:ff:ff:ff') /
2883 ARP(op=ARP.who_has, pdst=self.nat_addr,
2884 psrc=self.pg1.remote_ip4, hwsrc=self.pg1.remote_mac))
2885 self.pg1.add_stream(p)
2886 self.pg_enable_capture(self.pg_interfaces)
2888 capture = self.pg1.get_capture(1)
2889 self.assertTrue(capture[0].haslayer(ARP))
2890 self.assertTrue(capture[0][ARP].op, ARP.is_at)
2893 p = (Ether(src=self.pg1.remote_mac, dst='ff:ff:ff:ff:ff:ff') /
2894 ARP(op=ARP.who_has, pdst=static_addr,
2895 psrc=self.pg1.remote_ip4, hwsrc=self.pg1.remote_mac))
2896 self.pg1.add_stream(p)
2897 self.pg_enable_capture(self.pg_interfaces)
2899 capture = self.pg1.get_capture(1)
2900 self.assertTrue(capture[0].haslayer(ARP))
2901 self.assertTrue(capture[0][ARP].op, ARP.is_at)
2903 # send ARP to non-NAT44 interface
2904 p = (Ether(src=self.pg2.remote_mac, dst='ff:ff:ff:ff:ff:ff') /
2905 ARP(op=ARP.who_has, pdst=self.nat_addr,
2906 psrc=self.pg2.remote_ip4, hwsrc=self.pg2.remote_mac))
2907 self.pg2.add_stream(p)
2908 self.pg_enable_capture(self.pg_interfaces)
2910 self.pg1.assert_nothing_captured()
2912 # remove addresses and verify
2913 self.nat44_add_address(self.nat_addr, is_add=0)
2914 self.nat44_add_static_mapping(self.pg0.remote_ip4, static_addr,
2917 p = (Ether(src=self.pg1.remote_mac, dst='ff:ff:ff:ff:ff:ff') /
2918 ARP(op=ARP.who_has, pdst=self.nat_addr,
2919 psrc=self.pg1.remote_ip4, hwsrc=self.pg1.remote_mac))
2920 self.pg1.add_stream(p)
2921 self.pg_enable_capture(self.pg_interfaces)
2923 self.pg1.assert_nothing_captured()
2925 p = (Ether(src=self.pg1.remote_mac, dst='ff:ff:ff:ff:ff:ff') /
2926 ARP(op=ARP.who_has, pdst=static_addr,
2927 psrc=self.pg1.remote_ip4, hwsrc=self.pg1.remote_mac))
2928 self.pg1.add_stream(p)
2929 self.pg_enable_capture(self.pg_interfaces)
2931 self.pg1.assert_nothing_captured()
2933 def test_vrf_mode(self):
2934 """ NAT44 tenant VRF aware address pool mode """
2938 nat_ip1 = "10.0.0.10"
2939 nat_ip2 = "10.0.0.11"
2941 self.pg0.unconfig_ip4()
2942 self.pg1.unconfig_ip4()
2943 self.vapi.ip_table_add_del(is_add=1, table_id=vrf_id1)
2944 self.vapi.ip_table_add_del(is_add=1, table_id=vrf_id2)
2945 self.pg0.set_table_ip4(vrf_id1)
2946 self.pg1.set_table_ip4(vrf_id2)
2947 self.pg0.config_ip4()
2948 self.pg1.config_ip4()
2949 self.pg0.resolve_arp()
2950 self.pg1.resolve_arp()
2952 self.nat44_add_address(nat_ip1, vrf_id=vrf_id1)
2953 self.nat44_add_address(nat_ip2, vrf_id=vrf_id2)
2954 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
2955 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index)
2956 self.vapi.nat44_interface_add_del_feature(self.pg2.sw_if_index,
2961 pkts = self.create_stream_in(self.pg0, self.pg2)
2962 self.pg0.add_stream(pkts)
2963 self.pg_enable_capture(self.pg_interfaces)
2965 capture = self.pg2.get_capture(len(pkts))
2966 self.verify_capture_out(capture, nat_ip1)
2969 pkts = self.create_stream_in(self.pg1, self.pg2)
2970 self.pg1.add_stream(pkts)
2971 self.pg_enable_capture(self.pg_interfaces)
2973 capture = self.pg2.get_capture(len(pkts))
2974 self.verify_capture_out(capture, nat_ip2)
2977 self.pg0.unconfig_ip4()
2978 self.pg1.unconfig_ip4()
2979 self.pg0.set_table_ip4(0)
2980 self.pg1.set_table_ip4(0)
2981 self.pg0.config_ip4()
2982 self.pg1.config_ip4()
2983 self.pg0.resolve_arp()
2984 self.pg1.resolve_arp()
2985 self.vapi.ip_table_add_del(is_add=0, table_id=vrf_id1)
2986 self.vapi.ip_table_add_del(is_add=0, table_id=vrf_id2)
2988 def test_vrf_feature_independent(self):
2989 """ NAT44 tenant VRF independent address pool mode """
2991 nat_ip1 = "10.0.0.10"
2992 nat_ip2 = "10.0.0.11"
2994 self.nat44_add_address(nat_ip1)
2995 self.nat44_add_address(nat_ip2, vrf_id=99)
2996 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
2997 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index)
2998 self.vapi.nat44_interface_add_del_feature(self.pg2.sw_if_index,
3002 pkts = self.create_stream_in(self.pg0, self.pg2)
3003 self.pg0.add_stream(pkts)
3004 self.pg_enable_capture(self.pg_interfaces)
3006 capture = self.pg2.get_capture(len(pkts))
3007 self.verify_capture_out(capture, nat_ip1)
3010 pkts = self.create_stream_in(self.pg1, self.pg2)
3011 self.pg1.add_stream(pkts)
3012 self.pg_enable_capture(self.pg_interfaces)
3014 capture = self.pg2.get_capture(len(pkts))
3015 self.verify_capture_out(capture, nat_ip1)
3017 def test_dynamic_ipless_interfaces(self):
3018 """ NAT44 interfaces without configured IP address """
3020 self.vapi.ip_neighbor_add_del(
3021 self.pg7.sw_if_index,
3022 self.pg7.remote_mac,
3023 self.pg7.remote_ip4,
3024 flags=(VppEnum.vl_api_ip_neighbor_flags_t.
3025 IP_API_NEIGHBOR_FLAG_STATIC))
3026 self.vapi.ip_neighbor_add_del(
3027 self.pg8.sw_if_index,
3028 self.pg8.remote_mac,
3029 self.pg8.remote_ip4,
3030 flags=(VppEnum.vl_api_ip_neighbor_flags_t.
3031 IP_API_NEIGHBOR_FLAG_STATIC))
3033 self.vapi.ip_add_del_route(dst_address=self.pg7.remote_ip4n,
3034 dst_address_length=32,
3035 next_hop_address=self.pg7.remote_ip4n,
3036 next_hop_sw_if_index=self.pg7.sw_if_index)
3037 self.vapi.ip_add_del_route(dst_address=self.pg8.remote_ip4n,
3038 dst_address_length=32,
3039 next_hop_address=self.pg8.remote_ip4n,
3040 next_hop_sw_if_index=self.pg8.sw_if_index)
3042 self.nat44_add_address(self.nat_addr)
3043 self.vapi.nat44_interface_add_del_feature(self.pg7.sw_if_index)
3044 self.vapi.nat44_interface_add_del_feature(self.pg8.sw_if_index,
3048 pkts = self.create_stream_in(self.pg7, self.pg8)
3049 self.pg7.add_stream(pkts)
3050 self.pg_enable_capture(self.pg_interfaces)
3052 capture = self.pg8.get_capture(len(pkts))
3053 self.verify_capture_out(capture)
3056 pkts = self.create_stream_out(self.pg8, self.nat_addr)
3057 self.pg8.add_stream(pkts)
3058 self.pg_enable_capture(self.pg_interfaces)
3060 capture = self.pg7.get_capture(len(pkts))
3061 self.verify_capture_in(capture, self.pg7)
3063 def test_static_ipless_interfaces(self):
3064 """ NAT44 interfaces without configured IP address - 1:1 NAT """
3066 self.vapi.ip_neighbor_add_del(
3067 self.pg7.sw_if_index,
3068 self.pg7.remote_mac,
3069 self.pg7.remote_ip4,
3070 flags=(VppEnum.vl_api_ip_neighbor_flags_t.
3071 IP_API_NEIGHBOR_FLAG_STATIC))
3072 self.vapi.ip_neighbor_add_del(
3073 self.pg8.sw_if_index,
3074 self.pg8.remote_mac,
3075 self.pg8.remote_ip4,
3076 flags=(VppEnum.vl_api_ip_neighbor_flags_t.
3077 IP_API_NEIGHBOR_FLAG_STATIC))
3079 self.vapi.ip_add_del_route(dst_address=self.pg7.remote_ip4n,
3080 dst_address_length=32,
3081 next_hop_address=self.pg7.remote_ip4n,
3082 next_hop_sw_if_index=self.pg7.sw_if_index)
3083 self.vapi.ip_add_del_route(dst_address=self.pg8.remote_ip4n,
3084 dst_address_length=32,
3085 next_hop_address=self.pg8.remote_ip4n,
3086 next_hop_sw_if_index=self.pg8.sw_if_index)
3088 self.nat44_add_static_mapping(self.pg7.remote_ip4, self.nat_addr)
3089 self.vapi.nat44_interface_add_del_feature(self.pg7.sw_if_index)
3090 self.vapi.nat44_interface_add_del_feature(self.pg8.sw_if_index,
3094 pkts = self.create_stream_out(self.pg8)
3095 self.pg8.add_stream(pkts)
3096 self.pg_enable_capture(self.pg_interfaces)
3098 capture = self.pg7.get_capture(len(pkts))
3099 self.verify_capture_in(capture, self.pg7)
3102 pkts = self.create_stream_in(self.pg7, self.pg8)
3103 self.pg7.add_stream(pkts)
3104 self.pg_enable_capture(self.pg_interfaces)
3106 capture = self.pg8.get_capture(len(pkts))
3107 self.verify_capture_out(capture, self.nat_addr, True)
3109 def test_static_with_port_ipless_interfaces(self):
3110 """ NAT44 interfaces without configured IP address - 1:1 NAPT """
3112 self.tcp_port_out = 30606
3113 self.udp_port_out = 30607
3114 self.icmp_id_out = 30608
3116 self.vapi.ip_neighbor_add_del(
3117 self.pg7.sw_if_index,
3118 self.pg7.remote_mac,
3119 self.pg7.remote_ip4,
3120 flags=(VppEnum.vl_api_ip_neighbor_flags_t.
3121 IP_API_NEIGHBOR_FLAG_STATIC))
3122 self.vapi.ip_neighbor_add_del(
3123 self.pg8.sw_if_index,
3124 self.pg8.remote_mac,
3125 self.pg8.remote_ip4,
3126 flags=(VppEnum.vl_api_ip_neighbor_flags_t.
3127 IP_API_NEIGHBOR_FLAG_STATIC))
3129 self.vapi.ip_add_del_route(dst_address=self.pg7.remote_ip4n,
3130 dst_address_length=32,
3131 next_hop_address=self.pg7.remote_ip4n,
3132 next_hop_sw_if_index=self.pg7.sw_if_index)
3133 self.vapi.ip_add_del_route(dst_address=self.pg8.remote_ip4n,
3134 dst_address_length=32,
3135 next_hop_address=self.pg8.remote_ip4n,
3136 next_hop_sw_if_index=self.pg8.sw_if_index)
3138 self.nat44_add_address(self.nat_addr)
3139 self.nat44_add_static_mapping(self.pg7.remote_ip4, self.nat_addr,
3140 self.tcp_port_in, self.tcp_port_out,
3141 proto=IP_PROTOS.tcp)
3142 self.nat44_add_static_mapping(self.pg7.remote_ip4, self.nat_addr,
3143 self.udp_port_in, self.udp_port_out,
3144 proto=IP_PROTOS.udp)
3145 self.nat44_add_static_mapping(self.pg7.remote_ip4, self.nat_addr,
3146 self.icmp_id_in, self.icmp_id_out,
3147 proto=IP_PROTOS.icmp)
3148 self.vapi.nat44_interface_add_del_feature(self.pg7.sw_if_index)
3149 self.vapi.nat44_interface_add_del_feature(self.pg8.sw_if_index,
3153 pkts = self.create_stream_out(self.pg8)
3154 self.pg8.add_stream(pkts)
3155 self.pg_enable_capture(self.pg_interfaces)
3157 capture = self.pg7.get_capture(len(pkts))
3158 self.verify_capture_in(capture, self.pg7)
3161 pkts = self.create_stream_in(self.pg7, self.pg8)
3162 self.pg7.add_stream(pkts)
3163 self.pg_enable_capture(self.pg_interfaces)
3165 capture = self.pg8.get_capture(len(pkts))
3166 self.verify_capture_out(capture)
3168 def test_static_unknown_proto(self):
3169 """ 1:1 NAT translate packet with unknown protocol """
3170 nat_ip = "10.0.0.10"
3171 self.nat44_add_static_mapping(self.pg0.remote_ip4, nat_ip)
3172 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
3173 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
3177 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
3178 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
3180 IP(src=self.pg2.remote_ip4, dst=self.pg3.remote_ip4) /
3181 TCP(sport=1234, dport=1234))
3182 self.pg0.add_stream(p)
3183 self.pg_enable_capture(self.pg_interfaces)
3185 p = self.pg1.get_capture(1)
3188 self.assertEqual(packet[IP].src, nat_ip)
3189 self.assertEqual(packet[IP].dst, self.pg1.remote_ip4)
3190 self.assertEqual(packet.haslayer(GRE), 1)
3191 self.assert_packet_checksums_valid(packet)
3193 self.logger.error(ppp("Unexpected or invalid packet:", packet))
3197 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
3198 IP(src=self.pg1.remote_ip4, dst=nat_ip) /
3200 IP(src=self.pg3.remote_ip4, dst=self.pg2.remote_ip4) /
3201 TCP(sport=1234, dport=1234))
3202 self.pg1.add_stream(p)
3203 self.pg_enable_capture(self.pg_interfaces)
3205 p = self.pg0.get_capture(1)
3208 self.assertEqual(packet[IP].src, self.pg1.remote_ip4)
3209 self.assertEqual(packet[IP].dst, self.pg0.remote_ip4)
3210 self.assertEqual(packet.haslayer(GRE), 1)
3211 self.assert_packet_checksums_valid(packet)
3213 self.logger.error(ppp("Unexpected or invalid packet:", packet))
3216 def test_hairpinning_static_unknown_proto(self):
3217 """ 1:1 NAT translate packet with unknown protocol - hairpinning """
3219 host = self.pg0.remote_hosts[0]
3220 server = self.pg0.remote_hosts[1]
3222 host_nat_ip = "10.0.0.10"
3223 server_nat_ip = "10.0.0.11"
3225 self.nat44_add_static_mapping(host.ip4, host_nat_ip)
3226 self.nat44_add_static_mapping(server.ip4, server_nat_ip)
3227 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
3228 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
3232 p = (Ether(dst=self.pg0.local_mac, src=host.mac) /
3233 IP(src=host.ip4, dst=server_nat_ip) /
3235 IP(src=self.pg2.remote_ip4, dst=self.pg3.remote_ip4) /
3236 TCP(sport=1234, dport=1234))
3237 self.pg0.add_stream(p)
3238 self.pg_enable_capture(self.pg_interfaces)
3240 p = self.pg0.get_capture(1)
3243 self.assertEqual(packet[IP].src, host_nat_ip)
3244 self.assertEqual(packet[IP].dst, server.ip4)
3245 self.assertEqual(packet.haslayer(GRE), 1)
3246 self.assert_packet_checksums_valid(packet)
3248 self.logger.error(ppp("Unexpected or invalid packet:", packet))
3252 p = (Ether(dst=self.pg0.local_mac, src=server.mac) /
3253 IP(src=server.ip4, dst=host_nat_ip) /
3255 IP(src=self.pg3.remote_ip4, dst=self.pg2.remote_ip4) /
3256 TCP(sport=1234, dport=1234))
3257 self.pg0.add_stream(p)
3258 self.pg_enable_capture(self.pg_interfaces)
3260 p = self.pg0.get_capture(1)
3263 self.assertEqual(packet[IP].src, server_nat_ip)
3264 self.assertEqual(packet[IP].dst, host.ip4)
3265 self.assertEqual(packet.haslayer(GRE), 1)
3266 self.assert_packet_checksums_valid(packet)
3268 self.logger.error(ppp("Unexpected or invalid packet:", packet))
3271 def test_output_feature(self):
3272 """ NAT44 interface output feature (in2out postrouting) """
3273 self.nat44_add_address(self.nat_addr)
3274 self.vapi.nat44_interface_add_del_output_feature(self.pg0.sw_if_index)
3275 self.vapi.nat44_interface_add_del_output_feature(self.pg1.sw_if_index)
3276 self.vapi.nat44_interface_add_del_output_feature(self.pg3.sw_if_index,
3280 pkts = self.create_stream_in(self.pg0, self.pg3)
3281 self.pg0.add_stream(pkts)
3282 self.pg_enable_capture(self.pg_interfaces)
3284 capture = self.pg3.get_capture(len(pkts))
3285 self.verify_capture_out(capture)
3288 pkts = self.create_stream_out(self.pg3)
3289 self.pg3.add_stream(pkts)
3290 self.pg_enable_capture(self.pg_interfaces)
3292 capture = self.pg0.get_capture(len(pkts))
3293 self.verify_capture_in(capture, self.pg0)
3295 # from non-NAT interface to NAT inside interface
3296 pkts = self.create_stream_in(self.pg2, self.pg0)
3297 self.pg2.add_stream(pkts)
3298 self.pg_enable_capture(self.pg_interfaces)
3300 capture = self.pg0.get_capture(len(pkts))
3301 self.verify_capture_no_translation(capture, self.pg2, self.pg0)
3303 def test_output_feature_vrf_aware(self):
3304 """ NAT44 interface output feature VRF aware (in2out postrouting) """
3305 nat_ip_vrf10 = "10.0.0.10"
3306 nat_ip_vrf20 = "10.0.0.20"
3308 self.vapi.ip_add_del_route(dst_address=self.pg3.remote_ip4n,
3309 dst_address_length=32,
3310 next_hop_address=self.pg3.remote_ip4n,
3311 next_hop_sw_if_index=self.pg3.sw_if_index,
3313 self.vapi.ip_add_del_route(dst_address=self.pg3.remote_ip4n,
3314 dst_address_length=32,
3315 next_hop_address=self.pg3.remote_ip4n,
3316 next_hop_sw_if_index=self.pg3.sw_if_index,
3319 self.nat44_add_address(nat_ip_vrf10, vrf_id=10)
3320 self.nat44_add_address(nat_ip_vrf20, vrf_id=20)
3321 self.vapi.nat44_interface_add_del_output_feature(self.pg4.sw_if_index)
3322 self.vapi.nat44_interface_add_del_output_feature(self.pg6.sw_if_index)
3323 self.vapi.nat44_interface_add_del_output_feature(self.pg3.sw_if_index,
3327 pkts = self.create_stream_in(self.pg4, self.pg3)
3328 self.pg4.add_stream(pkts)
3329 self.pg_enable_capture(self.pg_interfaces)
3331 capture = self.pg3.get_capture(len(pkts))
3332 self.verify_capture_out(capture, nat_ip=nat_ip_vrf10)
3335 pkts = self.create_stream_out(self.pg3, dst_ip=nat_ip_vrf10)
3336 self.pg3.add_stream(pkts)
3337 self.pg_enable_capture(self.pg_interfaces)
3339 capture = self.pg4.get_capture(len(pkts))
3340 self.verify_capture_in(capture, self.pg4)
3343 pkts = self.create_stream_in(self.pg6, self.pg3)
3344 self.pg6.add_stream(pkts)
3345 self.pg_enable_capture(self.pg_interfaces)
3347 capture = self.pg3.get_capture(len(pkts))
3348 self.verify_capture_out(capture, nat_ip=nat_ip_vrf20)
3351 pkts = self.create_stream_out(self.pg3, dst_ip=nat_ip_vrf20)
3352 self.pg3.add_stream(pkts)
3353 self.pg_enable_capture(self.pg_interfaces)
3355 capture = self.pg6.get_capture(len(pkts))
3356 self.verify_capture_in(capture, self.pg6)
3358 def test_output_feature_hairpinning(self):
3359 """ NAT44 interface output feature hairpinning (in2out postrouting) """
3360 host = self.pg0.remote_hosts[0]
3361 server = self.pg0.remote_hosts[1]
3364 server_in_port = 5678
3365 server_out_port = 8765
3367 self.nat44_add_address(self.nat_addr)
3368 self.vapi.nat44_interface_add_del_output_feature(self.pg0.sw_if_index)
3369 self.vapi.nat44_interface_add_del_output_feature(self.pg1.sw_if_index,
3372 # add static mapping for server
3373 self.nat44_add_static_mapping(server.ip4, self.nat_addr,
3374 server_in_port, server_out_port,
3375 proto=IP_PROTOS.tcp)
3377 # send packet from host to server
3378 p = (Ether(src=host.mac, dst=self.pg0.local_mac) /
3379 IP(src=host.ip4, dst=self.nat_addr) /
3380 TCP(sport=host_in_port, dport=server_out_port))
3381 self.pg0.add_stream(p)
3382 self.pg_enable_capture(self.pg_interfaces)
3384 capture = self.pg0.get_capture(1)
3389 self.assertEqual(ip.src, self.nat_addr)
3390 self.assertEqual(ip.dst, server.ip4)
3391 self.assertNotEqual(tcp.sport, host_in_port)
3392 self.assertEqual(tcp.dport, server_in_port)
3393 self.assert_packet_checksums_valid(p)
3394 host_out_port = tcp.sport
3396 self.logger.error(ppp("Unexpected or invalid packet:", p))
3399 # send reply from server to host
3400 p = (Ether(src=server.mac, dst=self.pg0.local_mac) /
3401 IP(src=server.ip4, dst=self.nat_addr) /
3402 TCP(sport=server_in_port, dport=host_out_port))
3403 self.pg0.add_stream(p)
3404 self.pg_enable_capture(self.pg_interfaces)
3406 capture = self.pg0.get_capture(1)
3411 self.assertEqual(ip.src, self.nat_addr)
3412 self.assertEqual(ip.dst, host.ip4)
3413 self.assertEqual(tcp.sport, server_out_port)
3414 self.assertEqual(tcp.dport, host_in_port)
3415 self.assert_packet_checksums_valid(p)
3417 self.logger.error(ppp("Unexpected or invalid packet:", p))
3420 def test_one_armed_nat44(self):
3421 """ One armed NAT44 """
3422 remote_host = self.pg9.remote_hosts[0]
3423 local_host = self.pg9.remote_hosts[1]
3426 self.nat44_add_address(self.nat_addr)
3427 self.vapi.nat44_interface_add_del_feature(self.pg9.sw_if_index)
3428 self.vapi.nat44_interface_add_del_feature(self.pg9.sw_if_index,
3432 p = (Ether(src=self.pg9.remote_mac, dst=self.pg9.local_mac) /
3433 IP(src=local_host.ip4, dst=remote_host.ip4) /
3434 TCP(sport=12345, dport=80))
3435 self.pg9.add_stream(p)
3436 self.pg_enable_capture(self.pg_interfaces)
3438 capture = self.pg9.get_capture(1)
3443 self.assertEqual(ip.src, self.nat_addr)
3444 self.assertEqual(ip.dst, remote_host.ip4)
3445 self.assertNotEqual(tcp.sport, 12345)
3446 external_port = tcp.sport
3447 self.assertEqual(tcp.dport, 80)
3448 self.assert_packet_checksums_valid(p)
3450 self.logger.error(ppp("Unexpected or invalid packet:", p))
3454 p = (Ether(src=self.pg9.remote_mac, dst=self.pg9.local_mac) /
3455 IP(src=remote_host.ip4, dst=self.nat_addr) /
3456 TCP(sport=80, dport=external_port))
3457 self.pg9.add_stream(p)
3458 self.pg_enable_capture(self.pg_interfaces)
3460 capture = self.pg9.get_capture(1)
3465 self.assertEqual(ip.src, remote_host.ip4)
3466 self.assertEqual(ip.dst, local_host.ip4)
3467 self.assertEqual(tcp.sport, 80)
3468 self.assertEqual(tcp.dport, 12345)
3469 self.assert_packet_checksums_valid(p)
3471 self.logger.error(ppp("Unexpected or invalid packet:", p))
3474 err = self.statistics.get_counter('/err/nat44-classify/next in2out')
3475 self.assertEqual(err, 1)
3476 err = self.statistics.get_counter('/err/nat44-classify/next out2in')
3477 self.assertEqual(err, 1)
3479 def test_del_session(self):
3480 """ Delete NAT44 session """
3481 self.nat44_add_address(self.nat_addr)
3482 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
3483 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
3486 pkts = self.create_stream_in(self.pg0, self.pg1)
3487 self.pg0.add_stream(pkts)
3488 self.pg_enable_capture(self.pg_interfaces)
3490 self.pg1.get_capture(len(pkts))
3492 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4n, 0)
3493 nsessions = len(sessions)
3495 self.vapi.nat44_del_session(sessions[0].inside_ip_address,
3496 sessions[0].inside_port,
3497 sessions[0].protocol)
3498 self.vapi.nat44_del_session(sessions[1].outside_ip_address,
3499 sessions[1].outside_port,
3500 sessions[1].protocol,
3503 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4n, 0)
3504 self.assertEqual(nsessions - len(sessions), 2)
3506 self.vapi.nat44_del_session(sessions[0].inside_ip_address,
3507 sessions[0].inside_port,
3508 sessions[0].protocol)
3510 self.verify_no_nat44_user()
3512 def test_set_get_reass(self):
3513 """ NAT44 set/get virtual fragmentation reassembly """
3514 reas_cfg1 = self.vapi.nat_get_reass()
3516 self.vapi.nat_set_reass(timeout=reas_cfg1.ip4_timeout + 5,
3517 max_reass=reas_cfg1.ip4_max_reass * 2,
3518 max_frag=reas_cfg1.ip4_max_frag * 2)
3520 reas_cfg2 = self.vapi.nat_get_reass()
3522 self.assertEqual(reas_cfg1.ip4_timeout + 5, reas_cfg2.ip4_timeout)
3523 self.assertEqual(reas_cfg1.ip4_max_reass * 2, reas_cfg2.ip4_max_reass)
3524 self.assertEqual(reas_cfg1.ip4_max_frag * 2, reas_cfg2.ip4_max_frag)
3526 self.vapi.nat_set_reass(drop_frag=1)
3527 self.assertTrue(self.vapi.nat_get_reass().ip4_drop_frag)
3529 def test_frag_in_order(self):
3530 """ NAT44 translate fragments arriving in order """
3532 self.nat44_add_address(self.nat_addr)
3533 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
3534 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
3537 self.frag_in_order(proto=IP_PROTOS.tcp)
3538 self.frag_in_order(proto=IP_PROTOS.udp)
3539 self.frag_in_order(proto=IP_PROTOS.icmp)
3541 def test_frag_forwarding(self):
3542 """ NAT44 forwarding fragment test """
3543 self.vapi.nat44_add_del_interface_addr(self.pg1.sw_if_index)
3544 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
3545 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
3547 self.vapi.nat44_forwarding_enable_disable(1)
3549 data = b"A" * 16 + b"B" * 16 + b"C" * 3
3550 pkts = self.create_stream_frag(self.pg1,
3551 self.pg0.remote_ip4,
3555 proto=IP_PROTOS.udp)
3556 self.pg1.add_stream(pkts)
3557 self.pg_enable_capture(self.pg_interfaces)
3559 frags = self.pg0.get_capture(len(pkts))
3560 p = self.reass_frags_and_verify(frags,
3561 self.pg1.remote_ip4,
3562 self.pg0.remote_ip4)
3563 self.assertEqual(p[UDP].sport, 4789)
3564 self.assertEqual(p[UDP].dport, 4789)
3565 self.assertEqual(data, p[Raw].load)
3567 def test_reass_hairpinning(self):
3568 """ NAT44 fragments hairpinning """
3570 self.server = self.pg0.remote_hosts[1]
3571 self.host_in_port = random.randint(1025, 65535)
3572 self.server_in_port = random.randint(1025, 65535)
3573 self.server_out_port = random.randint(1025, 65535)
3575 self.nat44_add_address(self.nat_addr)
3576 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
3577 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
3579 # add static mapping for server
3580 self.nat44_add_static_mapping(self.server.ip4, self.nat_addr,
3581 self.server_in_port,
3582 self.server_out_port,
3583 proto=IP_PROTOS.tcp)
3584 self.nat44_add_static_mapping(self.server.ip4, self.nat_addr,
3585 self.server_in_port,
3586 self.server_out_port,
3587 proto=IP_PROTOS.udp)
3588 self.nat44_add_static_mapping(self.server.ip4, self.nat_addr)
3590 self.reass_hairpinning(proto=IP_PROTOS.tcp)
3591 self.reass_hairpinning(proto=IP_PROTOS.udp)
3592 self.reass_hairpinning(proto=IP_PROTOS.icmp)
3594 def test_frag_out_of_order(self):
3595 """ NAT44 translate fragments arriving out of order """
3597 self.nat44_add_address(self.nat_addr)
3598 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
3599 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
3602 self.frag_out_of_order(proto=IP_PROTOS.tcp)
3603 self.frag_out_of_order(proto=IP_PROTOS.udp)
3604 self.frag_out_of_order(proto=IP_PROTOS.icmp)
3606 def test_port_restricted(self):
3607 """ Port restricted NAT44 (MAP-E CE) """
3608 self.nat44_add_address(self.nat_addr)
3609 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
3610 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
3612 self.vapi.nat_set_addr_and_port_alloc_alg(alg=1,
3617 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
3618 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
3619 TCP(sport=4567, dport=22))
3620 self.pg0.add_stream(p)
3621 self.pg_enable_capture(self.pg_interfaces)
3623 capture = self.pg1.get_capture(1)
3628 self.assertEqual(ip.dst, self.pg1.remote_ip4)
3629 self.assertEqual(ip.src, self.nat_addr)
3630 self.assertEqual(tcp.dport, 22)
3631 self.assertNotEqual(tcp.sport, 4567)
3632 self.assertEqual((tcp.sport >> 6) & 63, 10)
3633 self.assert_packet_checksums_valid(p)
3635 self.logger.error(ppp("Unexpected or invalid packet:", p))
3638 def test_port_range(self):
3639 """ External address port range """
3640 self.nat44_add_address(self.nat_addr)
3641 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
3642 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
3644 self.vapi.nat_set_addr_and_port_alloc_alg(alg=2,
3649 for port in range(0, 5):
3650 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
3651 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
3652 TCP(sport=1125 + port))
3654 self.pg0.add_stream(pkts)
3655 self.pg_enable_capture(self.pg_interfaces)
3657 capture = self.pg1.get_capture(3)
3660 self.assertGreaterEqual(tcp.sport, 1025)
3661 self.assertLessEqual(tcp.sport, 1027)
3663 def test_ipfix_max_frags(self):
3664 """ IPFIX logging maximum fragments pending reassembly exceeded """
3665 self.nat44_add_address(self.nat_addr)
3666 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
3667 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
3669 self.vapi.nat_set_reass(max_frag=1)
3670 self.vapi.set_ipfix_exporter(collector_address=self.pg3.remote_ip4n,
3671 src_address=self.pg3.local_ip4n,
3673 template_interval=10)
3674 self.vapi.nat_ipfix_enable_disable(domain_id=self.ipfix_domain_id,
3675 src_port=self.ipfix_src_port)
3677 data = b"A" * 4 + b"B" * 16 + b"C" * 3
3678 self.tcp_port_in = random.randint(1025, 65535)
3679 pkts = self.create_stream_frag(self.pg0,
3680 self.pg1.remote_ip4,
3685 self.pg0.add_stream(pkts)
3686 self.pg_enable_capture(self.pg_interfaces)
3688 self.pg1.assert_nothing_captured()
3690 self.vapi.cli("ipfix flush") # FIXME this should be an API call
3691 capture = self.pg3.get_capture(9)
3692 ipfix = IPFIXDecoder()
3693 # first load template
3695 self.assertTrue(p.haslayer(IPFIX))
3696 self.assertEqual(p[IP].src, self.pg3.local_ip4)
3697 self.assertEqual(p[IP].dst, self.pg3.remote_ip4)
3698 self.assertEqual(p[UDP].sport, self.ipfix_src_port)
3699 self.assertEqual(p[UDP].dport, 4739)
3700 self.assertEqual(p[IPFIX].observationDomainID,
3701 self.ipfix_domain_id)
3702 if p.haslayer(Template):
3703 ipfix.add_template(p.getlayer(Template))
3704 # verify events in data set
3706 if p.haslayer(Data):
3707 data = ipfix.decode_data_set(p.getlayer(Set))
3708 self.verify_ipfix_max_fragments_ip4(data, 1,
3709 self.pg0.remote_ip4n)
3711 def test_multiple_outside_vrf(self):
3712 """ Multiple outside VRF """
3716 self.pg1.unconfig_ip4()
3717 self.pg2.unconfig_ip4()
3718 self.vapi.ip_table_add_del(is_add=1, table_id=vrf_id1)
3719 self.vapi.ip_table_add_del(is_add=1, table_id=vrf_id2)
3720 self.pg1.set_table_ip4(vrf_id1)
3721 self.pg2.set_table_ip4(vrf_id2)
3722 self.pg1.config_ip4()
3723 self.pg2.config_ip4()
3724 self.pg1.resolve_arp()
3725 self.pg2.resolve_arp()
3727 self.nat44_add_address(self.nat_addr)
3728 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
3729 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
3731 self.vapi.nat44_interface_add_del_feature(self.pg2.sw_if_index,
3736 pkts = self.create_stream_in(self.pg0, self.pg1)
3737 self.pg0.add_stream(pkts)
3738 self.pg_enable_capture(self.pg_interfaces)
3740 capture = self.pg1.get_capture(len(pkts))
3741 self.verify_capture_out(capture, self.nat_addr)
3743 pkts = self.create_stream_out(self.pg1, self.nat_addr)
3744 self.pg1.add_stream(pkts)
3745 self.pg_enable_capture(self.pg_interfaces)
3747 capture = self.pg0.get_capture(len(pkts))
3748 self.verify_capture_in(capture, self.pg0)
3750 self.tcp_port_in = 60303
3751 self.udp_port_in = 60304
3752 self.icmp_id_in = 60305
3755 pkts = self.create_stream_in(self.pg0, self.pg2)
3756 self.pg0.add_stream(pkts)
3757 self.pg_enable_capture(self.pg_interfaces)
3759 capture = self.pg2.get_capture(len(pkts))
3760 self.verify_capture_out(capture, self.nat_addr)
3762 pkts = self.create_stream_out(self.pg2, self.nat_addr)
3763 self.pg2.add_stream(pkts)
3764 self.pg_enable_capture(self.pg_interfaces)
3766 capture = self.pg0.get_capture(len(pkts))
3767 self.verify_capture_in(capture, self.pg0)
3770 self.pg1.unconfig_ip4()
3771 self.pg2.unconfig_ip4()
3772 self.pg1.set_table_ip4(0)
3773 self.pg2.set_table_ip4(0)
3774 self.pg1.config_ip4()
3775 self.pg2.config_ip4()
3776 self.pg1.resolve_arp()
3777 self.pg2.resolve_arp()
3779 @unittest.skipUnless(running_extended_tests, "part of extended tests")
3780 def test_session_timeout(self):
3781 """ NAT44 session timeouts """
3782 self.nat44_add_address(self.nat_addr)
3783 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
3784 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
3786 self.vapi.nat_set_timeouts(udp=5)
3790 for i in range(0, max_sessions):
3791 src = "10.10.%u.%u" % ((i & 0xFF00) >> 8, i & 0xFF)
3792 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
3793 IP(src=src, dst=self.pg1.remote_ip4) /
3794 UDP(sport=1025, dport=53))
3796 self.pg0.add_stream(pkts)
3797 self.pg_enable_capture(self.pg_interfaces)
3799 self.pg1.get_capture(max_sessions)
3804 for i in range(0, max_sessions):
3805 src = "10.10.%u.%u" % ((i & 0xFF00) >> 8, i & 0xFF)
3806 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
3807 IP(src=src, dst=self.pg1.remote_ip4) /
3808 UDP(sport=1026, dport=53))
3810 self.pg0.add_stream(pkts)
3811 self.pg_enable_capture(self.pg_interfaces)
3813 self.pg1.get_capture(max_sessions)
3816 users = self.vapi.nat44_user_dump()
3818 nsessions = nsessions + user.nsessions
3819 self.assertLess(nsessions, 2 * max_sessions)
3821 def test_mss_clamping(self):
3822 """ TCP MSS clamping """
3823 self.nat44_add_address(self.nat_addr)
3824 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
3825 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
3828 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
3829 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
3830 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
3831 flags="S", options=[('MSS', 1400)]))
3833 self.vapi.nat_set_mss_clamping(enable=1, mss_value=1000)
3834 self.pg0.add_stream(p)
3835 self.pg_enable_capture(self.pg_interfaces)
3837 capture = self.pg1.get_capture(1)
3838 # Negotiated MSS value greater than configured - changed
3839 self.verify_mss_value(capture[0], 1000)
3841 self.vapi.nat_set_mss_clamping(enable=0)
3842 self.pg0.add_stream(p)
3843 self.pg_enable_capture(self.pg_interfaces)
3845 capture = self.pg1.get_capture(1)
3846 # MSS clamping disabled - negotiated MSS unchanged
3847 self.verify_mss_value(capture[0], 1400)
3849 self.vapi.nat_set_mss_clamping(enable=1, mss_value=1500)
3850 self.pg0.add_stream(p)
3851 self.pg_enable_capture(self.pg_interfaces)
3853 capture = self.pg1.get_capture(1)
3854 # Negotiated MSS value smaller than configured - unchanged
3855 self.verify_mss_value(capture[0], 1400)
3857 @unittest.skipUnless(running_extended_tests, "part of extended tests")
3858 def test_ha_send(self):
3859 """ Send HA session synchronization events (active) """
3860 self.nat44_add_address(self.nat_addr)
3861 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
3862 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
3864 self.vapi.nat_ha_set_listener(self.pg3.local_ip4, port=12345)
3865 self.vapi.nat_ha_set_failover(self.pg3.remote_ip4, port=12346)
3866 bind_layers(UDP, HANATStateSync, sport=12345)
3869 pkts = self.create_stream_in(self.pg0, self.pg1)
3870 self.pg0.add_stream(pkts)
3871 self.pg_enable_capture(self.pg_interfaces)
3873 capture = self.pg1.get_capture(len(pkts))
3874 self.verify_capture_out(capture)
3875 # active send HA events
3876 self.vapi.nat_ha_flush()
3877 stats = self.statistics.get_counter('/nat44/ha/add-event-send')
3878 self.assertEqual(stats[0][0], 3)
3879 capture = self.pg3.get_capture(1)
3881 self.assert_packet_checksums_valid(p)
3885 hanat = p[HANATStateSync]
3887 self.logger.error(ppp("Invalid packet:", p))
3890 self.assertEqual(ip.src, self.pg3.local_ip4)
3891 self.assertEqual(ip.dst, self.pg3.remote_ip4)
3892 self.assertEqual(udp.sport, 12345)
3893 self.assertEqual(udp.dport, 12346)
3894 self.assertEqual(hanat.version, 1)
3895 self.assertEqual(hanat.thread_index, 0)
3896 self.assertEqual(hanat.count, 3)
3897 seq = hanat.sequence_number
3898 for event in hanat.events:
3899 self.assertEqual(event.event_type, 1)
3900 self.assertEqual(event.in_addr, self.pg0.remote_ip4)
3901 self.assertEqual(event.out_addr, self.nat_addr)
3902 self.assertEqual(event.fib_index, 0)
3904 # ACK received events
3905 ack = (Ether(dst=self.pg3.local_mac, src=self.pg3.remote_mac) /
3906 IP(src=self.pg3.remote_ip4, dst=self.pg3.local_ip4) /
3907 UDP(sport=12346, dport=12345) /
3908 HANATStateSync(sequence_number=seq, flags='ACK'))
3909 self.pg3.add_stream(ack)
3911 stats = self.statistics.get_counter('/nat44/ha/ack-recv')
3912 self.assertEqual(stats[0][0], 1)
3914 # delete one session
3915 self.pg_enable_capture(self.pg_interfaces)
3916 self.vapi.nat44_del_session(self.pg0.remote_ip4n, self.tcp_port_in,
3918 self.vapi.nat_ha_flush()
3919 stats = self.statistics.get_counter('/nat44/ha/del-event-send')
3920 self.assertEqual(stats[0][0], 1)
3921 capture = self.pg3.get_capture(1)
3924 hanat = p[HANATStateSync]
3926 self.logger.error(ppp("Invalid packet:", p))
3929 self.assertGreater(hanat.sequence_number, seq)
3931 # do not send ACK, active retry send HA event again
3932 self.pg_enable_capture(self.pg_interfaces)
3934 stats = self.statistics.get_counter('/nat44/ha/retry-count')
3935 self.assertEqual(stats[0][0], 3)
3936 stats = self.statistics.get_counter('/nat44/ha/missed-count')
3937 self.assertEqual(stats[0][0], 1)
3938 capture = self.pg3.get_capture(3)
3939 for packet in capture:
3940 self.assertEqual(packet, p)
3942 # session counters refresh
3943 pkts = self.create_stream_out(self.pg1)
3944 self.pg1.add_stream(pkts)
3945 self.pg_enable_capture(self.pg_interfaces)
3947 self.pg0.get_capture(2)
3948 self.vapi.nat_ha_flush()
3949 stats = self.statistics.get_counter('/nat44/ha/refresh-event-send')
3950 self.assertEqual(stats[0][0], 2)
3951 capture = self.pg3.get_capture(1)
3953 self.assert_packet_checksums_valid(p)
3957 hanat = p[HANATStateSync]
3959 self.logger.error(ppp("Invalid packet:", p))
3962 self.assertEqual(ip.src, self.pg3.local_ip4)
3963 self.assertEqual(ip.dst, self.pg3.remote_ip4)
3964 self.assertEqual(udp.sport, 12345)
3965 self.assertEqual(udp.dport, 12346)
3966 self.assertEqual(hanat.version, 1)
3967 self.assertEqual(hanat.count, 2)
3968 seq = hanat.sequence_number
3969 for event in hanat.events:
3970 self.assertEqual(event.event_type, 3)
3971 self.assertEqual(event.out_addr, self.nat_addr)
3972 self.assertEqual(event.fib_index, 0)
3973 self.assertEqual(event.total_pkts, 2)
3974 self.assertGreater(event.total_bytes, 0)
3976 ack = (Ether(dst=self.pg3.local_mac, src=self.pg3.remote_mac) /
3977 IP(src=self.pg3.remote_ip4, dst=self.pg3.local_ip4) /
3978 UDP(sport=12346, dport=12345) /
3979 HANATStateSync(sequence_number=seq, flags='ACK'))
3980 self.pg3.add_stream(ack)
3982 stats = self.statistics.get_counter('/nat44/ha/ack-recv')
3983 self.assertEqual(stats[0][0], 2)
3985 def test_ha_recv(self):
3986 """ Receive HA session synchronization events (passive) """
3987 self.nat44_add_address(self.nat_addr)
3988 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
3989 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
3991 self.vapi.nat_ha_set_listener(self.pg3.local_ip4, port=12345)
3992 bind_layers(UDP, HANATStateSync, sport=12345)
3994 self.tcp_port_out = random.randint(1025, 65535)
3995 self.udp_port_out = random.randint(1025, 65535)
3997 # send HA session add events to failover/passive
3998 p = (Ether(dst=self.pg3.local_mac, src=self.pg3.remote_mac) /
3999 IP(src=self.pg3.remote_ip4, dst=self.pg3.local_ip4) /
4000 UDP(sport=12346, dport=12345) /
4001 HANATStateSync(sequence_number=1, events=[
4002 Event(event_type='add', protocol='tcp',
4003 in_addr=self.pg0.remote_ip4, out_addr=self.nat_addr,
4004 in_port=self.tcp_port_in, out_port=self.tcp_port_out,
4005 eh_addr=self.pg1.remote_ip4,
4006 ehn_addr=self.pg1.remote_ip4,
4007 eh_port=self.tcp_external_port,
4008 ehn_port=self.tcp_external_port, fib_index=0),
4009 Event(event_type='add', protocol='udp',
4010 in_addr=self.pg0.remote_ip4, out_addr=self.nat_addr,
4011 in_port=self.udp_port_in, out_port=self.udp_port_out,
4012 eh_addr=self.pg1.remote_ip4,
4013 ehn_addr=self.pg1.remote_ip4,
4014 eh_port=self.udp_external_port,
4015 ehn_port=self.udp_external_port, fib_index=0)]))
4017 self.pg3.add_stream(p)
4018 self.pg_enable_capture(self.pg_interfaces)
4021 capture = self.pg3.get_capture(1)
4024 hanat = p[HANATStateSync]
4026 self.logger.error(ppp("Invalid packet:", p))
4029 self.assertEqual(hanat.sequence_number, 1)
4030 self.assertEqual(hanat.flags, 'ACK')
4031 self.assertEqual(hanat.version, 1)
4032 self.assertEqual(hanat.thread_index, 0)
4033 stats = self.statistics.get_counter('/nat44/ha/ack-send')
4034 self.assertEqual(stats[0][0], 1)
4035 stats = self.statistics.get_counter('/nat44/ha/add-event-recv')
4036 self.assertEqual(stats[0][0], 2)
4037 users = self.statistics.get_counter('/nat44/total-users')
4038 self.assertEqual(users[0][0], 1)
4039 sessions = self.statistics.get_counter('/nat44/total-sessions')
4040 self.assertEqual(sessions[0][0], 2)
4041 users = self.vapi.nat44_user_dump()
4042 self.assertEqual(len(users), 1)
4043 self.assertEqual(users[0].ip_address, self.pg0.remote_ip4n)
4044 # there should be 2 sessions created by HA
4045 sessions = self.vapi.nat44_user_session_dump(users[0].ip_address,
4047 self.assertEqual(len(sessions), 2)
4048 for session in sessions:
4049 self.assertEqual(session.inside_ip_address, self.pg0.remote_ip4n)
4050 self.assertEqual(session.outside_ip_address, self.nat_addr_n)
4051 self.assertIn(session.inside_port,
4052 [self.tcp_port_in, self.udp_port_in])
4053 self.assertIn(session.outside_port,
4054 [self.tcp_port_out, self.udp_port_out])
4055 self.assertIn(session.protocol, [IP_PROTOS.tcp, IP_PROTOS.udp])
4057 # send HA session delete event to failover/passive
4058 p = (Ether(dst=self.pg3.local_mac, src=self.pg3.remote_mac) /
4059 IP(src=self.pg3.remote_ip4, dst=self.pg3.local_ip4) /
4060 UDP(sport=12346, dport=12345) /
4061 HANATStateSync(sequence_number=2, events=[
4062 Event(event_type='del', protocol='udp',
4063 in_addr=self.pg0.remote_ip4, out_addr=self.nat_addr,
4064 in_port=self.udp_port_in, out_port=self.udp_port_out,
4065 eh_addr=self.pg1.remote_ip4,
4066 ehn_addr=self.pg1.remote_ip4,
4067 eh_port=self.udp_external_port,
4068 ehn_port=self.udp_external_port, fib_index=0)]))
4070 self.pg3.add_stream(p)
4071 self.pg_enable_capture(self.pg_interfaces)
4074 capture = self.pg3.get_capture(1)
4077 hanat = p[HANATStateSync]
4079 self.logger.error(ppp("Invalid packet:", p))
4082 self.assertEqual(hanat.sequence_number, 2)
4083 self.assertEqual(hanat.flags, 'ACK')
4084 self.assertEqual(hanat.version, 1)
4085 users = self.vapi.nat44_user_dump()
4086 self.assertEqual(len(users), 1)
4087 self.assertEqual(users[0].ip_address, self.pg0.remote_ip4n)
4088 # now we should have only 1 session, 1 deleted by HA
4089 sessions = self.vapi.nat44_user_session_dump(users[0].ip_address,
4091 self.assertEqual(len(sessions), 1)
4092 stats = self.statistics.get_counter('/nat44/ha/del-event-recv')
4093 self.assertEqual(stats[0][0], 1)
4095 stats = self.statistics.get_counter('/err/nat-ha/pkts-processed')
4096 self.assertEqual(stats, 2)
4098 # send HA session refresh event to failover/passive
4099 p = (Ether(dst=self.pg3.local_mac, src=self.pg3.remote_mac) /
4100 IP(src=self.pg3.remote_ip4, dst=self.pg3.local_ip4) /
4101 UDP(sport=12346, dport=12345) /
4102 HANATStateSync(sequence_number=3, events=[
4103 Event(event_type='refresh', protocol='tcp',
4104 in_addr=self.pg0.remote_ip4, out_addr=self.nat_addr,
4105 in_port=self.tcp_port_in, out_port=self.tcp_port_out,
4106 eh_addr=self.pg1.remote_ip4,
4107 ehn_addr=self.pg1.remote_ip4,
4108 eh_port=self.tcp_external_port,
4109 ehn_port=self.tcp_external_port, fib_index=0,
4110 total_bytes=1024, total_pkts=2)]))
4111 self.pg3.add_stream(p)
4112 self.pg_enable_capture(self.pg_interfaces)
4115 capture = self.pg3.get_capture(1)
4118 hanat = p[HANATStateSync]
4120 self.logger.error(ppp("Invalid packet:", p))
4123 self.assertEqual(hanat.sequence_number, 3)
4124 self.assertEqual(hanat.flags, 'ACK')
4125 self.assertEqual(hanat.version, 1)
4126 users = self.vapi.nat44_user_dump()
4127 self.assertEqual(len(users), 1)
4128 self.assertEqual(users[0].ip_address, self.pg0.remote_ip4n)
4129 sessions = self.vapi.nat44_user_session_dump(users[0].ip_address,
4131 self.assertEqual(len(sessions), 1)
4132 session = sessions[0]
4133 self.assertEqual(session.total_bytes, 1024)
4134 self.assertEqual(session.total_pkts, 2)
4135 stats = self.statistics.get_counter('/nat44/ha/refresh-event-recv')
4136 self.assertEqual(stats[0][0], 1)
4138 stats = self.statistics.get_counter('/err/nat-ha/pkts-processed')
4139 self.assertEqual(stats, 3)
4141 # send packet to test session created by HA
4142 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
4143 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
4144 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out))
4145 self.pg1.add_stream(p)
4146 self.pg_enable_capture(self.pg_interfaces)
4148 capture = self.pg0.get_capture(1)
4154 self.logger.error(ppp("Invalid packet:", p))
4157 self.assertEqual(ip.src, self.pg1.remote_ip4)
4158 self.assertEqual(ip.dst, self.pg0.remote_ip4)
4159 self.assertEqual(tcp.sport, self.tcp_external_port)
4160 self.assertEqual(tcp.dport, self.tcp_port_in)
4163 super(TestNAT44, self).tearDown()
4165 self.vapi.cli("clear logging")
4167 def show_commands_at_teardown(self):
4168 self.logger.info(self.vapi.cli("show nat44 addresses"))
4169 self.logger.info(self.vapi.cli("show nat44 interfaces"))
4170 self.logger.info(self.vapi.cli("show nat44 static mappings"))
4171 self.logger.info(self.vapi.cli("show nat44 interface address"))
4172 self.logger.info(self.vapi.cli("show nat44 sessions detail"))
4173 self.logger.info(self.vapi.cli("show nat virtual-reassembly"))
4174 self.logger.info(self.vapi.cli("show nat44 hash tables detail"))
4175 self.logger.info(self.vapi.cli("show nat timeouts"))
4177 self.vapi.cli("show nat addr-port-assignment-alg"))
4178 self.logger.info(self.vapi.cli("show nat ha"))
4181 class TestNAT44EndpointDependent(MethodHolder):
4182 """ Endpoint-Dependent mapping and filtering test cases """
4185 def setUpConstants(cls):
4186 super(TestNAT44EndpointDependent, cls).setUpConstants()
4187 cls.vpp_cmdline.extend(["nat", "{", "endpoint-dependent", "}"])
4190 def setUpClass(cls):
4191 super(TestNAT44EndpointDependent, cls).setUpClass()
4192 cls.vapi.cli("set log class nat level debug")
4194 cls.tcp_port_in = 6303
4195 cls.tcp_port_out = 6303
4196 cls.udp_port_in = 6304
4197 cls.udp_port_out = 6304
4198 cls.icmp_id_in = 6305
4199 cls.icmp_id_out = 6305
4200 cls.nat_addr = '10.0.0.3'
4201 cls.nat_addr_n = socket.inet_pton(socket.AF_INET, cls.nat_addr)
4202 cls.ipfix_src_port = 4739
4203 cls.ipfix_domain_id = 1
4204 cls.tcp_external_port = 80
4206 cls.create_pg_interfaces(range(7))
4207 cls.interfaces = list(cls.pg_interfaces[0:3])
4209 for i in cls.interfaces:
4214 cls.pg0.generate_remote_hosts(3)
4215 cls.pg0.configure_ipv4_neighbors()
4219 cls.pg4.generate_remote_hosts(2)
4220 cls.pg4.config_ip4()
4221 ip_addr_n = socket.inet_pton(socket.AF_INET, "10.0.0.1")
4222 cls.vapi.sw_interface_add_del_address(
4223 sw_if_index=cls.pg4.sw_if_index, address=ip_addr_n,
4226 cls.pg4.resolve_arp()
4227 cls.pg4._remote_hosts[1]._ip4 = cls.pg4._remote_hosts[0]._ip4
4228 cls.pg4.resolve_arp()
4230 zero_ip4n = socket.inet_pton(socket.AF_INET, "0.0.0.0")
4231 cls.vapi.ip_table_add_del(is_add=1, table_id=1)
4233 cls.pg5._local_ip4 = "10.1.1.1"
4234 cls.pg5._local_ip4n = socket.inet_pton(socket.AF_INET,
4236 cls.pg5._remote_hosts[0]._ip4 = "10.1.1.2"
4237 cls.pg5._remote_hosts[0]._ip4n = socket.inet_pton(
4238 socket.AF_INET, cls.pg5.remote_ip4)
4239 cls.pg5.set_table_ip4(1)
4240 cls.pg5.config_ip4()
4242 cls.vapi.ip_add_del_route(dst_address=cls.pg5.remote_ip4n,
4243 dst_address_length=32,
4244 next_hop_address=zero_ip4n,
4245 next_hop_sw_if_index=cls.pg5.sw_if_index,
4248 cls.pg6._local_ip4 = "10.1.2.1"
4249 cls.pg6._local_ip4n = socket.inet_pton(socket.AF_INET,
4251 cls.pg6._remote_hosts[0]._ip4 = "10.1.2.2"
4252 cls.pg6._remote_hosts[0]._ip4n = socket.inet_pton(
4253 socket.AF_INET, cls.pg6.remote_ip4)
4254 cls.pg6.set_table_ip4(1)
4255 cls.pg6.config_ip4()
4257 cls.vapi.ip_add_del_route(dst_address=cls.pg6.remote_ip4n,
4258 dst_address_length=32,
4259 next_hop_address=zero_ip4n,
4260 next_hop_sw_if_index=cls.pg6.sw_if_index,
4263 cls.vapi.ip_add_del_route(dst_address=cls.pg6.remote_ip4n,
4264 dst_address_length=16,
4265 next_hop_address=zero_ip4n, table_id=0,
4266 next_hop_table_id=1)
4267 cls.vapi.ip_add_del_route(dst_address=zero_ip4n,
4268 dst_address_length=0,
4269 next_hop_address=zero_ip4n, table_id=1,
4270 next_hop_table_id=0)
4271 cls.vapi.ip_add_del_route(dst_address=zero_ip4n,
4272 dst_address_length=0,
4273 next_hop_address=cls.pg1.local_ip4n,
4274 next_hop_sw_if_index=cls.pg1.sw_if_index,
4277 cls.pg5.resolve_arp()
4278 cls.pg6.resolve_arp()
4281 super(TestNAT44EndpointDependent, cls).tearDownClass()
4285 def tearDownClass(cls):
4286 super(TestNAT44EndpointDependent, cls).tearDownClass()
4288 def test_frag_in_order(self):
4289 """ NAT44 translate fragments arriving in order """
4290 self.nat44_add_address(self.nat_addr)
4291 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
4292 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
4294 self.frag_in_order(proto=IP_PROTOS.tcp)
4295 self.frag_in_order(proto=IP_PROTOS.udp)
4296 self.frag_in_order(proto=IP_PROTOS.icmp)
4298 def test_frag_in_order_dont_translate(self):
4299 """ NAT44 don't translate fragments arriving in order """
4300 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
4301 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
4303 self.vapi.nat44_forwarding_enable_disable(enable=True)
4304 self.frag_in_order(proto=IP_PROTOS.tcp, dont_translate=True)
4306 def test_frag_out_of_order(self):
4307 """ NAT44 translate fragments arriving out of order """
4308 self.nat44_add_address(self.nat_addr)
4309 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
4310 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
4312 self.frag_out_of_order(proto=IP_PROTOS.tcp)
4313 self.frag_out_of_order(proto=IP_PROTOS.udp)
4314 self.frag_out_of_order(proto=IP_PROTOS.icmp)
4316 def test_frag_out_of_order_dont_translate(self):
4317 """ NAT44 don't translate fragments arriving out of order """
4318 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
4319 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
4321 self.vapi.nat44_forwarding_enable_disable(enable=True)
4322 self.frag_out_of_order(proto=IP_PROTOS.tcp, dont_translate=True)
4324 def test_frag_in_order_in_plus_out(self):
4325 """ in+out interface fragments in order """
4326 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
4327 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index,
4329 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index)
4330 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
4333 self.server = self.pg1.remote_hosts[0]
4335 self.server_in_addr = self.server.ip4
4336 self.server_out_addr = '11.11.11.11'
4337 self.server_in_port = random.randint(1025, 65535)
4338 self.server_out_port = random.randint(1025, 65535)
4340 self.nat44_add_address(self.server_out_addr)
4342 # add static mappings for server
4343 self.nat44_add_static_mapping(self.server_in_addr,
4344 self.server_out_addr,
4345 self.server_in_port,
4346 self.server_out_port,
4347 proto=IP_PROTOS.tcp)
4348 self.nat44_add_static_mapping(self.server_in_addr,
4349 self.server_out_addr,
4350 self.server_in_port,
4351 self.server_out_port,
4352 proto=IP_PROTOS.udp)
4353 self.nat44_add_static_mapping(self.server_in_addr,
4354 self.server_out_addr,
4355 proto=IP_PROTOS.icmp)
4357 self.vapi.nat_set_reass(timeout=10)
4359 self.frag_in_order_in_plus_out(proto=IP_PROTOS.tcp)
4360 self.frag_in_order_in_plus_out(proto=IP_PROTOS.udp)
4361 self.frag_in_order_in_plus_out(proto=IP_PROTOS.icmp)
4363 def test_frag_out_of_order_in_plus_out(self):
4364 """ in+out interface fragments out of order """
4365 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
4366 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index,
4368 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index)
4369 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
4372 self.server = self.pg1.remote_hosts[0]
4374 self.server_in_addr = self.server.ip4
4375 self.server_out_addr = '11.11.11.11'
4376 self.server_in_port = random.randint(1025, 65535)
4377 self.server_out_port = random.randint(1025, 65535)
4379 self.nat44_add_address(self.server_out_addr)
4381 # add static mappings for server
4382 self.nat44_add_static_mapping(self.server_in_addr,
4383 self.server_out_addr,
4384 self.server_in_port,
4385 self.server_out_port,
4386 proto=IP_PROTOS.tcp)
4387 self.nat44_add_static_mapping(self.server_in_addr,
4388 self.server_out_addr,
4389 self.server_in_port,
4390 self.server_out_port,
4391 proto=IP_PROTOS.udp)
4392 self.nat44_add_static_mapping(self.server_in_addr,
4393 self.server_out_addr,
4394 proto=IP_PROTOS.icmp)
4396 self.vapi.nat_set_reass(timeout=10)
4398 self.frag_out_of_order_in_plus_out(proto=IP_PROTOS.tcp)
4399 self.frag_out_of_order_in_plus_out(proto=IP_PROTOS.udp)
4400 self.frag_out_of_order_in_plus_out(proto=IP_PROTOS.icmp)
4402 def test_reass_hairpinning(self):
4403 """ NAT44 fragments hairpinning """
4404 self.server = self.pg0.remote_hosts[1]
4405 self.host_in_port = random.randint(1025, 65535)
4406 self.server_in_port = random.randint(1025, 65535)
4407 self.server_out_port = random.randint(1025, 65535)
4409 self.nat44_add_address(self.nat_addr)
4410 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
4411 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
4413 # add static mapping for server
4414 self.nat44_add_static_mapping(self.server.ip4, self.nat_addr,
4415 self.server_in_port,
4416 self.server_out_port,
4417 proto=IP_PROTOS.tcp)
4418 self.nat44_add_static_mapping(self.server.ip4, self.nat_addr,
4419 self.server_in_port,
4420 self.server_out_port,
4421 proto=IP_PROTOS.udp)
4422 self.nat44_add_static_mapping(self.server.ip4, self.nat_addr)
4424 self.reass_hairpinning(proto=IP_PROTOS.tcp)
4425 self.reass_hairpinning(proto=IP_PROTOS.udp)
4426 self.reass_hairpinning(proto=IP_PROTOS.icmp)
4428 def test_dynamic(self):
4429 """ NAT44 dynamic translation test """
4431 self.nat44_add_address(self.nat_addr)
4432 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
4433 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
4436 nat_config = self.vapi.nat_show_config()
4437 self.assertEqual(1, nat_config.endpoint_dependent)
4440 tcpn = self.statistics.get_counter(
4441 '/err/nat44-ed-in2out-slowpath/TCP packets')
4442 udpn = self.statistics.get_counter(
4443 '/err/nat44-ed-in2out-slowpath/UDP packets')
4444 icmpn = self.statistics.get_counter(
4445 '/err/nat44-ed-in2out-slowpath/ICMP packets')
4446 totaln = self.statistics.get_counter(
4447 '/err/nat44-ed-in2out-slowpath/good in2out packets processed')
4449 pkts = self.create_stream_in(self.pg0, self.pg1)
4450 self.pg0.add_stream(pkts)
4451 self.pg_enable_capture(self.pg_interfaces)
4453 capture = self.pg1.get_capture(len(pkts))
4454 self.verify_capture_out(capture)
4456 err = self.statistics.get_counter(
4457 '/err/nat44-ed-in2out-slowpath/TCP packets')
4458 self.assertEqual(err - tcpn, 1)
4459 err = self.statistics.get_counter(
4460 '/err/nat44-ed-in2out-slowpath/UDP packets')
4461 self.assertEqual(err - udpn, 1)
4462 err = self.statistics.get_counter(
4463 '/err/nat44-ed-in2out-slowpath/ICMP packets')
4464 self.assertEqual(err - icmpn, 1)
4465 err = self.statistics.get_counter(
4466 '/err/nat44-ed-in2out-slowpath/good in2out packets processed')
4467 self.assertEqual(err - totaln, 3)
4470 tcpn = self.statistics.get_counter('/err/nat44-ed-out2in/TCP packets')
4471 udpn = self.statistics.get_counter('/err/nat44-ed-out2in/UDP packets')
4472 icmpn = self.statistics.get_counter(
4473 '/err/nat44-ed-out2in-slowpath/ICMP packets')
4474 totaln = self.statistics.get_counter(
4475 '/err/nat44-ed-out2in/good out2in packets processed')
4477 pkts = self.create_stream_out(self.pg1)
4478 self.pg1.add_stream(pkts)
4479 self.pg_enable_capture(self.pg_interfaces)
4481 capture = self.pg0.get_capture(len(pkts))
4482 self.verify_capture_in(capture, self.pg0)
4484 err = self.statistics.get_counter('/err/nat44-ed-out2in/TCP packets')
4485 self.assertEqual(err - tcpn, 1)
4486 err = self.statistics.get_counter('/err/nat44-ed-out2in/UDP packets')
4487 self.assertEqual(err - udpn, 1)
4488 err = self.statistics.get_counter(
4489 '/err/nat44-ed-out2in-slowpath/ICMP packets')
4490 self.assertEqual(err - icmpn, 1)
4491 err = self.statistics.get_counter(
4492 '/err/nat44-ed-out2in/good out2in packets processed')
4493 self.assertEqual(err - totaln, 2)
4495 users = self.statistics.get_counter('/nat44/total-users')
4496 self.assertEqual(users[0][0], 1)
4497 sessions = self.statistics.get_counter('/nat44/total-sessions')
4498 self.assertEqual(sessions[0][0], 3)
4500 def test_forwarding(self):
4501 """ NAT44 forwarding test """
4503 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
4504 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
4506 self.vapi.nat44_forwarding_enable_disable(1)
4508 real_ip = self.pg0.remote_ip4n
4509 alias_ip = self.nat_addr_n
4510 self.vapi.nat44_add_del_static_mapping(local_ip=real_ip,
4511 external_ip=alias_ip)
4514 # in2out - static mapping match
4516 pkts = self.create_stream_out(self.pg1)
4517 self.pg1.add_stream(pkts)
4518 self.pg_enable_capture(self.pg_interfaces)
4520 capture = self.pg0.get_capture(len(pkts))
4521 self.verify_capture_in(capture, self.pg0)
4523 pkts = self.create_stream_in(self.pg0, self.pg1)
4524 self.pg0.add_stream(pkts)
4525 self.pg_enable_capture(self.pg_interfaces)
4527 capture = self.pg1.get_capture(len(pkts))
4528 self.verify_capture_out(capture, same_port=True)
4530 # in2out - no static mapping match
4532 host0 = self.pg0.remote_hosts[0]
4533 self.pg0.remote_hosts[0] = self.pg0.remote_hosts[1]
4535 pkts = self.create_stream_out(self.pg1,
4536 dst_ip=self.pg0.remote_ip4,
4537 use_inside_ports=True)
4538 self.pg1.add_stream(pkts)
4539 self.pg_enable_capture(self.pg_interfaces)
4541 capture = self.pg0.get_capture(len(pkts))
4542 self.verify_capture_in(capture, self.pg0)
4544 pkts = self.create_stream_in(self.pg0, self.pg1)
4545 self.pg0.add_stream(pkts)
4546 self.pg_enable_capture(self.pg_interfaces)
4548 capture = self.pg1.get_capture(len(pkts))
4549 self.verify_capture_out(capture, nat_ip=self.pg0.remote_ip4,
4552 self.pg0.remote_hosts[0] = host0
4554 user = self.pg0.remote_hosts[1]
4555 sessions = self.vapi.nat44_user_session_dump(user.ip4n, 0)
4556 self.assertEqual(len(sessions), 3)
4557 self.assertTrue(sessions[0].ext_host_valid)
4558 self.vapi.nat44_del_session(
4559 sessions[0].inside_ip_address,
4560 sessions[0].inside_port,
4561 sessions[0].protocol,
4562 ext_host_address=sessions[0].ext_host_address,
4563 ext_host_port=sessions[0].ext_host_port)
4564 sessions = self.vapi.nat44_user_session_dump(user.ip4n, 0)
4565 self.assertEqual(len(sessions), 2)
4568 self.vapi.nat44_forwarding_enable_disable(0)
4569 self.vapi.nat44_add_del_static_mapping(local_ip=real_ip,
4570 external_ip=alias_ip,
4573 def test_static_lb(self):
4574 """ NAT44 local service load balancing """
4575 external_addr_n = socket.inet_pton(socket.AF_INET, self.nat_addr)
4578 server1 = self.pg0.remote_hosts[0]
4579 server2 = self.pg0.remote_hosts[1]
4581 locals = [{'addr': server1.ip4n,
4585 {'addr': server2.ip4n,
4590 self.nat44_add_address(self.nat_addr)
4591 self.vapi.nat44_add_del_lb_static_mapping(external_addr_n,
4594 local_num=len(locals),
4596 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
4597 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
4600 # from client to service
4601 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
4602 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
4603 TCP(sport=12345, dport=external_port))
4604 self.pg1.add_stream(p)
4605 self.pg_enable_capture(self.pg_interfaces)
4607 capture = self.pg0.get_capture(1)
4613 self.assertIn(ip.dst, [server1.ip4, server2.ip4])
4614 if ip.dst == server1.ip4:
4618 self.assertEqual(tcp.dport, local_port)
4619 self.assert_packet_checksums_valid(p)
4621 self.logger.error(ppp("Unexpected or invalid packet:", p))
4624 # from service back to client
4625 p = (Ether(src=server.mac, dst=self.pg0.local_mac) /
4626 IP(src=server.ip4, dst=self.pg1.remote_ip4) /
4627 TCP(sport=local_port, dport=12345))
4628 self.pg0.add_stream(p)
4629 self.pg_enable_capture(self.pg_interfaces)
4631 capture = self.pg1.get_capture(1)
4636 self.assertEqual(ip.src, self.nat_addr)
4637 self.assertEqual(tcp.sport, external_port)
4638 self.assert_packet_checksums_valid(p)
4640 self.logger.error(ppp("Unexpected or invalid packet:", p))
4643 sessions = self.vapi.nat44_user_session_dump(server.ip4n, 0)
4644 self.assertEqual(len(sessions), 1)
4645 self.assertTrue(sessions[0].ext_host_valid)
4646 self.vapi.nat44_del_session(
4647 sessions[0].inside_ip_address,
4648 sessions[0].inside_port,
4649 sessions[0].protocol,
4650 ext_host_address=sessions[0].ext_host_address,
4651 ext_host_port=sessions[0].ext_host_port)
4652 sessions = self.vapi.nat44_user_session_dump(server.ip4n, 0)
4653 self.assertEqual(len(sessions), 0)
4655 @unittest.skipUnless(running_extended_tests, "part of extended tests")
4656 def test_static_lb_multi_clients(self):
4657 """ NAT44 local service load balancing - multiple clients"""
4659 external_addr_n = socket.inet_pton(socket.AF_INET, self.nat_addr)
4662 server1 = self.pg0.remote_hosts[0]
4663 server2 = self.pg0.remote_hosts[1]
4664 server3 = self.pg0.remote_hosts[2]
4666 locals = [{'addr': server1.ip4n,
4670 {'addr': server2.ip4n,
4675 self.nat44_add_address(self.nat_addr)
4676 self.vapi.nat44_add_del_lb_static_mapping(external_addr_n,
4679 local_num=len(locals),
4681 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
4682 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
4687 clients = ip4_range(self.pg1.remote_ip4, 10, 50)
4689 for client in clients:
4690 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
4691 IP(src=client, dst=self.nat_addr) /
4692 TCP(sport=12345, dport=external_port))
4694 self.pg1.add_stream(pkts)
4695 self.pg_enable_capture(self.pg_interfaces)
4697 capture = self.pg0.get_capture(len(pkts))
4699 if p[IP].dst == server1.ip4:
4703 self.assertGreater(server1_n, server2_n)
4706 self.vapi.nat44_lb_static_mapping_add_del_local(external_addr_n,
4715 clients = ip4_range(self.pg1.remote_ip4, 60, 110)
4717 for client in clients:
4718 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
4719 IP(src=client, dst=self.nat_addr) /
4720 TCP(sport=12346, dport=external_port))
4722 self.assertGreater(len(pkts), 0)
4723 self.pg1.add_stream(pkts)
4724 self.pg_enable_capture(self.pg_interfaces)
4726 capture = self.pg0.get_capture(len(pkts))
4728 if p[IP].dst == server1.ip4:
4730 elif p[IP].dst == server2.ip4:
4734 self.assertGreater(server1_n, 0)
4735 self.assertGreater(server2_n, 0)
4736 self.assertGreater(server3_n, 0)
4738 # remove one back-end
4739 self.vapi.nat44_lb_static_mapping_add_del_local(external_addr_n,
4749 self.pg1.add_stream(pkts)
4750 self.pg_enable_capture(self.pg_interfaces)
4752 capture = self.pg0.get_capture(len(pkts))
4754 if p[IP].dst == server1.ip4:
4756 elif p[IP].dst == server2.ip4:
4760 self.assertGreater(server1_n, 0)
4761 self.assertEqual(server2_n, 0)
4762 self.assertGreater(server3_n, 0)
4764 def test_static_lb_2(self):
4765 """ NAT44 local service load balancing (asymmetrical rule) """
4766 external_addr_n = socket.inet_pton(socket.AF_INET, self.nat_addr)
4769 server1 = self.pg0.remote_hosts[0]
4770 server2 = self.pg0.remote_hosts[1]
4772 locals = [{'addr': server1.ip4n,
4776 {'addr': server2.ip4n,
4781 self.vapi.nat44_forwarding_enable_disable(1)
4782 self.vapi.nat44_add_del_lb_static_mapping(external_addr_n,
4786 local_num=len(locals),
4788 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
4789 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
4792 # from client to service
4793 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
4794 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
4795 TCP(sport=12345, dport=external_port))
4796 self.pg1.add_stream(p)
4797 self.pg_enable_capture(self.pg_interfaces)
4799 capture = self.pg0.get_capture(1)
4805 self.assertIn(ip.dst, [server1.ip4, server2.ip4])
4806 if ip.dst == server1.ip4:
4810 self.assertEqual(tcp.dport, local_port)
4811 self.assert_packet_checksums_valid(p)
4813 self.logger.error(ppp("Unexpected or invalid packet:", p))
4816 # from service back to client
4817 p = (Ether(src=server.mac, dst=self.pg0.local_mac) /
4818 IP(src=server.ip4, dst=self.pg1.remote_ip4) /
4819 TCP(sport=local_port, dport=12345))
4820 self.pg0.add_stream(p)
4821 self.pg_enable_capture(self.pg_interfaces)
4823 capture = self.pg1.get_capture(1)
4828 self.assertEqual(ip.src, self.nat_addr)
4829 self.assertEqual(tcp.sport, external_port)
4830 self.assert_packet_checksums_valid(p)
4832 self.logger.error(ppp("Unexpected or invalid packet:", p))
4835 # from client to server (no translation)
4836 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
4837 IP(src=self.pg1.remote_ip4, dst=server1.ip4) /
4838 TCP(sport=12346, dport=local_port))
4839 self.pg1.add_stream(p)
4840 self.pg_enable_capture(self.pg_interfaces)
4842 capture = self.pg0.get_capture(1)
4848 self.assertEqual(ip.dst, server1.ip4)
4849 self.assertEqual(tcp.dport, local_port)
4850 self.assert_packet_checksums_valid(p)
4852 self.logger.error(ppp("Unexpected or invalid packet:", p))
4855 # from service back to client (no translation)
4856 p = (Ether(src=server1.mac, dst=self.pg0.local_mac) /
4857 IP(src=server1.ip4, dst=self.pg1.remote_ip4) /
4858 TCP(sport=local_port, dport=12346))
4859 self.pg0.add_stream(p)
4860 self.pg_enable_capture(self.pg_interfaces)
4862 capture = self.pg1.get_capture(1)
4867 self.assertEqual(ip.src, server1.ip4)
4868 self.assertEqual(tcp.sport, local_port)
4869 self.assert_packet_checksums_valid(p)
4871 self.logger.error(ppp("Unexpected or invalid packet:", p))
4874 def test_lb_affinity(self):
4875 """ NAT44 local service load balancing affinity """
4876 external_addr_n = socket.inet_pton(socket.AF_INET, self.nat_addr)
4879 server1 = self.pg0.remote_hosts[0]
4880 server2 = self.pg0.remote_hosts[1]
4882 locals = [{'addr': server1.ip4n,
4886 {'addr': server2.ip4n,
4891 self.nat44_add_address(self.nat_addr)
4892 self.vapi.nat44_add_del_lb_static_mapping(external_addr_n,
4896 local_num=len(locals),
4898 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
4899 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
4902 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
4903 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
4904 TCP(sport=1025, dport=external_port))
4905 self.pg1.add_stream(p)
4906 self.pg_enable_capture(self.pg_interfaces)
4908 capture = self.pg0.get_capture(1)
4909 backend = capture[0][IP].dst
4911 sessions = self.vapi.nat44_user_session_dump(
4912 socket.inet_pton(socket.AF_INET, backend), 0)
4913 self.assertEqual(len(sessions), 1)
4914 self.assertTrue(sessions[0].ext_host_valid)
4915 self.vapi.nat44_del_session(
4916 sessions[0].inside_ip_address,
4917 sessions[0].inside_port,
4918 sessions[0].protocol,
4919 ext_host_address=sessions[0].ext_host_address,
4920 ext_host_port=sessions[0].ext_host_port)
4923 for port in range(1030, 1100):
4924 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
4925 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
4926 TCP(sport=port, dport=external_port))
4928 self.pg1.add_stream(pkts)
4929 self.pg_enable_capture(self.pg_interfaces)
4931 capture = self.pg0.get_capture(len(pkts))
4933 self.assertEqual(p[IP].dst, backend)
4935 def test_unknown_proto(self):
4936 """ NAT44 translate packet with unknown protocol """
4937 self.nat44_add_address(self.nat_addr)
4938 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
4939 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
4943 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
4944 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
4945 TCP(sport=self.tcp_port_in, dport=20))
4946 self.pg0.add_stream(p)
4947 self.pg_enable_capture(self.pg_interfaces)
4949 p = self.pg1.get_capture(1)
4951 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
4952 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
4954 IP(src=self.pg2.remote_ip4, dst=self.pg2.remote_ip4) /
4955 TCP(sport=1234, dport=1234))
4956 self.pg0.add_stream(p)
4957 self.pg_enable_capture(self.pg_interfaces)
4959 p = self.pg1.get_capture(1)
4962 self.assertEqual(packet[IP].src, self.nat_addr)
4963 self.assertEqual(packet[IP].dst, self.pg1.remote_ip4)
4964 self.assertEqual(packet.haslayer(GRE), 1)
4965 self.assert_packet_checksums_valid(packet)
4967 self.logger.error(ppp("Unexpected or invalid packet:", packet))
4971 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
4972 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
4974 IP(src=self.pg2.remote_ip4, dst=self.pg2.remote_ip4) /
4975 TCP(sport=1234, dport=1234))
4976 self.pg1.add_stream(p)
4977 self.pg_enable_capture(self.pg_interfaces)
4979 p = self.pg0.get_capture(1)
4982 self.assertEqual(packet[IP].src, self.pg1.remote_ip4)
4983 self.assertEqual(packet[IP].dst, self.pg0.remote_ip4)
4984 self.assertEqual(packet.haslayer(GRE), 1)
4985 self.assert_packet_checksums_valid(packet)
4987 self.logger.error(ppp("Unexpected or invalid packet:", packet))
4990 def test_hairpinning_unknown_proto(self):
4991 """ NAT44 translate packet with unknown protocol - hairpinning """
4992 host = self.pg0.remote_hosts[0]
4993 server = self.pg0.remote_hosts[1]
4995 server_out_port = 8765
4996 server_nat_ip = "10.0.0.11"
4998 self.nat44_add_address(self.nat_addr)
4999 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
5000 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
5003 # add static mapping for server
5004 self.nat44_add_static_mapping(server.ip4, server_nat_ip)
5007 p = (Ether(src=host.mac, dst=self.pg0.local_mac) /
5008 IP(src=host.ip4, dst=server_nat_ip) /
5009 TCP(sport=host_in_port, dport=server_out_port))
5010 self.pg0.add_stream(p)
5011 self.pg_enable_capture(self.pg_interfaces)
5013 self.pg0.get_capture(1)
5015 p = (Ether(dst=self.pg0.local_mac, src=host.mac) /
5016 IP(src=host.ip4, dst=server_nat_ip) /
5018 IP(src=self.pg2.remote_ip4, dst=self.pg2.remote_ip4) /
5019 TCP(sport=1234, dport=1234))
5020 self.pg0.add_stream(p)
5021 self.pg_enable_capture(self.pg_interfaces)
5023 p = self.pg0.get_capture(1)
5026 self.assertEqual(packet[IP].src, self.nat_addr)
5027 self.assertEqual(packet[IP].dst, server.ip4)
5028 self.assertEqual(packet.haslayer(GRE), 1)
5029 self.assert_packet_checksums_valid(packet)
5031 self.logger.error(ppp("Unexpected or invalid packet:", packet))
5035 p = (Ether(dst=self.pg0.local_mac, src=server.mac) /
5036 IP(src=server.ip4, dst=self.nat_addr) /
5038 IP(src=self.pg2.remote_ip4, dst=self.pg2.remote_ip4) /
5039 TCP(sport=1234, dport=1234))
5040 self.pg0.add_stream(p)
5041 self.pg_enable_capture(self.pg_interfaces)
5043 p = self.pg0.get_capture(1)
5046 self.assertEqual(packet[IP].src, server_nat_ip)
5047 self.assertEqual(packet[IP].dst, host.ip4)
5048 self.assertEqual(packet.haslayer(GRE), 1)
5049 self.assert_packet_checksums_valid(packet)
5051 self.logger.error(ppp("Unexpected or invalid packet:", packet))
5054 def test_output_feature_and_service(self):
5055 """ NAT44 interface output feature and services """
5056 external_addr = '1.2.3.4'
5060 self.vapi.nat44_forwarding_enable_disable(1)
5061 self.nat44_add_address(self.nat_addr)
5062 self.vapi.nat44_add_del_identity_mapping(ip=self.pg1.remote_ip4n)
5063 self.nat44_add_static_mapping(self.pg0.remote_ip4, external_addr,
5064 local_port, external_port,
5065 proto=IP_PROTOS.tcp, out2in_only=1)
5066 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
5067 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index,
5069 self.vapi.nat44_interface_add_del_output_feature(self.pg1.sw_if_index,
5072 # from client to service
5073 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
5074 IP(src=self.pg1.remote_ip4, dst=external_addr) /
5075 TCP(sport=12345, dport=external_port))
5076 self.pg1.add_stream(p)
5077 self.pg_enable_capture(self.pg_interfaces)
5079 capture = self.pg0.get_capture(1)
5084 self.assertEqual(ip.dst, self.pg0.remote_ip4)
5085 self.assertEqual(tcp.dport, local_port)
5086 self.assert_packet_checksums_valid(p)
5088 self.logger.error(ppp("Unexpected or invalid packet:", p))
5091 # from service back to client
5092 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5093 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
5094 TCP(sport=local_port, dport=12345))
5095 self.pg0.add_stream(p)
5096 self.pg_enable_capture(self.pg_interfaces)
5098 capture = self.pg1.get_capture(1)
5103 self.assertEqual(ip.src, external_addr)
5104 self.assertEqual(tcp.sport, external_port)
5105 self.assert_packet_checksums_valid(p)
5107 self.logger.error(ppp("Unexpected or invalid packet:", p))
5110 # from local network host to external network
5111 pkts = self.create_stream_in(self.pg0, self.pg1)
5112 self.pg0.add_stream(pkts)
5113 self.pg_enable_capture(self.pg_interfaces)
5115 capture = self.pg1.get_capture(len(pkts))
5116 self.verify_capture_out(capture)
5117 pkts = self.create_stream_in(self.pg0, self.pg1)
5118 self.pg0.add_stream(pkts)
5119 self.pg_enable_capture(self.pg_interfaces)
5121 capture = self.pg1.get_capture(len(pkts))
5122 self.verify_capture_out(capture)
5124 # from external network back to local network host
5125 pkts = self.create_stream_out(self.pg1)
5126 self.pg1.add_stream(pkts)
5127 self.pg_enable_capture(self.pg_interfaces)
5129 capture = self.pg0.get_capture(len(pkts))
5130 self.verify_capture_in(capture, self.pg0)
5132 def test_output_feature_and_service2(self):
5133 """ NAT44 interface output feature and service host direct access """
5134 self.vapi.nat44_forwarding_enable_disable(1)
5135 self.nat44_add_address(self.nat_addr)
5136 self.vapi.nat44_interface_add_del_output_feature(self.pg1.sw_if_index,
5139 # session initiated from service host - translate
5140 pkts = self.create_stream_in(self.pg0, self.pg1)
5141 self.pg0.add_stream(pkts)
5142 self.pg_enable_capture(self.pg_interfaces)
5144 capture = self.pg1.get_capture(len(pkts))
5145 self.verify_capture_out(capture)
5147 pkts = self.create_stream_out(self.pg1)
5148 self.pg1.add_stream(pkts)
5149 self.pg_enable_capture(self.pg_interfaces)
5151 capture = self.pg0.get_capture(len(pkts))
5152 self.verify_capture_in(capture, self.pg0)
5154 # session initiated from remote host - do not translate
5155 self.tcp_port_in = 60303
5156 self.udp_port_in = 60304
5157 self.icmp_id_in = 60305
5158 pkts = self.create_stream_out(self.pg1,
5159 self.pg0.remote_ip4,
5160 use_inside_ports=True)
5161 self.pg1.add_stream(pkts)
5162 self.pg_enable_capture(self.pg_interfaces)
5164 capture = self.pg0.get_capture(len(pkts))
5165 self.verify_capture_in(capture, self.pg0)
5167 pkts = self.create_stream_in(self.pg0, self.pg1)
5168 self.pg0.add_stream(pkts)
5169 self.pg_enable_capture(self.pg_interfaces)
5171 capture = self.pg1.get_capture(len(pkts))
5172 self.verify_capture_out(capture, nat_ip=self.pg0.remote_ip4,
5175 def test_output_feature_and_service3(self):
5176 """ NAT44 interface output feature and DST NAT """
5177 external_addr = '1.2.3.4'
5181 self.vapi.nat44_forwarding_enable_disable(1)
5182 self.nat44_add_address(self.nat_addr)
5183 self.nat44_add_static_mapping(self.pg1.remote_ip4, external_addr,
5184 local_port, external_port,
5185 proto=IP_PROTOS.tcp, out2in_only=1)
5186 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
5187 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index,
5189 self.vapi.nat44_interface_add_del_output_feature(self.pg1.sw_if_index,
5192 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5193 IP(src=self.pg0.remote_ip4, dst=external_addr) /
5194 TCP(sport=12345, dport=external_port))
5195 self.pg0.add_stream(p)
5196 self.pg_enable_capture(self.pg_interfaces)
5198 capture = self.pg1.get_capture(1)
5203 self.assertEqual(ip.src, self.pg0.remote_ip4)
5204 self.assertEqual(tcp.sport, 12345)
5205 self.assertEqual(ip.dst, self.pg1.remote_ip4)
5206 self.assertEqual(tcp.dport, local_port)
5207 self.assert_packet_checksums_valid(p)
5209 self.logger.error(ppp("Unexpected or invalid packet:", p))
5212 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
5213 IP(src=self.pg1.remote_ip4, dst=self.pg0.remote_ip4) /
5214 TCP(sport=local_port, dport=12345))
5215 self.pg1.add_stream(p)
5216 self.pg_enable_capture(self.pg_interfaces)
5218 capture = self.pg0.get_capture(1)
5223 self.assertEqual(ip.src, external_addr)
5224 self.assertEqual(tcp.sport, external_port)
5225 self.assertEqual(ip.dst, self.pg0.remote_ip4)
5226 self.assertEqual(tcp.dport, 12345)
5227 self.assert_packet_checksums_valid(p)
5229 self.logger.error(ppp("Unexpected or invalid packet:", p))
5232 def test_next_src_nat(self):
5233 """ On way back forward packet to nat44-in2out node. """
5234 twice_nat_addr = '10.0.1.3'
5237 post_twice_nat_port = 0
5239 self.vapi.nat44_forwarding_enable_disable(1)
5240 self.nat44_add_address(twice_nat_addr, twice_nat=1)
5241 self.nat44_add_static_mapping(self.pg6.remote_ip4, self.pg1.remote_ip4,
5242 local_port, external_port,
5243 proto=IP_PROTOS.tcp, out2in_only=1,
5244 self_twice_nat=1, vrf_id=1)
5245 self.vapi.nat44_interface_add_del_feature(self.pg6.sw_if_index,
5248 p = (Ether(src=self.pg6.remote_mac, dst=self.pg6.local_mac) /
5249 IP(src=self.pg6.remote_ip4, dst=self.pg1.remote_ip4) /
5250 TCP(sport=12345, dport=external_port))
5251 self.pg6.add_stream(p)
5252 self.pg_enable_capture(self.pg_interfaces)
5254 capture = self.pg6.get_capture(1)
5259 self.assertEqual(ip.src, twice_nat_addr)
5260 self.assertNotEqual(tcp.sport, 12345)
5261 post_twice_nat_port = tcp.sport
5262 self.assertEqual(ip.dst, self.pg6.remote_ip4)
5263 self.assertEqual(tcp.dport, local_port)
5264 self.assert_packet_checksums_valid(p)
5266 self.logger.error(ppp("Unexpected or invalid packet:", p))
5269 p = (Ether(src=self.pg6.remote_mac, dst=self.pg6.local_mac) /
5270 IP(src=self.pg6.remote_ip4, dst=twice_nat_addr) /
5271 TCP(sport=local_port, dport=post_twice_nat_port))
5272 self.pg6.add_stream(p)
5273 self.pg_enable_capture(self.pg_interfaces)
5275 capture = self.pg6.get_capture(1)
5280 self.assertEqual(ip.src, self.pg1.remote_ip4)
5281 self.assertEqual(tcp.sport, external_port)
5282 self.assertEqual(ip.dst, self.pg6.remote_ip4)
5283 self.assertEqual(tcp.dport, 12345)
5284 self.assert_packet_checksums_valid(p)
5286 self.logger.error(ppp("Unexpected or invalid packet:", p))
5289 def twice_nat_common(self, self_twice_nat=False, same_pg=False, lb=False,
5291 twice_nat_addr = '10.0.1.3'
5299 port_in1 = port_in + 1
5300 port_in2 = port_in + 2
5305 server1 = self.pg0.remote_hosts[0]
5306 server2 = self.pg0.remote_hosts[1]
5318 eh_translate = ((not self_twice_nat) or (not lb and same_pg) or
5321 self.nat44_add_address(self.nat_addr)
5322 self.nat44_add_address(twice_nat_addr, twice_nat=1)
5324 self.nat44_add_static_mapping(pg0.remote_ip4, self.nat_addr,
5326 proto=IP_PROTOS.tcp,
5327 twice_nat=int(not self_twice_nat),
5328 self_twice_nat=int(self_twice_nat))
5330 locals = [{'addr': server1.ip4n,
5334 {'addr': server2.ip4n,
5338 out_addr_n = socket.inet_pton(socket.AF_INET, self.nat_addr)
5339 self.vapi.nat44_add_del_lb_static_mapping(out_addr_n,
5343 not self_twice_nat),
5346 local_num=len(locals),
5348 self.vapi.nat44_interface_add_del_feature(pg0.sw_if_index)
5349 self.vapi.nat44_interface_add_del_feature(pg1.sw_if_index,
5356 assert client_id is not None
5358 client = self.pg0.remote_hosts[0]
5359 elif client_id == 2:
5360 client = self.pg0.remote_hosts[1]
5362 client = pg1.remote_hosts[0]
5363 p = (Ether(src=pg1.remote_mac, dst=pg1.local_mac) /
5364 IP(src=client.ip4, dst=self.nat_addr) /
5365 TCP(sport=eh_port_out, dport=port_out))
5367 self.pg_enable_capture(self.pg_interfaces)
5369 capture = pg0.get_capture(1)
5375 if ip.dst == server1.ip4:
5381 self.assertEqual(ip.dst, server.ip4)
5383 self.assertIn(tcp.dport, [port_in1, port_in2])
5385 self.assertEqual(tcp.dport, port_in)
5387 self.assertEqual(ip.src, twice_nat_addr)
5388 self.assertNotEqual(tcp.sport, eh_port_out)
5390 self.assertEqual(ip.src, client.ip4)
5391 self.assertEqual(tcp.sport, eh_port_out)
5393 eh_port_in = tcp.sport
5394 saved_port_in = tcp.dport
5395 self.assert_packet_checksums_valid(p)
5397 self.logger.error(ppp("Unexpected or invalid packet:", p))
5400 p = (Ether(src=server.mac, dst=pg0.local_mac) /
5401 IP(src=server.ip4, dst=eh_addr_in) /
5402 TCP(sport=saved_port_in, dport=eh_port_in))
5404 self.pg_enable_capture(self.pg_interfaces)
5406 capture = pg1.get_capture(1)
5411 self.assertEqual(ip.dst, client.ip4)
5412 self.assertEqual(ip.src, self.nat_addr)
5413 self.assertEqual(tcp.dport, eh_port_out)
5414 self.assertEqual(tcp.sport, port_out)
5415 self.assert_packet_checksums_valid(p)
5417 self.logger.error(ppp("Unexpected or invalid packet:", p))
5421 sessions = self.vapi.nat44_user_session_dump(server.ip4n, 0)
5422 self.assertEqual(len(sessions), 1)
5423 self.assertTrue(sessions[0].ext_host_valid)
5424 self.assertTrue(sessions[0].is_twicenat)
5425 self.vapi.nat44_del_session(
5426 sessions[0].inside_ip_address,
5427 sessions[0].inside_port,
5428 sessions[0].protocol,
5429 ext_host_address=sessions[0].ext_host_nat_address,
5430 ext_host_port=sessions[0].ext_host_nat_port)
5431 sessions = self.vapi.nat44_user_session_dump(server.ip4n, 0)
5432 self.assertEqual(len(sessions), 0)
5434 def test_twice_nat(self):
5436 self.twice_nat_common()
5438 def test_self_twice_nat_positive(self):
5439 """ Self Twice NAT44 (positive test) """
5440 self.twice_nat_common(self_twice_nat=True, same_pg=True)
5442 def test_self_twice_nat_negative(self):
5443 """ Self Twice NAT44 (negative test) """
5444 self.twice_nat_common(self_twice_nat=True)
5446 def test_twice_nat_lb(self):
5447 """ Twice NAT44 local service load balancing """
5448 self.twice_nat_common(lb=True)
5450 def test_self_twice_nat_lb_positive(self):
5451 """ Self Twice NAT44 local service load balancing (positive test) """
5452 self.twice_nat_common(lb=True, self_twice_nat=True, same_pg=True,
5455 def test_self_twice_nat_lb_negative(self):
5456 """ Self Twice NAT44 local service load balancing (negative test) """
5457 self.twice_nat_common(lb=True, self_twice_nat=True, same_pg=True,
5460 def test_twice_nat_interface_addr(self):
5461 """ Acquire twice NAT44 addresses from interface """
5462 self.vapi.nat44_add_del_interface_addr(self.pg3.sw_if_index,
5465 # no address in NAT pool
5466 adresses = self.vapi.nat44_address_dump()
5467 self.assertEqual(0, len(adresses))
5469 # configure interface address and check NAT address pool
5470 self.pg3.config_ip4()
5471 adresses = self.vapi.nat44_address_dump()
5472 self.assertEqual(1, len(adresses))
5473 self.assertEqual(adresses[0].ip_address[0:4], self.pg3.local_ip4n)
5474 self.assertEqual(adresses[0].twice_nat, 1)
5476 # remove interface address and check NAT address pool
5477 self.pg3.unconfig_ip4()
5478 adresses = self.vapi.nat44_address_dump()
5479 self.assertEqual(0, len(adresses))
5481 def test_tcp_close(self):
5482 """ Close TCP session from inside network - output feature """
5483 self.vapi.nat44_forwarding_enable_disable(1)
5484 self.nat44_add_address(self.pg1.local_ip4)
5485 twice_nat_addr = '10.0.1.3'
5486 service_ip = '192.168.16.150'
5487 self.nat44_add_address(twice_nat_addr, twice_nat=1)
5488 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
5489 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index,
5491 self.vapi.nat44_interface_add_del_output_feature(self.pg1.sw_if_index,
5493 self.nat44_add_static_mapping(self.pg0.remote_ip4,
5497 proto=IP_PROTOS.tcp,
5500 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4n, 0)
5501 start_sessnum = len(sessions)
5503 # SYN packet out->in
5504 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
5505 IP(src=self.pg1.remote_ip4, dst=service_ip) /
5506 TCP(sport=33898, dport=80, flags="S"))
5507 self.pg1.add_stream(p)
5508 self.pg_enable_capture(self.pg_interfaces)
5510 capture = self.pg0.get_capture(1)
5512 tcp_port = p[TCP].sport
5514 # SYN + ACK packet in->out
5515 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5516 IP(src=self.pg0.remote_ip4, dst=twice_nat_addr) /
5517 TCP(sport=80, dport=tcp_port, flags="SA"))
5518 self.pg0.add_stream(p)
5519 self.pg_enable_capture(self.pg_interfaces)
5521 self.pg1.get_capture(1)
5523 # ACK packet out->in
5524 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
5525 IP(src=self.pg1.remote_ip4, dst=service_ip) /
5526 TCP(sport=33898, dport=80, flags="A"))
5527 self.pg1.add_stream(p)
5528 self.pg_enable_capture(self.pg_interfaces)
5530 self.pg0.get_capture(1)
5532 # FIN packet in -> out
5533 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5534 IP(src=self.pg0.remote_ip4, dst=twice_nat_addr) /
5535 TCP(sport=80, dport=tcp_port, flags="FA", seq=100, ack=300))
5536 self.pg0.add_stream(p)
5537 self.pg_enable_capture(self.pg_interfaces)
5539 self.pg1.get_capture(1)
5541 # FIN+ACK packet out -> in
5542 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
5543 IP(src=self.pg1.remote_ip4, dst=service_ip) /
5544 TCP(sport=33898, dport=80, flags="FA", seq=300, ack=101))
5545 self.pg1.add_stream(p)
5546 self.pg_enable_capture(self.pg_interfaces)
5548 self.pg0.get_capture(1)
5550 # ACK packet in -> out
5551 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5552 IP(src=self.pg0.remote_ip4, dst=twice_nat_addr) /
5553 TCP(sport=80, dport=tcp_port, flags="A", seq=101, ack=301))
5554 self.pg0.add_stream(p)
5555 self.pg_enable_capture(self.pg_interfaces)
5557 self.pg1.get_capture(1)
5559 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4n,
5561 self.assertEqual(len(sessions) - start_sessnum, 0)
5563 def test_tcp_session_close_in(self):
5564 """ Close TCP session from inside network """
5565 self.tcp_port_out = 10505
5566 self.nat44_add_address(self.nat_addr)
5567 self.nat44_add_static_mapping(self.pg0.remote_ip4,
5571 proto=IP_PROTOS.tcp,
5573 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
5574 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
5577 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4n, 0)
5578 start_sessnum = len(sessions)
5580 self.initiate_tcp_session(self.pg0, self.pg1)
5582 # FIN packet in -> out
5583 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5584 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
5585 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
5586 flags="FA", seq=100, ack=300))
5587 self.pg0.add_stream(p)
5588 self.pg_enable_capture(self.pg_interfaces)
5590 self.pg1.get_capture(1)
5594 # ACK packet out -> in
5595 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
5596 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
5597 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
5598 flags="A", seq=300, ack=101))
5601 # FIN packet out -> in
5602 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
5603 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
5604 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
5605 flags="FA", seq=300, ack=101))
5608 self.pg1.add_stream(pkts)
5609 self.pg_enable_capture(self.pg_interfaces)
5611 self.pg0.get_capture(2)
5613 # ACK packet in -> out
5614 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5615 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
5616 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
5617 flags="A", seq=101, ack=301))
5618 self.pg0.add_stream(p)
5619 self.pg_enable_capture(self.pg_interfaces)
5621 self.pg1.get_capture(1)
5623 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4n,
5625 self.assertEqual(len(sessions) - start_sessnum, 0)
5627 def test_tcp_session_close_out(self):
5628 """ Close TCP session from outside network """
5629 self.tcp_port_out = 10505
5630 self.nat44_add_address(self.nat_addr)
5631 self.nat44_add_static_mapping(self.pg0.remote_ip4,
5635 proto=IP_PROTOS.tcp,
5637 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
5638 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
5641 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4n, 0)
5642 start_sessnum = len(sessions)
5644 self.initiate_tcp_session(self.pg0, self.pg1)
5646 # FIN packet out -> in
5647 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
5648 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
5649 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
5650 flags="FA", seq=100, ack=300))
5651 self.pg1.add_stream(p)
5652 self.pg_enable_capture(self.pg_interfaces)
5654 self.pg0.get_capture(1)
5656 # FIN+ACK packet in -> out
5657 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5658 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
5659 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
5660 flags="FA", seq=300, ack=101))
5662 self.pg0.add_stream(p)
5663 self.pg_enable_capture(self.pg_interfaces)
5665 self.pg1.get_capture(1)
5667 # ACK packet out -> in
5668 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
5669 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
5670 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
5671 flags="A", seq=101, ack=301))
5672 self.pg1.add_stream(p)
5673 self.pg_enable_capture(self.pg_interfaces)
5675 self.pg0.get_capture(1)
5677 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4n,
5679 self.assertEqual(len(sessions) - start_sessnum, 0)
5681 def test_tcp_session_close_simultaneous(self):
5682 """ Close TCP session from inside network """
5683 self.tcp_port_out = 10505
5684 self.nat44_add_address(self.nat_addr)
5685 self.nat44_add_static_mapping(self.pg0.remote_ip4,
5689 proto=IP_PROTOS.tcp,
5691 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
5692 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
5695 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4n, 0)
5696 start_sessnum = len(sessions)
5698 self.initiate_tcp_session(self.pg0, self.pg1)
5700 # FIN packet in -> out
5701 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5702 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
5703 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
5704 flags="FA", seq=100, ack=300))
5705 self.pg0.add_stream(p)
5706 self.pg_enable_capture(self.pg_interfaces)
5708 self.pg1.get_capture(1)
5710 # FIN packet out -> in
5711 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
5712 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
5713 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
5714 flags="FA", seq=300, ack=100))
5715 self.pg1.add_stream(p)
5716 self.pg_enable_capture(self.pg_interfaces)
5718 self.pg0.get_capture(1)
5720 # ACK packet in -> out
5721 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5722 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
5723 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
5724 flags="A", seq=101, ack=301))
5725 self.pg0.add_stream(p)
5726 self.pg_enable_capture(self.pg_interfaces)
5728 self.pg1.get_capture(1)
5730 # ACK packet out -> in
5731 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
5732 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
5733 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
5734 flags="A", seq=301, ack=101))
5735 self.pg1.add_stream(p)
5736 self.pg_enable_capture(self.pg_interfaces)
5738 self.pg0.get_capture(1)
5740 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4n,
5742 self.assertEqual(len(sessions) - start_sessnum, 0)
5744 def test_one_armed_nat44_static(self):
5745 """ One armed NAT44 and 1:1 NAPT asymmetrical rule """
5746 remote_host = self.pg4.remote_hosts[0]
5747 local_host = self.pg4.remote_hosts[1]
5752 self.vapi.nat44_forwarding_enable_disable(1)
5753 self.nat44_add_address(self.nat_addr, twice_nat=1)
5754 self.nat44_add_static_mapping(local_host.ip4, self.nat_addr,
5755 local_port, external_port,
5756 proto=IP_PROTOS.tcp, out2in_only=1,
5758 self.vapi.nat44_interface_add_del_feature(self.pg4.sw_if_index)
5759 self.vapi.nat44_interface_add_del_feature(self.pg4.sw_if_index,
5762 # from client to service
5763 p = (Ether(src=self.pg4.remote_mac, dst=self.pg4.local_mac) /
5764 IP(src=remote_host.ip4, dst=self.nat_addr) /
5765 TCP(sport=12345, dport=external_port))
5766 self.pg4.add_stream(p)
5767 self.pg_enable_capture(self.pg_interfaces)
5769 capture = self.pg4.get_capture(1)
5774 self.assertEqual(ip.dst, local_host.ip4)
5775 self.assertEqual(ip.src, self.nat_addr)
5776 self.assertEqual(tcp.dport, local_port)
5777 self.assertNotEqual(tcp.sport, 12345)
5778 eh_port_in = tcp.sport
5779 self.assert_packet_checksums_valid(p)
5781 self.logger.error(ppp("Unexpected or invalid packet:", p))
5784 # from service back to client
5785 p = (Ether(src=self.pg4.remote_mac, dst=self.pg4.local_mac) /
5786 IP(src=local_host.ip4, dst=self.nat_addr) /
5787 TCP(sport=local_port, dport=eh_port_in))
5788 self.pg4.add_stream(p)
5789 self.pg_enable_capture(self.pg_interfaces)
5791 capture = self.pg4.get_capture(1)
5796 self.assertEqual(ip.src, self.nat_addr)
5797 self.assertEqual(ip.dst, remote_host.ip4)
5798 self.assertEqual(tcp.sport, external_port)
5799 self.assertEqual(tcp.dport, 12345)
5800 self.assert_packet_checksums_valid(p)
5802 self.logger.error(ppp("Unexpected or invalid packet:", p))
5805 def test_static_with_port_out2(self):
5806 """ 1:1 NAPT asymmetrical rule """
5811 self.vapi.nat44_forwarding_enable_disable(1)
5812 self.nat44_add_static_mapping(self.pg0.remote_ip4, self.nat_addr,
5813 local_port, external_port,
5814 proto=IP_PROTOS.tcp, out2in_only=1)
5815 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
5816 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
5819 # from client to service
5820 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
5821 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
5822 TCP(sport=12345, dport=external_port))
5823 self.pg1.add_stream(p)
5824 self.pg_enable_capture(self.pg_interfaces)
5826 capture = self.pg0.get_capture(1)
5831 self.assertEqual(ip.dst, self.pg0.remote_ip4)
5832 self.assertEqual(tcp.dport, local_port)
5833 self.assert_packet_checksums_valid(p)
5835 self.logger.error(ppp("Unexpected or invalid packet:", p))
5839 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
5840 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
5841 ICMP(type=11) / capture[0][IP])
5842 self.pg0.add_stream(p)
5843 self.pg_enable_capture(self.pg_interfaces)
5845 capture = self.pg1.get_capture(1)
5848 self.assertEqual(p[IP].src, self.nat_addr)
5850 self.assertEqual(inner.dst, self.nat_addr)
5851 self.assertEqual(inner[TCPerror].dport, external_port)
5853 self.logger.error(ppp("Unexpected or invalid packet:", p))
5856 # from service back to client
5857 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5858 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
5859 TCP(sport=local_port, dport=12345))
5860 self.pg0.add_stream(p)
5861 self.pg_enable_capture(self.pg_interfaces)
5863 capture = self.pg1.get_capture(1)
5868 self.assertEqual(ip.src, self.nat_addr)
5869 self.assertEqual(tcp.sport, external_port)
5870 self.assert_packet_checksums_valid(p)
5872 self.logger.error(ppp("Unexpected or invalid packet:", p))
5876 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
5877 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
5878 ICMP(type=11) / capture[0][IP])
5879 self.pg1.add_stream(p)
5880 self.pg_enable_capture(self.pg_interfaces)
5882 capture = self.pg0.get_capture(1)
5885 self.assertEqual(p[IP].dst, self.pg0.remote_ip4)
5887 self.assertEqual(inner.src, self.pg0.remote_ip4)
5888 self.assertEqual(inner[TCPerror].sport, local_port)
5890 self.logger.error(ppp("Unexpected or invalid packet:", p))
5893 # from client to server (no translation)
5894 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
5895 IP(src=self.pg1.remote_ip4, dst=self.pg0.remote_ip4) /
5896 TCP(sport=12346, dport=local_port))
5897 self.pg1.add_stream(p)
5898 self.pg_enable_capture(self.pg_interfaces)
5900 capture = self.pg0.get_capture(1)
5905 self.assertEqual(ip.dst, self.pg0.remote_ip4)
5906 self.assertEqual(tcp.dport, local_port)
5907 self.assert_packet_checksums_valid(p)
5909 self.logger.error(ppp("Unexpected or invalid packet:", p))
5912 # from service back to client (no translation)
5913 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5914 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
5915 TCP(sport=local_port, dport=12346))
5916 self.pg0.add_stream(p)
5917 self.pg_enable_capture(self.pg_interfaces)
5919 capture = self.pg1.get_capture(1)
5924 self.assertEqual(ip.src, self.pg0.remote_ip4)
5925 self.assertEqual(tcp.sport, local_port)
5926 self.assert_packet_checksums_valid(p)
5928 self.logger.error(ppp("Unexpected or invalid packet:", p))
5931 def test_output_feature(self):
5932 """ NAT44 interface output feature (in2out postrouting) """
5933 self.vapi.nat44_forwarding_enable_disable(1)
5934 self.nat44_add_address(self.nat_addr)
5935 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index,
5937 self.vapi.nat44_interface_add_del_output_feature(self.pg1.sw_if_index,
5941 pkts = self.create_stream_in(self.pg0, self.pg1)
5942 self.pg0.add_stream(pkts)
5943 self.pg_enable_capture(self.pg_interfaces)
5945 capture = self.pg1.get_capture(len(pkts))
5946 self.verify_capture_out(capture)
5949 pkts = self.create_stream_out(self.pg1)
5950 self.pg1.add_stream(pkts)
5951 self.pg_enable_capture(self.pg_interfaces)
5953 capture = self.pg0.get_capture(len(pkts))
5954 self.verify_capture_in(capture, self.pg0)
5956 def test_multiple_vrf(self):
5957 """ Multiple VRF setup """
5958 external_addr = '1.2.3.4'
5963 self.vapi.nat44_forwarding_enable_disable(1)
5964 self.nat44_add_address(self.nat_addr)
5965 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
5966 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index,
5968 self.vapi.nat44_interface_add_del_output_feature(self.pg1.sw_if_index,
5970 self.vapi.nat44_interface_add_del_feature(self.pg5.sw_if_index)
5971 self.vapi.nat44_interface_add_del_feature(self.pg5.sw_if_index,
5973 self.vapi.nat44_interface_add_del_feature(self.pg6.sw_if_index,
5975 self.nat44_add_static_mapping(self.pg5.remote_ip4, external_addr,
5976 local_port, external_port, vrf_id=1,
5977 proto=IP_PROTOS.tcp, out2in_only=1)
5978 self.nat44_add_static_mapping(
5979 self.pg0.remote_ip4, external_sw_if_index=self.pg0.sw_if_index,
5980 local_port=local_port, vrf_id=0, external_port=external_port,
5981 proto=IP_PROTOS.tcp, out2in_only=1)
5983 # from client to service (both VRF1)
5984 p = (Ether(src=self.pg6.remote_mac, dst=self.pg6.local_mac) /
5985 IP(src=self.pg6.remote_ip4, dst=external_addr) /
5986 TCP(sport=12345, dport=external_port))
5987 self.pg6.add_stream(p)
5988 self.pg_enable_capture(self.pg_interfaces)
5990 capture = self.pg5.get_capture(1)
5995 self.assertEqual(ip.dst, self.pg5.remote_ip4)
5996 self.assertEqual(tcp.dport, local_port)
5997 self.assert_packet_checksums_valid(p)
5999 self.logger.error(ppp("Unexpected or invalid packet:", p))
6002 # from service back to client (both VRF1)
6003 p = (Ether(src=self.pg5.remote_mac, dst=self.pg5.local_mac) /
6004 IP(src=self.pg5.remote_ip4, dst=self.pg6.remote_ip4) /
6005 TCP(sport=local_port, dport=12345))
6006 self.pg5.add_stream(p)
6007 self.pg_enable_capture(self.pg_interfaces)
6009 capture = self.pg6.get_capture(1)
6014 self.assertEqual(ip.src, external_addr)
6015 self.assertEqual(tcp.sport, external_port)
6016 self.assert_packet_checksums_valid(p)
6018 self.logger.error(ppp("Unexpected or invalid packet:", p))
6021 # dynamic NAT from VRF1 to VRF0 (output-feature)
6022 p = (Ether(src=self.pg5.remote_mac, dst=self.pg5.local_mac) /
6023 IP(src=self.pg5.remote_ip4, dst=self.pg1.remote_ip4) /
6024 TCP(sport=2345, dport=22))
6025 self.pg5.add_stream(p)
6026 self.pg_enable_capture(self.pg_interfaces)
6028 capture = self.pg1.get_capture(1)
6033 self.assertEqual(ip.src, self.nat_addr)
6034 self.assertNotEqual(tcp.sport, 2345)
6035 self.assert_packet_checksums_valid(p)
6038 self.logger.error(ppp("Unexpected or invalid packet:", p))
6041 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
6042 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
6043 TCP(sport=22, dport=port))
6044 self.pg1.add_stream(p)
6045 self.pg_enable_capture(self.pg_interfaces)
6047 capture = self.pg5.get_capture(1)
6052 self.assertEqual(ip.dst, self.pg5.remote_ip4)
6053 self.assertEqual(tcp.dport, 2345)
6054 self.assert_packet_checksums_valid(p)
6056 self.logger.error(ppp("Unexpected or invalid packet:", p))
6059 # from client VRF1 to service VRF0
6060 p = (Ether(src=self.pg6.remote_mac, dst=self.pg6.local_mac) /
6061 IP(src=self.pg6.remote_ip4, dst=self.pg0.local_ip4) /
6062 TCP(sport=12346, dport=external_port))
6063 self.pg6.add_stream(p)
6064 self.pg_enable_capture(self.pg_interfaces)
6066 capture = self.pg0.get_capture(1)
6071 self.assertEqual(ip.dst, self.pg0.remote_ip4)
6072 self.assertEqual(tcp.dport, local_port)
6073 self.assert_packet_checksums_valid(p)
6075 self.logger.error(ppp("Unexpected or invalid packet:", p))
6078 # from service VRF0 back to client VRF1
6079 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6080 IP(src=self.pg0.remote_ip4, dst=self.pg6.remote_ip4) /
6081 TCP(sport=local_port, dport=12346))
6082 self.pg0.add_stream(p)
6083 self.pg_enable_capture(self.pg_interfaces)
6085 capture = self.pg6.get_capture(1)
6090 self.assertEqual(ip.src, self.pg0.local_ip4)
6091 self.assertEqual(tcp.sport, external_port)
6092 self.assert_packet_checksums_valid(p)
6094 self.logger.error(ppp("Unexpected or invalid packet:", p))
6097 # from client VRF0 to service VRF1
6098 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6099 IP(src=self.pg0.remote_ip4, dst=external_addr) /
6100 TCP(sport=12347, dport=external_port))
6101 self.pg0.add_stream(p)
6102 self.pg_enable_capture(self.pg_interfaces)
6104 capture = self.pg5.get_capture(1)
6109 self.assertEqual(ip.dst, self.pg5.remote_ip4)
6110 self.assertEqual(tcp.dport, local_port)
6111 self.assert_packet_checksums_valid(p)
6113 self.logger.error(ppp("Unexpected or invalid packet:", p))
6116 # from service VRF1 back to client VRF0
6117 p = (Ether(src=self.pg5.remote_mac, dst=self.pg5.local_mac) /
6118 IP(src=self.pg5.remote_ip4, dst=self.pg0.remote_ip4) /
6119 TCP(sport=local_port, dport=12347))
6120 self.pg5.add_stream(p)
6121 self.pg_enable_capture(self.pg_interfaces)
6123 capture = self.pg0.get_capture(1)
6128 self.assertEqual(ip.src, external_addr)
6129 self.assertEqual(tcp.sport, external_port)
6130 self.assert_packet_checksums_valid(p)
6132 self.logger.error(ppp("Unexpected or invalid packet:", p))
6135 # from client to server (both VRF1, no translation)
6136 p = (Ether(src=self.pg6.remote_mac, dst=self.pg6.local_mac) /
6137 IP(src=self.pg6.remote_ip4, dst=self.pg5.remote_ip4) /
6138 TCP(sport=12348, dport=local_port))
6139 self.pg6.add_stream(p)
6140 self.pg_enable_capture(self.pg_interfaces)
6142 capture = self.pg5.get_capture(1)
6147 self.assertEqual(ip.dst, self.pg5.remote_ip4)
6148 self.assertEqual(tcp.dport, local_port)
6149 self.assert_packet_checksums_valid(p)
6151 self.logger.error(ppp("Unexpected or invalid packet:", p))
6154 # from server back to client (both VRF1, no translation)
6155 p = (Ether(src=self.pg5.remote_mac, dst=self.pg5.local_mac) /
6156 IP(src=self.pg5.remote_ip4, dst=self.pg6.remote_ip4) /
6157 TCP(sport=local_port, dport=12348))
6158 self.pg5.add_stream(p)
6159 self.pg_enable_capture(self.pg_interfaces)
6161 capture = self.pg6.get_capture(1)
6166 self.assertEqual(ip.src, self.pg5.remote_ip4)
6167 self.assertEqual(tcp.sport, local_port)
6168 self.assert_packet_checksums_valid(p)
6170 self.logger.error(ppp("Unexpected or invalid packet:", p))
6173 # from client VRF1 to server VRF0 (no translation)
6174 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6175 IP(src=self.pg0.remote_ip4, dst=self.pg6.remote_ip4) /
6176 TCP(sport=local_port, dport=12349))
6177 self.pg0.add_stream(p)
6178 self.pg_enable_capture(self.pg_interfaces)
6180 capture = self.pg6.get_capture(1)
6185 self.assertEqual(ip.src, self.pg0.remote_ip4)
6186 self.assertEqual(tcp.sport, local_port)
6187 self.assert_packet_checksums_valid(p)
6189 self.logger.error(ppp("Unexpected or invalid packet:", p))
6192 # from server VRF0 back to client VRF1 (no translation)
6193 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6194 IP(src=self.pg0.remote_ip4, dst=self.pg6.remote_ip4) /
6195 TCP(sport=local_port, dport=12349))
6196 self.pg0.add_stream(p)
6197 self.pg_enable_capture(self.pg_interfaces)
6199 capture = self.pg6.get_capture(1)
6204 self.assertEqual(ip.src, self.pg0.remote_ip4)
6205 self.assertEqual(tcp.sport, local_port)
6206 self.assert_packet_checksums_valid(p)
6208 self.logger.error(ppp("Unexpected or invalid packet:", p))
6211 # from client VRF0 to server VRF1 (no translation)
6212 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6213 IP(src=self.pg0.remote_ip4, dst=self.pg5.remote_ip4) /
6214 TCP(sport=12344, dport=local_port))
6215 self.pg0.add_stream(p)
6216 self.pg_enable_capture(self.pg_interfaces)
6218 capture = self.pg5.get_capture(1)
6223 self.assertEqual(ip.dst, self.pg5.remote_ip4)
6224 self.assertEqual(tcp.dport, local_port)
6225 self.assert_packet_checksums_valid(p)
6227 self.logger.error(ppp("Unexpected or invalid packet:", p))
6230 # from server VRF1 back to client VRF0 (no translation)
6231 p = (Ether(src=self.pg5.remote_mac, dst=self.pg5.local_mac) /
6232 IP(src=self.pg5.remote_ip4, dst=self.pg0.remote_ip4) /
6233 TCP(sport=local_port, dport=12344))
6234 self.pg5.add_stream(p)
6235 self.pg_enable_capture(self.pg_interfaces)
6237 capture = self.pg0.get_capture(1)
6242 self.assertEqual(ip.src, self.pg5.remote_ip4)
6243 self.assertEqual(tcp.sport, local_port)
6244 self.assert_packet_checksums_valid(p)
6246 self.logger.error(ppp("Unexpected or invalid packet:", p))
6249 @unittest.skipUnless(running_extended_tests, "part of extended tests")
6250 def test_session_timeout(self):
6251 """ NAT44 session timeouts """
6252 self.nat44_add_address(self.nat_addr)
6253 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
6254 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
6256 self.vapi.nat_set_timeouts(icmp=5)
6260 for i in range(0, max_sessions):
6261 src = "10.10.%u.%u" % ((i & 0xFF00) >> 8, i & 0xFF)
6262 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
6263 IP(src=src, dst=self.pg1.remote_ip4) /
6264 ICMP(id=1025, type='echo-request'))
6266 self.pg0.add_stream(pkts)
6267 self.pg_enable_capture(self.pg_interfaces)
6269 self.pg1.get_capture(max_sessions)
6274 for i in range(0, max_sessions):
6275 src = "10.11.%u.%u" % ((i & 0xFF00) >> 8, i & 0xFF)
6276 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
6277 IP(src=src, dst=self.pg1.remote_ip4) /
6278 ICMP(id=1026, type='echo-request'))
6280 self.pg0.add_stream(pkts)
6281 self.pg_enable_capture(self.pg_interfaces)
6283 self.pg1.get_capture(max_sessions)
6286 users = self.vapi.nat44_user_dump()
6288 nsessions = nsessions + user.nsessions
6289 self.assertLess(nsessions, 2 * max_sessions)
6291 @unittest.skipUnless(running_extended_tests, "part of extended tests")
6292 def test_session_rst_timeout(self):
6293 """ NAT44 session RST timeouts """
6294 self.nat44_add_address(self.nat_addr)
6295 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
6296 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
6298 self.vapi.nat_set_timeouts(tcp_transitory=5)
6300 self.initiate_tcp_session(self.pg0, self.pg1)
6301 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6302 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6303 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
6305 self.pg0.add_stream(p)
6306 self.pg_enable_capture(self.pg_interfaces)
6308 self.pg1.get_capture(1)
6312 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6313 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6314 TCP(sport=self.tcp_port_in + 1, dport=self.tcp_external_port + 1,
6316 self.pg0.add_stream(p)
6317 self.pg_enable_capture(self.pg_interfaces)
6319 self.pg1.get_capture(1)
6322 users = self.vapi.nat44_user_dump()
6323 self.assertEqual(len(users), 1)
6324 self.assertEqual(users[0].ip_address, self.pg0.remote_ip4n)
6325 self.assertEqual(users[0].nsessions, 1)
6327 @unittest.skipUnless(running_extended_tests, "part of extended tests")
6328 def test_session_limit_per_user(self):
6329 """ Maximum sessions per user limit """
6330 self.nat44_add_address(self.nat_addr)
6331 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
6332 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
6334 self.vapi.set_ipfix_exporter(collector_address=self.pg2.remote_ip4n,
6335 src_address=self.pg2.local_ip4n,
6337 template_interval=10)
6338 self.vapi.nat_set_timeouts(udp=5)
6340 # get maximum number of translations per user
6341 nat44_config = self.vapi.nat_show_config()
6344 for port in range(0, nat44_config.max_translations_per_user):
6345 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6346 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6347 UDP(sport=1025 + port, dport=1025 + port))
6350 self.pg0.add_stream(pkts)
6351 self.pg_enable_capture(self.pg_interfaces)
6353 capture = self.pg1.get_capture(len(pkts))
6355 self.vapi.nat_ipfix_enable_disable(domain_id=self.ipfix_domain_id,
6356 src_port=self.ipfix_src_port)
6358 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6359 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6360 UDP(sport=3001, dport=3002))
6361 self.pg0.add_stream(p)
6362 self.pg_enable_capture(self.pg_interfaces)
6364 capture = self.pg1.assert_nothing_captured()
6366 # verify IPFIX logging
6367 self.vapi.cli("ipfix flush") # FIXME this should be an API call
6369 capture = self.pg2.get_capture(10)
6370 ipfix = IPFIXDecoder()
6371 # first load template
6373 self.assertTrue(p.haslayer(IPFIX))
6374 if p.haslayer(Template):
6375 ipfix.add_template(p.getlayer(Template))
6376 # verify events in data set
6378 if p.haslayer(Data):
6379 data = ipfix.decode_data_set(p.getlayer(Set))
6380 self.verify_ipfix_max_entries_per_user(
6382 nat44_config.max_translations_per_user,
6383 self.pg0.remote_ip4n)
6386 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6387 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6388 UDP(sport=3001, dport=3002))
6389 self.pg0.add_stream(p)
6390 self.pg_enable_capture(self.pg_interfaces)
6392 self.pg1.get_capture(1)
6394 def test_syslog_sess(self):
6395 """ Test syslog session creation and deletion """
6396 self.vapi.syslog_set_filter(SYSLOG_SEVERITY.INFO)
6397 self.vapi.syslog_set_sender(self.pg2.local_ip4n, self.pg2.remote_ip4n)
6398 self.nat44_add_address(self.nat_addr)
6399 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
6400 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
6403 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
6404 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6405 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port))
6406 self.pg0.add_stream(p)
6407 self.pg_enable_capture(self.pg_interfaces)
6409 capture = self.pg1.get_capture(1)
6410 self.tcp_port_out = capture[0][TCP].sport
6411 capture = self.pg2.get_capture(1)
6412 self.verify_syslog_sess(capture[0][Raw].load)
6414 self.pg_enable_capture(self.pg_interfaces)
6416 self.nat44_add_address(self.nat_addr, is_add=0)
6417 capture = self.pg2.get_capture(1)
6418 self.verify_syslog_sess(capture[0][Raw].load, False)
6421 super(TestNAT44EndpointDependent, self).tearDown()
6422 if not self.vpp_dead:
6424 self.vapi.cli("clear logging")
6426 def show_commands_at_teardown(self):
6427 self.logger.info(self.vapi.cli("show nat44 addresses"))
6428 self.logger.info(self.vapi.cli("show nat44 interfaces"))
6429 self.logger.info(self.vapi.cli("show nat44 static mappings"))
6430 self.logger.info(self.vapi.cli("show nat44 interface address"))
6431 self.logger.info(self.vapi.cli("show nat44 sessions detail"))
6432 self.logger.info(self.vapi.cli("show nat44 hash tables detail"))
6433 self.logger.info(self.vapi.cli("show nat timeouts"))
6436 class TestNAT44Out2InDPO(MethodHolder):
6437 """ NAT44 Test Cases using out2in DPO """
6440 def setUpConstants(cls):
6441 super(TestNAT44Out2InDPO, cls).setUpConstants()
6442 cls.vpp_cmdline.extend(["nat", "{", "out2in dpo", "}"])
6445 def setUpClass(cls):
6446 super(TestNAT44Out2InDPO, cls).setUpClass()
6447 cls.vapi.cli("set log class nat level debug")
6450 cls.tcp_port_in = 6303
6451 cls.tcp_port_out = 6303
6452 cls.udp_port_in = 6304
6453 cls.udp_port_out = 6304
6454 cls.icmp_id_in = 6305
6455 cls.icmp_id_out = 6305
6456 cls.nat_addr = '10.0.0.3'
6457 cls.nat_addr_n = socket.inet_pton(socket.AF_INET, cls.nat_addr)
6458 cls.dst_ip4 = '192.168.70.1'
6460 cls.create_pg_interfaces(range(2))
6463 cls.pg0.config_ip4()
6464 cls.pg0.resolve_arp()
6467 cls.pg1.config_ip6()
6468 cls.pg1.resolve_ndp()
6470 cls.vapi.ip_add_del_route(dst_address=b'\x00' * 16,
6471 dst_address_length=0,
6472 next_hop_address=cls.pg1.remote_ip6n,
6473 next_hop_sw_if_index=cls.pg1.sw_if_index,
6477 super(TestNAT44Out2InDPO, cls).tearDownClass()
6481 def tearDownClass(cls):
6482 super(TestNAT44Out2InDPO, cls).tearDownClass()
6484 def configure_xlat(self):
6485 self.dst_ip6_pfx = '1:2:3::'
6486 self.dst_ip6_pfx_n = socket.inet_pton(socket.AF_INET6,
6488 self.dst_ip6_pfx_len = 96
6489 self.src_ip6_pfx = '4:5:6::'
6490 self.src_ip6_pfx_n = socket.inet_pton(socket.AF_INET6,
6492 self.src_ip6_pfx_len = 96
6493 self.vapi.map_add_domain(self.dst_ip6_pfx_n, self.dst_ip6_pfx_len,
6494 self.src_ip6_pfx_n, self.src_ip6_pfx_len,
6495 '\x00\x00\x00\x00', 0)
6497 @unittest.skip('Temporary disabled')
6498 def test_464xlat_ce(self):
6499 """ Test 464XLAT CE with NAT44 """
6501 nat_config = self.vapi.nat_show_config()
6502 self.assertEqual(1, nat_config.out2in_dpo)
6504 self.configure_xlat()
6506 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
6507 self.vapi.nat44_add_del_address_range(self.nat_addr_n, self.nat_addr_n)
6509 out_src_ip6 = self.compose_ip6(self.dst_ip4, self.dst_ip6_pfx,
6510 self.dst_ip6_pfx_len)
6511 out_dst_ip6 = self.compose_ip6(self.nat_addr, self.src_ip6_pfx,
6512 self.src_ip6_pfx_len)
6515 pkts = self.create_stream_in(self.pg0, self.pg1, self.dst_ip4)
6516 self.pg0.add_stream(pkts)
6517 self.pg_enable_capture(self.pg_interfaces)
6519 capture = self.pg1.get_capture(len(pkts))
6520 self.verify_capture_out_ip6(capture, nat_ip=out_dst_ip6,
6523 pkts = self.create_stream_out_ip6(self.pg1, out_src_ip6,
6525 self.pg1.add_stream(pkts)
6526 self.pg_enable_capture(self.pg_interfaces)
6528 capture = self.pg0.get_capture(len(pkts))
6529 self.verify_capture_in(capture, self.pg0)
6531 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index,
6533 self.vapi.nat44_add_del_address_range(self.nat_addr_n,
6534 self.nat_addr_n, is_add=0)
6536 @unittest.skip('Temporary disabled')
6537 def test_464xlat_ce_no_nat(self):
6538 """ Test 464XLAT CE without NAT44 """
6540 self.configure_xlat()
6542 out_src_ip6 = self.compose_ip6(self.dst_ip4, self.dst_ip6_pfx,
6543 self.dst_ip6_pfx_len)
6544 out_dst_ip6 = self.compose_ip6(self.pg0.remote_ip4, self.src_ip6_pfx,
6545 self.src_ip6_pfx_len)
6547 pkts = self.create_stream_in(self.pg0, self.pg1, self.dst_ip4)
6548 self.pg0.add_stream(pkts)
6549 self.pg_enable_capture(self.pg_interfaces)
6551 capture = self.pg1.get_capture(len(pkts))
6552 self.verify_capture_out_ip6(capture, dst_ip=out_src_ip6,
6553 nat_ip=out_dst_ip6, same_port=True)
6555 pkts = self.create_stream_out_ip6(self.pg1, out_src_ip6, out_dst_ip6)
6556 self.pg1.add_stream(pkts)
6557 self.pg_enable_capture(self.pg_interfaces)
6559 capture = self.pg0.get_capture(len(pkts))
6560 self.verify_capture_in(capture, self.pg0)
6563 class TestDeterministicNAT(MethodHolder):
6564 """ Deterministic NAT Test Cases """
6567 def setUpConstants(cls):
6568 super(TestDeterministicNAT, cls).setUpConstants()
6569 cls.vpp_cmdline.extend(["nat", "{", "deterministic", "}"])
6572 def setUpClass(cls):
6573 super(TestDeterministicNAT, cls).setUpClass()
6574 cls.vapi.cli("set log class nat level debug")
6577 cls.tcp_port_in = 6303
6578 cls.tcp_external_port = 6303
6579 cls.udp_port_in = 6304
6580 cls.udp_external_port = 6304
6581 cls.icmp_id_in = 6305
6582 cls.nat_addr = '10.0.0.3'
6584 cls.create_pg_interfaces(range(3))
6585 cls.interfaces = list(cls.pg_interfaces)
6587 for i in cls.interfaces:
6592 cls.pg0.generate_remote_hosts(2)
6593 cls.pg0.configure_ipv4_neighbors()
6596 super(TestDeterministicNAT, cls).tearDownClass()
6600 def tearDownClass(cls):
6601 super(TestDeterministicNAT, cls).tearDownClass()
6603 def create_stream_in(self, in_if, out_if, ttl=64):
6605 Create packet stream for inside network
6607 :param in_if: Inside interface
6608 :param out_if: Outside interface
6609 :param ttl: TTL of generated packets
6613 p = (Ether(dst=in_if.local_mac, src=in_if.remote_mac) /
6614 IP(src=in_if.remote_ip4, dst=out_if.remote_ip4, ttl=ttl) /
6615 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port))
6619 p = (Ether(dst=in_if.local_mac, src=in_if.remote_mac) /
6620 IP(src=in_if.remote_ip4, dst=out_if.remote_ip4, ttl=ttl) /
6621 UDP(sport=self.udp_port_in, dport=self.udp_external_port))
6625 p = (Ether(dst=in_if.local_mac, src=in_if.remote_mac) /
6626 IP(src=in_if.remote_ip4, dst=out_if.remote_ip4, ttl=ttl) /
6627 ICMP(id=self.icmp_id_in, type='echo-request'))
6632 def create_stream_out(self, out_if, dst_ip=None, ttl=64):
6634 Create packet stream for outside network
6636 :param out_if: Outside interface
6637 :param dst_ip: Destination IP address (Default use global NAT address)
6638 :param ttl: TTL of generated packets
6641 dst_ip = self.nat_addr
6644 p = (Ether(dst=out_if.local_mac, src=out_if.remote_mac) /
6645 IP(src=out_if.remote_ip4, dst=dst_ip, ttl=ttl) /
6646 TCP(dport=self.tcp_port_out, sport=self.tcp_external_port))
6650 p = (Ether(dst=out_if.local_mac, src=out_if.remote_mac) /
6651 IP(src=out_if.remote_ip4, dst=dst_ip, ttl=ttl) /
6652 UDP(dport=self.udp_port_out, sport=self.udp_external_port))
6656 p = (Ether(dst=out_if.local_mac, src=out_if.remote_mac) /
6657 IP(src=out_if.remote_ip4, dst=dst_ip, ttl=ttl) /
6658 ICMP(id=self.icmp_external_id, type='echo-reply'))
6663 def verify_capture_out(self, capture, nat_ip=None):
6665 Verify captured packets on outside network
6667 :param capture: Captured packets
6668 :param nat_ip: Translated IP address (Default use global NAT address)
6669 :param same_port: Source port number is not translated (Default False)
6672 nat_ip = self.nat_addr
6673 for packet in capture:
6675 self.assertEqual(packet[IP].src, nat_ip)
6676 if packet.haslayer(TCP):
6677 self.tcp_port_out = packet[TCP].sport
6678 elif packet.haslayer(UDP):
6679 self.udp_port_out = packet[UDP].sport
6681 self.icmp_external_id = packet[ICMP].id
6683 self.logger.error(ppp("Unexpected or invalid packet "
6684 "(outside network):", packet))
6687 def test_deterministic_mode(self):
6688 """ NAT plugin run deterministic mode """
6689 in_addr = '172.16.255.0'
6690 out_addr = '172.17.255.50'
6691 in_addr_t = '172.16.255.20'
6692 in_addr_n = socket.inet_aton(in_addr)
6693 out_addr_n = socket.inet_aton(out_addr)
6694 in_addr_t_n = socket.inet_aton(in_addr_t)
6698 nat_config = self.vapi.nat_show_config()
6699 self.assertEqual(1, nat_config.deterministic)
6701 self.vapi.nat_det_add_del_map(in_addr_n, in_plen, out_addr_n, out_plen)
6703 rep1 = self.vapi.nat_det_forward(in_addr_t_n)
6704 self.assertEqual(rep1.out_addr[:4], out_addr_n)
6705 rep2 = self.vapi.nat_det_reverse(out_addr_n, rep1.out_port_hi)
6706 self.assertEqual(rep2.in_addr[:4], in_addr_t_n)
6708 deterministic_mappings = self.vapi.nat_det_map_dump()
6709 self.assertEqual(len(deterministic_mappings), 1)
6710 dsm = deterministic_mappings[0]
6711 self.assertEqual(in_addr_n, dsm.in_addr[:4])
6712 self.assertEqual(in_plen, dsm.in_plen)
6713 self.assertEqual(out_addr_n, dsm.out_addr[:4])
6714 self.assertEqual(out_plen, dsm.out_plen)
6716 self.clear_nat_det()
6717 deterministic_mappings = self.vapi.nat_det_map_dump()
6718 self.assertEqual(len(deterministic_mappings), 0)
6720 def test_set_timeouts(self):
6721 """ Set deterministic NAT timeouts """
6722 timeouts_before = self.vapi.nat_get_timeouts()
6724 self.vapi.nat_set_timeouts(timeouts_before.udp + 10,
6725 timeouts_before.tcp_established + 10,
6726 timeouts_before.tcp_transitory + 10,
6727 timeouts_before.icmp + 10)
6729 timeouts_after = self.vapi.nat_get_timeouts()
6731 self.assertNotEqual(timeouts_before.udp, timeouts_after.udp)
6732 self.assertNotEqual(timeouts_before.icmp, timeouts_after.icmp)
6733 self.assertNotEqual(timeouts_before.tcp_established,
6734 timeouts_after.tcp_established)
6735 self.assertNotEqual(timeouts_before.tcp_transitory,
6736 timeouts_after.tcp_transitory)
6738 def test_det_in(self):
6739 """ Deterministic NAT translation test (TCP, UDP, ICMP) """
6741 nat_ip = "10.0.0.10"
6743 self.vapi.nat_det_add_del_map(self.pg0.remote_ip4n,
6745 socket.inet_aton(nat_ip),
6747 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
6748 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
6752 pkts = self.create_stream_in(self.pg0, self.pg1)
6753 self.pg0.add_stream(pkts)
6754 self.pg_enable_capture(self.pg_interfaces)
6756 capture = self.pg1.get_capture(len(pkts))
6757 self.verify_capture_out(capture, nat_ip)
6760 pkts = self.create_stream_out(self.pg1, nat_ip)
6761 self.pg1.add_stream(pkts)
6762 self.pg_enable_capture(self.pg_interfaces)
6764 capture = self.pg0.get_capture(len(pkts))
6765 self.verify_capture_in(capture, self.pg0)
6768 sessions = self.vapi.nat_det_session_dump(self.pg0.remote_ip4n)
6769 self.assertEqual(len(sessions), 3)
6773 self.assertEqual(s.ext_addr[:4], self.pg1.remote_ip4n)
6774 self.assertEqual(s.in_port, self.tcp_port_in)
6775 self.assertEqual(s.out_port, self.tcp_port_out)
6776 self.assertEqual(s.ext_port, self.tcp_external_port)
6780 self.assertEqual(s.ext_addr[:4], self.pg1.remote_ip4n)
6781 self.assertEqual(s.in_port, self.udp_port_in)
6782 self.assertEqual(s.out_port, self.udp_port_out)
6783 self.assertEqual(s.ext_port, self.udp_external_port)
6787 self.assertEqual(s.ext_addr[:4], self.pg1.remote_ip4n)
6788 self.assertEqual(s.in_port, self.icmp_id_in)
6789 self.assertEqual(s.out_port, self.icmp_external_id)
6791 def test_multiple_users(self):
6792 """ Deterministic NAT multiple users """
6794 nat_ip = "10.0.0.10"
6796 external_port = 6303
6798 host0 = self.pg0.remote_hosts[0]
6799 host1 = self.pg0.remote_hosts[1]
6801 self.vapi.nat_det_add_del_map(host0.ip4n,
6803 socket.inet_aton(nat_ip),
6805 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
6806 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
6810 p = (Ether(src=host0.mac, dst=self.pg0.local_mac) /
6811 IP(src=host0.ip4, dst=self.pg1.remote_ip4) /
6812 TCP(sport=port_in, dport=external_port))
6813 self.pg0.add_stream(p)
6814 self.pg_enable_capture(self.pg_interfaces)
6816 capture = self.pg1.get_capture(1)
6821 self.assertEqual(ip.src, nat_ip)
6822 self.assertEqual(ip.dst, self.pg1.remote_ip4)
6823 self.assertEqual(tcp.dport, external_port)
6824 port_out0 = tcp.sport
6826 self.logger.error(ppp("Unexpected or invalid packet:", p))
6830 p = (Ether(src=host1.mac, dst=self.pg0.local_mac) /
6831 IP(src=host1.ip4, dst=self.pg1.remote_ip4) /
6832 TCP(sport=port_in, dport=external_port))
6833 self.pg0.add_stream(p)
6834 self.pg_enable_capture(self.pg_interfaces)
6836 capture = self.pg1.get_capture(1)
6841 self.assertEqual(ip.src, nat_ip)
6842 self.assertEqual(ip.dst, self.pg1.remote_ip4)
6843 self.assertEqual(tcp.dport, external_port)
6844 port_out1 = tcp.sport
6846 self.logger.error(ppp("Unexpected or invalid packet:", p))
6849 dms = self.vapi.nat_det_map_dump()
6850 self.assertEqual(1, len(dms))
6851 self.assertEqual(2, dms[0].ses_num)
6854 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
6855 IP(src=self.pg1.remote_ip4, dst=nat_ip) /
6856 TCP(sport=external_port, dport=port_out0))
6857 self.pg1.add_stream(p)
6858 self.pg_enable_capture(self.pg_interfaces)
6860 capture = self.pg0.get_capture(1)
6865 self.assertEqual(ip.src, self.pg1.remote_ip4)
6866 self.assertEqual(ip.dst, host0.ip4)
6867 self.assertEqual(tcp.dport, port_in)
6868 self.assertEqual(tcp.sport, external_port)
6870 self.logger.error(ppp("Unexpected or invalid packet:", p))
6874 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
6875 IP(src=self.pg1.remote_ip4, dst=nat_ip) /
6876 TCP(sport=external_port, dport=port_out1))
6877 self.pg1.add_stream(p)
6878 self.pg_enable_capture(self.pg_interfaces)
6880 capture = self.pg0.get_capture(1)
6885 self.assertEqual(ip.src, self.pg1.remote_ip4)
6886 self.assertEqual(ip.dst, host1.ip4)
6887 self.assertEqual(tcp.dport, port_in)
6888 self.assertEqual(tcp.sport, external_port)
6890 self.logger.error(ppp("Unexpected or invalid packet", p))
6893 # session close api test
6894 self.vapi.nat_det_close_session_out(socket.inet_aton(nat_ip),
6896 self.pg1.remote_ip4n,
6898 dms = self.vapi.nat_det_map_dump()
6899 self.assertEqual(dms[0].ses_num, 1)
6901 self.vapi.nat_det_close_session_in(host0.ip4n,
6903 self.pg1.remote_ip4n,
6905 dms = self.vapi.nat_det_map_dump()
6906 self.assertEqual(dms[0].ses_num, 0)
6908 def test_tcp_session_close_detection_in(self):
6909 """ Deterministic NAT TCP session close from inside network """
6910 self.vapi.nat_det_add_del_map(self.pg0.remote_ip4n,
6912 socket.inet_aton(self.nat_addr),
6914 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
6915 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
6918 self.initiate_tcp_session(self.pg0, self.pg1)
6920 # close the session from inside
6922 # FIN packet in -> out
6923 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6924 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6925 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
6927 self.pg0.add_stream(p)
6928 self.pg_enable_capture(self.pg_interfaces)
6930 self.pg1.get_capture(1)
6934 # ACK packet out -> in
6935 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
6936 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
6937 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
6941 # FIN packet out -> in
6942 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
6943 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
6944 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
6948 self.pg1.add_stream(pkts)
6949 self.pg_enable_capture(self.pg_interfaces)
6951 self.pg0.get_capture(2)
6953 # ACK packet in -> out
6954 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6955 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6956 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
6958 self.pg0.add_stream(p)
6959 self.pg_enable_capture(self.pg_interfaces)
6961 self.pg1.get_capture(1)
6963 # Check if deterministic NAT44 closed the session
6964 dms = self.vapi.nat_det_map_dump()
6965 self.assertEqual(0, dms[0].ses_num)
6967 self.logger.error("TCP session termination failed")
6970 def test_tcp_session_close_detection_out(self):
6971 """ Deterministic NAT TCP session close from outside network """
6972 self.vapi.nat_det_add_del_map(self.pg0.remote_ip4n,
6974 socket.inet_aton(self.nat_addr),
6976 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
6977 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
6980 self.initiate_tcp_session(self.pg0, self.pg1)
6982 # close the session from outside
6984 # FIN packet out -> in
6985 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
6986 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
6987 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
6989 self.pg1.add_stream(p)
6990 self.pg_enable_capture(self.pg_interfaces)
6992 self.pg0.get_capture(1)
6996 # ACK packet in -> out
6997 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6998 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6999 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
7003 # ACK packet in -> out
7004 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
7005 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
7006 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
7010 self.pg0.add_stream(pkts)
7011 self.pg_enable_capture(self.pg_interfaces)
7013 self.pg1.get_capture(2)
7015 # ACK packet out -> in
7016 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
7017 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
7018 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
7020 self.pg1.add_stream(p)
7021 self.pg_enable_capture(self.pg_interfaces)
7023 self.pg0.get_capture(1)
7025 # Check if deterministic NAT44 closed the session
7026 dms = self.vapi.nat_det_map_dump()
7027 self.assertEqual(0, dms[0].ses_num)
7029 self.logger.error("TCP session termination failed")
7032 @unittest.skipUnless(running_extended_tests, "part of extended tests")
7033 def test_session_timeout(self):
7034 """ Deterministic NAT session timeouts """
7035 self.vapi.nat_det_add_del_map(self.pg0.remote_ip4n,
7037 socket.inet_aton(self.nat_addr),
7039 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
7040 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
7043 self.initiate_tcp_session(self.pg0, self.pg1)
7044 self.vapi.nat_set_timeouts(5, 5, 5, 5)
7045 pkts = self.create_stream_in(self.pg0, self.pg1)
7046 self.pg0.add_stream(pkts)
7047 self.pg_enable_capture(self.pg_interfaces)
7049 capture = self.pg1.get_capture(len(pkts))
7052 dms = self.vapi.nat_det_map_dump()
7053 self.assertEqual(0, dms[0].ses_num)
7055 @unittest.skipUnless(running_extended_tests, "part of extended tests")
7056 def test_session_limit_per_user(self):
7057 """ Deterministic NAT maximum sessions per user limit """
7058 self.vapi.nat_det_add_del_map(self.pg0.remote_ip4n,
7060 socket.inet_aton(self.nat_addr),
7062 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
7063 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
7065 self.vapi.set_ipfix_exporter(collector_address=self.pg2.remote_ip4n,
7066 src_address=self.pg2.local_ip4n,
7068 template_interval=10)
7069 self.vapi.nat_ipfix_enable_disable()
7072 for port in range(1025, 2025):
7073 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
7074 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
7075 UDP(sport=port, dport=port))
7078 self.pg0.add_stream(pkts)
7079 self.pg_enable_capture(self.pg_interfaces)
7081 capture = self.pg1.get_capture(len(pkts))
7083 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
7084 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
7085 UDP(sport=3001, dport=3002))
7086 self.pg0.add_stream(p)
7087 self.pg_enable_capture(self.pg_interfaces)
7089 capture = self.pg1.assert_nothing_captured()
7091 # verify ICMP error packet
7092 capture = self.pg0.get_capture(1)
7094 self.assertTrue(p.haslayer(ICMP))
7096 self.assertEqual(icmp.type, 3)
7097 self.assertEqual(icmp.code, 1)
7098 self.assertTrue(icmp.haslayer(IPerror))
7099 inner_ip = icmp[IPerror]
7100 self.assertEqual(inner_ip[UDPerror].sport, 3001)
7101 self.assertEqual(inner_ip[UDPerror].dport, 3002)
7103 dms = self.vapi.nat_det_map_dump()
7105 self.assertEqual(1000, dms[0].ses_num)
7107 # verify IPFIX logging
7108 self.vapi.cli("ipfix flush") # FIXME this should be an API call
7110 capture = self.pg2.get_capture(2)
7111 ipfix = IPFIXDecoder()
7112 # first load template
7114 self.assertTrue(p.haslayer(IPFIX))
7115 if p.haslayer(Template):
7116 ipfix.add_template(p.getlayer(Template))
7117 # verify events in data set
7119 if p.haslayer(Data):
7120 data = ipfix.decode_data_set(p.getlayer(Set))
7121 self.verify_ipfix_max_entries_per_user(data,
7123 self.pg0.remote_ip4n)
7125 def clear_nat_det(self):
7127 Clear deterministic NAT configuration.
7129 self.vapi.nat_ipfix_enable_disable(enable=0)
7130 self.vapi.nat_set_timeouts()
7131 deterministic_mappings = self.vapi.nat_det_map_dump()
7132 for dsm in deterministic_mappings:
7133 self.vapi.nat_det_add_del_map(dsm.in_addr,
7139 interfaces = self.vapi.nat44_interface_dump()
7140 for intf in interfaces:
7141 self.vapi.nat44_interface_add_del_feature(intf.sw_if_index,
7146 super(TestDeterministicNAT, self).tearDown()
7147 if not self.vpp_dead:
7148 self.clear_nat_det()
7150 def show_commands_at_teardown(self):
7151 self.logger.info(self.vapi.cli("show nat44 interfaces"))
7152 self.logger.info(self.vapi.cli("show nat timeouts"))
7154 self.vapi.cli("show nat44 deterministic mappings"))
7156 self.vapi.cli("show nat44 deterministic sessions"))
7159 class TestNAT64(MethodHolder):
7160 """ NAT64 Test Cases """
7163 def setUpConstants(cls):
7164 super(TestNAT64, cls).setUpConstants()
7165 cls.vpp_cmdline.extend(["nat", "{", "nat64 bib hash buckets 128",
7166 "nat64 st hash buckets 256", "}"])
7169 def setUpClass(cls):
7170 super(TestNAT64, cls).setUpClass()
7173 cls.tcp_port_in = 6303
7174 cls.tcp_port_out = 6303
7175 cls.udp_port_in = 6304
7176 cls.udp_port_out = 6304
7177 cls.icmp_id_in = 6305
7178 cls.icmp_id_out = 6305
7179 cls.tcp_external_port = 80
7180 cls.nat_addr = '10.0.0.3'
7181 cls.nat_addr_n = socket.inet_pton(socket.AF_INET, cls.nat_addr)
7183 cls.vrf1_nat_addr = '10.0.10.3'
7184 cls.vrf1_nat_addr_n = socket.inet_pton(socket.AF_INET,
7186 cls.ipfix_src_port = 4739
7187 cls.ipfix_domain_id = 1
7189 cls.create_pg_interfaces(range(6))
7190 cls.ip6_interfaces = list(cls.pg_interfaces[0:1])
7191 cls.ip6_interfaces.append(cls.pg_interfaces[2])
7192 cls.ip4_interfaces = list(cls.pg_interfaces[1:2])
7194 cls.vapi.ip_table_add_del(is_ipv6=1, is_add=1,
7195 table_id=cls.vrf1_id)
7197 cls.pg_interfaces[2].set_table_ip6(cls.vrf1_id)
7199 cls.pg0.generate_remote_hosts(2)
7201 for i in cls.ip6_interfaces:
7204 i.configure_ipv6_neighbors()
7206 for i in cls.ip4_interfaces:
7212 cls.pg3.config_ip4()
7213 cls.pg3.resolve_arp()
7214 cls.pg3.config_ip6()
7215 cls.pg3.configure_ipv6_neighbors()
7218 cls.pg5.config_ip6()
7221 super(TestNAT64, cls).tearDownClass()
7225 def tearDownClass(cls):
7226 super(TestNAT64, cls).tearDownClass()
7228 def test_nat64_inside_interface_handles_neighbor_advertisement(self):
7229 """ NAT64 inside interface handles Neighbor Advertisement """
7231 self.vapi.nat64_add_del_interface(self.pg5.sw_if_index)
7234 ping = (Ether(dst=self.pg5.local_mac, src=self.pg5.remote_mac) /
7235 IPv6(src=self.pg5.remote_ip6, dst=self.pg5.local_ip6) /
7236 ICMPv6EchoRequest())
7238 self.pg5.add_stream(pkts)
7239 self.pg_enable_capture(self.pg_interfaces)
7242 # Wait for Neighbor Solicitation
7243 capture = self.pg5.get_capture(len(pkts))
7246 self.assertEqual(packet[IPv6].src, self.pg5.local_ip6)
7247 self.assertEqual(packet.haslayer(ICMPv6ND_NS), 1)
7248 tgt = packet[ICMPv6ND_NS].tgt
7250 self.logger.error(ppp("Unexpected or invalid packet:", packet))
7253 # Send Neighbor Advertisement
7254 p = (Ether(dst=self.pg5.local_mac, src=self.pg5.remote_mac) /
7255 IPv6(src=self.pg5.remote_ip6, dst=self.pg5.local_ip6) /
7256 ICMPv6ND_NA(tgt=tgt) /
7257 ICMPv6NDOptDstLLAddr(lladdr=self.pg5.remote_mac))
7259 self.pg5.add_stream(pkts)
7260 self.pg_enable_capture(self.pg_interfaces)
7263 # Try to send ping again
7265 self.pg5.add_stream(pkts)
7266 self.pg_enable_capture(self.pg_interfaces)
7269 # Wait for ping reply
7270 capture = self.pg5.get_capture(len(pkts))
7273 self.assertEqual(packet[IPv6].src, self.pg5.local_ip6)
7274 self.assertEqual(packet[IPv6].dst, self.pg5.remote_ip6)
7275 self.assertEqual(packet.haslayer(ICMPv6EchoReply), 1)
7277 self.logger.error(ppp("Unexpected or invalid packet:", packet))
7280 def test_pool(self):
7281 """ Add/delete address to NAT64 pool """
7282 nat_addr = socket.inet_pton(socket.AF_INET, '1.2.3.4')
7284 self.vapi.nat64_add_del_pool_addr_range(nat_addr, nat_addr)
7286 addresses = self.vapi.nat64_pool_addr_dump()
7287 self.assertEqual(len(addresses), 1)
7288 self.assertEqual(addresses[0].address, nat_addr)
7290 self.vapi.nat64_add_del_pool_addr_range(nat_addr, nat_addr, is_add=0)
7292 addresses = self.vapi.nat64_pool_addr_dump()
7293 self.assertEqual(len(addresses), 0)
7295 def test_interface(self):
7296 """ Enable/disable NAT64 feature on the interface """
7297 self.vapi.nat64_add_del_interface(self.pg0.sw_if_index)
7298 self.vapi.nat64_add_del_interface(self.pg1.sw_if_index, is_inside=0)
7300 interfaces = self.vapi.nat64_interface_dump()
7301 self.assertEqual(len(interfaces), 2)
7304 for intf in interfaces:
7305 if intf.sw_if_index == self.pg0.sw_if_index:
7306 self.assertEqual(intf.is_inside, 1)
7308 elif intf.sw_if_index == self.pg1.sw_if_index:
7309 self.assertEqual(intf.is_inside, 0)
7311 self.assertTrue(pg0_found)
7312 self.assertTrue(pg1_found)
7314 features = self.vapi.cli("show interface features pg0")
7315 self.assertIn('nat64-in2out', features)
7316 features = self.vapi.cli("show interface features pg1")
7317 self.assertIn('nat64-out2in', features)
7319 self.vapi.nat64_add_del_interface(self.pg0.sw_if_index, is_add=0)
7320 self.vapi.nat64_add_del_interface(self.pg1.sw_if_index, is_add=0)
7322 interfaces = self.vapi.nat64_interface_dump()
7323 self.assertEqual(len(interfaces), 0)
7325 def test_static_bib(self):
7326 """ Add/delete static BIB entry """
7327 in_addr = socket.inet_pton(socket.AF_INET6,
7328 '2001:db8:85a3::8a2e:370:7334')
7329 out_addr = socket.inet_pton(socket.AF_INET, '10.1.1.3')
7332 proto = IP_PROTOS.tcp
7334 self.vapi.nat64_add_del_static_bib(in_addr,
7339 bib = self.vapi.nat64_bib_dump(IP_PROTOS.tcp)
7344 self.assertEqual(bibe.i_addr, in_addr)
7345 self.assertEqual(bibe.o_addr, out_addr)
7346 self.assertEqual(bibe.i_port, in_port)
7347 self.assertEqual(bibe.o_port, out_port)
7348 self.assertEqual(static_bib_num, 1)
7349 bibs = self.statistics.get_counter('/nat64/total-bibs')
7350 self.assertEqual(bibs[0][0], 1)
7352 self.vapi.nat64_add_del_static_bib(in_addr,
7358 bib = self.vapi.nat64_bib_dump(IP_PROTOS.tcp)
7363 self.assertEqual(static_bib_num, 0)
7364 bibs = self.statistics.get_counter('/nat64/total-bibs')
7365 self.assertEqual(bibs[0][0], 0)
7367 def test_set_timeouts(self):
7368 """ Set NAT64 timeouts """
7369 # verify default values
7370 timeouts = self.vapi.nat_get_timeouts()
7371 self.assertEqual(timeouts.udp, 300)
7372 self.assertEqual(timeouts.icmp, 60)
7373 self.assertEqual(timeouts.tcp_transitory, 240)
7374 self.assertEqual(timeouts.tcp_established, 7440)
7376 # set and verify custom values
7377 self.vapi.nat_set_timeouts(udp=200, icmp=30, tcp_transitory=250,
7378 tcp_established=7450)
7379 timeouts = self.vapi.nat_get_timeouts()
7380 self.assertEqual(timeouts.udp, 200)
7381 self.assertEqual(timeouts.icmp, 30)
7382 self.assertEqual(timeouts.tcp_transitory, 250)
7383 self.assertEqual(timeouts.tcp_established, 7450)
7385 def test_dynamic(self):
7386 """ NAT64 dynamic translation test """
7387 self.tcp_port_in = 6303
7388 self.udp_port_in = 6304
7389 self.icmp_id_in = 6305
7391 ses_num_start = self.nat64_get_ses_num()
7393 self.vapi.nat64_add_del_pool_addr_range(self.nat_addr_n,
7395 self.vapi.nat64_add_del_interface(self.pg0.sw_if_index)
7396 self.vapi.nat64_add_del_interface(self.pg1.sw_if_index, is_inside=0)
7399 tcpn = self.statistics.get_counter('/err/nat64-in2out/TCP packets')
7400 udpn = self.statistics.get_counter('/err/nat64-in2out/UDP packets')
7401 icmpn = self.statistics.get_counter('/err/nat64-in2out/ICMP packets')
7402 totaln = self.statistics.get_counter(
7403 '/err/nat64-in2out/good in2out packets processed')
7405 pkts = self.create_stream_in_ip6(self.pg0, self.pg1)
7406 self.pg0.add_stream(pkts)
7407 self.pg_enable_capture(self.pg_interfaces)
7409 capture = self.pg1.get_capture(len(pkts))
7410 self.verify_capture_out(capture, nat_ip=self.nat_addr,
7411 dst_ip=self.pg1.remote_ip4)
7413 err = self.statistics.get_counter('/err/nat64-in2out/TCP packets')
7414 self.assertEqual(err - tcpn, 1)
7415 err = self.statistics.get_counter('/err/nat64-in2out/UDP packets')
7416 self.assertEqual(err - udpn, 1)
7417 err = self.statistics.get_counter('/err/nat64-in2out/ICMP packets')
7418 self.assertEqual(err - icmpn, 1)
7419 err = self.statistics.get_counter(
7420 '/err/nat64-in2out/good in2out packets processed')
7421 self.assertEqual(err - totaln, 3)
7424 tcpn = self.statistics.get_counter('/err/nat64-out2in/TCP packets')
7425 udpn = self.statistics.get_counter('/err/nat64-out2in/UDP packets')
7426 icmpn = self.statistics.get_counter('/err/nat64-out2in/ICMP packets')
7427 totaln = self.statistics.get_counter(
7428 '/err/nat64-out2in/good out2in packets processed')
7430 pkts = self.create_stream_out(self.pg1, dst_ip=self.nat_addr)
7431 self.pg1.add_stream(pkts)
7432 self.pg_enable_capture(self.pg_interfaces)
7434 capture = self.pg0.get_capture(len(pkts))
7435 ip = IPv6(src=''.join(['64:ff9b::', self.pg1.remote_ip4]))
7436 self.verify_capture_in_ip6(capture, ip[IPv6].src, self.pg0.remote_ip6)
7438 err = self.statistics.get_counter('/err/nat64-out2in/TCP packets')
7439 self.assertEqual(err - tcpn, 1)
7440 err = self.statistics.get_counter('/err/nat64-out2in/UDP packets')
7441 self.assertEqual(err - udpn, 1)
7442 err = self.statistics.get_counter('/err/nat64-out2in/ICMP packets')
7443 self.assertEqual(err - icmpn, 1)
7444 err = self.statistics.get_counter(
7445 '/err/nat64-out2in/good out2in packets processed')
7446 self.assertEqual(err - totaln, 3)
7448 bibs = self.statistics.get_counter('/nat64/total-bibs')
7449 self.assertEqual(bibs[0][0], 3)
7450 sessions = self.statistics.get_counter('/nat64/total-sessions')
7451 self.assertEqual(sessions[0][0], 3)
7454 pkts = self.create_stream_in_ip6(self.pg0, self.pg1)
7455 self.pg0.add_stream(pkts)
7456 self.pg_enable_capture(self.pg_interfaces)
7458 capture = self.pg1.get_capture(len(pkts))
7459 self.verify_capture_out(capture, nat_ip=self.nat_addr,
7460 dst_ip=self.pg1.remote_ip4)
7463 pkts = self.create_stream_out(self.pg1, dst_ip=self.nat_addr)
7464 self.pg1.add_stream(pkts)
7465 self.pg_enable_capture(self.pg_interfaces)
7467 capture = self.pg0.get_capture(len(pkts))
7468 self.verify_capture_in_ip6(capture, ip[IPv6].src, self.pg0.remote_ip6)
7470 ses_num_end = self.nat64_get_ses_num()
7472 self.assertEqual(ses_num_end - ses_num_start, 3)
7474 # tenant with specific VRF
7475 self.vapi.nat64_add_del_pool_addr_range(self.vrf1_nat_addr_n,
7476 self.vrf1_nat_addr_n,
7477 vrf_id=self.vrf1_id)
7478 self.vapi.nat64_add_del_interface(self.pg2.sw_if_index)
7480 pkts = self.create_stream_in_ip6(self.pg2, self.pg1)
7481 self.pg2.add_stream(pkts)
7482 self.pg_enable_capture(self.pg_interfaces)
7484 capture = self.pg1.get_capture(len(pkts))
7485 self.verify_capture_out(capture, nat_ip=self.vrf1_nat_addr,
7486 dst_ip=self.pg1.remote_ip4)
7488 pkts = self.create_stream_out(self.pg1, dst_ip=self.vrf1_nat_addr)
7489 self.pg1.add_stream(pkts)
7490 self.pg_enable_capture(self.pg_interfaces)
7492 capture = self.pg2.get_capture(len(pkts))
7493 self.verify_capture_in_ip6(capture, ip[IPv6].src, self.pg2.remote_ip6)
7495 def test_static(self):
7496 """ NAT64 static translation test """
7497 self.tcp_port_in = 60303
7498 self.udp_port_in = 60304
7499 self.icmp_id_in = 60305
7500 self.tcp_port_out = 60303
7501 self.udp_port_out = 60304
7502 self.icmp_id_out = 60305
7504 ses_num_start = self.nat64_get_ses_num()
7506 self.vapi.nat64_add_del_pool_addr_range(self.nat_addr_n,
7508 self.vapi.nat64_add_del_interface(self.pg0.sw_if_index)
7509 self.vapi.nat64_add_del_interface(self.pg1.sw_if_index, is_inside=0)
7511 self.vapi.nat64_add_del_static_bib(self.pg0.remote_ip6n,
7516 self.vapi.nat64_add_del_static_bib(self.pg0.remote_ip6n,
7521 self.vapi.nat64_add_del_static_bib(self.pg0.remote_ip6n,
7528 pkts = self.create_stream_in_ip6(self.pg0, self.pg1)
7529 self.pg0.add_stream(pkts)
7530 self.pg_enable_capture(self.pg_interfaces)
7532 capture = self.pg1.get_capture(len(pkts))
7533 self.verify_capture_out(capture, nat_ip=self.nat_addr,
7534 dst_ip=self.pg1.remote_ip4, same_port=True)
7537 pkts = self.create_stream_out(self.pg1, dst_ip=self.nat_addr)
7538 self.pg1.add_stream(pkts)
7539 self.pg_enable_capture(self.pg_interfaces)
7541 capture = self.pg0.get_capture(len(pkts))
7542 ip = IPv6(src=''.join(['64:ff9b::', self.pg1.remote_ip4]))
7543 self.verify_capture_in_ip6(capture, ip[IPv6].src, self.pg0.remote_ip6)
7545 ses_num_end = self.nat64_get_ses_num()
7547 self.assertEqual(ses_num_end - ses_num_start, 3)
7549 @unittest.skipUnless(running_extended_tests, "part of extended tests")
7550 def test_session_timeout(self):
7551 """ NAT64 session timeout """
7552 self.icmp_id_in = 1234
7553 self.vapi.nat64_add_del_pool_addr_range(self.nat_addr_n,
7555 self.vapi.nat64_add_del_interface(self.pg0.sw_if_index)
7556 self.vapi.nat64_add_del_interface(self.pg1.sw_if_index, is_inside=0)
7557 self.vapi.nat_set_timeouts(icmp=5, tcp_transitory=5, tcp_established=5)
7559 pkts = self.create_stream_in_ip6(self.pg0, self.pg1)
7560 self.pg0.add_stream(pkts)
7561 self.pg_enable_capture(self.pg_interfaces)
7563 capture = self.pg1.get_capture(len(pkts))
7565 ses_num_before_timeout = self.nat64_get_ses_num()
7569 # ICMP and TCP session after timeout
7570 ses_num_after_timeout = self.nat64_get_ses_num()
7571 self.assertEqual(ses_num_before_timeout - ses_num_after_timeout, 2)
7573 def test_icmp_error(self):
7574 """ NAT64 ICMP Error message translation """
7575 self.tcp_port_in = 6303
7576 self.udp_port_in = 6304
7577 self.icmp_id_in = 6305
7579 self.vapi.nat64_add_del_pool_addr_range(self.nat_addr_n,
7581 self.vapi.nat64_add_del_interface(self.pg0.sw_if_index)
7582 self.vapi.nat64_add_del_interface(self.pg1.sw_if_index, is_inside=0)
7584 # send some packets to create sessions
7585 pkts = self.create_stream_in_ip6(self.pg0, self.pg1)
7586 self.pg0.add_stream(pkts)
7587 self.pg_enable_capture(self.pg_interfaces)
7589 capture_ip4 = self.pg1.get_capture(len(pkts))
7590 self.verify_capture_out(capture_ip4,
7591 nat_ip=self.nat_addr,
7592 dst_ip=self.pg1.remote_ip4)
7594 pkts = self.create_stream_out(self.pg1, dst_ip=self.nat_addr)
7595 self.pg1.add_stream(pkts)
7596 self.pg_enable_capture(self.pg_interfaces)
7598 capture_ip6 = self.pg0.get_capture(len(pkts))
7599 ip = IPv6(src=''.join(['64:ff9b::', self.pg1.remote_ip4]))
7600 self.verify_capture_in_ip6(capture_ip6, ip[IPv6].src,
7601 self.pg0.remote_ip6)
7604 pkts = [Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
7605 IPv6(src=self.pg0.remote_ip6, dst=ip[IPv6].src) /
7606 ICMPv6DestUnreach(code=1) /
7607 packet[IPv6] for packet in capture_ip6]
7608 self.pg0.add_stream(pkts)
7609 self.pg_enable_capture(self.pg_interfaces)
7611 capture = self.pg1.get_capture(len(pkts))
7612 for packet in capture:
7614 self.assertEqual(packet[IP].src, self.nat_addr)
7615 self.assertEqual(packet[IP].dst, self.pg1.remote_ip4)
7616 self.assertEqual(packet[ICMP].type, 3)
7617 self.assertEqual(packet[ICMP].code, 13)
7618 inner = packet[IPerror]
7619 self.assertEqual(inner.src, self.pg1.remote_ip4)
7620 self.assertEqual(inner.dst, self.nat_addr)
7621 self.assert_packet_checksums_valid(packet)
7622 if inner.haslayer(TCPerror):
7623 self.assertEqual(inner[TCPerror].dport, self.tcp_port_out)
7624 elif inner.haslayer(UDPerror):
7625 self.assertEqual(inner[UDPerror].dport, self.udp_port_out)
7627 self.assertEqual(inner[ICMPerror].id, self.icmp_id_out)
7629 self.logger.error(ppp("Unexpected or invalid packet:", packet))
7633 pkts = [Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
7634 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
7635 ICMP(type=3, code=13) /
7636 packet[IP] for packet in capture_ip4]
7637 self.pg1.add_stream(pkts)
7638 self.pg_enable_capture(self.pg_interfaces)
7640 capture = self.pg0.get_capture(len(pkts))
7641 for packet in capture:
7643 self.assertEqual(packet[IPv6].src, ip.src)
7644 self.assertEqual(packet[IPv6].dst, self.pg0.remote_ip6)
7645 icmp = packet[ICMPv6DestUnreach]
7646 self.assertEqual(icmp.code, 1)
7647 inner = icmp[IPerror6]
7648 self.assertEqual(inner.src, self.pg0.remote_ip6)
7649 self.assertEqual(inner.dst, ip.src)
7650 self.assert_icmpv6_checksum_valid(packet)
7651 if inner.haslayer(TCPerror):
7652 self.assertEqual(inner[TCPerror].sport, self.tcp_port_in)
7653 elif inner.haslayer(UDPerror):
7654 self.assertEqual(inner[UDPerror].sport, self.udp_port_in)
7656 self.assertEqual(inner[ICMPv6EchoRequest].id,
7659 self.logger.error(ppp("Unexpected or invalid packet:", packet))
7662 def test_hairpinning(self):
7663 """ NAT64 hairpinning """
7665 client = self.pg0.remote_hosts[0]
7666 server = self.pg0.remote_hosts[1]
7667 server_tcp_in_port = 22
7668 server_tcp_out_port = 4022
7669 server_udp_in_port = 23
7670 server_udp_out_port = 4023
7671 client_tcp_in_port = 1234
7672 client_udp_in_port = 1235
7673 client_tcp_out_port = 0
7674 client_udp_out_port = 0
7675 ip = IPv6(src=''.join(['64:ff9b::', self.nat_addr]))
7676 nat_addr_ip6 = ip.src
7678 self.vapi.nat64_add_del_pool_addr_range(self.nat_addr_n,
7680 self.vapi.nat64_add_del_interface(self.pg0.sw_if_index)
7681 self.vapi.nat64_add_del_interface(self.pg1.sw_if_index, is_inside=0)
7683 self.vapi.nat64_add_del_static_bib(server.ip6n,
7686 server_tcp_out_port,
7688 self.vapi.nat64_add_del_static_bib(server.ip6n,
7691 server_udp_out_port,
7696 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
7697 IPv6(src=client.ip6, dst=nat_addr_ip6) /
7698 TCP(sport=client_tcp_in_port, dport=server_tcp_out_port))
7700 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
7701 IPv6(src=client.ip6, dst=nat_addr_ip6) /
7702 UDP(sport=client_udp_in_port, dport=server_udp_out_port))
7704 self.pg0.add_stream(pkts)
7705 self.pg_enable_capture(self.pg_interfaces)
7707 capture = self.pg0.get_capture(len(pkts))
7708 for packet in capture:
7710 self.assertEqual(packet[IPv6].src, nat_addr_ip6)
7711 self.assertEqual(packet[IPv6].dst, server.ip6)
7712 self.assert_packet_checksums_valid(packet)
7713 if packet.haslayer(TCP):
7714 self.assertNotEqual(packet[TCP].sport, client_tcp_in_port)
7715 self.assertEqual(packet[TCP].dport, server_tcp_in_port)
7716 client_tcp_out_port = packet[TCP].sport
7718 self.assertNotEqual(packet[UDP].sport, client_udp_in_port)
7719 self.assertEqual(packet[UDP].dport, server_udp_in_port)
7720 client_udp_out_port = packet[UDP].sport
7722 self.logger.error(ppp("Unexpected or invalid packet:", packet))
7727 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
7728 IPv6(src=server.ip6, dst=nat_addr_ip6) /
7729 TCP(sport=server_tcp_in_port, dport=client_tcp_out_port))
7731 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
7732 IPv6(src=server.ip6, dst=nat_addr_ip6) /
7733 UDP(sport=server_udp_in_port, dport=client_udp_out_port))
7735 self.pg0.add_stream(pkts)
7736 self.pg_enable_capture(self.pg_interfaces)
7738 capture = self.pg0.get_capture(len(pkts))
7739 for packet in capture:
7741 self.assertEqual(packet[IPv6].src, nat_addr_ip6)
7742 self.assertEqual(packet[IPv6].dst, client.ip6)
7743 self.assert_packet_checksums_valid(packet)
7744 if packet.haslayer(TCP):
7745 self.assertEqual(packet[TCP].sport, server_tcp_out_port)
7746 self.assertEqual(packet[TCP].dport, client_tcp_in_port)
7748 self.assertEqual(packet[UDP].sport, server_udp_out_port)
7749 self.assertEqual(packet[UDP].dport, client_udp_in_port)
7751 self.logger.error(ppp("Unexpected or invalid packet:", packet))
7756 pkts = [Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
7757 IPv6(src=client.ip6, dst=nat_addr_ip6) /
7758 ICMPv6DestUnreach(code=1) /
7759 packet[IPv6] for packet in capture]
7760 self.pg0.add_stream(pkts)
7761 self.pg_enable_capture(self.pg_interfaces)
7763 capture = self.pg0.get_capture(len(pkts))
7764 for packet in capture:
7766 self.assertEqual(packet[IPv6].src, nat_addr_ip6)
7767 self.assertEqual(packet[IPv6].dst, server.ip6)
7768 icmp = packet[ICMPv6DestUnreach]
7769 self.assertEqual(icmp.code, 1)
7770 inner = icmp[IPerror6]
7771 self.assertEqual(inner.src, server.ip6)
7772 self.assertEqual(inner.dst, nat_addr_ip6)
7773 self.assert_packet_checksums_valid(packet)
7774 if inner.haslayer(TCPerror):
7775 self.assertEqual(inner[TCPerror].sport, server_tcp_in_port)
7776 self.assertEqual(inner[TCPerror].dport,
7777 client_tcp_out_port)
7779 self.assertEqual(inner[UDPerror].sport, server_udp_in_port)
7780 self.assertEqual(inner[UDPerror].dport,
7781 client_udp_out_port)
7783 self.logger.error(ppp("Unexpected or invalid packet:", packet))
7786 def test_prefix(self):
7787 """ NAT64 Network-Specific Prefix """
7789 self.vapi.nat64_add_del_pool_addr_range(self.nat_addr_n,
7791 self.vapi.nat64_add_del_interface(self.pg0.sw_if_index)
7792 self.vapi.nat64_add_del_interface(self.pg1.sw_if_index, is_inside=0)
7793 self.vapi.nat64_add_del_pool_addr_range(self.vrf1_nat_addr_n,
7794 self.vrf1_nat_addr_n,
7795 vrf_id=self.vrf1_id)
7796 self.vapi.nat64_add_del_interface(self.pg2.sw_if_index)
7799 global_pref64 = "2001:db8::"
7800 global_pref64_n = socket.inet_pton(socket.AF_INET6, global_pref64)
7801 global_pref64_len = 32
7802 self.vapi.nat64_add_del_prefix(global_pref64_n, global_pref64_len)
7804 prefix = self.vapi.nat64_prefix_dump()
7805 self.assertEqual(len(prefix), 1)
7806 self.assertEqual(prefix[0].prefix, global_pref64_n)
7807 self.assertEqual(prefix[0].prefix_len, global_pref64_len)
7808 self.assertEqual(prefix[0].vrf_id, 0)
7810 # Add tenant specific prefix
7811 vrf1_pref64 = "2001:db8:122:300::"
7812 vrf1_pref64_n = socket.inet_pton(socket.AF_INET6, vrf1_pref64)
7813 vrf1_pref64_len = 56
7814 self.vapi.nat64_add_del_prefix(vrf1_pref64_n,
7816 vrf_id=self.vrf1_id)
7817 prefix = self.vapi.nat64_prefix_dump()
7818 self.assertEqual(len(prefix), 2)
7821 pkts = self.create_stream_in_ip6(self.pg0,
7824 plen=global_pref64_len)
7825 self.pg0.add_stream(pkts)
7826 self.pg_enable_capture(self.pg_interfaces)
7828 capture = self.pg1.get_capture(len(pkts))
7829 self.verify_capture_out(capture, nat_ip=self.nat_addr,
7830 dst_ip=self.pg1.remote_ip4)
7832 pkts = self.create_stream_out(self.pg1, dst_ip=self.nat_addr)
7833 self.pg1.add_stream(pkts)
7834 self.pg_enable_capture(self.pg_interfaces)
7836 capture = self.pg0.get_capture(len(pkts))
7837 dst_ip = self.compose_ip6(self.pg1.remote_ip4,
7840 self.verify_capture_in_ip6(capture, dst_ip, self.pg0.remote_ip6)
7842 # Tenant specific prefix
7843 pkts = self.create_stream_in_ip6(self.pg2,
7846 plen=vrf1_pref64_len)
7847 self.pg2.add_stream(pkts)
7848 self.pg_enable_capture(self.pg_interfaces)
7850 capture = self.pg1.get_capture(len(pkts))
7851 self.verify_capture_out(capture, nat_ip=self.vrf1_nat_addr,
7852 dst_ip=self.pg1.remote_ip4)
7854 pkts = self.create_stream_out(self.pg1, dst_ip=self.vrf1_nat_addr)
7855 self.pg1.add_stream(pkts)
7856 self.pg_enable_capture(self.pg_interfaces)
7858 capture = self.pg2.get_capture(len(pkts))
7859 dst_ip = self.compose_ip6(self.pg1.remote_ip4,
7862 self.verify_capture_in_ip6(capture, dst_ip, self.pg2.remote_ip6)
7864 def test_unknown_proto(self):
7865 """ NAT64 translate packet with unknown protocol """
7867 self.vapi.nat64_add_del_pool_addr_range(self.nat_addr_n,
7869 self.vapi.nat64_add_del_interface(self.pg0.sw_if_index)
7870 self.vapi.nat64_add_del_interface(self.pg1.sw_if_index, is_inside=0)
7871 remote_ip6 = self.compose_ip6(self.pg1.remote_ip4, '64:ff9b::', 96)
7874 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
7875 IPv6(src=self.pg0.remote_ip6, dst=remote_ip6) /
7876 TCP(sport=self.tcp_port_in, dport=20))
7877 self.pg0.add_stream(p)
7878 self.pg_enable_capture(self.pg_interfaces)
7880 p = self.pg1.get_capture(1)
7882 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
7883 IPv6(src=self.pg0.remote_ip6, dst=remote_ip6, nh=47) /
7885 IP(src=self.pg2.local_ip4, dst=self.pg2.remote_ip4) /
7886 TCP(sport=1234, dport=1234))
7887 self.pg0.add_stream(p)
7888 self.pg_enable_capture(self.pg_interfaces)
7890 p = self.pg1.get_capture(1)
7893 self.assertEqual(packet[IP].src, self.nat_addr)
7894 self.assertEqual(packet[IP].dst, self.pg1.remote_ip4)
7895 self.assertEqual(packet.haslayer(GRE), 1)
7896 self.assert_packet_checksums_valid(packet)
7898 self.logger.error(ppp("Unexpected or invalid packet:", packet))
7902 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
7903 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
7905 IP(src=self.pg2.remote_ip4, dst=self.pg2.local_ip4) /
7906 TCP(sport=1234, dport=1234))
7907 self.pg1.add_stream(p)
7908 self.pg_enable_capture(self.pg_interfaces)
7910 p = self.pg0.get_capture(1)
7913 self.assertEqual(packet[IPv6].src, remote_ip6)
7914 self.assertEqual(packet[IPv6].dst, self.pg0.remote_ip6)
7915 self.assertEqual(packet[IPv6].nh, 47)
7917 self.logger.error(ppp("Unexpected or invalid packet:", packet))
7920 def test_hairpinning_unknown_proto(self):
7921 """ NAT64 translate packet with unknown protocol - hairpinning """
7923 client = self.pg0.remote_hosts[0]
7924 server = self.pg0.remote_hosts[1]
7925 server_tcp_in_port = 22
7926 server_tcp_out_port = 4022
7927 client_tcp_in_port = 1234
7928 client_tcp_out_port = 1235
7929 server_nat_ip = "10.0.0.100"
7930 client_nat_ip = "10.0.0.110"
7931 server_nat_ip_n = socket.inet_pton(socket.AF_INET, server_nat_ip)
7932 client_nat_ip_n = socket.inet_pton(socket.AF_INET, client_nat_ip)
7933 server_nat_ip6 = self.compose_ip6(server_nat_ip, '64:ff9b::', 96)
7934 client_nat_ip6 = self.compose_ip6(client_nat_ip, '64:ff9b::', 96)
7936 self.vapi.nat64_add_del_pool_addr_range(server_nat_ip_n,
7938 self.vapi.nat64_add_del_interface(self.pg0.sw_if_index)
7939 self.vapi.nat64_add_del_interface(self.pg1.sw_if_index, is_inside=0)
7941 self.vapi.nat64_add_del_static_bib(server.ip6n,
7944 server_tcp_out_port,
7947 self.vapi.nat64_add_del_static_bib(server.ip6n,
7953 self.vapi.nat64_add_del_static_bib(client.ip6n,
7956 client_tcp_out_port,
7960 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
7961 IPv6(src=client.ip6, dst=server_nat_ip6) /
7962 TCP(sport=client_tcp_in_port, dport=server_tcp_out_port))
7963 self.pg0.add_stream(p)
7964 self.pg_enable_capture(self.pg_interfaces)
7966 p = self.pg0.get_capture(1)
7968 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
7969 IPv6(src=client.ip6, dst=server_nat_ip6, nh=IP_PROTOS.gre) /
7971 IP(src=self.pg2.local_ip4, dst=self.pg2.remote_ip4) /
7972 TCP(sport=1234, dport=1234))
7973 self.pg0.add_stream(p)
7974 self.pg_enable_capture(self.pg_interfaces)
7976 p = self.pg0.get_capture(1)
7979 self.assertEqual(packet[IPv6].src, client_nat_ip6)
7980 self.assertEqual(packet[IPv6].dst, server.ip6)
7981 self.assertEqual(packet[IPv6].nh, IP_PROTOS.gre)
7983 self.logger.error(ppp("Unexpected or invalid packet:", packet))
7987 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
7988 IPv6(src=server.ip6, dst=client_nat_ip6, nh=IP_PROTOS.gre) /
7990 IP(src=self.pg2.remote_ip4, dst=self.pg2.local_ip4) /
7991 TCP(sport=1234, dport=1234))
7992 self.pg0.add_stream(p)
7993 self.pg_enable_capture(self.pg_interfaces)
7995 p = self.pg0.get_capture(1)
7998 self.assertEqual(packet[IPv6].src, server_nat_ip6)
7999 self.assertEqual(packet[IPv6].dst, client.ip6)
8000 self.assertEqual(packet[IPv6].nh, IP_PROTOS.gre)
8002 self.logger.error(ppp("Unexpected or invalid packet:", packet))
8005 def test_one_armed_nat64(self):
8006 """ One armed NAT64 """
8008 remote_host_ip6 = self.compose_ip6(self.pg3.remote_ip4,
8012 self.vapi.nat64_add_del_pool_addr_range(self.nat_addr_n,
8014 self.vapi.nat64_add_del_interface(self.pg3.sw_if_index)
8015 self.vapi.nat64_add_del_interface(self.pg3.sw_if_index, is_inside=0)
8018 p = (Ether(src=self.pg3.remote_mac, dst=self.pg3.local_mac) /
8019 IPv6(src=self.pg3.remote_ip6, dst=remote_host_ip6) /
8020 TCP(sport=12345, dport=80))
8021 self.pg3.add_stream(p)
8022 self.pg_enable_capture(self.pg_interfaces)
8024 capture = self.pg3.get_capture(1)
8029 self.assertEqual(ip.src, self.nat_addr)
8030 self.assertEqual(ip.dst, self.pg3.remote_ip4)
8031 self.assertNotEqual(tcp.sport, 12345)
8032 external_port = tcp.sport
8033 self.assertEqual(tcp.dport, 80)
8034 self.assert_packet_checksums_valid(p)
8036 self.logger.error(ppp("Unexpected or invalid packet:", p))
8040 p = (Ether(src=self.pg3.remote_mac, dst=self.pg3.local_mac) /
8041 IP(src=self.pg3.remote_ip4, dst=self.nat_addr) /
8042 TCP(sport=80, dport=external_port))
8043 self.pg3.add_stream(p)
8044 self.pg_enable_capture(self.pg_interfaces)
8046 capture = self.pg3.get_capture(1)
8051 self.assertEqual(ip.src, remote_host_ip6)
8052 self.assertEqual(ip.dst, self.pg3.remote_ip6)
8053 self.assertEqual(tcp.sport, 80)
8054 self.assertEqual(tcp.dport, 12345)
8055 self.assert_packet_checksums_valid(p)
8057 self.logger.error(ppp("Unexpected or invalid packet:", p))
8060 def test_frag_in_order(self):
8061 """ NAT64 translate fragments arriving in order """
8062 self.tcp_port_in = random.randint(1025, 65535)
8064 self.vapi.nat64_add_del_pool_addr_range(self.nat_addr_n,
8066 self.vapi.nat64_add_del_interface(self.pg0.sw_if_index)
8067 self.vapi.nat64_add_del_interface(self.pg1.sw_if_index, is_inside=0)
8069 reass = self.vapi.nat_reass_dump()
8070 reass_n_start = len(reass)
8074 pkts = self.create_stream_frag_ip6(self.pg0, self.pg1.remote_ip4,
8075 self.tcp_port_in, 20, data)
8076 self.pg0.add_stream(pkts)
8077 self.pg_enable_capture(self.pg_interfaces)
8079 frags = self.pg1.get_capture(len(pkts))
8080 p = self.reass_frags_and_verify(frags,
8082 self.pg1.remote_ip4)
8083 self.assertEqual(p[TCP].dport, 20)
8084 self.assertNotEqual(p[TCP].sport, self.tcp_port_in)
8085 self.tcp_port_out = p[TCP].sport
8086 self.assertEqual(data, p[Raw].load)
8089 data = b"A" * 4 + b"b" * 16 + b"C" * 3
8090 pkts = self.create_stream_frag(self.pg1,
8095 self.pg1.add_stream(pkts)
8096 self.pg_enable_capture(self.pg_interfaces)
8098 frags = self.pg0.get_capture(len(pkts))
8099 src = self.compose_ip6(self.pg1.remote_ip4, '64:ff9b::', 96)
8100 p = self.reass_frags_and_verify_ip6(frags, src, self.pg0.remote_ip6)
8101 self.assertEqual(p[TCP].sport, 20)
8102 self.assertEqual(p[TCP].dport, self.tcp_port_in)
8103 self.assertEqual(data, p[Raw].load)
8105 reass = self.vapi.nat_reass_dump()
8106 reass_n_end = len(reass)
8108 self.assertEqual(reass_n_end - reass_n_start, 2)
8110 def test_reass_hairpinning(self):
8111 """ NAT64 fragments hairpinning """
8113 server = self.pg0.remote_hosts[1]
8114 server_in_port = random.randint(1025, 65535)
8115 server_out_port = random.randint(1025, 65535)
8116 client_in_port = random.randint(1025, 65535)
8117 ip = IPv6(src=''.join(['64:ff9b::', self.nat_addr]))
8118 nat_addr_ip6 = ip.src
8120 self.vapi.nat64_add_del_pool_addr_range(self.nat_addr_n,
8122 self.vapi.nat64_add_del_interface(self.pg0.sw_if_index)
8123 self.vapi.nat64_add_del_interface(self.pg1.sw_if_index, is_inside=0)
8125 # add static BIB entry for server
8126 self.vapi.nat64_add_del_static_bib(server.ip6n,
8132 # send packet from host to server
8133 pkts = self.create_stream_frag_ip6(self.pg0,
8138 self.pg0.add_stream(pkts)
8139 self.pg_enable_capture(self.pg_interfaces)
8141 frags = self.pg0.get_capture(len(pkts))
8142 p = self.reass_frags_and_verify_ip6(frags, nat_addr_ip6, server.ip6)
8143 self.assertNotEqual(p[TCP].sport, client_in_port)
8144 self.assertEqual(p[TCP].dport, server_in_port)
8145 self.assertEqual(data, p[Raw].load)
8147 def test_frag_out_of_order(self):
8148 """ NAT64 translate fragments arriving out of order """
8149 self.tcp_port_in = random.randint(1025, 65535)
8151 self.vapi.nat64_add_del_pool_addr_range(self.nat_addr_n,
8153 self.vapi.nat64_add_del_interface(self.pg0.sw_if_index)
8154 self.vapi.nat64_add_del_interface(self.pg1.sw_if_index, is_inside=0)
8158 pkts = self.create_stream_frag_ip6(self.pg0, self.pg1.remote_ip4,
8159 self.tcp_port_in, 20, data)
8161 self.pg0.add_stream(pkts)
8162 self.pg_enable_capture(self.pg_interfaces)
8164 frags = self.pg1.get_capture(len(pkts))
8165 p = self.reass_frags_and_verify(frags,
8167 self.pg1.remote_ip4)
8168 self.assertEqual(p[TCP].dport, 20)
8169 self.assertNotEqual(p[TCP].sport, self.tcp_port_in)
8170 self.tcp_port_out = p[TCP].sport
8171 self.assertEqual(data, p[Raw].load)
8174 data = b"A" * 4 + b"B" * 16 + b"C" * 3
8175 pkts = self.create_stream_frag(self.pg1,
8181 self.pg1.add_stream(pkts)
8182 self.pg_enable_capture(self.pg_interfaces)
8184 frags = self.pg0.get_capture(len(pkts))
8185 src = self.compose_ip6(self.pg1.remote_ip4, '64:ff9b::', 96)
8186 p = self.reass_frags_and_verify_ip6(frags, src, self.pg0.remote_ip6)
8187 self.assertEqual(p[TCP].sport, 20)
8188 self.assertEqual(p[TCP].dport, self.tcp_port_in)
8189 self.assertEqual(data, p[Raw].load)
8191 def test_interface_addr(self):
8192 """ Acquire NAT64 pool addresses from interface """
8193 self.vapi.nat64_add_del_interface_addr(self.pg4.sw_if_index)
8195 # no address in NAT64 pool
8196 addresses = self.vapi.nat44_address_dump()
8197 self.assertEqual(0, len(addresses))
8199 # configure interface address and check NAT64 address pool
8200 self.pg4.config_ip4()
8201 addresses = self.vapi.nat64_pool_addr_dump()
8202 self.assertEqual(len(addresses), 1)
8203 self.assertEqual(addresses[0].address, self.pg4.local_ip4n)
8205 # remove interface address and check NAT64 address pool
8206 self.pg4.unconfig_ip4()
8207 addresses = self.vapi.nat64_pool_addr_dump()
8208 self.assertEqual(0, len(addresses))
8210 @unittest.skipUnless(running_extended_tests, "part of extended tests")
8211 def test_ipfix_max_bibs_sessions(self):
8212 """ IPFIX logging maximum session and BIB entries exceeded """
8215 remote_host_ip6 = self.compose_ip6(self.pg1.remote_ip4,
8219 self.vapi.nat64_add_del_pool_addr_range(self.nat_addr_n,
8221 self.vapi.nat64_add_del_interface(self.pg0.sw_if_index)
8222 self.vapi.nat64_add_del_interface(self.pg1.sw_if_index, is_inside=0)
8226 for i in range(0, max_bibs):
8227 src = "fd01:aa::%x" % (i)
8228 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
8229 IPv6(src=src, dst=remote_host_ip6) /
8230 TCP(sport=12345, dport=80))
8232 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
8233 IPv6(src=src, dst=remote_host_ip6) /
8234 TCP(sport=12345, dport=22))
8236 self.pg0.add_stream(pkts)
8237 self.pg_enable_capture(self.pg_interfaces)
8239 self.pg1.get_capture(max_sessions)
8241 self.vapi.set_ipfix_exporter(collector_address=self.pg3.remote_ip4n,
8242 src_address=self.pg3.local_ip4n,
8244 template_interval=10)
8245 self.vapi.nat_ipfix_enable_disable(domain_id=self.ipfix_domain_id,
8246 src_port=self.ipfix_src_port)
8248 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
8249 IPv6(src=src, dst=remote_host_ip6) /
8250 TCP(sport=12345, dport=25))
8251 self.pg0.add_stream(p)
8252 self.pg_enable_capture(self.pg_interfaces)
8254 self.pg1.assert_nothing_captured()
8256 self.vapi.cli("ipfix flush") # FIXME this should be an API call
8257 capture = self.pg3.get_capture(9)
8258 ipfix = IPFIXDecoder()
8259 # first load template
8261 self.assertTrue(p.haslayer(IPFIX))
8262 self.assertEqual(p[IP].src, self.pg3.local_ip4)
8263 self.assertEqual(p[IP].dst, self.pg3.remote_ip4)
8264 self.assertEqual(p[UDP].sport, self.ipfix_src_port)
8265 self.assertEqual(p[UDP].dport, 4739)
8266 self.assertEqual(p[IPFIX].observationDomainID,
8267 self.ipfix_domain_id)
8268 if p.haslayer(Template):
8269 ipfix.add_template(p.getlayer(Template))
8270 # verify events in data set
8272 if p.haslayer(Data):
8273 data = ipfix.decode_data_set(p.getlayer(Set))
8274 self.verify_ipfix_max_sessions(data, max_sessions)
8276 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
8277 IPv6(src=self.pg0.remote_ip6, dst=remote_host_ip6) /
8278 TCP(sport=12345, dport=80))
8279 self.pg0.add_stream(p)
8280 self.pg_enable_capture(self.pg_interfaces)
8282 self.pg1.assert_nothing_captured()
8284 self.vapi.cli("ipfix flush") # FIXME this should be an API call
8285 capture = self.pg3.get_capture(1)
8286 # verify events in data set
8288 self.assertTrue(p.haslayer(IPFIX))
8289 self.assertEqual(p[IP].src, self.pg3.local_ip4)
8290 self.assertEqual(p[IP].dst, self.pg3.remote_ip4)
8291 self.assertEqual(p[UDP].sport, self.ipfix_src_port)
8292 self.assertEqual(p[UDP].dport, 4739)
8293 self.assertEqual(p[IPFIX].observationDomainID,
8294 self.ipfix_domain_id)
8295 if p.haslayer(Data):
8296 data = ipfix.decode_data_set(p.getlayer(Set))
8297 self.verify_ipfix_max_bibs(data, max_bibs)
8299 def test_ipfix_max_frags(self):
8300 """ IPFIX logging maximum fragments pending reassembly exceeded """
8301 self.vapi.nat64_add_del_pool_addr_range(self.nat_addr_n,
8303 self.vapi.nat64_add_del_interface(self.pg0.sw_if_index)
8304 self.vapi.nat64_add_del_interface(self.pg1.sw_if_index, is_inside=0)
8305 self.vapi.nat_set_reass(max_frag=1, is_ip6=1)
8306 self.vapi.set_ipfix_exporter(collector_address=self.pg3.remote_ip4n,
8307 src_address=self.pg3.local_ip4n,
8309 template_interval=10)
8310 self.vapi.nat_ipfix_enable_disable(domain_id=self.ipfix_domain_id,
8311 src_port=self.ipfix_src_port)
8314 pkts = self.create_stream_frag_ip6(self.pg0, self.pg1.remote_ip4,
8315 self.tcp_port_in, 20, data)
8317 self.pg0.add_stream(pkts)
8318 self.pg_enable_capture(self.pg_interfaces)
8320 self.pg1.assert_nothing_captured()
8322 self.vapi.cli("ipfix flush") # FIXME this should be an API call
8323 capture = self.pg3.get_capture(9)
8324 ipfix = IPFIXDecoder()
8325 # first load template
8327 self.assertTrue(p.haslayer(IPFIX))
8328 self.assertEqual(p[IP].src, self.pg3.local_ip4)
8329 self.assertEqual(p[IP].dst, self.pg3.remote_ip4)
8330 self.assertEqual(p[UDP].sport, self.ipfix_src_port)
8331 self.assertEqual(p[UDP].dport, 4739)
8332 self.assertEqual(p[IPFIX].observationDomainID,
8333 self.ipfix_domain_id)
8334 if p.haslayer(Template):
8335 ipfix.add_template(p.getlayer(Template))
8336 # verify events in data set
8338 if p.haslayer(Data):
8339 data = ipfix.decode_data_set(p.getlayer(Set))
8340 self.verify_ipfix_max_fragments_ip6(data, 1,
8341 self.pg0.remote_ip6n)
8343 def test_ipfix_bib_ses(self):
8344 """ IPFIX logging NAT64 BIB/session create and delete events """
8345 self.tcp_port_in = random.randint(1025, 65535)
8346 remote_host_ip6 = self.compose_ip6(self.pg1.remote_ip4,
8350 self.vapi.nat64_add_del_pool_addr_range(self.nat_addr_n,
8352 self.vapi.nat64_add_del_interface(self.pg0.sw_if_index)
8353 self.vapi.nat64_add_del_interface(self.pg1.sw_if_index, is_inside=0)
8354 self.vapi.set_ipfix_exporter(collector_address=self.pg3.remote_ip4n,
8355 src_address=self.pg3.local_ip4n,
8357 template_interval=10)
8358 self.vapi.nat_ipfix_enable_disable(domain_id=self.ipfix_domain_id,
8359 src_port=self.ipfix_src_port)
8362 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
8363 IPv6(src=self.pg0.remote_ip6, dst=remote_host_ip6) /
8364 TCP(sport=self.tcp_port_in, dport=25))
8365 self.pg0.add_stream(p)
8366 self.pg_enable_capture(self.pg_interfaces)
8368 p = self.pg1.get_capture(1)
8369 self.tcp_port_out = p[0][TCP].sport
8370 self.vapi.cli("ipfix flush") # FIXME this should be an API call
8371 capture = self.pg3.get_capture(10)
8372 ipfix = IPFIXDecoder()
8373 # first load template
8375 self.assertTrue(p.haslayer(IPFIX))
8376 self.assertEqual(p[IP].src, self.pg3.local_ip4)
8377 self.assertEqual(p[IP].dst, self.pg3.remote_ip4)
8378 self.assertEqual(p[UDP].sport, self.ipfix_src_port)
8379 self.assertEqual(p[UDP].dport, 4739)
8380 self.assertEqual(p[IPFIX].observationDomainID,
8381 self.ipfix_domain_id)
8382 if p.haslayer(Template):
8383 ipfix.add_template(p.getlayer(Template))
8384 # verify events in data set
8386 if p.haslayer(Data):
8387 data = ipfix.decode_data_set(p.getlayer(Set))
8388 if scapy.compat.orb(data[0][230]) == 10:
8389 self.verify_ipfix_bib(data, 1, self.pg0.remote_ip6n)
8390 elif scapy.compat.orb(data[0][230]) == 6:
8391 self.verify_ipfix_nat64_ses(data,
8393 self.pg0.remote_ip6n,
8394 self.pg1.remote_ip4,
8397 self.logger.error(ppp("Unexpected or invalid packet: ", p))
8400 self.pg_enable_capture(self.pg_interfaces)
8401 self.vapi.nat64_add_del_pool_addr_range(self.nat_addr_n,
8404 self.vapi.cli("ipfix flush") # FIXME this should be an API call
8405 capture = self.pg3.get_capture(2)
8406 # verify events in data set
8408 self.assertTrue(p.haslayer(IPFIX))
8409 self.assertEqual(p[IP].src, self.pg3.local_ip4)
8410 self.assertEqual(p[IP].dst, self.pg3.remote_ip4)
8411 self.assertEqual(p[UDP].sport, self.ipfix_src_port)
8412 self.assertEqual(p[UDP].dport, 4739)
8413 self.assertEqual(p[IPFIX].observationDomainID,
8414 self.ipfix_domain_id)
8415 if p.haslayer(Data):
8416 data = ipfix.decode_data_set(p.getlayer(Set))
8417 if scapy.compat.orb(data[0][230]) == 11:
8418 self.verify_ipfix_bib(data, 0, self.pg0.remote_ip6n)
8419 elif scapy.compat.orb(data[0][230]) == 7:
8420 self.verify_ipfix_nat64_ses(data,
8422 self.pg0.remote_ip6n,
8423 self.pg1.remote_ip4,
8426 self.logger.error(ppp("Unexpected or invalid packet: ", p))
8428 def test_syslog_sess(self):
8429 """ Test syslog session creation and deletion """
8430 self.tcp_port_in = random.randint(1025, 65535)
8431 remote_host_ip6 = self.compose_ip6(self.pg1.remote_ip4,
8435 self.vapi.nat64_add_del_pool_addr_range(self.nat_addr_n,
8437 self.vapi.nat64_add_del_interface(self.pg0.sw_if_index)
8438 self.vapi.nat64_add_del_interface(self.pg1.sw_if_index, is_inside=0)
8439 self.vapi.syslog_set_filter(SYSLOG_SEVERITY.INFO)
8440 self.vapi.syslog_set_sender(self.pg3.local_ip4n, self.pg3.remote_ip4n)
8442 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
8443 IPv6(src=self.pg0.remote_ip6, dst=remote_host_ip6) /
8444 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port))
8445 self.pg0.add_stream(p)
8446 self.pg_enable_capture(self.pg_interfaces)
8448 p = self.pg1.get_capture(1)
8449 self.tcp_port_out = p[0][TCP].sport
8450 capture = self.pg3.get_capture(1)
8451 self.verify_syslog_sess(capture[0][Raw].load, is_ip6=True)
8453 self.pg_enable_capture(self.pg_interfaces)
8455 self.vapi.nat64_add_del_pool_addr_range(self.nat_addr_n,
8458 capture = self.pg3.get_capture(1)
8459 self.verify_syslog_sess(capture[0][Raw].load, False, True)
8461 def nat64_get_ses_num(self):
8463 Return number of active NAT64 sessions.
8465 st = self.vapi.nat64_st_dump()
8468 def clear_nat64(self):
8470 Clear NAT64 configuration.
8472 self.vapi.nat_ipfix_enable_disable(enable=0,
8473 src_port=self.ipfix_src_port,
8474 domain_id=self.ipfix_domain_id)
8475 self.ipfix_src_port = 4739
8476 self.ipfix_domain_id = 1
8478 self.vapi.syslog_set_filter(SYSLOG_SEVERITY.EMERG)
8480 self.vapi.nat_set_timeouts()
8482 interfaces = self.vapi.nat64_interface_dump()
8483 for intf in interfaces:
8484 if intf.is_inside > 1:
8485 self.vapi.nat64_add_del_interface(intf.sw_if_index,
8488 self.vapi.nat64_add_del_interface(intf.sw_if_index,
8492 bib = self.vapi.nat64_bib_dump(255)
8495 self.vapi.nat64_add_del_static_bib(bibe.i_addr,
8503 adresses = self.vapi.nat64_pool_addr_dump()
8504 for addr in adresses:
8505 self.vapi.nat64_add_del_pool_addr_range(addr.address,
8510 prefixes = self.vapi.nat64_prefix_dump()
8511 for prefix in prefixes:
8512 self.vapi.nat64_add_del_prefix(prefix.prefix,
8514 vrf_id=prefix.vrf_id,
8517 bibs = self.statistics.get_counter('/nat64/total-bibs')
8518 self.assertEqual(bibs[0][0], 0)
8519 sessions = self.statistics.get_counter('/nat64/total-sessions')
8520 self.assertEqual(sessions[0][0], 0)
8523 super(TestNAT64, self).tearDown()
8524 if not self.vpp_dead:
8527 def show_commands_at_teardown(self):
8528 self.logger.info(self.vapi.cli("show nat64 pool"))
8529 self.logger.info(self.vapi.cli("show nat64 interfaces"))
8530 self.logger.info(self.vapi.cli("show nat64 prefix"))
8531 self.logger.info(self.vapi.cli("show nat64 bib all"))
8532 self.logger.info(self.vapi.cli("show nat64 session table all"))
8533 self.logger.info(self.vapi.cli("show nat virtual-reassembly"))
8536 class TestDSlite(MethodHolder):
8537 """ DS-Lite Test Cases """
8540 def setUpClass(cls):
8541 super(TestDSlite, cls).setUpClass()
8544 cls.nat_addr = '10.0.0.3'
8545 cls.nat_addr_n = socket.inet_pton(socket.AF_INET, cls.nat_addr)
8547 cls.create_pg_interfaces(range(3))
8549 cls.pg0.config_ip4()
8550 cls.pg0.resolve_arp()
8552 cls.pg1.config_ip6()
8553 cls.pg1.generate_remote_hosts(2)
8554 cls.pg1.configure_ipv6_neighbors()
8556 cls.pg2.config_ip4()
8557 cls.pg2.resolve_arp()
8560 super(TestDSlite, cls).tearDownClass()
8564 def tearDownClass(cls):
8565 super(TestDSlite, cls).tearDownClass()
8567 def verify_syslog_apmadd(self, data, isaddr, isport, xsaddr, xsport,
8569 message = data.decode('utf-8')
8571 message = SyslogMessage.parse(message)
8572 except ParseError as e:
8573 self.logger.error(e)
8575 self.assertEqual(message.severity, SyslogSeverity.info)
8576 self.assertEqual(message.appname, 'NAT')
8577 self.assertEqual(message.msgid, 'APMADD')
8578 sd_params = message.sd.get('napmap')
8579 self.assertTrue(sd_params is not None)
8580 self.assertEqual(sd_params.get('IATYP'), 'IPv4')
8581 self.assertEqual(sd_params.get('ISADDR'), isaddr)
8582 self.assertEqual(sd_params.get('ISPORT'), "%d" % isport)
8583 self.assertEqual(sd_params.get('XATYP'), 'IPv4')
8584 self.assertEqual(sd_params.get('XSADDR'), xsaddr)
8585 self.assertEqual(sd_params.get('XSPORT'), "%d" % xsport)
8586 self.assertEqual(sd_params.get('PROTO'), "%d" % proto)
8587 self.assertTrue(sd_params.get('SSUBIX') is not None)
8588 self.assertEqual(sd_params.get('SV6ENC'), sv6enc)
8590 def test_dslite(self):
8591 """ Test DS-Lite """
8592 nat_config = self.vapi.nat_show_config()
8593 self.assertEqual(0, nat_config.dslite_ce)
8595 self.vapi.dslite_add_del_pool_addr_range(self.nat_addr_n,
8597 aftr_ip4 = '192.0.0.1'
8598 aftr_ip4_n = socket.inet_pton(socket.AF_INET, aftr_ip4)
8599 aftr_ip6 = '2001:db8:85a3::8a2e:370:1'
8600 aftr_ip6_n = socket.inet_pton(socket.AF_INET6, aftr_ip6)
8601 self.vapi.dslite_set_aftr_addr(aftr_ip6_n, aftr_ip4_n)
8602 self.vapi.syslog_set_sender(self.pg2.local_ip4n, self.pg2.remote_ip4n)
8605 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
8606 IPv6(dst=aftr_ip6, src=self.pg1.remote_hosts[0].ip6) /
8607 IP(dst=self.pg0.remote_ip4, src='192.168.1.1') /
8608 UDP(sport=20000, dport=10000))
8609 self.pg1.add_stream(p)
8610 self.pg_enable_capture(self.pg_interfaces)
8612 capture = self.pg0.get_capture(1)
8613 capture = capture[0]
8614 self.assertFalse(capture.haslayer(IPv6))
8615 self.assertEqual(capture[IP].src, self.nat_addr)
8616 self.assertEqual(capture[IP].dst, self.pg0.remote_ip4)
8617 self.assertNotEqual(capture[UDP].sport, 20000)
8618 self.assertEqual(capture[UDP].dport, 10000)
8619 self.assert_packet_checksums_valid(capture)
8620 out_port = capture[UDP].sport
8621 capture = self.pg2.get_capture(1)
8622 self.verify_syslog_apmadd(capture[0][Raw].load, '192.168.1.1',
8623 20000, self.nat_addr, out_port,
8624 self.pg1.remote_hosts[0].ip6, IP_PROTOS.udp)
8626 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
8627 IP(dst=self.nat_addr, src=self.pg0.remote_ip4) /
8628 UDP(sport=10000, dport=out_port))
8629 self.pg0.add_stream(p)
8630 self.pg_enable_capture(self.pg_interfaces)
8632 capture = self.pg1.get_capture(1)
8633 capture = capture[0]
8634 self.assertEqual(capture[IPv6].src, aftr_ip6)
8635 self.assertEqual(capture[IPv6].dst, self.pg1.remote_hosts[0].ip6)
8636 self.assertEqual(capture[IP].src, self.pg0.remote_ip4)
8637 self.assertEqual(capture[IP].dst, '192.168.1.1')
8638 self.assertEqual(capture[UDP].sport, 10000)
8639 self.assertEqual(capture[UDP].dport, 20000)
8640 self.assert_packet_checksums_valid(capture)
8643 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
8644 IPv6(dst=aftr_ip6, src=self.pg1.remote_hosts[1].ip6) /
8645 IP(dst=self.pg0.remote_ip4, src='192.168.1.1') /
8646 TCP(sport=20001, dport=10001))
8647 self.pg1.add_stream(p)
8648 self.pg_enable_capture(self.pg_interfaces)
8650 capture = self.pg0.get_capture(1)
8651 capture = capture[0]
8652 self.assertFalse(capture.haslayer(IPv6))
8653 self.assertEqual(capture[IP].src, self.nat_addr)
8654 self.assertEqual(capture[IP].dst, self.pg0.remote_ip4)
8655 self.assertNotEqual(capture[TCP].sport, 20001)
8656 self.assertEqual(capture[TCP].dport, 10001)
8657 self.assert_packet_checksums_valid(capture)
8658 out_port = capture[TCP].sport
8660 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
8661 IP(dst=self.nat_addr, src=self.pg0.remote_ip4) /
8662 TCP(sport=10001, dport=out_port))
8663 self.pg0.add_stream(p)
8664 self.pg_enable_capture(self.pg_interfaces)
8666 capture = self.pg1.get_capture(1)
8667 capture = capture[0]
8668 self.assertEqual(capture[IPv6].src, aftr_ip6)
8669 self.assertEqual(capture[IPv6].dst, self.pg1.remote_hosts[1].ip6)
8670 self.assertEqual(capture[IP].src, self.pg0.remote_ip4)
8671 self.assertEqual(capture[IP].dst, '192.168.1.1')
8672 self.assertEqual(capture[TCP].sport, 10001)
8673 self.assertEqual(capture[TCP].dport, 20001)
8674 self.assert_packet_checksums_valid(capture)
8677 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
8678 IPv6(dst=aftr_ip6, src=self.pg1.remote_hosts[1].ip6) /
8679 IP(dst=self.pg0.remote_ip4, src='192.168.1.1') /
8680 ICMP(id=4000, type='echo-request'))
8681 self.pg1.add_stream(p)
8682 self.pg_enable_capture(self.pg_interfaces)
8684 capture = self.pg0.get_capture(1)
8685 capture = capture[0]
8686 self.assertFalse(capture.haslayer(IPv6))
8687 self.assertEqual(capture[IP].src, self.nat_addr)
8688 self.assertEqual(capture[IP].dst, self.pg0.remote_ip4)
8689 self.assertNotEqual(capture[ICMP].id, 4000)
8690 self.assert_packet_checksums_valid(capture)
8691 out_id = capture[ICMP].id
8693 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
8694 IP(dst=self.nat_addr, src=self.pg0.remote_ip4) /
8695 ICMP(id=out_id, type='echo-reply'))
8696 self.pg0.add_stream(p)
8697 self.pg_enable_capture(self.pg_interfaces)
8699 capture = self.pg1.get_capture(1)
8700 capture = capture[0]
8701 self.assertEqual(capture[IPv6].src, aftr_ip6)
8702 self.assertEqual(capture[IPv6].dst, self.pg1.remote_hosts[1].ip6)
8703 self.assertEqual(capture[IP].src, self.pg0.remote_ip4)
8704 self.assertEqual(capture[IP].dst, '192.168.1.1')
8705 self.assertEqual(capture[ICMP].id, 4000)
8706 self.assert_packet_checksums_valid(capture)
8708 # ping DS-Lite AFTR tunnel endpoint address
8709 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
8710 IPv6(src=self.pg1.remote_hosts[1].ip6, dst=aftr_ip6) /
8711 ICMPv6EchoRequest())
8712 self.pg1.add_stream(p)
8713 self.pg_enable_capture(self.pg_interfaces)
8715 capture = self.pg1.get_capture(1)
8716 capture = capture[0]
8717 self.assertEqual(capture[IPv6].src, aftr_ip6)
8718 self.assertEqual(capture[IPv6].dst, self.pg1.remote_hosts[1].ip6)
8719 self.assertTrue(capture.haslayer(ICMPv6EchoReply))
8721 b4s = self.statistics.get_counter('/dslite/total-b4s')
8722 self.assertEqual(b4s[0][0], 2)
8723 sessions = self.statistics.get_counter('/dslite/total-sessions')
8724 self.assertEqual(sessions[0][0], 3)
8727 super(TestDSlite, self).tearDown()
8729 def show_commands_at_teardown(self):
8730 self.logger.info(self.vapi.cli("show dslite pool"))
8732 self.vapi.cli("show dslite aftr-tunnel-endpoint-address"))
8733 self.logger.info(self.vapi.cli("show dslite sessions"))
8736 class TestDSliteCE(MethodHolder):
8737 """ DS-Lite CE Test Cases """
8740 def setUpConstants(cls):
8741 super(TestDSliteCE, cls).setUpConstants()
8742 cls.vpp_cmdline.extend(["nat", "{", "dslite ce", "}"])
8745 def setUpClass(cls):
8746 super(TestDSliteCE, cls).setUpClass()
8749 cls.create_pg_interfaces(range(2))
8751 cls.pg0.config_ip4()
8752 cls.pg0.resolve_arp()
8754 cls.pg1.config_ip6()
8755 cls.pg1.generate_remote_hosts(1)
8756 cls.pg1.configure_ipv6_neighbors()
8759 super(TestDSliteCE, cls).tearDownClass()
8763 def tearDownClass(cls):
8764 super(TestDSliteCE, cls).tearDownClass()
8766 def test_dslite_ce(self):
8767 """ Test DS-Lite CE """
8769 nat_config = self.vapi.nat_show_config()
8770 self.assertEqual(1, nat_config.dslite_ce)
8772 b4_ip4 = '192.0.0.2'
8773 b4_ip4_n = socket.inet_pton(socket.AF_INET, b4_ip4)
8774 b4_ip6 = '2001:db8:62aa::375e:f4c1:1'
8775 b4_ip6_n = socket.inet_pton(socket.AF_INET6, b4_ip6)
8776 self.vapi.dslite_set_b4_addr(b4_ip6_n, b4_ip4_n)
8778 aftr_ip4 = '192.0.0.1'
8779 aftr_ip4_n = socket.inet_pton(socket.AF_INET, aftr_ip4)
8780 aftr_ip6 = '2001:db8:85a3::8a2e:370:1'
8781 aftr_ip6_n = socket.inet_pton(socket.AF_INET6, aftr_ip6)
8782 self.vapi.dslite_set_aftr_addr(aftr_ip6_n, aftr_ip4_n)
8784 self.vapi.ip_add_del_route(dst_address=aftr_ip6_n,
8785 dst_address_length=128,
8786 next_hop_address=self.pg1.remote_ip6n,
8787 next_hop_sw_if_index=self.pg1.sw_if_index,
8791 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
8792 IP(dst=self.pg1.remote_ip4, src=self.pg0.remote_ip4) /
8793 UDP(sport=10000, dport=20000))
8794 self.pg0.add_stream(p)
8795 self.pg_enable_capture(self.pg_interfaces)
8797 capture = self.pg1.get_capture(1)
8798 capture = capture[0]
8799 self.assertEqual(capture[IPv6].src, b4_ip6)
8800 self.assertEqual(capture[IPv6].dst, aftr_ip6)
8801 self.assertEqual(capture[IP].src, self.pg0.remote_ip4)
8802 self.assertEqual(capture[IP].dst, self.pg1.remote_ip4)
8803 self.assertEqual(capture[UDP].sport, 10000)
8804 self.assertEqual(capture[UDP].dport, 20000)
8805 self.assert_packet_checksums_valid(capture)
8808 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
8809 IPv6(dst=b4_ip6, src=aftr_ip6) /
8810 IP(dst=self.pg0.remote_ip4, src=self.pg1.remote_ip4) /
8811 UDP(sport=20000, dport=10000))
8812 self.pg1.add_stream(p)
8813 self.pg_enable_capture(self.pg_interfaces)
8815 capture = self.pg0.get_capture(1)
8816 capture = capture[0]
8817 self.assertFalse(capture.haslayer(IPv6))
8818 self.assertEqual(capture[IP].src, self.pg1.remote_ip4)
8819 self.assertEqual(capture[IP].dst, self.pg0.remote_ip4)
8820 self.assertEqual(capture[UDP].sport, 20000)
8821 self.assertEqual(capture[UDP].dport, 10000)
8822 self.assert_packet_checksums_valid(capture)
8824 # ping DS-Lite B4 tunnel endpoint address
8825 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
8826 IPv6(src=self.pg1.remote_hosts[0].ip6, dst=b4_ip6) /
8827 ICMPv6EchoRequest())
8828 self.pg1.add_stream(p)
8829 self.pg_enable_capture(self.pg_interfaces)
8831 capture = self.pg1.get_capture(1)
8832 capture = capture[0]
8833 self.assertEqual(capture[IPv6].src, b4_ip6)
8834 self.assertEqual(capture[IPv6].dst, self.pg1.remote_hosts[0].ip6)
8835 self.assertTrue(capture.haslayer(ICMPv6EchoReply))
8838 super(TestDSliteCE, self).tearDown()
8840 def show_commands_at_teardown(self):
8842 self.vapi.cli("show dslite aftr-tunnel-endpoint-address"))
8844 self.vapi.cli("show dslite b4-tunnel-endpoint-address"))
8847 class TestNAT66(MethodHolder):
8848 """ NAT66 Test Cases """
8851 def setUpClass(cls):
8852 super(TestNAT66, cls).setUpClass()
8855 cls.nat_addr = 'fd01:ff::2'
8856 cls.nat_addr_n = socket.inet_pton(socket.AF_INET6, cls.nat_addr)
8858 cls.create_pg_interfaces(range(2))
8859 cls.interfaces = list(cls.pg_interfaces)
8861 for i in cls.interfaces:
8864 i.configure_ipv6_neighbors()
8867 super(TestNAT66, cls).tearDownClass()
8871 def tearDownClass(cls):
8872 super(TestNAT66, cls).tearDownClass()
8874 def test_static(self):
8875 """ 1:1 NAT66 test """
8876 self.vapi.nat66_add_del_interface(self.pg0.sw_if_index)
8877 self.vapi.nat66_add_del_interface(self.pg1.sw_if_index, is_inside=0)
8878 self.vapi.nat66_add_del_static_mapping(self.pg0.remote_ip6n,
8883 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
8884 IPv6(src=self.pg0.remote_ip6, dst=self.pg1.remote_ip6) /
8887 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
8888 IPv6(src=self.pg0.remote_ip6, dst=self.pg1.remote_ip6) /
8891 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
8892 IPv6(src=self.pg0.remote_ip6, dst=self.pg1.remote_ip6) /
8893 ICMPv6EchoRequest())
8895 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
8896 IPv6(src=self.pg0.remote_ip6, dst=self.pg1.remote_ip6) /
8897 GRE() / IP() / TCP())
8899 self.pg0.add_stream(pkts)
8900 self.pg_enable_capture(self.pg_interfaces)
8902 capture = self.pg1.get_capture(len(pkts))
8903 for packet in capture:
8905 self.assertEqual(packet[IPv6].src, self.nat_addr)
8906 self.assertEqual(packet[IPv6].dst, self.pg1.remote_ip6)
8907 self.assert_packet_checksums_valid(packet)
8909 self.logger.error(ppp("Unexpected or invalid packet:", packet))
8914 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
8915 IPv6(src=self.pg1.remote_ip6, dst=self.nat_addr) /
8918 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
8919 IPv6(src=self.pg1.remote_ip6, dst=self.nat_addr) /
8922 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
8923 IPv6(src=self.pg1.remote_ip6, dst=self.nat_addr) /
8926 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
8927 IPv6(src=self.pg1.remote_ip6, dst=self.nat_addr) /
8928 GRE() / IP() / TCP())
8930 self.pg1.add_stream(pkts)
8931 self.pg_enable_capture(self.pg_interfaces)
8933 capture = self.pg0.get_capture(len(pkts))
8934 for packet in capture:
8936 self.assertEqual(packet[IPv6].src, self.pg1.remote_ip6)
8937 self.assertEqual(packet[IPv6].dst, self.pg0.remote_ip6)
8938 self.assert_packet_checksums_valid(packet)
8940 self.logger.error(ppp("Unexpected or invalid packet:", packet))
8943 sm = self.vapi.nat66_static_mapping_dump()
8944 self.assertEqual(len(sm), 1)
8945 self.assertEqual(sm[0].total_pkts, 8)
8947 def test_check_no_translate(self):
8948 """ NAT66 translate only when egress interface is outside interface """
8949 self.vapi.nat66_add_del_interface(self.pg0.sw_if_index)
8950 self.vapi.nat66_add_del_interface(self.pg1.sw_if_index)
8951 self.vapi.nat66_add_del_static_mapping(self.pg0.remote_ip6n,
8955 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
8956 IPv6(src=self.pg0.remote_ip6, dst=self.pg1.remote_ip6) /
8958 self.pg0.add_stream([p])
8959 self.pg_enable_capture(self.pg_interfaces)
8961 capture = self.pg1.get_capture(1)
8964 self.assertEqual(packet[IPv6].src, self.pg0.remote_ip6)
8965 self.assertEqual(packet[IPv6].dst, self.pg1.remote_ip6)
8967 self.logger.error(ppp("Unexpected or invalid packet:", packet))
8970 def clear_nat66(self):
8972 Clear NAT66 configuration.
8974 interfaces = self.vapi.nat66_interface_dump()
8975 for intf in interfaces:
8976 self.vapi.nat66_add_del_interface(intf.sw_if_index,
8980 static_mappings = self.vapi.nat66_static_mapping_dump()
8981 for sm in static_mappings:
8982 self.vapi.nat66_add_del_static_mapping(sm.local_ip_address,
8983 sm.external_ip_address,
8988 super(TestNAT66, self).tearDown()
8991 def show_commands_at_teardown(self):
8992 self.logger.info(self.vapi.cli("show nat66 interfaces"))
8993 self.logger.info(self.vapi.cli("show nat66 static mappings"))
8995 if __name__ == '__main__':
8996 unittest.main(testRunner=VppTestRunner)