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()
1565 def test_dynamic(self):
1566 """ NAT44 dynamic translation test """
1567 self.nat44_add_address(self.nat_addr)
1568 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
1569 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
1573 tcpn = self.statistics.get_counter(
1574 '/err/nat44-in2out-slowpath/TCP packets')
1575 udpn = self.statistics.get_counter(
1576 '/err/nat44-in2out-slowpath/UDP packets')
1577 icmpn = self.statistics.get_counter(
1578 '/err/nat44-in2out-slowpath/ICMP packets')
1579 totaln = self.statistics.get_counter(
1580 '/err/nat44-in2out-slowpath/good in2out packets processed')
1582 pkts = self.create_stream_in(self.pg0, self.pg1)
1583 self.pg0.add_stream(pkts)
1584 self.pg_enable_capture(self.pg_interfaces)
1586 capture = self.pg1.get_capture(len(pkts))
1587 self.verify_capture_out(capture)
1589 err = self.statistics.get_counter(
1590 '/err/nat44-in2out-slowpath/TCP packets')
1591 self.assertEqual(err - tcpn, 1)
1592 err = self.statistics.get_counter(
1593 '/err/nat44-in2out-slowpath/UDP packets')
1594 self.assertEqual(err - udpn, 1)
1595 err = self.statistics.get_counter(
1596 '/err/nat44-in2out-slowpath/ICMP packets')
1597 self.assertEqual(err - icmpn, 1)
1598 err = self.statistics.get_counter(
1599 '/err/nat44-in2out-slowpath/good in2out packets processed')
1600 self.assertEqual(err - totaln, 3)
1603 tcpn = self.statistics.get_counter('/err/nat44-out2in/TCP packets')
1604 udpn = self.statistics.get_counter('/err/nat44-out2in/UDP packets')
1605 icmpn = self.statistics.get_counter('/err/nat44-out2in/ICMP packets')
1606 totaln = self.statistics.get_counter(
1607 '/err/nat44-out2in/good out2in packets processed')
1609 pkts = self.create_stream_out(self.pg1)
1610 self.pg1.add_stream(pkts)
1611 self.pg_enable_capture(self.pg_interfaces)
1613 capture = self.pg0.get_capture(len(pkts))
1614 self.verify_capture_in(capture, self.pg0)
1616 err = self.statistics.get_counter('/err/nat44-out2in/TCP packets')
1617 self.assertEqual(err - tcpn, 1)
1618 err = self.statistics.get_counter('/err/nat44-out2in/UDP packets')
1619 self.assertEqual(err - udpn, 1)
1620 err = self.statistics.get_counter('/err/nat44-out2in/ICMP packets')
1621 self.assertEqual(err - icmpn, 1)
1622 err = self.statistics.get_counter(
1623 '/err/nat44-out2in/good out2in packets processed')
1624 self.assertEqual(err - totaln, 3)
1626 users = self.statistics.get_counter('/nat44/total-users')
1627 self.assertEqual(users[0][0], 1)
1628 sessions = self.statistics.get_counter('/nat44/total-sessions')
1629 self.assertEqual(sessions[0][0], 3)
1631 def test_dynamic_icmp_errors_in2out_ttl_1(self):
1632 """ NAT44 handling of client packets with TTL=1 """
1634 self.nat44_add_address(self.nat_addr)
1635 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
1636 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
1639 # Client side - generate traffic
1640 pkts = self.create_stream_in(self.pg0, self.pg1, ttl=1)
1641 self.pg0.add_stream(pkts)
1642 self.pg_enable_capture(self.pg_interfaces)
1645 # Client side - verify ICMP type 11 packets
1646 capture = self.pg0.get_capture(len(pkts))
1647 self.verify_capture_in_with_icmp_errors(capture, self.pg0)
1649 def test_dynamic_icmp_errors_out2in_ttl_1(self):
1650 """ NAT44 handling of server packets with TTL=1 """
1652 self.nat44_add_address(self.nat_addr)
1653 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
1654 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
1657 # Client side - create sessions
1658 pkts = self.create_stream_in(self.pg0, self.pg1)
1659 self.pg0.add_stream(pkts)
1660 self.pg_enable_capture(self.pg_interfaces)
1663 # Server side - generate traffic
1664 capture = self.pg1.get_capture(len(pkts))
1665 self.verify_capture_out(capture)
1666 pkts = self.create_stream_out(self.pg1, ttl=1)
1667 self.pg1.add_stream(pkts)
1668 self.pg_enable_capture(self.pg_interfaces)
1671 # Server side - verify ICMP type 11 packets
1672 capture = self.pg1.get_capture(len(pkts))
1673 self.verify_capture_out_with_icmp_errors(capture,
1674 src_ip=self.pg1.local_ip4)
1676 def test_dynamic_icmp_errors_in2out_ttl_2(self):
1677 """ NAT44 handling of error responses to client packets with TTL=2 """
1679 self.nat44_add_address(self.nat_addr)
1680 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
1681 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
1684 # Client side - generate traffic
1685 pkts = self.create_stream_in(self.pg0, self.pg1, ttl=2)
1686 self.pg0.add_stream(pkts)
1687 self.pg_enable_capture(self.pg_interfaces)
1690 # Server side - simulate ICMP type 11 response
1691 capture = self.pg1.get_capture(len(pkts))
1692 pkts = [Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
1693 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
1694 ICMP(type=11) / packet[IP] for packet in capture]
1695 self.pg1.add_stream(pkts)
1696 self.pg_enable_capture(self.pg_interfaces)
1699 # Client side - verify ICMP type 11 packets
1700 capture = self.pg0.get_capture(len(pkts))
1701 self.verify_capture_in_with_icmp_errors(capture, self.pg0)
1703 def test_dynamic_icmp_errors_out2in_ttl_2(self):
1704 """ NAT44 handling of error responses to server packets with TTL=2 """
1706 self.nat44_add_address(self.nat_addr)
1707 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
1708 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
1711 # Client side - create sessions
1712 pkts = self.create_stream_in(self.pg0, self.pg1)
1713 self.pg0.add_stream(pkts)
1714 self.pg_enable_capture(self.pg_interfaces)
1717 # Server side - generate traffic
1718 capture = self.pg1.get_capture(len(pkts))
1719 self.verify_capture_out(capture)
1720 pkts = self.create_stream_out(self.pg1, ttl=2)
1721 self.pg1.add_stream(pkts)
1722 self.pg_enable_capture(self.pg_interfaces)
1725 # Client side - simulate ICMP type 11 response
1726 capture = self.pg0.get_capture(len(pkts))
1727 pkts = [Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
1728 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
1729 ICMP(type=11) / packet[IP] for packet in capture]
1730 self.pg0.add_stream(pkts)
1731 self.pg_enable_capture(self.pg_interfaces)
1734 # Server side - verify ICMP type 11 packets
1735 capture = self.pg1.get_capture(len(pkts))
1736 self.verify_capture_out_with_icmp_errors(capture)
1738 def test_ping_out_interface_from_outside(self):
1739 """ Ping NAT44 out interface from outside network """
1741 self.nat44_add_address(self.nat_addr)
1742 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
1743 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
1746 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
1747 IP(src=self.pg1.remote_ip4, dst=self.pg1.local_ip4) /
1748 ICMP(id=self.icmp_id_out, type='echo-request'))
1750 self.pg1.add_stream(pkts)
1751 self.pg_enable_capture(self.pg_interfaces)
1753 capture = self.pg1.get_capture(len(pkts))
1756 self.assertEqual(packet[IP].src, self.pg1.local_ip4)
1757 self.assertEqual(packet[IP].dst, self.pg1.remote_ip4)
1758 self.assertEqual(packet[ICMP].id, self.icmp_id_in)
1759 self.assertEqual(packet[ICMP].type, 0) # echo reply
1761 self.logger.error(ppp("Unexpected or invalid packet "
1762 "(outside network):", packet))
1765 def test_ping_internal_host_from_outside(self):
1766 """ Ping internal host from outside network """
1768 self.nat44_add_static_mapping(self.pg0.remote_ip4, self.nat_addr)
1769 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
1770 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
1774 pkt = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
1775 IP(src=self.pg1.remote_ip4, dst=self.nat_addr, ttl=64) /
1776 ICMP(id=self.icmp_id_out, type='echo-request'))
1777 self.pg1.add_stream(pkt)
1778 self.pg_enable_capture(self.pg_interfaces)
1780 capture = self.pg0.get_capture(1)
1781 self.verify_capture_in(capture, self.pg0)
1782 self.assert_equal(capture[0][IP].proto, IP_PROTOS.icmp)
1785 pkt = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
1786 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4, ttl=64) /
1787 ICMP(id=self.icmp_id_in, type='echo-reply'))
1788 self.pg0.add_stream(pkt)
1789 self.pg_enable_capture(self.pg_interfaces)
1791 capture = self.pg1.get_capture(1)
1792 self.verify_capture_out(capture, same_port=True)
1793 self.assert_equal(capture[0][IP].proto, IP_PROTOS.icmp)
1795 def test_forwarding(self):
1796 """ NAT44 forwarding test """
1798 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
1799 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
1801 self.vapi.nat44_forwarding_enable_disable(1)
1803 real_ip = self.pg0.remote_ip4n
1804 alias_ip = self.nat_addr_n
1805 self.vapi.nat44_add_del_static_mapping(local_ip=real_ip,
1806 external_ip=alias_ip)
1809 # static mapping match
1811 pkts = self.create_stream_out(self.pg1)
1812 self.pg1.add_stream(pkts)
1813 self.pg_enable_capture(self.pg_interfaces)
1815 capture = self.pg0.get_capture(len(pkts))
1816 self.verify_capture_in(capture, self.pg0)
1818 pkts = self.create_stream_in(self.pg0, self.pg1)
1819 self.pg0.add_stream(pkts)
1820 self.pg_enable_capture(self.pg_interfaces)
1822 capture = self.pg1.get_capture(len(pkts))
1823 self.verify_capture_out(capture, same_port=True)
1825 # no static mapping match
1827 host0 = self.pg0.remote_hosts[0]
1828 self.pg0.remote_hosts[0] = self.pg0.remote_hosts[1]
1830 pkts = self.create_stream_out(self.pg1,
1831 dst_ip=self.pg0.remote_ip4,
1832 use_inside_ports=True)
1833 self.pg1.add_stream(pkts)
1834 self.pg_enable_capture(self.pg_interfaces)
1836 capture = self.pg0.get_capture(len(pkts))
1837 self.verify_capture_in(capture, self.pg0)
1839 pkts = self.create_stream_in(self.pg0, self.pg1)
1840 self.pg0.add_stream(pkts)
1841 self.pg_enable_capture(self.pg_interfaces)
1843 capture = self.pg1.get_capture(len(pkts))
1844 self.verify_capture_out(capture, nat_ip=self.pg0.remote_ip4,
1847 self.pg0.remote_hosts[0] = host0
1850 self.vapi.nat44_forwarding_enable_disable(0)
1851 self.vapi.nat44_add_del_static_mapping(local_ip=real_ip,
1852 external_ip=alias_ip,
1855 def test_static_in(self):
1856 """ 1:1 NAT initialized from inside network """
1858 nat_ip = "10.0.0.10"
1859 self.tcp_port_out = 6303
1860 self.udp_port_out = 6304
1861 self.icmp_id_out = 6305
1863 self.nat44_add_static_mapping(self.pg0.remote_ip4, nat_ip)
1864 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
1865 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
1867 sm = self.vapi.nat44_static_mapping_dump()
1868 self.assertEqual(len(sm), 1)
1869 self.assertEqual((sm[0].tag).split(b'\0', 1)[0], b'')
1870 self.assertEqual(sm[0].protocol, 0)
1871 self.assertEqual(sm[0].local_port, 0)
1872 self.assertEqual(sm[0].external_port, 0)
1875 pkts = self.create_stream_in(self.pg0, self.pg1)
1876 self.pg0.add_stream(pkts)
1877 self.pg_enable_capture(self.pg_interfaces)
1879 capture = self.pg1.get_capture(len(pkts))
1880 self.verify_capture_out(capture, nat_ip, True)
1883 pkts = self.create_stream_out(self.pg1, nat_ip)
1884 self.pg1.add_stream(pkts)
1885 self.pg_enable_capture(self.pg_interfaces)
1887 capture = self.pg0.get_capture(len(pkts))
1888 self.verify_capture_in(capture, self.pg0)
1890 def test_static_out(self):
1891 """ 1:1 NAT initialized from outside network """
1893 nat_ip = "10.0.0.20"
1894 self.tcp_port_out = 6303
1895 self.udp_port_out = 6304
1896 self.icmp_id_out = 6305
1899 self.nat44_add_static_mapping(self.pg0.remote_ip4, nat_ip, tag=tag)
1900 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
1901 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
1903 sm = self.vapi.nat44_static_mapping_dump()
1904 self.assertEqual(len(sm), 1)
1905 self.assertEqual((sm[0].tag).split(b'\0', 1)[0], tag)
1908 pkts = self.create_stream_out(self.pg1, nat_ip)
1909 self.pg1.add_stream(pkts)
1910 self.pg_enable_capture(self.pg_interfaces)
1912 capture = self.pg0.get_capture(len(pkts))
1913 self.verify_capture_in(capture, self.pg0)
1916 pkts = self.create_stream_in(self.pg0, self.pg1)
1917 self.pg0.add_stream(pkts)
1918 self.pg_enable_capture(self.pg_interfaces)
1920 capture = self.pg1.get_capture(len(pkts))
1921 self.verify_capture_out(capture, nat_ip, True)
1923 def test_static_with_port_in(self):
1924 """ 1:1 NAPT initialized from inside network """
1926 self.tcp_port_out = 3606
1927 self.udp_port_out = 3607
1928 self.icmp_id_out = 3608
1930 self.nat44_add_address(self.nat_addr)
1931 self.nat44_add_static_mapping(self.pg0.remote_ip4, self.nat_addr,
1932 self.tcp_port_in, self.tcp_port_out,
1933 proto=IP_PROTOS.tcp)
1934 self.nat44_add_static_mapping(self.pg0.remote_ip4, self.nat_addr,
1935 self.udp_port_in, self.udp_port_out,
1936 proto=IP_PROTOS.udp)
1937 self.nat44_add_static_mapping(self.pg0.remote_ip4, self.nat_addr,
1938 self.icmp_id_in, self.icmp_id_out,
1939 proto=IP_PROTOS.icmp)
1940 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
1941 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
1945 pkts = self.create_stream_in(self.pg0, self.pg1)
1946 self.pg0.add_stream(pkts)
1947 self.pg_enable_capture(self.pg_interfaces)
1949 capture = self.pg1.get_capture(len(pkts))
1950 self.verify_capture_out(capture)
1953 pkts = self.create_stream_out(self.pg1)
1954 self.pg1.add_stream(pkts)
1955 self.pg_enable_capture(self.pg_interfaces)
1957 capture = self.pg0.get_capture(len(pkts))
1958 self.verify_capture_in(capture, self.pg0)
1960 def test_static_with_port_out(self):
1961 """ 1:1 NAPT initialized from outside network """
1963 self.tcp_port_out = 30606
1964 self.udp_port_out = 30607
1965 self.icmp_id_out = 30608
1967 self.nat44_add_address(self.nat_addr)
1968 self.nat44_add_static_mapping(self.pg0.remote_ip4, self.nat_addr,
1969 self.tcp_port_in, self.tcp_port_out,
1970 proto=IP_PROTOS.tcp)
1971 self.nat44_add_static_mapping(self.pg0.remote_ip4, self.nat_addr,
1972 self.udp_port_in, self.udp_port_out,
1973 proto=IP_PROTOS.udp)
1974 self.nat44_add_static_mapping(self.pg0.remote_ip4, self.nat_addr,
1975 self.icmp_id_in, self.icmp_id_out,
1976 proto=IP_PROTOS.icmp)
1977 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
1978 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
1982 pkts = self.create_stream_out(self.pg1)
1983 self.pg1.add_stream(pkts)
1984 self.pg_enable_capture(self.pg_interfaces)
1986 capture = self.pg0.get_capture(len(pkts))
1987 self.verify_capture_in(capture, self.pg0)
1990 pkts = self.create_stream_in(self.pg0, self.pg1)
1991 self.pg0.add_stream(pkts)
1992 self.pg_enable_capture(self.pg_interfaces)
1994 capture = self.pg1.get_capture(len(pkts))
1995 self.verify_capture_out(capture)
1997 def test_static_vrf_aware(self):
1998 """ 1:1 NAT VRF awareness """
2000 nat_ip1 = "10.0.0.30"
2001 nat_ip2 = "10.0.0.40"
2002 self.tcp_port_out = 6303
2003 self.udp_port_out = 6304
2004 self.icmp_id_out = 6305
2006 self.nat44_add_static_mapping(self.pg4.remote_ip4, nat_ip1,
2008 self.nat44_add_static_mapping(self.pg0.remote_ip4, nat_ip2,
2010 self.vapi.nat44_interface_add_del_feature(self.pg3.sw_if_index,
2012 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
2013 self.vapi.nat44_interface_add_del_feature(self.pg4.sw_if_index)
2015 # inside interface VRF match NAT44 static mapping VRF
2016 pkts = self.create_stream_in(self.pg4, self.pg3)
2017 self.pg4.add_stream(pkts)
2018 self.pg_enable_capture(self.pg_interfaces)
2020 capture = self.pg3.get_capture(len(pkts))
2021 self.verify_capture_out(capture, nat_ip1, True)
2023 # inside interface VRF don't match NAT44 static mapping VRF (packets
2025 pkts = self.create_stream_in(self.pg0, self.pg3)
2026 self.pg0.add_stream(pkts)
2027 self.pg_enable_capture(self.pg_interfaces)
2029 self.pg3.assert_nothing_captured()
2031 def test_dynamic_to_static(self):
2032 """ Switch from dynamic translation to 1:1NAT """
2033 nat_ip = "10.0.0.10"
2034 self.tcp_port_out = 6303
2035 self.udp_port_out = 6304
2036 self.icmp_id_out = 6305
2038 self.nat44_add_address(self.nat_addr)
2039 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
2040 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
2044 pkts = self.create_stream_in(self.pg0, self.pg1)
2045 self.pg0.add_stream(pkts)
2046 self.pg_enable_capture(self.pg_interfaces)
2048 capture = self.pg1.get_capture(len(pkts))
2049 self.verify_capture_out(capture)
2052 self.nat44_add_static_mapping(self.pg0.remote_ip4, nat_ip)
2053 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4n, 0)
2054 self.assertEqual(len(sessions), 0)
2055 pkts = self.create_stream_in(self.pg0, self.pg1)
2056 self.pg0.add_stream(pkts)
2057 self.pg_enable_capture(self.pg_interfaces)
2059 capture = self.pg1.get_capture(len(pkts))
2060 self.verify_capture_out(capture, nat_ip, True)
2062 def test_identity_nat(self):
2063 """ Identity NAT """
2065 self.vapi.nat44_add_del_identity_mapping(ip=self.pg0.remote_ip4n)
2066 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
2067 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
2070 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
2071 IP(src=self.pg1.remote_ip4, dst=self.pg0.remote_ip4) /
2072 TCP(sport=12345, dport=56789))
2073 self.pg1.add_stream(p)
2074 self.pg_enable_capture(self.pg_interfaces)
2076 capture = self.pg0.get_capture(1)
2081 self.assertEqual(ip.dst, self.pg0.remote_ip4)
2082 self.assertEqual(ip.src, self.pg1.remote_ip4)
2083 self.assertEqual(tcp.dport, 56789)
2084 self.assertEqual(tcp.sport, 12345)
2085 self.assert_packet_checksums_valid(p)
2087 self.logger.error(ppp("Unexpected or invalid packet:", p))
2090 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4n, 0)
2091 self.assertEqual(len(sessions), 0)
2092 self.vapi.nat44_add_del_identity_mapping(ip=self.pg0.remote_ip4n,
2094 identity_mappings = self.vapi.nat44_identity_mapping_dump()
2095 self.assertEqual(len(identity_mappings), 2)
2097 def test_multiple_inside_interfaces(self):
2098 """ NAT44 multiple non-overlapping address space inside interfaces """
2100 self.nat44_add_address(self.nat_addr)
2101 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
2102 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index)
2103 self.vapi.nat44_interface_add_del_feature(self.pg3.sw_if_index,
2106 # between two NAT44 inside interfaces (no translation)
2107 pkts = self.create_stream_in(self.pg0, self.pg1)
2108 self.pg0.add_stream(pkts)
2109 self.pg_enable_capture(self.pg_interfaces)
2111 capture = self.pg1.get_capture(len(pkts))
2112 self.verify_capture_no_translation(capture, self.pg0, self.pg1)
2114 # from NAT44 inside to interface without NAT44 feature (no translation)
2115 pkts = self.create_stream_in(self.pg0, self.pg2)
2116 self.pg0.add_stream(pkts)
2117 self.pg_enable_capture(self.pg_interfaces)
2119 capture = self.pg2.get_capture(len(pkts))
2120 self.verify_capture_no_translation(capture, self.pg0, self.pg2)
2122 # in2out 1st interface
2123 pkts = self.create_stream_in(self.pg0, self.pg3)
2124 self.pg0.add_stream(pkts)
2125 self.pg_enable_capture(self.pg_interfaces)
2127 capture = self.pg3.get_capture(len(pkts))
2128 self.verify_capture_out(capture)
2130 # out2in 1st interface
2131 pkts = self.create_stream_out(self.pg3)
2132 self.pg3.add_stream(pkts)
2133 self.pg_enable_capture(self.pg_interfaces)
2135 capture = self.pg0.get_capture(len(pkts))
2136 self.verify_capture_in(capture, self.pg0)
2138 # in2out 2nd interface
2139 pkts = self.create_stream_in(self.pg1, self.pg3)
2140 self.pg1.add_stream(pkts)
2141 self.pg_enable_capture(self.pg_interfaces)
2143 capture = self.pg3.get_capture(len(pkts))
2144 self.verify_capture_out(capture)
2146 # out2in 2nd interface
2147 pkts = self.create_stream_out(self.pg3)
2148 self.pg3.add_stream(pkts)
2149 self.pg_enable_capture(self.pg_interfaces)
2151 capture = self.pg1.get_capture(len(pkts))
2152 self.verify_capture_in(capture, self.pg1)
2154 def test_inside_overlapping_interfaces(self):
2155 """ NAT44 multiple inside interfaces with overlapping address space """
2157 static_nat_ip = "10.0.0.10"
2158 self.nat44_add_address(self.nat_addr)
2159 self.vapi.nat44_interface_add_del_feature(self.pg3.sw_if_index,
2161 self.vapi.nat44_interface_add_del_feature(self.pg4.sw_if_index)
2162 self.vapi.nat44_interface_add_del_feature(self.pg5.sw_if_index)
2163 self.vapi.nat44_interface_add_del_feature(self.pg6.sw_if_index)
2164 self.nat44_add_static_mapping(self.pg6.remote_ip4, static_nat_ip,
2167 # between NAT44 inside interfaces with same VRF (no translation)
2168 pkts = self.create_stream_in(self.pg4, self.pg5)
2169 self.pg4.add_stream(pkts)
2170 self.pg_enable_capture(self.pg_interfaces)
2172 capture = self.pg5.get_capture(len(pkts))
2173 self.verify_capture_no_translation(capture, self.pg4, self.pg5)
2175 # between NAT44 inside interfaces with different VRF (hairpinning)
2176 p = (Ether(src=self.pg4.remote_mac, dst=self.pg4.local_mac) /
2177 IP(src=self.pg4.remote_ip4, dst=static_nat_ip) /
2178 TCP(sport=1234, dport=5678))
2179 self.pg4.add_stream(p)
2180 self.pg_enable_capture(self.pg_interfaces)
2182 capture = self.pg6.get_capture(1)
2187 self.assertEqual(ip.src, self.nat_addr)
2188 self.assertEqual(ip.dst, self.pg6.remote_ip4)
2189 self.assertNotEqual(tcp.sport, 1234)
2190 self.assertEqual(tcp.dport, 5678)
2192 self.logger.error(ppp("Unexpected or invalid packet:", p))
2195 # in2out 1st interface
2196 pkts = self.create_stream_in(self.pg4, self.pg3)
2197 self.pg4.add_stream(pkts)
2198 self.pg_enable_capture(self.pg_interfaces)
2200 capture = self.pg3.get_capture(len(pkts))
2201 self.verify_capture_out(capture)
2203 # out2in 1st interface
2204 pkts = self.create_stream_out(self.pg3)
2205 self.pg3.add_stream(pkts)
2206 self.pg_enable_capture(self.pg_interfaces)
2208 capture = self.pg4.get_capture(len(pkts))
2209 self.verify_capture_in(capture, self.pg4)
2211 # in2out 2nd interface
2212 pkts = self.create_stream_in(self.pg5, self.pg3)
2213 self.pg5.add_stream(pkts)
2214 self.pg_enable_capture(self.pg_interfaces)
2216 capture = self.pg3.get_capture(len(pkts))
2217 self.verify_capture_out(capture)
2219 # out2in 2nd interface
2220 pkts = self.create_stream_out(self.pg3)
2221 self.pg3.add_stream(pkts)
2222 self.pg_enable_capture(self.pg_interfaces)
2224 capture = self.pg5.get_capture(len(pkts))
2225 self.verify_capture_in(capture, self.pg5)
2228 addresses = self.vapi.nat44_address_dump()
2229 self.assertEqual(len(addresses), 1)
2230 sessions = self.vapi.nat44_user_session_dump(self.pg5.remote_ip4n, 10)
2231 self.assertEqual(len(sessions), 3)
2232 for session in sessions:
2233 self.assertFalse(session.is_static)
2234 self.assertEqual(session.inside_ip_address[0:4],
2235 self.pg5.remote_ip4n)
2236 self.assertEqual(session.outside_ip_address,
2237 addresses[0].ip_address)
2238 self.assertEqual(sessions[0].protocol, IP_PROTOS.tcp)
2239 self.assertEqual(sessions[1].protocol, IP_PROTOS.udp)
2240 self.assertEqual(sessions[2].protocol, IP_PROTOS.icmp)
2241 self.assertEqual(sessions[0].inside_port, self.tcp_port_in)
2242 self.assertEqual(sessions[1].inside_port, self.udp_port_in)
2243 self.assertEqual(sessions[2].inside_port, self.icmp_id_in)
2244 self.assertEqual(sessions[0].outside_port, self.tcp_port_out)
2245 self.assertEqual(sessions[1].outside_port, self.udp_port_out)
2246 self.assertEqual(sessions[2].outside_port, self.icmp_id_out)
2248 # in2out 3rd interface
2249 pkts = self.create_stream_in(self.pg6, self.pg3)
2250 self.pg6.add_stream(pkts)
2251 self.pg_enable_capture(self.pg_interfaces)
2253 capture = self.pg3.get_capture(len(pkts))
2254 self.verify_capture_out(capture, static_nat_ip, True)
2256 # out2in 3rd interface
2257 pkts = self.create_stream_out(self.pg3, static_nat_ip)
2258 self.pg3.add_stream(pkts)
2259 self.pg_enable_capture(self.pg_interfaces)
2261 capture = self.pg6.get_capture(len(pkts))
2262 self.verify_capture_in(capture, self.pg6)
2264 # general user and session dump verifications
2265 users = self.vapi.nat44_user_dump()
2266 self.assertGreaterEqual(len(users), 3)
2267 addresses = self.vapi.nat44_address_dump()
2268 self.assertEqual(len(addresses), 1)
2270 sessions = self.vapi.nat44_user_session_dump(user.ip_address,
2272 for session in sessions:
2273 self.assertEqual(user.ip_address, session.inside_ip_address)
2274 self.assertTrue(session.total_bytes > session.total_pkts > 0)
2275 self.assertTrue(session.protocol in
2276 [IP_PROTOS.tcp, IP_PROTOS.udp,
2278 self.assertFalse(session.ext_host_valid)
2281 sessions = self.vapi.nat44_user_session_dump(self.pg4.remote_ip4n, 10)
2282 self.assertGreaterEqual(len(sessions), 4)
2283 for session in sessions:
2284 self.assertFalse(session.is_static)
2285 self.assertEqual(session.inside_ip_address[0:4],
2286 self.pg4.remote_ip4n)
2287 self.assertEqual(session.outside_ip_address,
2288 addresses[0].ip_address)
2291 sessions = self.vapi.nat44_user_session_dump(self.pg6.remote_ip4n, 20)
2292 self.assertGreaterEqual(len(sessions), 3)
2293 for session in sessions:
2294 self.assertTrue(session.is_static)
2295 self.assertEqual(session.inside_ip_address[0:4],
2296 self.pg6.remote_ip4n)
2297 self.assertEqual(session.outside_ip_address,
2298 socket.inet_pton(socket.AF_INET, static_nat_ip))
2299 self.assertTrue(session.inside_port in
2300 [self.tcp_port_in, self.udp_port_in,
2303 def test_hairpinning(self):
2304 """ NAT44 hairpinning - 1:1 NAPT """
2306 host = self.pg0.remote_hosts[0]
2307 server = self.pg0.remote_hosts[1]
2310 server_in_port = 5678
2311 server_out_port = 8765
2313 self.nat44_add_address(self.nat_addr)
2314 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
2315 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
2317 # add static mapping for server
2318 self.nat44_add_static_mapping(server.ip4, self.nat_addr,
2319 server_in_port, server_out_port,
2320 proto=IP_PROTOS.tcp)
2322 # send packet from host to server
2323 p = (Ether(src=host.mac, dst=self.pg0.local_mac) /
2324 IP(src=host.ip4, dst=self.nat_addr) /
2325 TCP(sport=host_in_port, dport=server_out_port))
2326 self.pg0.add_stream(p)
2327 self.pg_enable_capture(self.pg_interfaces)
2329 capture = self.pg0.get_capture(1)
2334 self.assertEqual(ip.src, self.nat_addr)
2335 self.assertEqual(ip.dst, server.ip4)
2336 self.assertNotEqual(tcp.sport, host_in_port)
2337 self.assertEqual(tcp.dport, server_in_port)
2338 self.assert_packet_checksums_valid(p)
2339 host_out_port = tcp.sport
2341 self.logger.error(ppp("Unexpected or invalid packet:", p))
2344 # send reply from server to host
2345 p = (Ether(src=server.mac, dst=self.pg0.local_mac) /
2346 IP(src=server.ip4, dst=self.nat_addr) /
2347 TCP(sport=server_in_port, dport=host_out_port))
2348 self.pg0.add_stream(p)
2349 self.pg_enable_capture(self.pg_interfaces)
2351 capture = self.pg0.get_capture(1)
2356 self.assertEqual(ip.src, self.nat_addr)
2357 self.assertEqual(ip.dst, host.ip4)
2358 self.assertEqual(tcp.sport, server_out_port)
2359 self.assertEqual(tcp.dport, host_in_port)
2360 self.assert_packet_checksums_valid(p)
2362 self.logger.error(ppp("Unexpected or invalid packet:", p))
2365 def test_hairpinning2(self):
2366 """ NAT44 hairpinning - 1:1 NAT"""
2368 server1_nat_ip = "10.0.0.10"
2369 server2_nat_ip = "10.0.0.11"
2370 host = self.pg0.remote_hosts[0]
2371 server1 = self.pg0.remote_hosts[1]
2372 server2 = self.pg0.remote_hosts[2]
2373 server_tcp_port = 22
2374 server_udp_port = 20
2376 self.nat44_add_address(self.nat_addr)
2377 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
2378 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
2381 # add static mapping for servers
2382 self.nat44_add_static_mapping(server1.ip4, server1_nat_ip)
2383 self.nat44_add_static_mapping(server2.ip4, server2_nat_ip)
2387 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2388 IP(src=host.ip4, dst=server1_nat_ip) /
2389 TCP(sport=self.tcp_port_in, dport=server_tcp_port))
2391 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2392 IP(src=host.ip4, dst=server1_nat_ip) /
2393 UDP(sport=self.udp_port_in, dport=server_udp_port))
2395 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2396 IP(src=host.ip4, dst=server1_nat_ip) /
2397 ICMP(id=self.icmp_id_in, type='echo-request'))
2399 self.pg0.add_stream(pkts)
2400 self.pg_enable_capture(self.pg_interfaces)
2402 capture = self.pg0.get_capture(len(pkts))
2403 for packet in capture:
2405 self.assertEqual(packet[IP].src, self.nat_addr)
2406 self.assertEqual(packet[IP].dst, server1.ip4)
2407 if packet.haslayer(TCP):
2408 self.assertNotEqual(packet[TCP].sport, self.tcp_port_in)
2409 self.assertEqual(packet[TCP].dport, server_tcp_port)
2410 self.tcp_port_out = packet[TCP].sport
2411 self.assert_packet_checksums_valid(packet)
2412 elif packet.haslayer(UDP):
2413 self.assertNotEqual(packet[UDP].sport, self.udp_port_in)
2414 self.assertEqual(packet[UDP].dport, server_udp_port)
2415 self.udp_port_out = packet[UDP].sport
2417 self.assertNotEqual(packet[ICMP].id, self.icmp_id_in)
2418 self.icmp_id_out = packet[ICMP].id
2420 self.logger.error(ppp("Unexpected or invalid packet:", packet))
2425 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2426 IP(src=server1.ip4, dst=self.nat_addr) /
2427 TCP(sport=server_tcp_port, dport=self.tcp_port_out))
2429 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2430 IP(src=server1.ip4, dst=self.nat_addr) /
2431 UDP(sport=server_udp_port, dport=self.udp_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 ICMP(id=self.icmp_id_out, type='echo-reply'))
2437 self.pg0.add_stream(pkts)
2438 self.pg_enable_capture(self.pg_interfaces)
2440 capture = self.pg0.get_capture(len(pkts))
2441 for packet in capture:
2443 self.assertEqual(packet[IP].src, server1_nat_ip)
2444 self.assertEqual(packet[IP].dst, host.ip4)
2445 if packet.haslayer(TCP):
2446 self.assertEqual(packet[TCP].dport, self.tcp_port_in)
2447 self.assertEqual(packet[TCP].sport, server_tcp_port)
2448 self.assert_packet_checksums_valid(packet)
2449 elif packet.haslayer(UDP):
2450 self.assertEqual(packet[UDP].dport, self.udp_port_in)
2451 self.assertEqual(packet[UDP].sport, server_udp_port)
2453 self.assertEqual(packet[ICMP].id, self.icmp_id_in)
2455 self.logger.error(ppp("Unexpected or invalid packet:", packet))
2458 # server2 to server1
2460 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2461 IP(src=server2.ip4, dst=server1_nat_ip) /
2462 TCP(sport=self.tcp_port_in, dport=server_tcp_port))
2464 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2465 IP(src=server2.ip4, dst=server1_nat_ip) /
2466 UDP(sport=self.udp_port_in, dport=server_udp_port))
2468 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2469 IP(src=server2.ip4, dst=server1_nat_ip) /
2470 ICMP(id=self.icmp_id_in, type='echo-request'))
2472 self.pg0.add_stream(pkts)
2473 self.pg_enable_capture(self.pg_interfaces)
2475 capture = self.pg0.get_capture(len(pkts))
2476 for packet in capture:
2478 self.assertEqual(packet[IP].src, server2_nat_ip)
2479 self.assertEqual(packet[IP].dst, server1.ip4)
2480 if packet.haslayer(TCP):
2481 self.assertEqual(packet[TCP].sport, self.tcp_port_in)
2482 self.assertEqual(packet[TCP].dport, server_tcp_port)
2483 self.tcp_port_out = packet[TCP].sport
2484 self.assert_packet_checksums_valid(packet)
2485 elif packet.haslayer(UDP):
2486 self.assertEqual(packet[UDP].sport, self.udp_port_in)
2487 self.assertEqual(packet[UDP].dport, server_udp_port)
2488 self.udp_port_out = packet[UDP].sport
2490 self.assertEqual(packet[ICMP].id, self.icmp_id_in)
2491 self.icmp_id_out = packet[ICMP].id
2493 self.logger.error(ppp("Unexpected or invalid packet:", packet))
2496 # server1 to server2
2498 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2499 IP(src=server1.ip4, dst=server2_nat_ip) /
2500 TCP(sport=server_tcp_port, dport=self.tcp_port_out))
2502 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2503 IP(src=server1.ip4, dst=server2_nat_ip) /
2504 UDP(sport=server_udp_port, dport=self.udp_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 ICMP(id=self.icmp_id_out, type='echo-reply'))
2510 self.pg0.add_stream(pkts)
2511 self.pg_enable_capture(self.pg_interfaces)
2513 capture = self.pg0.get_capture(len(pkts))
2514 for packet in capture:
2516 self.assertEqual(packet[IP].src, server1_nat_ip)
2517 self.assertEqual(packet[IP].dst, server2.ip4)
2518 if packet.haslayer(TCP):
2519 self.assertEqual(packet[TCP].dport, self.tcp_port_in)
2520 self.assertEqual(packet[TCP].sport, server_tcp_port)
2521 self.assert_packet_checksums_valid(packet)
2522 elif packet.haslayer(UDP):
2523 self.assertEqual(packet[UDP].dport, self.udp_port_in)
2524 self.assertEqual(packet[UDP].sport, server_udp_port)
2526 self.assertEqual(packet[ICMP].id, self.icmp_id_in)
2528 self.logger.error(ppp("Unexpected or invalid packet:", packet))
2531 def test_max_translations_per_user(self):
2532 """ MAX translations per user - recycle the least recently used """
2534 self.nat44_add_address(self.nat_addr)
2535 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
2536 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
2539 # get maximum number of translations per user
2540 nat44_config = self.vapi.nat_show_config()
2542 # send more than maximum number of translations per user packets
2543 pkts_num = nat44_config.max_translations_per_user + 5
2545 for port in range(0, pkts_num):
2546 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2547 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
2548 TCP(sport=1025 + port))
2550 self.pg0.add_stream(pkts)
2551 self.pg_enable_capture(self.pg_interfaces)
2554 # verify number of translated packet
2555 self.pg1.get_capture(pkts_num)
2557 users = self.vapi.nat44_user_dump()
2559 if user.ip_address == self.pg0.remote_ip4n:
2560 self.assertEqual(user.nsessions,
2561 nat44_config.max_translations_per_user)
2562 self.assertEqual(user.nstaticsessions, 0)
2565 self.nat44_add_static_mapping(self.pg0.remote_ip4, self.nat_addr,
2567 proto=IP_PROTOS.tcp)
2568 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2569 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
2570 TCP(sport=tcp_port))
2571 self.pg0.add_stream(p)
2572 self.pg_enable_capture(self.pg_interfaces)
2574 self.pg1.get_capture(1)
2575 users = self.vapi.nat44_user_dump()
2577 if user.ip_address == self.pg0.remote_ip4n:
2578 self.assertEqual(user.nsessions,
2579 nat44_config.max_translations_per_user - 1)
2580 self.assertEqual(user.nstaticsessions, 1)
2582 def test_interface_addr(self):
2583 """ Acquire NAT44 addresses from interface """
2584 self.vapi.nat44_add_del_interface_addr(self.pg7.sw_if_index)
2586 # no address in NAT pool
2587 addresses = self.vapi.nat44_address_dump()
2588 self.assertEqual(0, len(addresses))
2590 # configure interface address and check NAT address pool
2591 self.pg7.config_ip4()
2592 addresses = self.vapi.nat44_address_dump()
2593 self.assertEqual(1, len(addresses))
2594 self.assertEqual(addresses[0].ip_address[0:4], self.pg7.local_ip4n)
2596 # remove interface address and check NAT address pool
2597 self.pg7.unconfig_ip4()
2598 addresses = self.vapi.nat44_address_dump()
2599 self.assertEqual(0, len(addresses))
2601 def test_interface_addr_static_mapping(self):
2602 """ Static mapping with addresses from interface """
2605 self.vapi.nat44_add_del_interface_addr(self.pg7.sw_if_index)
2606 self.nat44_add_static_mapping(
2608 external_sw_if_index=self.pg7.sw_if_index,
2611 # static mappings with external interface
2612 static_mappings = self.vapi.nat44_static_mapping_dump()
2613 self.assertEqual(1, len(static_mappings))
2614 self.assertEqual(self.pg7.sw_if_index,
2615 static_mappings[0].external_sw_if_index)
2616 self.assertEqual((static_mappings[0].tag).split(b'\0', 1)[0], tag)
2618 # configure interface address and check static mappings
2619 self.pg7.config_ip4()
2620 static_mappings = self.vapi.nat44_static_mapping_dump()
2621 self.assertEqual(2, len(static_mappings))
2623 for sm in static_mappings:
2624 if sm.external_sw_if_index == 0xFFFFFFFF:
2625 self.assertEqual(sm.external_ip_address[0:4],
2626 self.pg7.local_ip4n)
2627 self.assertEqual((sm.tag).split(b'\0', 1)[0], tag)
2629 self.assertTrue(resolved)
2631 # remove interface address and check static mappings
2632 self.pg7.unconfig_ip4()
2633 static_mappings = self.vapi.nat44_static_mapping_dump()
2634 self.assertEqual(1, len(static_mappings))
2635 self.assertEqual(self.pg7.sw_if_index,
2636 static_mappings[0].external_sw_if_index)
2637 self.assertEqual((static_mappings[0].tag).split(b'\0', 1)[0], tag)
2639 # configure interface address again and check static mappings
2640 self.pg7.config_ip4()
2641 static_mappings = self.vapi.nat44_static_mapping_dump()
2642 self.assertEqual(2, len(static_mappings))
2644 for sm in static_mappings:
2645 if sm.external_sw_if_index == 0xFFFFFFFF:
2646 self.assertEqual(sm.external_ip_address[0:4],
2647 self.pg7.local_ip4n)
2648 self.assertEqual((sm.tag).split(b'\0', 1)[0], tag)
2650 self.assertTrue(resolved)
2652 # remove static mapping
2653 self.nat44_add_static_mapping(
2655 external_sw_if_index=self.pg7.sw_if_index,
2658 static_mappings = self.vapi.nat44_static_mapping_dump()
2659 self.assertEqual(0, len(static_mappings))
2661 def test_interface_addr_identity_nat(self):
2662 """ Identity NAT with addresses from interface """
2665 self.vapi.nat44_add_del_interface_addr(self.pg7.sw_if_index)
2666 self.vapi.nat44_add_del_identity_mapping(
2667 sw_if_index=self.pg7.sw_if_index,
2669 protocol=IP_PROTOS.tcp,
2672 # identity mappings with external interface
2673 identity_mappings = self.vapi.nat44_identity_mapping_dump()
2674 self.assertEqual(1, len(identity_mappings))
2675 self.assertEqual(self.pg7.sw_if_index,
2676 identity_mappings[0].sw_if_index)
2678 # configure interface address and check identity mappings
2679 self.pg7.config_ip4()
2680 identity_mappings = self.vapi.nat44_identity_mapping_dump()
2682 self.assertEqual(2, len(identity_mappings))
2683 for sm in identity_mappings:
2684 if sm.sw_if_index == 0xFFFFFFFF:
2685 self.assertEqual(identity_mappings[0].ip_address,
2686 self.pg7.local_ip4n)
2687 self.assertEqual(port, identity_mappings[0].port)
2688 self.assertEqual(IP_PROTOS.tcp, identity_mappings[0].protocol)
2690 self.assertTrue(resolved)
2692 # remove interface address and check identity mappings
2693 self.pg7.unconfig_ip4()
2694 identity_mappings = self.vapi.nat44_identity_mapping_dump()
2695 self.assertEqual(1, len(identity_mappings))
2696 self.assertEqual(self.pg7.sw_if_index,
2697 identity_mappings[0].sw_if_index)
2699 def test_ipfix_nat44_sess(self):
2700 """ IPFIX logging NAT44 session created/deleted """
2701 self.ipfix_domain_id = 10
2702 self.ipfix_src_port = 20202
2703 collector_port = 30303
2704 bind_layers(UDP, IPFIX, dport=30303)
2705 self.nat44_add_address(self.nat_addr)
2706 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
2707 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
2709 self.vapi.set_ipfix_exporter(collector_address=self.pg3.remote_ip4n,
2710 src_address=self.pg3.local_ip4n,
2712 template_interval=10,
2713 collector_port=collector_port)
2714 self.vapi.nat_ipfix_enable_disable(domain_id=self.ipfix_domain_id,
2715 src_port=self.ipfix_src_port)
2717 pkts = self.create_stream_in(self.pg0, self.pg1)
2718 self.pg0.add_stream(pkts)
2719 self.pg_enable_capture(self.pg_interfaces)
2721 capture = self.pg1.get_capture(len(pkts))
2722 self.verify_capture_out(capture)
2723 self.nat44_add_address(self.nat_addr, is_add=0)
2724 self.vapi.cli("ipfix flush") # FIXME this should be an API call
2725 capture = self.pg3.get_capture(9)
2726 ipfix = IPFIXDecoder()
2727 # first load template
2729 self.assertTrue(p.haslayer(IPFIX))
2730 self.assertEqual(p[IP].src, self.pg3.local_ip4)
2731 self.assertEqual(p[IP].dst, self.pg3.remote_ip4)
2732 self.assertEqual(p[UDP].sport, self.ipfix_src_port)
2733 self.assertEqual(p[UDP].dport, collector_port)
2734 self.assertEqual(p[IPFIX].observationDomainID,
2735 self.ipfix_domain_id)
2736 if p.haslayer(Template):
2737 ipfix.add_template(p.getlayer(Template))
2738 # verify events in data set
2740 if p.haslayer(Data):
2741 data = ipfix.decode_data_set(p.getlayer(Set))
2742 self.verify_ipfix_nat44_ses(data)
2744 def test_ipfix_addr_exhausted(self):
2745 """ IPFIX logging NAT addresses exhausted """
2746 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
2747 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
2749 self.vapi.set_ipfix_exporter(collector_address=self.pg3.remote_ip4n,
2750 src_address=self.pg3.local_ip4n,
2752 template_interval=10)
2753 self.vapi.nat_ipfix_enable_disable(domain_id=self.ipfix_domain_id,
2754 src_port=self.ipfix_src_port)
2756 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
2757 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
2759 self.pg0.add_stream(p)
2760 self.pg_enable_capture(self.pg_interfaces)
2762 self.pg1.assert_nothing_captured()
2764 self.vapi.cli("ipfix flush") # FIXME this should be an API call
2765 capture = self.pg3.get_capture(9)
2766 ipfix = IPFIXDecoder()
2767 # first load template
2769 self.assertTrue(p.haslayer(IPFIX))
2770 self.assertEqual(p[IP].src, self.pg3.local_ip4)
2771 self.assertEqual(p[IP].dst, self.pg3.remote_ip4)
2772 self.assertEqual(p[UDP].sport, self.ipfix_src_port)
2773 self.assertEqual(p[UDP].dport, 4739)
2774 self.assertEqual(p[IPFIX].observationDomainID,
2775 self.ipfix_domain_id)
2776 if p.haslayer(Template):
2777 ipfix.add_template(p.getlayer(Template))
2778 # verify events in data set
2780 if p.haslayer(Data):
2781 data = ipfix.decode_data_set(p.getlayer(Set))
2782 self.verify_ipfix_addr_exhausted(data)
2784 @unittest.skipUnless(running_extended_tests, "part of extended tests")
2785 def test_ipfix_max_sessions(self):
2786 """ IPFIX logging maximum session entries exceeded """
2787 self.nat44_add_address(self.nat_addr)
2788 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
2789 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
2792 nat44_config = self.vapi.nat_show_config()
2793 max_sessions = 10 * nat44_config.translation_buckets
2796 for i in range(0, max_sessions):
2797 src = "10.10.%u.%u" % ((i & 0xFF00) >> 8, i & 0xFF)
2798 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2799 IP(src=src, dst=self.pg1.remote_ip4) /
2802 self.pg0.add_stream(pkts)
2803 self.pg_enable_capture(self.pg_interfaces)
2806 self.pg1.get_capture(max_sessions)
2807 self.vapi.set_ipfix_exporter(collector_address=self.pg3.remote_ip4n,
2808 src_address=self.pg3.local_ip4n,
2810 template_interval=10)
2811 self.vapi.nat_ipfix_enable_disable(domain_id=self.ipfix_domain_id,
2812 src_port=self.ipfix_src_port)
2814 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2815 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
2817 self.pg0.add_stream(p)
2818 self.pg_enable_capture(self.pg_interfaces)
2820 self.pg1.assert_nothing_captured()
2822 self.vapi.cli("ipfix flush") # FIXME this should be an API call
2823 capture = self.pg3.get_capture(9)
2824 ipfix = IPFIXDecoder()
2825 # first load template
2827 self.assertTrue(p.haslayer(IPFIX))
2828 self.assertEqual(p[IP].src, self.pg3.local_ip4)
2829 self.assertEqual(p[IP].dst, self.pg3.remote_ip4)
2830 self.assertEqual(p[UDP].sport, self.ipfix_src_port)
2831 self.assertEqual(p[UDP].dport, 4739)
2832 self.assertEqual(p[IPFIX].observationDomainID,
2833 self.ipfix_domain_id)
2834 if p.haslayer(Template):
2835 ipfix.add_template(p.getlayer(Template))
2836 # verify events in data set
2838 if p.haslayer(Data):
2839 data = ipfix.decode_data_set(p.getlayer(Set))
2840 self.verify_ipfix_max_sessions(data, max_sessions)
2842 def test_syslog_apmap(self):
2843 """ Test syslog address and port mapping creation and deletion """
2844 self.vapi.syslog_set_filter(SYSLOG_SEVERITY.INFO)
2845 self.vapi.syslog_set_sender(self.pg3.local_ip4n, self.pg3.remote_ip4n)
2846 self.nat44_add_address(self.nat_addr)
2847 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
2848 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
2851 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2852 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
2853 TCP(sport=self.tcp_port_in, dport=20))
2854 self.pg0.add_stream(p)
2855 self.pg_enable_capture(self.pg_interfaces)
2857 capture = self.pg1.get_capture(1)
2858 self.tcp_port_out = capture[0][TCP].sport
2859 capture = self.pg3.get_capture(1)
2860 self.verify_syslog_apmap(capture[0][Raw].load)
2862 self.pg_enable_capture(self.pg_interfaces)
2864 self.nat44_add_address(self.nat_addr, is_add=0)
2865 capture = self.pg3.get_capture(1)
2866 self.verify_syslog_apmap(capture[0][Raw].load, False)
2868 def test_pool_addr_fib(self):
2869 """ NAT44 add pool addresses to FIB """
2870 static_addr = '10.0.0.10'
2871 self.nat44_add_address(self.nat_addr)
2872 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
2873 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
2875 self.nat44_add_static_mapping(self.pg0.remote_ip4, static_addr)
2878 p = (Ether(src=self.pg1.remote_mac, dst='ff:ff:ff:ff:ff:ff') /
2879 ARP(op=ARP.who_has, pdst=self.nat_addr,
2880 psrc=self.pg1.remote_ip4, hwsrc=self.pg1.remote_mac))
2881 self.pg1.add_stream(p)
2882 self.pg_enable_capture(self.pg_interfaces)
2884 capture = self.pg1.get_capture(1)
2885 self.assertTrue(capture[0].haslayer(ARP))
2886 self.assertTrue(capture[0][ARP].op, ARP.is_at)
2889 p = (Ether(src=self.pg1.remote_mac, dst='ff:ff:ff:ff:ff:ff') /
2890 ARP(op=ARP.who_has, pdst=static_addr,
2891 psrc=self.pg1.remote_ip4, hwsrc=self.pg1.remote_mac))
2892 self.pg1.add_stream(p)
2893 self.pg_enable_capture(self.pg_interfaces)
2895 capture = self.pg1.get_capture(1)
2896 self.assertTrue(capture[0].haslayer(ARP))
2897 self.assertTrue(capture[0][ARP].op, ARP.is_at)
2899 # send ARP to non-NAT44 interface
2900 p = (Ether(src=self.pg2.remote_mac, dst='ff:ff:ff:ff:ff:ff') /
2901 ARP(op=ARP.who_has, pdst=self.nat_addr,
2902 psrc=self.pg2.remote_ip4, hwsrc=self.pg2.remote_mac))
2903 self.pg2.add_stream(p)
2904 self.pg_enable_capture(self.pg_interfaces)
2906 self.pg1.assert_nothing_captured()
2908 # remove addresses and verify
2909 self.nat44_add_address(self.nat_addr, is_add=0)
2910 self.nat44_add_static_mapping(self.pg0.remote_ip4, static_addr,
2913 p = (Ether(src=self.pg1.remote_mac, dst='ff:ff:ff:ff:ff:ff') /
2914 ARP(op=ARP.who_has, pdst=self.nat_addr,
2915 psrc=self.pg1.remote_ip4, hwsrc=self.pg1.remote_mac))
2916 self.pg1.add_stream(p)
2917 self.pg_enable_capture(self.pg_interfaces)
2919 self.pg1.assert_nothing_captured()
2921 p = (Ether(src=self.pg1.remote_mac, dst='ff:ff:ff:ff:ff:ff') /
2922 ARP(op=ARP.who_has, pdst=static_addr,
2923 psrc=self.pg1.remote_ip4, hwsrc=self.pg1.remote_mac))
2924 self.pg1.add_stream(p)
2925 self.pg_enable_capture(self.pg_interfaces)
2927 self.pg1.assert_nothing_captured()
2929 def test_vrf_mode(self):
2930 """ NAT44 tenant VRF aware address pool mode """
2934 nat_ip1 = "10.0.0.10"
2935 nat_ip2 = "10.0.0.11"
2937 self.pg0.unconfig_ip4()
2938 self.pg1.unconfig_ip4()
2939 self.vapi.ip_table_add_del(is_add=1, table_id=vrf_id1)
2940 self.vapi.ip_table_add_del(is_add=1, table_id=vrf_id2)
2941 self.pg0.set_table_ip4(vrf_id1)
2942 self.pg1.set_table_ip4(vrf_id2)
2943 self.pg0.config_ip4()
2944 self.pg1.config_ip4()
2945 self.pg0.resolve_arp()
2946 self.pg1.resolve_arp()
2948 self.nat44_add_address(nat_ip1, vrf_id=vrf_id1)
2949 self.nat44_add_address(nat_ip2, vrf_id=vrf_id2)
2950 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
2951 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index)
2952 self.vapi.nat44_interface_add_del_feature(self.pg2.sw_if_index,
2957 pkts = self.create_stream_in(self.pg0, self.pg2)
2958 self.pg0.add_stream(pkts)
2959 self.pg_enable_capture(self.pg_interfaces)
2961 capture = self.pg2.get_capture(len(pkts))
2962 self.verify_capture_out(capture, nat_ip1)
2965 pkts = self.create_stream_in(self.pg1, self.pg2)
2966 self.pg1.add_stream(pkts)
2967 self.pg_enable_capture(self.pg_interfaces)
2969 capture = self.pg2.get_capture(len(pkts))
2970 self.verify_capture_out(capture, nat_ip2)
2973 self.pg0.unconfig_ip4()
2974 self.pg1.unconfig_ip4()
2975 self.pg0.set_table_ip4(0)
2976 self.pg1.set_table_ip4(0)
2977 self.pg0.config_ip4()
2978 self.pg1.config_ip4()
2979 self.pg0.resolve_arp()
2980 self.pg1.resolve_arp()
2981 self.vapi.ip_table_add_del(is_add=0, table_id=vrf_id1)
2982 self.vapi.ip_table_add_del(is_add=0, table_id=vrf_id2)
2984 def test_vrf_feature_independent(self):
2985 """ NAT44 tenant VRF independent address pool mode """
2987 nat_ip1 = "10.0.0.10"
2988 nat_ip2 = "10.0.0.11"
2990 self.nat44_add_address(nat_ip1)
2991 self.nat44_add_address(nat_ip2, vrf_id=99)
2992 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
2993 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index)
2994 self.vapi.nat44_interface_add_del_feature(self.pg2.sw_if_index,
2998 pkts = self.create_stream_in(self.pg0, self.pg2)
2999 self.pg0.add_stream(pkts)
3000 self.pg_enable_capture(self.pg_interfaces)
3002 capture = self.pg2.get_capture(len(pkts))
3003 self.verify_capture_out(capture, nat_ip1)
3006 pkts = self.create_stream_in(self.pg1, self.pg2)
3007 self.pg1.add_stream(pkts)
3008 self.pg_enable_capture(self.pg_interfaces)
3010 capture = self.pg2.get_capture(len(pkts))
3011 self.verify_capture_out(capture, nat_ip1)
3013 def test_dynamic_ipless_interfaces(self):
3014 """ NAT44 interfaces without configured IP address """
3016 self.vapi.ip_neighbor_add_del(
3017 self.pg7.sw_if_index,
3018 self.pg7.remote_mac,
3019 self.pg7.remote_ip4,
3020 flags=(VppEnum.vl_api_ip_neighbor_flags_t.
3021 IP_API_NEIGHBOR_FLAG_STATIC))
3022 self.vapi.ip_neighbor_add_del(
3023 self.pg8.sw_if_index,
3024 self.pg8.remote_mac,
3025 self.pg8.remote_ip4,
3026 flags=(VppEnum.vl_api_ip_neighbor_flags_t.
3027 IP_API_NEIGHBOR_FLAG_STATIC))
3029 self.vapi.ip_add_del_route(dst_address=self.pg7.remote_ip4n,
3030 dst_address_length=32,
3031 next_hop_address=self.pg7.remote_ip4n,
3032 next_hop_sw_if_index=self.pg7.sw_if_index)
3033 self.vapi.ip_add_del_route(dst_address=self.pg8.remote_ip4n,
3034 dst_address_length=32,
3035 next_hop_address=self.pg8.remote_ip4n,
3036 next_hop_sw_if_index=self.pg8.sw_if_index)
3038 self.nat44_add_address(self.nat_addr)
3039 self.vapi.nat44_interface_add_del_feature(self.pg7.sw_if_index)
3040 self.vapi.nat44_interface_add_del_feature(self.pg8.sw_if_index,
3044 pkts = self.create_stream_in(self.pg7, self.pg8)
3045 self.pg7.add_stream(pkts)
3046 self.pg_enable_capture(self.pg_interfaces)
3048 capture = self.pg8.get_capture(len(pkts))
3049 self.verify_capture_out(capture)
3052 pkts = self.create_stream_out(self.pg8, self.nat_addr)
3053 self.pg8.add_stream(pkts)
3054 self.pg_enable_capture(self.pg_interfaces)
3056 capture = self.pg7.get_capture(len(pkts))
3057 self.verify_capture_in(capture, self.pg7)
3059 def test_static_ipless_interfaces(self):
3060 """ NAT44 interfaces without configured IP address - 1:1 NAT """
3062 self.vapi.ip_neighbor_add_del(
3063 self.pg7.sw_if_index,
3064 self.pg7.remote_mac,
3065 self.pg7.remote_ip4,
3066 flags=(VppEnum.vl_api_ip_neighbor_flags_t.
3067 IP_API_NEIGHBOR_FLAG_STATIC))
3068 self.vapi.ip_neighbor_add_del(
3069 self.pg8.sw_if_index,
3070 self.pg8.remote_mac,
3071 self.pg8.remote_ip4,
3072 flags=(VppEnum.vl_api_ip_neighbor_flags_t.
3073 IP_API_NEIGHBOR_FLAG_STATIC))
3075 self.vapi.ip_add_del_route(dst_address=self.pg7.remote_ip4n,
3076 dst_address_length=32,
3077 next_hop_address=self.pg7.remote_ip4n,
3078 next_hop_sw_if_index=self.pg7.sw_if_index)
3079 self.vapi.ip_add_del_route(dst_address=self.pg8.remote_ip4n,
3080 dst_address_length=32,
3081 next_hop_address=self.pg8.remote_ip4n,
3082 next_hop_sw_if_index=self.pg8.sw_if_index)
3084 self.nat44_add_static_mapping(self.pg7.remote_ip4, self.nat_addr)
3085 self.vapi.nat44_interface_add_del_feature(self.pg7.sw_if_index)
3086 self.vapi.nat44_interface_add_del_feature(self.pg8.sw_if_index,
3090 pkts = self.create_stream_out(self.pg8)
3091 self.pg8.add_stream(pkts)
3092 self.pg_enable_capture(self.pg_interfaces)
3094 capture = self.pg7.get_capture(len(pkts))
3095 self.verify_capture_in(capture, self.pg7)
3098 pkts = self.create_stream_in(self.pg7, self.pg8)
3099 self.pg7.add_stream(pkts)
3100 self.pg_enable_capture(self.pg_interfaces)
3102 capture = self.pg8.get_capture(len(pkts))
3103 self.verify_capture_out(capture, self.nat_addr, True)
3105 def test_static_with_port_ipless_interfaces(self):
3106 """ NAT44 interfaces without configured IP address - 1:1 NAPT """
3108 self.tcp_port_out = 30606
3109 self.udp_port_out = 30607
3110 self.icmp_id_out = 30608
3112 self.vapi.ip_neighbor_add_del(
3113 self.pg7.sw_if_index,
3114 self.pg7.remote_mac,
3115 self.pg7.remote_ip4,
3116 flags=(VppEnum.vl_api_ip_neighbor_flags_t.
3117 IP_API_NEIGHBOR_FLAG_STATIC))
3118 self.vapi.ip_neighbor_add_del(
3119 self.pg8.sw_if_index,
3120 self.pg8.remote_mac,
3121 self.pg8.remote_ip4,
3122 flags=(VppEnum.vl_api_ip_neighbor_flags_t.
3123 IP_API_NEIGHBOR_FLAG_STATIC))
3125 self.vapi.ip_add_del_route(dst_address=self.pg7.remote_ip4n,
3126 dst_address_length=32,
3127 next_hop_address=self.pg7.remote_ip4n,
3128 next_hop_sw_if_index=self.pg7.sw_if_index)
3129 self.vapi.ip_add_del_route(dst_address=self.pg8.remote_ip4n,
3130 dst_address_length=32,
3131 next_hop_address=self.pg8.remote_ip4n,
3132 next_hop_sw_if_index=self.pg8.sw_if_index)
3134 self.nat44_add_address(self.nat_addr)
3135 self.nat44_add_static_mapping(self.pg7.remote_ip4, self.nat_addr,
3136 self.tcp_port_in, self.tcp_port_out,
3137 proto=IP_PROTOS.tcp)
3138 self.nat44_add_static_mapping(self.pg7.remote_ip4, self.nat_addr,
3139 self.udp_port_in, self.udp_port_out,
3140 proto=IP_PROTOS.udp)
3141 self.nat44_add_static_mapping(self.pg7.remote_ip4, self.nat_addr,
3142 self.icmp_id_in, self.icmp_id_out,
3143 proto=IP_PROTOS.icmp)
3144 self.vapi.nat44_interface_add_del_feature(self.pg7.sw_if_index)
3145 self.vapi.nat44_interface_add_del_feature(self.pg8.sw_if_index,
3149 pkts = self.create_stream_out(self.pg8)
3150 self.pg8.add_stream(pkts)
3151 self.pg_enable_capture(self.pg_interfaces)
3153 capture = self.pg7.get_capture(len(pkts))
3154 self.verify_capture_in(capture, self.pg7)
3157 pkts = self.create_stream_in(self.pg7, self.pg8)
3158 self.pg7.add_stream(pkts)
3159 self.pg_enable_capture(self.pg_interfaces)
3161 capture = self.pg8.get_capture(len(pkts))
3162 self.verify_capture_out(capture)
3164 def test_static_unknown_proto(self):
3165 """ 1:1 NAT translate packet with unknown protocol """
3166 nat_ip = "10.0.0.10"
3167 self.nat44_add_static_mapping(self.pg0.remote_ip4, nat_ip)
3168 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
3169 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
3173 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
3174 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
3176 IP(src=self.pg2.remote_ip4, dst=self.pg3.remote_ip4) /
3177 TCP(sport=1234, dport=1234))
3178 self.pg0.add_stream(p)
3179 self.pg_enable_capture(self.pg_interfaces)
3181 p = self.pg1.get_capture(1)
3184 self.assertEqual(packet[IP].src, nat_ip)
3185 self.assertEqual(packet[IP].dst, self.pg1.remote_ip4)
3186 self.assertEqual(packet.haslayer(GRE), 1)
3187 self.assert_packet_checksums_valid(packet)
3189 self.logger.error(ppp("Unexpected or invalid packet:", packet))
3193 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
3194 IP(src=self.pg1.remote_ip4, dst=nat_ip) /
3196 IP(src=self.pg3.remote_ip4, dst=self.pg2.remote_ip4) /
3197 TCP(sport=1234, dport=1234))
3198 self.pg1.add_stream(p)
3199 self.pg_enable_capture(self.pg_interfaces)
3201 p = self.pg0.get_capture(1)
3204 self.assertEqual(packet[IP].src, self.pg1.remote_ip4)
3205 self.assertEqual(packet[IP].dst, self.pg0.remote_ip4)
3206 self.assertEqual(packet.haslayer(GRE), 1)
3207 self.assert_packet_checksums_valid(packet)
3209 self.logger.error(ppp("Unexpected or invalid packet:", packet))
3212 def test_hairpinning_static_unknown_proto(self):
3213 """ 1:1 NAT translate packet with unknown protocol - hairpinning """
3215 host = self.pg0.remote_hosts[0]
3216 server = self.pg0.remote_hosts[1]
3218 host_nat_ip = "10.0.0.10"
3219 server_nat_ip = "10.0.0.11"
3221 self.nat44_add_static_mapping(host.ip4, host_nat_ip)
3222 self.nat44_add_static_mapping(server.ip4, server_nat_ip)
3223 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
3224 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
3228 p = (Ether(dst=self.pg0.local_mac, src=host.mac) /
3229 IP(src=host.ip4, dst=server_nat_ip) /
3231 IP(src=self.pg2.remote_ip4, dst=self.pg3.remote_ip4) /
3232 TCP(sport=1234, dport=1234))
3233 self.pg0.add_stream(p)
3234 self.pg_enable_capture(self.pg_interfaces)
3236 p = self.pg0.get_capture(1)
3239 self.assertEqual(packet[IP].src, host_nat_ip)
3240 self.assertEqual(packet[IP].dst, server.ip4)
3241 self.assertEqual(packet.haslayer(GRE), 1)
3242 self.assert_packet_checksums_valid(packet)
3244 self.logger.error(ppp("Unexpected or invalid packet:", packet))
3248 p = (Ether(dst=self.pg0.local_mac, src=server.mac) /
3249 IP(src=server.ip4, dst=host_nat_ip) /
3251 IP(src=self.pg3.remote_ip4, dst=self.pg2.remote_ip4) /
3252 TCP(sport=1234, dport=1234))
3253 self.pg0.add_stream(p)
3254 self.pg_enable_capture(self.pg_interfaces)
3256 p = self.pg0.get_capture(1)
3259 self.assertEqual(packet[IP].src, server_nat_ip)
3260 self.assertEqual(packet[IP].dst, host.ip4)
3261 self.assertEqual(packet.haslayer(GRE), 1)
3262 self.assert_packet_checksums_valid(packet)
3264 self.logger.error(ppp("Unexpected or invalid packet:", packet))
3267 def test_output_feature(self):
3268 """ NAT44 interface output feature (in2out postrouting) """
3269 self.nat44_add_address(self.nat_addr)
3270 self.vapi.nat44_interface_add_del_output_feature(self.pg0.sw_if_index)
3271 self.vapi.nat44_interface_add_del_output_feature(self.pg1.sw_if_index)
3272 self.vapi.nat44_interface_add_del_output_feature(self.pg3.sw_if_index,
3276 pkts = self.create_stream_in(self.pg0, self.pg3)
3277 self.pg0.add_stream(pkts)
3278 self.pg_enable_capture(self.pg_interfaces)
3280 capture = self.pg3.get_capture(len(pkts))
3281 self.verify_capture_out(capture)
3284 pkts = self.create_stream_out(self.pg3)
3285 self.pg3.add_stream(pkts)
3286 self.pg_enable_capture(self.pg_interfaces)
3288 capture = self.pg0.get_capture(len(pkts))
3289 self.verify_capture_in(capture, self.pg0)
3291 # from non-NAT interface to NAT inside interface
3292 pkts = self.create_stream_in(self.pg2, self.pg0)
3293 self.pg2.add_stream(pkts)
3294 self.pg_enable_capture(self.pg_interfaces)
3296 capture = self.pg0.get_capture(len(pkts))
3297 self.verify_capture_no_translation(capture, self.pg2, self.pg0)
3299 def test_output_feature_vrf_aware(self):
3300 """ NAT44 interface output feature VRF aware (in2out postrouting) """
3301 nat_ip_vrf10 = "10.0.0.10"
3302 nat_ip_vrf20 = "10.0.0.20"
3304 self.vapi.ip_add_del_route(dst_address=self.pg3.remote_ip4n,
3305 dst_address_length=32,
3306 next_hop_address=self.pg3.remote_ip4n,
3307 next_hop_sw_if_index=self.pg3.sw_if_index,
3309 self.vapi.ip_add_del_route(dst_address=self.pg3.remote_ip4n,
3310 dst_address_length=32,
3311 next_hop_address=self.pg3.remote_ip4n,
3312 next_hop_sw_if_index=self.pg3.sw_if_index,
3315 self.nat44_add_address(nat_ip_vrf10, vrf_id=10)
3316 self.nat44_add_address(nat_ip_vrf20, vrf_id=20)
3317 self.vapi.nat44_interface_add_del_output_feature(self.pg4.sw_if_index)
3318 self.vapi.nat44_interface_add_del_output_feature(self.pg6.sw_if_index)
3319 self.vapi.nat44_interface_add_del_output_feature(self.pg3.sw_if_index,
3323 pkts = self.create_stream_in(self.pg4, self.pg3)
3324 self.pg4.add_stream(pkts)
3325 self.pg_enable_capture(self.pg_interfaces)
3327 capture = self.pg3.get_capture(len(pkts))
3328 self.verify_capture_out(capture, nat_ip=nat_ip_vrf10)
3331 pkts = self.create_stream_out(self.pg3, dst_ip=nat_ip_vrf10)
3332 self.pg3.add_stream(pkts)
3333 self.pg_enable_capture(self.pg_interfaces)
3335 capture = self.pg4.get_capture(len(pkts))
3336 self.verify_capture_in(capture, self.pg4)
3339 pkts = self.create_stream_in(self.pg6, self.pg3)
3340 self.pg6.add_stream(pkts)
3341 self.pg_enable_capture(self.pg_interfaces)
3343 capture = self.pg3.get_capture(len(pkts))
3344 self.verify_capture_out(capture, nat_ip=nat_ip_vrf20)
3347 pkts = self.create_stream_out(self.pg3, dst_ip=nat_ip_vrf20)
3348 self.pg3.add_stream(pkts)
3349 self.pg_enable_capture(self.pg_interfaces)
3351 capture = self.pg6.get_capture(len(pkts))
3352 self.verify_capture_in(capture, self.pg6)
3354 def test_output_feature_hairpinning(self):
3355 """ NAT44 interface output feature hairpinning (in2out postrouting) """
3356 host = self.pg0.remote_hosts[0]
3357 server = self.pg0.remote_hosts[1]
3360 server_in_port = 5678
3361 server_out_port = 8765
3363 self.nat44_add_address(self.nat_addr)
3364 self.vapi.nat44_interface_add_del_output_feature(self.pg0.sw_if_index)
3365 self.vapi.nat44_interface_add_del_output_feature(self.pg1.sw_if_index,
3368 # add static mapping for server
3369 self.nat44_add_static_mapping(server.ip4, self.nat_addr,
3370 server_in_port, server_out_port,
3371 proto=IP_PROTOS.tcp)
3373 # send packet from host to server
3374 p = (Ether(src=host.mac, dst=self.pg0.local_mac) /
3375 IP(src=host.ip4, dst=self.nat_addr) /
3376 TCP(sport=host_in_port, dport=server_out_port))
3377 self.pg0.add_stream(p)
3378 self.pg_enable_capture(self.pg_interfaces)
3380 capture = self.pg0.get_capture(1)
3385 self.assertEqual(ip.src, self.nat_addr)
3386 self.assertEqual(ip.dst, server.ip4)
3387 self.assertNotEqual(tcp.sport, host_in_port)
3388 self.assertEqual(tcp.dport, server_in_port)
3389 self.assert_packet_checksums_valid(p)
3390 host_out_port = tcp.sport
3392 self.logger.error(ppp("Unexpected or invalid packet:", p))
3395 # send reply from server to host
3396 p = (Ether(src=server.mac, dst=self.pg0.local_mac) /
3397 IP(src=server.ip4, dst=self.nat_addr) /
3398 TCP(sport=server_in_port, dport=host_out_port))
3399 self.pg0.add_stream(p)
3400 self.pg_enable_capture(self.pg_interfaces)
3402 capture = self.pg0.get_capture(1)
3407 self.assertEqual(ip.src, self.nat_addr)
3408 self.assertEqual(ip.dst, host.ip4)
3409 self.assertEqual(tcp.sport, server_out_port)
3410 self.assertEqual(tcp.dport, host_in_port)
3411 self.assert_packet_checksums_valid(p)
3413 self.logger.error(ppp("Unexpected or invalid packet:", p))
3416 def test_one_armed_nat44(self):
3417 """ One armed NAT44 """
3418 remote_host = self.pg9.remote_hosts[0]
3419 local_host = self.pg9.remote_hosts[1]
3422 self.nat44_add_address(self.nat_addr)
3423 self.vapi.nat44_interface_add_del_feature(self.pg9.sw_if_index)
3424 self.vapi.nat44_interface_add_del_feature(self.pg9.sw_if_index,
3428 p = (Ether(src=self.pg9.remote_mac, dst=self.pg9.local_mac) /
3429 IP(src=local_host.ip4, dst=remote_host.ip4) /
3430 TCP(sport=12345, dport=80))
3431 self.pg9.add_stream(p)
3432 self.pg_enable_capture(self.pg_interfaces)
3434 capture = self.pg9.get_capture(1)
3439 self.assertEqual(ip.src, self.nat_addr)
3440 self.assertEqual(ip.dst, remote_host.ip4)
3441 self.assertNotEqual(tcp.sport, 12345)
3442 external_port = tcp.sport
3443 self.assertEqual(tcp.dport, 80)
3444 self.assert_packet_checksums_valid(p)
3446 self.logger.error(ppp("Unexpected or invalid packet:", p))
3450 p = (Ether(src=self.pg9.remote_mac, dst=self.pg9.local_mac) /
3451 IP(src=remote_host.ip4, dst=self.nat_addr) /
3452 TCP(sport=80, dport=external_port))
3453 self.pg9.add_stream(p)
3454 self.pg_enable_capture(self.pg_interfaces)
3456 capture = self.pg9.get_capture(1)
3461 self.assertEqual(ip.src, remote_host.ip4)
3462 self.assertEqual(ip.dst, local_host.ip4)
3463 self.assertEqual(tcp.sport, 80)
3464 self.assertEqual(tcp.dport, 12345)
3465 self.assert_packet_checksums_valid(p)
3467 self.logger.error(ppp("Unexpected or invalid packet:", p))
3470 err = self.statistics.get_counter('/err/nat44-classify/next in2out')
3471 self.assertEqual(err, 1)
3472 err = self.statistics.get_counter('/err/nat44-classify/next out2in')
3473 self.assertEqual(err, 1)
3475 def test_del_session(self):
3476 """ Delete NAT44 session """
3477 self.nat44_add_address(self.nat_addr)
3478 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
3479 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
3482 pkts = self.create_stream_in(self.pg0, self.pg1)
3483 self.pg0.add_stream(pkts)
3484 self.pg_enable_capture(self.pg_interfaces)
3486 self.pg1.get_capture(len(pkts))
3488 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4n, 0)
3489 nsessions = len(sessions)
3491 self.vapi.nat44_del_session(sessions[0].inside_ip_address,
3492 sessions[0].inside_port,
3493 sessions[0].protocol)
3494 self.vapi.nat44_del_session(sessions[1].outside_ip_address,
3495 sessions[1].outside_port,
3496 sessions[1].protocol,
3499 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4n, 0)
3500 self.assertEqual(nsessions - len(sessions), 2)
3502 self.vapi.nat44_del_session(sessions[0].inside_ip_address,
3503 sessions[0].inside_port,
3504 sessions[0].protocol)
3506 self.verify_no_nat44_user()
3508 def test_set_get_reass(self):
3509 """ NAT44 set/get virtual fragmentation reassembly """
3510 reas_cfg1 = self.vapi.nat_get_reass()
3512 self.vapi.nat_set_reass(timeout=reas_cfg1.ip4_timeout + 5,
3513 max_reass=reas_cfg1.ip4_max_reass * 2,
3514 max_frag=reas_cfg1.ip4_max_frag * 2)
3516 reas_cfg2 = self.vapi.nat_get_reass()
3518 self.assertEqual(reas_cfg1.ip4_timeout + 5, reas_cfg2.ip4_timeout)
3519 self.assertEqual(reas_cfg1.ip4_max_reass * 2, reas_cfg2.ip4_max_reass)
3520 self.assertEqual(reas_cfg1.ip4_max_frag * 2, reas_cfg2.ip4_max_frag)
3522 self.vapi.nat_set_reass(drop_frag=1)
3523 self.assertTrue(self.vapi.nat_get_reass().ip4_drop_frag)
3525 def test_frag_in_order(self):
3526 """ NAT44 translate fragments arriving in order """
3528 self.nat44_add_address(self.nat_addr)
3529 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
3530 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
3533 self.frag_in_order(proto=IP_PROTOS.tcp)
3534 self.frag_in_order(proto=IP_PROTOS.udp)
3535 self.frag_in_order(proto=IP_PROTOS.icmp)
3537 def test_frag_forwarding(self):
3538 """ NAT44 forwarding fragment test """
3539 self.vapi.nat44_add_del_interface_addr(self.pg1.sw_if_index)
3540 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
3541 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
3543 self.vapi.nat44_forwarding_enable_disable(1)
3545 data = b"A" * 16 + b"B" * 16 + b"C" * 3
3546 pkts = self.create_stream_frag(self.pg1,
3547 self.pg0.remote_ip4,
3551 proto=IP_PROTOS.udp)
3552 self.pg1.add_stream(pkts)
3553 self.pg_enable_capture(self.pg_interfaces)
3555 frags = self.pg0.get_capture(len(pkts))
3556 p = self.reass_frags_and_verify(frags,
3557 self.pg1.remote_ip4,
3558 self.pg0.remote_ip4)
3559 self.assertEqual(p[UDP].sport, 4789)
3560 self.assertEqual(p[UDP].dport, 4789)
3561 self.assertEqual(data, p[Raw].load)
3563 def test_reass_hairpinning(self):
3564 """ NAT44 fragments hairpinning """
3566 self.server = self.pg0.remote_hosts[1]
3567 self.host_in_port = random.randint(1025, 65535)
3568 self.server_in_port = random.randint(1025, 65535)
3569 self.server_out_port = random.randint(1025, 65535)
3571 self.nat44_add_address(self.nat_addr)
3572 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
3573 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
3575 # add static mapping for server
3576 self.nat44_add_static_mapping(self.server.ip4, self.nat_addr,
3577 self.server_in_port,
3578 self.server_out_port,
3579 proto=IP_PROTOS.tcp)
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.udp)
3584 self.nat44_add_static_mapping(self.server.ip4, self.nat_addr)
3586 self.reass_hairpinning(proto=IP_PROTOS.tcp)
3587 self.reass_hairpinning(proto=IP_PROTOS.udp)
3588 self.reass_hairpinning(proto=IP_PROTOS.icmp)
3590 def test_frag_out_of_order(self):
3591 """ NAT44 translate fragments arriving out of order """
3593 self.nat44_add_address(self.nat_addr)
3594 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
3595 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
3598 self.frag_out_of_order(proto=IP_PROTOS.tcp)
3599 self.frag_out_of_order(proto=IP_PROTOS.udp)
3600 self.frag_out_of_order(proto=IP_PROTOS.icmp)
3602 def test_port_restricted(self):
3603 """ Port restricted NAT44 (MAP-E CE) """
3604 self.nat44_add_address(self.nat_addr)
3605 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
3606 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
3608 self.vapi.nat_set_addr_and_port_alloc_alg(alg=1,
3613 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
3614 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
3615 TCP(sport=4567, dport=22))
3616 self.pg0.add_stream(p)
3617 self.pg_enable_capture(self.pg_interfaces)
3619 capture = self.pg1.get_capture(1)
3624 self.assertEqual(ip.dst, self.pg1.remote_ip4)
3625 self.assertEqual(ip.src, self.nat_addr)
3626 self.assertEqual(tcp.dport, 22)
3627 self.assertNotEqual(tcp.sport, 4567)
3628 self.assertEqual((tcp.sport >> 6) & 63, 10)
3629 self.assert_packet_checksums_valid(p)
3631 self.logger.error(ppp("Unexpected or invalid packet:", p))
3634 def test_port_range(self):
3635 """ External address port range """
3636 self.nat44_add_address(self.nat_addr)
3637 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
3638 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
3640 self.vapi.nat_set_addr_and_port_alloc_alg(alg=2,
3645 for port in range(0, 5):
3646 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
3647 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
3648 TCP(sport=1125 + port))
3650 self.pg0.add_stream(pkts)
3651 self.pg_enable_capture(self.pg_interfaces)
3653 capture = self.pg1.get_capture(3)
3656 self.assertGreaterEqual(tcp.sport, 1025)
3657 self.assertLessEqual(tcp.sport, 1027)
3659 def test_ipfix_max_frags(self):
3660 """ IPFIX logging maximum fragments pending reassembly exceeded """
3661 self.nat44_add_address(self.nat_addr)
3662 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
3663 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
3665 self.vapi.nat_set_reass(max_frag=1)
3666 self.vapi.set_ipfix_exporter(collector_address=self.pg3.remote_ip4n,
3667 src_address=self.pg3.local_ip4n,
3669 template_interval=10)
3670 self.vapi.nat_ipfix_enable_disable(domain_id=self.ipfix_domain_id,
3671 src_port=self.ipfix_src_port)
3673 data = b"A" * 4 + b"B" * 16 + b"C" * 3
3674 self.tcp_port_in = random.randint(1025, 65535)
3675 pkts = self.create_stream_frag(self.pg0,
3676 self.pg1.remote_ip4,
3681 self.pg0.add_stream(pkts)
3682 self.pg_enable_capture(self.pg_interfaces)
3684 self.pg1.assert_nothing_captured()
3686 self.vapi.cli("ipfix flush") # FIXME this should be an API call
3687 capture = self.pg3.get_capture(9)
3688 ipfix = IPFIXDecoder()
3689 # first load template
3691 self.assertTrue(p.haslayer(IPFIX))
3692 self.assertEqual(p[IP].src, self.pg3.local_ip4)
3693 self.assertEqual(p[IP].dst, self.pg3.remote_ip4)
3694 self.assertEqual(p[UDP].sport, self.ipfix_src_port)
3695 self.assertEqual(p[UDP].dport, 4739)
3696 self.assertEqual(p[IPFIX].observationDomainID,
3697 self.ipfix_domain_id)
3698 if p.haslayer(Template):
3699 ipfix.add_template(p.getlayer(Template))
3700 # verify events in data set
3702 if p.haslayer(Data):
3703 data = ipfix.decode_data_set(p.getlayer(Set))
3704 self.verify_ipfix_max_fragments_ip4(data, 1,
3705 self.pg0.remote_ip4n)
3707 def test_multiple_outside_vrf(self):
3708 """ Multiple outside VRF """
3712 self.pg1.unconfig_ip4()
3713 self.pg2.unconfig_ip4()
3714 self.vapi.ip_table_add_del(is_add=1, table_id=vrf_id1)
3715 self.vapi.ip_table_add_del(is_add=1, table_id=vrf_id2)
3716 self.pg1.set_table_ip4(vrf_id1)
3717 self.pg2.set_table_ip4(vrf_id2)
3718 self.pg1.config_ip4()
3719 self.pg2.config_ip4()
3720 self.pg1.resolve_arp()
3721 self.pg2.resolve_arp()
3723 self.nat44_add_address(self.nat_addr)
3724 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
3725 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
3727 self.vapi.nat44_interface_add_del_feature(self.pg2.sw_if_index,
3732 pkts = self.create_stream_in(self.pg0, self.pg1)
3733 self.pg0.add_stream(pkts)
3734 self.pg_enable_capture(self.pg_interfaces)
3736 capture = self.pg1.get_capture(len(pkts))
3737 self.verify_capture_out(capture, self.nat_addr)
3739 pkts = self.create_stream_out(self.pg1, self.nat_addr)
3740 self.pg1.add_stream(pkts)
3741 self.pg_enable_capture(self.pg_interfaces)
3743 capture = self.pg0.get_capture(len(pkts))
3744 self.verify_capture_in(capture, self.pg0)
3746 self.tcp_port_in = 60303
3747 self.udp_port_in = 60304
3748 self.icmp_id_in = 60305
3751 pkts = self.create_stream_in(self.pg0, self.pg2)
3752 self.pg0.add_stream(pkts)
3753 self.pg_enable_capture(self.pg_interfaces)
3755 capture = self.pg2.get_capture(len(pkts))
3756 self.verify_capture_out(capture, self.nat_addr)
3758 pkts = self.create_stream_out(self.pg2, self.nat_addr)
3759 self.pg2.add_stream(pkts)
3760 self.pg_enable_capture(self.pg_interfaces)
3762 capture = self.pg0.get_capture(len(pkts))
3763 self.verify_capture_in(capture, self.pg0)
3766 self.pg1.unconfig_ip4()
3767 self.pg2.unconfig_ip4()
3768 self.pg1.set_table_ip4(0)
3769 self.pg2.set_table_ip4(0)
3770 self.pg1.config_ip4()
3771 self.pg2.config_ip4()
3772 self.pg1.resolve_arp()
3773 self.pg2.resolve_arp()
3775 @unittest.skipUnless(running_extended_tests, "part of extended tests")
3776 def test_session_timeout(self):
3777 """ NAT44 session timeouts """
3778 self.nat44_add_address(self.nat_addr)
3779 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
3780 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
3782 self.vapi.nat_set_timeouts(udp=5)
3786 for i in range(0, max_sessions):
3787 src = "10.10.%u.%u" % ((i & 0xFF00) >> 8, i & 0xFF)
3788 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
3789 IP(src=src, dst=self.pg1.remote_ip4) /
3790 UDP(sport=1025, dport=53))
3792 self.pg0.add_stream(pkts)
3793 self.pg_enable_capture(self.pg_interfaces)
3795 self.pg1.get_capture(max_sessions)
3800 for i in range(0, max_sessions):
3801 src = "10.10.%u.%u" % ((i & 0xFF00) >> 8, i & 0xFF)
3802 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
3803 IP(src=src, dst=self.pg1.remote_ip4) /
3804 UDP(sport=1026, dport=53))
3806 self.pg0.add_stream(pkts)
3807 self.pg_enable_capture(self.pg_interfaces)
3809 self.pg1.get_capture(max_sessions)
3812 users = self.vapi.nat44_user_dump()
3814 nsessions = nsessions + user.nsessions
3815 self.assertLess(nsessions, 2 * max_sessions)
3817 def test_mss_clamping(self):
3818 """ TCP MSS clamping """
3819 self.nat44_add_address(self.nat_addr)
3820 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
3821 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
3824 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
3825 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
3826 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
3827 flags="S", options=[('MSS', 1400)]))
3829 self.vapi.nat_set_mss_clamping(enable=1, mss_value=1000)
3830 self.pg0.add_stream(p)
3831 self.pg_enable_capture(self.pg_interfaces)
3833 capture = self.pg1.get_capture(1)
3834 # Negotiated MSS value greater than configured - changed
3835 self.verify_mss_value(capture[0], 1000)
3837 self.vapi.nat_set_mss_clamping(enable=0)
3838 self.pg0.add_stream(p)
3839 self.pg_enable_capture(self.pg_interfaces)
3841 capture = self.pg1.get_capture(1)
3842 # MSS clamping disabled - negotiated MSS unchanged
3843 self.verify_mss_value(capture[0], 1400)
3845 self.vapi.nat_set_mss_clamping(enable=1, mss_value=1500)
3846 self.pg0.add_stream(p)
3847 self.pg_enable_capture(self.pg_interfaces)
3849 capture = self.pg1.get_capture(1)
3850 # Negotiated MSS value smaller than configured - unchanged
3851 self.verify_mss_value(capture[0], 1400)
3853 @unittest.skipUnless(running_extended_tests, "part of extended tests")
3854 def test_ha_send(self):
3855 """ Send HA session synchronization events (active) """
3856 self.nat44_add_address(self.nat_addr)
3857 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
3858 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
3860 self.vapi.nat_ha_set_listener(self.pg3.local_ip4, port=12345)
3861 self.vapi.nat_ha_set_failover(self.pg3.remote_ip4, port=12346)
3862 bind_layers(UDP, HANATStateSync, sport=12345)
3865 pkts = self.create_stream_in(self.pg0, self.pg1)
3866 self.pg0.add_stream(pkts)
3867 self.pg_enable_capture(self.pg_interfaces)
3869 capture = self.pg1.get_capture(len(pkts))
3870 self.verify_capture_out(capture)
3871 # active send HA events
3872 self.vapi.nat_ha_flush()
3873 stats = self.statistics.get_counter('/nat44/ha/add-event-send')
3874 self.assertEqual(stats[0][0], 3)
3875 capture = self.pg3.get_capture(1)
3877 self.assert_packet_checksums_valid(p)
3881 hanat = p[HANATStateSync]
3883 self.logger.error(ppp("Invalid packet:", p))
3886 self.assertEqual(ip.src, self.pg3.local_ip4)
3887 self.assertEqual(ip.dst, self.pg3.remote_ip4)
3888 self.assertEqual(udp.sport, 12345)
3889 self.assertEqual(udp.dport, 12346)
3890 self.assertEqual(hanat.version, 1)
3891 self.assertEqual(hanat.thread_index, 0)
3892 self.assertEqual(hanat.count, 3)
3893 seq = hanat.sequence_number
3894 for event in hanat.events:
3895 self.assertEqual(event.event_type, 1)
3896 self.assertEqual(event.in_addr, self.pg0.remote_ip4)
3897 self.assertEqual(event.out_addr, self.nat_addr)
3898 self.assertEqual(event.fib_index, 0)
3900 # ACK received events
3901 ack = (Ether(dst=self.pg3.local_mac, src=self.pg3.remote_mac) /
3902 IP(src=self.pg3.remote_ip4, dst=self.pg3.local_ip4) /
3903 UDP(sport=12346, dport=12345) /
3904 HANATStateSync(sequence_number=seq, flags='ACK'))
3905 self.pg3.add_stream(ack)
3907 stats = self.statistics.get_counter('/nat44/ha/ack-recv')
3908 self.assertEqual(stats[0][0], 1)
3910 # delete one session
3911 self.pg_enable_capture(self.pg_interfaces)
3912 self.vapi.nat44_del_session(self.pg0.remote_ip4n, self.tcp_port_in,
3914 self.vapi.nat_ha_flush()
3915 stats = self.statistics.get_counter('/nat44/ha/del-event-send')
3916 self.assertEqual(stats[0][0], 1)
3917 capture = self.pg3.get_capture(1)
3920 hanat = p[HANATStateSync]
3922 self.logger.error(ppp("Invalid packet:", p))
3925 self.assertGreater(hanat.sequence_number, seq)
3927 # do not send ACK, active retry send HA event again
3928 self.pg_enable_capture(self.pg_interfaces)
3930 stats = self.statistics.get_counter('/nat44/ha/retry-count')
3931 self.assertEqual(stats[0][0], 3)
3932 stats = self.statistics.get_counter('/nat44/ha/missed-count')
3933 self.assertEqual(stats[0][0], 1)
3934 capture = self.pg3.get_capture(3)
3935 for packet in capture:
3936 self.assertEqual(packet, p)
3938 # session counters refresh
3939 pkts = self.create_stream_out(self.pg1)
3940 self.pg1.add_stream(pkts)
3941 self.pg_enable_capture(self.pg_interfaces)
3943 self.pg0.get_capture(2)
3944 self.vapi.nat_ha_flush()
3945 stats = self.statistics.get_counter('/nat44/ha/refresh-event-send')
3946 self.assertEqual(stats[0][0], 2)
3947 capture = self.pg3.get_capture(1)
3949 self.assert_packet_checksums_valid(p)
3953 hanat = p[HANATStateSync]
3955 self.logger.error(ppp("Invalid packet:", p))
3958 self.assertEqual(ip.src, self.pg3.local_ip4)
3959 self.assertEqual(ip.dst, self.pg3.remote_ip4)
3960 self.assertEqual(udp.sport, 12345)
3961 self.assertEqual(udp.dport, 12346)
3962 self.assertEqual(hanat.version, 1)
3963 self.assertEqual(hanat.count, 2)
3964 seq = hanat.sequence_number
3965 for event in hanat.events:
3966 self.assertEqual(event.event_type, 3)
3967 self.assertEqual(event.out_addr, self.nat_addr)
3968 self.assertEqual(event.fib_index, 0)
3969 self.assertEqual(event.total_pkts, 2)
3970 self.assertGreater(event.total_bytes, 0)
3972 ack = (Ether(dst=self.pg3.local_mac, src=self.pg3.remote_mac) /
3973 IP(src=self.pg3.remote_ip4, dst=self.pg3.local_ip4) /
3974 UDP(sport=12346, dport=12345) /
3975 HANATStateSync(sequence_number=seq, flags='ACK'))
3976 self.pg3.add_stream(ack)
3978 stats = self.statistics.get_counter('/nat44/ha/ack-recv')
3979 self.assertEqual(stats[0][0], 2)
3981 def test_ha_recv(self):
3982 """ Receive HA session synchronization events (passive) """
3983 self.nat44_add_address(self.nat_addr)
3984 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
3985 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
3987 self.vapi.nat_ha_set_listener(self.pg3.local_ip4, port=12345)
3988 bind_layers(UDP, HANATStateSync, sport=12345)
3990 self.tcp_port_out = random.randint(1025, 65535)
3991 self.udp_port_out = random.randint(1025, 65535)
3993 # send HA session add events to failover/passive
3994 p = (Ether(dst=self.pg3.local_mac, src=self.pg3.remote_mac) /
3995 IP(src=self.pg3.remote_ip4, dst=self.pg3.local_ip4) /
3996 UDP(sport=12346, dport=12345) /
3997 HANATStateSync(sequence_number=1, events=[
3998 Event(event_type='add', protocol='tcp',
3999 in_addr=self.pg0.remote_ip4, out_addr=self.nat_addr,
4000 in_port=self.tcp_port_in, out_port=self.tcp_port_out,
4001 eh_addr=self.pg1.remote_ip4,
4002 ehn_addr=self.pg1.remote_ip4,
4003 eh_port=self.tcp_external_port,
4004 ehn_port=self.tcp_external_port, fib_index=0),
4005 Event(event_type='add', protocol='udp',
4006 in_addr=self.pg0.remote_ip4, out_addr=self.nat_addr,
4007 in_port=self.udp_port_in, out_port=self.udp_port_out,
4008 eh_addr=self.pg1.remote_ip4,
4009 ehn_addr=self.pg1.remote_ip4,
4010 eh_port=self.udp_external_port,
4011 ehn_port=self.udp_external_port, fib_index=0)]))
4013 self.pg3.add_stream(p)
4014 self.pg_enable_capture(self.pg_interfaces)
4017 capture = self.pg3.get_capture(1)
4020 hanat = p[HANATStateSync]
4022 self.logger.error(ppp("Invalid packet:", p))
4025 self.assertEqual(hanat.sequence_number, 1)
4026 self.assertEqual(hanat.flags, 'ACK')
4027 self.assertEqual(hanat.version, 1)
4028 self.assertEqual(hanat.thread_index, 0)
4029 stats = self.statistics.get_counter('/nat44/ha/ack-send')
4030 self.assertEqual(stats[0][0], 1)
4031 stats = self.statistics.get_counter('/nat44/ha/add-event-recv')
4032 self.assertEqual(stats[0][0], 2)
4033 users = self.statistics.get_counter('/nat44/total-users')
4034 self.assertEqual(users[0][0], 1)
4035 sessions = self.statistics.get_counter('/nat44/total-sessions')
4036 self.assertEqual(sessions[0][0], 2)
4037 users = self.vapi.nat44_user_dump()
4038 self.assertEqual(len(users), 1)
4039 self.assertEqual(users[0].ip_address, self.pg0.remote_ip4n)
4040 # there should be 2 sessions created by HA
4041 sessions = self.vapi.nat44_user_session_dump(users[0].ip_address,
4043 self.assertEqual(len(sessions), 2)
4044 for session in sessions:
4045 self.assertEqual(session.inside_ip_address, self.pg0.remote_ip4n)
4046 self.assertEqual(session.outside_ip_address, self.nat_addr_n)
4047 self.assertIn(session.inside_port,
4048 [self.tcp_port_in, self.udp_port_in])
4049 self.assertIn(session.outside_port,
4050 [self.tcp_port_out, self.udp_port_out])
4051 self.assertIn(session.protocol, [IP_PROTOS.tcp, IP_PROTOS.udp])
4053 # send HA session delete event to failover/passive
4054 p = (Ether(dst=self.pg3.local_mac, src=self.pg3.remote_mac) /
4055 IP(src=self.pg3.remote_ip4, dst=self.pg3.local_ip4) /
4056 UDP(sport=12346, dport=12345) /
4057 HANATStateSync(sequence_number=2, events=[
4058 Event(event_type='del', protocol='udp',
4059 in_addr=self.pg0.remote_ip4, out_addr=self.nat_addr,
4060 in_port=self.udp_port_in, out_port=self.udp_port_out,
4061 eh_addr=self.pg1.remote_ip4,
4062 ehn_addr=self.pg1.remote_ip4,
4063 eh_port=self.udp_external_port,
4064 ehn_port=self.udp_external_port, fib_index=0)]))
4066 self.pg3.add_stream(p)
4067 self.pg_enable_capture(self.pg_interfaces)
4070 capture = self.pg3.get_capture(1)
4073 hanat = p[HANATStateSync]
4075 self.logger.error(ppp("Invalid packet:", p))
4078 self.assertEqual(hanat.sequence_number, 2)
4079 self.assertEqual(hanat.flags, 'ACK')
4080 self.assertEqual(hanat.version, 1)
4081 users = self.vapi.nat44_user_dump()
4082 self.assertEqual(len(users), 1)
4083 self.assertEqual(users[0].ip_address, self.pg0.remote_ip4n)
4084 # now we should have only 1 session, 1 deleted by HA
4085 sessions = self.vapi.nat44_user_session_dump(users[0].ip_address,
4087 self.assertEqual(len(sessions), 1)
4088 stats = self.statistics.get_counter('/nat44/ha/del-event-recv')
4089 self.assertEqual(stats[0][0], 1)
4091 stats = self.statistics.get_counter('/err/nat-ha/pkts-processed')
4092 self.assertEqual(stats, 2)
4094 # send HA session refresh event to failover/passive
4095 p = (Ether(dst=self.pg3.local_mac, src=self.pg3.remote_mac) /
4096 IP(src=self.pg3.remote_ip4, dst=self.pg3.local_ip4) /
4097 UDP(sport=12346, dport=12345) /
4098 HANATStateSync(sequence_number=3, events=[
4099 Event(event_type='refresh', protocol='tcp',
4100 in_addr=self.pg0.remote_ip4, out_addr=self.nat_addr,
4101 in_port=self.tcp_port_in, out_port=self.tcp_port_out,
4102 eh_addr=self.pg1.remote_ip4,
4103 ehn_addr=self.pg1.remote_ip4,
4104 eh_port=self.tcp_external_port,
4105 ehn_port=self.tcp_external_port, fib_index=0,
4106 total_bytes=1024, total_pkts=2)]))
4107 self.pg3.add_stream(p)
4108 self.pg_enable_capture(self.pg_interfaces)
4111 capture = self.pg3.get_capture(1)
4114 hanat = p[HANATStateSync]
4116 self.logger.error(ppp("Invalid packet:", p))
4119 self.assertEqual(hanat.sequence_number, 3)
4120 self.assertEqual(hanat.flags, 'ACK')
4121 self.assertEqual(hanat.version, 1)
4122 users = self.vapi.nat44_user_dump()
4123 self.assertEqual(len(users), 1)
4124 self.assertEqual(users[0].ip_address, self.pg0.remote_ip4n)
4125 sessions = self.vapi.nat44_user_session_dump(users[0].ip_address,
4127 self.assertEqual(len(sessions), 1)
4128 session = sessions[0]
4129 self.assertEqual(session.total_bytes, 1024)
4130 self.assertEqual(session.total_pkts, 2)
4131 stats = self.statistics.get_counter('/nat44/ha/refresh-event-recv')
4132 self.assertEqual(stats[0][0], 1)
4134 stats = self.statistics.get_counter('/err/nat-ha/pkts-processed')
4135 self.assertEqual(stats, 3)
4137 # send packet to test session created by HA
4138 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
4139 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
4140 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out))
4141 self.pg1.add_stream(p)
4142 self.pg_enable_capture(self.pg_interfaces)
4144 capture = self.pg0.get_capture(1)
4150 self.logger.error(ppp("Invalid packet:", p))
4153 self.assertEqual(ip.src, self.pg1.remote_ip4)
4154 self.assertEqual(ip.dst, self.pg0.remote_ip4)
4155 self.assertEqual(tcp.sport, self.tcp_external_port)
4156 self.assertEqual(tcp.dport, self.tcp_port_in)
4159 super(TestNAT44, self).tearDown()
4160 if not self.vpp_dead:
4161 self.logger.info(self.vapi.cli("show nat44 addresses"))
4162 self.logger.info(self.vapi.cli("show nat44 interfaces"))
4163 self.logger.info(self.vapi.cli("show nat44 static mappings"))
4164 self.logger.info(self.vapi.cli("show nat44 interface address"))
4165 self.logger.info(self.vapi.cli("show nat44 sessions detail"))
4166 self.logger.info(self.vapi.cli("show nat virtual-reassembly"))
4167 self.logger.info(self.vapi.cli("show nat44 hash tables detail"))
4168 self.logger.info(self.vapi.cli("show nat timeouts"))
4170 self.vapi.cli("show nat addr-port-assignment-alg"))
4171 self.logger.info(self.vapi.cli("show nat ha"))
4173 self.vapi.cli("clear logging")
4176 class TestNAT44EndpointDependent(MethodHolder):
4177 """ Endpoint-Dependent mapping and filtering test cases """
4180 def setUpConstants(cls):
4181 super(TestNAT44EndpointDependent, cls).setUpConstants()
4182 cls.vpp_cmdline.extend(["nat", "{", "endpoint-dependent", "}"])
4185 def setUpClass(cls):
4186 super(TestNAT44EndpointDependent, cls).setUpClass()
4187 cls.vapi.cli("set log class nat level debug")
4189 cls.tcp_port_in = 6303
4190 cls.tcp_port_out = 6303
4191 cls.udp_port_in = 6304
4192 cls.udp_port_out = 6304
4193 cls.icmp_id_in = 6305
4194 cls.icmp_id_out = 6305
4195 cls.nat_addr = '10.0.0.3'
4196 cls.nat_addr_n = socket.inet_pton(socket.AF_INET, cls.nat_addr)
4197 cls.ipfix_src_port = 4739
4198 cls.ipfix_domain_id = 1
4199 cls.tcp_external_port = 80
4201 cls.create_pg_interfaces(range(7))
4202 cls.interfaces = list(cls.pg_interfaces[0:3])
4204 for i in cls.interfaces:
4209 cls.pg0.generate_remote_hosts(3)
4210 cls.pg0.configure_ipv4_neighbors()
4214 cls.pg4.generate_remote_hosts(2)
4215 cls.pg4.config_ip4()
4216 ip_addr_n = socket.inet_pton(socket.AF_INET, "10.0.0.1")
4217 cls.vapi.sw_interface_add_del_address(
4218 sw_if_index=cls.pg4.sw_if_index, address=ip_addr_n,
4221 cls.pg4.resolve_arp()
4222 cls.pg4._remote_hosts[1]._ip4 = cls.pg4._remote_hosts[0]._ip4
4223 cls.pg4.resolve_arp()
4225 zero_ip4n = socket.inet_pton(socket.AF_INET, "0.0.0.0")
4226 cls.vapi.ip_table_add_del(is_add=1, table_id=1)
4228 cls.pg5._local_ip4 = "10.1.1.1"
4229 cls.pg5._local_ip4n = socket.inet_pton(socket.AF_INET,
4231 cls.pg5._remote_hosts[0]._ip4 = "10.1.1.2"
4232 cls.pg5._remote_hosts[0]._ip4n = socket.inet_pton(
4233 socket.AF_INET, cls.pg5.remote_ip4)
4234 cls.pg5.set_table_ip4(1)
4235 cls.pg5.config_ip4()
4237 cls.vapi.ip_add_del_route(dst_address=cls.pg5.remote_ip4n,
4238 dst_address_length=32,
4239 next_hop_address=zero_ip4n,
4240 next_hop_sw_if_index=cls.pg5.sw_if_index,
4243 cls.pg6._local_ip4 = "10.1.2.1"
4244 cls.pg6._local_ip4n = socket.inet_pton(socket.AF_INET,
4246 cls.pg6._remote_hosts[0]._ip4 = "10.1.2.2"
4247 cls.pg6._remote_hosts[0]._ip4n = socket.inet_pton(
4248 socket.AF_INET, cls.pg6.remote_ip4)
4249 cls.pg6.set_table_ip4(1)
4250 cls.pg6.config_ip4()
4252 cls.vapi.ip_add_del_route(dst_address=cls.pg6.remote_ip4n,
4253 dst_address_length=32,
4254 next_hop_address=zero_ip4n,
4255 next_hop_sw_if_index=cls.pg6.sw_if_index,
4258 cls.vapi.ip_add_del_route(dst_address=cls.pg6.remote_ip4n,
4259 dst_address_length=16,
4260 next_hop_address=zero_ip4n, table_id=0,
4261 next_hop_table_id=1)
4262 cls.vapi.ip_add_del_route(dst_address=zero_ip4n,
4263 dst_address_length=0,
4264 next_hop_address=zero_ip4n, table_id=1,
4265 next_hop_table_id=0)
4266 cls.vapi.ip_add_del_route(dst_address=zero_ip4n,
4267 dst_address_length=0,
4268 next_hop_address=cls.pg1.local_ip4n,
4269 next_hop_sw_if_index=cls.pg1.sw_if_index,
4272 cls.pg5.resolve_arp()
4273 cls.pg6.resolve_arp()
4276 super(TestNAT44EndpointDependent, cls).tearDownClass()
4279 def test_frag_in_order(self):
4280 """ NAT44 translate fragments arriving in order """
4281 self.nat44_add_address(self.nat_addr)
4282 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
4283 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
4285 self.frag_in_order(proto=IP_PROTOS.tcp)
4286 self.frag_in_order(proto=IP_PROTOS.udp)
4287 self.frag_in_order(proto=IP_PROTOS.icmp)
4289 def test_frag_in_order_dont_translate(self):
4290 """ NAT44 don't translate fragments arriving in order """
4291 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
4292 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
4294 self.vapi.nat44_forwarding_enable_disable(enable=True)
4295 self.frag_in_order(proto=IP_PROTOS.tcp, dont_translate=True)
4297 def test_frag_out_of_order(self):
4298 """ NAT44 translate fragments arriving out of order """
4299 self.nat44_add_address(self.nat_addr)
4300 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
4301 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
4303 self.frag_out_of_order(proto=IP_PROTOS.tcp)
4304 self.frag_out_of_order(proto=IP_PROTOS.udp)
4305 self.frag_out_of_order(proto=IP_PROTOS.icmp)
4307 def test_frag_out_of_order_dont_translate(self):
4308 """ NAT44 don't translate fragments arriving out of order """
4309 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
4310 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
4312 self.vapi.nat44_forwarding_enable_disable(enable=True)
4313 self.frag_out_of_order(proto=IP_PROTOS.tcp, dont_translate=True)
4315 def test_frag_in_order_in_plus_out(self):
4316 """ in+out interface fragments in order """
4317 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
4318 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index,
4320 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index)
4321 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
4324 self.server = self.pg1.remote_hosts[0]
4326 self.server_in_addr = self.server.ip4
4327 self.server_out_addr = '11.11.11.11'
4328 self.server_in_port = random.randint(1025, 65535)
4329 self.server_out_port = random.randint(1025, 65535)
4331 self.nat44_add_address(self.server_out_addr)
4333 # add static mappings for server
4334 self.nat44_add_static_mapping(self.server_in_addr,
4335 self.server_out_addr,
4336 self.server_in_port,
4337 self.server_out_port,
4338 proto=IP_PROTOS.tcp)
4339 self.nat44_add_static_mapping(self.server_in_addr,
4340 self.server_out_addr,
4341 self.server_in_port,
4342 self.server_out_port,
4343 proto=IP_PROTOS.udp)
4344 self.nat44_add_static_mapping(self.server_in_addr,
4345 self.server_out_addr,
4346 proto=IP_PROTOS.icmp)
4348 self.vapi.nat_set_reass(timeout=10)
4350 self.frag_in_order_in_plus_out(proto=IP_PROTOS.tcp)
4351 self.frag_in_order_in_plus_out(proto=IP_PROTOS.udp)
4352 self.frag_in_order_in_plus_out(proto=IP_PROTOS.icmp)
4354 def test_frag_out_of_order_in_plus_out(self):
4355 """ in+out interface fragments out of order """
4356 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
4357 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index,
4359 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index)
4360 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
4363 self.server = self.pg1.remote_hosts[0]
4365 self.server_in_addr = self.server.ip4
4366 self.server_out_addr = '11.11.11.11'
4367 self.server_in_port = random.randint(1025, 65535)
4368 self.server_out_port = random.randint(1025, 65535)
4370 self.nat44_add_address(self.server_out_addr)
4372 # add static mappings for server
4373 self.nat44_add_static_mapping(self.server_in_addr,
4374 self.server_out_addr,
4375 self.server_in_port,
4376 self.server_out_port,
4377 proto=IP_PROTOS.tcp)
4378 self.nat44_add_static_mapping(self.server_in_addr,
4379 self.server_out_addr,
4380 self.server_in_port,
4381 self.server_out_port,
4382 proto=IP_PROTOS.udp)
4383 self.nat44_add_static_mapping(self.server_in_addr,
4384 self.server_out_addr,
4385 proto=IP_PROTOS.icmp)
4387 self.vapi.nat_set_reass(timeout=10)
4389 self.frag_out_of_order_in_plus_out(proto=IP_PROTOS.tcp)
4390 self.frag_out_of_order_in_plus_out(proto=IP_PROTOS.udp)
4391 self.frag_out_of_order_in_plus_out(proto=IP_PROTOS.icmp)
4393 def test_reass_hairpinning(self):
4394 """ NAT44 fragments hairpinning """
4395 self.server = self.pg0.remote_hosts[1]
4396 self.host_in_port = random.randint(1025, 65535)
4397 self.server_in_port = random.randint(1025, 65535)
4398 self.server_out_port = random.randint(1025, 65535)
4400 self.nat44_add_address(self.nat_addr)
4401 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
4402 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
4404 # add static mapping for server
4405 self.nat44_add_static_mapping(self.server.ip4, self.nat_addr,
4406 self.server_in_port,
4407 self.server_out_port,
4408 proto=IP_PROTOS.tcp)
4409 self.nat44_add_static_mapping(self.server.ip4, self.nat_addr,
4410 self.server_in_port,
4411 self.server_out_port,
4412 proto=IP_PROTOS.udp)
4413 self.nat44_add_static_mapping(self.server.ip4, self.nat_addr)
4415 self.reass_hairpinning(proto=IP_PROTOS.tcp)
4416 self.reass_hairpinning(proto=IP_PROTOS.udp)
4417 self.reass_hairpinning(proto=IP_PROTOS.icmp)
4419 def test_dynamic(self):
4420 """ NAT44 dynamic translation test """
4422 self.nat44_add_address(self.nat_addr)
4423 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
4424 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
4427 nat_config = self.vapi.nat_show_config()
4428 self.assertEqual(1, nat_config.endpoint_dependent)
4431 tcpn = self.statistics.get_counter(
4432 '/err/nat44-ed-in2out-slowpath/TCP packets')
4433 udpn = self.statistics.get_counter(
4434 '/err/nat44-ed-in2out-slowpath/UDP packets')
4435 icmpn = self.statistics.get_counter(
4436 '/err/nat44-ed-in2out-slowpath/ICMP packets')
4437 totaln = self.statistics.get_counter(
4438 '/err/nat44-ed-in2out-slowpath/good in2out packets processed')
4440 pkts = self.create_stream_in(self.pg0, self.pg1)
4441 self.pg0.add_stream(pkts)
4442 self.pg_enable_capture(self.pg_interfaces)
4444 capture = self.pg1.get_capture(len(pkts))
4445 self.verify_capture_out(capture)
4447 err = self.statistics.get_counter(
4448 '/err/nat44-ed-in2out-slowpath/TCP packets')
4449 self.assertEqual(err - tcpn, 1)
4450 err = self.statistics.get_counter(
4451 '/err/nat44-ed-in2out-slowpath/UDP packets')
4452 self.assertEqual(err - udpn, 1)
4453 err = self.statistics.get_counter(
4454 '/err/nat44-ed-in2out-slowpath/ICMP packets')
4455 self.assertEqual(err - icmpn, 1)
4456 err = self.statistics.get_counter(
4457 '/err/nat44-ed-in2out-slowpath/good in2out packets processed')
4458 self.assertEqual(err - totaln, 3)
4461 tcpn = self.statistics.get_counter('/err/nat44-ed-out2in/TCP packets')
4462 udpn = self.statistics.get_counter('/err/nat44-ed-out2in/UDP packets')
4463 icmpn = self.statistics.get_counter(
4464 '/err/nat44-ed-out2in-slowpath/ICMP packets')
4465 totaln = self.statistics.get_counter(
4466 '/err/nat44-ed-out2in/good out2in packets processed')
4468 pkts = self.create_stream_out(self.pg1)
4469 self.pg1.add_stream(pkts)
4470 self.pg_enable_capture(self.pg_interfaces)
4472 capture = self.pg0.get_capture(len(pkts))
4473 self.verify_capture_in(capture, self.pg0)
4475 err = self.statistics.get_counter('/err/nat44-ed-out2in/TCP packets')
4476 self.assertEqual(err - tcpn, 1)
4477 err = self.statistics.get_counter('/err/nat44-ed-out2in/UDP packets')
4478 self.assertEqual(err - udpn, 1)
4479 err = self.statistics.get_counter(
4480 '/err/nat44-ed-out2in-slowpath/ICMP packets')
4481 self.assertEqual(err - icmpn, 1)
4482 err = self.statistics.get_counter(
4483 '/err/nat44-ed-out2in/good out2in packets processed')
4484 self.assertEqual(err - totaln, 2)
4486 users = self.statistics.get_counter('/nat44/total-users')
4487 self.assertEqual(users[0][0], 1)
4488 sessions = self.statistics.get_counter('/nat44/total-sessions')
4489 self.assertEqual(sessions[0][0], 3)
4491 def test_forwarding(self):
4492 """ NAT44 forwarding test """
4494 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
4495 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
4497 self.vapi.nat44_forwarding_enable_disable(1)
4499 real_ip = self.pg0.remote_ip4n
4500 alias_ip = self.nat_addr_n
4501 self.vapi.nat44_add_del_static_mapping(local_ip=real_ip,
4502 external_ip=alias_ip)
4505 # in2out - static mapping match
4507 pkts = self.create_stream_out(self.pg1)
4508 self.pg1.add_stream(pkts)
4509 self.pg_enable_capture(self.pg_interfaces)
4511 capture = self.pg0.get_capture(len(pkts))
4512 self.verify_capture_in(capture, self.pg0)
4514 pkts = self.create_stream_in(self.pg0, self.pg1)
4515 self.pg0.add_stream(pkts)
4516 self.pg_enable_capture(self.pg_interfaces)
4518 capture = self.pg1.get_capture(len(pkts))
4519 self.verify_capture_out(capture, same_port=True)
4521 # in2out - no static mapping match
4523 host0 = self.pg0.remote_hosts[0]
4524 self.pg0.remote_hosts[0] = self.pg0.remote_hosts[1]
4526 pkts = self.create_stream_out(self.pg1,
4527 dst_ip=self.pg0.remote_ip4,
4528 use_inside_ports=True)
4529 self.pg1.add_stream(pkts)
4530 self.pg_enable_capture(self.pg_interfaces)
4532 capture = self.pg0.get_capture(len(pkts))
4533 self.verify_capture_in(capture, self.pg0)
4535 pkts = self.create_stream_in(self.pg0, self.pg1)
4536 self.pg0.add_stream(pkts)
4537 self.pg_enable_capture(self.pg_interfaces)
4539 capture = self.pg1.get_capture(len(pkts))
4540 self.verify_capture_out(capture, nat_ip=self.pg0.remote_ip4,
4543 self.pg0.remote_hosts[0] = host0
4545 user = self.pg0.remote_hosts[1]
4546 sessions = self.vapi.nat44_user_session_dump(user.ip4n, 0)
4547 self.assertEqual(len(sessions), 3)
4548 self.assertTrue(sessions[0].ext_host_valid)
4549 self.vapi.nat44_del_session(
4550 sessions[0].inside_ip_address,
4551 sessions[0].inside_port,
4552 sessions[0].protocol,
4553 ext_host_address=sessions[0].ext_host_address,
4554 ext_host_port=sessions[0].ext_host_port)
4555 sessions = self.vapi.nat44_user_session_dump(user.ip4n, 0)
4556 self.assertEqual(len(sessions), 2)
4559 self.vapi.nat44_forwarding_enable_disable(0)
4560 self.vapi.nat44_add_del_static_mapping(local_ip=real_ip,
4561 external_ip=alias_ip,
4564 def test_static_lb(self):
4565 """ NAT44 local service load balancing """
4566 external_addr_n = socket.inet_pton(socket.AF_INET, self.nat_addr)
4569 server1 = self.pg0.remote_hosts[0]
4570 server2 = self.pg0.remote_hosts[1]
4572 locals = [{'addr': server1.ip4n,
4576 {'addr': server2.ip4n,
4581 self.nat44_add_address(self.nat_addr)
4582 self.vapi.nat44_add_del_lb_static_mapping(external_addr_n,
4585 local_num=len(locals),
4587 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
4588 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
4591 # from client to service
4592 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
4593 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
4594 TCP(sport=12345, dport=external_port))
4595 self.pg1.add_stream(p)
4596 self.pg_enable_capture(self.pg_interfaces)
4598 capture = self.pg0.get_capture(1)
4604 self.assertIn(ip.dst, [server1.ip4, server2.ip4])
4605 if ip.dst == server1.ip4:
4609 self.assertEqual(tcp.dport, local_port)
4610 self.assert_packet_checksums_valid(p)
4612 self.logger.error(ppp("Unexpected or invalid packet:", p))
4615 # from service back to client
4616 p = (Ether(src=server.mac, dst=self.pg0.local_mac) /
4617 IP(src=server.ip4, dst=self.pg1.remote_ip4) /
4618 TCP(sport=local_port, dport=12345))
4619 self.pg0.add_stream(p)
4620 self.pg_enable_capture(self.pg_interfaces)
4622 capture = self.pg1.get_capture(1)
4627 self.assertEqual(ip.src, self.nat_addr)
4628 self.assertEqual(tcp.sport, external_port)
4629 self.assert_packet_checksums_valid(p)
4631 self.logger.error(ppp("Unexpected or invalid packet:", p))
4634 sessions = self.vapi.nat44_user_session_dump(server.ip4n, 0)
4635 self.assertEqual(len(sessions), 1)
4636 self.assertTrue(sessions[0].ext_host_valid)
4637 self.vapi.nat44_del_session(
4638 sessions[0].inside_ip_address,
4639 sessions[0].inside_port,
4640 sessions[0].protocol,
4641 ext_host_address=sessions[0].ext_host_address,
4642 ext_host_port=sessions[0].ext_host_port)
4643 sessions = self.vapi.nat44_user_session_dump(server.ip4n, 0)
4644 self.assertEqual(len(sessions), 0)
4646 @unittest.skipUnless(running_extended_tests, "part of extended tests")
4647 def test_static_lb_multi_clients(self):
4648 """ NAT44 local service load balancing - multiple clients"""
4650 external_addr_n = socket.inet_pton(socket.AF_INET, self.nat_addr)
4653 server1 = self.pg0.remote_hosts[0]
4654 server2 = self.pg0.remote_hosts[1]
4655 server3 = self.pg0.remote_hosts[2]
4657 locals = [{'addr': server1.ip4n,
4661 {'addr': server2.ip4n,
4666 self.nat44_add_address(self.nat_addr)
4667 self.vapi.nat44_add_del_lb_static_mapping(external_addr_n,
4670 local_num=len(locals),
4672 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
4673 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
4678 clients = ip4_range(self.pg1.remote_ip4, 10, 50)
4680 for client in clients:
4681 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
4682 IP(src=client, dst=self.nat_addr) /
4683 TCP(sport=12345, dport=external_port))
4685 self.pg1.add_stream(pkts)
4686 self.pg_enable_capture(self.pg_interfaces)
4688 capture = self.pg0.get_capture(len(pkts))
4690 if p[IP].dst == server1.ip4:
4694 self.assertGreater(server1_n, server2_n)
4697 self.vapi.nat44_lb_static_mapping_add_del_local(external_addr_n,
4706 clients = ip4_range(self.pg1.remote_ip4, 60, 110)
4708 for client in clients:
4709 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
4710 IP(src=client, dst=self.nat_addr) /
4711 TCP(sport=12346, dport=external_port))
4713 self.assertGreater(len(pkts), 0)
4714 self.pg1.add_stream(pkts)
4715 self.pg_enable_capture(self.pg_interfaces)
4717 capture = self.pg0.get_capture(len(pkts))
4719 if p[IP].dst == server1.ip4:
4721 elif p[IP].dst == server2.ip4:
4725 self.assertGreater(server1_n, 0)
4726 self.assertGreater(server2_n, 0)
4727 self.assertGreater(server3_n, 0)
4729 # remove one back-end
4730 self.vapi.nat44_lb_static_mapping_add_del_local(external_addr_n,
4740 self.pg1.add_stream(pkts)
4741 self.pg_enable_capture(self.pg_interfaces)
4743 capture = self.pg0.get_capture(len(pkts))
4745 if p[IP].dst == server1.ip4:
4747 elif p[IP].dst == server2.ip4:
4751 self.assertGreater(server1_n, 0)
4752 self.assertEqual(server2_n, 0)
4753 self.assertGreater(server3_n, 0)
4755 def test_static_lb_2(self):
4756 """ NAT44 local service load balancing (asymmetrical rule) """
4757 external_addr_n = socket.inet_pton(socket.AF_INET, self.nat_addr)
4760 server1 = self.pg0.remote_hosts[0]
4761 server2 = self.pg0.remote_hosts[1]
4763 locals = [{'addr': server1.ip4n,
4767 {'addr': server2.ip4n,
4772 self.vapi.nat44_forwarding_enable_disable(1)
4773 self.vapi.nat44_add_del_lb_static_mapping(external_addr_n,
4777 local_num=len(locals),
4779 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
4780 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
4783 # from client to service
4784 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
4785 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
4786 TCP(sport=12345, dport=external_port))
4787 self.pg1.add_stream(p)
4788 self.pg_enable_capture(self.pg_interfaces)
4790 capture = self.pg0.get_capture(1)
4796 self.assertIn(ip.dst, [server1.ip4, server2.ip4])
4797 if ip.dst == server1.ip4:
4801 self.assertEqual(tcp.dport, local_port)
4802 self.assert_packet_checksums_valid(p)
4804 self.logger.error(ppp("Unexpected or invalid packet:", p))
4807 # from service back to client
4808 p = (Ether(src=server.mac, dst=self.pg0.local_mac) /
4809 IP(src=server.ip4, dst=self.pg1.remote_ip4) /
4810 TCP(sport=local_port, dport=12345))
4811 self.pg0.add_stream(p)
4812 self.pg_enable_capture(self.pg_interfaces)
4814 capture = self.pg1.get_capture(1)
4819 self.assertEqual(ip.src, self.nat_addr)
4820 self.assertEqual(tcp.sport, external_port)
4821 self.assert_packet_checksums_valid(p)
4823 self.logger.error(ppp("Unexpected or invalid packet:", p))
4826 # from client to server (no translation)
4827 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
4828 IP(src=self.pg1.remote_ip4, dst=server1.ip4) /
4829 TCP(sport=12346, dport=local_port))
4830 self.pg1.add_stream(p)
4831 self.pg_enable_capture(self.pg_interfaces)
4833 capture = self.pg0.get_capture(1)
4839 self.assertEqual(ip.dst, server1.ip4)
4840 self.assertEqual(tcp.dport, local_port)
4841 self.assert_packet_checksums_valid(p)
4843 self.logger.error(ppp("Unexpected or invalid packet:", p))
4846 # from service back to client (no translation)
4847 p = (Ether(src=server1.mac, dst=self.pg0.local_mac) /
4848 IP(src=server1.ip4, dst=self.pg1.remote_ip4) /
4849 TCP(sport=local_port, dport=12346))
4850 self.pg0.add_stream(p)
4851 self.pg_enable_capture(self.pg_interfaces)
4853 capture = self.pg1.get_capture(1)
4858 self.assertEqual(ip.src, server1.ip4)
4859 self.assertEqual(tcp.sport, local_port)
4860 self.assert_packet_checksums_valid(p)
4862 self.logger.error(ppp("Unexpected or invalid packet:", p))
4865 def test_lb_affinity(self):
4866 """ NAT44 local service load balancing affinity """
4867 external_addr_n = socket.inet_pton(socket.AF_INET, self.nat_addr)
4870 server1 = self.pg0.remote_hosts[0]
4871 server2 = self.pg0.remote_hosts[1]
4873 locals = [{'addr': server1.ip4n,
4877 {'addr': server2.ip4n,
4882 self.nat44_add_address(self.nat_addr)
4883 self.vapi.nat44_add_del_lb_static_mapping(external_addr_n,
4887 local_num=len(locals),
4889 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
4890 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
4893 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
4894 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
4895 TCP(sport=1025, dport=external_port))
4896 self.pg1.add_stream(p)
4897 self.pg_enable_capture(self.pg_interfaces)
4899 capture = self.pg0.get_capture(1)
4900 backend = capture[0][IP].dst
4902 sessions = self.vapi.nat44_user_session_dump(
4903 socket.inet_pton(socket.AF_INET, backend), 0)
4904 self.assertEqual(len(sessions), 1)
4905 self.assertTrue(sessions[0].ext_host_valid)
4906 self.vapi.nat44_del_session(
4907 sessions[0].inside_ip_address,
4908 sessions[0].inside_port,
4909 sessions[0].protocol,
4910 ext_host_address=sessions[0].ext_host_address,
4911 ext_host_port=sessions[0].ext_host_port)
4914 for port in range(1030, 1100):
4915 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
4916 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
4917 TCP(sport=port, dport=external_port))
4919 self.pg1.add_stream(pkts)
4920 self.pg_enable_capture(self.pg_interfaces)
4922 capture = self.pg0.get_capture(len(pkts))
4924 self.assertEqual(p[IP].dst, backend)
4926 def test_unknown_proto(self):
4927 """ NAT44 translate packet with unknown protocol """
4928 self.nat44_add_address(self.nat_addr)
4929 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
4930 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
4934 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
4935 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
4936 TCP(sport=self.tcp_port_in, dport=20))
4937 self.pg0.add_stream(p)
4938 self.pg_enable_capture(self.pg_interfaces)
4940 p = self.pg1.get_capture(1)
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) /
4945 IP(src=self.pg2.remote_ip4, dst=self.pg2.remote_ip4) /
4946 TCP(sport=1234, dport=1234))
4947 self.pg0.add_stream(p)
4948 self.pg_enable_capture(self.pg_interfaces)
4950 p = self.pg1.get_capture(1)
4953 self.assertEqual(packet[IP].src, self.nat_addr)
4954 self.assertEqual(packet[IP].dst, self.pg1.remote_ip4)
4955 self.assertEqual(packet.haslayer(GRE), 1)
4956 self.assert_packet_checksums_valid(packet)
4958 self.logger.error(ppp("Unexpected or invalid packet:", packet))
4962 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
4963 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
4965 IP(src=self.pg2.remote_ip4, dst=self.pg2.remote_ip4) /
4966 TCP(sport=1234, dport=1234))
4967 self.pg1.add_stream(p)
4968 self.pg_enable_capture(self.pg_interfaces)
4970 p = self.pg0.get_capture(1)
4973 self.assertEqual(packet[IP].src, self.pg1.remote_ip4)
4974 self.assertEqual(packet[IP].dst, self.pg0.remote_ip4)
4975 self.assertEqual(packet.haslayer(GRE), 1)
4976 self.assert_packet_checksums_valid(packet)
4978 self.logger.error(ppp("Unexpected or invalid packet:", packet))
4981 def test_hairpinning_unknown_proto(self):
4982 """ NAT44 translate packet with unknown protocol - hairpinning """
4983 host = self.pg0.remote_hosts[0]
4984 server = self.pg0.remote_hosts[1]
4986 server_out_port = 8765
4987 server_nat_ip = "10.0.0.11"
4989 self.nat44_add_address(self.nat_addr)
4990 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
4991 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
4994 # add static mapping for server
4995 self.nat44_add_static_mapping(server.ip4, server_nat_ip)
4998 p = (Ether(src=host.mac, dst=self.pg0.local_mac) /
4999 IP(src=host.ip4, dst=server_nat_ip) /
5000 TCP(sport=host_in_port, dport=server_out_port))
5001 self.pg0.add_stream(p)
5002 self.pg_enable_capture(self.pg_interfaces)
5004 self.pg0.get_capture(1)
5006 p = (Ether(dst=self.pg0.local_mac, src=host.mac) /
5007 IP(src=host.ip4, dst=server_nat_ip) /
5009 IP(src=self.pg2.remote_ip4, dst=self.pg2.remote_ip4) /
5010 TCP(sport=1234, dport=1234))
5011 self.pg0.add_stream(p)
5012 self.pg_enable_capture(self.pg_interfaces)
5014 p = self.pg0.get_capture(1)
5017 self.assertEqual(packet[IP].src, self.nat_addr)
5018 self.assertEqual(packet[IP].dst, server.ip4)
5019 self.assertEqual(packet.haslayer(GRE), 1)
5020 self.assert_packet_checksums_valid(packet)
5022 self.logger.error(ppp("Unexpected or invalid packet:", packet))
5026 p = (Ether(dst=self.pg0.local_mac, src=server.mac) /
5027 IP(src=server.ip4, dst=self.nat_addr) /
5029 IP(src=self.pg2.remote_ip4, dst=self.pg2.remote_ip4) /
5030 TCP(sport=1234, dport=1234))
5031 self.pg0.add_stream(p)
5032 self.pg_enable_capture(self.pg_interfaces)
5034 p = self.pg0.get_capture(1)
5037 self.assertEqual(packet[IP].src, server_nat_ip)
5038 self.assertEqual(packet[IP].dst, host.ip4)
5039 self.assertEqual(packet.haslayer(GRE), 1)
5040 self.assert_packet_checksums_valid(packet)
5042 self.logger.error(ppp("Unexpected or invalid packet:", packet))
5045 def test_output_feature_and_service(self):
5046 """ NAT44 interface output feature and services """
5047 external_addr = '1.2.3.4'
5051 self.vapi.nat44_forwarding_enable_disable(1)
5052 self.nat44_add_address(self.nat_addr)
5053 self.vapi.nat44_add_del_identity_mapping(ip=self.pg1.remote_ip4n)
5054 self.nat44_add_static_mapping(self.pg0.remote_ip4, external_addr,
5055 local_port, external_port,
5056 proto=IP_PROTOS.tcp, out2in_only=1)
5057 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
5058 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index,
5060 self.vapi.nat44_interface_add_del_output_feature(self.pg1.sw_if_index,
5063 # from client to service
5064 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
5065 IP(src=self.pg1.remote_ip4, dst=external_addr) /
5066 TCP(sport=12345, dport=external_port))
5067 self.pg1.add_stream(p)
5068 self.pg_enable_capture(self.pg_interfaces)
5070 capture = self.pg0.get_capture(1)
5075 self.assertEqual(ip.dst, self.pg0.remote_ip4)
5076 self.assertEqual(tcp.dport, local_port)
5077 self.assert_packet_checksums_valid(p)
5079 self.logger.error(ppp("Unexpected or invalid packet:", p))
5082 # from service back to client
5083 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5084 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
5085 TCP(sport=local_port, dport=12345))
5086 self.pg0.add_stream(p)
5087 self.pg_enable_capture(self.pg_interfaces)
5089 capture = self.pg1.get_capture(1)
5094 self.assertEqual(ip.src, external_addr)
5095 self.assertEqual(tcp.sport, external_port)
5096 self.assert_packet_checksums_valid(p)
5098 self.logger.error(ppp("Unexpected or invalid packet:", p))
5101 # from local network host to external network
5102 pkts = self.create_stream_in(self.pg0, self.pg1)
5103 self.pg0.add_stream(pkts)
5104 self.pg_enable_capture(self.pg_interfaces)
5106 capture = self.pg1.get_capture(len(pkts))
5107 self.verify_capture_out(capture)
5108 pkts = self.create_stream_in(self.pg0, self.pg1)
5109 self.pg0.add_stream(pkts)
5110 self.pg_enable_capture(self.pg_interfaces)
5112 capture = self.pg1.get_capture(len(pkts))
5113 self.verify_capture_out(capture)
5115 # from external network back to local network host
5116 pkts = self.create_stream_out(self.pg1)
5117 self.pg1.add_stream(pkts)
5118 self.pg_enable_capture(self.pg_interfaces)
5120 capture = self.pg0.get_capture(len(pkts))
5121 self.verify_capture_in(capture, self.pg0)
5123 def test_output_feature_and_service2(self):
5124 """ NAT44 interface output feature and service host direct access """
5125 self.vapi.nat44_forwarding_enable_disable(1)
5126 self.nat44_add_address(self.nat_addr)
5127 self.vapi.nat44_interface_add_del_output_feature(self.pg1.sw_if_index,
5130 # session initiated from service host - translate
5131 pkts = self.create_stream_in(self.pg0, self.pg1)
5132 self.pg0.add_stream(pkts)
5133 self.pg_enable_capture(self.pg_interfaces)
5135 capture = self.pg1.get_capture(len(pkts))
5136 self.verify_capture_out(capture)
5138 pkts = self.create_stream_out(self.pg1)
5139 self.pg1.add_stream(pkts)
5140 self.pg_enable_capture(self.pg_interfaces)
5142 capture = self.pg0.get_capture(len(pkts))
5143 self.verify_capture_in(capture, self.pg0)
5145 # session initiated from remote host - do not translate
5146 self.tcp_port_in = 60303
5147 self.udp_port_in = 60304
5148 self.icmp_id_in = 60305
5149 pkts = self.create_stream_out(self.pg1,
5150 self.pg0.remote_ip4,
5151 use_inside_ports=True)
5152 self.pg1.add_stream(pkts)
5153 self.pg_enable_capture(self.pg_interfaces)
5155 capture = self.pg0.get_capture(len(pkts))
5156 self.verify_capture_in(capture, self.pg0)
5158 pkts = self.create_stream_in(self.pg0, self.pg1)
5159 self.pg0.add_stream(pkts)
5160 self.pg_enable_capture(self.pg_interfaces)
5162 capture = self.pg1.get_capture(len(pkts))
5163 self.verify_capture_out(capture, nat_ip=self.pg0.remote_ip4,
5166 def test_output_feature_and_service3(self):
5167 """ NAT44 interface output feature and DST NAT """
5168 external_addr = '1.2.3.4'
5172 self.vapi.nat44_forwarding_enable_disable(1)
5173 self.nat44_add_address(self.nat_addr)
5174 self.nat44_add_static_mapping(self.pg1.remote_ip4, external_addr,
5175 local_port, external_port,
5176 proto=IP_PROTOS.tcp, out2in_only=1)
5177 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
5178 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index,
5180 self.vapi.nat44_interface_add_del_output_feature(self.pg1.sw_if_index,
5183 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5184 IP(src=self.pg0.remote_ip4, dst=external_addr) /
5185 TCP(sport=12345, dport=external_port))
5186 self.pg0.add_stream(p)
5187 self.pg_enable_capture(self.pg_interfaces)
5189 capture = self.pg1.get_capture(1)
5194 self.assertEqual(ip.src, self.pg0.remote_ip4)
5195 self.assertEqual(tcp.sport, 12345)
5196 self.assertEqual(ip.dst, self.pg1.remote_ip4)
5197 self.assertEqual(tcp.dport, local_port)
5198 self.assert_packet_checksums_valid(p)
5200 self.logger.error(ppp("Unexpected or invalid packet:", p))
5203 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
5204 IP(src=self.pg1.remote_ip4, dst=self.pg0.remote_ip4) /
5205 TCP(sport=local_port, dport=12345))
5206 self.pg1.add_stream(p)
5207 self.pg_enable_capture(self.pg_interfaces)
5209 capture = self.pg0.get_capture(1)
5214 self.assertEqual(ip.src, external_addr)
5215 self.assertEqual(tcp.sport, external_port)
5216 self.assertEqual(ip.dst, self.pg0.remote_ip4)
5217 self.assertEqual(tcp.dport, 12345)
5218 self.assert_packet_checksums_valid(p)
5220 self.logger.error(ppp("Unexpected or invalid packet:", p))
5223 def test_next_src_nat(self):
5224 """ On way back forward packet to nat44-in2out node. """
5225 twice_nat_addr = '10.0.1.3'
5228 post_twice_nat_port = 0
5230 self.vapi.nat44_forwarding_enable_disable(1)
5231 self.nat44_add_address(twice_nat_addr, twice_nat=1)
5232 self.nat44_add_static_mapping(self.pg6.remote_ip4, self.pg1.remote_ip4,
5233 local_port, external_port,
5234 proto=IP_PROTOS.tcp, out2in_only=1,
5235 self_twice_nat=1, vrf_id=1)
5236 self.vapi.nat44_interface_add_del_feature(self.pg6.sw_if_index,
5239 p = (Ether(src=self.pg6.remote_mac, dst=self.pg6.local_mac) /
5240 IP(src=self.pg6.remote_ip4, dst=self.pg1.remote_ip4) /
5241 TCP(sport=12345, dport=external_port))
5242 self.pg6.add_stream(p)
5243 self.pg_enable_capture(self.pg_interfaces)
5245 capture = self.pg6.get_capture(1)
5250 self.assertEqual(ip.src, twice_nat_addr)
5251 self.assertNotEqual(tcp.sport, 12345)
5252 post_twice_nat_port = tcp.sport
5253 self.assertEqual(ip.dst, self.pg6.remote_ip4)
5254 self.assertEqual(tcp.dport, local_port)
5255 self.assert_packet_checksums_valid(p)
5257 self.logger.error(ppp("Unexpected or invalid packet:", p))
5260 p = (Ether(src=self.pg6.remote_mac, dst=self.pg6.local_mac) /
5261 IP(src=self.pg6.remote_ip4, dst=twice_nat_addr) /
5262 TCP(sport=local_port, dport=post_twice_nat_port))
5263 self.pg6.add_stream(p)
5264 self.pg_enable_capture(self.pg_interfaces)
5266 capture = self.pg6.get_capture(1)
5271 self.assertEqual(ip.src, self.pg1.remote_ip4)
5272 self.assertEqual(tcp.sport, external_port)
5273 self.assertEqual(ip.dst, self.pg6.remote_ip4)
5274 self.assertEqual(tcp.dport, 12345)
5275 self.assert_packet_checksums_valid(p)
5277 self.logger.error(ppp("Unexpected or invalid packet:", p))
5280 def twice_nat_common(self, self_twice_nat=False, same_pg=False, lb=False,
5282 twice_nat_addr = '10.0.1.3'
5290 port_in1 = port_in + 1
5291 port_in2 = port_in + 2
5296 server1 = self.pg0.remote_hosts[0]
5297 server2 = self.pg0.remote_hosts[1]
5309 eh_translate = ((not self_twice_nat) or (not lb and same_pg) or
5312 self.nat44_add_address(self.nat_addr)
5313 self.nat44_add_address(twice_nat_addr, twice_nat=1)
5315 self.nat44_add_static_mapping(pg0.remote_ip4, self.nat_addr,
5317 proto=IP_PROTOS.tcp,
5318 twice_nat=int(not self_twice_nat),
5319 self_twice_nat=int(self_twice_nat))
5321 locals = [{'addr': server1.ip4n,
5325 {'addr': server2.ip4n,
5329 out_addr_n = socket.inet_pton(socket.AF_INET, self.nat_addr)
5330 self.vapi.nat44_add_del_lb_static_mapping(out_addr_n,
5334 not self_twice_nat),
5337 local_num=len(locals),
5339 self.vapi.nat44_interface_add_del_feature(pg0.sw_if_index)
5340 self.vapi.nat44_interface_add_del_feature(pg1.sw_if_index,
5347 assert client_id is not None
5349 client = self.pg0.remote_hosts[0]
5350 elif client_id == 2:
5351 client = self.pg0.remote_hosts[1]
5353 client = pg1.remote_hosts[0]
5354 p = (Ether(src=pg1.remote_mac, dst=pg1.local_mac) /
5355 IP(src=client.ip4, dst=self.nat_addr) /
5356 TCP(sport=eh_port_out, dport=port_out))
5358 self.pg_enable_capture(self.pg_interfaces)
5360 capture = pg0.get_capture(1)
5366 if ip.dst == server1.ip4:
5372 self.assertEqual(ip.dst, server.ip4)
5374 self.assertIn(tcp.dport, [port_in1, port_in2])
5376 self.assertEqual(tcp.dport, port_in)
5378 self.assertEqual(ip.src, twice_nat_addr)
5379 self.assertNotEqual(tcp.sport, eh_port_out)
5381 self.assertEqual(ip.src, client.ip4)
5382 self.assertEqual(tcp.sport, eh_port_out)
5384 eh_port_in = tcp.sport
5385 saved_port_in = tcp.dport
5386 self.assert_packet_checksums_valid(p)
5388 self.logger.error(ppp("Unexpected or invalid packet:", p))
5391 p = (Ether(src=server.mac, dst=pg0.local_mac) /
5392 IP(src=server.ip4, dst=eh_addr_in) /
5393 TCP(sport=saved_port_in, dport=eh_port_in))
5395 self.pg_enable_capture(self.pg_interfaces)
5397 capture = pg1.get_capture(1)
5402 self.assertEqual(ip.dst, client.ip4)
5403 self.assertEqual(ip.src, self.nat_addr)
5404 self.assertEqual(tcp.dport, eh_port_out)
5405 self.assertEqual(tcp.sport, port_out)
5406 self.assert_packet_checksums_valid(p)
5408 self.logger.error(ppp("Unexpected or invalid packet:", p))
5412 sessions = self.vapi.nat44_user_session_dump(server.ip4n, 0)
5413 self.assertEqual(len(sessions), 1)
5414 self.assertTrue(sessions[0].ext_host_valid)
5415 self.assertTrue(sessions[0].is_twicenat)
5416 self.vapi.nat44_del_session(
5417 sessions[0].inside_ip_address,
5418 sessions[0].inside_port,
5419 sessions[0].protocol,
5420 ext_host_address=sessions[0].ext_host_nat_address,
5421 ext_host_port=sessions[0].ext_host_nat_port)
5422 sessions = self.vapi.nat44_user_session_dump(server.ip4n, 0)
5423 self.assertEqual(len(sessions), 0)
5425 def test_twice_nat(self):
5427 self.twice_nat_common()
5429 def test_self_twice_nat_positive(self):
5430 """ Self Twice NAT44 (positive test) """
5431 self.twice_nat_common(self_twice_nat=True, same_pg=True)
5433 def test_self_twice_nat_negative(self):
5434 """ Self Twice NAT44 (negative test) """
5435 self.twice_nat_common(self_twice_nat=True)
5437 def test_twice_nat_lb(self):
5438 """ Twice NAT44 local service load balancing """
5439 self.twice_nat_common(lb=True)
5441 def test_self_twice_nat_lb_positive(self):
5442 """ Self Twice NAT44 local service load balancing (positive test) """
5443 self.twice_nat_common(lb=True, self_twice_nat=True, same_pg=True,
5446 def test_self_twice_nat_lb_negative(self):
5447 """ Self Twice NAT44 local service load balancing (negative test) """
5448 self.twice_nat_common(lb=True, self_twice_nat=True, same_pg=True,
5451 def test_twice_nat_interface_addr(self):
5452 """ Acquire twice NAT44 addresses from interface """
5453 self.vapi.nat44_add_del_interface_addr(self.pg3.sw_if_index,
5456 # no address in NAT pool
5457 adresses = self.vapi.nat44_address_dump()
5458 self.assertEqual(0, len(adresses))
5460 # configure interface address and check NAT address pool
5461 self.pg3.config_ip4()
5462 adresses = self.vapi.nat44_address_dump()
5463 self.assertEqual(1, len(adresses))
5464 self.assertEqual(adresses[0].ip_address[0:4], self.pg3.local_ip4n)
5465 self.assertEqual(adresses[0].twice_nat, 1)
5467 # remove interface address and check NAT address pool
5468 self.pg3.unconfig_ip4()
5469 adresses = self.vapi.nat44_address_dump()
5470 self.assertEqual(0, len(adresses))
5472 def test_tcp_close(self):
5473 """ Close TCP session from inside network - output feature """
5474 self.vapi.nat44_forwarding_enable_disable(1)
5475 self.nat44_add_address(self.pg1.local_ip4)
5476 twice_nat_addr = '10.0.1.3'
5477 service_ip = '192.168.16.150'
5478 self.nat44_add_address(twice_nat_addr, twice_nat=1)
5479 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
5480 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index,
5482 self.vapi.nat44_interface_add_del_output_feature(self.pg1.sw_if_index,
5484 self.nat44_add_static_mapping(self.pg0.remote_ip4,
5488 proto=IP_PROTOS.tcp,
5491 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4n, 0)
5492 start_sessnum = len(sessions)
5494 # SYN packet out->in
5495 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
5496 IP(src=self.pg1.remote_ip4, dst=service_ip) /
5497 TCP(sport=33898, dport=80, flags="S"))
5498 self.pg1.add_stream(p)
5499 self.pg_enable_capture(self.pg_interfaces)
5501 capture = self.pg0.get_capture(1)
5503 tcp_port = p[TCP].sport
5505 # SYN + ACK packet in->out
5506 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5507 IP(src=self.pg0.remote_ip4, dst=twice_nat_addr) /
5508 TCP(sport=80, dport=tcp_port, flags="SA"))
5509 self.pg0.add_stream(p)
5510 self.pg_enable_capture(self.pg_interfaces)
5512 self.pg1.get_capture(1)
5514 # ACK packet out->in
5515 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
5516 IP(src=self.pg1.remote_ip4, dst=service_ip) /
5517 TCP(sport=33898, dport=80, flags="A"))
5518 self.pg1.add_stream(p)
5519 self.pg_enable_capture(self.pg_interfaces)
5521 self.pg0.get_capture(1)
5523 # FIN packet in -> out
5524 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5525 IP(src=self.pg0.remote_ip4, dst=twice_nat_addr) /
5526 TCP(sport=80, dport=tcp_port, flags="FA", seq=100, ack=300))
5527 self.pg0.add_stream(p)
5528 self.pg_enable_capture(self.pg_interfaces)
5530 self.pg1.get_capture(1)
5532 # FIN+ACK packet out -> in
5533 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
5534 IP(src=self.pg1.remote_ip4, dst=service_ip) /
5535 TCP(sport=33898, dport=80, flags="FA", seq=300, ack=101))
5536 self.pg1.add_stream(p)
5537 self.pg_enable_capture(self.pg_interfaces)
5539 self.pg0.get_capture(1)
5541 # ACK packet in -> out
5542 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5543 IP(src=self.pg0.remote_ip4, dst=twice_nat_addr) /
5544 TCP(sport=80, dport=tcp_port, flags="A", seq=101, ack=301))
5545 self.pg0.add_stream(p)
5546 self.pg_enable_capture(self.pg_interfaces)
5548 self.pg1.get_capture(1)
5550 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4n,
5552 self.assertEqual(len(sessions) - start_sessnum, 0)
5554 def test_tcp_session_close_in(self):
5555 """ Close TCP session from inside network """
5556 self.tcp_port_out = 10505
5557 self.nat44_add_address(self.nat_addr)
5558 self.nat44_add_static_mapping(self.pg0.remote_ip4,
5562 proto=IP_PROTOS.tcp,
5564 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
5565 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
5568 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4n, 0)
5569 start_sessnum = len(sessions)
5571 self.initiate_tcp_session(self.pg0, self.pg1)
5573 # FIN packet in -> out
5574 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5575 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
5576 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
5577 flags="FA", seq=100, ack=300))
5578 self.pg0.add_stream(p)
5579 self.pg_enable_capture(self.pg_interfaces)
5581 self.pg1.get_capture(1)
5585 # ACK packet out -> in
5586 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
5587 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
5588 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
5589 flags="A", seq=300, ack=101))
5592 # FIN packet out -> in
5593 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
5594 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
5595 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
5596 flags="FA", seq=300, ack=101))
5599 self.pg1.add_stream(pkts)
5600 self.pg_enable_capture(self.pg_interfaces)
5602 self.pg0.get_capture(2)
5604 # ACK packet in -> out
5605 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5606 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
5607 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
5608 flags="A", seq=101, ack=301))
5609 self.pg0.add_stream(p)
5610 self.pg_enable_capture(self.pg_interfaces)
5612 self.pg1.get_capture(1)
5614 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4n,
5616 self.assertEqual(len(sessions) - start_sessnum, 0)
5618 def test_tcp_session_close_out(self):
5619 """ Close TCP session from outside network """
5620 self.tcp_port_out = 10505
5621 self.nat44_add_address(self.nat_addr)
5622 self.nat44_add_static_mapping(self.pg0.remote_ip4,
5626 proto=IP_PROTOS.tcp,
5628 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
5629 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
5632 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4n, 0)
5633 start_sessnum = len(sessions)
5635 self.initiate_tcp_session(self.pg0, self.pg1)
5637 # FIN packet out -> in
5638 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
5639 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
5640 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
5641 flags="FA", seq=100, ack=300))
5642 self.pg1.add_stream(p)
5643 self.pg_enable_capture(self.pg_interfaces)
5645 self.pg0.get_capture(1)
5647 # FIN+ACK packet in -> out
5648 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5649 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
5650 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
5651 flags="FA", seq=300, ack=101))
5653 self.pg0.add_stream(p)
5654 self.pg_enable_capture(self.pg_interfaces)
5656 self.pg1.get_capture(1)
5658 # ACK packet out -> in
5659 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
5660 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
5661 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
5662 flags="A", seq=101, ack=301))
5663 self.pg1.add_stream(p)
5664 self.pg_enable_capture(self.pg_interfaces)
5666 self.pg0.get_capture(1)
5668 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4n,
5670 self.assertEqual(len(sessions) - start_sessnum, 0)
5672 def test_tcp_session_close_simultaneous(self):
5673 """ Close TCP session from inside network """
5674 self.tcp_port_out = 10505
5675 self.nat44_add_address(self.nat_addr)
5676 self.nat44_add_static_mapping(self.pg0.remote_ip4,
5680 proto=IP_PROTOS.tcp,
5682 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
5683 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
5686 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4n, 0)
5687 start_sessnum = len(sessions)
5689 self.initiate_tcp_session(self.pg0, self.pg1)
5691 # FIN packet in -> out
5692 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5693 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
5694 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
5695 flags="FA", seq=100, ack=300))
5696 self.pg0.add_stream(p)
5697 self.pg_enable_capture(self.pg_interfaces)
5699 self.pg1.get_capture(1)
5701 # FIN packet out -> in
5702 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
5703 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
5704 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
5705 flags="FA", seq=300, ack=100))
5706 self.pg1.add_stream(p)
5707 self.pg_enable_capture(self.pg_interfaces)
5709 self.pg0.get_capture(1)
5711 # ACK packet in -> out
5712 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5713 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
5714 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
5715 flags="A", seq=101, ack=301))
5716 self.pg0.add_stream(p)
5717 self.pg_enable_capture(self.pg_interfaces)
5719 self.pg1.get_capture(1)
5721 # ACK packet out -> in
5722 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
5723 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
5724 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
5725 flags="A", seq=301, ack=101))
5726 self.pg1.add_stream(p)
5727 self.pg_enable_capture(self.pg_interfaces)
5729 self.pg0.get_capture(1)
5731 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4n,
5733 self.assertEqual(len(sessions) - start_sessnum, 0)
5735 def test_one_armed_nat44_static(self):
5736 """ One armed NAT44 and 1:1 NAPT asymmetrical rule """
5737 remote_host = self.pg4.remote_hosts[0]
5738 local_host = self.pg4.remote_hosts[1]
5743 self.vapi.nat44_forwarding_enable_disable(1)
5744 self.nat44_add_address(self.nat_addr, twice_nat=1)
5745 self.nat44_add_static_mapping(local_host.ip4, self.nat_addr,
5746 local_port, external_port,
5747 proto=IP_PROTOS.tcp, out2in_only=1,
5749 self.vapi.nat44_interface_add_del_feature(self.pg4.sw_if_index)
5750 self.vapi.nat44_interface_add_del_feature(self.pg4.sw_if_index,
5753 # from client to service
5754 p = (Ether(src=self.pg4.remote_mac, dst=self.pg4.local_mac) /
5755 IP(src=remote_host.ip4, dst=self.nat_addr) /
5756 TCP(sport=12345, dport=external_port))
5757 self.pg4.add_stream(p)
5758 self.pg_enable_capture(self.pg_interfaces)
5760 capture = self.pg4.get_capture(1)
5765 self.assertEqual(ip.dst, local_host.ip4)
5766 self.assertEqual(ip.src, self.nat_addr)
5767 self.assertEqual(tcp.dport, local_port)
5768 self.assertNotEqual(tcp.sport, 12345)
5769 eh_port_in = tcp.sport
5770 self.assert_packet_checksums_valid(p)
5772 self.logger.error(ppp("Unexpected or invalid packet:", p))
5775 # from service back to client
5776 p = (Ether(src=self.pg4.remote_mac, dst=self.pg4.local_mac) /
5777 IP(src=local_host.ip4, dst=self.nat_addr) /
5778 TCP(sport=local_port, dport=eh_port_in))
5779 self.pg4.add_stream(p)
5780 self.pg_enable_capture(self.pg_interfaces)
5782 capture = self.pg4.get_capture(1)
5787 self.assertEqual(ip.src, self.nat_addr)
5788 self.assertEqual(ip.dst, remote_host.ip4)
5789 self.assertEqual(tcp.sport, external_port)
5790 self.assertEqual(tcp.dport, 12345)
5791 self.assert_packet_checksums_valid(p)
5793 self.logger.error(ppp("Unexpected or invalid packet:", p))
5796 def test_static_with_port_out2(self):
5797 """ 1:1 NAPT asymmetrical rule """
5802 self.vapi.nat44_forwarding_enable_disable(1)
5803 self.nat44_add_static_mapping(self.pg0.remote_ip4, self.nat_addr,
5804 local_port, external_port,
5805 proto=IP_PROTOS.tcp, out2in_only=1)
5806 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
5807 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
5810 # from client to service
5811 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
5812 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
5813 TCP(sport=12345, dport=external_port))
5814 self.pg1.add_stream(p)
5815 self.pg_enable_capture(self.pg_interfaces)
5817 capture = self.pg0.get_capture(1)
5822 self.assertEqual(ip.dst, self.pg0.remote_ip4)
5823 self.assertEqual(tcp.dport, local_port)
5824 self.assert_packet_checksums_valid(p)
5826 self.logger.error(ppp("Unexpected or invalid packet:", p))
5830 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
5831 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
5832 ICMP(type=11) / capture[0][IP])
5833 self.pg0.add_stream(p)
5834 self.pg_enable_capture(self.pg_interfaces)
5836 capture = self.pg1.get_capture(1)
5839 self.assertEqual(p[IP].src, self.nat_addr)
5841 self.assertEqual(inner.dst, self.nat_addr)
5842 self.assertEqual(inner[TCPerror].dport, external_port)
5844 self.logger.error(ppp("Unexpected or invalid packet:", p))
5847 # from service back to client
5848 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5849 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
5850 TCP(sport=local_port, dport=12345))
5851 self.pg0.add_stream(p)
5852 self.pg_enable_capture(self.pg_interfaces)
5854 capture = self.pg1.get_capture(1)
5859 self.assertEqual(ip.src, self.nat_addr)
5860 self.assertEqual(tcp.sport, external_port)
5861 self.assert_packet_checksums_valid(p)
5863 self.logger.error(ppp("Unexpected or invalid packet:", p))
5867 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
5868 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
5869 ICMP(type=11) / capture[0][IP])
5870 self.pg1.add_stream(p)
5871 self.pg_enable_capture(self.pg_interfaces)
5873 capture = self.pg0.get_capture(1)
5876 self.assertEqual(p[IP].dst, self.pg0.remote_ip4)
5878 self.assertEqual(inner.src, self.pg0.remote_ip4)
5879 self.assertEqual(inner[TCPerror].sport, local_port)
5881 self.logger.error(ppp("Unexpected or invalid packet:", p))
5884 # from client to server (no translation)
5885 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
5886 IP(src=self.pg1.remote_ip4, dst=self.pg0.remote_ip4) /
5887 TCP(sport=12346, dport=local_port))
5888 self.pg1.add_stream(p)
5889 self.pg_enable_capture(self.pg_interfaces)
5891 capture = self.pg0.get_capture(1)
5896 self.assertEqual(ip.dst, self.pg0.remote_ip4)
5897 self.assertEqual(tcp.dport, local_port)
5898 self.assert_packet_checksums_valid(p)
5900 self.logger.error(ppp("Unexpected or invalid packet:", p))
5903 # from service back to client (no translation)
5904 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5905 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
5906 TCP(sport=local_port, dport=12346))
5907 self.pg0.add_stream(p)
5908 self.pg_enable_capture(self.pg_interfaces)
5910 capture = self.pg1.get_capture(1)
5915 self.assertEqual(ip.src, self.pg0.remote_ip4)
5916 self.assertEqual(tcp.sport, local_port)
5917 self.assert_packet_checksums_valid(p)
5919 self.logger.error(ppp("Unexpected or invalid packet:", p))
5922 def test_output_feature(self):
5923 """ NAT44 interface output feature (in2out postrouting) """
5924 self.vapi.nat44_forwarding_enable_disable(1)
5925 self.nat44_add_address(self.nat_addr)
5926 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index,
5928 self.vapi.nat44_interface_add_del_output_feature(self.pg1.sw_if_index,
5932 pkts = self.create_stream_in(self.pg0, self.pg1)
5933 self.pg0.add_stream(pkts)
5934 self.pg_enable_capture(self.pg_interfaces)
5936 capture = self.pg1.get_capture(len(pkts))
5937 self.verify_capture_out(capture)
5940 pkts = self.create_stream_out(self.pg1)
5941 self.pg1.add_stream(pkts)
5942 self.pg_enable_capture(self.pg_interfaces)
5944 capture = self.pg0.get_capture(len(pkts))
5945 self.verify_capture_in(capture, self.pg0)
5947 def test_multiple_vrf(self):
5948 """ Multiple VRF setup """
5949 external_addr = '1.2.3.4'
5954 self.vapi.nat44_forwarding_enable_disable(1)
5955 self.nat44_add_address(self.nat_addr)
5956 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
5957 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index,
5959 self.vapi.nat44_interface_add_del_output_feature(self.pg1.sw_if_index,
5961 self.vapi.nat44_interface_add_del_feature(self.pg5.sw_if_index)
5962 self.vapi.nat44_interface_add_del_feature(self.pg5.sw_if_index,
5964 self.vapi.nat44_interface_add_del_feature(self.pg6.sw_if_index,
5966 self.nat44_add_static_mapping(self.pg5.remote_ip4, external_addr,
5967 local_port, external_port, vrf_id=1,
5968 proto=IP_PROTOS.tcp, out2in_only=1)
5969 self.nat44_add_static_mapping(
5970 self.pg0.remote_ip4, external_sw_if_index=self.pg0.sw_if_index,
5971 local_port=local_port, vrf_id=0, external_port=external_port,
5972 proto=IP_PROTOS.tcp, out2in_only=1)
5974 # from client to service (both VRF1)
5975 p = (Ether(src=self.pg6.remote_mac, dst=self.pg6.local_mac) /
5976 IP(src=self.pg6.remote_ip4, dst=external_addr) /
5977 TCP(sport=12345, dport=external_port))
5978 self.pg6.add_stream(p)
5979 self.pg_enable_capture(self.pg_interfaces)
5981 capture = self.pg5.get_capture(1)
5986 self.assertEqual(ip.dst, self.pg5.remote_ip4)
5987 self.assertEqual(tcp.dport, local_port)
5988 self.assert_packet_checksums_valid(p)
5990 self.logger.error(ppp("Unexpected or invalid packet:", p))
5993 # from service back to client (both VRF1)
5994 p = (Ether(src=self.pg5.remote_mac, dst=self.pg5.local_mac) /
5995 IP(src=self.pg5.remote_ip4, dst=self.pg6.remote_ip4) /
5996 TCP(sport=local_port, dport=12345))
5997 self.pg5.add_stream(p)
5998 self.pg_enable_capture(self.pg_interfaces)
6000 capture = self.pg6.get_capture(1)
6005 self.assertEqual(ip.src, external_addr)
6006 self.assertEqual(tcp.sport, external_port)
6007 self.assert_packet_checksums_valid(p)
6009 self.logger.error(ppp("Unexpected or invalid packet:", p))
6012 # dynamic NAT from VRF1 to VRF0 (output-feature)
6013 p = (Ether(src=self.pg5.remote_mac, dst=self.pg5.local_mac) /
6014 IP(src=self.pg5.remote_ip4, dst=self.pg1.remote_ip4) /
6015 TCP(sport=2345, dport=22))
6016 self.pg5.add_stream(p)
6017 self.pg_enable_capture(self.pg_interfaces)
6019 capture = self.pg1.get_capture(1)
6024 self.assertEqual(ip.src, self.nat_addr)
6025 self.assertNotEqual(tcp.sport, 2345)
6026 self.assert_packet_checksums_valid(p)
6029 self.logger.error(ppp("Unexpected or invalid packet:", p))
6032 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
6033 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
6034 TCP(sport=22, dport=port))
6035 self.pg1.add_stream(p)
6036 self.pg_enable_capture(self.pg_interfaces)
6038 capture = self.pg5.get_capture(1)
6043 self.assertEqual(ip.dst, self.pg5.remote_ip4)
6044 self.assertEqual(tcp.dport, 2345)
6045 self.assert_packet_checksums_valid(p)
6047 self.logger.error(ppp("Unexpected or invalid packet:", p))
6050 # from client VRF1 to service VRF0
6051 p = (Ether(src=self.pg6.remote_mac, dst=self.pg6.local_mac) /
6052 IP(src=self.pg6.remote_ip4, dst=self.pg0.local_ip4) /
6053 TCP(sport=12346, dport=external_port))
6054 self.pg6.add_stream(p)
6055 self.pg_enable_capture(self.pg_interfaces)
6057 capture = self.pg0.get_capture(1)
6062 self.assertEqual(ip.dst, self.pg0.remote_ip4)
6063 self.assertEqual(tcp.dport, local_port)
6064 self.assert_packet_checksums_valid(p)
6066 self.logger.error(ppp("Unexpected or invalid packet:", p))
6069 # from service VRF0 back to client VRF1
6070 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6071 IP(src=self.pg0.remote_ip4, dst=self.pg6.remote_ip4) /
6072 TCP(sport=local_port, dport=12346))
6073 self.pg0.add_stream(p)
6074 self.pg_enable_capture(self.pg_interfaces)
6076 capture = self.pg6.get_capture(1)
6081 self.assertEqual(ip.src, self.pg0.local_ip4)
6082 self.assertEqual(tcp.sport, external_port)
6083 self.assert_packet_checksums_valid(p)
6085 self.logger.error(ppp("Unexpected or invalid packet:", p))
6088 # from client VRF0 to service VRF1
6089 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6090 IP(src=self.pg0.remote_ip4, dst=external_addr) /
6091 TCP(sport=12347, dport=external_port))
6092 self.pg0.add_stream(p)
6093 self.pg_enable_capture(self.pg_interfaces)
6095 capture = self.pg5.get_capture(1)
6100 self.assertEqual(ip.dst, self.pg5.remote_ip4)
6101 self.assertEqual(tcp.dport, local_port)
6102 self.assert_packet_checksums_valid(p)
6104 self.logger.error(ppp("Unexpected or invalid packet:", p))
6107 # from service VRF1 back to client VRF0
6108 p = (Ether(src=self.pg5.remote_mac, dst=self.pg5.local_mac) /
6109 IP(src=self.pg5.remote_ip4, dst=self.pg0.remote_ip4) /
6110 TCP(sport=local_port, dport=12347))
6111 self.pg5.add_stream(p)
6112 self.pg_enable_capture(self.pg_interfaces)
6114 capture = self.pg0.get_capture(1)
6119 self.assertEqual(ip.src, external_addr)
6120 self.assertEqual(tcp.sport, external_port)
6121 self.assert_packet_checksums_valid(p)
6123 self.logger.error(ppp("Unexpected or invalid packet:", p))
6126 # from client to server (both VRF1, no translation)
6127 p = (Ether(src=self.pg6.remote_mac, dst=self.pg6.local_mac) /
6128 IP(src=self.pg6.remote_ip4, dst=self.pg5.remote_ip4) /
6129 TCP(sport=12348, dport=local_port))
6130 self.pg6.add_stream(p)
6131 self.pg_enable_capture(self.pg_interfaces)
6133 capture = self.pg5.get_capture(1)
6138 self.assertEqual(ip.dst, self.pg5.remote_ip4)
6139 self.assertEqual(tcp.dport, local_port)
6140 self.assert_packet_checksums_valid(p)
6142 self.logger.error(ppp("Unexpected or invalid packet:", p))
6145 # from server back to client (both VRF1, no translation)
6146 p = (Ether(src=self.pg5.remote_mac, dst=self.pg5.local_mac) /
6147 IP(src=self.pg5.remote_ip4, dst=self.pg6.remote_ip4) /
6148 TCP(sport=local_port, dport=12348))
6149 self.pg5.add_stream(p)
6150 self.pg_enable_capture(self.pg_interfaces)
6152 capture = self.pg6.get_capture(1)
6157 self.assertEqual(ip.src, self.pg5.remote_ip4)
6158 self.assertEqual(tcp.sport, local_port)
6159 self.assert_packet_checksums_valid(p)
6161 self.logger.error(ppp("Unexpected or invalid packet:", p))
6164 # from client VRF1 to server VRF0 (no translation)
6165 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6166 IP(src=self.pg0.remote_ip4, dst=self.pg6.remote_ip4) /
6167 TCP(sport=local_port, dport=12349))
6168 self.pg0.add_stream(p)
6169 self.pg_enable_capture(self.pg_interfaces)
6171 capture = self.pg6.get_capture(1)
6176 self.assertEqual(ip.src, self.pg0.remote_ip4)
6177 self.assertEqual(tcp.sport, local_port)
6178 self.assert_packet_checksums_valid(p)
6180 self.logger.error(ppp("Unexpected or invalid packet:", p))
6183 # from server VRF0 back to client VRF1 (no translation)
6184 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6185 IP(src=self.pg0.remote_ip4, dst=self.pg6.remote_ip4) /
6186 TCP(sport=local_port, dport=12349))
6187 self.pg0.add_stream(p)
6188 self.pg_enable_capture(self.pg_interfaces)
6190 capture = self.pg6.get_capture(1)
6195 self.assertEqual(ip.src, self.pg0.remote_ip4)
6196 self.assertEqual(tcp.sport, local_port)
6197 self.assert_packet_checksums_valid(p)
6199 self.logger.error(ppp("Unexpected or invalid packet:", p))
6202 # from client VRF0 to server VRF1 (no translation)
6203 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6204 IP(src=self.pg0.remote_ip4, dst=self.pg5.remote_ip4) /
6205 TCP(sport=12344, dport=local_port))
6206 self.pg0.add_stream(p)
6207 self.pg_enable_capture(self.pg_interfaces)
6209 capture = self.pg5.get_capture(1)
6214 self.assertEqual(ip.dst, self.pg5.remote_ip4)
6215 self.assertEqual(tcp.dport, local_port)
6216 self.assert_packet_checksums_valid(p)
6218 self.logger.error(ppp("Unexpected or invalid packet:", p))
6221 # from server VRF1 back to client VRF0 (no translation)
6222 p = (Ether(src=self.pg5.remote_mac, dst=self.pg5.local_mac) /
6223 IP(src=self.pg5.remote_ip4, dst=self.pg0.remote_ip4) /
6224 TCP(sport=local_port, dport=12344))
6225 self.pg5.add_stream(p)
6226 self.pg_enable_capture(self.pg_interfaces)
6228 capture = self.pg0.get_capture(1)
6233 self.assertEqual(ip.src, self.pg5.remote_ip4)
6234 self.assertEqual(tcp.sport, local_port)
6235 self.assert_packet_checksums_valid(p)
6237 self.logger.error(ppp("Unexpected or invalid packet:", p))
6240 @unittest.skipUnless(running_extended_tests, "part of extended tests")
6241 def test_session_timeout(self):
6242 """ NAT44 session timeouts """
6243 self.nat44_add_address(self.nat_addr)
6244 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
6245 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
6247 self.vapi.nat_set_timeouts(icmp=5)
6251 for i in range(0, max_sessions):
6252 src = "10.10.%u.%u" % ((i & 0xFF00) >> 8, i & 0xFF)
6253 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
6254 IP(src=src, dst=self.pg1.remote_ip4) /
6255 ICMP(id=1025, type='echo-request'))
6257 self.pg0.add_stream(pkts)
6258 self.pg_enable_capture(self.pg_interfaces)
6260 self.pg1.get_capture(max_sessions)
6265 for i in range(0, max_sessions):
6266 src = "10.11.%u.%u" % ((i & 0xFF00) >> 8, i & 0xFF)
6267 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
6268 IP(src=src, dst=self.pg1.remote_ip4) /
6269 ICMP(id=1026, type='echo-request'))
6271 self.pg0.add_stream(pkts)
6272 self.pg_enable_capture(self.pg_interfaces)
6274 self.pg1.get_capture(max_sessions)
6277 users = self.vapi.nat44_user_dump()
6279 nsessions = nsessions + user.nsessions
6280 self.assertLess(nsessions, 2 * max_sessions)
6282 @unittest.skipUnless(running_extended_tests, "part of extended tests")
6283 def test_session_rst_timeout(self):
6284 """ NAT44 session RST timeouts """
6285 self.nat44_add_address(self.nat_addr)
6286 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
6287 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
6289 self.vapi.nat_set_timeouts(tcp_transitory=5)
6291 self.initiate_tcp_session(self.pg0, self.pg1)
6292 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6293 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6294 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
6296 self.pg0.add_stream(p)
6297 self.pg_enable_capture(self.pg_interfaces)
6299 self.pg1.get_capture(1)
6303 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6304 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6305 TCP(sport=self.tcp_port_in + 1, dport=self.tcp_external_port + 1,
6307 self.pg0.add_stream(p)
6308 self.pg_enable_capture(self.pg_interfaces)
6310 self.pg1.get_capture(1)
6313 users = self.vapi.nat44_user_dump()
6314 self.assertEqual(len(users), 1)
6315 self.assertEqual(users[0].ip_address, self.pg0.remote_ip4n)
6316 self.assertEqual(users[0].nsessions, 1)
6318 @unittest.skipUnless(running_extended_tests, "part of extended tests")
6319 def test_session_limit_per_user(self):
6320 """ Maximum sessions per user limit """
6321 self.nat44_add_address(self.nat_addr)
6322 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
6323 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
6325 self.vapi.set_ipfix_exporter(collector_address=self.pg2.remote_ip4n,
6326 src_address=self.pg2.local_ip4n,
6328 template_interval=10)
6329 self.vapi.nat_set_timeouts(udp=5)
6331 # get maximum number of translations per user
6332 nat44_config = self.vapi.nat_show_config()
6335 for port in range(0, nat44_config.max_translations_per_user):
6336 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6337 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6338 UDP(sport=1025 + port, dport=1025 + port))
6341 self.pg0.add_stream(pkts)
6342 self.pg_enable_capture(self.pg_interfaces)
6344 capture = self.pg1.get_capture(len(pkts))
6346 self.vapi.nat_ipfix_enable_disable(domain_id=self.ipfix_domain_id,
6347 src_port=self.ipfix_src_port)
6349 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6350 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6351 UDP(sport=3001, dport=3002))
6352 self.pg0.add_stream(p)
6353 self.pg_enable_capture(self.pg_interfaces)
6355 capture = self.pg1.assert_nothing_captured()
6357 # verify IPFIX logging
6358 self.vapi.cli("ipfix flush") # FIXME this should be an API call
6360 capture = self.pg2.get_capture(10)
6361 ipfix = IPFIXDecoder()
6362 # first load template
6364 self.assertTrue(p.haslayer(IPFIX))
6365 if p.haslayer(Template):
6366 ipfix.add_template(p.getlayer(Template))
6367 # verify events in data set
6369 if p.haslayer(Data):
6370 data = ipfix.decode_data_set(p.getlayer(Set))
6371 self.verify_ipfix_max_entries_per_user(
6373 nat44_config.max_translations_per_user,
6374 self.pg0.remote_ip4n)
6377 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6378 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6379 UDP(sport=3001, dport=3002))
6380 self.pg0.add_stream(p)
6381 self.pg_enable_capture(self.pg_interfaces)
6383 self.pg1.get_capture(1)
6385 def test_syslog_sess(self):
6386 """ Test syslog session creation and deletion """
6387 self.vapi.syslog_set_filter(SYSLOG_SEVERITY.INFO)
6388 self.vapi.syslog_set_sender(self.pg2.local_ip4n, self.pg2.remote_ip4n)
6389 self.nat44_add_address(self.nat_addr)
6390 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
6391 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
6394 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
6395 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6396 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port))
6397 self.pg0.add_stream(p)
6398 self.pg_enable_capture(self.pg_interfaces)
6400 capture = self.pg1.get_capture(1)
6401 self.tcp_port_out = capture[0][TCP].sport
6402 capture = self.pg2.get_capture(1)
6403 self.verify_syslog_sess(capture[0][Raw].load)
6405 self.pg_enable_capture(self.pg_interfaces)
6407 self.nat44_add_address(self.nat_addr, is_add=0)
6408 capture = self.pg2.get_capture(1)
6409 self.verify_syslog_sess(capture[0][Raw].load, False)
6412 super(TestNAT44EndpointDependent, self).tearDown()
6413 if not self.vpp_dead:
6414 self.logger.info(self.vapi.cli("show nat44 addresses"))
6415 self.logger.info(self.vapi.cli("show nat44 interfaces"))
6416 self.logger.info(self.vapi.cli("show nat44 static mappings"))
6417 self.logger.info(self.vapi.cli("show nat44 interface address"))
6418 self.logger.info(self.vapi.cli("show nat44 sessions detail"))
6419 self.logger.info(self.vapi.cli("show nat44 hash tables detail"))
6420 self.logger.info(self.vapi.cli("show nat timeouts"))
6422 self.vapi.cli("clear logging")
6425 class TestNAT44Out2InDPO(MethodHolder):
6426 """ NAT44 Test Cases using out2in DPO """
6429 def setUpConstants(cls):
6430 super(TestNAT44Out2InDPO, cls).setUpConstants()
6431 cls.vpp_cmdline.extend(["nat", "{", "out2in dpo", "}"])
6434 def setUpClass(cls):
6435 super(TestNAT44Out2InDPO, cls).setUpClass()
6436 cls.vapi.cli("set log class nat level debug")
6439 cls.tcp_port_in = 6303
6440 cls.tcp_port_out = 6303
6441 cls.udp_port_in = 6304
6442 cls.udp_port_out = 6304
6443 cls.icmp_id_in = 6305
6444 cls.icmp_id_out = 6305
6445 cls.nat_addr = '10.0.0.3'
6446 cls.nat_addr_n = socket.inet_pton(socket.AF_INET, cls.nat_addr)
6447 cls.dst_ip4 = '192.168.70.1'
6449 cls.create_pg_interfaces(range(2))
6452 cls.pg0.config_ip4()
6453 cls.pg0.resolve_arp()
6456 cls.pg1.config_ip6()
6457 cls.pg1.resolve_ndp()
6459 cls.vapi.ip_add_del_route(dst_address=b'\x00' * 16,
6460 dst_address_length=0,
6461 next_hop_address=cls.pg1.remote_ip6n,
6462 next_hop_sw_if_index=cls.pg1.sw_if_index,
6466 super(TestNAT44Out2InDPO, cls).tearDownClass()
6469 def configure_xlat(self):
6470 self.dst_ip6_pfx = '1:2:3::'
6471 self.dst_ip6_pfx_n = socket.inet_pton(socket.AF_INET6,
6473 self.dst_ip6_pfx_len = 96
6474 self.src_ip6_pfx = '4:5:6::'
6475 self.src_ip6_pfx_n = socket.inet_pton(socket.AF_INET6,
6477 self.src_ip6_pfx_len = 96
6478 self.vapi.map_add_domain(self.dst_ip6_pfx_n, self.dst_ip6_pfx_len,
6479 self.src_ip6_pfx_n, self.src_ip6_pfx_len,
6480 '\x00\x00\x00\x00', 0)
6482 @unittest.skip('Temporary disabled')
6483 def test_464xlat_ce(self):
6484 """ Test 464XLAT CE with NAT44 """
6486 nat_config = self.vapi.nat_show_config()
6487 self.assertEqual(1, nat_config.out2in_dpo)
6489 self.configure_xlat()
6491 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
6492 self.vapi.nat44_add_del_address_range(self.nat_addr_n, self.nat_addr_n)
6494 out_src_ip6 = self.compose_ip6(self.dst_ip4, self.dst_ip6_pfx,
6495 self.dst_ip6_pfx_len)
6496 out_dst_ip6 = self.compose_ip6(self.nat_addr, self.src_ip6_pfx,
6497 self.src_ip6_pfx_len)
6500 pkts = self.create_stream_in(self.pg0, self.pg1, self.dst_ip4)
6501 self.pg0.add_stream(pkts)
6502 self.pg_enable_capture(self.pg_interfaces)
6504 capture = self.pg1.get_capture(len(pkts))
6505 self.verify_capture_out_ip6(capture, nat_ip=out_dst_ip6,
6508 pkts = self.create_stream_out_ip6(self.pg1, out_src_ip6,
6510 self.pg1.add_stream(pkts)
6511 self.pg_enable_capture(self.pg_interfaces)
6513 capture = self.pg0.get_capture(len(pkts))
6514 self.verify_capture_in(capture, self.pg0)
6516 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index,
6518 self.vapi.nat44_add_del_address_range(self.nat_addr_n,
6519 self.nat_addr_n, is_add=0)
6521 @unittest.skip('Temporary disabled')
6522 def test_464xlat_ce_no_nat(self):
6523 """ Test 464XLAT CE without NAT44 """
6525 self.configure_xlat()
6527 out_src_ip6 = self.compose_ip6(self.dst_ip4, self.dst_ip6_pfx,
6528 self.dst_ip6_pfx_len)
6529 out_dst_ip6 = self.compose_ip6(self.pg0.remote_ip4, self.src_ip6_pfx,
6530 self.src_ip6_pfx_len)
6532 pkts = self.create_stream_in(self.pg0, self.pg1, self.dst_ip4)
6533 self.pg0.add_stream(pkts)
6534 self.pg_enable_capture(self.pg_interfaces)
6536 capture = self.pg1.get_capture(len(pkts))
6537 self.verify_capture_out_ip6(capture, dst_ip=out_src_ip6,
6538 nat_ip=out_dst_ip6, same_port=True)
6540 pkts = self.create_stream_out_ip6(self.pg1, out_src_ip6, out_dst_ip6)
6541 self.pg1.add_stream(pkts)
6542 self.pg_enable_capture(self.pg_interfaces)
6544 capture = self.pg0.get_capture(len(pkts))
6545 self.verify_capture_in(capture, self.pg0)
6548 class TestDeterministicNAT(MethodHolder):
6549 """ Deterministic NAT Test Cases """
6552 def setUpConstants(cls):
6553 super(TestDeterministicNAT, cls).setUpConstants()
6554 cls.vpp_cmdline.extend(["nat", "{", "deterministic", "}"])
6557 def setUpClass(cls):
6558 super(TestDeterministicNAT, cls).setUpClass()
6559 cls.vapi.cli("set log class nat level debug")
6562 cls.tcp_port_in = 6303
6563 cls.tcp_external_port = 6303
6564 cls.udp_port_in = 6304
6565 cls.udp_external_port = 6304
6566 cls.icmp_id_in = 6305
6567 cls.nat_addr = '10.0.0.3'
6569 cls.create_pg_interfaces(range(3))
6570 cls.interfaces = list(cls.pg_interfaces)
6572 for i in cls.interfaces:
6577 cls.pg0.generate_remote_hosts(2)
6578 cls.pg0.configure_ipv4_neighbors()
6581 super(TestDeterministicNAT, cls).tearDownClass()
6584 def create_stream_in(self, in_if, out_if, ttl=64):
6586 Create packet stream for inside network
6588 :param in_if: Inside interface
6589 :param out_if: Outside interface
6590 :param ttl: TTL of generated packets
6594 p = (Ether(dst=in_if.local_mac, src=in_if.remote_mac) /
6595 IP(src=in_if.remote_ip4, dst=out_if.remote_ip4, ttl=ttl) /
6596 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port))
6600 p = (Ether(dst=in_if.local_mac, src=in_if.remote_mac) /
6601 IP(src=in_if.remote_ip4, dst=out_if.remote_ip4, ttl=ttl) /
6602 UDP(sport=self.udp_port_in, dport=self.udp_external_port))
6606 p = (Ether(dst=in_if.local_mac, src=in_if.remote_mac) /
6607 IP(src=in_if.remote_ip4, dst=out_if.remote_ip4, ttl=ttl) /
6608 ICMP(id=self.icmp_id_in, type='echo-request'))
6613 def create_stream_out(self, out_if, dst_ip=None, ttl=64):
6615 Create packet stream for outside network
6617 :param out_if: Outside interface
6618 :param dst_ip: Destination IP address (Default use global NAT address)
6619 :param ttl: TTL of generated packets
6622 dst_ip = self.nat_addr
6625 p = (Ether(dst=out_if.local_mac, src=out_if.remote_mac) /
6626 IP(src=out_if.remote_ip4, dst=dst_ip, ttl=ttl) /
6627 TCP(dport=self.tcp_port_out, sport=self.tcp_external_port))
6631 p = (Ether(dst=out_if.local_mac, src=out_if.remote_mac) /
6632 IP(src=out_if.remote_ip4, dst=dst_ip, ttl=ttl) /
6633 UDP(dport=self.udp_port_out, sport=self.udp_external_port))
6637 p = (Ether(dst=out_if.local_mac, src=out_if.remote_mac) /
6638 IP(src=out_if.remote_ip4, dst=dst_ip, ttl=ttl) /
6639 ICMP(id=self.icmp_external_id, type='echo-reply'))
6644 def verify_capture_out(self, capture, nat_ip=None):
6646 Verify captured packets on outside network
6648 :param capture: Captured packets
6649 :param nat_ip: Translated IP address (Default use global NAT address)
6650 :param same_port: Source port number is not translated (Default False)
6653 nat_ip = self.nat_addr
6654 for packet in capture:
6656 self.assertEqual(packet[IP].src, nat_ip)
6657 if packet.haslayer(TCP):
6658 self.tcp_port_out = packet[TCP].sport
6659 elif packet.haslayer(UDP):
6660 self.udp_port_out = packet[UDP].sport
6662 self.icmp_external_id = packet[ICMP].id
6664 self.logger.error(ppp("Unexpected or invalid packet "
6665 "(outside network):", packet))
6668 def test_deterministic_mode(self):
6669 """ NAT plugin run deterministic mode """
6670 in_addr = '172.16.255.0'
6671 out_addr = '172.17.255.50'
6672 in_addr_t = '172.16.255.20'
6673 in_addr_n = socket.inet_aton(in_addr)
6674 out_addr_n = socket.inet_aton(out_addr)
6675 in_addr_t_n = socket.inet_aton(in_addr_t)
6679 nat_config = self.vapi.nat_show_config()
6680 self.assertEqual(1, nat_config.deterministic)
6682 self.vapi.nat_det_add_del_map(in_addr_n, in_plen, out_addr_n, out_plen)
6684 rep1 = self.vapi.nat_det_forward(in_addr_t_n)
6685 self.assertEqual(rep1.out_addr[:4], out_addr_n)
6686 rep2 = self.vapi.nat_det_reverse(out_addr_n, rep1.out_port_hi)
6687 self.assertEqual(rep2.in_addr[:4], in_addr_t_n)
6689 deterministic_mappings = self.vapi.nat_det_map_dump()
6690 self.assertEqual(len(deterministic_mappings), 1)
6691 dsm = deterministic_mappings[0]
6692 self.assertEqual(in_addr_n, dsm.in_addr[:4])
6693 self.assertEqual(in_plen, dsm.in_plen)
6694 self.assertEqual(out_addr_n, dsm.out_addr[:4])
6695 self.assertEqual(out_plen, dsm.out_plen)
6697 self.clear_nat_det()
6698 deterministic_mappings = self.vapi.nat_det_map_dump()
6699 self.assertEqual(len(deterministic_mappings), 0)
6701 def test_set_timeouts(self):
6702 """ Set deterministic NAT timeouts """
6703 timeouts_before = self.vapi.nat_get_timeouts()
6705 self.vapi.nat_set_timeouts(timeouts_before.udp + 10,
6706 timeouts_before.tcp_established + 10,
6707 timeouts_before.tcp_transitory + 10,
6708 timeouts_before.icmp + 10)
6710 timeouts_after = self.vapi.nat_get_timeouts()
6712 self.assertNotEqual(timeouts_before.udp, timeouts_after.udp)
6713 self.assertNotEqual(timeouts_before.icmp, timeouts_after.icmp)
6714 self.assertNotEqual(timeouts_before.tcp_established,
6715 timeouts_after.tcp_established)
6716 self.assertNotEqual(timeouts_before.tcp_transitory,
6717 timeouts_after.tcp_transitory)
6719 def test_det_in(self):
6720 """ Deterministic NAT translation test (TCP, UDP, ICMP) """
6722 nat_ip = "10.0.0.10"
6724 self.vapi.nat_det_add_del_map(self.pg0.remote_ip4n,
6726 socket.inet_aton(nat_ip),
6728 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
6729 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
6733 pkts = self.create_stream_in(self.pg0, self.pg1)
6734 self.pg0.add_stream(pkts)
6735 self.pg_enable_capture(self.pg_interfaces)
6737 capture = self.pg1.get_capture(len(pkts))
6738 self.verify_capture_out(capture, nat_ip)
6741 pkts = self.create_stream_out(self.pg1, nat_ip)
6742 self.pg1.add_stream(pkts)
6743 self.pg_enable_capture(self.pg_interfaces)
6745 capture = self.pg0.get_capture(len(pkts))
6746 self.verify_capture_in(capture, self.pg0)
6749 sessions = self.vapi.nat_det_session_dump(self.pg0.remote_ip4n)
6750 self.assertEqual(len(sessions), 3)
6754 self.assertEqual(s.ext_addr[:4], self.pg1.remote_ip4n)
6755 self.assertEqual(s.in_port, self.tcp_port_in)
6756 self.assertEqual(s.out_port, self.tcp_port_out)
6757 self.assertEqual(s.ext_port, self.tcp_external_port)
6761 self.assertEqual(s.ext_addr[:4], self.pg1.remote_ip4n)
6762 self.assertEqual(s.in_port, self.udp_port_in)
6763 self.assertEqual(s.out_port, self.udp_port_out)
6764 self.assertEqual(s.ext_port, self.udp_external_port)
6768 self.assertEqual(s.ext_addr[:4], self.pg1.remote_ip4n)
6769 self.assertEqual(s.in_port, self.icmp_id_in)
6770 self.assertEqual(s.out_port, self.icmp_external_id)
6772 def test_multiple_users(self):
6773 """ Deterministic NAT multiple users """
6775 nat_ip = "10.0.0.10"
6777 external_port = 6303
6779 host0 = self.pg0.remote_hosts[0]
6780 host1 = self.pg0.remote_hosts[1]
6782 self.vapi.nat_det_add_del_map(host0.ip4n,
6784 socket.inet_aton(nat_ip),
6786 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
6787 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
6791 p = (Ether(src=host0.mac, dst=self.pg0.local_mac) /
6792 IP(src=host0.ip4, dst=self.pg1.remote_ip4) /
6793 TCP(sport=port_in, dport=external_port))
6794 self.pg0.add_stream(p)
6795 self.pg_enable_capture(self.pg_interfaces)
6797 capture = self.pg1.get_capture(1)
6802 self.assertEqual(ip.src, nat_ip)
6803 self.assertEqual(ip.dst, self.pg1.remote_ip4)
6804 self.assertEqual(tcp.dport, external_port)
6805 port_out0 = tcp.sport
6807 self.logger.error(ppp("Unexpected or invalid packet:", p))
6811 p = (Ether(src=host1.mac, dst=self.pg0.local_mac) /
6812 IP(src=host1.ip4, dst=self.pg1.remote_ip4) /
6813 TCP(sport=port_in, dport=external_port))
6814 self.pg0.add_stream(p)
6815 self.pg_enable_capture(self.pg_interfaces)
6817 capture = self.pg1.get_capture(1)
6822 self.assertEqual(ip.src, nat_ip)
6823 self.assertEqual(ip.dst, self.pg1.remote_ip4)
6824 self.assertEqual(tcp.dport, external_port)
6825 port_out1 = tcp.sport
6827 self.logger.error(ppp("Unexpected or invalid packet:", p))
6830 dms = self.vapi.nat_det_map_dump()
6831 self.assertEqual(1, len(dms))
6832 self.assertEqual(2, dms[0].ses_num)
6835 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
6836 IP(src=self.pg1.remote_ip4, dst=nat_ip) /
6837 TCP(sport=external_port, dport=port_out0))
6838 self.pg1.add_stream(p)
6839 self.pg_enable_capture(self.pg_interfaces)
6841 capture = self.pg0.get_capture(1)
6846 self.assertEqual(ip.src, self.pg1.remote_ip4)
6847 self.assertEqual(ip.dst, host0.ip4)
6848 self.assertEqual(tcp.dport, port_in)
6849 self.assertEqual(tcp.sport, external_port)
6851 self.logger.error(ppp("Unexpected or invalid packet:", p))
6855 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
6856 IP(src=self.pg1.remote_ip4, dst=nat_ip) /
6857 TCP(sport=external_port, dport=port_out1))
6858 self.pg1.add_stream(p)
6859 self.pg_enable_capture(self.pg_interfaces)
6861 capture = self.pg0.get_capture(1)
6866 self.assertEqual(ip.src, self.pg1.remote_ip4)
6867 self.assertEqual(ip.dst, host1.ip4)
6868 self.assertEqual(tcp.dport, port_in)
6869 self.assertEqual(tcp.sport, external_port)
6871 self.logger.error(ppp("Unexpected or invalid packet", p))
6874 # session close api test
6875 self.vapi.nat_det_close_session_out(socket.inet_aton(nat_ip),
6877 self.pg1.remote_ip4n,
6879 dms = self.vapi.nat_det_map_dump()
6880 self.assertEqual(dms[0].ses_num, 1)
6882 self.vapi.nat_det_close_session_in(host0.ip4n,
6884 self.pg1.remote_ip4n,
6886 dms = self.vapi.nat_det_map_dump()
6887 self.assertEqual(dms[0].ses_num, 0)
6889 def test_tcp_session_close_detection_in(self):
6890 """ Deterministic NAT TCP session close from inside network """
6891 self.vapi.nat_det_add_del_map(self.pg0.remote_ip4n,
6893 socket.inet_aton(self.nat_addr),
6895 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
6896 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
6899 self.initiate_tcp_session(self.pg0, self.pg1)
6901 # close the session from inside
6903 # FIN packet in -> out
6904 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6905 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6906 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
6908 self.pg0.add_stream(p)
6909 self.pg_enable_capture(self.pg_interfaces)
6911 self.pg1.get_capture(1)
6915 # ACK packet out -> in
6916 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
6917 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
6918 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
6922 # FIN packet out -> in
6923 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
6924 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
6925 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
6929 self.pg1.add_stream(pkts)
6930 self.pg_enable_capture(self.pg_interfaces)
6932 self.pg0.get_capture(2)
6934 # ACK packet in -> out
6935 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6936 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6937 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
6939 self.pg0.add_stream(p)
6940 self.pg_enable_capture(self.pg_interfaces)
6942 self.pg1.get_capture(1)
6944 # Check if deterministic NAT44 closed the session
6945 dms = self.vapi.nat_det_map_dump()
6946 self.assertEqual(0, dms[0].ses_num)
6948 self.logger.error("TCP session termination failed")
6951 def test_tcp_session_close_detection_out(self):
6952 """ Deterministic NAT TCP session close from outside network """
6953 self.vapi.nat_det_add_del_map(self.pg0.remote_ip4n,
6955 socket.inet_aton(self.nat_addr),
6957 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
6958 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
6961 self.initiate_tcp_session(self.pg0, self.pg1)
6963 # close the session from outside
6965 # FIN packet out -> in
6966 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
6967 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
6968 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
6970 self.pg1.add_stream(p)
6971 self.pg_enable_capture(self.pg_interfaces)
6973 self.pg0.get_capture(1)
6977 # ACK packet in -> out
6978 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6979 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6980 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
6984 # ACK packet in -> out
6985 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6986 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6987 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
6991 self.pg0.add_stream(pkts)
6992 self.pg_enable_capture(self.pg_interfaces)
6994 self.pg1.get_capture(2)
6996 # ACK packet out -> in
6997 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
6998 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
6999 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
7001 self.pg1.add_stream(p)
7002 self.pg_enable_capture(self.pg_interfaces)
7004 self.pg0.get_capture(1)
7006 # Check if deterministic NAT44 closed the session
7007 dms = self.vapi.nat_det_map_dump()
7008 self.assertEqual(0, dms[0].ses_num)
7010 self.logger.error("TCP session termination failed")
7013 @unittest.skipUnless(running_extended_tests, "part of extended tests")
7014 def test_session_timeout(self):
7015 """ Deterministic NAT session timeouts """
7016 self.vapi.nat_det_add_del_map(self.pg0.remote_ip4n,
7018 socket.inet_aton(self.nat_addr),
7020 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
7021 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
7024 self.initiate_tcp_session(self.pg0, self.pg1)
7025 self.vapi.nat_set_timeouts(5, 5, 5, 5)
7026 pkts = self.create_stream_in(self.pg0, self.pg1)
7027 self.pg0.add_stream(pkts)
7028 self.pg_enable_capture(self.pg_interfaces)
7030 capture = self.pg1.get_capture(len(pkts))
7033 dms = self.vapi.nat_det_map_dump()
7034 self.assertEqual(0, dms[0].ses_num)
7036 @unittest.skipUnless(running_extended_tests, "part of extended tests")
7037 def test_session_limit_per_user(self):
7038 """ Deterministic NAT maximum sessions per user limit """
7039 self.vapi.nat_det_add_del_map(self.pg0.remote_ip4n,
7041 socket.inet_aton(self.nat_addr),
7043 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
7044 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
7046 self.vapi.set_ipfix_exporter(collector_address=self.pg2.remote_ip4n,
7047 src_address=self.pg2.local_ip4n,
7049 template_interval=10)
7050 self.vapi.nat_ipfix_enable_disable()
7053 for port in range(1025, 2025):
7054 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
7055 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
7056 UDP(sport=port, dport=port))
7059 self.pg0.add_stream(pkts)
7060 self.pg_enable_capture(self.pg_interfaces)
7062 capture = self.pg1.get_capture(len(pkts))
7064 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
7065 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
7066 UDP(sport=3001, dport=3002))
7067 self.pg0.add_stream(p)
7068 self.pg_enable_capture(self.pg_interfaces)
7070 capture = self.pg1.assert_nothing_captured()
7072 # verify ICMP error packet
7073 capture = self.pg0.get_capture(1)
7075 self.assertTrue(p.haslayer(ICMP))
7077 self.assertEqual(icmp.type, 3)
7078 self.assertEqual(icmp.code, 1)
7079 self.assertTrue(icmp.haslayer(IPerror))
7080 inner_ip = icmp[IPerror]
7081 self.assertEqual(inner_ip[UDPerror].sport, 3001)
7082 self.assertEqual(inner_ip[UDPerror].dport, 3002)
7084 dms = self.vapi.nat_det_map_dump()
7086 self.assertEqual(1000, dms[0].ses_num)
7088 # verify IPFIX logging
7089 self.vapi.cli("ipfix flush") # FIXME this should be an API call
7091 capture = self.pg2.get_capture(2)
7092 ipfix = IPFIXDecoder()
7093 # first load template
7095 self.assertTrue(p.haslayer(IPFIX))
7096 if p.haslayer(Template):
7097 ipfix.add_template(p.getlayer(Template))
7098 # verify events in data set
7100 if p.haslayer(Data):
7101 data = ipfix.decode_data_set(p.getlayer(Set))
7102 self.verify_ipfix_max_entries_per_user(data,
7104 self.pg0.remote_ip4n)
7106 def clear_nat_det(self):
7108 Clear deterministic NAT configuration.
7110 self.vapi.nat_ipfix_enable_disable(enable=0)
7111 self.vapi.nat_set_timeouts()
7112 deterministic_mappings = self.vapi.nat_det_map_dump()
7113 for dsm in deterministic_mappings:
7114 self.vapi.nat_det_add_del_map(dsm.in_addr,
7120 interfaces = self.vapi.nat44_interface_dump()
7121 for intf in interfaces:
7122 self.vapi.nat44_interface_add_del_feature(intf.sw_if_index,
7127 super(TestDeterministicNAT, self).tearDown()
7128 if not self.vpp_dead:
7129 self.logger.info(self.vapi.cli("show nat44 interfaces"))
7130 self.logger.info(self.vapi.cli("show nat timeouts"))
7132 self.vapi.cli("show nat44 deterministic mappings"))
7134 self.vapi.cli("show nat44 deterministic sessions"))
7135 self.clear_nat_det()
7138 class TestNAT64(MethodHolder):
7139 """ NAT64 Test Cases """
7142 def setUpConstants(cls):
7143 super(TestNAT64, cls).setUpConstants()
7144 cls.vpp_cmdline.extend(["nat", "{", "nat64 bib hash buckets 128",
7145 "nat64 st hash buckets 256", "}"])
7148 def setUpClass(cls):
7149 super(TestNAT64, cls).setUpClass()
7152 cls.tcp_port_in = 6303
7153 cls.tcp_port_out = 6303
7154 cls.udp_port_in = 6304
7155 cls.udp_port_out = 6304
7156 cls.icmp_id_in = 6305
7157 cls.icmp_id_out = 6305
7158 cls.tcp_external_port = 80
7159 cls.nat_addr = '10.0.0.3'
7160 cls.nat_addr_n = socket.inet_pton(socket.AF_INET, cls.nat_addr)
7162 cls.vrf1_nat_addr = '10.0.10.3'
7163 cls.vrf1_nat_addr_n = socket.inet_pton(socket.AF_INET,
7165 cls.ipfix_src_port = 4739
7166 cls.ipfix_domain_id = 1
7168 cls.create_pg_interfaces(range(6))
7169 cls.ip6_interfaces = list(cls.pg_interfaces[0:1])
7170 cls.ip6_interfaces.append(cls.pg_interfaces[2])
7171 cls.ip4_interfaces = list(cls.pg_interfaces[1:2])
7173 cls.vapi.ip_table_add_del(is_ipv6=1, is_add=1,
7174 table_id=cls.vrf1_id)
7176 cls.pg_interfaces[2].set_table_ip6(cls.vrf1_id)
7178 cls.pg0.generate_remote_hosts(2)
7180 for i in cls.ip6_interfaces:
7183 i.configure_ipv6_neighbors()
7185 for i in cls.ip4_interfaces:
7191 cls.pg3.config_ip4()
7192 cls.pg3.resolve_arp()
7193 cls.pg3.config_ip6()
7194 cls.pg3.configure_ipv6_neighbors()
7197 cls.pg5.config_ip6()
7200 super(TestNAT64, cls).tearDownClass()
7203 def test_nat64_inside_interface_handles_neighbor_advertisement(self):
7204 """ NAT64 inside interface handles Neighbor Advertisement """
7206 self.vapi.nat64_add_del_interface(self.pg5.sw_if_index)
7209 ping = (Ether(dst=self.pg5.local_mac, src=self.pg5.remote_mac) /
7210 IPv6(src=self.pg5.remote_ip6, dst=self.pg5.local_ip6) /
7211 ICMPv6EchoRequest())
7213 self.pg5.add_stream(pkts)
7214 self.pg_enable_capture(self.pg_interfaces)
7217 # Wait for Neighbor Solicitation
7218 capture = self.pg5.get_capture(len(pkts))
7221 self.assertEqual(packet[IPv6].src, self.pg5.local_ip6)
7222 self.assertEqual(packet.haslayer(ICMPv6ND_NS), 1)
7223 tgt = packet[ICMPv6ND_NS].tgt
7225 self.logger.error(ppp("Unexpected or invalid packet:", packet))
7228 # Send Neighbor Advertisement
7229 p = (Ether(dst=self.pg5.local_mac, src=self.pg5.remote_mac) /
7230 IPv6(src=self.pg5.remote_ip6, dst=self.pg5.local_ip6) /
7231 ICMPv6ND_NA(tgt=tgt) /
7232 ICMPv6NDOptDstLLAddr(lladdr=self.pg5.remote_mac))
7234 self.pg5.add_stream(pkts)
7235 self.pg_enable_capture(self.pg_interfaces)
7238 # Try to send ping again
7240 self.pg5.add_stream(pkts)
7241 self.pg_enable_capture(self.pg_interfaces)
7244 # Wait for ping reply
7245 capture = self.pg5.get_capture(len(pkts))
7248 self.assertEqual(packet[IPv6].src, self.pg5.local_ip6)
7249 self.assertEqual(packet[IPv6].dst, self.pg5.remote_ip6)
7250 self.assertEqual(packet.haslayer(ICMPv6EchoReply), 1)
7252 self.logger.error(ppp("Unexpected or invalid packet:", packet))
7255 def test_pool(self):
7256 """ Add/delete address to NAT64 pool """
7257 nat_addr = socket.inet_pton(socket.AF_INET, '1.2.3.4')
7259 self.vapi.nat64_add_del_pool_addr_range(nat_addr, nat_addr)
7261 addresses = self.vapi.nat64_pool_addr_dump()
7262 self.assertEqual(len(addresses), 1)
7263 self.assertEqual(addresses[0].address, nat_addr)
7265 self.vapi.nat64_add_del_pool_addr_range(nat_addr, nat_addr, is_add=0)
7267 addresses = self.vapi.nat64_pool_addr_dump()
7268 self.assertEqual(len(addresses), 0)
7270 def test_interface(self):
7271 """ Enable/disable NAT64 feature on the interface """
7272 self.vapi.nat64_add_del_interface(self.pg0.sw_if_index)
7273 self.vapi.nat64_add_del_interface(self.pg1.sw_if_index, is_inside=0)
7275 interfaces = self.vapi.nat64_interface_dump()
7276 self.assertEqual(len(interfaces), 2)
7279 for intf in interfaces:
7280 if intf.sw_if_index == self.pg0.sw_if_index:
7281 self.assertEqual(intf.is_inside, 1)
7283 elif intf.sw_if_index == self.pg1.sw_if_index:
7284 self.assertEqual(intf.is_inside, 0)
7286 self.assertTrue(pg0_found)
7287 self.assertTrue(pg1_found)
7289 features = self.vapi.cli("show interface features pg0")
7290 self.assertIn('nat64-in2out', features)
7291 features = self.vapi.cli("show interface features pg1")
7292 self.assertIn('nat64-out2in', features)
7294 self.vapi.nat64_add_del_interface(self.pg0.sw_if_index, is_add=0)
7295 self.vapi.nat64_add_del_interface(self.pg1.sw_if_index, is_add=0)
7297 interfaces = self.vapi.nat64_interface_dump()
7298 self.assertEqual(len(interfaces), 0)
7300 def test_static_bib(self):
7301 """ Add/delete static BIB entry """
7302 in_addr = socket.inet_pton(socket.AF_INET6,
7303 '2001:db8:85a3::8a2e:370:7334')
7304 out_addr = socket.inet_pton(socket.AF_INET, '10.1.1.3')
7307 proto = IP_PROTOS.tcp
7309 self.vapi.nat64_add_del_static_bib(in_addr,
7314 bib = self.vapi.nat64_bib_dump(IP_PROTOS.tcp)
7319 self.assertEqual(bibe.i_addr, in_addr)
7320 self.assertEqual(bibe.o_addr, out_addr)
7321 self.assertEqual(bibe.i_port, in_port)
7322 self.assertEqual(bibe.o_port, out_port)
7323 self.assertEqual(static_bib_num, 1)
7324 bibs = self.statistics.get_counter('/nat64/total-bibs')
7325 self.assertEqual(bibs[0][0], 1)
7327 self.vapi.nat64_add_del_static_bib(in_addr,
7333 bib = self.vapi.nat64_bib_dump(IP_PROTOS.tcp)
7338 self.assertEqual(static_bib_num, 0)
7339 bibs = self.statistics.get_counter('/nat64/total-bibs')
7340 self.assertEqual(bibs[0][0], 0)
7342 def test_set_timeouts(self):
7343 """ Set NAT64 timeouts """
7344 # verify default values
7345 timeouts = self.vapi.nat_get_timeouts()
7346 self.assertEqual(timeouts.udp, 300)
7347 self.assertEqual(timeouts.icmp, 60)
7348 self.assertEqual(timeouts.tcp_transitory, 240)
7349 self.assertEqual(timeouts.tcp_established, 7440)
7351 # set and verify custom values
7352 self.vapi.nat_set_timeouts(udp=200, icmp=30, tcp_transitory=250,
7353 tcp_established=7450)
7354 timeouts = self.vapi.nat_get_timeouts()
7355 self.assertEqual(timeouts.udp, 200)
7356 self.assertEqual(timeouts.icmp, 30)
7357 self.assertEqual(timeouts.tcp_transitory, 250)
7358 self.assertEqual(timeouts.tcp_established, 7450)
7360 def test_dynamic(self):
7361 """ NAT64 dynamic translation test """
7362 self.tcp_port_in = 6303
7363 self.udp_port_in = 6304
7364 self.icmp_id_in = 6305
7366 ses_num_start = self.nat64_get_ses_num()
7368 self.vapi.nat64_add_del_pool_addr_range(self.nat_addr_n,
7370 self.vapi.nat64_add_del_interface(self.pg0.sw_if_index)
7371 self.vapi.nat64_add_del_interface(self.pg1.sw_if_index, is_inside=0)
7374 tcpn = self.statistics.get_counter('/err/nat64-in2out/TCP packets')
7375 udpn = self.statistics.get_counter('/err/nat64-in2out/UDP packets')
7376 icmpn = self.statistics.get_counter('/err/nat64-in2out/ICMP packets')
7377 totaln = self.statistics.get_counter(
7378 '/err/nat64-in2out/good in2out packets processed')
7380 pkts = self.create_stream_in_ip6(self.pg0, self.pg1)
7381 self.pg0.add_stream(pkts)
7382 self.pg_enable_capture(self.pg_interfaces)
7384 capture = self.pg1.get_capture(len(pkts))
7385 self.verify_capture_out(capture, nat_ip=self.nat_addr,
7386 dst_ip=self.pg1.remote_ip4)
7388 err = self.statistics.get_counter('/err/nat64-in2out/TCP packets')
7389 self.assertEqual(err - tcpn, 1)
7390 err = self.statistics.get_counter('/err/nat64-in2out/UDP packets')
7391 self.assertEqual(err - udpn, 1)
7392 err = self.statistics.get_counter('/err/nat64-in2out/ICMP packets')
7393 self.assertEqual(err - icmpn, 1)
7394 err = self.statistics.get_counter(
7395 '/err/nat64-in2out/good in2out packets processed')
7396 self.assertEqual(err - totaln, 3)
7399 tcpn = self.statistics.get_counter('/err/nat64-out2in/TCP packets')
7400 udpn = self.statistics.get_counter('/err/nat64-out2in/UDP packets')
7401 icmpn = self.statistics.get_counter('/err/nat64-out2in/ICMP packets')
7402 totaln = self.statistics.get_counter(
7403 '/err/nat64-out2in/good out2in packets processed')
7405 pkts = self.create_stream_out(self.pg1, dst_ip=self.nat_addr)
7406 self.pg1.add_stream(pkts)
7407 self.pg_enable_capture(self.pg_interfaces)
7409 capture = self.pg0.get_capture(len(pkts))
7410 ip = IPv6(src=''.join(['64:ff9b::', self.pg1.remote_ip4]))
7411 self.verify_capture_in_ip6(capture, ip[IPv6].src, self.pg0.remote_ip6)
7413 err = self.statistics.get_counter('/err/nat64-out2in/TCP packets')
7414 self.assertEqual(err - tcpn, 1)
7415 err = self.statistics.get_counter('/err/nat64-out2in/UDP packets')
7416 self.assertEqual(err - udpn, 1)
7417 err = self.statistics.get_counter('/err/nat64-out2in/ICMP packets')
7418 self.assertEqual(err - icmpn, 1)
7419 err = self.statistics.get_counter(
7420 '/err/nat64-out2in/good out2in packets processed')
7421 self.assertEqual(err - totaln, 3)
7423 bibs = self.statistics.get_counter('/nat64/total-bibs')
7424 self.assertEqual(bibs[0][0], 3)
7425 sessions = self.statistics.get_counter('/nat64/total-sessions')
7426 self.assertEqual(sessions[0][0], 3)
7429 pkts = self.create_stream_in_ip6(self.pg0, self.pg1)
7430 self.pg0.add_stream(pkts)
7431 self.pg_enable_capture(self.pg_interfaces)
7433 capture = self.pg1.get_capture(len(pkts))
7434 self.verify_capture_out(capture, nat_ip=self.nat_addr,
7435 dst_ip=self.pg1.remote_ip4)
7438 pkts = self.create_stream_out(self.pg1, dst_ip=self.nat_addr)
7439 self.pg1.add_stream(pkts)
7440 self.pg_enable_capture(self.pg_interfaces)
7442 capture = self.pg0.get_capture(len(pkts))
7443 self.verify_capture_in_ip6(capture, ip[IPv6].src, self.pg0.remote_ip6)
7445 ses_num_end = self.nat64_get_ses_num()
7447 self.assertEqual(ses_num_end - ses_num_start, 3)
7449 # tenant with specific VRF
7450 self.vapi.nat64_add_del_pool_addr_range(self.vrf1_nat_addr_n,
7451 self.vrf1_nat_addr_n,
7452 vrf_id=self.vrf1_id)
7453 self.vapi.nat64_add_del_interface(self.pg2.sw_if_index)
7455 pkts = self.create_stream_in_ip6(self.pg2, self.pg1)
7456 self.pg2.add_stream(pkts)
7457 self.pg_enable_capture(self.pg_interfaces)
7459 capture = self.pg1.get_capture(len(pkts))
7460 self.verify_capture_out(capture, nat_ip=self.vrf1_nat_addr,
7461 dst_ip=self.pg1.remote_ip4)
7463 pkts = self.create_stream_out(self.pg1, dst_ip=self.vrf1_nat_addr)
7464 self.pg1.add_stream(pkts)
7465 self.pg_enable_capture(self.pg_interfaces)
7467 capture = self.pg2.get_capture(len(pkts))
7468 self.verify_capture_in_ip6(capture, ip[IPv6].src, self.pg2.remote_ip6)
7470 def test_static(self):
7471 """ NAT64 static translation test """
7472 self.tcp_port_in = 60303
7473 self.udp_port_in = 60304
7474 self.icmp_id_in = 60305
7475 self.tcp_port_out = 60303
7476 self.udp_port_out = 60304
7477 self.icmp_id_out = 60305
7479 ses_num_start = self.nat64_get_ses_num()
7481 self.vapi.nat64_add_del_pool_addr_range(self.nat_addr_n,
7483 self.vapi.nat64_add_del_interface(self.pg0.sw_if_index)
7484 self.vapi.nat64_add_del_interface(self.pg1.sw_if_index, is_inside=0)
7486 self.vapi.nat64_add_del_static_bib(self.pg0.remote_ip6n,
7491 self.vapi.nat64_add_del_static_bib(self.pg0.remote_ip6n,
7496 self.vapi.nat64_add_del_static_bib(self.pg0.remote_ip6n,
7503 pkts = self.create_stream_in_ip6(self.pg0, self.pg1)
7504 self.pg0.add_stream(pkts)
7505 self.pg_enable_capture(self.pg_interfaces)
7507 capture = self.pg1.get_capture(len(pkts))
7508 self.verify_capture_out(capture, nat_ip=self.nat_addr,
7509 dst_ip=self.pg1.remote_ip4, same_port=True)
7512 pkts = self.create_stream_out(self.pg1, dst_ip=self.nat_addr)
7513 self.pg1.add_stream(pkts)
7514 self.pg_enable_capture(self.pg_interfaces)
7516 capture = self.pg0.get_capture(len(pkts))
7517 ip = IPv6(src=''.join(['64:ff9b::', self.pg1.remote_ip4]))
7518 self.verify_capture_in_ip6(capture, ip[IPv6].src, self.pg0.remote_ip6)
7520 ses_num_end = self.nat64_get_ses_num()
7522 self.assertEqual(ses_num_end - ses_num_start, 3)
7524 @unittest.skipUnless(running_extended_tests, "part of extended tests")
7525 def test_session_timeout(self):
7526 """ NAT64 session timeout """
7527 self.icmp_id_in = 1234
7528 self.vapi.nat64_add_del_pool_addr_range(self.nat_addr_n,
7530 self.vapi.nat64_add_del_interface(self.pg0.sw_if_index)
7531 self.vapi.nat64_add_del_interface(self.pg1.sw_if_index, is_inside=0)
7532 self.vapi.nat_set_timeouts(icmp=5, tcp_transitory=5, tcp_established=5)
7534 pkts = self.create_stream_in_ip6(self.pg0, self.pg1)
7535 self.pg0.add_stream(pkts)
7536 self.pg_enable_capture(self.pg_interfaces)
7538 capture = self.pg1.get_capture(len(pkts))
7540 ses_num_before_timeout = self.nat64_get_ses_num()
7544 # ICMP and TCP session after timeout
7545 ses_num_after_timeout = self.nat64_get_ses_num()
7546 self.assertEqual(ses_num_before_timeout - ses_num_after_timeout, 2)
7548 def test_icmp_error(self):
7549 """ NAT64 ICMP Error message translation """
7550 self.tcp_port_in = 6303
7551 self.udp_port_in = 6304
7552 self.icmp_id_in = 6305
7554 self.vapi.nat64_add_del_pool_addr_range(self.nat_addr_n,
7556 self.vapi.nat64_add_del_interface(self.pg0.sw_if_index)
7557 self.vapi.nat64_add_del_interface(self.pg1.sw_if_index, is_inside=0)
7559 # send some packets to create sessions
7560 pkts = self.create_stream_in_ip6(self.pg0, self.pg1)
7561 self.pg0.add_stream(pkts)
7562 self.pg_enable_capture(self.pg_interfaces)
7564 capture_ip4 = self.pg1.get_capture(len(pkts))
7565 self.verify_capture_out(capture_ip4,
7566 nat_ip=self.nat_addr,
7567 dst_ip=self.pg1.remote_ip4)
7569 pkts = self.create_stream_out(self.pg1, dst_ip=self.nat_addr)
7570 self.pg1.add_stream(pkts)
7571 self.pg_enable_capture(self.pg_interfaces)
7573 capture_ip6 = self.pg0.get_capture(len(pkts))
7574 ip = IPv6(src=''.join(['64:ff9b::', self.pg1.remote_ip4]))
7575 self.verify_capture_in_ip6(capture_ip6, ip[IPv6].src,
7576 self.pg0.remote_ip6)
7579 pkts = [Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
7580 IPv6(src=self.pg0.remote_ip6, dst=ip[IPv6].src) /
7581 ICMPv6DestUnreach(code=1) /
7582 packet[IPv6] for packet in capture_ip6]
7583 self.pg0.add_stream(pkts)
7584 self.pg_enable_capture(self.pg_interfaces)
7586 capture = self.pg1.get_capture(len(pkts))
7587 for packet in capture:
7589 self.assertEqual(packet[IP].src, self.nat_addr)
7590 self.assertEqual(packet[IP].dst, self.pg1.remote_ip4)
7591 self.assertEqual(packet[ICMP].type, 3)
7592 self.assertEqual(packet[ICMP].code, 13)
7593 inner = packet[IPerror]
7594 self.assertEqual(inner.src, self.pg1.remote_ip4)
7595 self.assertEqual(inner.dst, self.nat_addr)
7596 self.assert_packet_checksums_valid(packet)
7597 if inner.haslayer(TCPerror):
7598 self.assertEqual(inner[TCPerror].dport, self.tcp_port_out)
7599 elif inner.haslayer(UDPerror):
7600 self.assertEqual(inner[UDPerror].dport, self.udp_port_out)
7602 self.assertEqual(inner[ICMPerror].id, self.icmp_id_out)
7604 self.logger.error(ppp("Unexpected or invalid packet:", packet))
7608 pkts = [Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
7609 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
7610 ICMP(type=3, code=13) /
7611 packet[IP] for packet in capture_ip4]
7612 self.pg1.add_stream(pkts)
7613 self.pg_enable_capture(self.pg_interfaces)
7615 capture = self.pg0.get_capture(len(pkts))
7616 for packet in capture:
7618 self.assertEqual(packet[IPv6].src, ip.src)
7619 self.assertEqual(packet[IPv6].dst, self.pg0.remote_ip6)
7620 icmp = packet[ICMPv6DestUnreach]
7621 self.assertEqual(icmp.code, 1)
7622 inner = icmp[IPerror6]
7623 self.assertEqual(inner.src, self.pg0.remote_ip6)
7624 self.assertEqual(inner.dst, ip.src)
7625 self.assert_icmpv6_checksum_valid(packet)
7626 if inner.haslayer(TCPerror):
7627 self.assertEqual(inner[TCPerror].sport, self.tcp_port_in)
7628 elif inner.haslayer(UDPerror):
7629 self.assertEqual(inner[UDPerror].sport, self.udp_port_in)
7631 self.assertEqual(inner[ICMPv6EchoRequest].id,
7634 self.logger.error(ppp("Unexpected or invalid packet:", packet))
7637 def test_hairpinning(self):
7638 """ NAT64 hairpinning """
7640 client = self.pg0.remote_hosts[0]
7641 server = self.pg0.remote_hosts[1]
7642 server_tcp_in_port = 22
7643 server_tcp_out_port = 4022
7644 server_udp_in_port = 23
7645 server_udp_out_port = 4023
7646 client_tcp_in_port = 1234
7647 client_udp_in_port = 1235
7648 client_tcp_out_port = 0
7649 client_udp_out_port = 0
7650 ip = IPv6(src=''.join(['64:ff9b::', self.nat_addr]))
7651 nat_addr_ip6 = ip.src
7653 self.vapi.nat64_add_del_pool_addr_range(self.nat_addr_n,
7655 self.vapi.nat64_add_del_interface(self.pg0.sw_if_index)
7656 self.vapi.nat64_add_del_interface(self.pg1.sw_if_index, is_inside=0)
7658 self.vapi.nat64_add_del_static_bib(server.ip6n,
7661 server_tcp_out_port,
7663 self.vapi.nat64_add_del_static_bib(server.ip6n,
7666 server_udp_out_port,
7671 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
7672 IPv6(src=client.ip6, dst=nat_addr_ip6) /
7673 TCP(sport=client_tcp_in_port, dport=server_tcp_out_port))
7675 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
7676 IPv6(src=client.ip6, dst=nat_addr_ip6) /
7677 UDP(sport=client_udp_in_port, dport=server_udp_out_port))
7679 self.pg0.add_stream(pkts)
7680 self.pg_enable_capture(self.pg_interfaces)
7682 capture = self.pg0.get_capture(len(pkts))
7683 for packet in capture:
7685 self.assertEqual(packet[IPv6].src, nat_addr_ip6)
7686 self.assertEqual(packet[IPv6].dst, server.ip6)
7687 self.assert_packet_checksums_valid(packet)
7688 if packet.haslayer(TCP):
7689 self.assertNotEqual(packet[TCP].sport, client_tcp_in_port)
7690 self.assertEqual(packet[TCP].dport, server_tcp_in_port)
7691 client_tcp_out_port = packet[TCP].sport
7693 self.assertNotEqual(packet[UDP].sport, client_udp_in_port)
7694 self.assertEqual(packet[UDP].dport, server_udp_in_port)
7695 client_udp_out_port = packet[UDP].sport
7697 self.logger.error(ppp("Unexpected or invalid packet:", packet))
7702 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
7703 IPv6(src=server.ip6, dst=nat_addr_ip6) /
7704 TCP(sport=server_tcp_in_port, dport=client_tcp_out_port))
7706 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
7707 IPv6(src=server.ip6, dst=nat_addr_ip6) /
7708 UDP(sport=server_udp_in_port, dport=client_udp_out_port))
7710 self.pg0.add_stream(pkts)
7711 self.pg_enable_capture(self.pg_interfaces)
7713 capture = self.pg0.get_capture(len(pkts))
7714 for packet in capture:
7716 self.assertEqual(packet[IPv6].src, nat_addr_ip6)
7717 self.assertEqual(packet[IPv6].dst, client.ip6)
7718 self.assert_packet_checksums_valid(packet)
7719 if packet.haslayer(TCP):
7720 self.assertEqual(packet[TCP].sport, server_tcp_out_port)
7721 self.assertEqual(packet[TCP].dport, client_tcp_in_port)
7723 self.assertEqual(packet[UDP].sport, server_udp_out_port)
7724 self.assertEqual(packet[UDP].dport, client_udp_in_port)
7726 self.logger.error(ppp("Unexpected or invalid packet:", packet))
7731 pkts = [Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
7732 IPv6(src=client.ip6, dst=nat_addr_ip6) /
7733 ICMPv6DestUnreach(code=1) /
7734 packet[IPv6] for packet in capture]
7735 self.pg0.add_stream(pkts)
7736 self.pg_enable_capture(self.pg_interfaces)
7738 capture = self.pg0.get_capture(len(pkts))
7739 for packet in capture:
7741 self.assertEqual(packet[IPv6].src, nat_addr_ip6)
7742 self.assertEqual(packet[IPv6].dst, server.ip6)
7743 icmp = packet[ICMPv6DestUnreach]
7744 self.assertEqual(icmp.code, 1)
7745 inner = icmp[IPerror6]
7746 self.assertEqual(inner.src, server.ip6)
7747 self.assertEqual(inner.dst, nat_addr_ip6)
7748 self.assert_packet_checksums_valid(packet)
7749 if inner.haslayer(TCPerror):
7750 self.assertEqual(inner[TCPerror].sport, server_tcp_in_port)
7751 self.assertEqual(inner[TCPerror].dport,
7752 client_tcp_out_port)
7754 self.assertEqual(inner[UDPerror].sport, server_udp_in_port)
7755 self.assertEqual(inner[UDPerror].dport,
7756 client_udp_out_port)
7758 self.logger.error(ppp("Unexpected or invalid packet:", packet))
7761 def test_prefix(self):
7762 """ NAT64 Network-Specific Prefix """
7764 self.vapi.nat64_add_del_pool_addr_range(self.nat_addr_n,
7766 self.vapi.nat64_add_del_interface(self.pg0.sw_if_index)
7767 self.vapi.nat64_add_del_interface(self.pg1.sw_if_index, is_inside=0)
7768 self.vapi.nat64_add_del_pool_addr_range(self.vrf1_nat_addr_n,
7769 self.vrf1_nat_addr_n,
7770 vrf_id=self.vrf1_id)
7771 self.vapi.nat64_add_del_interface(self.pg2.sw_if_index)
7774 global_pref64 = "2001:db8::"
7775 global_pref64_n = socket.inet_pton(socket.AF_INET6, global_pref64)
7776 global_pref64_len = 32
7777 self.vapi.nat64_add_del_prefix(global_pref64_n, global_pref64_len)
7779 prefix = self.vapi.nat64_prefix_dump()
7780 self.assertEqual(len(prefix), 1)
7781 self.assertEqual(prefix[0].prefix, global_pref64_n)
7782 self.assertEqual(prefix[0].prefix_len, global_pref64_len)
7783 self.assertEqual(prefix[0].vrf_id, 0)
7785 # Add tenant specific prefix
7786 vrf1_pref64 = "2001:db8:122:300::"
7787 vrf1_pref64_n = socket.inet_pton(socket.AF_INET6, vrf1_pref64)
7788 vrf1_pref64_len = 56
7789 self.vapi.nat64_add_del_prefix(vrf1_pref64_n,
7791 vrf_id=self.vrf1_id)
7792 prefix = self.vapi.nat64_prefix_dump()
7793 self.assertEqual(len(prefix), 2)
7796 pkts = self.create_stream_in_ip6(self.pg0,
7799 plen=global_pref64_len)
7800 self.pg0.add_stream(pkts)
7801 self.pg_enable_capture(self.pg_interfaces)
7803 capture = self.pg1.get_capture(len(pkts))
7804 self.verify_capture_out(capture, nat_ip=self.nat_addr,
7805 dst_ip=self.pg1.remote_ip4)
7807 pkts = self.create_stream_out(self.pg1, dst_ip=self.nat_addr)
7808 self.pg1.add_stream(pkts)
7809 self.pg_enable_capture(self.pg_interfaces)
7811 capture = self.pg0.get_capture(len(pkts))
7812 dst_ip = self.compose_ip6(self.pg1.remote_ip4,
7815 self.verify_capture_in_ip6(capture, dst_ip, self.pg0.remote_ip6)
7817 # Tenant specific prefix
7818 pkts = self.create_stream_in_ip6(self.pg2,
7821 plen=vrf1_pref64_len)
7822 self.pg2.add_stream(pkts)
7823 self.pg_enable_capture(self.pg_interfaces)
7825 capture = self.pg1.get_capture(len(pkts))
7826 self.verify_capture_out(capture, nat_ip=self.vrf1_nat_addr,
7827 dst_ip=self.pg1.remote_ip4)
7829 pkts = self.create_stream_out(self.pg1, dst_ip=self.vrf1_nat_addr)
7830 self.pg1.add_stream(pkts)
7831 self.pg_enable_capture(self.pg_interfaces)
7833 capture = self.pg2.get_capture(len(pkts))
7834 dst_ip = self.compose_ip6(self.pg1.remote_ip4,
7837 self.verify_capture_in_ip6(capture, dst_ip, self.pg2.remote_ip6)
7839 def test_unknown_proto(self):
7840 """ NAT64 translate packet with unknown protocol """
7842 self.vapi.nat64_add_del_pool_addr_range(self.nat_addr_n,
7844 self.vapi.nat64_add_del_interface(self.pg0.sw_if_index)
7845 self.vapi.nat64_add_del_interface(self.pg1.sw_if_index, is_inside=0)
7846 remote_ip6 = self.compose_ip6(self.pg1.remote_ip4, '64:ff9b::', 96)
7849 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
7850 IPv6(src=self.pg0.remote_ip6, dst=remote_ip6) /
7851 TCP(sport=self.tcp_port_in, dport=20))
7852 self.pg0.add_stream(p)
7853 self.pg_enable_capture(self.pg_interfaces)
7855 p = self.pg1.get_capture(1)
7857 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
7858 IPv6(src=self.pg0.remote_ip6, dst=remote_ip6, nh=47) /
7860 IP(src=self.pg2.local_ip4, dst=self.pg2.remote_ip4) /
7861 TCP(sport=1234, dport=1234))
7862 self.pg0.add_stream(p)
7863 self.pg_enable_capture(self.pg_interfaces)
7865 p = self.pg1.get_capture(1)
7868 self.assertEqual(packet[IP].src, self.nat_addr)
7869 self.assertEqual(packet[IP].dst, self.pg1.remote_ip4)
7870 self.assertEqual(packet.haslayer(GRE), 1)
7871 self.assert_packet_checksums_valid(packet)
7873 self.logger.error(ppp("Unexpected or invalid packet:", packet))
7877 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
7878 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
7880 IP(src=self.pg2.remote_ip4, dst=self.pg2.local_ip4) /
7881 TCP(sport=1234, dport=1234))
7882 self.pg1.add_stream(p)
7883 self.pg_enable_capture(self.pg_interfaces)
7885 p = self.pg0.get_capture(1)
7888 self.assertEqual(packet[IPv6].src, remote_ip6)
7889 self.assertEqual(packet[IPv6].dst, self.pg0.remote_ip6)
7890 self.assertEqual(packet[IPv6].nh, 47)
7892 self.logger.error(ppp("Unexpected or invalid packet:", packet))
7895 def test_hairpinning_unknown_proto(self):
7896 """ NAT64 translate packet with unknown protocol - hairpinning """
7898 client = self.pg0.remote_hosts[0]
7899 server = self.pg0.remote_hosts[1]
7900 server_tcp_in_port = 22
7901 server_tcp_out_port = 4022
7902 client_tcp_in_port = 1234
7903 client_tcp_out_port = 1235
7904 server_nat_ip = "10.0.0.100"
7905 client_nat_ip = "10.0.0.110"
7906 server_nat_ip_n = socket.inet_pton(socket.AF_INET, server_nat_ip)
7907 client_nat_ip_n = socket.inet_pton(socket.AF_INET, client_nat_ip)
7908 server_nat_ip6 = self.compose_ip6(server_nat_ip, '64:ff9b::', 96)
7909 client_nat_ip6 = self.compose_ip6(client_nat_ip, '64:ff9b::', 96)
7911 self.vapi.nat64_add_del_pool_addr_range(server_nat_ip_n,
7913 self.vapi.nat64_add_del_interface(self.pg0.sw_if_index)
7914 self.vapi.nat64_add_del_interface(self.pg1.sw_if_index, is_inside=0)
7916 self.vapi.nat64_add_del_static_bib(server.ip6n,
7919 server_tcp_out_port,
7922 self.vapi.nat64_add_del_static_bib(server.ip6n,
7928 self.vapi.nat64_add_del_static_bib(client.ip6n,
7931 client_tcp_out_port,
7935 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
7936 IPv6(src=client.ip6, dst=server_nat_ip6) /
7937 TCP(sport=client_tcp_in_port, dport=server_tcp_out_port))
7938 self.pg0.add_stream(p)
7939 self.pg_enable_capture(self.pg_interfaces)
7941 p = self.pg0.get_capture(1)
7943 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
7944 IPv6(src=client.ip6, dst=server_nat_ip6, nh=IP_PROTOS.gre) /
7946 IP(src=self.pg2.local_ip4, dst=self.pg2.remote_ip4) /
7947 TCP(sport=1234, dport=1234))
7948 self.pg0.add_stream(p)
7949 self.pg_enable_capture(self.pg_interfaces)
7951 p = self.pg0.get_capture(1)
7954 self.assertEqual(packet[IPv6].src, client_nat_ip6)
7955 self.assertEqual(packet[IPv6].dst, server.ip6)
7956 self.assertEqual(packet[IPv6].nh, IP_PROTOS.gre)
7958 self.logger.error(ppp("Unexpected or invalid packet:", packet))
7962 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
7963 IPv6(src=server.ip6, dst=client_nat_ip6, nh=IP_PROTOS.gre) /
7965 IP(src=self.pg2.remote_ip4, dst=self.pg2.local_ip4) /
7966 TCP(sport=1234, dport=1234))
7967 self.pg0.add_stream(p)
7968 self.pg_enable_capture(self.pg_interfaces)
7970 p = self.pg0.get_capture(1)
7973 self.assertEqual(packet[IPv6].src, server_nat_ip6)
7974 self.assertEqual(packet[IPv6].dst, client.ip6)
7975 self.assertEqual(packet[IPv6].nh, IP_PROTOS.gre)
7977 self.logger.error(ppp("Unexpected or invalid packet:", packet))
7980 def test_one_armed_nat64(self):
7981 """ One armed NAT64 """
7983 remote_host_ip6 = self.compose_ip6(self.pg3.remote_ip4,
7987 self.vapi.nat64_add_del_pool_addr_range(self.nat_addr_n,
7989 self.vapi.nat64_add_del_interface(self.pg3.sw_if_index)
7990 self.vapi.nat64_add_del_interface(self.pg3.sw_if_index, is_inside=0)
7993 p = (Ether(src=self.pg3.remote_mac, dst=self.pg3.local_mac) /
7994 IPv6(src=self.pg3.remote_ip6, dst=remote_host_ip6) /
7995 TCP(sport=12345, dport=80))
7996 self.pg3.add_stream(p)
7997 self.pg_enable_capture(self.pg_interfaces)
7999 capture = self.pg3.get_capture(1)
8004 self.assertEqual(ip.src, self.nat_addr)
8005 self.assertEqual(ip.dst, self.pg3.remote_ip4)
8006 self.assertNotEqual(tcp.sport, 12345)
8007 external_port = tcp.sport
8008 self.assertEqual(tcp.dport, 80)
8009 self.assert_packet_checksums_valid(p)
8011 self.logger.error(ppp("Unexpected or invalid packet:", p))
8015 p = (Ether(src=self.pg3.remote_mac, dst=self.pg3.local_mac) /
8016 IP(src=self.pg3.remote_ip4, dst=self.nat_addr) /
8017 TCP(sport=80, dport=external_port))
8018 self.pg3.add_stream(p)
8019 self.pg_enable_capture(self.pg_interfaces)
8021 capture = self.pg3.get_capture(1)
8026 self.assertEqual(ip.src, remote_host_ip6)
8027 self.assertEqual(ip.dst, self.pg3.remote_ip6)
8028 self.assertEqual(tcp.sport, 80)
8029 self.assertEqual(tcp.dport, 12345)
8030 self.assert_packet_checksums_valid(p)
8032 self.logger.error(ppp("Unexpected or invalid packet:", p))
8035 def test_frag_in_order(self):
8036 """ NAT64 translate fragments arriving in order """
8037 self.tcp_port_in = random.randint(1025, 65535)
8039 self.vapi.nat64_add_del_pool_addr_range(self.nat_addr_n,
8041 self.vapi.nat64_add_del_interface(self.pg0.sw_if_index)
8042 self.vapi.nat64_add_del_interface(self.pg1.sw_if_index, is_inside=0)
8044 reass = self.vapi.nat_reass_dump()
8045 reass_n_start = len(reass)
8049 pkts = self.create_stream_frag_ip6(self.pg0, self.pg1.remote_ip4,
8050 self.tcp_port_in, 20, data)
8051 self.pg0.add_stream(pkts)
8052 self.pg_enable_capture(self.pg_interfaces)
8054 frags = self.pg1.get_capture(len(pkts))
8055 p = self.reass_frags_and_verify(frags,
8057 self.pg1.remote_ip4)
8058 self.assertEqual(p[TCP].dport, 20)
8059 self.assertNotEqual(p[TCP].sport, self.tcp_port_in)
8060 self.tcp_port_out = p[TCP].sport
8061 self.assertEqual(data, p[Raw].load)
8064 data = b"A" * 4 + b"b" * 16 + b"C" * 3
8065 pkts = self.create_stream_frag(self.pg1,
8070 self.pg1.add_stream(pkts)
8071 self.pg_enable_capture(self.pg_interfaces)
8073 frags = self.pg0.get_capture(len(pkts))
8074 src = self.compose_ip6(self.pg1.remote_ip4, '64:ff9b::', 96)
8075 p = self.reass_frags_and_verify_ip6(frags, src, self.pg0.remote_ip6)
8076 self.assertEqual(p[TCP].sport, 20)
8077 self.assertEqual(p[TCP].dport, self.tcp_port_in)
8078 self.assertEqual(data, p[Raw].load)
8080 reass = self.vapi.nat_reass_dump()
8081 reass_n_end = len(reass)
8083 self.assertEqual(reass_n_end - reass_n_start, 2)
8085 def test_reass_hairpinning(self):
8086 """ NAT64 fragments hairpinning """
8088 server = self.pg0.remote_hosts[1]
8089 server_in_port = random.randint(1025, 65535)
8090 server_out_port = random.randint(1025, 65535)
8091 client_in_port = random.randint(1025, 65535)
8092 ip = IPv6(src=''.join(['64:ff9b::', self.nat_addr]))
8093 nat_addr_ip6 = ip.src
8095 self.vapi.nat64_add_del_pool_addr_range(self.nat_addr_n,
8097 self.vapi.nat64_add_del_interface(self.pg0.sw_if_index)
8098 self.vapi.nat64_add_del_interface(self.pg1.sw_if_index, is_inside=0)
8100 # add static BIB entry for server
8101 self.vapi.nat64_add_del_static_bib(server.ip6n,
8107 # send packet from host to server
8108 pkts = self.create_stream_frag_ip6(self.pg0,
8113 self.pg0.add_stream(pkts)
8114 self.pg_enable_capture(self.pg_interfaces)
8116 frags = self.pg0.get_capture(len(pkts))
8117 p = self.reass_frags_and_verify_ip6(frags, nat_addr_ip6, server.ip6)
8118 self.assertNotEqual(p[TCP].sport, client_in_port)
8119 self.assertEqual(p[TCP].dport, server_in_port)
8120 self.assertEqual(data, p[Raw].load)
8122 def test_frag_out_of_order(self):
8123 """ NAT64 translate fragments arriving out of order """
8124 self.tcp_port_in = random.randint(1025, 65535)
8126 self.vapi.nat64_add_del_pool_addr_range(self.nat_addr_n,
8128 self.vapi.nat64_add_del_interface(self.pg0.sw_if_index)
8129 self.vapi.nat64_add_del_interface(self.pg1.sw_if_index, is_inside=0)
8133 pkts = self.create_stream_frag_ip6(self.pg0, self.pg1.remote_ip4,
8134 self.tcp_port_in, 20, data)
8136 self.pg0.add_stream(pkts)
8137 self.pg_enable_capture(self.pg_interfaces)
8139 frags = self.pg1.get_capture(len(pkts))
8140 p = self.reass_frags_and_verify(frags,
8142 self.pg1.remote_ip4)
8143 self.assertEqual(p[TCP].dport, 20)
8144 self.assertNotEqual(p[TCP].sport, self.tcp_port_in)
8145 self.tcp_port_out = p[TCP].sport
8146 self.assertEqual(data, p[Raw].load)
8149 data = b"A" * 4 + b"B" * 16 + b"C" * 3
8150 pkts = self.create_stream_frag(self.pg1,
8156 self.pg1.add_stream(pkts)
8157 self.pg_enable_capture(self.pg_interfaces)
8159 frags = self.pg0.get_capture(len(pkts))
8160 src = self.compose_ip6(self.pg1.remote_ip4, '64:ff9b::', 96)
8161 p = self.reass_frags_and_verify_ip6(frags, src, self.pg0.remote_ip6)
8162 self.assertEqual(p[TCP].sport, 20)
8163 self.assertEqual(p[TCP].dport, self.tcp_port_in)
8164 self.assertEqual(data, p[Raw].load)
8166 def test_interface_addr(self):
8167 """ Acquire NAT64 pool addresses from interface """
8168 self.vapi.nat64_add_del_interface_addr(self.pg4.sw_if_index)
8170 # no address in NAT64 pool
8171 addresses = self.vapi.nat44_address_dump()
8172 self.assertEqual(0, len(addresses))
8174 # configure interface address and check NAT64 address pool
8175 self.pg4.config_ip4()
8176 addresses = self.vapi.nat64_pool_addr_dump()
8177 self.assertEqual(len(addresses), 1)
8178 self.assertEqual(addresses[0].address, self.pg4.local_ip4n)
8180 # remove interface address and check NAT64 address pool
8181 self.pg4.unconfig_ip4()
8182 addresses = self.vapi.nat64_pool_addr_dump()
8183 self.assertEqual(0, len(addresses))
8185 @unittest.skipUnless(running_extended_tests, "part of extended tests")
8186 def test_ipfix_max_bibs_sessions(self):
8187 """ IPFIX logging maximum session and BIB entries exceeded """
8190 remote_host_ip6 = self.compose_ip6(self.pg1.remote_ip4,
8194 self.vapi.nat64_add_del_pool_addr_range(self.nat_addr_n,
8196 self.vapi.nat64_add_del_interface(self.pg0.sw_if_index)
8197 self.vapi.nat64_add_del_interface(self.pg1.sw_if_index, is_inside=0)
8201 for i in range(0, max_bibs):
8202 src = "fd01:aa::%x" % (i)
8203 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
8204 IPv6(src=src, dst=remote_host_ip6) /
8205 TCP(sport=12345, dport=80))
8207 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
8208 IPv6(src=src, dst=remote_host_ip6) /
8209 TCP(sport=12345, dport=22))
8211 self.pg0.add_stream(pkts)
8212 self.pg_enable_capture(self.pg_interfaces)
8214 self.pg1.get_capture(max_sessions)
8216 self.vapi.set_ipfix_exporter(collector_address=self.pg3.remote_ip4n,
8217 src_address=self.pg3.local_ip4n,
8219 template_interval=10)
8220 self.vapi.nat_ipfix_enable_disable(domain_id=self.ipfix_domain_id,
8221 src_port=self.ipfix_src_port)
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=25))
8226 self.pg0.add_stream(p)
8227 self.pg_enable_capture(self.pg_interfaces)
8229 self.pg1.assert_nothing_captured()
8231 self.vapi.cli("ipfix flush") # FIXME this should be an API call
8232 capture = self.pg3.get_capture(9)
8233 ipfix = IPFIXDecoder()
8234 # first load template
8236 self.assertTrue(p.haslayer(IPFIX))
8237 self.assertEqual(p[IP].src, self.pg3.local_ip4)
8238 self.assertEqual(p[IP].dst, self.pg3.remote_ip4)
8239 self.assertEqual(p[UDP].sport, self.ipfix_src_port)
8240 self.assertEqual(p[UDP].dport, 4739)
8241 self.assertEqual(p[IPFIX].observationDomainID,
8242 self.ipfix_domain_id)
8243 if p.haslayer(Template):
8244 ipfix.add_template(p.getlayer(Template))
8245 # verify events in data set
8247 if p.haslayer(Data):
8248 data = ipfix.decode_data_set(p.getlayer(Set))
8249 self.verify_ipfix_max_sessions(data, max_sessions)
8251 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
8252 IPv6(src=self.pg0.remote_ip6, dst=remote_host_ip6) /
8253 TCP(sport=12345, dport=80))
8254 self.pg0.add_stream(p)
8255 self.pg_enable_capture(self.pg_interfaces)
8257 self.pg1.assert_nothing_captured()
8259 self.vapi.cli("ipfix flush") # FIXME this should be an API call
8260 capture = self.pg3.get_capture(1)
8261 # verify events in data set
8263 self.assertTrue(p.haslayer(IPFIX))
8264 self.assertEqual(p[IP].src, self.pg3.local_ip4)
8265 self.assertEqual(p[IP].dst, self.pg3.remote_ip4)
8266 self.assertEqual(p[UDP].sport, self.ipfix_src_port)
8267 self.assertEqual(p[UDP].dport, 4739)
8268 self.assertEqual(p[IPFIX].observationDomainID,
8269 self.ipfix_domain_id)
8270 if p.haslayer(Data):
8271 data = ipfix.decode_data_set(p.getlayer(Set))
8272 self.verify_ipfix_max_bibs(data, max_bibs)
8274 def test_ipfix_max_frags(self):
8275 """ IPFIX logging maximum fragments pending reassembly exceeded """
8276 self.vapi.nat64_add_del_pool_addr_range(self.nat_addr_n,
8278 self.vapi.nat64_add_del_interface(self.pg0.sw_if_index)
8279 self.vapi.nat64_add_del_interface(self.pg1.sw_if_index, is_inside=0)
8280 self.vapi.nat_set_reass(max_frag=1, is_ip6=1)
8281 self.vapi.set_ipfix_exporter(collector_address=self.pg3.remote_ip4n,
8282 src_address=self.pg3.local_ip4n,
8284 template_interval=10)
8285 self.vapi.nat_ipfix_enable_disable(domain_id=self.ipfix_domain_id,
8286 src_port=self.ipfix_src_port)
8289 pkts = self.create_stream_frag_ip6(self.pg0, self.pg1.remote_ip4,
8290 self.tcp_port_in, 20, data)
8292 self.pg0.add_stream(pkts)
8293 self.pg_enable_capture(self.pg_interfaces)
8295 self.pg1.assert_nothing_captured()
8297 self.vapi.cli("ipfix flush") # FIXME this should be an API call
8298 capture = self.pg3.get_capture(9)
8299 ipfix = IPFIXDecoder()
8300 # first load template
8302 self.assertTrue(p.haslayer(IPFIX))
8303 self.assertEqual(p[IP].src, self.pg3.local_ip4)
8304 self.assertEqual(p[IP].dst, self.pg3.remote_ip4)
8305 self.assertEqual(p[UDP].sport, self.ipfix_src_port)
8306 self.assertEqual(p[UDP].dport, 4739)
8307 self.assertEqual(p[IPFIX].observationDomainID,
8308 self.ipfix_domain_id)
8309 if p.haslayer(Template):
8310 ipfix.add_template(p.getlayer(Template))
8311 # verify events in data set
8313 if p.haslayer(Data):
8314 data = ipfix.decode_data_set(p.getlayer(Set))
8315 self.verify_ipfix_max_fragments_ip6(data, 1,
8316 self.pg0.remote_ip6n)
8318 def test_ipfix_bib_ses(self):
8319 """ IPFIX logging NAT64 BIB/session create and delete events """
8320 self.tcp_port_in = random.randint(1025, 65535)
8321 remote_host_ip6 = self.compose_ip6(self.pg1.remote_ip4,
8325 self.vapi.nat64_add_del_pool_addr_range(self.nat_addr_n,
8327 self.vapi.nat64_add_del_interface(self.pg0.sw_if_index)
8328 self.vapi.nat64_add_del_interface(self.pg1.sw_if_index, is_inside=0)
8329 self.vapi.set_ipfix_exporter(collector_address=self.pg3.remote_ip4n,
8330 src_address=self.pg3.local_ip4n,
8332 template_interval=10)
8333 self.vapi.nat_ipfix_enable_disable(domain_id=self.ipfix_domain_id,
8334 src_port=self.ipfix_src_port)
8337 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
8338 IPv6(src=self.pg0.remote_ip6, dst=remote_host_ip6) /
8339 TCP(sport=self.tcp_port_in, dport=25))
8340 self.pg0.add_stream(p)
8341 self.pg_enable_capture(self.pg_interfaces)
8343 p = self.pg1.get_capture(1)
8344 self.tcp_port_out = p[0][TCP].sport
8345 self.vapi.cli("ipfix flush") # FIXME this should be an API call
8346 capture = self.pg3.get_capture(10)
8347 ipfix = IPFIXDecoder()
8348 # first load template
8350 self.assertTrue(p.haslayer(IPFIX))
8351 self.assertEqual(p[IP].src, self.pg3.local_ip4)
8352 self.assertEqual(p[IP].dst, self.pg3.remote_ip4)
8353 self.assertEqual(p[UDP].sport, self.ipfix_src_port)
8354 self.assertEqual(p[UDP].dport, 4739)
8355 self.assertEqual(p[IPFIX].observationDomainID,
8356 self.ipfix_domain_id)
8357 if p.haslayer(Template):
8358 ipfix.add_template(p.getlayer(Template))
8359 # verify events in data set
8361 if p.haslayer(Data):
8362 data = ipfix.decode_data_set(p.getlayer(Set))
8363 if scapy.compat.orb(data[0][230]) == 10:
8364 self.verify_ipfix_bib(data, 1, self.pg0.remote_ip6n)
8365 elif scapy.compat.orb(data[0][230]) == 6:
8366 self.verify_ipfix_nat64_ses(data,
8368 self.pg0.remote_ip6n,
8369 self.pg1.remote_ip4,
8372 self.logger.error(ppp("Unexpected or invalid packet: ", p))
8375 self.pg_enable_capture(self.pg_interfaces)
8376 self.vapi.nat64_add_del_pool_addr_range(self.nat_addr_n,
8379 self.vapi.cli("ipfix flush") # FIXME this should be an API call
8380 capture = self.pg3.get_capture(2)
8381 # verify events in data set
8383 self.assertTrue(p.haslayer(IPFIX))
8384 self.assertEqual(p[IP].src, self.pg3.local_ip4)
8385 self.assertEqual(p[IP].dst, self.pg3.remote_ip4)
8386 self.assertEqual(p[UDP].sport, self.ipfix_src_port)
8387 self.assertEqual(p[UDP].dport, 4739)
8388 self.assertEqual(p[IPFIX].observationDomainID,
8389 self.ipfix_domain_id)
8390 if p.haslayer(Data):
8391 data = ipfix.decode_data_set(p.getlayer(Set))
8392 if scapy.compat.orb(data[0][230]) == 11:
8393 self.verify_ipfix_bib(data, 0, self.pg0.remote_ip6n)
8394 elif scapy.compat.orb(data[0][230]) == 7:
8395 self.verify_ipfix_nat64_ses(data,
8397 self.pg0.remote_ip6n,
8398 self.pg1.remote_ip4,
8401 self.logger.error(ppp("Unexpected or invalid packet: ", p))
8403 def test_syslog_sess(self):
8404 """ Test syslog session creation and deletion """
8405 self.tcp_port_in = random.randint(1025, 65535)
8406 remote_host_ip6 = self.compose_ip6(self.pg1.remote_ip4,
8410 self.vapi.nat64_add_del_pool_addr_range(self.nat_addr_n,
8412 self.vapi.nat64_add_del_interface(self.pg0.sw_if_index)
8413 self.vapi.nat64_add_del_interface(self.pg1.sw_if_index, is_inside=0)
8414 self.vapi.syslog_set_filter(SYSLOG_SEVERITY.INFO)
8415 self.vapi.syslog_set_sender(self.pg3.local_ip4n, self.pg3.remote_ip4n)
8417 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
8418 IPv6(src=self.pg0.remote_ip6, dst=remote_host_ip6) /
8419 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port))
8420 self.pg0.add_stream(p)
8421 self.pg_enable_capture(self.pg_interfaces)
8423 p = self.pg1.get_capture(1)
8424 self.tcp_port_out = p[0][TCP].sport
8425 capture = self.pg3.get_capture(1)
8426 self.verify_syslog_sess(capture[0][Raw].load, is_ip6=True)
8428 self.pg_enable_capture(self.pg_interfaces)
8430 self.vapi.nat64_add_del_pool_addr_range(self.nat_addr_n,
8433 capture = self.pg3.get_capture(1)
8434 self.verify_syslog_sess(capture[0][Raw].load, False, True)
8436 def nat64_get_ses_num(self):
8438 Return number of active NAT64 sessions.
8440 st = self.vapi.nat64_st_dump()
8443 def clear_nat64(self):
8445 Clear NAT64 configuration.
8447 self.vapi.nat_ipfix_enable_disable(enable=0,
8448 src_port=self.ipfix_src_port,
8449 domain_id=self.ipfix_domain_id)
8450 self.ipfix_src_port = 4739
8451 self.ipfix_domain_id = 1
8453 self.vapi.syslog_set_filter(SYSLOG_SEVERITY.EMERG)
8455 self.vapi.nat_set_timeouts()
8457 interfaces = self.vapi.nat64_interface_dump()
8458 for intf in interfaces:
8459 if intf.is_inside > 1:
8460 self.vapi.nat64_add_del_interface(intf.sw_if_index,
8463 self.vapi.nat64_add_del_interface(intf.sw_if_index,
8467 bib = self.vapi.nat64_bib_dump(255)
8470 self.vapi.nat64_add_del_static_bib(bibe.i_addr,
8478 adresses = self.vapi.nat64_pool_addr_dump()
8479 for addr in adresses:
8480 self.vapi.nat64_add_del_pool_addr_range(addr.address,
8485 prefixes = self.vapi.nat64_prefix_dump()
8486 for prefix in prefixes:
8487 self.vapi.nat64_add_del_prefix(prefix.prefix,
8489 vrf_id=prefix.vrf_id,
8492 bibs = self.statistics.get_counter('/nat64/total-bibs')
8493 self.assertEqual(bibs[0][0], 0)
8494 sessions = self.statistics.get_counter('/nat64/total-sessions')
8495 self.assertEqual(sessions[0][0], 0)
8498 super(TestNAT64, self).tearDown()
8499 if not self.vpp_dead:
8500 self.logger.info(self.vapi.cli("show nat64 pool"))
8501 self.logger.info(self.vapi.cli("show nat64 interfaces"))
8502 self.logger.info(self.vapi.cli("show nat64 prefix"))
8503 self.logger.info(self.vapi.cli("show nat64 bib all"))
8504 self.logger.info(self.vapi.cli("show nat64 session table all"))
8505 self.logger.info(self.vapi.cli("show nat virtual-reassembly"))
8509 class TestDSlite(MethodHolder):
8510 """ DS-Lite Test Cases """
8513 def setUpClass(cls):
8514 super(TestDSlite, cls).setUpClass()
8517 cls.nat_addr = '10.0.0.3'
8518 cls.nat_addr_n = socket.inet_pton(socket.AF_INET, cls.nat_addr)
8520 cls.create_pg_interfaces(range(3))
8522 cls.pg0.config_ip4()
8523 cls.pg0.resolve_arp()
8525 cls.pg1.config_ip6()
8526 cls.pg1.generate_remote_hosts(2)
8527 cls.pg1.configure_ipv6_neighbors()
8529 cls.pg2.config_ip4()
8530 cls.pg2.resolve_arp()
8533 super(TestDSlite, cls).tearDownClass()
8536 def verify_syslog_apmadd(self, data, isaddr, isport, xsaddr, xsport,
8538 message = data.decode('utf-8')
8540 message = SyslogMessage.parse(message)
8541 except ParseError as e:
8542 self.logger.error(e)
8544 self.assertEqual(message.severity, SyslogSeverity.info)
8545 self.assertEqual(message.appname, 'NAT')
8546 self.assertEqual(message.msgid, 'APMADD')
8547 sd_params = message.sd.get('napmap')
8548 self.assertTrue(sd_params is not None)
8549 self.assertEqual(sd_params.get('IATYP'), 'IPv4')
8550 self.assertEqual(sd_params.get('ISADDR'), isaddr)
8551 self.assertEqual(sd_params.get('ISPORT'), "%d" % isport)
8552 self.assertEqual(sd_params.get('XATYP'), 'IPv4')
8553 self.assertEqual(sd_params.get('XSADDR'), xsaddr)
8554 self.assertEqual(sd_params.get('XSPORT'), "%d" % xsport)
8555 self.assertEqual(sd_params.get('PROTO'), "%d" % proto)
8556 self.assertTrue(sd_params.get('SSUBIX') is not None)
8557 self.assertEqual(sd_params.get('SV6ENC'), sv6enc)
8559 def test_dslite(self):
8560 """ Test DS-Lite """
8561 nat_config = self.vapi.nat_show_config()
8562 self.assertEqual(0, nat_config.dslite_ce)
8564 self.vapi.dslite_add_del_pool_addr_range(self.nat_addr_n,
8566 aftr_ip4 = '192.0.0.1'
8567 aftr_ip4_n = socket.inet_pton(socket.AF_INET, aftr_ip4)
8568 aftr_ip6 = '2001:db8:85a3::8a2e:370:1'
8569 aftr_ip6_n = socket.inet_pton(socket.AF_INET6, aftr_ip6)
8570 self.vapi.dslite_set_aftr_addr(aftr_ip6_n, aftr_ip4_n)
8571 self.vapi.syslog_set_sender(self.pg2.local_ip4n, self.pg2.remote_ip4n)
8574 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
8575 IPv6(dst=aftr_ip6, src=self.pg1.remote_hosts[0].ip6) /
8576 IP(dst=self.pg0.remote_ip4, src='192.168.1.1') /
8577 UDP(sport=20000, dport=10000))
8578 self.pg1.add_stream(p)
8579 self.pg_enable_capture(self.pg_interfaces)
8581 capture = self.pg0.get_capture(1)
8582 capture = capture[0]
8583 self.assertFalse(capture.haslayer(IPv6))
8584 self.assertEqual(capture[IP].src, self.nat_addr)
8585 self.assertEqual(capture[IP].dst, self.pg0.remote_ip4)
8586 self.assertNotEqual(capture[UDP].sport, 20000)
8587 self.assertEqual(capture[UDP].dport, 10000)
8588 self.assert_packet_checksums_valid(capture)
8589 out_port = capture[UDP].sport
8590 capture = self.pg2.get_capture(1)
8591 self.verify_syslog_apmadd(capture[0][Raw].load, '192.168.1.1',
8592 20000, self.nat_addr, out_port,
8593 self.pg1.remote_hosts[0].ip6, IP_PROTOS.udp)
8595 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
8596 IP(dst=self.nat_addr, src=self.pg0.remote_ip4) /
8597 UDP(sport=10000, dport=out_port))
8598 self.pg0.add_stream(p)
8599 self.pg_enable_capture(self.pg_interfaces)
8601 capture = self.pg1.get_capture(1)
8602 capture = capture[0]
8603 self.assertEqual(capture[IPv6].src, aftr_ip6)
8604 self.assertEqual(capture[IPv6].dst, self.pg1.remote_hosts[0].ip6)
8605 self.assertEqual(capture[IP].src, self.pg0.remote_ip4)
8606 self.assertEqual(capture[IP].dst, '192.168.1.1')
8607 self.assertEqual(capture[UDP].sport, 10000)
8608 self.assertEqual(capture[UDP].dport, 20000)
8609 self.assert_packet_checksums_valid(capture)
8612 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
8613 IPv6(dst=aftr_ip6, src=self.pg1.remote_hosts[1].ip6) /
8614 IP(dst=self.pg0.remote_ip4, src='192.168.1.1') /
8615 TCP(sport=20001, dport=10001))
8616 self.pg1.add_stream(p)
8617 self.pg_enable_capture(self.pg_interfaces)
8619 capture = self.pg0.get_capture(1)
8620 capture = capture[0]
8621 self.assertFalse(capture.haslayer(IPv6))
8622 self.assertEqual(capture[IP].src, self.nat_addr)
8623 self.assertEqual(capture[IP].dst, self.pg0.remote_ip4)
8624 self.assertNotEqual(capture[TCP].sport, 20001)
8625 self.assertEqual(capture[TCP].dport, 10001)
8626 self.assert_packet_checksums_valid(capture)
8627 out_port = capture[TCP].sport
8629 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
8630 IP(dst=self.nat_addr, src=self.pg0.remote_ip4) /
8631 TCP(sport=10001, dport=out_port))
8632 self.pg0.add_stream(p)
8633 self.pg_enable_capture(self.pg_interfaces)
8635 capture = self.pg1.get_capture(1)
8636 capture = capture[0]
8637 self.assertEqual(capture[IPv6].src, aftr_ip6)
8638 self.assertEqual(capture[IPv6].dst, self.pg1.remote_hosts[1].ip6)
8639 self.assertEqual(capture[IP].src, self.pg0.remote_ip4)
8640 self.assertEqual(capture[IP].dst, '192.168.1.1')
8641 self.assertEqual(capture[TCP].sport, 10001)
8642 self.assertEqual(capture[TCP].dport, 20001)
8643 self.assert_packet_checksums_valid(capture)
8646 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
8647 IPv6(dst=aftr_ip6, src=self.pg1.remote_hosts[1].ip6) /
8648 IP(dst=self.pg0.remote_ip4, src='192.168.1.1') /
8649 ICMP(id=4000, type='echo-request'))
8650 self.pg1.add_stream(p)
8651 self.pg_enable_capture(self.pg_interfaces)
8653 capture = self.pg0.get_capture(1)
8654 capture = capture[0]
8655 self.assertFalse(capture.haslayer(IPv6))
8656 self.assertEqual(capture[IP].src, self.nat_addr)
8657 self.assertEqual(capture[IP].dst, self.pg0.remote_ip4)
8658 self.assertNotEqual(capture[ICMP].id, 4000)
8659 self.assert_packet_checksums_valid(capture)
8660 out_id = capture[ICMP].id
8662 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
8663 IP(dst=self.nat_addr, src=self.pg0.remote_ip4) /
8664 ICMP(id=out_id, type='echo-reply'))
8665 self.pg0.add_stream(p)
8666 self.pg_enable_capture(self.pg_interfaces)
8668 capture = self.pg1.get_capture(1)
8669 capture = capture[0]
8670 self.assertEqual(capture[IPv6].src, aftr_ip6)
8671 self.assertEqual(capture[IPv6].dst, self.pg1.remote_hosts[1].ip6)
8672 self.assertEqual(capture[IP].src, self.pg0.remote_ip4)
8673 self.assertEqual(capture[IP].dst, '192.168.1.1')
8674 self.assertEqual(capture[ICMP].id, 4000)
8675 self.assert_packet_checksums_valid(capture)
8677 # ping DS-Lite AFTR tunnel endpoint address
8678 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
8679 IPv6(src=self.pg1.remote_hosts[1].ip6, dst=aftr_ip6) /
8680 ICMPv6EchoRequest())
8681 self.pg1.add_stream(p)
8682 self.pg_enable_capture(self.pg_interfaces)
8684 capture = self.pg1.get_capture(1)
8685 capture = capture[0]
8686 self.assertEqual(capture[IPv6].src, aftr_ip6)
8687 self.assertEqual(capture[IPv6].dst, self.pg1.remote_hosts[1].ip6)
8688 self.assertTrue(capture.haslayer(ICMPv6EchoReply))
8690 b4s = self.statistics.get_counter('/dslite/total-b4s')
8691 self.assertEqual(b4s[0][0], 2)
8692 sessions = self.statistics.get_counter('/dslite/total-sessions')
8693 self.assertEqual(sessions[0][0], 3)
8696 super(TestDSlite, self).tearDown()
8697 if not self.vpp_dead:
8698 self.logger.info(self.vapi.cli("show dslite pool"))
8700 self.vapi.cli("show dslite aftr-tunnel-endpoint-address"))
8701 self.logger.info(self.vapi.cli("show dslite sessions"))
8704 class TestDSliteCE(MethodHolder):
8705 """ DS-Lite CE Test Cases """
8708 def setUpConstants(cls):
8709 super(TestDSliteCE, cls).setUpConstants()
8710 cls.vpp_cmdline.extend(["nat", "{", "dslite ce", "}"])
8713 def setUpClass(cls):
8714 super(TestDSliteCE, cls).setUpClass()
8717 cls.create_pg_interfaces(range(2))
8719 cls.pg0.config_ip4()
8720 cls.pg0.resolve_arp()
8722 cls.pg1.config_ip6()
8723 cls.pg1.generate_remote_hosts(1)
8724 cls.pg1.configure_ipv6_neighbors()
8727 super(TestDSliteCE, cls).tearDownClass()
8730 def test_dslite_ce(self):
8731 """ Test DS-Lite CE """
8733 nat_config = self.vapi.nat_show_config()
8734 self.assertEqual(1, nat_config.dslite_ce)
8736 b4_ip4 = '192.0.0.2'
8737 b4_ip4_n = socket.inet_pton(socket.AF_INET, b4_ip4)
8738 b4_ip6 = '2001:db8:62aa::375e:f4c1:1'
8739 b4_ip6_n = socket.inet_pton(socket.AF_INET6, b4_ip6)
8740 self.vapi.dslite_set_b4_addr(b4_ip6_n, b4_ip4_n)
8742 aftr_ip4 = '192.0.0.1'
8743 aftr_ip4_n = socket.inet_pton(socket.AF_INET, aftr_ip4)
8744 aftr_ip6 = '2001:db8:85a3::8a2e:370:1'
8745 aftr_ip6_n = socket.inet_pton(socket.AF_INET6, aftr_ip6)
8746 self.vapi.dslite_set_aftr_addr(aftr_ip6_n, aftr_ip4_n)
8748 self.vapi.ip_add_del_route(dst_address=aftr_ip6_n,
8749 dst_address_length=128,
8750 next_hop_address=self.pg1.remote_ip6n,
8751 next_hop_sw_if_index=self.pg1.sw_if_index,
8755 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
8756 IP(dst=self.pg1.remote_ip4, src=self.pg0.remote_ip4) /
8757 UDP(sport=10000, dport=20000))
8758 self.pg0.add_stream(p)
8759 self.pg_enable_capture(self.pg_interfaces)
8761 capture = self.pg1.get_capture(1)
8762 capture = capture[0]
8763 self.assertEqual(capture[IPv6].src, b4_ip6)
8764 self.assertEqual(capture[IPv6].dst, aftr_ip6)
8765 self.assertEqual(capture[IP].src, self.pg0.remote_ip4)
8766 self.assertEqual(capture[IP].dst, self.pg1.remote_ip4)
8767 self.assertEqual(capture[UDP].sport, 10000)
8768 self.assertEqual(capture[UDP].dport, 20000)
8769 self.assert_packet_checksums_valid(capture)
8772 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
8773 IPv6(dst=b4_ip6, src=aftr_ip6) /
8774 IP(dst=self.pg0.remote_ip4, src=self.pg1.remote_ip4) /
8775 UDP(sport=20000, dport=10000))
8776 self.pg1.add_stream(p)
8777 self.pg_enable_capture(self.pg_interfaces)
8779 capture = self.pg0.get_capture(1)
8780 capture = capture[0]
8781 self.assertFalse(capture.haslayer(IPv6))
8782 self.assertEqual(capture[IP].src, self.pg1.remote_ip4)
8783 self.assertEqual(capture[IP].dst, self.pg0.remote_ip4)
8784 self.assertEqual(capture[UDP].sport, 20000)
8785 self.assertEqual(capture[UDP].dport, 10000)
8786 self.assert_packet_checksums_valid(capture)
8788 # ping DS-Lite B4 tunnel endpoint address
8789 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
8790 IPv6(src=self.pg1.remote_hosts[0].ip6, dst=b4_ip6) /
8791 ICMPv6EchoRequest())
8792 self.pg1.add_stream(p)
8793 self.pg_enable_capture(self.pg_interfaces)
8795 capture = self.pg1.get_capture(1)
8796 capture = capture[0]
8797 self.assertEqual(capture[IPv6].src, b4_ip6)
8798 self.assertEqual(capture[IPv6].dst, self.pg1.remote_hosts[0].ip6)
8799 self.assertTrue(capture.haslayer(ICMPv6EchoReply))
8802 super(TestDSliteCE, self).tearDown()
8803 if not self.vpp_dead:
8805 self.vapi.cli("show dslite aftr-tunnel-endpoint-address"))
8807 self.vapi.cli("show dslite b4-tunnel-endpoint-address"))
8810 class TestNAT66(MethodHolder):
8811 """ NAT66 Test Cases """
8814 def setUpClass(cls):
8815 super(TestNAT66, cls).setUpClass()
8818 cls.nat_addr = 'fd01:ff::2'
8819 cls.nat_addr_n = socket.inet_pton(socket.AF_INET6, cls.nat_addr)
8821 cls.create_pg_interfaces(range(2))
8822 cls.interfaces = list(cls.pg_interfaces)
8824 for i in cls.interfaces:
8827 i.configure_ipv6_neighbors()
8830 super(TestNAT66, cls).tearDownClass()
8833 def test_static(self):
8834 """ 1:1 NAT66 test """
8835 self.vapi.nat66_add_del_interface(self.pg0.sw_if_index)
8836 self.vapi.nat66_add_del_interface(self.pg1.sw_if_index, is_inside=0)
8837 self.vapi.nat66_add_del_static_mapping(self.pg0.remote_ip6n,
8842 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
8843 IPv6(src=self.pg0.remote_ip6, dst=self.pg1.remote_ip6) /
8846 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
8847 IPv6(src=self.pg0.remote_ip6, dst=self.pg1.remote_ip6) /
8850 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
8851 IPv6(src=self.pg0.remote_ip6, dst=self.pg1.remote_ip6) /
8852 ICMPv6EchoRequest())
8854 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
8855 IPv6(src=self.pg0.remote_ip6, dst=self.pg1.remote_ip6) /
8856 GRE() / IP() / TCP())
8858 self.pg0.add_stream(pkts)
8859 self.pg_enable_capture(self.pg_interfaces)
8861 capture = self.pg1.get_capture(len(pkts))
8862 for packet in capture:
8864 self.assertEqual(packet[IPv6].src, self.nat_addr)
8865 self.assertEqual(packet[IPv6].dst, self.pg1.remote_ip6)
8866 self.assert_packet_checksums_valid(packet)
8868 self.logger.error(ppp("Unexpected or invalid packet:", packet))
8873 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
8874 IPv6(src=self.pg1.remote_ip6, dst=self.nat_addr) /
8877 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
8878 IPv6(src=self.pg1.remote_ip6, dst=self.nat_addr) /
8881 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
8882 IPv6(src=self.pg1.remote_ip6, dst=self.nat_addr) /
8885 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
8886 IPv6(src=self.pg1.remote_ip6, dst=self.nat_addr) /
8887 GRE() / IP() / TCP())
8889 self.pg1.add_stream(pkts)
8890 self.pg_enable_capture(self.pg_interfaces)
8892 capture = self.pg0.get_capture(len(pkts))
8893 for packet in capture:
8895 self.assertEqual(packet[IPv6].src, self.pg1.remote_ip6)
8896 self.assertEqual(packet[IPv6].dst, self.pg0.remote_ip6)
8897 self.assert_packet_checksums_valid(packet)
8899 self.logger.error(ppp("Unexpected or invalid packet:", packet))
8902 sm = self.vapi.nat66_static_mapping_dump()
8903 self.assertEqual(len(sm), 1)
8904 self.assertEqual(sm[0].total_pkts, 8)
8906 def test_check_no_translate(self):
8907 """ NAT66 translate only when egress interface is outside interface """
8908 self.vapi.nat66_add_del_interface(self.pg0.sw_if_index)
8909 self.vapi.nat66_add_del_interface(self.pg1.sw_if_index)
8910 self.vapi.nat66_add_del_static_mapping(self.pg0.remote_ip6n,
8914 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
8915 IPv6(src=self.pg0.remote_ip6, dst=self.pg1.remote_ip6) /
8917 self.pg0.add_stream([p])
8918 self.pg_enable_capture(self.pg_interfaces)
8920 capture = self.pg1.get_capture(1)
8923 self.assertEqual(packet[IPv6].src, self.pg0.remote_ip6)
8924 self.assertEqual(packet[IPv6].dst, self.pg1.remote_ip6)
8926 self.logger.error(ppp("Unexpected or invalid packet:", packet))
8929 def clear_nat66(self):
8931 Clear NAT66 configuration.
8933 interfaces = self.vapi.nat66_interface_dump()
8934 for intf in interfaces:
8935 self.vapi.nat66_add_del_interface(intf.sw_if_index,
8939 static_mappings = self.vapi.nat66_static_mapping_dump()
8940 for sm in static_mappings:
8941 self.vapi.nat66_add_del_static_mapping(sm.local_ip_address,
8942 sm.external_ip_address,
8947 super(TestNAT66, self).tearDown()
8948 if not self.vpp_dead:
8949 self.logger.info(self.vapi.cli("show nat66 interfaces"))
8950 self.logger.info(self.vapi.cli("show nat66 static mappings"))
8954 if __name__ == '__main__':
8955 unittest.main(testRunner=VppTestRunner)