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()
4164 if not self.vpp_dead:
4165 self.logger.info(self.vapi.cli("show nat44 addresses"))
4166 self.logger.info(self.vapi.cli("show nat44 interfaces"))
4167 self.logger.info(self.vapi.cli("show nat44 static mappings"))
4168 self.logger.info(self.vapi.cli("show nat44 interface address"))
4169 self.logger.info(self.vapi.cli("show nat44 sessions detail"))
4170 self.logger.info(self.vapi.cli("show nat virtual-reassembly"))
4171 self.logger.info(self.vapi.cli("show nat44 hash tables detail"))
4172 self.logger.info(self.vapi.cli("show nat timeouts"))
4174 self.vapi.cli("show nat addr-port-assignment-alg"))
4175 self.logger.info(self.vapi.cli("show nat ha"))
4177 self.vapi.cli("clear logging")
4180 class TestNAT44EndpointDependent(MethodHolder):
4181 """ Endpoint-Dependent mapping and filtering test cases """
4184 def setUpConstants(cls):
4185 super(TestNAT44EndpointDependent, cls).setUpConstants()
4186 cls.vpp_cmdline.extend(["nat", "{", "endpoint-dependent", "}"])
4189 def setUpClass(cls):
4190 super(TestNAT44EndpointDependent, cls).setUpClass()
4191 cls.vapi.cli("set log class nat level debug")
4193 cls.tcp_port_in = 6303
4194 cls.tcp_port_out = 6303
4195 cls.udp_port_in = 6304
4196 cls.udp_port_out = 6304
4197 cls.icmp_id_in = 6305
4198 cls.icmp_id_out = 6305
4199 cls.nat_addr = '10.0.0.3'
4200 cls.nat_addr_n = socket.inet_pton(socket.AF_INET, cls.nat_addr)
4201 cls.ipfix_src_port = 4739
4202 cls.ipfix_domain_id = 1
4203 cls.tcp_external_port = 80
4205 cls.create_pg_interfaces(range(7))
4206 cls.interfaces = list(cls.pg_interfaces[0:3])
4208 for i in cls.interfaces:
4213 cls.pg0.generate_remote_hosts(3)
4214 cls.pg0.configure_ipv4_neighbors()
4218 cls.pg4.generate_remote_hosts(2)
4219 cls.pg4.config_ip4()
4220 ip_addr_n = socket.inet_pton(socket.AF_INET, "10.0.0.1")
4221 cls.vapi.sw_interface_add_del_address(
4222 sw_if_index=cls.pg4.sw_if_index, address=ip_addr_n,
4225 cls.pg4.resolve_arp()
4226 cls.pg4._remote_hosts[1]._ip4 = cls.pg4._remote_hosts[0]._ip4
4227 cls.pg4.resolve_arp()
4229 zero_ip4n = socket.inet_pton(socket.AF_INET, "0.0.0.0")
4230 cls.vapi.ip_table_add_del(is_add=1, table_id=1)
4232 cls.pg5._local_ip4 = "10.1.1.1"
4233 cls.pg5._local_ip4n = socket.inet_pton(socket.AF_INET,
4235 cls.pg5._remote_hosts[0]._ip4 = "10.1.1.2"
4236 cls.pg5._remote_hosts[0]._ip4n = socket.inet_pton(
4237 socket.AF_INET, cls.pg5.remote_ip4)
4238 cls.pg5.set_table_ip4(1)
4239 cls.pg5.config_ip4()
4241 cls.vapi.ip_add_del_route(dst_address=cls.pg5.remote_ip4n,
4242 dst_address_length=32,
4243 next_hop_address=zero_ip4n,
4244 next_hop_sw_if_index=cls.pg5.sw_if_index,
4247 cls.pg6._local_ip4 = "10.1.2.1"
4248 cls.pg6._local_ip4n = socket.inet_pton(socket.AF_INET,
4250 cls.pg6._remote_hosts[0]._ip4 = "10.1.2.2"
4251 cls.pg6._remote_hosts[0]._ip4n = socket.inet_pton(
4252 socket.AF_INET, cls.pg6.remote_ip4)
4253 cls.pg6.set_table_ip4(1)
4254 cls.pg6.config_ip4()
4256 cls.vapi.ip_add_del_route(dst_address=cls.pg6.remote_ip4n,
4257 dst_address_length=32,
4258 next_hop_address=zero_ip4n,
4259 next_hop_sw_if_index=cls.pg6.sw_if_index,
4262 cls.vapi.ip_add_del_route(dst_address=cls.pg6.remote_ip4n,
4263 dst_address_length=16,
4264 next_hop_address=zero_ip4n, table_id=0,
4265 next_hop_table_id=1)
4266 cls.vapi.ip_add_del_route(dst_address=zero_ip4n,
4267 dst_address_length=0,
4268 next_hop_address=zero_ip4n, table_id=1,
4269 next_hop_table_id=0)
4270 cls.vapi.ip_add_del_route(dst_address=zero_ip4n,
4271 dst_address_length=0,
4272 next_hop_address=cls.pg1.local_ip4n,
4273 next_hop_sw_if_index=cls.pg1.sw_if_index,
4276 cls.pg5.resolve_arp()
4277 cls.pg6.resolve_arp()
4280 super(TestNAT44EndpointDependent, cls).tearDownClass()
4284 def tearDownClass(cls):
4285 super(TestNAT44EndpointDependent, cls).tearDownClass()
4287 def test_frag_in_order(self):
4288 """ NAT44 translate fragments arriving in order """
4289 self.nat44_add_address(self.nat_addr)
4290 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
4291 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
4293 self.frag_in_order(proto=IP_PROTOS.tcp)
4294 self.frag_in_order(proto=IP_PROTOS.udp)
4295 self.frag_in_order(proto=IP_PROTOS.icmp)
4297 def test_frag_in_order_dont_translate(self):
4298 """ NAT44 don't translate fragments arriving in order """
4299 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
4300 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
4302 self.vapi.nat44_forwarding_enable_disable(enable=True)
4303 self.frag_in_order(proto=IP_PROTOS.tcp, dont_translate=True)
4305 def test_frag_out_of_order(self):
4306 """ NAT44 translate fragments arriving out of order """
4307 self.nat44_add_address(self.nat_addr)
4308 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
4309 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
4311 self.frag_out_of_order(proto=IP_PROTOS.tcp)
4312 self.frag_out_of_order(proto=IP_PROTOS.udp)
4313 self.frag_out_of_order(proto=IP_PROTOS.icmp)
4315 def test_frag_out_of_order_dont_translate(self):
4316 """ NAT44 don't translate fragments arriving out of order """
4317 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
4318 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
4320 self.vapi.nat44_forwarding_enable_disable(enable=True)
4321 self.frag_out_of_order(proto=IP_PROTOS.tcp, dont_translate=True)
4323 def test_frag_in_order_in_plus_out(self):
4324 """ in+out interface fragments in order """
4325 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
4326 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index,
4328 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index)
4329 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
4332 self.server = self.pg1.remote_hosts[0]
4334 self.server_in_addr = self.server.ip4
4335 self.server_out_addr = '11.11.11.11'
4336 self.server_in_port = random.randint(1025, 65535)
4337 self.server_out_port = random.randint(1025, 65535)
4339 self.nat44_add_address(self.server_out_addr)
4341 # add static mappings for server
4342 self.nat44_add_static_mapping(self.server_in_addr,
4343 self.server_out_addr,
4344 self.server_in_port,
4345 self.server_out_port,
4346 proto=IP_PROTOS.tcp)
4347 self.nat44_add_static_mapping(self.server_in_addr,
4348 self.server_out_addr,
4349 self.server_in_port,
4350 self.server_out_port,
4351 proto=IP_PROTOS.udp)
4352 self.nat44_add_static_mapping(self.server_in_addr,
4353 self.server_out_addr,
4354 proto=IP_PROTOS.icmp)
4356 self.vapi.nat_set_reass(timeout=10)
4358 self.frag_in_order_in_plus_out(proto=IP_PROTOS.tcp)
4359 self.frag_in_order_in_plus_out(proto=IP_PROTOS.udp)
4360 self.frag_in_order_in_plus_out(proto=IP_PROTOS.icmp)
4362 def test_frag_out_of_order_in_plus_out(self):
4363 """ in+out interface fragments out of order """
4364 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
4365 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index,
4367 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index)
4368 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
4371 self.server = self.pg1.remote_hosts[0]
4373 self.server_in_addr = self.server.ip4
4374 self.server_out_addr = '11.11.11.11'
4375 self.server_in_port = random.randint(1025, 65535)
4376 self.server_out_port = random.randint(1025, 65535)
4378 self.nat44_add_address(self.server_out_addr)
4380 # add static mappings for server
4381 self.nat44_add_static_mapping(self.server_in_addr,
4382 self.server_out_addr,
4383 self.server_in_port,
4384 self.server_out_port,
4385 proto=IP_PROTOS.tcp)
4386 self.nat44_add_static_mapping(self.server_in_addr,
4387 self.server_out_addr,
4388 self.server_in_port,
4389 self.server_out_port,
4390 proto=IP_PROTOS.udp)
4391 self.nat44_add_static_mapping(self.server_in_addr,
4392 self.server_out_addr,
4393 proto=IP_PROTOS.icmp)
4395 self.vapi.nat_set_reass(timeout=10)
4397 self.frag_out_of_order_in_plus_out(proto=IP_PROTOS.tcp)
4398 self.frag_out_of_order_in_plus_out(proto=IP_PROTOS.udp)
4399 self.frag_out_of_order_in_plus_out(proto=IP_PROTOS.icmp)
4401 def test_reass_hairpinning(self):
4402 """ NAT44 fragments hairpinning """
4403 self.server = self.pg0.remote_hosts[1]
4404 self.host_in_port = random.randint(1025, 65535)
4405 self.server_in_port = random.randint(1025, 65535)
4406 self.server_out_port = random.randint(1025, 65535)
4408 self.nat44_add_address(self.nat_addr)
4409 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
4410 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
4412 # add static mapping for server
4413 self.nat44_add_static_mapping(self.server.ip4, self.nat_addr,
4414 self.server_in_port,
4415 self.server_out_port,
4416 proto=IP_PROTOS.tcp)
4417 self.nat44_add_static_mapping(self.server.ip4, self.nat_addr,
4418 self.server_in_port,
4419 self.server_out_port,
4420 proto=IP_PROTOS.udp)
4421 self.nat44_add_static_mapping(self.server.ip4, self.nat_addr)
4423 self.reass_hairpinning(proto=IP_PROTOS.tcp)
4424 self.reass_hairpinning(proto=IP_PROTOS.udp)
4425 self.reass_hairpinning(proto=IP_PROTOS.icmp)
4427 def test_dynamic(self):
4428 """ NAT44 dynamic translation test """
4430 self.nat44_add_address(self.nat_addr)
4431 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
4432 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
4435 nat_config = self.vapi.nat_show_config()
4436 self.assertEqual(1, nat_config.endpoint_dependent)
4439 tcpn = self.statistics.get_counter(
4440 '/err/nat44-ed-in2out-slowpath/TCP packets')
4441 udpn = self.statistics.get_counter(
4442 '/err/nat44-ed-in2out-slowpath/UDP packets')
4443 icmpn = self.statistics.get_counter(
4444 '/err/nat44-ed-in2out-slowpath/ICMP packets')
4445 totaln = self.statistics.get_counter(
4446 '/err/nat44-ed-in2out-slowpath/good in2out packets processed')
4448 pkts = self.create_stream_in(self.pg0, self.pg1)
4449 self.pg0.add_stream(pkts)
4450 self.pg_enable_capture(self.pg_interfaces)
4452 capture = self.pg1.get_capture(len(pkts))
4453 self.verify_capture_out(capture)
4455 err = self.statistics.get_counter(
4456 '/err/nat44-ed-in2out-slowpath/TCP packets')
4457 self.assertEqual(err - tcpn, 1)
4458 err = self.statistics.get_counter(
4459 '/err/nat44-ed-in2out-slowpath/UDP packets')
4460 self.assertEqual(err - udpn, 1)
4461 err = self.statistics.get_counter(
4462 '/err/nat44-ed-in2out-slowpath/ICMP packets')
4463 self.assertEqual(err - icmpn, 1)
4464 err = self.statistics.get_counter(
4465 '/err/nat44-ed-in2out-slowpath/good in2out packets processed')
4466 self.assertEqual(err - totaln, 3)
4469 tcpn = self.statistics.get_counter('/err/nat44-ed-out2in/TCP packets')
4470 udpn = self.statistics.get_counter('/err/nat44-ed-out2in/UDP packets')
4471 icmpn = self.statistics.get_counter(
4472 '/err/nat44-ed-out2in-slowpath/ICMP packets')
4473 totaln = self.statistics.get_counter(
4474 '/err/nat44-ed-out2in/good out2in packets processed')
4476 pkts = self.create_stream_out(self.pg1)
4477 self.pg1.add_stream(pkts)
4478 self.pg_enable_capture(self.pg_interfaces)
4480 capture = self.pg0.get_capture(len(pkts))
4481 self.verify_capture_in(capture, self.pg0)
4483 err = self.statistics.get_counter('/err/nat44-ed-out2in/TCP packets')
4484 self.assertEqual(err - tcpn, 1)
4485 err = self.statistics.get_counter('/err/nat44-ed-out2in/UDP packets')
4486 self.assertEqual(err - udpn, 1)
4487 err = self.statistics.get_counter(
4488 '/err/nat44-ed-out2in-slowpath/ICMP packets')
4489 self.assertEqual(err - icmpn, 1)
4490 err = self.statistics.get_counter(
4491 '/err/nat44-ed-out2in/good out2in packets processed')
4492 self.assertEqual(err - totaln, 2)
4494 users = self.statistics.get_counter('/nat44/total-users')
4495 self.assertEqual(users[0][0], 1)
4496 sessions = self.statistics.get_counter('/nat44/total-sessions')
4497 self.assertEqual(sessions[0][0], 3)
4499 def test_forwarding(self):
4500 """ NAT44 forwarding test """
4502 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
4503 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
4505 self.vapi.nat44_forwarding_enable_disable(1)
4507 real_ip = self.pg0.remote_ip4n
4508 alias_ip = self.nat_addr_n
4509 self.vapi.nat44_add_del_static_mapping(local_ip=real_ip,
4510 external_ip=alias_ip)
4513 # in2out - static mapping match
4515 pkts = self.create_stream_out(self.pg1)
4516 self.pg1.add_stream(pkts)
4517 self.pg_enable_capture(self.pg_interfaces)
4519 capture = self.pg0.get_capture(len(pkts))
4520 self.verify_capture_in(capture, self.pg0)
4522 pkts = self.create_stream_in(self.pg0, self.pg1)
4523 self.pg0.add_stream(pkts)
4524 self.pg_enable_capture(self.pg_interfaces)
4526 capture = self.pg1.get_capture(len(pkts))
4527 self.verify_capture_out(capture, same_port=True)
4529 # in2out - no static mapping match
4531 host0 = self.pg0.remote_hosts[0]
4532 self.pg0.remote_hosts[0] = self.pg0.remote_hosts[1]
4534 pkts = self.create_stream_out(self.pg1,
4535 dst_ip=self.pg0.remote_ip4,
4536 use_inside_ports=True)
4537 self.pg1.add_stream(pkts)
4538 self.pg_enable_capture(self.pg_interfaces)
4540 capture = self.pg0.get_capture(len(pkts))
4541 self.verify_capture_in(capture, self.pg0)
4543 pkts = self.create_stream_in(self.pg0, self.pg1)
4544 self.pg0.add_stream(pkts)
4545 self.pg_enable_capture(self.pg_interfaces)
4547 capture = self.pg1.get_capture(len(pkts))
4548 self.verify_capture_out(capture, nat_ip=self.pg0.remote_ip4,
4551 self.pg0.remote_hosts[0] = host0
4553 user = self.pg0.remote_hosts[1]
4554 sessions = self.vapi.nat44_user_session_dump(user.ip4n, 0)
4555 self.assertEqual(len(sessions), 3)
4556 self.assertTrue(sessions[0].ext_host_valid)
4557 self.vapi.nat44_del_session(
4558 sessions[0].inside_ip_address,
4559 sessions[0].inside_port,
4560 sessions[0].protocol,
4561 ext_host_address=sessions[0].ext_host_address,
4562 ext_host_port=sessions[0].ext_host_port)
4563 sessions = self.vapi.nat44_user_session_dump(user.ip4n, 0)
4564 self.assertEqual(len(sessions), 2)
4567 self.vapi.nat44_forwarding_enable_disable(0)
4568 self.vapi.nat44_add_del_static_mapping(local_ip=real_ip,
4569 external_ip=alias_ip,
4572 def test_static_lb(self):
4573 """ NAT44 local service load balancing """
4574 external_addr_n = socket.inet_pton(socket.AF_INET, self.nat_addr)
4577 server1 = self.pg0.remote_hosts[0]
4578 server2 = self.pg0.remote_hosts[1]
4580 locals = [{'addr': server1.ip4n,
4584 {'addr': server2.ip4n,
4589 self.nat44_add_address(self.nat_addr)
4590 self.vapi.nat44_add_del_lb_static_mapping(external_addr_n,
4593 local_num=len(locals),
4595 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
4596 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
4599 # from client to service
4600 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
4601 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
4602 TCP(sport=12345, dport=external_port))
4603 self.pg1.add_stream(p)
4604 self.pg_enable_capture(self.pg_interfaces)
4606 capture = self.pg0.get_capture(1)
4612 self.assertIn(ip.dst, [server1.ip4, server2.ip4])
4613 if ip.dst == server1.ip4:
4617 self.assertEqual(tcp.dport, local_port)
4618 self.assert_packet_checksums_valid(p)
4620 self.logger.error(ppp("Unexpected or invalid packet:", p))
4623 # from service back to client
4624 p = (Ether(src=server.mac, dst=self.pg0.local_mac) /
4625 IP(src=server.ip4, dst=self.pg1.remote_ip4) /
4626 TCP(sport=local_port, dport=12345))
4627 self.pg0.add_stream(p)
4628 self.pg_enable_capture(self.pg_interfaces)
4630 capture = self.pg1.get_capture(1)
4635 self.assertEqual(ip.src, self.nat_addr)
4636 self.assertEqual(tcp.sport, external_port)
4637 self.assert_packet_checksums_valid(p)
4639 self.logger.error(ppp("Unexpected or invalid packet:", p))
4642 sessions = self.vapi.nat44_user_session_dump(server.ip4n, 0)
4643 self.assertEqual(len(sessions), 1)
4644 self.assertTrue(sessions[0].ext_host_valid)
4645 self.vapi.nat44_del_session(
4646 sessions[0].inside_ip_address,
4647 sessions[0].inside_port,
4648 sessions[0].protocol,
4649 ext_host_address=sessions[0].ext_host_address,
4650 ext_host_port=sessions[0].ext_host_port)
4651 sessions = self.vapi.nat44_user_session_dump(server.ip4n, 0)
4652 self.assertEqual(len(sessions), 0)
4654 @unittest.skipUnless(running_extended_tests, "part of extended tests")
4655 def test_static_lb_multi_clients(self):
4656 """ NAT44 local service load balancing - multiple clients"""
4658 external_addr_n = socket.inet_pton(socket.AF_INET, self.nat_addr)
4661 server1 = self.pg0.remote_hosts[0]
4662 server2 = self.pg0.remote_hosts[1]
4663 server3 = self.pg0.remote_hosts[2]
4665 locals = [{'addr': server1.ip4n,
4669 {'addr': server2.ip4n,
4674 self.nat44_add_address(self.nat_addr)
4675 self.vapi.nat44_add_del_lb_static_mapping(external_addr_n,
4678 local_num=len(locals),
4680 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
4681 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
4686 clients = ip4_range(self.pg1.remote_ip4, 10, 50)
4688 for client in clients:
4689 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
4690 IP(src=client, dst=self.nat_addr) /
4691 TCP(sport=12345, dport=external_port))
4693 self.pg1.add_stream(pkts)
4694 self.pg_enable_capture(self.pg_interfaces)
4696 capture = self.pg0.get_capture(len(pkts))
4698 if p[IP].dst == server1.ip4:
4702 self.assertGreater(server1_n, server2_n)
4705 self.vapi.nat44_lb_static_mapping_add_del_local(external_addr_n,
4714 clients = ip4_range(self.pg1.remote_ip4, 60, 110)
4716 for client in clients:
4717 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
4718 IP(src=client, dst=self.nat_addr) /
4719 TCP(sport=12346, dport=external_port))
4721 self.assertGreater(len(pkts), 0)
4722 self.pg1.add_stream(pkts)
4723 self.pg_enable_capture(self.pg_interfaces)
4725 capture = self.pg0.get_capture(len(pkts))
4727 if p[IP].dst == server1.ip4:
4729 elif p[IP].dst == server2.ip4:
4733 self.assertGreater(server1_n, 0)
4734 self.assertGreater(server2_n, 0)
4735 self.assertGreater(server3_n, 0)
4737 # remove one back-end
4738 self.vapi.nat44_lb_static_mapping_add_del_local(external_addr_n,
4748 self.pg1.add_stream(pkts)
4749 self.pg_enable_capture(self.pg_interfaces)
4751 capture = self.pg0.get_capture(len(pkts))
4753 if p[IP].dst == server1.ip4:
4755 elif p[IP].dst == server2.ip4:
4759 self.assertGreater(server1_n, 0)
4760 self.assertEqual(server2_n, 0)
4761 self.assertGreater(server3_n, 0)
4763 def test_static_lb_2(self):
4764 """ NAT44 local service load balancing (asymmetrical rule) """
4765 external_addr_n = socket.inet_pton(socket.AF_INET, self.nat_addr)
4768 server1 = self.pg0.remote_hosts[0]
4769 server2 = self.pg0.remote_hosts[1]
4771 locals = [{'addr': server1.ip4n,
4775 {'addr': server2.ip4n,
4780 self.vapi.nat44_forwarding_enable_disable(1)
4781 self.vapi.nat44_add_del_lb_static_mapping(external_addr_n,
4785 local_num=len(locals),
4787 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
4788 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
4791 # from client to service
4792 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
4793 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
4794 TCP(sport=12345, dport=external_port))
4795 self.pg1.add_stream(p)
4796 self.pg_enable_capture(self.pg_interfaces)
4798 capture = self.pg0.get_capture(1)
4804 self.assertIn(ip.dst, [server1.ip4, server2.ip4])
4805 if ip.dst == server1.ip4:
4809 self.assertEqual(tcp.dport, local_port)
4810 self.assert_packet_checksums_valid(p)
4812 self.logger.error(ppp("Unexpected or invalid packet:", p))
4815 # from service back to client
4816 p = (Ether(src=server.mac, dst=self.pg0.local_mac) /
4817 IP(src=server.ip4, dst=self.pg1.remote_ip4) /
4818 TCP(sport=local_port, dport=12345))
4819 self.pg0.add_stream(p)
4820 self.pg_enable_capture(self.pg_interfaces)
4822 capture = self.pg1.get_capture(1)
4827 self.assertEqual(ip.src, self.nat_addr)
4828 self.assertEqual(tcp.sport, external_port)
4829 self.assert_packet_checksums_valid(p)
4831 self.logger.error(ppp("Unexpected or invalid packet:", p))
4834 # from client to server (no translation)
4835 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
4836 IP(src=self.pg1.remote_ip4, dst=server1.ip4) /
4837 TCP(sport=12346, dport=local_port))
4838 self.pg1.add_stream(p)
4839 self.pg_enable_capture(self.pg_interfaces)
4841 capture = self.pg0.get_capture(1)
4847 self.assertEqual(ip.dst, server1.ip4)
4848 self.assertEqual(tcp.dport, local_port)
4849 self.assert_packet_checksums_valid(p)
4851 self.logger.error(ppp("Unexpected or invalid packet:", p))
4854 # from service back to client (no translation)
4855 p = (Ether(src=server1.mac, dst=self.pg0.local_mac) /
4856 IP(src=server1.ip4, dst=self.pg1.remote_ip4) /
4857 TCP(sport=local_port, dport=12346))
4858 self.pg0.add_stream(p)
4859 self.pg_enable_capture(self.pg_interfaces)
4861 capture = self.pg1.get_capture(1)
4866 self.assertEqual(ip.src, server1.ip4)
4867 self.assertEqual(tcp.sport, local_port)
4868 self.assert_packet_checksums_valid(p)
4870 self.logger.error(ppp("Unexpected or invalid packet:", p))
4873 def test_lb_affinity(self):
4874 """ NAT44 local service load balancing affinity """
4875 external_addr_n = socket.inet_pton(socket.AF_INET, self.nat_addr)
4878 server1 = self.pg0.remote_hosts[0]
4879 server2 = self.pg0.remote_hosts[1]
4881 locals = [{'addr': server1.ip4n,
4885 {'addr': server2.ip4n,
4890 self.nat44_add_address(self.nat_addr)
4891 self.vapi.nat44_add_del_lb_static_mapping(external_addr_n,
4895 local_num=len(locals),
4897 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
4898 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
4901 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
4902 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
4903 TCP(sport=1025, dport=external_port))
4904 self.pg1.add_stream(p)
4905 self.pg_enable_capture(self.pg_interfaces)
4907 capture = self.pg0.get_capture(1)
4908 backend = capture[0][IP].dst
4910 sessions = self.vapi.nat44_user_session_dump(
4911 socket.inet_pton(socket.AF_INET, backend), 0)
4912 self.assertEqual(len(sessions), 1)
4913 self.assertTrue(sessions[0].ext_host_valid)
4914 self.vapi.nat44_del_session(
4915 sessions[0].inside_ip_address,
4916 sessions[0].inside_port,
4917 sessions[0].protocol,
4918 ext_host_address=sessions[0].ext_host_address,
4919 ext_host_port=sessions[0].ext_host_port)
4922 for port in range(1030, 1100):
4923 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
4924 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
4925 TCP(sport=port, dport=external_port))
4927 self.pg1.add_stream(pkts)
4928 self.pg_enable_capture(self.pg_interfaces)
4930 capture = self.pg0.get_capture(len(pkts))
4932 self.assertEqual(p[IP].dst, backend)
4934 def test_unknown_proto(self):
4935 """ NAT44 translate packet with unknown protocol """
4936 self.nat44_add_address(self.nat_addr)
4937 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
4938 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
4942 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
4943 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
4944 TCP(sport=self.tcp_port_in, dport=20))
4945 self.pg0.add_stream(p)
4946 self.pg_enable_capture(self.pg_interfaces)
4948 p = self.pg1.get_capture(1)
4950 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
4951 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
4953 IP(src=self.pg2.remote_ip4, dst=self.pg2.remote_ip4) /
4954 TCP(sport=1234, dport=1234))
4955 self.pg0.add_stream(p)
4956 self.pg_enable_capture(self.pg_interfaces)
4958 p = self.pg1.get_capture(1)
4961 self.assertEqual(packet[IP].src, self.nat_addr)
4962 self.assertEqual(packet[IP].dst, self.pg1.remote_ip4)
4963 self.assertEqual(packet.haslayer(GRE), 1)
4964 self.assert_packet_checksums_valid(packet)
4966 self.logger.error(ppp("Unexpected or invalid packet:", packet))
4970 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
4971 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
4973 IP(src=self.pg2.remote_ip4, dst=self.pg2.remote_ip4) /
4974 TCP(sport=1234, dport=1234))
4975 self.pg1.add_stream(p)
4976 self.pg_enable_capture(self.pg_interfaces)
4978 p = self.pg0.get_capture(1)
4981 self.assertEqual(packet[IP].src, self.pg1.remote_ip4)
4982 self.assertEqual(packet[IP].dst, self.pg0.remote_ip4)
4983 self.assertEqual(packet.haslayer(GRE), 1)
4984 self.assert_packet_checksums_valid(packet)
4986 self.logger.error(ppp("Unexpected or invalid packet:", packet))
4989 def test_hairpinning_unknown_proto(self):
4990 """ NAT44 translate packet with unknown protocol - hairpinning """
4991 host = self.pg0.remote_hosts[0]
4992 server = self.pg0.remote_hosts[1]
4994 server_out_port = 8765
4995 server_nat_ip = "10.0.0.11"
4997 self.nat44_add_address(self.nat_addr)
4998 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
4999 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
5002 # add static mapping for server
5003 self.nat44_add_static_mapping(server.ip4, server_nat_ip)
5006 p = (Ether(src=host.mac, dst=self.pg0.local_mac) /
5007 IP(src=host.ip4, dst=server_nat_ip) /
5008 TCP(sport=host_in_port, dport=server_out_port))
5009 self.pg0.add_stream(p)
5010 self.pg_enable_capture(self.pg_interfaces)
5012 self.pg0.get_capture(1)
5014 p = (Ether(dst=self.pg0.local_mac, src=host.mac) /
5015 IP(src=host.ip4, dst=server_nat_ip) /
5017 IP(src=self.pg2.remote_ip4, dst=self.pg2.remote_ip4) /
5018 TCP(sport=1234, dport=1234))
5019 self.pg0.add_stream(p)
5020 self.pg_enable_capture(self.pg_interfaces)
5022 p = self.pg0.get_capture(1)
5025 self.assertEqual(packet[IP].src, self.nat_addr)
5026 self.assertEqual(packet[IP].dst, server.ip4)
5027 self.assertEqual(packet.haslayer(GRE), 1)
5028 self.assert_packet_checksums_valid(packet)
5030 self.logger.error(ppp("Unexpected or invalid packet:", packet))
5034 p = (Ether(dst=self.pg0.local_mac, src=server.mac) /
5035 IP(src=server.ip4, dst=self.nat_addr) /
5037 IP(src=self.pg2.remote_ip4, dst=self.pg2.remote_ip4) /
5038 TCP(sport=1234, dport=1234))
5039 self.pg0.add_stream(p)
5040 self.pg_enable_capture(self.pg_interfaces)
5042 p = self.pg0.get_capture(1)
5045 self.assertEqual(packet[IP].src, server_nat_ip)
5046 self.assertEqual(packet[IP].dst, host.ip4)
5047 self.assertEqual(packet.haslayer(GRE), 1)
5048 self.assert_packet_checksums_valid(packet)
5050 self.logger.error(ppp("Unexpected or invalid packet:", packet))
5053 def test_output_feature_and_service(self):
5054 """ NAT44 interface output feature and services """
5055 external_addr = '1.2.3.4'
5059 self.vapi.nat44_forwarding_enable_disable(1)
5060 self.nat44_add_address(self.nat_addr)
5061 self.vapi.nat44_add_del_identity_mapping(ip=self.pg1.remote_ip4n)
5062 self.nat44_add_static_mapping(self.pg0.remote_ip4, external_addr,
5063 local_port, external_port,
5064 proto=IP_PROTOS.tcp, out2in_only=1)
5065 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
5066 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index,
5068 self.vapi.nat44_interface_add_del_output_feature(self.pg1.sw_if_index,
5071 # from client to service
5072 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
5073 IP(src=self.pg1.remote_ip4, dst=external_addr) /
5074 TCP(sport=12345, dport=external_port))
5075 self.pg1.add_stream(p)
5076 self.pg_enable_capture(self.pg_interfaces)
5078 capture = self.pg0.get_capture(1)
5083 self.assertEqual(ip.dst, self.pg0.remote_ip4)
5084 self.assertEqual(tcp.dport, local_port)
5085 self.assert_packet_checksums_valid(p)
5087 self.logger.error(ppp("Unexpected or invalid packet:", p))
5090 # from service back to client
5091 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5092 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
5093 TCP(sport=local_port, dport=12345))
5094 self.pg0.add_stream(p)
5095 self.pg_enable_capture(self.pg_interfaces)
5097 capture = self.pg1.get_capture(1)
5102 self.assertEqual(ip.src, external_addr)
5103 self.assertEqual(tcp.sport, external_port)
5104 self.assert_packet_checksums_valid(p)
5106 self.logger.error(ppp("Unexpected or invalid packet:", p))
5109 # from local network host to external network
5110 pkts = self.create_stream_in(self.pg0, self.pg1)
5111 self.pg0.add_stream(pkts)
5112 self.pg_enable_capture(self.pg_interfaces)
5114 capture = self.pg1.get_capture(len(pkts))
5115 self.verify_capture_out(capture)
5116 pkts = self.create_stream_in(self.pg0, self.pg1)
5117 self.pg0.add_stream(pkts)
5118 self.pg_enable_capture(self.pg_interfaces)
5120 capture = self.pg1.get_capture(len(pkts))
5121 self.verify_capture_out(capture)
5123 # from external network back to local network host
5124 pkts = self.create_stream_out(self.pg1)
5125 self.pg1.add_stream(pkts)
5126 self.pg_enable_capture(self.pg_interfaces)
5128 capture = self.pg0.get_capture(len(pkts))
5129 self.verify_capture_in(capture, self.pg0)
5131 def test_output_feature_and_service2(self):
5132 """ NAT44 interface output feature and service host direct access """
5133 self.vapi.nat44_forwarding_enable_disable(1)
5134 self.nat44_add_address(self.nat_addr)
5135 self.vapi.nat44_interface_add_del_output_feature(self.pg1.sw_if_index,
5138 # session initiated from service host - translate
5139 pkts = self.create_stream_in(self.pg0, self.pg1)
5140 self.pg0.add_stream(pkts)
5141 self.pg_enable_capture(self.pg_interfaces)
5143 capture = self.pg1.get_capture(len(pkts))
5144 self.verify_capture_out(capture)
5146 pkts = self.create_stream_out(self.pg1)
5147 self.pg1.add_stream(pkts)
5148 self.pg_enable_capture(self.pg_interfaces)
5150 capture = self.pg0.get_capture(len(pkts))
5151 self.verify_capture_in(capture, self.pg0)
5153 # session initiated from remote host - do not translate
5154 self.tcp_port_in = 60303
5155 self.udp_port_in = 60304
5156 self.icmp_id_in = 60305
5157 pkts = self.create_stream_out(self.pg1,
5158 self.pg0.remote_ip4,
5159 use_inside_ports=True)
5160 self.pg1.add_stream(pkts)
5161 self.pg_enable_capture(self.pg_interfaces)
5163 capture = self.pg0.get_capture(len(pkts))
5164 self.verify_capture_in(capture, self.pg0)
5166 pkts = self.create_stream_in(self.pg0, self.pg1)
5167 self.pg0.add_stream(pkts)
5168 self.pg_enable_capture(self.pg_interfaces)
5170 capture = self.pg1.get_capture(len(pkts))
5171 self.verify_capture_out(capture, nat_ip=self.pg0.remote_ip4,
5174 def test_output_feature_and_service3(self):
5175 """ NAT44 interface output feature and DST NAT """
5176 external_addr = '1.2.3.4'
5180 self.vapi.nat44_forwarding_enable_disable(1)
5181 self.nat44_add_address(self.nat_addr)
5182 self.nat44_add_static_mapping(self.pg1.remote_ip4, external_addr,
5183 local_port, external_port,
5184 proto=IP_PROTOS.tcp, out2in_only=1)
5185 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
5186 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index,
5188 self.vapi.nat44_interface_add_del_output_feature(self.pg1.sw_if_index,
5191 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5192 IP(src=self.pg0.remote_ip4, dst=external_addr) /
5193 TCP(sport=12345, dport=external_port))
5194 self.pg0.add_stream(p)
5195 self.pg_enable_capture(self.pg_interfaces)
5197 capture = self.pg1.get_capture(1)
5202 self.assertEqual(ip.src, self.pg0.remote_ip4)
5203 self.assertEqual(tcp.sport, 12345)
5204 self.assertEqual(ip.dst, self.pg1.remote_ip4)
5205 self.assertEqual(tcp.dport, local_port)
5206 self.assert_packet_checksums_valid(p)
5208 self.logger.error(ppp("Unexpected or invalid packet:", p))
5211 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
5212 IP(src=self.pg1.remote_ip4, dst=self.pg0.remote_ip4) /
5213 TCP(sport=local_port, dport=12345))
5214 self.pg1.add_stream(p)
5215 self.pg_enable_capture(self.pg_interfaces)
5217 capture = self.pg0.get_capture(1)
5222 self.assertEqual(ip.src, external_addr)
5223 self.assertEqual(tcp.sport, external_port)
5224 self.assertEqual(ip.dst, self.pg0.remote_ip4)
5225 self.assertEqual(tcp.dport, 12345)
5226 self.assert_packet_checksums_valid(p)
5228 self.logger.error(ppp("Unexpected or invalid packet:", p))
5231 def test_next_src_nat(self):
5232 """ On way back forward packet to nat44-in2out node. """
5233 twice_nat_addr = '10.0.1.3'
5236 post_twice_nat_port = 0
5238 self.vapi.nat44_forwarding_enable_disable(1)
5239 self.nat44_add_address(twice_nat_addr, twice_nat=1)
5240 self.nat44_add_static_mapping(self.pg6.remote_ip4, self.pg1.remote_ip4,
5241 local_port, external_port,
5242 proto=IP_PROTOS.tcp, out2in_only=1,
5243 self_twice_nat=1, vrf_id=1)
5244 self.vapi.nat44_interface_add_del_feature(self.pg6.sw_if_index,
5247 p = (Ether(src=self.pg6.remote_mac, dst=self.pg6.local_mac) /
5248 IP(src=self.pg6.remote_ip4, dst=self.pg1.remote_ip4) /
5249 TCP(sport=12345, dport=external_port))
5250 self.pg6.add_stream(p)
5251 self.pg_enable_capture(self.pg_interfaces)
5253 capture = self.pg6.get_capture(1)
5258 self.assertEqual(ip.src, twice_nat_addr)
5259 self.assertNotEqual(tcp.sport, 12345)
5260 post_twice_nat_port = tcp.sport
5261 self.assertEqual(ip.dst, self.pg6.remote_ip4)
5262 self.assertEqual(tcp.dport, local_port)
5263 self.assert_packet_checksums_valid(p)
5265 self.logger.error(ppp("Unexpected or invalid packet:", p))
5268 p = (Ether(src=self.pg6.remote_mac, dst=self.pg6.local_mac) /
5269 IP(src=self.pg6.remote_ip4, dst=twice_nat_addr) /
5270 TCP(sport=local_port, dport=post_twice_nat_port))
5271 self.pg6.add_stream(p)
5272 self.pg_enable_capture(self.pg_interfaces)
5274 capture = self.pg6.get_capture(1)
5279 self.assertEqual(ip.src, self.pg1.remote_ip4)
5280 self.assertEqual(tcp.sport, external_port)
5281 self.assertEqual(ip.dst, self.pg6.remote_ip4)
5282 self.assertEqual(tcp.dport, 12345)
5283 self.assert_packet_checksums_valid(p)
5285 self.logger.error(ppp("Unexpected or invalid packet:", p))
5288 def twice_nat_common(self, self_twice_nat=False, same_pg=False, lb=False,
5290 twice_nat_addr = '10.0.1.3'
5298 port_in1 = port_in + 1
5299 port_in2 = port_in + 2
5304 server1 = self.pg0.remote_hosts[0]
5305 server2 = self.pg0.remote_hosts[1]
5317 eh_translate = ((not self_twice_nat) or (not lb and same_pg) or
5320 self.nat44_add_address(self.nat_addr)
5321 self.nat44_add_address(twice_nat_addr, twice_nat=1)
5323 self.nat44_add_static_mapping(pg0.remote_ip4, self.nat_addr,
5325 proto=IP_PROTOS.tcp,
5326 twice_nat=int(not self_twice_nat),
5327 self_twice_nat=int(self_twice_nat))
5329 locals = [{'addr': server1.ip4n,
5333 {'addr': server2.ip4n,
5337 out_addr_n = socket.inet_pton(socket.AF_INET, self.nat_addr)
5338 self.vapi.nat44_add_del_lb_static_mapping(out_addr_n,
5342 not self_twice_nat),
5345 local_num=len(locals),
5347 self.vapi.nat44_interface_add_del_feature(pg0.sw_if_index)
5348 self.vapi.nat44_interface_add_del_feature(pg1.sw_if_index,
5355 assert client_id is not None
5357 client = self.pg0.remote_hosts[0]
5358 elif client_id == 2:
5359 client = self.pg0.remote_hosts[1]
5361 client = pg1.remote_hosts[0]
5362 p = (Ether(src=pg1.remote_mac, dst=pg1.local_mac) /
5363 IP(src=client.ip4, dst=self.nat_addr) /
5364 TCP(sport=eh_port_out, dport=port_out))
5366 self.pg_enable_capture(self.pg_interfaces)
5368 capture = pg0.get_capture(1)
5374 if ip.dst == server1.ip4:
5380 self.assertEqual(ip.dst, server.ip4)
5382 self.assertIn(tcp.dport, [port_in1, port_in2])
5384 self.assertEqual(tcp.dport, port_in)
5386 self.assertEqual(ip.src, twice_nat_addr)
5387 self.assertNotEqual(tcp.sport, eh_port_out)
5389 self.assertEqual(ip.src, client.ip4)
5390 self.assertEqual(tcp.sport, eh_port_out)
5392 eh_port_in = tcp.sport
5393 saved_port_in = tcp.dport
5394 self.assert_packet_checksums_valid(p)
5396 self.logger.error(ppp("Unexpected or invalid packet:", p))
5399 p = (Ether(src=server.mac, dst=pg0.local_mac) /
5400 IP(src=server.ip4, dst=eh_addr_in) /
5401 TCP(sport=saved_port_in, dport=eh_port_in))
5403 self.pg_enable_capture(self.pg_interfaces)
5405 capture = pg1.get_capture(1)
5410 self.assertEqual(ip.dst, client.ip4)
5411 self.assertEqual(ip.src, self.nat_addr)
5412 self.assertEqual(tcp.dport, eh_port_out)
5413 self.assertEqual(tcp.sport, port_out)
5414 self.assert_packet_checksums_valid(p)
5416 self.logger.error(ppp("Unexpected or invalid packet:", p))
5420 sessions = self.vapi.nat44_user_session_dump(server.ip4n, 0)
5421 self.assertEqual(len(sessions), 1)
5422 self.assertTrue(sessions[0].ext_host_valid)
5423 self.assertTrue(sessions[0].is_twicenat)
5424 self.vapi.nat44_del_session(
5425 sessions[0].inside_ip_address,
5426 sessions[0].inside_port,
5427 sessions[0].protocol,
5428 ext_host_address=sessions[0].ext_host_nat_address,
5429 ext_host_port=sessions[0].ext_host_nat_port)
5430 sessions = self.vapi.nat44_user_session_dump(server.ip4n, 0)
5431 self.assertEqual(len(sessions), 0)
5433 def test_twice_nat(self):
5435 self.twice_nat_common()
5437 def test_self_twice_nat_positive(self):
5438 """ Self Twice NAT44 (positive test) """
5439 self.twice_nat_common(self_twice_nat=True, same_pg=True)
5441 def test_self_twice_nat_negative(self):
5442 """ Self Twice NAT44 (negative test) """
5443 self.twice_nat_common(self_twice_nat=True)
5445 def test_twice_nat_lb(self):
5446 """ Twice NAT44 local service load balancing """
5447 self.twice_nat_common(lb=True)
5449 def test_self_twice_nat_lb_positive(self):
5450 """ Self Twice NAT44 local service load balancing (positive test) """
5451 self.twice_nat_common(lb=True, self_twice_nat=True, same_pg=True,
5454 def test_self_twice_nat_lb_negative(self):
5455 """ Self Twice NAT44 local service load balancing (negative test) """
5456 self.twice_nat_common(lb=True, self_twice_nat=True, same_pg=True,
5459 def test_twice_nat_interface_addr(self):
5460 """ Acquire twice NAT44 addresses from interface """
5461 self.vapi.nat44_add_del_interface_addr(self.pg3.sw_if_index,
5464 # no address in NAT pool
5465 adresses = self.vapi.nat44_address_dump()
5466 self.assertEqual(0, len(adresses))
5468 # configure interface address and check NAT address pool
5469 self.pg3.config_ip4()
5470 adresses = self.vapi.nat44_address_dump()
5471 self.assertEqual(1, len(adresses))
5472 self.assertEqual(adresses[0].ip_address[0:4], self.pg3.local_ip4n)
5473 self.assertEqual(adresses[0].twice_nat, 1)
5475 # remove interface address and check NAT address pool
5476 self.pg3.unconfig_ip4()
5477 adresses = self.vapi.nat44_address_dump()
5478 self.assertEqual(0, len(adresses))
5480 def test_tcp_close(self):
5481 """ Close TCP session from inside network - output feature """
5482 self.vapi.nat44_forwarding_enable_disable(1)
5483 self.nat44_add_address(self.pg1.local_ip4)
5484 twice_nat_addr = '10.0.1.3'
5485 service_ip = '192.168.16.150'
5486 self.nat44_add_address(twice_nat_addr, twice_nat=1)
5487 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
5488 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index,
5490 self.vapi.nat44_interface_add_del_output_feature(self.pg1.sw_if_index,
5492 self.nat44_add_static_mapping(self.pg0.remote_ip4,
5496 proto=IP_PROTOS.tcp,
5499 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4n, 0)
5500 start_sessnum = len(sessions)
5502 # SYN packet out->in
5503 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
5504 IP(src=self.pg1.remote_ip4, dst=service_ip) /
5505 TCP(sport=33898, dport=80, flags="S"))
5506 self.pg1.add_stream(p)
5507 self.pg_enable_capture(self.pg_interfaces)
5509 capture = self.pg0.get_capture(1)
5511 tcp_port = p[TCP].sport
5513 # SYN + ACK packet in->out
5514 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5515 IP(src=self.pg0.remote_ip4, dst=twice_nat_addr) /
5516 TCP(sport=80, dport=tcp_port, flags="SA"))
5517 self.pg0.add_stream(p)
5518 self.pg_enable_capture(self.pg_interfaces)
5520 self.pg1.get_capture(1)
5522 # ACK packet out->in
5523 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
5524 IP(src=self.pg1.remote_ip4, dst=service_ip) /
5525 TCP(sport=33898, dport=80, flags="A"))
5526 self.pg1.add_stream(p)
5527 self.pg_enable_capture(self.pg_interfaces)
5529 self.pg0.get_capture(1)
5531 # FIN packet in -> out
5532 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5533 IP(src=self.pg0.remote_ip4, dst=twice_nat_addr) /
5534 TCP(sport=80, dport=tcp_port, flags="FA", seq=100, ack=300))
5535 self.pg0.add_stream(p)
5536 self.pg_enable_capture(self.pg_interfaces)
5538 self.pg1.get_capture(1)
5540 # FIN+ACK packet out -> in
5541 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
5542 IP(src=self.pg1.remote_ip4, dst=service_ip) /
5543 TCP(sport=33898, dport=80, flags="FA", seq=300, ack=101))
5544 self.pg1.add_stream(p)
5545 self.pg_enable_capture(self.pg_interfaces)
5547 self.pg0.get_capture(1)
5549 # ACK packet in -> out
5550 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5551 IP(src=self.pg0.remote_ip4, dst=twice_nat_addr) /
5552 TCP(sport=80, dport=tcp_port, flags="A", seq=101, ack=301))
5553 self.pg0.add_stream(p)
5554 self.pg_enable_capture(self.pg_interfaces)
5556 self.pg1.get_capture(1)
5558 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4n,
5560 self.assertEqual(len(sessions) - start_sessnum, 0)
5562 def test_tcp_session_close_in(self):
5563 """ Close TCP session from inside network """
5564 self.tcp_port_out = 10505
5565 self.nat44_add_address(self.nat_addr)
5566 self.nat44_add_static_mapping(self.pg0.remote_ip4,
5570 proto=IP_PROTOS.tcp,
5572 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
5573 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
5576 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4n, 0)
5577 start_sessnum = len(sessions)
5579 self.initiate_tcp_session(self.pg0, self.pg1)
5581 # FIN packet in -> out
5582 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5583 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
5584 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
5585 flags="FA", seq=100, ack=300))
5586 self.pg0.add_stream(p)
5587 self.pg_enable_capture(self.pg_interfaces)
5589 self.pg1.get_capture(1)
5593 # ACK packet out -> in
5594 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
5595 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
5596 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
5597 flags="A", seq=300, ack=101))
5600 # FIN packet out -> in
5601 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
5602 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
5603 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
5604 flags="FA", seq=300, ack=101))
5607 self.pg1.add_stream(pkts)
5608 self.pg_enable_capture(self.pg_interfaces)
5610 self.pg0.get_capture(2)
5612 # ACK packet in -> out
5613 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5614 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
5615 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
5616 flags="A", seq=101, ack=301))
5617 self.pg0.add_stream(p)
5618 self.pg_enable_capture(self.pg_interfaces)
5620 self.pg1.get_capture(1)
5622 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4n,
5624 self.assertEqual(len(sessions) - start_sessnum, 0)
5626 def test_tcp_session_close_out(self):
5627 """ Close TCP session from outside network """
5628 self.tcp_port_out = 10505
5629 self.nat44_add_address(self.nat_addr)
5630 self.nat44_add_static_mapping(self.pg0.remote_ip4,
5634 proto=IP_PROTOS.tcp,
5636 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
5637 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
5640 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4n, 0)
5641 start_sessnum = len(sessions)
5643 self.initiate_tcp_session(self.pg0, self.pg1)
5645 # FIN packet out -> in
5646 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
5647 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
5648 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
5649 flags="FA", seq=100, ack=300))
5650 self.pg1.add_stream(p)
5651 self.pg_enable_capture(self.pg_interfaces)
5653 self.pg0.get_capture(1)
5655 # FIN+ACK packet in -> out
5656 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5657 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
5658 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
5659 flags="FA", seq=300, ack=101))
5661 self.pg0.add_stream(p)
5662 self.pg_enable_capture(self.pg_interfaces)
5664 self.pg1.get_capture(1)
5666 # ACK packet out -> in
5667 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
5668 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
5669 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
5670 flags="A", seq=101, ack=301))
5671 self.pg1.add_stream(p)
5672 self.pg_enable_capture(self.pg_interfaces)
5674 self.pg0.get_capture(1)
5676 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4n,
5678 self.assertEqual(len(sessions) - start_sessnum, 0)
5680 def test_tcp_session_close_simultaneous(self):
5681 """ Close TCP session from inside network """
5682 self.tcp_port_out = 10505
5683 self.nat44_add_address(self.nat_addr)
5684 self.nat44_add_static_mapping(self.pg0.remote_ip4,
5688 proto=IP_PROTOS.tcp,
5690 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
5691 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
5694 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4n, 0)
5695 start_sessnum = len(sessions)
5697 self.initiate_tcp_session(self.pg0, self.pg1)
5699 # FIN packet in -> out
5700 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5701 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
5702 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
5703 flags="FA", seq=100, ack=300))
5704 self.pg0.add_stream(p)
5705 self.pg_enable_capture(self.pg_interfaces)
5707 self.pg1.get_capture(1)
5709 # FIN packet out -> in
5710 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
5711 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
5712 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
5713 flags="FA", seq=300, ack=100))
5714 self.pg1.add_stream(p)
5715 self.pg_enable_capture(self.pg_interfaces)
5717 self.pg0.get_capture(1)
5719 # ACK packet in -> out
5720 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5721 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
5722 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
5723 flags="A", seq=101, ack=301))
5724 self.pg0.add_stream(p)
5725 self.pg_enable_capture(self.pg_interfaces)
5727 self.pg1.get_capture(1)
5729 # ACK packet out -> in
5730 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
5731 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
5732 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
5733 flags="A", seq=301, ack=101))
5734 self.pg1.add_stream(p)
5735 self.pg_enable_capture(self.pg_interfaces)
5737 self.pg0.get_capture(1)
5739 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4n,
5741 self.assertEqual(len(sessions) - start_sessnum, 0)
5743 def test_one_armed_nat44_static(self):
5744 """ One armed NAT44 and 1:1 NAPT asymmetrical rule """
5745 remote_host = self.pg4.remote_hosts[0]
5746 local_host = self.pg4.remote_hosts[1]
5751 self.vapi.nat44_forwarding_enable_disable(1)
5752 self.nat44_add_address(self.nat_addr, twice_nat=1)
5753 self.nat44_add_static_mapping(local_host.ip4, self.nat_addr,
5754 local_port, external_port,
5755 proto=IP_PROTOS.tcp, out2in_only=1,
5757 self.vapi.nat44_interface_add_del_feature(self.pg4.sw_if_index)
5758 self.vapi.nat44_interface_add_del_feature(self.pg4.sw_if_index,
5761 # from client to service
5762 p = (Ether(src=self.pg4.remote_mac, dst=self.pg4.local_mac) /
5763 IP(src=remote_host.ip4, dst=self.nat_addr) /
5764 TCP(sport=12345, dport=external_port))
5765 self.pg4.add_stream(p)
5766 self.pg_enable_capture(self.pg_interfaces)
5768 capture = self.pg4.get_capture(1)
5773 self.assertEqual(ip.dst, local_host.ip4)
5774 self.assertEqual(ip.src, self.nat_addr)
5775 self.assertEqual(tcp.dport, local_port)
5776 self.assertNotEqual(tcp.sport, 12345)
5777 eh_port_in = tcp.sport
5778 self.assert_packet_checksums_valid(p)
5780 self.logger.error(ppp("Unexpected or invalid packet:", p))
5783 # from service back to client
5784 p = (Ether(src=self.pg4.remote_mac, dst=self.pg4.local_mac) /
5785 IP(src=local_host.ip4, dst=self.nat_addr) /
5786 TCP(sport=local_port, dport=eh_port_in))
5787 self.pg4.add_stream(p)
5788 self.pg_enable_capture(self.pg_interfaces)
5790 capture = self.pg4.get_capture(1)
5795 self.assertEqual(ip.src, self.nat_addr)
5796 self.assertEqual(ip.dst, remote_host.ip4)
5797 self.assertEqual(tcp.sport, external_port)
5798 self.assertEqual(tcp.dport, 12345)
5799 self.assert_packet_checksums_valid(p)
5801 self.logger.error(ppp("Unexpected or invalid packet:", p))
5804 def test_static_with_port_out2(self):
5805 """ 1:1 NAPT asymmetrical rule """
5810 self.vapi.nat44_forwarding_enable_disable(1)
5811 self.nat44_add_static_mapping(self.pg0.remote_ip4, self.nat_addr,
5812 local_port, external_port,
5813 proto=IP_PROTOS.tcp, out2in_only=1)
5814 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
5815 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
5818 # from client to service
5819 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
5820 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
5821 TCP(sport=12345, dport=external_port))
5822 self.pg1.add_stream(p)
5823 self.pg_enable_capture(self.pg_interfaces)
5825 capture = self.pg0.get_capture(1)
5830 self.assertEqual(ip.dst, self.pg0.remote_ip4)
5831 self.assertEqual(tcp.dport, local_port)
5832 self.assert_packet_checksums_valid(p)
5834 self.logger.error(ppp("Unexpected or invalid packet:", p))
5838 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
5839 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
5840 ICMP(type=11) / capture[0][IP])
5841 self.pg0.add_stream(p)
5842 self.pg_enable_capture(self.pg_interfaces)
5844 capture = self.pg1.get_capture(1)
5847 self.assertEqual(p[IP].src, self.nat_addr)
5849 self.assertEqual(inner.dst, self.nat_addr)
5850 self.assertEqual(inner[TCPerror].dport, external_port)
5852 self.logger.error(ppp("Unexpected or invalid packet:", p))
5855 # from service back to client
5856 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5857 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
5858 TCP(sport=local_port, dport=12345))
5859 self.pg0.add_stream(p)
5860 self.pg_enable_capture(self.pg_interfaces)
5862 capture = self.pg1.get_capture(1)
5867 self.assertEqual(ip.src, self.nat_addr)
5868 self.assertEqual(tcp.sport, external_port)
5869 self.assert_packet_checksums_valid(p)
5871 self.logger.error(ppp("Unexpected or invalid packet:", p))
5875 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
5876 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
5877 ICMP(type=11) / capture[0][IP])
5878 self.pg1.add_stream(p)
5879 self.pg_enable_capture(self.pg_interfaces)
5881 capture = self.pg0.get_capture(1)
5884 self.assertEqual(p[IP].dst, self.pg0.remote_ip4)
5886 self.assertEqual(inner.src, self.pg0.remote_ip4)
5887 self.assertEqual(inner[TCPerror].sport, local_port)
5889 self.logger.error(ppp("Unexpected or invalid packet:", p))
5892 # from client to server (no translation)
5893 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
5894 IP(src=self.pg1.remote_ip4, dst=self.pg0.remote_ip4) /
5895 TCP(sport=12346, dport=local_port))
5896 self.pg1.add_stream(p)
5897 self.pg_enable_capture(self.pg_interfaces)
5899 capture = self.pg0.get_capture(1)
5904 self.assertEqual(ip.dst, self.pg0.remote_ip4)
5905 self.assertEqual(tcp.dport, local_port)
5906 self.assert_packet_checksums_valid(p)
5908 self.logger.error(ppp("Unexpected or invalid packet:", p))
5911 # from service back to client (no translation)
5912 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5913 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
5914 TCP(sport=local_port, dport=12346))
5915 self.pg0.add_stream(p)
5916 self.pg_enable_capture(self.pg_interfaces)
5918 capture = self.pg1.get_capture(1)
5923 self.assertEqual(ip.src, self.pg0.remote_ip4)
5924 self.assertEqual(tcp.sport, local_port)
5925 self.assert_packet_checksums_valid(p)
5927 self.logger.error(ppp("Unexpected or invalid packet:", p))
5930 def test_output_feature(self):
5931 """ NAT44 interface output feature (in2out postrouting) """
5932 self.vapi.nat44_forwarding_enable_disable(1)
5933 self.nat44_add_address(self.nat_addr)
5934 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index,
5936 self.vapi.nat44_interface_add_del_output_feature(self.pg1.sw_if_index,
5940 pkts = self.create_stream_in(self.pg0, self.pg1)
5941 self.pg0.add_stream(pkts)
5942 self.pg_enable_capture(self.pg_interfaces)
5944 capture = self.pg1.get_capture(len(pkts))
5945 self.verify_capture_out(capture)
5948 pkts = self.create_stream_out(self.pg1)
5949 self.pg1.add_stream(pkts)
5950 self.pg_enable_capture(self.pg_interfaces)
5952 capture = self.pg0.get_capture(len(pkts))
5953 self.verify_capture_in(capture, self.pg0)
5955 def test_multiple_vrf(self):
5956 """ Multiple VRF setup """
5957 external_addr = '1.2.3.4'
5962 self.vapi.nat44_forwarding_enable_disable(1)
5963 self.nat44_add_address(self.nat_addr)
5964 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
5965 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index,
5967 self.vapi.nat44_interface_add_del_output_feature(self.pg1.sw_if_index,
5969 self.vapi.nat44_interface_add_del_feature(self.pg5.sw_if_index)
5970 self.vapi.nat44_interface_add_del_feature(self.pg5.sw_if_index,
5972 self.vapi.nat44_interface_add_del_feature(self.pg6.sw_if_index,
5974 self.nat44_add_static_mapping(self.pg5.remote_ip4, external_addr,
5975 local_port, external_port, vrf_id=1,
5976 proto=IP_PROTOS.tcp, out2in_only=1)
5977 self.nat44_add_static_mapping(
5978 self.pg0.remote_ip4, external_sw_if_index=self.pg0.sw_if_index,
5979 local_port=local_port, vrf_id=0, external_port=external_port,
5980 proto=IP_PROTOS.tcp, out2in_only=1)
5982 # from client to service (both VRF1)
5983 p = (Ether(src=self.pg6.remote_mac, dst=self.pg6.local_mac) /
5984 IP(src=self.pg6.remote_ip4, dst=external_addr) /
5985 TCP(sport=12345, dport=external_port))
5986 self.pg6.add_stream(p)
5987 self.pg_enable_capture(self.pg_interfaces)
5989 capture = self.pg5.get_capture(1)
5994 self.assertEqual(ip.dst, self.pg5.remote_ip4)
5995 self.assertEqual(tcp.dport, local_port)
5996 self.assert_packet_checksums_valid(p)
5998 self.logger.error(ppp("Unexpected or invalid packet:", p))
6001 # from service back to client (both VRF1)
6002 p = (Ether(src=self.pg5.remote_mac, dst=self.pg5.local_mac) /
6003 IP(src=self.pg5.remote_ip4, dst=self.pg6.remote_ip4) /
6004 TCP(sport=local_port, dport=12345))
6005 self.pg5.add_stream(p)
6006 self.pg_enable_capture(self.pg_interfaces)
6008 capture = self.pg6.get_capture(1)
6013 self.assertEqual(ip.src, external_addr)
6014 self.assertEqual(tcp.sport, external_port)
6015 self.assert_packet_checksums_valid(p)
6017 self.logger.error(ppp("Unexpected or invalid packet:", p))
6020 # dynamic NAT from VRF1 to VRF0 (output-feature)
6021 p = (Ether(src=self.pg5.remote_mac, dst=self.pg5.local_mac) /
6022 IP(src=self.pg5.remote_ip4, dst=self.pg1.remote_ip4) /
6023 TCP(sport=2345, dport=22))
6024 self.pg5.add_stream(p)
6025 self.pg_enable_capture(self.pg_interfaces)
6027 capture = self.pg1.get_capture(1)
6032 self.assertEqual(ip.src, self.nat_addr)
6033 self.assertNotEqual(tcp.sport, 2345)
6034 self.assert_packet_checksums_valid(p)
6037 self.logger.error(ppp("Unexpected or invalid packet:", p))
6040 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
6041 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
6042 TCP(sport=22, dport=port))
6043 self.pg1.add_stream(p)
6044 self.pg_enable_capture(self.pg_interfaces)
6046 capture = self.pg5.get_capture(1)
6051 self.assertEqual(ip.dst, self.pg5.remote_ip4)
6052 self.assertEqual(tcp.dport, 2345)
6053 self.assert_packet_checksums_valid(p)
6055 self.logger.error(ppp("Unexpected or invalid packet:", p))
6058 # from client VRF1 to service VRF0
6059 p = (Ether(src=self.pg6.remote_mac, dst=self.pg6.local_mac) /
6060 IP(src=self.pg6.remote_ip4, dst=self.pg0.local_ip4) /
6061 TCP(sport=12346, dport=external_port))
6062 self.pg6.add_stream(p)
6063 self.pg_enable_capture(self.pg_interfaces)
6065 capture = self.pg0.get_capture(1)
6070 self.assertEqual(ip.dst, self.pg0.remote_ip4)
6071 self.assertEqual(tcp.dport, local_port)
6072 self.assert_packet_checksums_valid(p)
6074 self.logger.error(ppp("Unexpected or invalid packet:", p))
6077 # from service VRF0 back to client VRF1
6078 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6079 IP(src=self.pg0.remote_ip4, dst=self.pg6.remote_ip4) /
6080 TCP(sport=local_port, dport=12346))
6081 self.pg0.add_stream(p)
6082 self.pg_enable_capture(self.pg_interfaces)
6084 capture = self.pg6.get_capture(1)
6089 self.assertEqual(ip.src, self.pg0.local_ip4)
6090 self.assertEqual(tcp.sport, external_port)
6091 self.assert_packet_checksums_valid(p)
6093 self.logger.error(ppp("Unexpected or invalid packet:", p))
6096 # from client VRF0 to service VRF1
6097 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6098 IP(src=self.pg0.remote_ip4, dst=external_addr) /
6099 TCP(sport=12347, dport=external_port))
6100 self.pg0.add_stream(p)
6101 self.pg_enable_capture(self.pg_interfaces)
6103 capture = self.pg5.get_capture(1)
6108 self.assertEqual(ip.dst, self.pg5.remote_ip4)
6109 self.assertEqual(tcp.dport, local_port)
6110 self.assert_packet_checksums_valid(p)
6112 self.logger.error(ppp("Unexpected or invalid packet:", p))
6115 # from service VRF1 back to client VRF0
6116 p = (Ether(src=self.pg5.remote_mac, dst=self.pg5.local_mac) /
6117 IP(src=self.pg5.remote_ip4, dst=self.pg0.remote_ip4) /
6118 TCP(sport=local_port, dport=12347))
6119 self.pg5.add_stream(p)
6120 self.pg_enable_capture(self.pg_interfaces)
6122 capture = self.pg0.get_capture(1)
6127 self.assertEqual(ip.src, external_addr)
6128 self.assertEqual(tcp.sport, external_port)
6129 self.assert_packet_checksums_valid(p)
6131 self.logger.error(ppp("Unexpected or invalid packet:", p))
6134 # from client to server (both VRF1, no translation)
6135 p = (Ether(src=self.pg6.remote_mac, dst=self.pg6.local_mac) /
6136 IP(src=self.pg6.remote_ip4, dst=self.pg5.remote_ip4) /
6137 TCP(sport=12348, dport=local_port))
6138 self.pg6.add_stream(p)
6139 self.pg_enable_capture(self.pg_interfaces)
6141 capture = self.pg5.get_capture(1)
6146 self.assertEqual(ip.dst, self.pg5.remote_ip4)
6147 self.assertEqual(tcp.dport, local_port)
6148 self.assert_packet_checksums_valid(p)
6150 self.logger.error(ppp("Unexpected or invalid packet:", p))
6153 # from server back to client (both VRF1, no translation)
6154 p = (Ether(src=self.pg5.remote_mac, dst=self.pg5.local_mac) /
6155 IP(src=self.pg5.remote_ip4, dst=self.pg6.remote_ip4) /
6156 TCP(sport=local_port, dport=12348))
6157 self.pg5.add_stream(p)
6158 self.pg_enable_capture(self.pg_interfaces)
6160 capture = self.pg6.get_capture(1)
6165 self.assertEqual(ip.src, self.pg5.remote_ip4)
6166 self.assertEqual(tcp.sport, local_port)
6167 self.assert_packet_checksums_valid(p)
6169 self.logger.error(ppp("Unexpected or invalid packet:", p))
6172 # from client VRF1 to server VRF0 (no translation)
6173 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6174 IP(src=self.pg0.remote_ip4, dst=self.pg6.remote_ip4) /
6175 TCP(sport=local_port, dport=12349))
6176 self.pg0.add_stream(p)
6177 self.pg_enable_capture(self.pg_interfaces)
6179 capture = self.pg6.get_capture(1)
6184 self.assertEqual(ip.src, self.pg0.remote_ip4)
6185 self.assertEqual(tcp.sport, local_port)
6186 self.assert_packet_checksums_valid(p)
6188 self.logger.error(ppp("Unexpected or invalid packet:", p))
6191 # from server VRF0 back to client VRF1 (no translation)
6192 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6193 IP(src=self.pg0.remote_ip4, dst=self.pg6.remote_ip4) /
6194 TCP(sport=local_port, dport=12349))
6195 self.pg0.add_stream(p)
6196 self.pg_enable_capture(self.pg_interfaces)
6198 capture = self.pg6.get_capture(1)
6203 self.assertEqual(ip.src, self.pg0.remote_ip4)
6204 self.assertEqual(tcp.sport, local_port)
6205 self.assert_packet_checksums_valid(p)
6207 self.logger.error(ppp("Unexpected or invalid packet:", p))
6210 # from client VRF0 to server VRF1 (no translation)
6211 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6212 IP(src=self.pg0.remote_ip4, dst=self.pg5.remote_ip4) /
6213 TCP(sport=12344, dport=local_port))
6214 self.pg0.add_stream(p)
6215 self.pg_enable_capture(self.pg_interfaces)
6217 capture = self.pg5.get_capture(1)
6222 self.assertEqual(ip.dst, self.pg5.remote_ip4)
6223 self.assertEqual(tcp.dport, local_port)
6224 self.assert_packet_checksums_valid(p)
6226 self.logger.error(ppp("Unexpected or invalid packet:", p))
6229 # from server VRF1 back to client VRF0 (no translation)
6230 p = (Ether(src=self.pg5.remote_mac, dst=self.pg5.local_mac) /
6231 IP(src=self.pg5.remote_ip4, dst=self.pg0.remote_ip4) /
6232 TCP(sport=local_port, dport=12344))
6233 self.pg5.add_stream(p)
6234 self.pg_enable_capture(self.pg_interfaces)
6236 capture = self.pg0.get_capture(1)
6241 self.assertEqual(ip.src, self.pg5.remote_ip4)
6242 self.assertEqual(tcp.sport, local_port)
6243 self.assert_packet_checksums_valid(p)
6245 self.logger.error(ppp("Unexpected or invalid packet:", p))
6248 @unittest.skipUnless(running_extended_tests, "part of extended tests")
6249 def test_session_timeout(self):
6250 """ NAT44 session timeouts """
6251 self.nat44_add_address(self.nat_addr)
6252 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
6253 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
6255 self.vapi.nat_set_timeouts(icmp=5)
6259 for i in range(0, max_sessions):
6260 src = "10.10.%u.%u" % ((i & 0xFF00) >> 8, i & 0xFF)
6261 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
6262 IP(src=src, dst=self.pg1.remote_ip4) /
6263 ICMP(id=1025, type='echo-request'))
6265 self.pg0.add_stream(pkts)
6266 self.pg_enable_capture(self.pg_interfaces)
6268 self.pg1.get_capture(max_sessions)
6273 for i in range(0, max_sessions):
6274 src = "10.11.%u.%u" % ((i & 0xFF00) >> 8, i & 0xFF)
6275 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
6276 IP(src=src, dst=self.pg1.remote_ip4) /
6277 ICMP(id=1026, type='echo-request'))
6279 self.pg0.add_stream(pkts)
6280 self.pg_enable_capture(self.pg_interfaces)
6282 self.pg1.get_capture(max_sessions)
6285 users = self.vapi.nat44_user_dump()
6287 nsessions = nsessions + user.nsessions
6288 self.assertLess(nsessions, 2 * max_sessions)
6290 @unittest.skipUnless(running_extended_tests, "part of extended tests")
6291 def test_session_rst_timeout(self):
6292 """ NAT44 session RST timeouts """
6293 self.nat44_add_address(self.nat_addr)
6294 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
6295 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
6297 self.vapi.nat_set_timeouts(tcp_transitory=5)
6299 self.initiate_tcp_session(self.pg0, self.pg1)
6300 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6301 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6302 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
6304 self.pg0.add_stream(p)
6305 self.pg_enable_capture(self.pg_interfaces)
6307 self.pg1.get_capture(1)
6311 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6312 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6313 TCP(sport=self.tcp_port_in + 1, dport=self.tcp_external_port + 1,
6315 self.pg0.add_stream(p)
6316 self.pg_enable_capture(self.pg_interfaces)
6318 self.pg1.get_capture(1)
6321 users = self.vapi.nat44_user_dump()
6322 self.assertEqual(len(users), 1)
6323 self.assertEqual(users[0].ip_address, self.pg0.remote_ip4n)
6324 self.assertEqual(users[0].nsessions, 1)
6326 @unittest.skipUnless(running_extended_tests, "part of extended tests")
6327 def test_session_limit_per_user(self):
6328 """ Maximum sessions per user limit """
6329 self.nat44_add_address(self.nat_addr)
6330 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
6331 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
6333 self.vapi.set_ipfix_exporter(collector_address=self.pg2.remote_ip4n,
6334 src_address=self.pg2.local_ip4n,
6336 template_interval=10)
6337 self.vapi.nat_set_timeouts(udp=5)
6339 # get maximum number of translations per user
6340 nat44_config = self.vapi.nat_show_config()
6343 for port in range(0, nat44_config.max_translations_per_user):
6344 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6345 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6346 UDP(sport=1025 + port, dport=1025 + port))
6349 self.pg0.add_stream(pkts)
6350 self.pg_enable_capture(self.pg_interfaces)
6352 capture = self.pg1.get_capture(len(pkts))
6354 self.vapi.nat_ipfix_enable_disable(domain_id=self.ipfix_domain_id,
6355 src_port=self.ipfix_src_port)
6357 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6358 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6359 UDP(sport=3001, dport=3002))
6360 self.pg0.add_stream(p)
6361 self.pg_enable_capture(self.pg_interfaces)
6363 capture = self.pg1.assert_nothing_captured()
6365 # verify IPFIX logging
6366 self.vapi.cli("ipfix flush") # FIXME this should be an API call
6368 capture = self.pg2.get_capture(10)
6369 ipfix = IPFIXDecoder()
6370 # first load template
6372 self.assertTrue(p.haslayer(IPFIX))
6373 if p.haslayer(Template):
6374 ipfix.add_template(p.getlayer(Template))
6375 # verify events in data set
6377 if p.haslayer(Data):
6378 data = ipfix.decode_data_set(p.getlayer(Set))
6379 self.verify_ipfix_max_entries_per_user(
6381 nat44_config.max_translations_per_user,
6382 self.pg0.remote_ip4n)
6385 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6386 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6387 UDP(sport=3001, dport=3002))
6388 self.pg0.add_stream(p)
6389 self.pg_enable_capture(self.pg_interfaces)
6391 self.pg1.get_capture(1)
6393 def test_syslog_sess(self):
6394 """ Test syslog session creation and deletion """
6395 self.vapi.syslog_set_filter(SYSLOG_SEVERITY.INFO)
6396 self.vapi.syslog_set_sender(self.pg2.local_ip4n, self.pg2.remote_ip4n)
6397 self.nat44_add_address(self.nat_addr)
6398 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
6399 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
6402 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
6403 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6404 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port))
6405 self.pg0.add_stream(p)
6406 self.pg_enable_capture(self.pg_interfaces)
6408 capture = self.pg1.get_capture(1)
6409 self.tcp_port_out = capture[0][TCP].sport
6410 capture = self.pg2.get_capture(1)
6411 self.verify_syslog_sess(capture[0][Raw].load)
6413 self.pg_enable_capture(self.pg_interfaces)
6415 self.nat44_add_address(self.nat_addr, is_add=0)
6416 capture = self.pg2.get_capture(1)
6417 self.verify_syslog_sess(capture[0][Raw].load, False)
6420 super(TestNAT44EndpointDependent, self).tearDown()
6421 if not self.vpp_dead:
6422 self.logger.info(self.vapi.cli("show nat44 addresses"))
6423 self.logger.info(self.vapi.cli("show nat44 interfaces"))
6424 self.logger.info(self.vapi.cli("show nat44 static mappings"))
6425 self.logger.info(self.vapi.cli("show nat44 interface address"))
6426 self.logger.info(self.vapi.cli("show nat44 sessions detail"))
6427 self.logger.info(self.vapi.cli("show nat44 hash tables detail"))
6428 self.logger.info(self.vapi.cli("show nat timeouts"))
6430 self.vapi.cli("clear logging")
6433 class TestNAT44Out2InDPO(MethodHolder):
6434 """ NAT44 Test Cases using out2in DPO """
6437 def setUpConstants(cls):
6438 super(TestNAT44Out2InDPO, cls).setUpConstants()
6439 cls.vpp_cmdline.extend(["nat", "{", "out2in dpo", "}"])
6442 def setUpClass(cls):
6443 super(TestNAT44Out2InDPO, cls).setUpClass()
6444 cls.vapi.cli("set log class nat level debug")
6447 cls.tcp_port_in = 6303
6448 cls.tcp_port_out = 6303
6449 cls.udp_port_in = 6304
6450 cls.udp_port_out = 6304
6451 cls.icmp_id_in = 6305
6452 cls.icmp_id_out = 6305
6453 cls.nat_addr = '10.0.0.3'
6454 cls.nat_addr_n = socket.inet_pton(socket.AF_INET, cls.nat_addr)
6455 cls.dst_ip4 = '192.168.70.1'
6457 cls.create_pg_interfaces(range(2))
6460 cls.pg0.config_ip4()
6461 cls.pg0.resolve_arp()
6464 cls.pg1.config_ip6()
6465 cls.pg1.resolve_ndp()
6467 cls.vapi.ip_add_del_route(dst_address=b'\x00' * 16,
6468 dst_address_length=0,
6469 next_hop_address=cls.pg1.remote_ip6n,
6470 next_hop_sw_if_index=cls.pg1.sw_if_index,
6474 super(TestNAT44Out2InDPO, cls).tearDownClass()
6478 def tearDownClass(cls):
6479 super(TestNAT44Out2InDPO, cls).tearDownClass()
6481 def configure_xlat(self):
6482 self.dst_ip6_pfx = '1:2:3::'
6483 self.dst_ip6_pfx_n = socket.inet_pton(socket.AF_INET6,
6485 self.dst_ip6_pfx_len = 96
6486 self.src_ip6_pfx = '4:5:6::'
6487 self.src_ip6_pfx_n = socket.inet_pton(socket.AF_INET6,
6489 self.src_ip6_pfx_len = 96
6490 self.vapi.map_add_domain(self.dst_ip6_pfx_n, self.dst_ip6_pfx_len,
6491 self.src_ip6_pfx_n, self.src_ip6_pfx_len,
6492 '\x00\x00\x00\x00', 0)
6494 @unittest.skip('Temporary disabled')
6495 def test_464xlat_ce(self):
6496 """ Test 464XLAT CE with NAT44 """
6498 nat_config = self.vapi.nat_show_config()
6499 self.assertEqual(1, nat_config.out2in_dpo)
6501 self.configure_xlat()
6503 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
6504 self.vapi.nat44_add_del_address_range(self.nat_addr_n, self.nat_addr_n)
6506 out_src_ip6 = self.compose_ip6(self.dst_ip4, self.dst_ip6_pfx,
6507 self.dst_ip6_pfx_len)
6508 out_dst_ip6 = self.compose_ip6(self.nat_addr, self.src_ip6_pfx,
6509 self.src_ip6_pfx_len)
6512 pkts = self.create_stream_in(self.pg0, self.pg1, self.dst_ip4)
6513 self.pg0.add_stream(pkts)
6514 self.pg_enable_capture(self.pg_interfaces)
6516 capture = self.pg1.get_capture(len(pkts))
6517 self.verify_capture_out_ip6(capture, nat_ip=out_dst_ip6,
6520 pkts = self.create_stream_out_ip6(self.pg1, out_src_ip6,
6522 self.pg1.add_stream(pkts)
6523 self.pg_enable_capture(self.pg_interfaces)
6525 capture = self.pg0.get_capture(len(pkts))
6526 self.verify_capture_in(capture, self.pg0)
6528 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index,
6530 self.vapi.nat44_add_del_address_range(self.nat_addr_n,
6531 self.nat_addr_n, is_add=0)
6533 @unittest.skip('Temporary disabled')
6534 def test_464xlat_ce_no_nat(self):
6535 """ Test 464XLAT CE without NAT44 """
6537 self.configure_xlat()
6539 out_src_ip6 = self.compose_ip6(self.dst_ip4, self.dst_ip6_pfx,
6540 self.dst_ip6_pfx_len)
6541 out_dst_ip6 = self.compose_ip6(self.pg0.remote_ip4, self.src_ip6_pfx,
6542 self.src_ip6_pfx_len)
6544 pkts = self.create_stream_in(self.pg0, self.pg1, self.dst_ip4)
6545 self.pg0.add_stream(pkts)
6546 self.pg_enable_capture(self.pg_interfaces)
6548 capture = self.pg1.get_capture(len(pkts))
6549 self.verify_capture_out_ip6(capture, dst_ip=out_src_ip6,
6550 nat_ip=out_dst_ip6, same_port=True)
6552 pkts = self.create_stream_out_ip6(self.pg1, out_src_ip6, out_dst_ip6)
6553 self.pg1.add_stream(pkts)
6554 self.pg_enable_capture(self.pg_interfaces)
6556 capture = self.pg0.get_capture(len(pkts))
6557 self.verify_capture_in(capture, self.pg0)
6560 class TestDeterministicNAT(MethodHolder):
6561 """ Deterministic NAT Test Cases """
6564 def setUpConstants(cls):
6565 super(TestDeterministicNAT, cls).setUpConstants()
6566 cls.vpp_cmdline.extend(["nat", "{", "deterministic", "}"])
6569 def setUpClass(cls):
6570 super(TestDeterministicNAT, cls).setUpClass()
6571 cls.vapi.cli("set log class nat level debug")
6574 cls.tcp_port_in = 6303
6575 cls.tcp_external_port = 6303
6576 cls.udp_port_in = 6304
6577 cls.udp_external_port = 6304
6578 cls.icmp_id_in = 6305
6579 cls.nat_addr = '10.0.0.3'
6581 cls.create_pg_interfaces(range(3))
6582 cls.interfaces = list(cls.pg_interfaces)
6584 for i in cls.interfaces:
6589 cls.pg0.generate_remote_hosts(2)
6590 cls.pg0.configure_ipv4_neighbors()
6593 super(TestDeterministicNAT, cls).tearDownClass()
6597 def tearDownClass(cls):
6598 super(TestDeterministicNAT, cls).tearDownClass()
6600 def create_stream_in(self, in_if, out_if, ttl=64):
6602 Create packet stream for inside network
6604 :param in_if: Inside interface
6605 :param out_if: Outside interface
6606 :param ttl: TTL of generated packets
6610 p = (Ether(dst=in_if.local_mac, src=in_if.remote_mac) /
6611 IP(src=in_if.remote_ip4, dst=out_if.remote_ip4, ttl=ttl) /
6612 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port))
6616 p = (Ether(dst=in_if.local_mac, src=in_if.remote_mac) /
6617 IP(src=in_if.remote_ip4, dst=out_if.remote_ip4, ttl=ttl) /
6618 UDP(sport=self.udp_port_in, dport=self.udp_external_port))
6622 p = (Ether(dst=in_if.local_mac, src=in_if.remote_mac) /
6623 IP(src=in_if.remote_ip4, dst=out_if.remote_ip4, ttl=ttl) /
6624 ICMP(id=self.icmp_id_in, type='echo-request'))
6629 def create_stream_out(self, out_if, dst_ip=None, ttl=64):
6631 Create packet stream for outside network
6633 :param out_if: Outside interface
6634 :param dst_ip: Destination IP address (Default use global NAT address)
6635 :param ttl: TTL of generated packets
6638 dst_ip = self.nat_addr
6641 p = (Ether(dst=out_if.local_mac, src=out_if.remote_mac) /
6642 IP(src=out_if.remote_ip4, dst=dst_ip, ttl=ttl) /
6643 TCP(dport=self.tcp_port_out, sport=self.tcp_external_port))
6647 p = (Ether(dst=out_if.local_mac, src=out_if.remote_mac) /
6648 IP(src=out_if.remote_ip4, dst=dst_ip, ttl=ttl) /
6649 UDP(dport=self.udp_port_out, sport=self.udp_external_port))
6653 p = (Ether(dst=out_if.local_mac, src=out_if.remote_mac) /
6654 IP(src=out_if.remote_ip4, dst=dst_ip, ttl=ttl) /
6655 ICMP(id=self.icmp_external_id, type='echo-reply'))
6660 def verify_capture_out(self, capture, nat_ip=None):
6662 Verify captured packets on outside network
6664 :param capture: Captured packets
6665 :param nat_ip: Translated IP address (Default use global NAT address)
6666 :param same_port: Source port number is not translated (Default False)
6669 nat_ip = self.nat_addr
6670 for packet in capture:
6672 self.assertEqual(packet[IP].src, nat_ip)
6673 if packet.haslayer(TCP):
6674 self.tcp_port_out = packet[TCP].sport
6675 elif packet.haslayer(UDP):
6676 self.udp_port_out = packet[UDP].sport
6678 self.icmp_external_id = packet[ICMP].id
6680 self.logger.error(ppp("Unexpected or invalid packet "
6681 "(outside network):", packet))
6684 def test_deterministic_mode(self):
6685 """ NAT plugin run deterministic mode """
6686 in_addr = '172.16.255.0'
6687 out_addr = '172.17.255.50'
6688 in_addr_t = '172.16.255.20'
6689 in_addr_n = socket.inet_aton(in_addr)
6690 out_addr_n = socket.inet_aton(out_addr)
6691 in_addr_t_n = socket.inet_aton(in_addr_t)
6695 nat_config = self.vapi.nat_show_config()
6696 self.assertEqual(1, nat_config.deterministic)
6698 self.vapi.nat_det_add_del_map(in_addr_n, in_plen, out_addr_n, out_plen)
6700 rep1 = self.vapi.nat_det_forward(in_addr_t_n)
6701 self.assertEqual(rep1.out_addr[:4], out_addr_n)
6702 rep2 = self.vapi.nat_det_reverse(out_addr_n, rep1.out_port_hi)
6703 self.assertEqual(rep2.in_addr[:4], in_addr_t_n)
6705 deterministic_mappings = self.vapi.nat_det_map_dump()
6706 self.assertEqual(len(deterministic_mappings), 1)
6707 dsm = deterministic_mappings[0]
6708 self.assertEqual(in_addr_n, dsm.in_addr[:4])
6709 self.assertEqual(in_plen, dsm.in_plen)
6710 self.assertEqual(out_addr_n, dsm.out_addr[:4])
6711 self.assertEqual(out_plen, dsm.out_plen)
6713 self.clear_nat_det()
6714 deterministic_mappings = self.vapi.nat_det_map_dump()
6715 self.assertEqual(len(deterministic_mappings), 0)
6717 def test_set_timeouts(self):
6718 """ Set deterministic NAT timeouts """
6719 timeouts_before = self.vapi.nat_get_timeouts()
6721 self.vapi.nat_set_timeouts(timeouts_before.udp + 10,
6722 timeouts_before.tcp_established + 10,
6723 timeouts_before.tcp_transitory + 10,
6724 timeouts_before.icmp + 10)
6726 timeouts_after = self.vapi.nat_get_timeouts()
6728 self.assertNotEqual(timeouts_before.udp, timeouts_after.udp)
6729 self.assertNotEqual(timeouts_before.icmp, timeouts_after.icmp)
6730 self.assertNotEqual(timeouts_before.tcp_established,
6731 timeouts_after.tcp_established)
6732 self.assertNotEqual(timeouts_before.tcp_transitory,
6733 timeouts_after.tcp_transitory)
6735 def test_det_in(self):
6736 """ Deterministic NAT translation test (TCP, UDP, ICMP) """
6738 nat_ip = "10.0.0.10"
6740 self.vapi.nat_det_add_del_map(self.pg0.remote_ip4n,
6742 socket.inet_aton(nat_ip),
6744 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
6745 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
6749 pkts = self.create_stream_in(self.pg0, self.pg1)
6750 self.pg0.add_stream(pkts)
6751 self.pg_enable_capture(self.pg_interfaces)
6753 capture = self.pg1.get_capture(len(pkts))
6754 self.verify_capture_out(capture, nat_ip)
6757 pkts = self.create_stream_out(self.pg1, nat_ip)
6758 self.pg1.add_stream(pkts)
6759 self.pg_enable_capture(self.pg_interfaces)
6761 capture = self.pg0.get_capture(len(pkts))
6762 self.verify_capture_in(capture, self.pg0)
6765 sessions = self.vapi.nat_det_session_dump(self.pg0.remote_ip4n)
6766 self.assertEqual(len(sessions), 3)
6770 self.assertEqual(s.ext_addr[:4], self.pg1.remote_ip4n)
6771 self.assertEqual(s.in_port, self.tcp_port_in)
6772 self.assertEqual(s.out_port, self.tcp_port_out)
6773 self.assertEqual(s.ext_port, self.tcp_external_port)
6777 self.assertEqual(s.ext_addr[:4], self.pg1.remote_ip4n)
6778 self.assertEqual(s.in_port, self.udp_port_in)
6779 self.assertEqual(s.out_port, self.udp_port_out)
6780 self.assertEqual(s.ext_port, self.udp_external_port)
6784 self.assertEqual(s.ext_addr[:4], self.pg1.remote_ip4n)
6785 self.assertEqual(s.in_port, self.icmp_id_in)
6786 self.assertEqual(s.out_port, self.icmp_external_id)
6788 def test_multiple_users(self):
6789 """ Deterministic NAT multiple users """
6791 nat_ip = "10.0.0.10"
6793 external_port = 6303
6795 host0 = self.pg0.remote_hosts[0]
6796 host1 = self.pg0.remote_hosts[1]
6798 self.vapi.nat_det_add_del_map(host0.ip4n,
6800 socket.inet_aton(nat_ip),
6802 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
6803 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
6807 p = (Ether(src=host0.mac, dst=self.pg0.local_mac) /
6808 IP(src=host0.ip4, dst=self.pg1.remote_ip4) /
6809 TCP(sport=port_in, dport=external_port))
6810 self.pg0.add_stream(p)
6811 self.pg_enable_capture(self.pg_interfaces)
6813 capture = self.pg1.get_capture(1)
6818 self.assertEqual(ip.src, nat_ip)
6819 self.assertEqual(ip.dst, self.pg1.remote_ip4)
6820 self.assertEqual(tcp.dport, external_port)
6821 port_out0 = tcp.sport
6823 self.logger.error(ppp("Unexpected or invalid packet:", p))
6827 p = (Ether(src=host1.mac, dst=self.pg0.local_mac) /
6828 IP(src=host1.ip4, dst=self.pg1.remote_ip4) /
6829 TCP(sport=port_in, dport=external_port))
6830 self.pg0.add_stream(p)
6831 self.pg_enable_capture(self.pg_interfaces)
6833 capture = self.pg1.get_capture(1)
6838 self.assertEqual(ip.src, nat_ip)
6839 self.assertEqual(ip.dst, self.pg1.remote_ip4)
6840 self.assertEqual(tcp.dport, external_port)
6841 port_out1 = tcp.sport
6843 self.logger.error(ppp("Unexpected or invalid packet:", p))
6846 dms = self.vapi.nat_det_map_dump()
6847 self.assertEqual(1, len(dms))
6848 self.assertEqual(2, dms[0].ses_num)
6851 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
6852 IP(src=self.pg1.remote_ip4, dst=nat_ip) /
6853 TCP(sport=external_port, dport=port_out0))
6854 self.pg1.add_stream(p)
6855 self.pg_enable_capture(self.pg_interfaces)
6857 capture = self.pg0.get_capture(1)
6862 self.assertEqual(ip.src, self.pg1.remote_ip4)
6863 self.assertEqual(ip.dst, host0.ip4)
6864 self.assertEqual(tcp.dport, port_in)
6865 self.assertEqual(tcp.sport, external_port)
6867 self.logger.error(ppp("Unexpected or invalid packet:", p))
6871 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
6872 IP(src=self.pg1.remote_ip4, dst=nat_ip) /
6873 TCP(sport=external_port, dport=port_out1))
6874 self.pg1.add_stream(p)
6875 self.pg_enable_capture(self.pg_interfaces)
6877 capture = self.pg0.get_capture(1)
6882 self.assertEqual(ip.src, self.pg1.remote_ip4)
6883 self.assertEqual(ip.dst, host1.ip4)
6884 self.assertEqual(tcp.dport, port_in)
6885 self.assertEqual(tcp.sport, external_port)
6887 self.logger.error(ppp("Unexpected or invalid packet", p))
6890 # session close api test
6891 self.vapi.nat_det_close_session_out(socket.inet_aton(nat_ip),
6893 self.pg1.remote_ip4n,
6895 dms = self.vapi.nat_det_map_dump()
6896 self.assertEqual(dms[0].ses_num, 1)
6898 self.vapi.nat_det_close_session_in(host0.ip4n,
6900 self.pg1.remote_ip4n,
6902 dms = self.vapi.nat_det_map_dump()
6903 self.assertEqual(dms[0].ses_num, 0)
6905 def test_tcp_session_close_detection_in(self):
6906 """ Deterministic NAT TCP session close from inside network """
6907 self.vapi.nat_det_add_del_map(self.pg0.remote_ip4n,
6909 socket.inet_aton(self.nat_addr),
6911 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
6912 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
6915 self.initiate_tcp_session(self.pg0, self.pg1)
6917 # close the session from inside
6919 # FIN packet in -> out
6920 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6921 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6922 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
6924 self.pg0.add_stream(p)
6925 self.pg_enable_capture(self.pg_interfaces)
6927 self.pg1.get_capture(1)
6931 # ACK packet out -> in
6932 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
6933 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
6934 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
6938 # FIN packet out -> in
6939 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
6940 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
6941 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
6945 self.pg1.add_stream(pkts)
6946 self.pg_enable_capture(self.pg_interfaces)
6948 self.pg0.get_capture(2)
6950 # ACK packet in -> out
6951 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6952 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6953 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
6955 self.pg0.add_stream(p)
6956 self.pg_enable_capture(self.pg_interfaces)
6958 self.pg1.get_capture(1)
6960 # Check if deterministic NAT44 closed the session
6961 dms = self.vapi.nat_det_map_dump()
6962 self.assertEqual(0, dms[0].ses_num)
6964 self.logger.error("TCP session termination failed")
6967 def test_tcp_session_close_detection_out(self):
6968 """ Deterministic NAT TCP session close from outside network """
6969 self.vapi.nat_det_add_del_map(self.pg0.remote_ip4n,
6971 socket.inet_aton(self.nat_addr),
6973 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
6974 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
6977 self.initiate_tcp_session(self.pg0, self.pg1)
6979 # close the session from outside
6981 # FIN packet out -> in
6982 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
6983 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
6984 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
6986 self.pg1.add_stream(p)
6987 self.pg_enable_capture(self.pg_interfaces)
6989 self.pg0.get_capture(1)
6993 # ACK packet in -> out
6994 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6995 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6996 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
7000 # ACK packet in -> out
7001 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
7002 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
7003 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
7007 self.pg0.add_stream(pkts)
7008 self.pg_enable_capture(self.pg_interfaces)
7010 self.pg1.get_capture(2)
7012 # ACK packet out -> in
7013 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
7014 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
7015 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
7017 self.pg1.add_stream(p)
7018 self.pg_enable_capture(self.pg_interfaces)
7020 self.pg0.get_capture(1)
7022 # Check if deterministic NAT44 closed the session
7023 dms = self.vapi.nat_det_map_dump()
7024 self.assertEqual(0, dms[0].ses_num)
7026 self.logger.error("TCP session termination failed")
7029 @unittest.skipUnless(running_extended_tests, "part of extended tests")
7030 def test_session_timeout(self):
7031 """ Deterministic NAT session timeouts """
7032 self.vapi.nat_det_add_del_map(self.pg0.remote_ip4n,
7034 socket.inet_aton(self.nat_addr),
7036 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
7037 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
7040 self.initiate_tcp_session(self.pg0, self.pg1)
7041 self.vapi.nat_set_timeouts(5, 5, 5, 5)
7042 pkts = self.create_stream_in(self.pg0, self.pg1)
7043 self.pg0.add_stream(pkts)
7044 self.pg_enable_capture(self.pg_interfaces)
7046 capture = self.pg1.get_capture(len(pkts))
7049 dms = self.vapi.nat_det_map_dump()
7050 self.assertEqual(0, dms[0].ses_num)
7052 @unittest.skipUnless(running_extended_tests, "part of extended tests")
7053 def test_session_limit_per_user(self):
7054 """ Deterministic NAT maximum sessions per user limit """
7055 self.vapi.nat_det_add_del_map(self.pg0.remote_ip4n,
7057 socket.inet_aton(self.nat_addr),
7059 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
7060 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
7062 self.vapi.set_ipfix_exporter(collector_address=self.pg2.remote_ip4n,
7063 src_address=self.pg2.local_ip4n,
7065 template_interval=10)
7066 self.vapi.nat_ipfix_enable_disable()
7069 for port in range(1025, 2025):
7070 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
7071 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
7072 UDP(sport=port, dport=port))
7075 self.pg0.add_stream(pkts)
7076 self.pg_enable_capture(self.pg_interfaces)
7078 capture = self.pg1.get_capture(len(pkts))
7080 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
7081 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
7082 UDP(sport=3001, dport=3002))
7083 self.pg0.add_stream(p)
7084 self.pg_enable_capture(self.pg_interfaces)
7086 capture = self.pg1.assert_nothing_captured()
7088 # verify ICMP error packet
7089 capture = self.pg0.get_capture(1)
7091 self.assertTrue(p.haslayer(ICMP))
7093 self.assertEqual(icmp.type, 3)
7094 self.assertEqual(icmp.code, 1)
7095 self.assertTrue(icmp.haslayer(IPerror))
7096 inner_ip = icmp[IPerror]
7097 self.assertEqual(inner_ip[UDPerror].sport, 3001)
7098 self.assertEqual(inner_ip[UDPerror].dport, 3002)
7100 dms = self.vapi.nat_det_map_dump()
7102 self.assertEqual(1000, dms[0].ses_num)
7104 # verify IPFIX logging
7105 self.vapi.cli("ipfix flush") # FIXME this should be an API call
7107 capture = self.pg2.get_capture(2)
7108 ipfix = IPFIXDecoder()
7109 # first load template
7111 self.assertTrue(p.haslayer(IPFIX))
7112 if p.haslayer(Template):
7113 ipfix.add_template(p.getlayer(Template))
7114 # verify events in data set
7116 if p.haslayer(Data):
7117 data = ipfix.decode_data_set(p.getlayer(Set))
7118 self.verify_ipfix_max_entries_per_user(data,
7120 self.pg0.remote_ip4n)
7122 def clear_nat_det(self):
7124 Clear deterministic NAT configuration.
7126 self.vapi.nat_ipfix_enable_disable(enable=0)
7127 self.vapi.nat_set_timeouts()
7128 deterministic_mappings = self.vapi.nat_det_map_dump()
7129 for dsm in deterministic_mappings:
7130 self.vapi.nat_det_add_del_map(dsm.in_addr,
7136 interfaces = self.vapi.nat44_interface_dump()
7137 for intf in interfaces:
7138 self.vapi.nat44_interface_add_del_feature(intf.sw_if_index,
7143 super(TestDeterministicNAT, self).tearDown()
7144 if not self.vpp_dead:
7145 self.logger.info(self.vapi.cli("show nat44 interfaces"))
7146 self.logger.info(self.vapi.cli("show nat timeouts"))
7148 self.vapi.cli("show nat44 deterministic mappings"))
7150 self.vapi.cli("show nat44 deterministic sessions"))
7151 self.clear_nat_det()
7154 class TestNAT64(MethodHolder):
7155 """ NAT64 Test Cases """
7158 def setUpConstants(cls):
7159 super(TestNAT64, cls).setUpConstants()
7160 cls.vpp_cmdline.extend(["nat", "{", "nat64 bib hash buckets 128",
7161 "nat64 st hash buckets 256", "}"])
7164 def setUpClass(cls):
7165 super(TestNAT64, cls).setUpClass()
7168 cls.tcp_port_in = 6303
7169 cls.tcp_port_out = 6303
7170 cls.udp_port_in = 6304
7171 cls.udp_port_out = 6304
7172 cls.icmp_id_in = 6305
7173 cls.icmp_id_out = 6305
7174 cls.tcp_external_port = 80
7175 cls.nat_addr = '10.0.0.3'
7176 cls.nat_addr_n = socket.inet_pton(socket.AF_INET, cls.nat_addr)
7178 cls.vrf1_nat_addr = '10.0.10.3'
7179 cls.vrf1_nat_addr_n = socket.inet_pton(socket.AF_INET,
7181 cls.ipfix_src_port = 4739
7182 cls.ipfix_domain_id = 1
7184 cls.create_pg_interfaces(range(6))
7185 cls.ip6_interfaces = list(cls.pg_interfaces[0:1])
7186 cls.ip6_interfaces.append(cls.pg_interfaces[2])
7187 cls.ip4_interfaces = list(cls.pg_interfaces[1:2])
7189 cls.vapi.ip_table_add_del(is_ipv6=1, is_add=1,
7190 table_id=cls.vrf1_id)
7192 cls.pg_interfaces[2].set_table_ip6(cls.vrf1_id)
7194 cls.pg0.generate_remote_hosts(2)
7196 for i in cls.ip6_interfaces:
7199 i.configure_ipv6_neighbors()
7201 for i in cls.ip4_interfaces:
7207 cls.pg3.config_ip4()
7208 cls.pg3.resolve_arp()
7209 cls.pg3.config_ip6()
7210 cls.pg3.configure_ipv6_neighbors()
7213 cls.pg5.config_ip6()
7216 super(TestNAT64, cls).tearDownClass()
7220 def tearDownClass(cls):
7221 super(TestNAT64, cls).tearDownClass()
7223 def test_nat64_inside_interface_handles_neighbor_advertisement(self):
7224 """ NAT64 inside interface handles Neighbor Advertisement """
7226 self.vapi.nat64_add_del_interface(self.pg5.sw_if_index)
7229 ping = (Ether(dst=self.pg5.local_mac, src=self.pg5.remote_mac) /
7230 IPv6(src=self.pg5.remote_ip6, dst=self.pg5.local_ip6) /
7231 ICMPv6EchoRequest())
7233 self.pg5.add_stream(pkts)
7234 self.pg_enable_capture(self.pg_interfaces)
7237 # Wait for Neighbor Solicitation
7238 capture = self.pg5.get_capture(len(pkts))
7241 self.assertEqual(packet[IPv6].src, self.pg5.local_ip6)
7242 self.assertEqual(packet.haslayer(ICMPv6ND_NS), 1)
7243 tgt = packet[ICMPv6ND_NS].tgt
7245 self.logger.error(ppp("Unexpected or invalid packet:", packet))
7248 # Send Neighbor Advertisement
7249 p = (Ether(dst=self.pg5.local_mac, src=self.pg5.remote_mac) /
7250 IPv6(src=self.pg5.remote_ip6, dst=self.pg5.local_ip6) /
7251 ICMPv6ND_NA(tgt=tgt) /
7252 ICMPv6NDOptDstLLAddr(lladdr=self.pg5.remote_mac))
7254 self.pg5.add_stream(pkts)
7255 self.pg_enable_capture(self.pg_interfaces)
7258 # Try to send ping again
7260 self.pg5.add_stream(pkts)
7261 self.pg_enable_capture(self.pg_interfaces)
7264 # Wait for ping reply
7265 capture = self.pg5.get_capture(len(pkts))
7268 self.assertEqual(packet[IPv6].src, self.pg5.local_ip6)
7269 self.assertEqual(packet[IPv6].dst, self.pg5.remote_ip6)
7270 self.assertEqual(packet.haslayer(ICMPv6EchoReply), 1)
7272 self.logger.error(ppp("Unexpected or invalid packet:", packet))
7275 def test_pool(self):
7276 """ Add/delete address to NAT64 pool """
7277 nat_addr = socket.inet_pton(socket.AF_INET, '1.2.3.4')
7279 self.vapi.nat64_add_del_pool_addr_range(nat_addr, nat_addr)
7281 addresses = self.vapi.nat64_pool_addr_dump()
7282 self.assertEqual(len(addresses), 1)
7283 self.assertEqual(addresses[0].address, nat_addr)
7285 self.vapi.nat64_add_del_pool_addr_range(nat_addr, nat_addr, is_add=0)
7287 addresses = self.vapi.nat64_pool_addr_dump()
7288 self.assertEqual(len(addresses), 0)
7290 def test_interface(self):
7291 """ Enable/disable NAT64 feature on the interface """
7292 self.vapi.nat64_add_del_interface(self.pg0.sw_if_index)
7293 self.vapi.nat64_add_del_interface(self.pg1.sw_if_index, is_inside=0)
7295 interfaces = self.vapi.nat64_interface_dump()
7296 self.assertEqual(len(interfaces), 2)
7299 for intf in interfaces:
7300 if intf.sw_if_index == self.pg0.sw_if_index:
7301 self.assertEqual(intf.is_inside, 1)
7303 elif intf.sw_if_index == self.pg1.sw_if_index:
7304 self.assertEqual(intf.is_inside, 0)
7306 self.assertTrue(pg0_found)
7307 self.assertTrue(pg1_found)
7309 features = self.vapi.cli("show interface features pg0")
7310 self.assertIn('nat64-in2out', features)
7311 features = self.vapi.cli("show interface features pg1")
7312 self.assertIn('nat64-out2in', features)
7314 self.vapi.nat64_add_del_interface(self.pg0.sw_if_index, is_add=0)
7315 self.vapi.nat64_add_del_interface(self.pg1.sw_if_index, is_add=0)
7317 interfaces = self.vapi.nat64_interface_dump()
7318 self.assertEqual(len(interfaces), 0)
7320 def test_static_bib(self):
7321 """ Add/delete static BIB entry """
7322 in_addr = socket.inet_pton(socket.AF_INET6,
7323 '2001:db8:85a3::8a2e:370:7334')
7324 out_addr = socket.inet_pton(socket.AF_INET, '10.1.1.3')
7327 proto = IP_PROTOS.tcp
7329 self.vapi.nat64_add_del_static_bib(in_addr,
7334 bib = self.vapi.nat64_bib_dump(IP_PROTOS.tcp)
7339 self.assertEqual(bibe.i_addr, in_addr)
7340 self.assertEqual(bibe.o_addr, out_addr)
7341 self.assertEqual(bibe.i_port, in_port)
7342 self.assertEqual(bibe.o_port, out_port)
7343 self.assertEqual(static_bib_num, 1)
7344 bibs = self.statistics.get_counter('/nat64/total-bibs')
7345 self.assertEqual(bibs[0][0], 1)
7347 self.vapi.nat64_add_del_static_bib(in_addr,
7353 bib = self.vapi.nat64_bib_dump(IP_PROTOS.tcp)
7358 self.assertEqual(static_bib_num, 0)
7359 bibs = self.statistics.get_counter('/nat64/total-bibs')
7360 self.assertEqual(bibs[0][0], 0)
7362 def test_set_timeouts(self):
7363 """ Set NAT64 timeouts """
7364 # verify default values
7365 timeouts = self.vapi.nat_get_timeouts()
7366 self.assertEqual(timeouts.udp, 300)
7367 self.assertEqual(timeouts.icmp, 60)
7368 self.assertEqual(timeouts.tcp_transitory, 240)
7369 self.assertEqual(timeouts.tcp_established, 7440)
7371 # set and verify custom values
7372 self.vapi.nat_set_timeouts(udp=200, icmp=30, tcp_transitory=250,
7373 tcp_established=7450)
7374 timeouts = self.vapi.nat_get_timeouts()
7375 self.assertEqual(timeouts.udp, 200)
7376 self.assertEqual(timeouts.icmp, 30)
7377 self.assertEqual(timeouts.tcp_transitory, 250)
7378 self.assertEqual(timeouts.tcp_established, 7450)
7380 def test_dynamic(self):
7381 """ NAT64 dynamic translation test """
7382 self.tcp_port_in = 6303
7383 self.udp_port_in = 6304
7384 self.icmp_id_in = 6305
7386 ses_num_start = self.nat64_get_ses_num()
7388 self.vapi.nat64_add_del_pool_addr_range(self.nat_addr_n,
7390 self.vapi.nat64_add_del_interface(self.pg0.sw_if_index)
7391 self.vapi.nat64_add_del_interface(self.pg1.sw_if_index, is_inside=0)
7394 tcpn = self.statistics.get_counter('/err/nat64-in2out/TCP packets')
7395 udpn = self.statistics.get_counter('/err/nat64-in2out/UDP packets')
7396 icmpn = self.statistics.get_counter('/err/nat64-in2out/ICMP packets')
7397 totaln = self.statistics.get_counter(
7398 '/err/nat64-in2out/good in2out packets processed')
7400 pkts = self.create_stream_in_ip6(self.pg0, self.pg1)
7401 self.pg0.add_stream(pkts)
7402 self.pg_enable_capture(self.pg_interfaces)
7404 capture = self.pg1.get_capture(len(pkts))
7405 self.verify_capture_out(capture, nat_ip=self.nat_addr,
7406 dst_ip=self.pg1.remote_ip4)
7408 err = self.statistics.get_counter('/err/nat64-in2out/TCP packets')
7409 self.assertEqual(err - tcpn, 1)
7410 err = self.statistics.get_counter('/err/nat64-in2out/UDP packets')
7411 self.assertEqual(err - udpn, 1)
7412 err = self.statistics.get_counter('/err/nat64-in2out/ICMP packets')
7413 self.assertEqual(err - icmpn, 1)
7414 err = self.statistics.get_counter(
7415 '/err/nat64-in2out/good in2out packets processed')
7416 self.assertEqual(err - totaln, 3)
7419 tcpn = self.statistics.get_counter('/err/nat64-out2in/TCP packets')
7420 udpn = self.statistics.get_counter('/err/nat64-out2in/UDP packets')
7421 icmpn = self.statistics.get_counter('/err/nat64-out2in/ICMP packets')
7422 totaln = self.statistics.get_counter(
7423 '/err/nat64-out2in/good out2in packets processed')
7425 pkts = self.create_stream_out(self.pg1, dst_ip=self.nat_addr)
7426 self.pg1.add_stream(pkts)
7427 self.pg_enable_capture(self.pg_interfaces)
7429 capture = self.pg0.get_capture(len(pkts))
7430 ip = IPv6(src=''.join(['64:ff9b::', self.pg1.remote_ip4]))
7431 self.verify_capture_in_ip6(capture, ip[IPv6].src, self.pg0.remote_ip6)
7433 err = self.statistics.get_counter('/err/nat64-out2in/TCP packets')
7434 self.assertEqual(err - tcpn, 1)
7435 err = self.statistics.get_counter('/err/nat64-out2in/UDP packets')
7436 self.assertEqual(err - udpn, 1)
7437 err = self.statistics.get_counter('/err/nat64-out2in/ICMP packets')
7438 self.assertEqual(err - icmpn, 1)
7439 err = self.statistics.get_counter(
7440 '/err/nat64-out2in/good out2in packets processed')
7441 self.assertEqual(err - totaln, 3)
7443 bibs = self.statistics.get_counter('/nat64/total-bibs')
7444 self.assertEqual(bibs[0][0], 3)
7445 sessions = self.statistics.get_counter('/nat64/total-sessions')
7446 self.assertEqual(sessions[0][0], 3)
7449 pkts = self.create_stream_in_ip6(self.pg0, self.pg1)
7450 self.pg0.add_stream(pkts)
7451 self.pg_enable_capture(self.pg_interfaces)
7453 capture = self.pg1.get_capture(len(pkts))
7454 self.verify_capture_out(capture, nat_ip=self.nat_addr,
7455 dst_ip=self.pg1.remote_ip4)
7458 pkts = self.create_stream_out(self.pg1, dst_ip=self.nat_addr)
7459 self.pg1.add_stream(pkts)
7460 self.pg_enable_capture(self.pg_interfaces)
7462 capture = self.pg0.get_capture(len(pkts))
7463 self.verify_capture_in_ip6(capture, ip[IPv6].src, self.pg0.remote_ip6)
7465 ses_num_end = self.nat64_get_ses_num()
7467 self.assertEqual(ses_num_end - ses_num_start, 3)
7469 # tenant with specific VRF
7470 self.vapi.nat64_add_del_pool_addr_range(self.vrf1_nat_addr_n,
7471 self.vrf1_nat_addr_n,
7472 vrf_id=self.vrf1_id)
7473 self.vapi.nat64_add_del_interface(self.pg2.sw_if_index)
7475 pkts = self.create_stream_in_ip6(self.pg2, self.pg1)
7476 self.pg2.add_stream(pkts)
7477 self.pg_enable_capture(self.pg_interfaces)
7479 capture = self.pg1.get_capture(len(pkts))
7480 self.verify_capture_out(capture, nat_ip=self.vrf1_nat_addr,
7481 dst_ip=self.pg1.remote_ip4)
7483 pkts = self.create_stream_out(self.pg1, dst_ip=self.vrf1_nat_addr)
7484 self.pg1.add_stream(pkts)
7485 self.pg_enable_capture(self.pg_interfaces)
7487 capture = self.pg2.get_capture(len(pkts))
7488 self.verify_capture_in_ip6(capture, ip[IPv6].src, self.pg2.remote_ip6)
7490 def test_static(self):
7491 """ NAT64 static translation test """
7492 self.tcp_port_in = 60303
7493 self.udp_port_in = 60304
7494 self.icmp_id_in = 60305
7495 self.tcp_port_out = 60303
7496 self.udp_port_out = 60304
7497 self.icmp_id_out = 60305
7499 ses_num_start = self.nat64_get_ses_num()
7501 self.vapi.nat64_add_del_pool_addr_range(self.nat_addr_n,
7503 self.vapi.nat64_add_del_interface(self.pg0.sw_if_index)
7504 self.vapi.nat64_add_del_interface(self.pg1.sw_if_index, is_inside=0)
7506 self.vapi.nat64_add_del_static_bib(self.pg0.remote_ip6n,
7511 self.vapi.nat64_add_del_static_bib(self.pg0.remote_ip6n,
7516 self.vapi.nat64_add_del_static_bib(self.pg0.remote_ip6n,
7523 pkts = self.create_stream_in_ip6(self.pg0, self.pg1)
7524 self.pg0.add_stream(pkts)
7525 self.pg_enable_capture(self.pg_interfaces)
7527 capture = self.pg1.get_capture(len(pkts))
7528 self.verify_capture_out(capture, nat_ip=self.nat_addr,
7529 dst_ip=self.pg1.remote_ip4, same_port=True)
7532 pkts = self.create_stream_out(self.pg1, dst_ip=self.nat_addr)
7533 self.pg1.add_stream(pkts)
7534 self.pg_enable_capture(self.pg_interfaces)
7536 capture = self.pg0.get_capture(len(pkts))
7537 ip = IPv6(src=''.join(['64:ff9b::', self.pg1.remote_ip4]))
7538 self.verify_capture_in_ip6(capture, ip[IPv6].src, self.pg0.remote_ip6)
7540 ses_num_end = self.nat64_get_ses_num()
7542 self.assertEqual(ses_num_end - ses_num_start, 3)
7544 @unittest.skipUnless(running_extended_tests, "part of extended tests")
7545 def test_session_timeout(self):
7546 """ NAT64 session timeout """
7547 self.icmp_id_in = 1234
7548 self.vapi.nat64_add_del_pool_addr_range(self.nat_addr_n,
7550 self.vapi.nat64_add_del_interface(self.pg0.sw_if_index)
7551 self.vapi.nat64_add_del_interface(self.pg1.sw_if_index, is_inside=0)
7552 self.vapi.nat_set_timeouts(icmp=5, tcp_transitory=5, tcp_established=5)
7554 pkts = self.create_stream_in_ip6(self.pg0, self.pg1)
7555 self.pg0.add_stream(pkts)
7556 self.pg_enable_capture(self.pg_interfaces)
7558 capture = self.pg1.get_capture(len(pkts))
7560 ses_num_before_timeout = self.nat64_get_ses_num()
7564 # ICMP and TCP session after timeout
7565 ses_num_after_timeout = self.nat64_get_ses_num()
7566 self.assertEqual(ses_num_before_timeout - ses_num_after_timeout, 2)
7568 def test_icmp_error(self):
7569 """ NAT64 ICMP Error message translation """
7570 self.tcp_port_in = 6303
7571 self.udp_port_in = 6304
7572 self.icmp_id_in = 6305
7574 self.vapi.nat64_add_del_pool_addr_range(self.nat_addr_n,
7576 self.vapi.nat64_add_del_interface(self.pg0.sw_if_index)
7577 self.vapi.nat64_add_del_interface(self.pg1.sw_if_index, is_inside=0)
7579 # send some packets to create sessions
7580 pkts = self.create_stream_in_ip6(self.pg0, self.pg1)
7581 self.pg0.add_stream(pkts)
7582 self.pg_enable_capture(self.pg_interfaces)
7584 capture_ip4 = self.pg1.get_capture(len(pkts))
7585 self.verify_capture_out(capture_ip4,
7586 nat_ip=self.nat_addr,
7587 dst_ip=self.pg1.remote_ip4)
7589 pkts = self.create_stream_out(self.pg1, dst_ip=self.nat_addr)
7590 self.pg1.add_stream(pkts)
7591 self.pg_enable_capture(self.pg_interfaces)
7593 capture_ip6 = self.pg0.get_capture(len(pkts))
7594 ip = IPv6(src=''.join(['64:ff9b::', self.pg1.remote_ip4]))
7595 self.verify_capture_in_ip6(capture_ip6, ip[IPv6].src,
7596 self.pg0.remote_ip6)
7599 pkts = [Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
7600 IPv6(src=self.pg0.remote_ip6, dst=ip[IPv6].src) /
7601 ICMPv6DestUnreach(code=1) /
7602 packet[IPv6] for packet in capture_ip6]
7603 self.pg0.add_stream(pkts)
7604 self.pg_enable_capture(self.pg_interfaces)
7606 capture = self.pg1.get_capture(len(pkts))
7607 for packet in capture:
7609 self.assertEqual(packet[IP].src, self.nat_addr)
7610 self.assertEqual(packet[IP].dst, self.pg1.remote_ip4)
7611 self.assertEqual(packet[ICMP].type, 3)
7612 self.assertEqual(packet[ICMP].code, 13)
7613 inner = packet[IPerror]
7614 self.assertEqual(inner.src, self.pg1.remote_ip4)
7615 self.assertEqual(inner.dst, self.nat_addr)
7616 self.assert_packet_checksums_valid(packet)
7617 if inner.haslayer(TCPerror):
7618 self.assertEqual(inner[TCPerror].dport, self.tcp_port_out)
7619 elif inner.haslayer(UDPerror):
7620 self.assertEqual(inner[UDPerror].dport, self.udp_port_out)
7622 self.assertEqual(inner[ICMPerror].id, self.icmp_id_out)
7624 self.logger.error(ppp("Unexpected or invalid packet:", packet))
7628 pkts = [Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
7629 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
7630 ICMP(type=3, code=13) /
7631 packet[IP] for packet in capture_ip4]
7632 self.pg1.add_stream(pkts)
7633 self.pg_enable_capture(self.pg_interfaces)
7635 capture = self.pg0.get_capture(len(pkts))
7636 for packet in capture:
7638 self.assertEqual(packet[IPv6].src, ip.src)
7639 self.assertEqual(packet[IPv6].dst, self.pg0.remote_ip6)
7640 icmp = packet[ICMPv6DestUnreach]
7641 self.assertEqual(icmp.code, 1)
7642 inner = icmp[IPerror6]
7643 self.assertEqual(inner.src, self.pg0.remote_ip6)
7644 self.assertEqual(inner.dst, ip.src)
7645 self.assert_icmpv6_checksum_valid(packet)
7646 if inner.haslayer(TCPerror):
7647 self.assertEqual(inner[TCPerror].sport, self.tcp_port_in)
7648 elif inner.haslayer(UDPerror):
7649 self.assertEqual(inner[UDPerror].sport, self.udp_port_in)
7651 self.assertEqual(inner[ICMPv6EchoRequest].id,
7654 self.logger.error(ppp("Unexpected or invalid packet:", packet))
7657 def test_hairpinning(self):
7658 """ NAT64 hairpinning """
7660 client = self.pg0.remote_hosts[0]
7661 server = self.pg0.remote_hosts[1]
7662 server_tcp_in_port = 22
7663 server_tcp_out_port = 4022
7664 server_udp_in_port = 23
7665 server_udp_out_port = 4023
7666 client_tcp_in_port = 1234
7667 client_udp_in_port = 1235
7668 client_tcp_out_port = 0
7669 client_udp_out_port = 0
7670 ip = IPv6(src=''.join(['64:ff9b::', self.nat_addr]))
7671 nat_addr_ip6 = ip.src
7673 self.vapi.nat64_add_del_pool_addr_range(self.nat_addr_n,
7675 self.vapi.nat64_add_del_interface(self.pg0.sw_if_index)
7676 self.vapi.nat64_add_del_interface(self.pg1.sw_if_index, is_inside=0)
7678 self.vapi.nat64_add_del_static_bib(server.ip6n,
7681 server_tcp_out_port,
7683 self.vapi.nat64_add_del_static_bib(server.ip6n,
7686 server_udp_out_port,
7691 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
7692 IPv6(src=client.ip6, dst=nat_addr_ip6) /
7693 TCP(sport=client_tcp_in_port, dport=server_tcp_out_port))
7695 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
7696 IPv6(src=client.ip6, dst=nat_addr_ip6) /
7697 UDP(sport=client_udp_in_port, dport=server_udp_out_port))
7699 self.pg0.add_stream(pkts)
7700 self.pg_enable_capture(self.pg_interfaces)
7702 capture = self.pg0.get_capture(len(pkts))
7703 for packet in capture:
7705 self.assertEqual(packet[IPv6].src, nat_addr_ip6)
7706 self.assertEqual(packet[IPv6].dst, server.ip6)
7707 self.assert_packet_checksums_valid(packet)
7708 if packet.haslayer(TCP):
7709 self.assertNotEqual(packet[TCP].sport, client_tcp_in_port)
7710 self.assertEqual(packet[TCP].dport, server_tcp_in_port)
7711 client_tcp_out_port = packet[TCP].sport
7713 self.assertNotEqual(packet[UDP].sport, client_udp_in_port)
7714 self.assertEqual(packet[UDP].dport, server_udp_in_port)
7715 client_udp_out_port = packet[UDP].sport
7717 self.logger.error(ppp("Unexpected or invalid packet:", packet))
7722 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
7723 IPv6(src=server.ip6, dst=nat_addr_ip6) /
7724 TCP(sport=server_tcp_in_port, dport=client_tcp_out_port))
7726 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
7727 IPv6(src=server.ip6, dst=nat_addr_ip6) /
7728 UDP(sport=server_udp_in_port, dport=client_udp_out_port))
7730 self.pg0.add_stream(pkts)
7731 self.pg_enable_capture(self.pg_interfaces)
7733 capture = self.pg0.get_capture(len(pkts))
7734 for packet in capture:
7736 self.assertEqual(packet[IPv6].src, nat_addr_ip6)
7737 self.assertEqual(packet[IPv6].dst, client.ip6)
7738 self.assert_packet_checksums_valid(packet)
7739 if packet.haslayer(TCP):
7740 self.assertEqual(packet[TCP].sport, server_tcp_out_port)
7741 self.assertEqual(packet[TCP].dport, client_tcp_in_port)
7743 self.assertEqual(packet[UDP].sport, server_udp_out_port)
7744 self.assertEqual(packet[UDP].dport, client_udp_in_port)
7746 self.logger.error(ppp("Unexpected or invalid packet:", packet))
7751 pkts = [Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
7752 IPv6(src=client.ip6, dst=nat_addr_ip6) /
7753 ICMPv6DestUnreach(code=1) /
7754 packet[IPv6] for packet in capture]
7755 self.pg0.add_stream(pkts)
7756 self.pg_enable_capture(self.pg_interfaces)
7758 capture = self.pg0.get_capture(len(pkts))
7759 for packet in capture:
7761 self.assertEqual(packet[IPv6].src, nat_addr_ip6)
7762 self.assertEqual(packet[IPv6].dst, server.ip6)
7763 icmp = packet[ICMPv6DestUnreach]
7764 self.assertEqual(icmp.code, 1)
7765 inner = icmp[IPerror6]
7766 self.assertEqual(inner.src, server.ip6)
7767 self.assertEqual(inner.dst, nat_addr_ip6)
7768 self.assert_packet_checksums_valid(packet)
7769 if inner.haslayer(TCPerror):
7770 self.assertEqual(inner[TCPerror].sport, server_tcp_in_port)
7771 self.assertEqual(inner[TCPerror].dport,
7772 client_tcp_out_port)
7774 self.assertEqual(inner[UDPerror].sport, server_udp_in_port)
7775 self.assertEqual(inner[UDPerror].dport,
7776 client_udp_out_port)
7778 self.logger.error(ppp("Unexpected or invalid packet:", packet))
7781 def test_prefix(self):
7782 """ NAT64 Network-Specific Prefix """
7784 self.vapi.nat64_add_del_pool_addr_range(self.nat_addr_n,
7786 self.vapi.nat64_add_del_interface(self.pg0.sw_if_index)
7787 self.vapi.nat64_add_del_interface(self.pg1.sw_if_index, is_inside=0)
7788 self.vapi.nat64_add_del_pool_addr_range(self.vrf1_nat_addr_n,
7789 self.vrf1_nat_addr_n,
7790 vrf_id=self.vrf1_id)
7791 self.vapi.nat64_add_del_interface(self.pg2.sw_if_index)
7794 global_pref64 = "2001:db8::"
7795 global_pref64_n = socket.inet_pton(socket.AF_INET6, global_pref64)
7796 global_pref64_len = 32
7797 self.vapi.nat64_add_del_prefix(global_pref64_n, global_pref64_len)
7799 prefix = self.vapi.nat64_prefix_dump()
7800 self.assertEqual(len(prefix), 1)
7801 self.assertEqual(prefix[0].prefix, global_pref64_n)
7802 self.assertEqual(prefix[0].prefix_len, global_pref64_len)
7803 self.assertEqual(prefix[0].vrf_id, 0)
7805 # Add tenant specific prefix
7806 vrf1_pref64 = "2001:db8:122:300::"
7807 vrf1_pref64_n = socket.inet_pton(socket.AF_INET6, vrf1_pref64)
7808 vrf1_pref64_len = 56
7809 self.vapi.nat64_add_del_prefix(vrf1_pref64_n,
7811 vrf_id=self.vrf1_id)
7812 prefix = self.vapi.nat64_prefix_dump()
7813 self.assertEqual(len(prefix), 2)
7816 pkts = self.create_stream_in_ip6(self.pg0,
7819 plen=global_pref64_len)
7820 self.pg0.add_stream(pkts)
7821 self.pg_enable_capture(self.pg_interfaces)
7823 capture = self.pg1.get_capture(len(pkts))
7824 self.verify_capture_out(capture, nat_ip=self.nat_addr,
7825 dst_ip=self.pg1.remote_ip4)
7827 pkts = self.create_stream_out(self.pg1, dst_ip=self.nat_addr)
7828 self.pg1.add_stream(pkts)
7829 self.pg_enable_capture(self.pg_interfaces)
7831 capture = self.pg0.get_capture(len(pkts))
7832 dst_ip = self.compose_ip6(self.pg1.remote_ip4,
7835 self.verify_capture_in_ip6(capture, dst_ip, self.pg0.remote_ip6)
7837 # Tenant specific prefix
7838 pkts = self.create_stream_in_ip6(self.pg2,
7841 plen=vrf1_pref64_len)
7842 self.pg2.add_stream(pkts)
7843 self.pg_enable_capture(self.pg_interfaces)
7845 capture = self.pg1.get_capture(len(pkts))
7846 self.verify_capture_out(capture, nat_ip=self.vrf1_nat_addr,
7847 dst_ip=self.pg1.remote_ip4)
7849 pkts = self.create_stream_out(self.pg1, dst_ip=self.vrf1_nat_addr)
7850 self.pg1.add_stream(pkts)
7851 self.pg_enable_capture(self.pg_interfaces)
7853 capture = self.pg2.get_capture(len(pkts))
7854 dst_ip = self.compose_ip6(self.pg1.remote_ip4,
7857 self.verify_capture_in_ip6(capture, dst_ip, self.pg2.remote_ip6)
7859 def test_unknown_proto(self):
7860 """ NAT64 translate packet with unknown protocol """
7862 self.vapi.nat64_add_del_pool_addr_range(self.nat_addr_n,
7864 self.vapi.nat64_add_del_interface(self.pg0.sw_if_index)
7865 self.vapi.nat64_add_del_interface(self.pg1.sw_if_index, is_inside=0)
7866 remote_ip6 = self.compose_ip6(self.pg1.remote_ip4, '64:ff9b::', 96)
7869 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
7870 IPv6(src=self.pg0.remote_ip6, dst=remote_ip6) /
7871 TCP(sport=self.tcp_port_in, dport=20))
7872 self.pg0.add_stream(p)
7873 self.pg_enable_capture(self.pg_interfaces)
7875 p = self.pg1.get_capture(1)
7877 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
7878 IPv6(src=self.pg0.remote_ip6, dst=remote_ip6, nh=47) /
7880 IP(src=self.pg2.local_ip4, dst=self.pg2.remote_ip4) /
7881 TCP(sport=1234, dport=1234))
7882 self.pg0.add_stream(p)
7883 self.pg_enable_capture(self.pg_interfaces)
7885 p = self.pg1.get_capture(1)
7888 self.assertEqual(packet[IP].src, self.nat_addr)
7889 self.assertEqual(packet[IP].dst, self.pg1.remote_ip4)
7890 self.assertEqual(packet.haslayer(GRE), 1)
7891 self.assert_packet_checksums_valid(packet)
7893 self.logger.error(ppp("Unexpected or invalid packet:", packet))
7897 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
7898 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
7900 IP(src=self.pg2.remote_ip4, dst=self.pg2.local_ip4) /
7901 TCP(sport=1234, dport=1234))
7902 self.pg1.add_stream(p)
7903 self.pg_enable_capture(self.pg_interfaces)
7905 p = self.pg0.get_capture(1)
7908 self.assertEqual(packet[IPv6].src, remote_ip6)
7909 self.assertEqual(packet[IPv6].dst, self.pg0.remote_ip6)
7910 self.assertEqual(packet[IPv6].nh, 47)
7912 self.logger.error(ppp("Unexpected or invalid packet:", packet))
7915 def test_hairpinning_unknown_proto(self):
7916 """ NAT64 translate packet with unknown protocol - hairpinning """
7918 client = self.pg0.remote_hosts[0]
7919 server = self.pg0.remote_hosts[1]
7920 server_tcp_in_port = 22
7921 server_tcp_out_port = 4022
7922 client_tcp_in_port = 1234
7923 client_tcp_out_port = 1235
7924 server_nat_ip = "10.0.0.100"
7925 client_nat_ip = "10.0.0.110"
7926 server_nat_ip_n = socket.inet_pton(socket.AF_INET, server_nat_ip)
7927 client_nat_ip_n = socket.inet_pton(socket.AF_INET, client_nat_ip)
7928 server_nat_ip6 = self.compose_ip6(server_nat_ip, '64:ff9b::', 96)
7929 client_nat_ip6 = self.compose_ip6(client_nat_ip, '64:ff9b::', 96)
7931 self.vapi.nat64_add_del_pool_addr_range(server_nat_ip_n,
7933 self.vapi.nat64_add_del_interface(self.pg0.sw_if_index)
7934 self.vapi.nat64_add_del_interface(self.pg1.sw_if_index, is_inside=0)
7936 self.vapi.nat64_add_del_static_bib(server.ip6n,
7939 server_tcp_out_port,
7942 self.vapi.nat64_add_del_static_bib(server.ip6n,
7948 self.vapi.nat64_add_del_static_bib(client.ip6n,
7951 client_tcp_out_port,
7955 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
7956 IPv6(src=client.ip6, dst=server_nat_ip6) /
7957 TCP(sport=client_tcp_in_port, dport=server_tcp_out_port))
7958 self.pg0.add_stream(p)
7959 self.pg_enable_capture(self.pg_interfaces)
7961 p = self.pg0.get_capture(1)
7963 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
7964 IPv6(src=client.ip6, dst=server_nat_ip6, nh=IP_PROTOS.gre) /
7966 IP(src=self.pg2.local_ip4, dst=self.pg2.remote_ip4) /
7967 TCP(sport=1234, dport=1234))
7968 self.pg0.add_stream(p)
7969 self.pg_enable_capture(self.pg_interfaces)
7971 p = self.pg0.get_capture(1)
7974 self.assertEqual(packet[IPv6].src, client_nat_ip6)
7975 self.assertEqual(packet[IPv6].dst, server.ip6)
7976 self.assertEqual(packet[IPv6].nh, IP_PROTOS.gre)
7978 self.logger.error(ppp("Unexpected or invalid packet:", packet))
7982 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
7983 IPv6(src=server.ip6, dst=client_nat_ip6, nh=IP_PROTOS.gre) /
7985 IP(src=self.pg2.remote_ip4, dst=self.pg2.local_ip4) /
7986 TCP(sport=1234, dport=1234))
7987 self.pg0.add_stream(p)
7988 self.pg_enable_capture(self.pg_interfaces)
7990 p = self.pg0.get_capture(1)
7993 self.assertEqual(packet[IPv6].src, server_nat_ip6)
7994 self.assertEqual(packet[IPv6].dst, client.ip6)
7995 self.assertEqual(packet[IPv6].nh, IP_PROTOS.gre)
7997 self.logger.error(ppp("Unexpected or invalid packet:", packet))
8000 def test_one_armed_nat64(self):
8001 """ One armed NAT64 """
8003 remote_host_ip6 = self.compose_ip6(self.pg3.remote_ip4,
8007 self.vapi.nat64_add_del_pool_addr_range(self.nat_addr_n,
8009 self.vapi.nat64_add_del_interface(self.pg3.sw_if_index)
8010 self.vapi.nat64_add_del_interface(self.pg3.sw_if_index, is_inside=0)
8013 p = (Ether(src=self.pg3.remote_mac, dst=self.pg3.local_mac) /
8014 IPv6(src=self.pg3.remote_ip6, dst=remote_host_ip6) /
8015 TCP(sport=12345, dport=80))
8016 self.pg3.add_stream(p)
8017 self.pg_enable_capture(self.pg_interfaces)
8019 capture = self.pg3.get_capture(1)
8024 self.assertEqual(ip.src, self.nat_addr)
8025 self.assertEqual(ip.dst, self.pg3.remote_ip4)
8026 self.assertNotEqual(tcp.sport, 12345)
8027 external_port = tcp.sport
8028 self.assertEqual(tcp.dport, 80)
8029 self.assert_packet_checksums_valid(p)
8031 self.logger.error(ppp("Unexpected or invalid packet:", p))
8035 p = (Ether(src=self.pg3.remote_mac, dst=self.pg3.local_mac) /
8036 IP(src=self.pg3.remote_ip4, dst=self.nat_addr) /
8037 TCP(sport=80, dport=external_port))
8038 self.pg3.add_stream(p)
8039 self.pg_enable_capture(self.pg_interfaces)
8041 capture = self.pg3.get_capture(1)
8046 self.assertEqual(ip.src, remote_host_ip6)
8047 self.assertEqual(ip.dst, self.pg3.remote_ip6)
8048 self.assertEqual(tcp.sport, 80)
8049 self.assertEqual(tcp.dport, 12345)
8050 self.assert_packet_checksums_valid(p)
8052 self.logger.error(ppp("Unexpected or invalid packet:", p))
8055 def test_frag_in_order(self):
8056 """ NAT64 translate fragments arriving in order """
8057 self.tcp_port_in = random.randint(1025, 65535)
8059 self.vapi.nat64_add_del_pool_addr_range(self.nat_addr_n,
8061 self.vapi.nat64_add_del_interface(self.pg0.sw_if_index)
8062 self.vapi.nat64_add_del_interface(self.pg1.sw_if_index, is_inside=0)
8064 reass = self.vapi.nat_reass_dump()
8065 reass_n_start = len(reass)
8069 pkts = self.create_stream_frag_ip6(self.pg0, self.pg1.remote_ip4,
8070 self.tcp_port_in, 20, data)
8071 self.pg0.add_stream(pkts)
8072 self.pg_enable_capture(self.pg_interfaces)
8074 frags = self.pg1.get_capture(len(pkts))
8075 p = self.reass_frags_and_verify(frags,
8077 self.pg1.remote_ip4)
8078 self.assertEqual(p[TCP].dport, 20)
8079 self.assertNotEqual(p[TCP].sport, self.tcp_port_in)
8080 self.tcp_port_out = p[TCP].sport
8081 self.assertEqual(data, p[Raw].load)
8084 data = b"A" * 4 + b"b" * 16 + b"C" * 3
8085 pkts = self.create_stream_frag(self.pg1,
8090 self.pg1.add_stream(pkts)
8091 self.pg_enable_capture(self.pg_interfaces)
8093 frags = self.pg0.get_capture(len(pkts))
8094 src = self.compose_ip6(self.pg1.remote_ip4, '64:ff9b::', 96)
8095 p = self.reass_frags_and_verify_ip6(frags, src, self.pg0.remote_ip6)
8096 self.assertEqual(p[TCP].sport, 20)
8097 self.assertEqual(p[TCP].dport, self.tcp_port_in)
8098 self.assertEqual(data, p[Raw].load)
8100 reass = self.vapi.nat_reass_dump()
8101 reass_n_end = len(reass)
8103 self.assertEqual(reass_n_end - reass_n_start, 2)
8105 def test_reass_hairpinning(self):
8106 """ NAT64 fragments hairpinning """
8108 server = self.pg0.remote_hosts[1]
8109 server_in_port = random.randint(1025, 65535)
8110 server_out_port = random.randint(1025, 65535)
8111 client_in_port = random.randint(1025, 65535)
8112 ip = IPv6(src=''.join(['64:ff9b::', self.nat_addr]))
8113 nat_addr_ip6 = ip.src
8115 self.vapi.nat64_add_del_pool_addr_range(self.nat_addr_n,
8117 self.vapi.nat64_add_del_interface(self.pg0.sw_if_index)
8118 self.vapi.nat64_add_del_interface(self.pg1.sw_if_index, is_inside=0)
8120 # add static BIB entry for server
8121 self.vapi.nat64_add_del_static_bib(server.ip6n,
8127 # send packet from host to server
8128 pkts = self.create_stream_frag_ip6(self.pg0,
8133 self.pg0.add_stream(pkts)
8134 self.pg_enable_capture(self.pg_interfaces)
8136 frags = self.pg0.get_capture(len(pkts))
8137 p = self.reass_frags_and_verify_ip6(frags, nat_addr_ip6, server.ip6)
8138 self.assertNotEqual(p[TCP].sport, client_in_port)
8139 self.assertEqual(p[TCP].dport, server_in_port)
8140 self.assertEqual(data, p[Raw].load)
8142 def test_frag_out_of_order(self):
8143 """ NAT64 translate fragments arriving out of order """
8144 self.tcp_port_in = random.randint(1025, 65535)
8146 self.vapi.nat64_add_del_pool_addr_range(self.nat_addr_n,
8148 self.vapi.nat64_add_del_interface(self.pg0.sw_if_index)
8149 self.vapi.nat64_add_del_interface(self.pg1.sw_if_index, is_inside=0)
8153 pkts = self.create_stream_frag_ip6(self.pg0, self.pg1.remote_ip4,
8154 self.tcp_port_in, 20, data)
8156 self.pg0.add_stream(pkts)
8157 self.pg_enable_capture(self.pg_interfaces)
8159 frags = self.pg1.get_capture(len(pkts))
8160 p = self.reass_frags_and_verify(frags,
8162 self.pg1.remote_ip4)
8163 self.assertEqual(p[TCP].dport, 20)
8164 self.assertNotEqual(p[TCP].sport, self.tcp_port_in)
8165 self.tcp_port_out = p[TCP].sport
8166 self.assertEqual(data, p[Raw].load)
8169 data = b"A" * 4 + b"B" * 16 + b"C" * 3
8170 pkts = self.create_stream_frag(self.pg1,
8176 self.pg1.add_stream(pkts)
8177 self.pg_enable_capture(self.pg_interfaces)
8179 frags = self.pg0.get_capture(len(pkts))
8180 src = self.compose_ip6(self.pg1.remote_ip4, '64:ff9b::', 96)
8181 p = self.reass_frags_and_verify_ip6(frags, src, self.pg0.remote_ip6)
8182 self.assertEqual(p[TCP].sport, 20)
8183 self.assertEqual(p[TCP].dport, self.tcp_port_in)
8184 self.assertEqual(data, p[Raw].load)
8186 def test_interface_addr(self):
8187 """ Acquire NAT64 pool addresses from interface """
8188 self.vapi.nat64_add_del_interface_addr(self.pg4.sw_if_index)
8190 # no address in NAT64 pool
8191 addresses = self.vapi.nat44_address_dump()
8192 self.assertEqual(0, len(addresses))
8194 # configure interface address and check NAT64 address pool
8195 self.pg4.config_ip4()
8196 addresses = self.vapi.nat64_pool_addr_dump()
8197 self.assertEqual(len(addresses), 1)
8198 self.assertEqual(addresses[0].address, self.pg4.local_ip4n)
8200 # remove interface address and check NAT64 address pool
8201 self.pg4.unconfig_ip4()
8202 addresses = self.vapi.nat64_pool_addr_dump()
8203 self.assertEqual(0, len(addresses))
8205 @unittest.skipUnless(running_extended_tests, "part of extended tests")
8206 def test_ipfix_max_bibs_sessions(self):
8207 """ IPFIX logging maximum session and BIB entries exceeded """
8210 remote_host_ip6 = self.compose_ip6(self.pg1.remote_ip4,
8214 self.vapi.nat64_add_del_pool_addr_range(self.nat_addr_n,
8216 self.vapi.nat64_add_del_interface(self.pg0.sw_if_index)
8217 self.vapi.nat64_add_del_interface(self.pg1.sw_if_index, is_inside=0)
8221 for i in range(0, max_bibs):
8222 src = "fd01:aa::%x" % (i)
8223 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
8224 IPv6(src=src, dst=remote_host_ip6) /
8225 TCP(sport=12345, dport=80))
8227 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
8228 IPv6(src=src, dst=remote_host_ip6) /
8229 TCP(sport=12345, dport=22))
8231 self.pg0.add_stream(pkts)
8232 self.pg_enable_capture(self.pg_interfaces)
8234 self.pg1.get_capture(max_sessions)
8236 self.vapi.set_ipfix_exporter(collector_address=self.pg3.remote_ip4n,
8237 src_address=self.pg3.local_ip4n,
8239 template_interval=10)
8240 self.vapi.nat_ipfix_enable_disable(domain_id=self.ipfix_domain_id,
8241 src_port=self.ipfix_src_port)
8243 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
8244 IPv6(src=src, dst=remote_host_ip6) /
8245 TCP(sport=12345, dport=25))
8246 self.pg0.add_stream(p)
8247 self.pg_enable_capture(self.pg_interfaces)
8249 self.pg1.assert_nothing_captured()
8251 self.vapi.cli("ipfix flush") # FIXME this should be an API call
8252 capture = self.pg3.get_capture(9)
8253 ipfix = IPFIXDecoder()
8254 # first load template
8256 self.assertTrue(p.haslayer(IPFIX))
8257 self.assertEqual(p[IP].src, self.pg3.local_ip4)
8258 self.assertEqual(p[IP].dst, self.pg3.remote_ip4)
8259 self.assertEqual(p[UDP].sport, self.ipfix_src_port)
8260 self.assertEqual(p[UDP].dport, 4739)
8261 self.assertEqual(p[IPFIX].observationDomainID,
8262 self.ipfix_domain_id)
8263 if p.haslayer(Template):
8264 ipfix.add_template(p.getlayer(Template))
8265 # verify events in data set
8267 if p.haslayer(Data):
8268 data = ipfix.decode_data_set(p.getlayer(Set))
8269 self.verify_ipfix_max_sessions(data, max_sessions)
8271 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
8272 IPv6(src=self.pg0.remote_ip6, dst=remote_host_ip6) /
8273 TCP(sport=12345, dport=80))
8274 self.pg0.add_stream(p)
8275 self.pg_enable_capture(self.pg_interfaces)
8277 self.pg1.assert_nothing_captured()
8279 self.vapi.cli("ipfix flush") # FIXME this should be an API call
8280 capture = self.pg3.get_capture(1)
8281 # verify events in data set
8283 self.assertTrue(p.haslayer(IPFIX))
8284 self.assertEqual(p[IP].src, self.pg3.local_ip4)
8285 self.assertEqual(p[IP].dst, self.pg3.remote_ip4)
8286 self.assertEqual(p[UDP].sport, self.ipfix_src_port)
8287 self.assertEqual(p[UDP].dport, 4739)
8288 self.assertEqual(p[IPFIX].observationDomainID,
8289 self.ipfix_domain_id)
8290 if p.haslayer(Data):
8291 data = ipfix.decode_data_set(p.getlayer(Set))
8292 self.verify_ipfix_max_bibs(data, max_bibs)
8294 def test_ipfix_max_frags(self):
8295 """ IPFIX logging maximum fragments pending reassembly exceeded """
8296 self.vapi.nat64_add_del_pool_addr_range(self.nat_addr_n,
8298 self.vapi.nat64_add_del_interface(self.pg0.sw_if_index)
8299 self.vapi.nat64_add_del_interface(self.pg1.sw_if_index, is_inside=0)
8300 self.vapi.nat_set_reass(max_frag=1, is_ip6=1)
8301 self.vapi.set_ipfix_exporter(collector_address=self.pg3.remote_ip4n,
8302 src_address=self.pg3.local_ip4n,
8304 template_interval=10)
8305 self.vapi.nat_ipfix_enable_disable(domain_id=self.ipfix_domain_id,
8306 src_port=self.ipfix_src_port)
8309 pkts = self.create_stream_frag_ip6(self.pg0, self.pg1.remote_ip4,
8310 self.tcp_port_in, 20, data)
8312 self.pg0.add_stream(pkts)
8313 self.pg_enable_capture(self.pg_interfaces)
8315 self.pg1.assert_nothing_captured()
8317 self.vapi.cli("ipfix flush") # FIXME this should be an API call
8318 capture = self.pg3.get_capture(9)
8319 ipfix = IPFIXDecoder()
8320 # first load template
8322 self.assertTrue(p.haslayer(IPFIX))
8323 self.assertEqual(p[IP].src, self.pg3.local_ip4)
8324 self.assertEqual(p[IP].dst, self.pg3.remote_ip4)
8325 self.assertEqual(p[UDP].sport, self.ipfix_src_port)
8326 self.assertEqual(p[UDP].dport, 4739)
8327 self.assertEqual(p[IPFIX].observationDomainID,
8328 self.ipfix_domain_id)
8329 if p.haslayer(Template):
8330 ipfix.add_template(p.getlayer(Template))
8331 # verify events in data set
8333 if p.haslayer(Data):
8334 data = ipfix.decode_data_set(p.getlayer(Set))
8335 self.verify_ipfix_max_fragments_ip6(data, 1,
8336 self.pg0.remote_ip6n)
8338 def test_ipfix_bib_ses(self):
8339 """ IPFIX logging NAT64 BIB/session create and delete events """
8340 self.tcp_port_in = random.randint(1025, 65535)
8341 remote_host_ip6 = self.compose_ip6(self.pg1.remote_ip4,
8345 self.vapi.nat64_add_del_pool_addr_range(self.nat_addr_n,
8347 self.vapi.nat64_add_del_interface(self.pg0.sw_if_index)
8348 self.vapi.nat64_add_del_interface(self.pg1.sw_if_index, is_inside=0)
8349 self.vapi.set_ipfix_exporter(collector_address=self.pg3.remote_ip4n,
8350 src_address=self.pg3.local_ip4n,
8352 template_interval=10)
8353 self.vapi.nat_ipfix_enable_disable(domain_id=self.ipfix_domain_id,
8354 src_port=self.ipfix_src_port)
8357 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
8358 IPv6(src=self.pg0.remote_ip6, dst=remote_host_ip6) /
8359 TCP(sport=self.tcp_port_in, dport=25))
8360 self.pg0.add_stream(p)
8361 self.pg_enable_capture(self.pg_interfaces)
8363 p = self.pg1.get_capture(1)
8364 self.tcp_port_out = p[0][TCP].sport
8365 self.vapi.cli("ipfix flush") # FIXME this should be an API call
8366 capture = self.pg3.get_capture(10)
8367 ipfix = IPFIXDecoder()
8368 # first load template
8370 self.assertTrue(p.haslayer(IPFIX))
8371 self.assertEqual(p[IP].src, self.pg3.local_ip4)
8372 self.assertEqual(p[IP].dst, self.pg3.remote_ip4)
8373 self.assertEqual(p[UDP].sport, self.ipfix_src_port)
8374 self.assertEqual(p[UDP].dport, 4739)
8375 self.assertEqual(p[IPFIX].observationDomainID,
8376 self.ipfix_domain_id)
8377 if p.haslayer(Template):
8378 ipfix.add_template(p.getlayer(Template))
8379 # verify events in data set
8381 if p.haslayer(Data):
8382 data = ipfix.decode_data_set(p.getlayer(Set))
8383 if scapy.compat.orb(data[0][230]) == 10:
8384 self.verify_ipfix_bib(data, 1, self.pg0.remote_ip6n)
8385 elif scapy.compat.orb(data[0][230]) == 6:
8386 self.verify_ipfix_nat64_ses(data,
8388 self.pg0.remote_ip6n,
8389 self.pg1.remote_ip4,
8392 self.logger.error(ppp("Unexpected or invalid packet: ", p))
8395 self.pg_enable_capture(self.pg_interfaces)
8396 self.vapi.nat64_add_del_pool_addr_range(self.nat_addr_n,
8399 self.vapi.cli("ipfix flush") # FIXME this should be an API call
8400 capture = self.pg3.get_capture(2)
8401 # verify events in data set
8403 self.assertTrue(p.haslayer(IPFIX))
8404 self.assertEqual(p[IP].src, self.pg3.local_ip4)
8405 self.assertEqual(p[IP].dst, self.pg3.remote_ip4)
8406 self.assertEqual(p[UDP].sport, self.ipfix_src_port)
8407 self.assertEqual(p[UDP].dport, 4739)
8408 self.assertEqual(p[IPFIX].observationDomainID,
8409 self.ipfix_domain_id)
8410 if p.haslayer(Data):
8411 data = ipfix.decode_data_set(p.getlayer(Set))
8412 if scapy.compat.orb(data[0][230]) == 11:
8413 self.verify_ipfix_bib(data, 0, self.pg0.remote_ip6n)
8414 elif scapy.compat.orb(data[0][230]) == 7:
8415 self.verify_ipfix_nat64_ses(data,
8417 self.pg0.remote_ip6n,
8418 self.pg1.remote_ip4,
8421 self.logger.error(ppp("Unexpected or invalid packet: ", p))
8423 def test_syslog_sess(self):
8424 """ Test syslog session creation and deletion """
8425 self.tcp_port_in = random.randint(1025, 65535)
8426 remote_host_ip6 = self.compose_ip6(self.pg1.remote_ip4,
8430 self.vapi.nat64_add_del_pool_addr_range(self.nat_addr_n,
8432 self.vapi.nat64_add_del_interface(self.pg0.sw_if_index)
8433 self.vapi.nat64_add_del_interface(self.pg1.sw_if_index, is_inside=0)
8434 self.vapi.syslog_set_filter(SYSLOG_SEVERITY.INFO)
8435 self.vapi.syslog_set_sender(self.pg3.local_ip4n, self.pg3.remote_ip4n)
8437 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
8438 IPv6(src=self.pg0.remote_ip6, dst=remote_host_ip6) /
8439 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port))
8440 self.pg0.add_stream(p)
8441 self.pg_enable_capture(self.pg_interfaces)
8443 p = self.pg1.get_capture(1)
8444 self.tcp_port_out = p[0][TCP].sport
8445 capture = self.pg3.get_capture(1)
8446 self.verify_syslog_sess(capture[0][Raw].load, is_ip6=True)
8448 self.pg_enable_capture(self.pg_interfaces)
8450 self.vapi.nat64_add_del_pool_addr_range(self.nat_addr_n,
8453 capture = self.pg3.get_capture(1)
8454 self.verify_syslog_sess(capture[0][Raw].load, False, True)
8456 def nat64_get_ses_num(self):
8458 Return number of active NAT64 sessions.
8460 st = self.vapi.nat64_st_dump()
8463 def clear_nat64(self):
8465 Clear NAT64 configuration.
8467 self.vapi.nat_ipfix_enable_disable(enable=0,
8468 src_port=self.ipfix_src_port,
8469 domain_id=self.ipfix_domain_id)
8470 self.ipfix_src_port = 4739
8471 self.ipfix_domain_id = 1
8473 self.vapi.syslog_set_filter(SYSLOG_SEVERITY.EMERG)
8475 self.vapi.nat_set_timeouts()
8477 interfaces = self.vapi.nat64_interface_dump()
8478 for intf in interfaces:
8479 if intf.is_inside > 1:
8480 self.vapi.nat64_add_del_interface(intf.sw_if_index,
8483 self.vapi.nat64_add_del_interface(intf.sw_if_index,
8487 bib = self.vapi.nat64_bib_dump(255)
8490 self.vapi.nat64_add_del_static_bib(bibe.i_addr,
8498 adresses = self.vapi.nat64_pool_addr_dump()
8499 for addr in adresses:
8500 self.vapi.nat64_add_del_pool_addr_range(addr.address,
8505 prefixes = self.vapi.nat64_prefix_dump()
8506 for prefix in prefixes:
8507 self.vapi.nat64_add_del_prefix(prefix.prefix,
8509 vrf_id=prefix.vrf_id,
8512 bibs = self.statistics.get_counter('/nat64/total-bibs')
8513 self.assertEqual(bibs[0][0], 0)
8514 sessions = self.statistics.get_counter('/nat64/total-sessions')
8515 self.assertEqual(sessions[0][0], 0)
8518 super(TestNAT64, self).tearDown()
8519 if not self.vpp_dead:
8520 self.logger.info(self.vapi.cli("show nat64 pool"))
8521 self.logger.info(self.vapi.cli("show nat64 interfaces"))
8522 self.logger.info(self.vapi.cli("show nat64 prefix"))
8523 self.logger.info(self.vapi.cli("show nat64 bib all"))
8524 self.logger.info(self.vapi.cli("show nat64 session table all"))
8525 self.logger.info(self.vapi.cli("show nat virtual-reassembly"))
8529 class TestDSlite(MethodHolder):
8530 """ DS-Lite Test Cases """
8533 def setUpClass(cls):
8534 super(TestDSlite, cls).setUpClass()
8537 cls.nat_addr = '10.0.0.3'
8538 cls.nat_addr_n = socket.inet_pton(socket.AF_INET, cls.nat_addr)
8540 cls.create_pg_interfaces(range(3))
8542 cls.pg0.config_ip4()
8543 cls.pg0.resolve_arp()
8545 cls.pg1.config_ip6()
8546 cls.pg1.generate_remote_hosts(2)
8547 cls.pg1.configure_ipv6_neighbors()
8549 cls.pg2.config_ip4()
8550 cls.pg2.resolve_arp()
8553 super(TestDSlite, cls).tearDownClass()
8557 def tearDownClass(cls):
8558 super(TestDSlite, cls).tearDownClass()
8560 def verify_syslog_apmadd(self, data, isaddr, isport, xsaddr, xsport,
8562 message = data.decode('utf-8')
8564 message = SyslogMessage.parse(message)
8565 except ParseError as e:
8566 self.logger.error(e)
8568 self.assertEqual(message.severity, SyslogSeverity.info)
8569 self.assertEqual(message.appname, 'NAT')
8570 self.assertEqual(message.msgid, 'APMADD')
8571 sd_params = message.sd.get('napmap')
8572 self.assertTrue(sd_params is not None)
8573 self.assertEqual(sd_params.get('IATYP'), 'IPv4')
8574 self.assertEqual(sd_params.get('ISADDR'), isaddr)
8575 self.assertEqual(sd_params.get('ISPORT'), "%d" % isport)
8576 self.assertEqual(sd_params.get('XATYP'), 'IPv4')
8577 self.assertEqual(sd_params.get('XSADDR'), xsaddr)
8578 self.assertEqual(sd_params.get('XSPORT'), "%d" % xsport)
8579 self.assertEqual(sd_params.get('PROTO'), "%d" % proto)
8580 self.assertTrue(sd_params.get('SSUBIX') is not None)
8581 self.assertEqual(sd_params.get('SV6ENC'), sv6enc)
8583 def test_dslite(self):
8584 """ Test DS-Lite """
8585 nat_config = self.vapi.nat_show_config()
8586 self.assertEqual(0, nat_config.dslite_ce)
8588 self.vapi.dslite_add_del_pool_addr_range(self.nat_addr_n,
8590 aftr_ip4 = '192.0.0.1'
8591 aftr_ip4_n = socket.inet_pton(socket.AF_INET, aftr_ip4)
8592 aftr_ip6 = '2001:db8:85a3::8a2e:370:1'
8593 aftr_ip6_n = socket.inet_pton(socket.AF_INET6, aftr_ip6)
8594 self.vapi.dslite_set_aftr_addr(aftr_ip6_n, aftr_ip4_n)
8595 self.vapi.syslog_set_sender(self.pg2.local_ip4n, self.pg2.remote_ip4n)
8598 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
8599 IPv6(dst=aftr_ip6, src=self.pg1.remote_hosts[0].ip6) /
8600 IP(dst=self.pg0.remote_ip4, src='192.168.1.1') /
8601 UDP(sport=20000, dport=10000))
8602 self.pg1.add_stream(p)
8603 self.pg_enable_capture(self.pg_interfaces)
8605 capture = self.pg0.get_capture(1)
8606 capture = capture[0]
8607 self.assertFalse(capture.haslayer(IPv6))
8608 self.assertEqual(capture[IP].src, self.nat_addr)
8609 self.assertEqual(capture[IP].dst, self.pg0.remote_ip4)
8610 self.assertNotEqual(capture[UDP].sport, 20000)
8611 self.assertEqual(capture[UDP].dport, 10000)
8612 self.assert_packet_checksums_valid(capture)
8613 out_port = capture[UDP].sport
8614 capture = self.pg2.get_capture(1)
8615 self.verify_syslog_apmadd(capture[0][Raw].load, '192.168.1.1',
8616 20000, self.nat_addr, out_port,
8617 self.pg1.remote_hosts[0].ip6, IP_PROTOS.udp)
8619 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
8620 IP(dst=self.nat_addr, src=self.pg0.remote_ip4) /
8621 UDP(sport=10000, dport=out_port))
8622 self.pg0.add_stream(p)
8623 self.pg_enable_capture(self.pg_interfaces)
8625 capture = self.pg1.get_capture(1)
8626 capture = capture[0]
8627 self.assertEqual(capture[IPv6].src, aftr_ip6)
8628 self.assertEqual(capture[IPv6].dst, self.pg1.remote_hosts[0].ip6)
8629 self.assertEqual(capture[IP].src, self.pg0.remote_ip4)
8630 self.assertEqual(capture[IP].dst, '192.168.1.1')
8631 self.assertEqual(capture[UDP].sport, 10000)
8632 self.assertEqual(capture[UDP].dport, 20000)
8633 self.assert_packet_checksums_valid(capture)
8636 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
8637 IPv6(dst=aftr_ip6, src=self.pg1.remote_hosts[1].ip6) /
8638 IP(dst=self.pg0.remote_ip4, src='192.168.1.1') /
8639 TCP(sport=20001, dport=10001))
8640 self.pg1.add_stream(p)
8641 self.pg_enable_capture(self.pg_interfaces)
8643 capture = self.pg0.get_capture(1)
8644 capture = capture[0]
8645 self.assertFalse(capture.haslayer(IPv6))
8646 self.assertEqual(capture[IP].src, self.nat_addr)
8647 self.assertEqual(capture[IP].dst, self.pg0.remote_ip4)
8648 self.assertNotEqual(capture[TCP].sport, 20001)
8649 self.assertEqual(capture[TCP].dport, 10001)
8650 self.assert_packet_checksums_valid(capture)
8651 out_port = capture[TCP].sport
8653 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
8654 IP(dst=self.nat_addr, src=self.pg0.remote_ip4) /
8655 TCP(sport=10001, dport=out_port))
8656 self.pg0.add_stream(p)
8657 self.pg_enable_capture(self.pg_interfaces)
8659 capture = self.pg1.get_capture(1)
8660 capture = capture[0]
8661 self.assertEqual(capture[IPv6].src, aftr_ip6)
8662 self.assertEqual(capture[IPv6].dst, self.pg1.remote_hosts[1].ip6)
8663 self.assertEqual(capture[IP].src, self.pg0.remote_ip4)
8664 self.assertEqual(capture[IP].dst, '192.168.1.1')
8665 self.assertEqual(capture[TCP].sport, 10001)
8666 self.assertEqual(capture[TCP].dport, 20001)
8667 self.assert_packet_checksums_valid(capture)
8670 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
8671 IPv6(dst=aftr_ip6, src=self.pg1.remote_hosts[1].ip6) /
8672 IP(dst=self.pg0.remote_ip4, src='192.168.1.1') /
8673 ICMP(id=4000, type='echo-request'))
8674 self.pg1.add_stream(p)
8675 self.pg_enable_capture(self.pg_interfaces)
8677 capture = self.pg0.get_capture(1)
8678 capture = capture[0]
8679 self.assertFalse(capture.haslayer(IPv6))
8680 self.assertEqual(capture[IP].src, self.nat_addr)
8681 self.assertEqual(capture[IP].dst, self.pg0.remote_ip4)
8682 self.assertNotEqual(capture[ICMP].id, 4000)
8683 self.assert_packet_checksums_valid(capture)
8684 out_id = capture[ICMP].id
8686 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
8687 IP(dst=self.nat_addr, src=self.pg0.remote_ip4) /
8688 ICMP(id=out_id, type='echo-reply'))
8689 self.pg0.add_stream(p)
8690 self.pg_enable_capture(self.pg_interfaces)
8692 capture = self.pg1.get_capture(1)
8693 capture = capture[0]
8694 self.assertEqual(capture[IPv6].src, aftr_ip6)
8695 self.assertEqual(capture[IPv6].dst, self.pg1.remote_hosts[1].ip6)
8696 self.assertEqual(capture[IP].src, self.pg0.remote_ip4)
8697 self.assertEqual(capture[IP].dst, '192.168.1.1')
8698 self.assertEqual(capture[ICMP].id, 4000)
8699 self.assert_packet_checksums_valid(capture)
8701 # ping DS-Lite AFTR tunnel endpoint address
8702 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
8703 IPv6(src=self.pg1.remote_hosts[1].ip6, dst=aftr_ip6) /
8704 ICMPv6EchoRequest())
8705 self.pg1.add_stream(p)
8706 self.pg_enable_capture(self.pg_interfaces)
8708 capture = self.pg1.get_capture(1)
8709 capture = capture[0]
8710 self.assertEqual(capture[IPv6].src, aftr_ip6)
8711 self.assertEqual(capture[IPv6].dst, self.pg1.remote_hosts[1].ip6)
8712 self.assertTrue(capture.haslayer(ICMPv6EchoReply))
8714 b4s = self.statistics.get_counter('/dslite/total-b4s')
8715 self.assertEqual(b4s[0][0], 2)
8716 sessions = self.statistics.get_counter('/dslite/total-sessions')
8717 self.assertEqual(sessions[0][0], 3)
8720 super(TestDSlite, self).tearDown()
8721 if not self.vpp_dead:
8722 self.logger.info(self.vapi.cli("show dslite pool"))
8724 self.vapi.cli("show dslite aftr-tunnel-endpoint-address"))
8725 self.logger.info(self.vapi.cli("show dslite sessions"))
8728 class TestDSliteCE(MethodHolder):
8729 """ DS-Lite CE Test Cases """
8732 def setUpConstants(cls):
8733 super(TestDSliteCE, cls).setUpConstants()
8734 cls.vpp_cmdline.extend(["nat", "{", "dslite ce", "}"])
8737 def setUpClass(cls):
8738 super(TestDSliteCE, cls).setUpClass()
8741 cls.create_pg_interfaces(range(2))
8743 cls.pg0.config_ip4()
8744 cls.pg0.resolve_arp()
8746 cls.pg1.config_ip6()
8747 cls.pg1.generate_remote_hosts(1)
8748 cls.pg1.configure_ipv6_neighbors()
8751 super(TestDSliteCE, cls).tearDownClass()
8755 def tearDownClass(cls):
8756 super(TestDSliteCE, cls).tearDownClass()
8758 def test_dslite_ce(self):
8759 """ Test DS-Lite CE """
8761 nat_config = self.vapi.nat_show_config()
8762 self.assertEqual(1, nat_config.dslite_ce)
8764 b4_ip4 = '192.0.0.2'
8765 b4_ip4_n = socket.inet_pton(socket.AF_INET, b4_ip4)
8766 b4_ip6 = '2001:db8:62aa::375e:f4c1:1'
8767 b4_ip6_n = socket.inet_pton(socket.AF_INET6, b4_ip6)
8768 self.vapi.dslite_set_b4_addr(b4_ip6_n, b4_ip4_n)
8770 aftr_ip4 = '192.0.0.1'
8771 aftr_ip4_n = socket.inet_pton(socket.AF_INET, aftr_ip4)
8772 aftr_ip6 = '2001:db8:85a3::8a2e:370:1'
8773 aftr_ip6_n = socket.inet_pton(socket.AF_INET6, aftr_ip6)
8774 self.vapi.dslite_set_aftr_addr(aftr_ip6_n, aftr_ip4_n)
8776 self.vapi.ip_add_del_route(dst_address=aftr_ip6_n,
8777 dst_address_length=128,
8778 next_hop_address=self.pg1.remote_ip6n,
8779 next_hop_sw_if_index=self.pg1.sw_if_index,
8783 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
8784 IP(dst=self.pg1.remote_ip4, src=self.pg0.remote_ip4) /
8785 UDP(sport=10000, dport=20000))
8786 self.pg0.add_stream(p)
8787 self.pg_enable_capture(self.pg_interfaces)
8789 capture = self.pg1.get_capture(1)
8790 capture = capture[0]
8791 self.assertEqual(capture[IPv6].src, b4_ip6)
8792 self.assertEqual(capture[IPv6].dst, aftr_ip6)
8793 self.assertEqual(capture[IP].src, self.pg0.remote_ip4)
8794 self.assertEqual(capture[IP].dst, self.pg1.remote_ip4)
8795 self.assertEqual(capture[UDP].sport, 10000)
8796 self.assertEqual(capture[UDP].dport, 20000)
8797 self.assert_packet_checksums_valid(capture)
8800 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
8801 IPv6(dst=b4_ip6, src=aftr_ip6) /
8802 IP(dst=self.pg0.remote_ip4, src=self.pg1.remote_ip4) /
8803 UDP(sport=20000, dport=10000))
8804 self.pg1.add_stream(p)
8805 self.pg_enable_capture(self.pg_interfaces)
8807 capture = self.pg0.get_capture(1)
8808 capture = capture[0]
8809 self.assertFalse(capture.haslayer(IPv6))
8810 self.assertEqual(capture[IP].src, self.pg1.remote_ip4)
8811 self.assertEqual(capture[IP].dst, self.pg0.remote_ip4)
8812 self.assertEqual(capture[UDP].sport, 20000)
8813 self.assertEqual(capture[UDP].dport, 10000)
8814 self.assert_packet_checksums_valid(capture)
8816 # ping DS-Lite B4 tunnel endpoint address
8817 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
8818 IPv6(src=self.pg1.remote_hosts[0].ip6, dst=b4_ip6) /
8819 ICMPv6EchoRequest())
8820 self.pg1.add_stream(p)
8821 self.pg_enable_capture(self.pg_interfaces)
8823 capture = self.pg1.get_capture(1)
8824 capture = capture[0]
8825 self.assertEqual(capture[IPv6].src, b4_ip6)
8826 self.assertEqual(capture[IPv6].dst, self.pg1.remote_hosts[0].ip6)
8827 self.assertTrue(capture.haslayer(ICMPv6EchoReply))
8830 super(TestDSliteCE, self).tearDown()
8831 if not self.vpp_dead:
8833 self.vapi.cli("show dslite aftr-tunnel-endpoint-address"))
8835 self.vapi.cli("show dslite b4-tunnel-endpoint-address"))
8838 class TestNAT66(MethodHolder):
8839 """ NAT66 Test Cases """
8842 def setUpClass(cls):
8843 super(TestNAT66, cls).setUpClass()
8846 cls.nat_addr = 'fd01:ff::2'
8847 cls.nat_addr_n = socket.inet_pton(socket.AF_INET6, cls.nat_addr)
8849 cls.create_pg_interfaces(range(2))
8850 cls.interfaces = list(cls.pg_interfaces)
8852 for i in cls.interfaces:
8855 i.configure_ipv6_neighbors()
8858 super(TestNAT66, cls).tearDownClass()
8862 def tearDownClass(cls):
8863 super(TestNAT66, cls).tearDownClass()
8865 def test_static(self):
8866 """ 1:1 NAT66 test """
8867 self.vapi.nat66_add_del_interface(self.pg0.sw_if_index)
8868 self.vapi.nat66_add_del_interface(self.pg1.sw_if_index, is_inside=0)
8869 self.vapi.nat66_add_del_static_mapping(self.pg0.remote_ip6n,
8874 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
8875 IPv6(src=self.pg0.remote_ip6, dst=self.pg1.remote_ip6) /
8878 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
8879 IPv6(src=self.pg0.remote_ip6, dst=self.pg1.remote_ip6) /
8882 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
8883 IPv6(src=self.pg0.remote_ip6, dst=self.pg1.remote_ip6) /
8884 ICMPv6EchoRequest())
8886 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
8887 IPv6(src=self.pg0.remote_ip6, dst=self.pg1.remote_ip6) /
8888 GRE() / IP() / TCP())
8890 self.pg0.add_stream(pkts)
8891 self.pg_enable_capture(self.pg_interfaces)
8893 capture = self.pg1.get_capture(len(pkts))
8894 for packet in capture:
8896 self.assertEqual(packet[IPv6].src, self.nat_addr)
8897 self.assertEqual(packet[IPv6].dst, self.pg1.remote_ip6)
8898 self.assert_packet_checksums_valid(packet)
8900 self.logger.error(ppp("Unexpected or invalid packet:", packet))
8905 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
8906 IPv6(src=self.pg1.remote_ip6, dst=self.nat_addr) /
8909 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
8910 IPv6(src=self.pg1.remote_ip6, dst=self.nat_addr) /
8913 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
8914 IPv6(src=self.pg1.remote_ip6, dst=self.nat_addr) /
8917 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
8918 IPv6(src=self.pg1.remote_ip6, dst=self.nat_addr) /
8919 GRE() / IP() / TCP())
8921 self.pg1.add_stream(pkts)
8922 self.pg_enable_capture(self.pg_interfaces)
8924 capture = self.pg0.get_capture(len(pkts))
8925 for packet in capture:
8927 self.assertEqual(packet[IPv6].src, self.pg1.remote_ip6)
8928 self.assertEqual(packet[IPv6].dst, self.pg0.remote_ip6)
8929 self.assert_packet_checksums_valid(packet)
8931 self.logger.error(ppp("Unexpected or invalid packet:", packet))
8934 sm = self.vapi.nat66_static_mapping_dump()
8935 self.assertEqual(len(sm), 1)
8936 self.assertEqual(sm[0].total_pkts, 8)
8938 def test_check_no_translate(self):
8939 """ NAT66 translate only when egress interface is outside interface """
8940 self.vapi.nat66_add_del_interface(self.pg0.sw_if_index)
8941 self.vapi.nat66_add_del_interface(self.pg1.sw_if_index)
8942 self.vapi.nat66_add_del_static_mapping(self.pg0.remote_ip6n,
8946 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
8947 IPv6(src=self.pg0.remote_ip6, dst=self.pg1.remote_ip6) /
8949 self.pg0.add_stream([p])
8950 self.pg_enable_capture(self.pg_interfaces)
8952 capture = self.pg1.get_capture(1)
8955 self.assertEqual(packet[IPv6].src, self.pg0.remote_ip6)
8956 self.assertEqual(packet[IPv6].dst, self.pg1.remote_ip6)
8958 self.logger.error(ppp("Unexpected or invalid packet:", packet))
8961 def clear_nat66(self):
8963 Clear NAT66 configuration.
8965 interfaces = self.vapi.nat66_interface_dump()
8966 for intf in interfaces:
8967 self.vapi.nat66_add_del_interface(intf.sw_if_index,
8971 static_mappings = self.vapi.nat66_static_mapping_dump()
8972 for sm in static_mappings:
8973 self.vapi.nat66_add_del_static_mapping(sm.local_ip_address,
8974 sm.external_ip_address,
8979 super(TestNAT66, self).tearDown()
8980 if not self.vpp_dead:
8981 self.logger.info(self.vapi.cli("show nat66 interfaces"))
8982 self.logger.info(self.vapi.cli("show nat66 static mappings"))
8986 if __name__ == '__main__':
8987 unittest.main(testRunner=VppTestRunner)