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 adresses = self.vapi.nat44_address_dump()
182 for addr in adresses:
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 extenal 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: Sorce 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: Sorce 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('\0', 1)[0], '')
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('\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 adresses = self.vapi.nat44_address_dump()
2588 self.assertEqual(0, len(adresses))
2590 # configure interface address and check NAT address pool
2591 self.pg7.config_ip4()
2592 adresses = self.vapi.nat44_address_dump()
2593 self.assertEqual(1, len(adresses))
2594 self.assertEqual(adresses[0].ip_address[0:4], self.pg7.local_ip4n)
2596 # remove interface address and check NAT address pool
2597 self.pg7.unconfig_ip4()
2598 adresses = self.vapi.nat44_address_dump()
2599 self.assertEqual(0, len(adresses))
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('\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('\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('\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('\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/delted """
2701 self.ipfix_domain_id = 10
2702 self.ipfix_src_port = 20202
2703 colector_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=colector_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, colector_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,
4240 next_hop_sw_if_index=cls.pg5.sw_if_index,
4241 next_hop_address=zero_ip4n)
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,
4255 next_hop_sw_if_index=cls.pg6.sw_if_index,
4256 next_hop_address=zero_ip4n)
4258 cls.vapi.ip_add_del_route(dst_address=cls.pg6.remote_ip4n,
4259 dst_address_length=16,
4260 next_hop_address=zero_ip4n,
4262 next_hop_table_id=1)
4263 cls.vapi.ip_add_del_route(dst_address=zero_ip4n,
4264 dst_address_length=0,
4265 next_hop_address=zero_ip4n,
4267 next_hop_table_id=0)
4268 cls.vapi.ip_add_del_route(dst_address=zero_ip4n,
4269 dst_address_length=0,
4271 next_hop_sw_if_index=cls.pg1.sw_if_index,
4272 next_hop_address=cls.pg1.local_ip4n)
4274 cls.pg5.resolve_arp()
4275 cls.pg6.resolve_arp()
4278 super(TestNAT44EndpointDependent, cls).tearDownClass()
4281 def test_frag_in_order(self):
4282 """ NAT44 translate fragments arriving in order """
4283 self.nat44_add_address(self.nat_addr)
4284 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
4285 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
4287 self.frag_in_order(proto=IP_PROTOS.tcp)
4288 self.frag_in_order(proto=IP_PROTOS.udp)
4289 self.frag_in_order(proto=IP_PROTOS.icmp)
4291 def test_frag_in_order_dont_translate(self):
4292 """ NAT44 don't translate fragments arriving in order """
4293 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
4294 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
4296 self.vapi.nat44_forwarding_enable_disable(enable=True)
4297 self.frag_in_order(proto=IP_PROTOS.tcp, dont_translate=True)
4299 def test_frag_out_of_order(self):
4300 """ NAT44 translate fragments arriving out of order """
4301 self.nat44_add_address(self.nat_addr)
4302 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
4303 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
4305 self.frag_out_of_order(proto=IP_PROTOS.tcp)
4306 self.frag_out_of_order(proto=IP_PROTOS.udp)
4307 self.frag_out_of_order(proto=IP_PROTOS.icmp)
4309 def test_frag_out_of_order_dont_translate(self):
4310 """ NAT44 don't translate fragments arriving out of order """
4311 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
4312 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
4314 self.vapi.nat44_forwarding_enable_disable(enable=True)
4315 self.frag_out_of_order(proto=IP_PROTOS.tcp, dont_translate=True)
4317 def test_frag_in_order_in_plus_out(self):
4318 """ in+out interface fragments in order """
4319 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
4320 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index,
4322 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index)
4323 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
4326 self.server = self.pg1.remote_hosts[0]
4328 self.server_in_addr = self.server.ip4
4329 self.server_out_addr = '11.11.11.11'
4330 self.server_in_port = random.randint(1025, 65535)
4331 self.server_out_port = random.randint(1025, 65535)
4333 self.nat44_add_address(self.server_out_addr)
4335 # add static mappings for server
4336 self.nat44_add_static_mapping(self.server_in_addr,
4337 self.server_out_addr,
4338 self.server_in_port,
4339 self.server_out_port,
4340 proto=IP_PROTOS.tcp)
4341 self.nat44_add_static_mapping(self.server_in_addr,
4342 self.server_out_addr,
4343 self.server_in_port,
4344 self.server_out_port,
4345 proto=IP_PROTOS.udp)
4346 self.nat44_add_static_mapping(self.server_in_addr,
4347 self.server_out_addr,
4348 proto=IP_PROTOS.icmp)
4350 self.vapi.nat_set_reass(timeout=10)
4352 self.frag_in_order_in_plus_out(proto=IP_PROTOS.tcp)
4353 self.frag_in_order_in_plus_out(proto=IP_PROTOS.udp)
4354 self.frag_in_order_in_plus_out(proto=IP_PROTOS.icmp)
4356 def test_frag_out_of_order_in_plus_out(self):
4357 """ in+out interface fragments out of order """
4358 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
4359 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index,
4361 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index)
4362 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
4365 self.server = self.pg1.remote_hosts[0]
4367 self.server_in_addr = self.server.ip4
4368 self.server_out_addr = '11.11.11.11'
4369 self.server_in_port = random.randint(1025, 65535)
4370 self.server_out_port = random.randint(1025, 65535)
4372 self.nat44_add_address(self.server_out_addr)
4374 # add static mappings for server
4375 self.nat44_add_static_mapping(self.server_in_addr,
4376 self.server_out_addr,
4377 self.server_in_port,
4378 self.server_out_port,
4379 proto=IP_PROTOS.tcp)
4380 self.nat44_add_static_mapping(self.server_in_addr,
4381 self.server_out_addr,
4382 self.server_in_port,
4383 self.server_out_port,
4384 proto=IP_PROTOS.udp)
4385 self.nat44_add_static_mapping(self.server_in_addr,
4386 self.server_out_addr,
4387 proto=IP_PROTOS.icmp)
4389 self.vapi.nat_set_reass(timeout=10)
4391 self.frag_out_of_order_in_plus_out(proto=IP_PROTOS.tcp)
4392 self.frag_out_of_order_in_plus_out(proto=IP_PROTOS.udp)
4393 self.frag_out_of_order_in_plus_out(proto=IP_PROTOS.icmp)
4395 def test_reass_hairpinning(self):
4396 """ NAT44 fragments hairpinning """
4397 self.server = self.pg0.remote_hosts[1]
4398 self.host_in_port = random.randint(1025, 65535)
4399 self.server_in_port = random.randint(1025, 65535)
4400 self.server_out_port = random.randint(1025, 65535)
4402 self.nat44_add_address(self.nat_addr)
4403 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
4404 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
4406 # add static mapping for server
4407 self.nat44_add_static_mapping(self.server.ip4, self.nat_addr,
4408 self.server_in_port,
4409 self.server_out_port,
4410 proto=IP_PROTOS.tcp)
4411 self.nat44_add_static_mapping(self.server.ip4, self.nat_addr,
4412 self.server_in_port,
4413 self.server_out_port,
4414 proto=IP_PROTOS.udp)
4415 self.nat44_add_static_mapping(self.server.ip4, self.nat_addr)
4417 self.reass_hairpinning(proto=IP_PROTOS.tcp)
4418 self.reass_hairpinning(proto=IP_PROTOS.udp)
4419 self.reass_hairpinning(proto=IP_PROTOS.icmp)
4421 def test_dynamic(self):
4422 """ NAT44 dynamic translation test """
4424 self.nat44_add_address(self.nat_addr)
4425 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
4426 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
4429 nat_config = self.vapi.nat_show_config()
4430 self.assertEqual(1, nat_config.endpoint_dependent)
4433 tcpn = self.statistics.get_counter(
4434 '/err/nat44-ed-in2out-slowpath/TCP packets')
4435 udpn = self.statistics.get_counter(
4436 '/err/nat44-ed-in2out-slowpath/UDP packets')
4437 icmpn = self.statistics.get_counter(
4438 '/err/nat44-ed-in2out-slowpath/ICMP packets')
4439 totaln = self.statistics.get_counter(
4440 '/err/nat44-ed-in2out-slowpath/good in2out packets processed')
4442 pkts = self.create_stream_in(self.pg0, self.pg1)
4443 self.pg0.add_stream(pkts)
4444 self.pg_enable_capture(self.pg_interfaces)
4446 capture = self.pg1.get_capture(len(pkts))
4447 self.verify_capture_out(capture)
4449 err = self.statistics.get_counter(
4450 '/err/nat44-ed-in2out-slowpath/TCP packets')
4451 self.assertEqual(err - tcpn, 1)
4452 err = self.statistics.get_counter(
4453 '/err/nat44-ed-in2out-slowpath/UDP packets')
4454 self.assertEqual(err - udpn, 1)
4455 err = self.statistics.get_counter(
4456 '/err/nat44-ed-in2out-slowpath/ICMP packets')
4457 self.assertEqual(err - icmpn, 1)
4458 err = self.statistics.get_counter(
4459 '/err/nat44-ed-in2out-slowpath/good in2out packets processed')
4460 self.assertEqual(err - totaln, 3)
4463 tcpn = self.statistics.get_counter('/err/nat44-ed-out2in/TCP packets')
4464 udpn = self.statistics.get_counter('/err/nat44-ed-out2in/UDP packets')
4465 icmpn = self.statistics.get_counter(
4466 '/err/nat44-ed-out2in-slowpath/ICMP packets')
4467 totaln = self.statistics.get_counter(
4468 '/err/nat44-ed-out2in/good out2in packets processed')
4470 pkts = self.create_stream_out(self.pg1)
4471 self.pg1.add_stream(pkts)
4472 self.pg_enable_capture(self.pg_interfaces)
4474 capture = self.pg0.get_capture(len(pkts))
4475 self.verify_capture_in(capture, self.pg0)
4477 err = self.statistics.get_counter('/err/nat44-ed-out2in/TCP packets')
4478 self.assertEqual(err - tcpn, 1)
4479 err = self.statistics.get_counter('/err/nat44-ed-out2in/UDP packets')
4480 self.assertEqual(err - udpn, 1)
4481 err = self.statistics.get_counter(
4482 '/err/nat44-ed-out2in-slowpath/ICMP packets')
4483 self.assertEqual(err - icmpn, 1)
4484 err = self.statistics.get_counter(
4485 '/err/nat44-ed-out2in/good out2in packets processed')
4486 self.assertEqual(err - totaln, 2)
4488 users = self.statistics.get_counter('/nat44/total-users')
4489 self.assertEqual(users[0][0], 1)
4490 sessions = self.statistics.get_counter('/nat44/total-sessions')
4491 self.assertEqual(sessions[0][0], 3)
4493 def test_forwarding(self):
4494 """ NAT44 forwarding test """
4496 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
4497 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
4499 self.vapi.nat44_forwarding_enable_disable(1)
4501 real_ip = self.pg0.remote_ip4n
4502 alias_ip = self.nat_addr_n
4503 self.vapi.nat44_add_del_static_mapping(local_ip=real_ip,
4504 external_ip=alias_ip)
4507 # in2out - static mapping match
4509 pkts = self.create_stream_out(self.pg1)
4510 self.pg1.add_stream(pkts)
4511 self.pg_enable_capture(self.pg_interfaces)
4513 capture = self.pg0.get_capture(len(pkts))
4514 self.verify_capture_in(capture, self.pg0)
4516 pkts = self.create_stream_in(self.pg0, self.pg1)
4517 self.pg0.add_stream(pkts)
4518 self.pg_enable_capture(self.pg_interfaces)
4520 capture = self.pg1.get_capture(len(pkts))
4521 self.verify_capture_out(capture, same_port=True)
4523 # in2out - no static mapping match
4525 host0 = self.pg0.remote_hosts[0]
4526 self.pg0.remote_hosts[0] = self.pg0.remote_hosts[1]
4528 pkts = self.create_stream_out(self.pg1,
4529 dst_ip=self.pg0.remote_ip4,
4530 use_inside_ports=True)
4531 self.pg1.add_stream(pkts)
4532 self.pg_enable_capture(self.pg_interfaces)
4534 capture = self.pg0.get_capture(len(pkts))
4535 self.verify_capture_in(capture, self.pg0)
4537 pkts = self.create_stream_in(self.pg0, self.pg1)
4538 self.pg0.add_stream(pkts)
4539 self.pg_enable_capture(self.pg_interfaces)
4541 capture = self.pg1.get_capture(len(pkts))
4542 self.verify_capture_out(capture, nat_ip=self.pg0.remote_ip4,
4545 self.pg0.remote_hosts[0] = host0
4547 user = self.pg0.remote_hosts[1]
4548 sessions = self.vapi.nat44_user_session_dump(user.ip4n, 0)
4549 self.assertEqual(len(sessions), 3)
4550 self.assertTrue(sessions[0].ext_host_valid)
4551 self.vapi.nat44_del_session(
4552 sessions[0].inside_ip_address,
4553 sessions[0].inside_port,
4554 sessions[0].protocol,
4555 ext_host_address=sessions[0].ext_host_address,
4556 ext_host_port=sessions[0].ext_host_port)
4557 sessions = self.vapi.nat44_user_session_dump(user.ip4n, 0)
4558 self.assertEqual(len(sessions), 2)
4561 self.vapi.nat44_forwarding_enable_disable(0)
4562 self.vapi.nat44_add_del_static_mapping(local_ip=real_ip,
4563 external_ip=alias_ip,
4566 def test_static_lb(self):
4567 """ NAT44 local service load balancing """
4568 external_addr_n = socket.inet_pton(socket.AF_INET, self.nat_addr)
4571 server1 = self.pg0.remote_hosts[0]
4572 server2 = self.pg0.remote_hosts[1]
4574 locals = [{'addr': server1.ip4n,
4578 {'addr': server2.ip4n,
4583 self.nat44_add_address(self.nat_addr)
4584 self.vapi.nat44_add_del_lb_static_mapping(external_addr_n,
4587 local_num=len(locals),
4589 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
4590 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
4593 # from client to service
4594 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
4595 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
4596 TCP(sport=12345, dport=external_port))
4597 self.pg1.add_stream(p)
4598 self.pg_enable_capture(self.pg_interfaces)
4600 capture = self.pg0.get_capture(1)
4606 self.assertIn(ip.dst, [server1.ip4, server2.ip4])
4607 if ip.dst == server1.ip4:
4611 self.assertEqual(tcp.dport, local_port)
4612 self.assert_packet_checksums_valid(p)
4614 self.logger.error(ppp("Unexpected or invalid packet:", p))
4617 # from service back to client
4618 p = (Ether(src=server.mac, dst=self.pg0.local_mac) /
4619 IP(src=server.ip4, dst=self.pg1.remote_ip4) /
4620 TCP(sport=local_port, dport=12345))
4621 self.pg0.add_stream(p)
4622 self.pg_enable_capture(self.pg_interfaces)
4624 capture = self.pg1.get_capture(1)
4629 self.assertEqual(ip.src, self.nat_addr)
4630 self.assertEqual(tcp.sport, external_port)
4631 self.assert_packet_checksums_valid(p)
4633 self.logger.error(ppp("Unexpected or invalid packet:", p))
4636 sessions = self.vapi.nat44_user_session_dump(server.ip4n, 0)
4637 self.assertEqual(len(sessions), 1)
4638 self.assertTrue(sessions[0].ext_host_valid)
4639 self.vapi.nat44_del_session(
4640 sessions[0].inside_ip_address,
4641 sessions[0].inside_port,
4642 sessions[0].protocol,
4643 ext_host_address=sessions[0].ext_host_address,
4644 ext_host_port=sessions[0].ext_host_port)
4645 sessions = self.vapi.nat44_user_session_dump(server.ip4n, 0)
4646 self.assertEqual(len(sessions), 0)
4648 @unittest.skipUnless(running_extended_tests, "part of extended tests")
4649 def test_static_lb_multi_clients(self):
4650 """ NAT44 local service load balancing - multiple clients"""
4652 external_addr_n = socket.inet_pton(socket.AF_INET, self.nat_addr)
4655 server1 = self.pg0.remote_hosts[0]
4656 server2 = self.pg0.remote_hosts[1]
4657 server3 = self.pg0.remote_hosts[2]
4659 locals = [{'addr': server1.ip4n,
4663 {'addr': server2.ip4n,
4668 self.nat44_add_address(self.nat_addr)
4669 self.vapi.nat44_add_del_lb_static_mapping(external_addr_n,
4672 local_num=len(locals),
4674 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
4675 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
4680 clients = ip4_range(self.pg1.remote_ip4, 10, 50)
4682 for client in clients:
4683 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
4684 IP(src=client, dst=self.nat_addr) /
4685 TCP(sport=12345, dport=external_port))
4687 self.pg1.add_stream(pkts)
4688 self.pg_enable_capture(self.pg_interfaces)
4690 capture = self.pg0.get_capture(len(pkts))
4692 if p[IP].dst == server1.ip4:
4696 self.assertGreater(server1_n, server2_n)
4699 self.vapi.nat44_lb_static_mapping_add_del_local(external_addr_n,
4708 clients = ip4_range(self.pg1.remote_ip4, 60, 110)
4710 for client in clients:
4711 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
4712 IP(src=client, dst=self.nat_addr) /
4713 TCP(sport=12346, dport=external_port))
4715 self.assertGreater(len(pkts), 0)
4716 self.pg1.add_stream(pkts)
4717 self.pg_enable_capture(self.pg_interfaces)
4719 capture = self.pg0.get_capture(len(pkts))
4721 if p[IP].dst == server1.ip4:
4723 elif p[IP].dst == server2.ip4:
4727 self.assertGreater(server1_n, 0)
4728 self.assertGreater(server2_n, 0)
4729 self.assertGreater(server3_n, 0)
4731 # remove one back-end
4732 self.vapi.nat44_lb_static_mapping_add_del_local(external_addr_n,
4742 self.pg1.add_stream(pkts)
4743 self.pg_enable_capture(self.pg_interfaces)
4745 capture = self.pg0.get_capture(len(pkts))
4747 if p[IP].dst == server1.ip4:
4749 elif p[IP].dst == server2.ip4:
4753 self.assertGreater(server1_n, 0)
4754 self.assertEqual(server2_n, 0)
4755 self.assertGreater(server3_n, 0)
4757 def test_static_lb_2(self):
4758 """ NAT44 local service load balancing (asymmetrical rule) """
4759 external_addr_n = socket.inet_pton(socket.AF_INET, self.nat_addr)
4762 server1 = self.pg0.remote_hosts[0]
4763 server2 = self.pg0.remote_hosts[1]
4765 locals = [{'addr': server1.ip4n,
4769 {'addr': server2.ip4n,
4774 self.vapi.nat44_forwarding_enable_disable(1)
4775 self.vapi.nat44_add_del_lb_static_mapping(external_addr_n,
4779 local_num=len(locals),
4781 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
4782 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
4785 # from client to service
4786 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
4787 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
4788 TCP(sport=12345, dport=external_port))
4789 self.pg1.add_stream(p)
4790 self.pg_enable_capture(self.pg_interfaces)
4792 capture = self.pg0.get_capture(1)
4798 self.assertIn(ip.dst, [server1.ip4, server2.ip4])
4799 if ip.dst == server1.ip4:
4803 self.assertEqual(tcp.dport, local_port)
4804 self.assert_packet_checksums_valid(p)
4806 self.logger.error(ppp("Unexpected or invalid packet:", p))
4809 # from service back to client
4810 p = (Ether(src=server.mac, dst=self.pg0.local_mac) /
4811 IP(src=server.ip4, dst=self.pg1.remote_ip4) /
4812 TCP(sport=local_port, dport=12345))
4813 self.pg0.add_stream(p)
4814 self.pg_enable_capture(self.pg_interfaces)
4816 capture = self.pg1.get_capture(1)
4821 self.assertEqual(ip.src, self.nat_addr)
4822 self.assertEqual(tcp.sport, external_port)
4823 self.assert_packet_checksums_valid(p)
4825 self.logger.error(ppp("Unexpected or invalid packet:", p))
4828 # from client to server (no translation)
4829 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
4830 IP(src=self.pg1.remote_ip4, dst=server1.ip4) /
4831 TCP(sport=12346, dport=local_port))
4832 self.pg1.add_stream(p)
4833 self.pg_enable_capture(self.pg_interfaces)
4835 capture = self.pg0.get_capture(1)
4841 self.assertEqual(ip.dst, server1.ip4)
4842 self.assertEqual(tcp.dport, local_port)
4843 self.assert_packet_checksums_valid(p)
4845 self.logger.error(ppp("Unexpected or invalid packet:", p))
4848 # from service back to client (no translation)
4849 p = (Ether(src=server1.mac, dst=self.pg0.local_mac) /
4850 IP(src=server1.ip4, dst=self.pg1.remote_ip4) /
4851 TCP(sport=local_port, dport=12346))
4852 self.pg0.add_stream(p)
4853 self.pg_enable_capture(self.pg_interfaces)
4855 capture = self.pg1.get_capture(1)
4860 self.assertEqual(ip.src, server1.ip4)
4861 self.assertEqual(tcp.sport, local_port)
4862 self.assert_packet_checksums_valid(p)
4864 self.logger.error(ppp("Unexpected or invalid packet:", p))
4867 def test_lb_affinity(self):
4868 """ NAT44 local service load balancing affinity """
4869 external_addr_n = socket.inet_pton(socket.AF_INET, self.nat_addr)
4872 server1 = self.pg0.remote_hosts[0]
4873 server2 = self.pg0.remote_hosts[1]
4875 locals = [{'addr': server1.ip4n,
4879 {'addr': server2.ip4n,
4884 self.nat44_add_address(self.nat_addr)
4885 self.vapi.nat44_add_del_lb_static_mapping(external_addr_n,
4889 local_num=len(locals),
4891 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
4892 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
4895 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
4896 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
4897 TCP(sport=1025, dport=external_port))
4898 self.pg1.add_stream(p)
4899 self.pg_enable_capture(self.pg_interfaces)
4901 capture = self.pg0.get_capture(1)
4902 backend = capture[0][IP].dst
4904 sessions = self.vapi.nat44_user_session_dump(
4905 socket.inet_pton(socket.AF_INET, backend), 0)
4906 self.assertEqual(len(sessions), 1)
4907 self.assertTrue(sessions[0].ext_host_valid)
4908 self.vapi.nat44_del_session(
4909 sessions[0].inside_ip_address,
4910 sessions[0].inside_port,
4911 sessions[0].protocol,
4912 ext_host_address=sessions[0].ext_host_address,
4913 ext_host_port=sessions[0].ext_host_port)
4916 for port in range(1030, 1100):
4917 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
4918 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
4919 TCP(sport=port, dport=external_port))
4921 self.pg1.add_stream(pkts)
4922 self.pg_enable_capture(self.pg_interfaces)
4924 capture = self.pg0.get_capture(len(pkts))
4926 self.assertEqual(p[IP].dst, backend)
4928 def test_unknown_proto(self):
4929 """ NAT44 translate packet with unknown protocol """
4930 self.nat44_add_address(self.nat_addr)
4931 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
4932 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
4936 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
4937 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
4938 TCP(sport=self.tcp_port_in, dport=20))
4939 self.pg0.add_stream(p)
4940 self.pg_enable_capture(self.pg_interfaces)
4942 p = self.pg1.get_capture(1)
4944 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
4945 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
4947 IP(src=self.pg2.remote_ip4, dst=self.pg2.remote_ip4) /
4948 TCP(sport=1234, dport=1234))
4949 self.pg0.add_stream(p)
4950 self.pg_enable_capture(self.pg_interfaces)
4952 p = self.pg1.get_capture(1)
4955 self.assertEqual(packet[IP].src, self.nat_addr)
4956 self.assertEqual(packet[IP].dst, self.pg1.remote_ip4)
4957 self.assertEqual(packet.haslayer(GRE), 1)
4958 self.assert_packet_checksums_valid(packet)
4960 self.logger.error(ppp("Unexpected or invalid packet:", packet))
4964 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
4965 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
4967 IP(src=self.pg2.remote_ip4, dst=self.pg2.remote_ip4) /
4968 TCP(sport=1234, dport=1234))
4969 self.pg1.add_stream(p)
4970 self.pg_enable_capture(self.pg_interfaces)
4972 p = self.pg0.get_capture(1)
4975 self.assertEqual(packet[IP].src, self.pg1.remote_ip4)
4976 self.assertEqual(packet[IP].dst, self.pg0.remote_ip4)
4977 self.assertEqual(packet.haslayer(GRE), 1)
4978 self.assert_packet_checksums_valid(packet)
4980 self.logger.error(ppp("Unexpected or invalid packet:", packet))
4983 def test_hairpinning_unknown_proto(self):
4984 """ NAT44 translate packet with unknown protocol - hairpinning """
4985 host = self.pg0.remote_hosts[0]
4986 server = self.pg0.remote_hosts[1]
4988 server_out_port = 8765
4989 server_nat_ip = "10.0.0.11"
4991 self.nat44_add_address(self.nat_addr)
4992 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
4993 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
4996 # add static mapping for server
4997 self.nat44_add_static_mapping(server.ip4, server_nat_ip)
5000 p = (Ether(src=host.mac, dst=self.pg0.local_mac) /
5001 IP(src=host.ip4, dst=server_nat_ip) /
5002 TCP(sport=host_in_port, dport=server_out_port))
5003 self.pg0.add_stream(p)
5004 self.pg_enable_capture(self.pg_interfaces)
5006 self.pg0.get_capture(1)
5008 p = (Ether(dst=self.pg0.local_mac, src=host.mac) /
5009 IP(src=host.ip4, dst=server_nat_ip) /
5011 IP(src=self.pg2.remote_ip4, dst=self.pg2.remote_ip4) /
5012 TCP(sport=1234, dport=1234))
5013 self.pg0.add_stream(p)
5014 self.pg_enable_capture(self.pg_interfaces)
5016 p = self.pg0.get_capture(1)
5019 self.assertEqual(packet[IP].src, self.nat_addr)
5020 self.assertEqual(packet[IP].dst, server.ip4)
5021 self.assertEqual(packet.haslayer(GRE), 1)
5022 self.assert_packet_checksums_valid(packet)
5024 self.logger.error(ppp("Unexpected or invalid packet:", packet))
5028 p = (Ether(dst=self.pg0.local_mac, src=server.mac) /
5029 IP(src=server.ip4, dst=self.nat_addr) /
5031 IP(src=self.pg2.remote_ip4, dst=self.pg2.remote_ip4) /
5032 TCP(sport=1234, dport=1234))
5033 self.pg0.add_stream(p)
5034 self.pg_enable_capture(self.pg_interfaces)
5036 p = self.pg0.get_capture(1)
5039 self.assertEqual(packet[IP].src, server_nat_ip)
5040 self.assertEqual(packet[IP].dst, host.ip4)
5041 self.assertEqual(packet.haslayer(GRE), 1)
5042 self.assert_packet_checksums_valid(packet)
5044 self.logger.error(ppp("Unexpected or invalid packet:", packet))
5047 def test_output_feature_and_service(self):
5048 """ NAT44 interface output feature and services """
5049 external_addr = '1.2.3.4'
5053 self.vapi.nat44_forwarding_enable_disable(1)
5054 self.nat44_add_address(self.nat_addr)
5055 self.vapi.nat44_add_del_identity_mapping(ip=self.pg1.remote_ip4n)
5056 self.nat44_add_static_mapping(self.pg0.remote_ip4, external_addr,
5057 local_port, external_port,
5058 proto=IP_PROTOS.tcp, out2in_only=1)
5059 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
5060 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index,
5062 self.vapi.nat44_interface_add_del_output_feature(self.pg1.sw_if_index,
5065 # from client to service
5066 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
5067 IP(src=self.pg1.remote_ip4, dst=external_addr) /
5068 TCP(sport=12345, dport=external_port))
5069 self.pg1.add_stream(p)
5070 self.pg_enable_capture(self.pg_interfaces)
5072 capture = self.pg0.get_capture(1)
5077 self.assertEqual(ip.dst, self.pg0.remote_ip4)
5078 self.assertEqual(tcp.dport, local_port)
5079 self.assert_packet_checksums_valid(p)
5081 self.logger.error(ppp("Unexpected or invalid packet:", p))
5084 # from service back to client
5085 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5086 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
5087 TCP(sport=local_port, dport=12345))
5088 self.pg0.add_stream(p)
5089 self.pg_enable_capture(self.pg_interfaces)
5091 capture = self.pg1.get_capture(1)
5096 self.assertEqual(ip.src, external_addr)
5097 self.assertEqual(tcp.sport, external_port)
5098 self.assert_packet_checksums_valid(p)
5100 self.logger.error(ppp("Unexpected or invalid packet:", p))
5103 # from local network host to external network
5104 pkts = self.create_stream_in(self.pg0, self.pg1)
5105 self.pg0.add_stream(pkts)
5106 self.pg_enable_capture(self.pg_interfaces)
5108 capture = self.pg1.get_capture(len(pkts))
5109 self.verify_capture_out(capture)
5110 pkts = self.create_stream_in(self.pg0, self.pg1)
5111 self.pg0.add_stream(pkts)
5112 self.pg_enable_capture(self.pg_interfaces)
5114 capture = self.pg1.get_capture(len(pkts))
5115 self.verify_capture_out(capture)
5117 # from external network back to local network host
5118 pkts = self.create_stream_out(self.pg1)
5119 self.pg1.add_stream(pkts)
5120 self.pg_enable_capture(self.pg_interfaces)
5122 capture = self.pg0.get_capture(len(pkts))
5123 self.verify_capture_in(capture, self.pg0)
5125 def test_output_feature_and_service2(self):
5126 """ NAT44 interface output feature and service host direct access """
5127 self.vapi.nat44_forwarding_enable_disable(1)
5128 self.nat44_add_address(self.nat_addr)
5129 self.vapi.nat44_interface_add_del_output_feature(self.pg1.sw_if_index,
5132 # session initiaded from service host - translate
5133 pkts = self.create_stream_in(self.pg0, self.pg1)
5134 self.pg0.add_stream(pkts)
5135 self.pg_enable_capture(self.pg_interfaces)
5137 capture = self.pg1.get_capture(len(pkts))
5138 self.verify_capture_out(capture)
5140 pkts = self.create_stream_out(self.pg1)
5141 self.pg1.add_stream(pkts)
5142 self.pg_enable_capture(self.pg_interfaces)
5144 capture = self.pg0.get_capture(len(pkts))
5145 self.verify_capture_in(capture, self.pg0)
5147 # session initiaded from remote host - do not translate
5148 self.tcp_port_in = 60303
5149 self.udp_port_in = 60304
5150 self.icmp_id_in = 60305
5151 pkts = self.create_stream_out(self.pg1,
5152 self.pg0.remote_ip4,
5153 use_inside_ports=True)
5154 self.pg1.add_stream(pkts)
5155 self.pg_enable_capture(self.pg_interfaces)
5157 capture = self.pg0.get_capture(len(pkts))
5158 self.verify_capture_in(capture, self.pg0)
5160 pkts = self.create_stream_in(self.pg0, self.pg1)
5161 self.pg0.add_stream(pkts)
5162 self.pg_enable_capture(self.pg_interfaces)
5164 capture = self.pg1.get_capture(len(pkts))
5165 self.verify_capture_out(capture, nat_ip=self.pg0.remote_ip4,
5168 def test_output_feature_and_service3(self):
5169 """ NAT44 interface output feature and DST NAT """
5170 external_addr = '1.2.3.4'
5174 self.vapi.nat44_forwarding_enable_disable(1)
5175 self.nat44_add_address(self.nat_addr)
5176 self.nat44_add_static_mapping(self.pg1.remote_ip4, external_addr,
5177 local_port, external_port,
5178 proto=IP_PROTOS.tcp, out2in_only=1)
5179 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
5180 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index,
5182 self.vapi.nat44_interface_add_del_output_feature(self.pg1.sw_if_index,
5185 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5186 IP(src=self.pg0.remote_ip4, dst=external_addr) /
5187 TCP(sport=12345, dport=external_port))
5188 self.pg0.add_stream(p)
5189 self.pg_enable_capture(self.pg_interfaces)
5191 capture = self.pg1.get_capture(1)
5196 self.assertEqual(ip.src, self.pg0.remote_ip4)
5197 self.assertEqual(tcp.sport, 12345)
5198 self.assertEqual(ip.dst, self.pg1.remote_ip4)
5199 self.assertEqual(tcp.dport, local_port)
5200 self.assert_packet_checksums_valid(p)
5202 self.logger.error(ppp("Unexpected or invalid packet:", p))
5205 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
5206 IP(src=self.pg1.remote_ip4, dst=self.pg0.remote_ip4) /
5207 TCP(sport=local_port, dport=12345))
5208 self.pg1.add_stream(p)
5209 self.pg_enable_capture(self.pg_interfaces)
5211 capture = self.pg0.get_capture(1)
5216 self.assertEqual(ip.src, external_addr)
5217 self.assertEqual(tcp.sport, external_port)
5218 self.assertEqual(ip.dst, self.pg0.remote_ip4)
5219 self.assertEqual(tcp.dport, 12345)
5220 self.assert_packet_checksums_valid(p)
5222 self.logger.error(ppp("Unexpected or invalid packet:", p))
5225 def test_next_src_nat(self):
5226 """ On way back forward packet to nat44-in2out node. """
5227 twice_nat_addr = '10.0.1.3'
5230 post_twice_nat_port = 0
5232 self.vapi.nat44_forwarding_enable_disable(1)
5233 self.nat44_add_address(twice_nat_addr, twice_nat=1)
5234 self.nat44_add_static_mapping(self.pg6.remote_ip4, self.pg1.remote_ip4,
5235 local_port, external_port,
5236 proto=IP_PROTOS.tcp, out2in_only=1,
5237 self_twice_nat=1, vrf_id=1)
5238 self.vapi.nat44_interface_add_del_feature(self.pg6.sw_if_index,
5241 p = (Ether(src=self.pg6.remote_mac, dst=self.pg6.local_mac) /
5242 IP(src=self.pg6.remote_ip4, dst=self.pg1.remote_ip4) /
5243 TCP(sport=12345, dport=external_port))
5244 self.pg6.add_stream(p)
5245 self.pg_enable_capture(self.pg_interfaces)
5247 capture = self.pg6.get_capture(1)
5252 self.assertEqual(ip.src, twice_nat_addr)
5253 self.assertNotEqual(tcp.sport, 12345)
5254 post_twice_nat_port = tcp.sport
5255 self.assertEqual(ip.dst, self.pg6.remote_ip4)
5256 self.assertEqual(tcp.dport, local_port)
5257 self.assert_packet_checksums_valid(p)
5259 self.logger.error(ppp("Unexpected or invalid packet:", p))
5262 p = (Ether(src=self.pg6.remote_mac, dst=self.pg6.local_mac) /
5263 IP(src=self.pg6.remote_ip4, dst=twice_nat_addr) /
5264 TCP(sport=local_port, dport=post_twice_nat_port))
5265 self.pg6.add_stream(p)
5266 self.pg_enable_capture(self.pg_interfaces)
5268 capture = self.pg6.get_capture(1)
5273 self.assertEqual(ip.src, self.pg1.remote_ip4)
5274 self.assertEqual(tcp.sport, external_port)
5275 self.assertEqual(ip.dst, self.pg6.remote_ip4)
5276 self.assertEqual(tcp.dport, 12345)
5277 self.assert_packet_checksums_valid(p)
5279 self.logger.error(ppp("Unexpected or invalid packet:", p))
5282 def twice_nat_common(self, self_twice_nat=False, same_pg=False, lb=False,
5284 twice_nat_addr = '10.0.1.3'
5292 port_in1 = port_in + 1
5293 port_in2 = port_in + 2
5298 server1 = self.pg0.remote_hosts[0]
5299 server2 = self.pg0.remote_hosts[1]
5311 eh_translate = ((not self_twice_nat) or (not lb and same_pg) or
5314 self.nat44_add_address(self.nat_addr)
5315 self.nat44_add_address(twice_nat_addr, twice_nat=1)
5317 self.nat44_add_static_mapping(pg0.remote_ip4, self.nat_addr,
5319 proto=IP_PROTOS.tcp,
5320 twice_nat=int(not self_twice_nat),
5321 self_twice_nat=int(self_twice_nat))
5323 locals = [{'addr': server1.ip4n,
5327 {'addr': server2.ip4n,
5331 out_addr_n = socket.inet_pton(socket.AF_INET, self.nat_addr)
5332 self.vapi.nat44_add_del_lb_static_mapping(out_addr_n,
5336 not self_twice_nat),
5339 local_num=len(locals),
5341 self.vapi.nat44_interface_add_del_feature(pg0.sw_if_index)
5342 self.vapi.nat44_interface_add_del_feature(pg1.sw_if_index,
5349 assert client_id is not None
5351 client = self.pg0.remote_hosts[0]
5352 elif client_id == 2:
5353 client = self.pg0.remote_hosts[1]
5355 client = pg1.remote_hosts[0]
5356 p = (Ether(src=pg1.remote_mac, dst=pg1.local_mac) /
5357 IP(src=client.ip4, dst=self.nat_addr) /
5358 TCP(sport=eh_port_out, dport=port_out))
5360 self.pg_enable_capture(self.pg_interfaces)
5362 capture = pg0.get_capture(1)
5368 if ip.dst == server1.ip4:
5374 self.assertEqual(ip.dst, server.ip4)
5376 self.assertIn(tcp.dport, [port_in1, port_in2])
5378 self.assertEqual(tcp.dport, port_in)
5380 self.assertEqual(ip.src, twice_nat_addr)
5381 self.assertNotEqual(tcp.sport, eh_port_out)
5383 self.assertEqual(ip.src, client.ip4)
5384 self.assertEqual(tcp.sport, eh_port_out)
5386 eh_port_in = tcp.sport
5387 saved_port_in = tcp.dport
5388 self.assert_packet_checksums_valid(p)
5390 self.logger.error(ppp("Unexpected or invalid packet:", p))
5393 p = (Ether(src=server.mac, dst=pg0.local_mac) /
5394 IP(src=server.ip4, dst=eh_addr_in) /
5395 TCP(sport=saved_port_in, dport=eh_port_in))
5397 self.pg_enable_capture(self.pg_interfaces)
5399 capture = pg1.get_capture(1)
5404 self.assertEqual(ip.dst, client.ip4)
5405 self.assertEqual(ip.src, self.nat_addr)
5406 self.assertEqual(tcp.dport, eh_port_out)
5407 self.assertEqual(tcp.sport, port_out)
5408 self.assert_packet_checksums_valid(p)
5410 self.logger.error(ppp("Unexpected or invalid packet:", p))
5414 sessions = self.vapi.nat44_user_session_dump(server.ip4n, 0)
5415 self.assertEqual(len(sessions), 1)
5416 self.assertTrue(sessions[0].ext_host_valid)
5417 self.assertTrue(sessions[0].is_twicenat)
5418 self.vapi.nat44_del_session(
5419 sessions[0].inside_ip_address,
5420 sessions[0].inside_port,
5421 sessions[0].protocol,
5422 ext_host_address=sessions[0].ext_host_nat_address,
5423 ext_host_port=sessions[0].ext_host_nat_port)
5424 sessions = self.vapi.nat44_user_session_dump(server.ip4n, 0)
5425 self.assertEqual(len(sessions), 0)
5427 def test_twice_nat(self):
5429 self.twice_nat_common()
5431 def test_self_twice_nat_positive(self):
5432 """ Self Twice NAT44 (positive test) """
5433 self.twice_nat_common(self_twice_nat=True, same_pg=True)
5435 def test_self_twice_nat_negative(self):
5436 """ Self Twice NAT44 (negative test) """
5437 self.twice_nat_common(self_twice_nat=True)
5439 def test_twice_nat_lb(self):
5440 """ Twice NAT44 local service load balancing """
5441 self.twice_nat_common(lb=True)
5443 def test_self_twice_nat_lb_positive(self):
5444 """ Self Twice NAT44 local service load balancing (positive test) """
5445 self.twice_nat_common(lb=True, self_twice_nat=True, same_pg=True,
5448 def test_self_twice_nat_lb_negative(self):
5449 """ Self Twice NAT44 local service load balancing (negative test) """
5450 self.twice_nat_common(lb=True, self_twice_nat=True, same_pg=True,
5453 def test_twice_nat_interface_addr(self):
5454 """ Acquire twice NAT44 addresses from interface """
5455 self.vapi.nat44_add_del_interface_addr(self.pg3.sw_if_index,
5458 # no address in NAT pool
5459 adresses = self.vapi.nat44_address_dump()
5460 self.assertEqual(0, len(adresses))
5462 # configure interface address and check NAT address pool
5463 self.pg3.config_ip4()
5464 adresses = self.vapi.nat44_address_dump()
5465 self.assertEqual(1, len(adresses))
5466 self.assertEqual(adresses[0].ip_address[0:4], self.pg3.local_ip4n)
5467 self.assertEqual(adresses[0].twice_nat, 1)
5469 # remove interface address and check NAT address pool
5470 self.pg3.unconfig_ip4()
5471 adresses = self.vapi.nat44_address_dump()
5472 self.assertEqual(0, len(adresses))
5474 def test_tcp_close(self):
5475 """ Close TCP session from inside network - output feature """
5476 self.vapi.nat44_forwarding_enable_disable(1)
5477 self.nat44_add_address(self.pg1.local_ip4)
5478 twice_nat_addr = '10.0.1.3'
5479 service_ip = '192.168.16.150'
5480 self.nat44_add_address(twice_nat_addr, twice_nat=1)
5481 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
5482 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index,
5484 self.vapi.nat44_interface_add_del_output_feature(self.pg1.sw_if_index,
5486 self.nat44_add_static_mapping(self.pg0.remote_ip4,
5490 proto=IP_PROTOS.tcp,
5493 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4n, 0)
5494 start_sessnum = len(sessions)
5496 # SYN packet out->in
5497 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
5498 IP(src=self.pg1.remote_ip4, dst=service_ip) /
5499 TCP(sport=33898, dport=80, flags="S"))
5500 self.pg1.add_stream(p)
5501 self.pg_enable_capture(self.pg_interfaces)
5503 capture = self.pg0.get_capture(1)
5505 tcp_port = p[TCP].sport
5507 # SYN + ACK packet in->out
5508 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5509 IP(src=self.pg0.remote_ip4, dst=twice_nat_addr) /
5510 TCP(sport=80, dport=tcp_port, flags="SA"))
5511 self.pg0.add_stream(p)
5512 self.pg_enable_capture(self.pg_interfaces)
5514 self.pg1.get_capture(1)
5516 # ACK packet out->in
5517 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
5518 IP(src=self.pg1.remote_ip4, dst=service_ip) /
5519 TCP(sport=33898, dport=80, flags="A"))
5520 self.pg1.add_stream(p)
5521 self.pg_enable_capture(self.pg_interfaces)
5523 self.pg0.get_capture(1)
5525 # FIN packet in -> out
5526 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5527 IP(src=self.pg0.remote_ip4, dst=twice_nat_addr) /
5528 TCP(sport=80, dport=tcp_port, flags="FA", seq=100, ack=300))
5529 self.pg0.add_stream(p)
5530 self.pg_enable_capture(self.pg_interfaces)
5532 self.pg1.get_capture(1)
5534 # FIN+ACK packet out -> in
5535 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
5536 IP(src=self.pg1.remote_ip4, dst=service_ip) /
5537 TCP(sport=33898, dport=80, flags="FA", seq=300, ack=101))
5538 self.pg1.add_stream(p)
5539 self.pg_enable_capture(self.pg_interfaces)
5541 self.pg0.get_capture(1)
5543 # ACK packet in -> out
5544 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5545 IP(src=self.pg0.remote_ip4, dst=twice_nat_addr) /
5546 TCP(sport=80, dport=tcp_port, flags="A", seq=101, ack=301))
5547 self.pg0.add_stream(p)
5548 self.pg_enable_capture(self.pg_interfaces)
5550 self.pg1.get_capture(1)
5552 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4n,
5554 self.assertEqual(len(sessions) - start_sessnum, 0)
5556 def test_tcp_session_close_in(self):
5557 """ Close TCP session from inside network """
5558 self.tcp_port_out = 10505
5559 self.nat44_add_address(self.nat_addr)
5560 self.nat44_add_static_mapping(self.pg0.remote_ip4,
5564 proto=IP_PROTOS.tcp,
5566 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
5567 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
5570 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4n, 0)
5571 start_sessnum = len(sessions)
5573 self.initiate_tcp_session(self.pg0, self.pg1)
5575 # FIN packet in -> out
5576 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5577 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
5578 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
5579 flags="FA", seq=100, ack=300))
5580 self.pg0.add_stream(p)
5581 self.pg_enable_capture(self.pg_interfaces)
5583 self.pg1.get_capture(1)
5587 # ACK packet out -> in
5588 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
5589 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
5590 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
5591 flags="A", seq=300, ack=101))
5594 # FIN packet out -> in
5595 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
5596 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
5597 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
5598 flags="FA", seq=300, ack=101))
5601 self.pg1.add_stream(pkts)
5602 self.pg_enable_capture(self.pg_interfaces)
5604 self.pg0.get_capture(2)
5606 # ACK packet in -> out
5607 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5608 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
5609 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
5610 flags="A", seq=101, ack=301))
5611 self.pg0.add_stream(p)
5612 self.pg_enable_capture(self.pg_interfaces)
5614 self.pg1.get_capture(1)
5616 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4n,
5618 self.assertEqual(len(sessions) - start_sessnum, 0)
5620 def test_tcp_session_close_out(self):
5621 """ Close TCP session from outside network """
5622 self.tcp_port_out = 10505
5623 self.nat44_add_address(self.nat_addr)
5624 self.nat44_add_static_mapping(self.pg0.remote_ip4,
5628 proto=IP_PROTOS.tcp,
5630 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
5631 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
5634 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4n, 0)
5635 start_sessnum = len(sessions)
5637 self.initiate_tcp_session(self.pg0, self.pg1)
5639 # FIN packet out -> in
5640 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
5641 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
5642 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
5643 flags="FA", seq=100, ack=300))
5644 self.pg1.add_stream(p)
5645 self.pg_enable_capture(self.pg_interfaces)
5647 self.pg0.get_capture(1)
5649 # FIN+ACK packet in -> out
5650 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5651 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
5652 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
5653 flags="FA", seq=300, ack=101))
5655 self.pg0.add_stream(p)
5656 self.pg_enable_capture(self.pg_interfaces)
5658 self.pg1.get_capture(1)
5660 # ACK packet out -> in
5661 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
5662 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
5663 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
5664 flags="A", seq=101, ack=301))
5665 self.pg1.add_stream(p)
5666 self.pg_enable_capture(self.pg_interfaces)
5668 self.pg0.get_capture(1)
5670 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4n,
5672 self.assertEqual(len(sessions) - start_sessnum, 0)
5674 def test_tcp_session_close_simultaneous(self):
5675 """ Close TCP session from inside network """
5676 self.tcp_port_out = 10505
5677 self.nat44_add_address(self.nat_addr)
5678 self.nat44_add_static_mapping(self.pg0.remote_ip4,
5682 proto=IP_PROTOS.tcp,
5684 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
5685 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
5688 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4n, 0)
5689 start_sessnum = len(sessions)
5691 self.initiate_tcp_session(self.pg0, self.pg1)
5693 # FIN packet in -> out
5694 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5695 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
5696 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
5697 flags="FA", seq=100, ack=300))
5698 self.pg0.add_stream(p)
5699 self.pg_enable_capture(self.pg_interfaces)
5701 self.pg1.get_capture(1)
5703 # FIN packet out -> in
5704 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
5705 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
5706 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
5707 flags="FA", seq=300, ack=100))
5708 self.pg1.add_stream(p)
5709 self.pg_enable_capture(self.pg_interfaces)
5711 self.pg0.get_capture(1)
5713 # ACK packet in -> out
5714 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5715 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
5716 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
5717 flags="A", seq=101, ack=301))
5718 self.pg0.add_stream(p)
5719 self.pg_enable_capture(self.pg_interfaces)
5721 self.pg1.get_capture(1)
5723 # ACK packet out -> in
5724 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
5725 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
5726 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
5727 flags="A", seq=301, ack=101))
5728 self.pg1.add_stream(p)
5729 self.pg_enable_capture(self.pg_interfaces)
5731 self.pg0.get_capture(1)
5733 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4n,
5735 self.assertEqual(len(sessions) - start_sessnum, 0)
5737 def test_one_armed_nat44_static(self):
5738 """ One armed NAT44 and 1:1 NAPT asymmetrical rule """
5739 remote_host = self.pg4.remote_hosts[0]
5740 local_host = self.pg4.remote_hosts[1]
5745 self.vapi.nat44_forwarding_enable_disable(1)
5746 self.nat44_add_address(self.nat_addr, twice_nat=1)
5747 self.nat44_add_static_mapping(local_host.ip4, self.nat_addr,
5748 local_port, external_port,
5749 proto=IP_PROTOS.tcp, out2in_only=1,
5751 self.vapi.nat44_interface_add_del_feature(self.pg4.sw_if_index)
5752 self.vapi.nat44_interface_add_del_feature(self.pg4.sw_if_index,
5755 # from client to service
5756 p = (Ether(src=self.pg4.remote_mac, dst=self.pg4.local_mac) /
5757 IP(src=remote_host.ip4, dst=self.nat_addr) /
5758 TCP(sport=12345, dport=external_port))
5759 self.pg4.add_stream(p)
5760 self.pg_enable_capture(self.pg_interfaces)
5762 capture = self.pg4.get_capture(1)
5767 self.assertEqual(ip.dst, local_host.ip4)
5768 self.assertEqual(ip.src, self.nat_addr)
5769 self.assertEqual(tcp.dport, local_port)
5770 self.assertNotEqual(tcp.sport, 12345)
5771 eh_port_in = tcp.sport
5772 self.assert_packet_checksums_valid(p)
5774 self.logger.error(ppp("Unexpected or invalid packet:", p))
5777 # from service back to client
5778 p = (Ether(src=self.pg4.remote_mac, dst=self.pg4.local_mac) /
5779 IP(src=local_host.ip4, dst=self.nat_addr) /
5780 TCP(sport=local_port, dport=eh_port_in))
5781 self.pg4.add_stream(p)
5782 self.pg_enable_capture(self.pg_interfaces)
5784 capture = self.pg4.get_capture(1)
5789 self.assertEqual(ip.src, self.nat_addr)
5790 self.assertEqual(ip.dst, remote_host.ip4)
5791 self.assertEqual(tcp.sport, external_port)
5792 self.assertEqual(tcp.dport, 12345)
5793 self.assert_packet_checksums_valid(p)
5795 self.logger.error(ppp("Unexpected or invalid packet:", p))
5798 def test_static_with_port_out2(self):
5799 """ 1:1 NAPT asymmetrical rule """
5804 self.vapi.nat44_forwarding_enable_disable(1)
5805 self.nat44_add_static_mapping(self.pg0.remote_ip4, self.nat_addr,
5806 local_port, external_port,
5807 proto=IP_PROTOS.tcp, out2in_only=1)
5808 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
5809 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
5812 # from client to service
5813 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
5814 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
5815 TCP(sport=12345, dport=external_port))
5816 self.pg1.add_stream(p)
5817 self.pg_enable_capture(self.pg_interfaces)
5819 capture = self.pg0.get_capture(1)
5824 self.assertEqual(ip.dst, self.pg0.remote_ip4)
5825 self.assertEqual(tcp.dport, local_port)
5826 self.assert_packet_checksums_valid(p)
5828 self.logger.error(ppp("Unexpected or invalid packet:", p))
5832 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
5833 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
5834 ICMP(type=11) / capture[0][IP])
5835 self.pg0.add_stream(p)
5836 self.pg_enable_capture(self.pg_interfaces)
5838 capture = self.pg1.get_capture(1)
5841 self.assertEqual(p[IP].src, self.nat_addr)
5843 self.assertEqual(inner.dst, self.nat_addr)
5844 self.assertEqual(inner[TCPerror].dport, external_port)
5846 self.logger.error(ppp("Unexpected or invalid packet:", p))
5849 # from service back to client
5850 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5851 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
5852 TCP(sport=local_port, dport=12345))
5853 self.pg0.add_stream(p)
5854 self.pg_enable_capture(self.pg_interfaces)
5856 capture = self.pg1.get_capture(1)
5861 self.assertEqual(ip.src, self.nat_addr)
5862 self.assertEqual(tcp.sport, external_port)
5863 self.assert_packet_checksums_valid(p)
5865 self.logger.error(ppp("Unexpected or invalid packet:", p))
5869 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
5870 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
5871 ICMP(type=11) / capture[0][IP])
5872 self.pg1.add_stream(p)
5873 self.pg_enable_capture(self.pg_interfaces)
5875 capture = self.pg0.get_capture(1)
5878 self.assertEqual(p[IP].dst, self.pg0.remote_ip4)
5880 self.assertEqual(inner.src, self.pg0.remote_ip4)
5881 self.assertEqual(inner[TCPerror].sport, local_port)
5883 self.logger.error(ppp("Unexpected or invalid packet:", p))
5886 # from client to server (no translation)
5887 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
5888 IP(src=self.pg1.remote_ip4, dst=self.pg0.remote_ip4) /
5889 TCP(sport=12346, dport=local_port))
5890 self.pg1.add_stream(p)
5891 self.pg_enable_capture(self.pg_interfaces)
5893 capture = self.pg0.get_capture(1)
5898 self.assertEqual(ip.dst, self.pg0.remote_ip4)
5899 self.assertEqual(tcp.dport, local_port)
5900 self.assert_packet_checksums_valid(p)
5902 self.logger.error(ppp("Unexpected or invalid packet:", p))
5905 # from service back to client (no translation)
5906 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5907 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
5908 TCP(sport=local_port, dport=12346))
5909 self.pg0.add_stream(p)
5910 self.pg_enable_capture(self.pg_interfaces)
5912 capture = self.pg1.get_capture(1)
5917 self.assertEqual(ip.src, self.pg0.remote_ip4)
5918 self.assertEqual(tcp.sport, local_port)
5919 self.assert_packet_checksums_valid(p)
5921 self.logger.error(ppp("Unexpected or invalid packet:", p))
5924 def test_output_feature(self):
5925 """ NAT44 interface output feature (in2out postrouting) """
5926 self.vapi.nat44_forwarding_enable_disable(1)
5927 self.nat44_add_address(self.nat_addr)
5928 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index,
5930 self.vapi.nat44_interface_add_del_output_feature(self.pg1.sw_if_index,
5934 pkts = self.create_stream_in(self.pg0, self.pg1)
5935 self.pg0.add_stream(pkts)
5936 self.pg_enable_capture(self.pg_interfaces)
5938 capture = self.pg1.get_capture(len(pkts))
5939 self.verify_capture_out(capture)
5942 pkts = self.create_stream_out(self.pg1)
5943 self.pg1.add_stream(pkts)
5944 self.pg_enable_capture(self.pg_interfaces)
5946 capture = self.pg0.get_capture(len(pkts))
5947 self.verify_capture_in(capture, self.pg0)
5949 def test_multiple_vrf(self):
5950 """ Multiple VRF setup """
5951 external_addr = '1.2.3.4'
5956 self.vapi.nat44_forwarding_enable_disable(1)
5957 self.nat44_add_address(self.nat_addr)
5958 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
5959 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index,
5961 self.vapi.nat44_interface_add_del_output_feature(self.pg1.sw_if_index,
5963 self.vapi.nat44_interface_add_del_feature(self.pg5.sw_if_index)
5964 self.vapi.nat44_interface_add_del_feature(self.pg5.sw_if_index,
5966 self.vapi.nat44_interface_add_del_feature(self.pg6.sw_if_index,
5968 self.nat44_add_static_mapping(self.pg5.remote_ip4, external_addr,
5969 local_port, external_port, vrf_id=1,
5970 proto=IP_PROTOS.tcp, out2in_only=1)
5971 self.nat44_add_static_mapping(
5972 self.pg0.remote_ip4, external_sw_if_index=self.pg0.sw_if_index,
5973 local_port=local_port, vrf_id=0, external_port=external_port,
5974 proto=IP_PROTOS.tcp, out2in_only=1)
5976 # from client to service (both VRF1)
5977 p = (Ether(src=self.pg6.remote_mac, dst=self.pg6.local_mac) /
5978 IP(src=self.pg6.remote_ip4, dst=external_addr) /
5979 TCP(sport=12345, dport=external_port))
5980 self.pg6.add_stream(p)
5981 self.pg_enable_capture(self.pg_interfaces)
5983 capture = self.pg5.get_capture(1)
5988 self.assertEqual(ip.dst, self.pg5.remote_ip4)
5989 self.assertEqual(tcp.dport, local_port)
5990 self.assert_packet_checksums_valid(p)
5992 self.logger.error(ppp("Unexpected or invalid packet:", p))
5995 # from service back to client (both VRF1)
5996 p = (Ether(src=self.pg5.remote_mac, dst=self.pg5.local_mac) /
5997 IP(src=self.pg5.remote_ip4, dst=self.pg6.remote_ip4) /
5998 TCP(sport=local_port, dport=12345))
5999 self.pg5.add_stream(p)
6000 self.pg_enable_capture(self.pg_interfaces)
6002 capture = self.pg6.get_capture(1)
6007 self.assertEqual(ip.src, external_addr)
6008 self.assertEqual(tcp.sport, external_port)
6009 self.assert_packet_checksums_valid(p)
6011 self.logger.error(ppp("Unexpected or invalid packet:", p))
6014 # dynamic NAT from VRF1 to VRF0 (output-feature)
6015 p = (Ether(src=self.pg5.remote_mac, dst=self.pg5.local_mac) /
6016 IP(src=self.pg5.remote_ip4, dst=self.pg1.remote_ip4) /
6017 TCP(sport=2345, dport=22))
6018 self.pg5.add_stream(p)
6019 self.pg_enable_capture(self.pg_interfaces)
6021 capture = self.pg1.get_capture(1)
6026 self.assertEqual(ip.src, self.nat_addr)
6027 self.assertNotEqual(tcp.sport, 2345)
6028 self.assert_packet_checksums_valid(p)
6031 self.logger.error(ppp("Unexpected or invalid packet:", p))
6034 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
6035 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
6036 TCP(sport=22, dport=port))
6037 self.pg1.add_stream(p)
6038 self.pg_enable_capture(self.pg_interfaces)
6040 capture = self.pg5.get_capture(1)
6045 self.assertEqual(ip.dst, self.pg5.remote_ip4)
6046 self.assertEqual(tcp.dport, 2345)
6047 self.assert_packet_checksums_valid(p)
6049 self.logger.error(ppp("Unexpected or invalid packet:", p))
6052 # from client VRF1 to service VRF0
6053 p = (Ether(src=self.pg6.remote_mac, dst=self.pg6.local_mac) /
6054 IP(src=self.pg6.remote_ip4, dst=self.pg0.local_ip4) /
6055 TCP(sport=12346, dport=external_port))
6056 self.pg6.add_stream(p)
6057 self.pg_enable_capture(self.pg_interfaces)
6059 capture = self.pg0.get_capture(1)
6064 self.assertEqual(ip.dst, self.pg0.remote_ip4)
6065 self.assertEqual(tcp.dport, local_port)
6066 self.assert_packet_checksums_valid(p)
6068 self.logger.error(ppp("Unexpected or invalid packet:", p))
6071 # from service VRF0 back to client VRF1
6072 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6073 IP(src=self.pg0.remote_ip4, dst=self.pg6.remote_ip4) /
6074 TCP(sport=local_port, dport=12346))
6075 self.pg0.add_stream(p)
6076 self.pg_enable_capture(self.pg_interfaces)
6078 capture = self.pg6.get_capture(1)
6083 self.assertEqual(ip.src, self.pg0.local_ip4)
6084 self.assertEqual(tcp.sport, external_port)
6085 self.assert_packet_checksums_valid(p)
6087 self.logger.error(ppp("Unexpected or invalid packet:", p))
6090 # from client VRF0 to service VRF1
6091 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6092 IP(src=self.pg0.remote_ip4, dst=external_addr) /
6093 TCP(sport=12347, dport=external_port))
6094 self.pg0.add_stream(p)
6095 self.pg_enable_capture(self.pg_interfaces)
6097 capture = self.pg5.get_capture(1)
6102 self.assertEqual(ip.dst, self.pg5.remote_ip4)
6103 self.assertEqual(tcp.dport, local_port)
6104 self.assert_packet_checksums_valid(p)
6106 self.logger.error(ppp("Unexpected or invalid packet:", p))
6109 # from service VRF1 back to client VRF0
6110 p = (Ether(src=self.pg5.remote_mac, dst=self.pg5.local_mac) /
6111 IP(src=self.pg5.remote_ip4, dst=self.pg0.remote_ip4) /
6112 TCP(sport=local_port, dport=12347))
6113 self.pg5.add_stream(p)
6114 self.pg_enable_capture(self.pg_interfaces)
6116 capture = self.pg0.get_capture(1)
6121 self.assertEqual(ip.src, external_addr)
6122 self.assertEqual(tcp.sport, external_port)
6123 self.assert_packet_checksums_valid(p)
6125 self.logger.error(ppp("Unexpected or invalid packet:", p))
6128 # from client to server (both VRF1, no translation)
6129 p = (Ether(src=self.pg6.remote_mac, dst=self.pg6.local_mac) /
6130 IP(src=self.pg6.remote_ip4, dst=self.pg5.remote_ip4) /
6131 TCP(sport=12348, dport=local_port))
6132 self.pg6.add_stream(p)
6133 self.pg_enable_capture(self.pg_interfaces)
6135 capture = self.pg5.get_capture(1)
6140 self.assertEqual(ip.dst, self.pg5.remote_ip4)
6141 self.assertEqual(tcp.dport, local_port)
6142 self.assert_packet_checksums_valid(p)
6144 self.logger.error(ppp("Unexpected or invalid packet:", p))
6147 # from server back to client (both VRF1, no translation)
6148 p = (Ether(src=self.pg5.remote_mac, dst=self.pg5.local_mac) /
6149 IP(src=self.pg5.remote_ip4, dst=self.pg6.remote_ip4) /
6150 TCP(sport=local_port, dport=12348))
6151 self.pg5.add_stream(p)
6152 self.pg_enable_capture(self.pg_interfaces)
6154 capture = self.pg6.get_capture(1)
6159 self.assertEqual(ip.src, self.pg5.remote_ip4)
6160 self.assertEqual(tcp.sport, local_port)
6161 self.assert_packet_checksums_valid(p)
6163 self.logger.error(ppp("Unexpected or invalid packet:", p))
6166 # from client VRF1 to server VRF0 (no translation)
6167 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6168 IP(src=self.pg0.remote_ip4, dst=self.pg6.remote_ip4) /
6169 TCP(sport=local_port, dport=12349))
6170 self.pg0.add_stream(p)
6171 self.pg_enable_capture(self.pg_interfaces)
6173 capture = self.pg6.get_capture(1)
6178 self.assertEqual(ip.src, self.pg0.remote_ip4)
6179 self.assertEqual(tcp.sport, local_port)
6180 self.assert_packet_checksums_valid(p)
6182 self.logger.error(ppp("Unexpected or invalid packet:", p))
6185 # from server VRF0 back to client VRF1 (no translation)
6186 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6187 IP(src=self.pg0.remote_ip4, dst=self.pg6.remote_ip4) /
6188 TCP(sport=local_port, dport=12349))
6189 self.pg0.add_stream(p)
6190 self.pg_enable_capture(self.pg_interfaces)
6192 capture = self.pg6.get_capture(1)
6197 self.assertEqual(ip.src, self.pg0.remote_ip4)
6198 self.assertEqual(tcp.sport, local_port)
6199 self.assert_packet_checksums_valid(p)
6201 self.logger.error(ppp("Unexpected or invalid packet:", p))
6204 # from client VRF0 to server VRF1 (no translation)
6205 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6206 IP(src=self.pg0.remote_ip4, dst=self.pg5.remote_ip4) /
6207 TCP(sport=12344, dport=local_port))
6208 self.pg0.add_stream(p)
6209 self.pg_enable_capture(self.pg_interfaces)
6211 capture = self.pg5.get_capture(1)
6216 self.assertEqual(ip.dst, self.pg5.remote_ip4)
6217 self.assertEqual(tcp.dport, local_port)
6218 self.assert_packet_checksums_valid(p)
6220 self.logger.error(ppp("Unexpected or invalid packet:", p))
6223 # from server VRF1 back to client VRF0 (no translation)
6224 p = (Ether(src=self.pg5.remote_mac, dst=self.pg5.local_mac) /
6225 IP(src=self.pg5.remote_ip4, dst=self.pg0.remote_ip4) /
6226 TCP(sport=local_port, dport=12344))
6227 self.pg5.add_stream(p)
6228 self.pg_enable_capture(self.pg_interfaces)
6230 capture = self.pg0.get_capture(1)
6235 self.assertEqual(ip.src, self.pg5.remote_ip4)
6236 self.assertEqual(tcp.sport, local_port)
6237 self.assert_packet_checksums_valid(p)
6239 self.logger.error(ppp("Unexpected or invalid packet:", p))
6242 @unittest.skipUnless(running_extended_tests, "part of extended tests")
6243 def test_session_timeout(self):
6244 """ NAT44 session timeouts """
6245 self.nat44_add_address(self.nat_addr)
6246 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
6247 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
6249 self.vapi.nat_set_timeouts(icmp=5)
6253 for i in range(0, max_sessions):
6254 src = "10.10.%u.%u" % ((i & 0xFF00) >> 8, i & 0xFF)
6255 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
6256 IP(src=src, dst=self.pg1.remote_ip4) /
6257 ICMP(id=1025, type='echo-request'))
6259 self.pg0.add_stream(pkts)
6260 self.pg_enable_capture(self.pg_interfaces)
6262 self.pg1.get_capture(max_sessions)
6267 for i in range(0, max_sessions):
6268 src = "10.11.%u.%u" % ((i & 0xFF00) >> 8, i & 0xFF)
6269 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
6270 IP(src=src, dst=self.pg1.remote_ip4) /
6271 ICMP(id=1026, type='echo-request'))
6273 self.pg0.add_stream(pkts)
6274 self.pg_enable_capture(self.pg_interfaces)
6276 self.pg1.get_capture(max_sessions)
6279 users = self.vapi.nat44_user_dump()
6281 nsessions = nsessions + user.nsessions
6282 self.assertLess(nsessions, 2 * max_sessions)
6284 @unittest.skipUnless(running_extended_tests, "part of extended tests")
6285 def test_session_rst_timeout(self):
6286 """ NAT44 session RST timeouts """
6287 self.nat44_add_address(self.nat_addr)
6288 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
6289 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
6291 self.vapi.nat_set_timeouts(tcp_transitory=5)
6293 self.initiate_tcp_session(self.pg0, self.pg1)
6294 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6295 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6296 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
6298 self.pg0.add_stream(p)
6299 self.pg_enable_capture(self.pg_interfaces)
6301 self.pg1.get_capture(1)
6305 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6306 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6307 TCP(sport=self.tcp_port_in + 1, dport=self.tcp_external_port + 1,
6309 self.pg0.add_stream(p)
6310 self.pg_enable_capture(self.pg_interfaces)
6312 self.pg1.get_capture(1)
6315 users = self.vapi.nat44_user_dump()
6316 self.assertEqual(len(users), 1)
6317 self.assertEqual(users[0].ip_address, self.pg0.remote_ip4n)
6318 self.assertEqual(users[0].nsessions, 1)
6320 @unittest.skipUnless(running_extended_tests, "part of extended tests")
6321 def test_session_limit_per_user(self):
6322 """ Maximum sessions per user limit """
6323 self.nat44_add_address(self.nat_addr)
6324 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
6325 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
6327 self.vapi.set_ipfix_exporter(collector_address=self.pg2.remote_ip4n,
6328 src_address=self.pg2.local_ip4n,
6330 template_interval=10)
6331 self.vapi.nat_set_timeouts(udp=5)
6333 # get maximum number of translations per user
6334 nat44_config = self.vapi.nat_show_config()
6337 for port in range(0, nat44_config.max_translations_per_user):
6338 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6339 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6340 UDP(sport=1025 + port, dport=1025 + port))
6343 self.pg0.add_stream(pkts)
6344 self.pg_enable_capture(self.pg_interfaces)
6346 capture = self.pg1.get_capture(len(pkts))
6348 self.vapi.nat_ipfix_enable_disable(domain_id=self.ipfix_domain_id,
6349 src_port=self.ipfix_src_port)
6351 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6352 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6353 UDP(sport=3001, dport=3002))
6354 self.pg0.add_stream(p)
6355 self.pg_enable_capture(self.pg_interfaces)
6357 capture = self.pg1.assert_nothing_captured()
6359 # verify IPFIX logging
6360 self.vapi.cli("ipfix flush") # FIXME this should be an API call
6362 capture = self.pg2.get_capture(10)
6363 ipfix = IPFIXDecoder()
6364 # first load template
6366 self.assertTrue(p.haslayer(IPFIX))
6367 if p.haslayer(Template):
6368 ipfix.add_template(p.getlayer(Template))
6369 # verify events in data set
6371 if p.haslayer(Data):
6372 data = ipfix.decode_data_set(p.getlayer(Set))
6373 self.verify_ipfix_max_entries_per_user(
6375 nat44_config.max_translations_per_user,
6376 self.pg0.remote_ip4n)
6379 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6380 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6381 UDP(sport=3001, dport=3002))
6382 self.pg0.add_stream(p)
6383 self.pg_enable_capture(self.pg_interfaces)
6385 self.pg1.get_capture(1)
6387 def test_syslog_sess(self):
6388 """ Test syslog session creation and deletion """
6389 self.vapi.syslog_set_filter(SYSLOG_SEVERITY.INFO)
6390 self.vapi.syslog_set_sender(self.pg2.local_ip4n, self.pg2.remote_ip4n)
6391 self.nat44_add_address(self.nat_addr)
6392 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
6393 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
6396 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
6397 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6398 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port))
6399 self.pg0.add_stream(p)
6400 self.pg_enable_capture(self.pg_interfaces)
6402 capture = self.pg1.get_capture(1)
6403 self.tcp_port_out = capture[0][TCP].sport
6404 capture = self.pg2.get_capture(1)
6405 self.verify_syslog_sess(capture[0][Raw].load)
6407 self.pg_enable_capture(self.pg_interfaces)
6409 self.nat44_add_address(self.nat_addr, is_add=0)
6410 capture = self.pg2.get_capture(1)
6411 self.verify_syslog_sess(capture[0][Raw].load, False)
6414 super(TestNAT44EndpointDependent, self).tearDown()
6415 if not self.vpp_dead:
6416 self.logger.info(self.vapi.cli("show nat44 addresses"))
6417 self.logger.info(self.vapi.cli("show nat44 interfaces"))
6418 self.logger.info(self.vapi.cli("show nat44 static mappings"))
6419 self.logger.info(self.vapi.cli("show nat44 interface address"))
6420 self.logger.info(self.vapi.cli("show nat44 sessions detail"))
6421 self.logger.info(self.vapi.cli("show nat44 hash tables detail"))
6422 self.logger.info(self.vapi.cli("show nat timeouts"))
6424 self.vapi.cli("clear logging")
6427 class TestNAT44Out2InDPO(MethodHolder):
6428 """ NAT44 Test Cases using out2in DPO """
6431 def setUpConstants(cls):
6432 super(TestNAT44Out2InDPO, cls).setUpConstants()
6433 cls.vpp_cmdline.extend(["nat", "{", "out2in dpo", "}"])
6436 def setUpClass(cls):
6437 super(TestNAT44Out2InDPO, cls).setUpClass()
6438 cls.vapi.cli("set log class nat level debug")
6441 cls.tcp_port_in = 6303
6442 cls.tcp_port_out = 6303
6443 cls.udp_port_in = 6304
6444 cls.udp_port_out = 6304
6445 cls.icmp_id_in = 6305
6446 cls.icmp_id_out = 6305
6447 cls.nat_addr = '10.0.0.3'
6448 cls.nat_addr_n = socket.inet_pton(socket.AF_INET, cls.nat_addr)
6449 cls.dst_ip4 = '192.168.70.1'
6451 cls.create_pg_interfaces(range(2))
6454 cls.pg0.config_ip4()
6455 cls.pg0.resolve_arp()
6458 cls.pg1.config_ip6()
6459 cls.pg1.resolve_ndp()
6461 cls.vapi.ip_add_del_route(is_ipv6=True, dst_address='\x00' * 16,
6462 dst_address_length=0,
6463 next_hop_address=cls.pg1.remote_ip6n,
6464 next_hop_sw_if_index=cls.pg1.sw_if_index)
6467 super(TestNAT44Out2InDPO, cls).tearDownClass()
6470 def configure_xlat(self):
6471 self.dst_ip6_pfx = '1:2:3::'
6472 self.dst_ip6_pfx_n = socket.inet_pton(socket.AF_INET6,
6474 self.dst_ip6_pfx_len = 96
6475 self.src_ip6_pfx = '4:5:6::'
6476 self.src_ip6_pfx_n = socket.inet_pton(socket.AF_INET6,
6478 self.src_ip6_pfx_len = 96
6479 self.vapi.map_add_domain(self.dst_ip6_pfx_n, self.dst_ip6_pfx_len,
6480 self.src_ip6_pfx_n, self.src_ip6_pfx_len,
6481 '\x00\x00\x00\x00', 0)
6483 @unittest.skip('Temporary disabled')
6484 def test_464xlat_ce(self):
6485 """ Test 464XLAT CE with NAT44 """
6487 nat_config = self.vapi.nat_show_config()
6488 self.assertEqual(1, nat_config.out2in_dpo)
6490 self.configure_xlat()
6492 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
6493 self.vapi.nat44_add_del_address_range(self.nat_addr_n, self.nat_addr_n)
6495 out_src_ip6 = self.compose_ip6(self.dst_ip4, self.dst_ip6_pfx,
6496 self.dst_ip6_pfx_len)
6497 out_dst_ip6 = self.compose_ip6(self.nat_addr, self.src_ip6_pfx,
6498 self.src_ip6_pfx_len)
6501 pkts = self.create_stream_in(self.pg0, self.pg1, self.dst_ip4)
6502 self.pg0.add_stream(pkts)
6503 self.pg_enable_capture(self.pg_interfaces)
6505 capture = self.pg1.get_capture(len(pkts))
6506 self.verify_capture_out_ip6(capture, nat_ip=out_dst_ip6,
6509 pkts = self.create_stream_out_ip6(self.pg1, out_src_ip6,
6511 self.pg1.add_stream(pkts)
6512 self.pg_enable_capture(self.pg_interfaces)
6514 capture = self.pg0.get_capture(len(pkts))
6515 self.verify_capture_in(capture, self.pg0)
6517 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index,
6519 self.vapi.nat44_add_del_address_range(self.nat_addr_n,
6520 self.nat_addr_n, is_add=0)
6522 @unittest.skip('Temporary disabled')
6523 def test_464xlat_ce_no_nat(self):
6524 """ Test 464XLAT CE without NAT44 """
6526 self.configure_xlat()
6528 out_src_ip6 = self.compose_ip6(self.dst_ip4, self.dst_ip6_pfx,
6529 self.dst_ip6_pfx_len)
6530 out_dst_ip6 = self.compose_ip6(self.pg0.remote_ip4, self.src_ip6_pfx,
6531 self.src_ip6_pfx_len)
6533 pkts = self.create_stream_in(self.pg0, self.pg1, self.dst_ip4)
6534 self.pg0.add_stream(pkts)
6535 self.pg_enable_capture(self.pg_interfaces)
6537 capture = self.pg1.get_capture(len(pkts))
6538 self.verify_capture_out_ip6(capture, dst_ip=out_src_ip6,
6539 nat_ip=out_dst_ip6, same_port=True)
6541 pkts = self.create_stream_out_ip6(self.pg1, out_src_ip6, out_dst_ip6)
6542 self.pg1.add_stream(pkts)
6543 self.pg_enable_capture(self.pg_interfaces)
6545 capture = self.pg0.get_capture(len(pkts))
6546 self.verify_capture_in(capture, self.pg0)
6549 class TestDeterministicNAT(MethodHolder):
6550 """ Deterministic NAT Test Cases """
6553 def setUpConstants(cls):
6554 super(TestDeterministicNAT, cls).setUpConstants()
6555 cls.vpp_cmdline.extend(["nat", "{", "deterministic", "}"])
6558 def setUpClass(cls):
6559 super(TestDeterministicNAT, cls).setUpClass()
6560 cls.vapi.cli("set log class nat level debug")
6563 cls.tcp_port_in = 6303
6564 cls.tcp_external_port = 6303
6565 cls.udp_port_in = 6304
6566 cls.udp_external_port = 6304
6567 cls.icmp_id_in = 6305
6568 cls.nat_addr = '10.0.0.3'
6570 cls.create_pg_interfaces(range(3))
6571 cls.interfaces = list(cls.pg_interfaces)
6573 for i in cls.interfaces:
6578 cls.pg0.generate_remote_hosts(2)
6579 cls.pg0.configure_ipv4_neighbors()
6582 super(TestDeterministicNAT, cls).tearDownClass()
6585 def create_stream_in(self, in_if, out_if, ttl=64):
6587 Create packet stream for inside network
6589 :param in_if: Inside interface
6590 :param out_if: Outside interface
6591 :param ttl: TTL of generated packets
6595 p = (Ether(dst=in_if.local_mac, src=in_if.remote_mac) /
6596 IP(src=in_if.remote_ip4, dst=out_if.remote_ip4, ttl=ttl) /
6597 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port))
6601 p = (Ether(dst=in_if.local_mac, src=in_if.remote_mac) /
6602 IP(src=in_if.remote_ip4, dst=out_if.remote_ip4, ttl=ttl) /
6603 UDP(sport=self.udp_port_in, dport=self.udp_external_port))
6607 p = (Ether(dst=in_if.local_mac, src=in_if.remote_mac) /
6608 IP(src=in_if.remote_ip4, dst=out_if.remote_ip4, ttl=ttl) /
6609 ICMP(id=self.icmp_id_in, type='echo-request'))
6614 def create_stream_out(self, out_if, dst_ip=None, ttl=64):
6616 Create packet stream for outside network
6618 :param out_if: Outside interface
6619 :param dst_ip: Destination IP address (Default use global NAT address)
6620 :param ttl: TTL of generated packets
6623 dst_ip = self.nat_addr
6626 p = (Ether(dst=out_if.local_mac, src=out_if.remote_mac) /
6627 IP(src=out_if.remote_ip4, dst=dst_ip, ttl=ttl) /
6628 TCP(dport=self.tcp_port_out, sport=self.tcp_external_port))
6632 p = (Ether(dst=out_if.local_mac, src=out_if.remote_mac) /
6633 IP(src=out_if.remote_ip4, dst=dst_ip, ttl=ttl) /
6634 UDP(dport=self.udp_port_out, sport=self.udp_external_port))
6638 p = (Ether(dst=out_if.local_mac, src=out_if.remote_mac) /
6639 IP(src=out_if.remote_ip4, dst=dst_ip, ttl=ttl) /
6640 ICMP(id=self.icmp_external_id, type='echo-reply'))
6645 def verify_capture_out(self, capture, nat_ip=None):
6647 Verify captured packets on outside network
6649 :param capture: Captured packets
6650 :param nat_ip: Translated IP address (Default use global NAT address)
6651 :param same_port: Sorce port number is not translated (Default False)
6654 nat_ip = self.nat_addr
6655 for packet in capture:
6657 self.assertEqual(packet[IP].src, nat_ip)
6658 if packet.haslayer(TCP):
6659 self.tcp_port_out = packet[TCP].sport
6660 elif packet.haslayer(UDP):
6661 self.udp_port_out = packet[UDP].sport
6663 self.icmp_external_id = packet[ICMP].id
6665 self.logger.error(ppp("Unexpected or invalid packet "
6666 "(outside network):", packet))
6669 def test_deterministic_mode(self):
6670 """ NAT plugin run deterministic mode """
6671 in_addr = '172.16.255.0'
6672 out_addr = '172.17.255.50'
6673 in_addr_t = '172.16.255.20'
6674 in_addr_n = socket.inet_aton(in_addr)
6675 out_addr_n = socket.inet_aton(out_addr)
6676 in_addr_t_n = socket.inet_aton(in_addr_t)
6680 nat_config = self.vapi.nat_show_config()
6681 self.assertEqual(1, nat_config.deterministic)
6683 self.vapi.nat_det_add_del_map(in_addr_n, in_plen, out_addr_n, out_plen)
6685 rep1 = self.vapi.nat_det_forward(in_addr_t_n)
6686 self.assertEqual(rep1.out_addr[:4], out_addr_n)
6687 rep2 = self.vapi.nat_det_reverse(out_addr_n, rep1.out_port_hi)
6688 self.assertEqual(rep2.in_addr[:4], in_addr_t_n)
6690 deterministic_mappings = self.vapi.nat_det_map_dump()
6691 self.assertEqual(len(deterministic_mappings), 1)
6692 dsm = deterministic_mappings[0]
6693 self.assertEqual(in_addr_n, dsm.in_addr[:4])
6694 self.assertEqual(in_plen, dsm.in_plen)
6695 self.assertEqual(out_addr_n, dsm.out_addr[:4])
6696 self.assertEqual(out_plen, dsm.out_plen)
6698 self.clear_nat_det()
6699 deterministic_mappings = self.vapi.nat_det_map_dump()
6700 self.assertEqual(len(deterministic_mappings), 0)
6702 def test_set_timeouts(self):
6703 """ Set deterministic NAT timeouts """
6704 timeouts_before = self.vapi.nat_get_timeouts()
6706 self.vapi.nat_set_timeouts(timeouts_before.udp + 10,
6707 timeouts_before.tcp_established + 10,
6708 timeouts_before.tcp_transitory + 10,
6709 timeouts_before.icmp + 10)
6711 timeouts_after = self.vapi.nat_get_timeouts()
6713 self.assertNotEqual(timeouts_before.udp, timeouts_after.udp)
6714 self.assertNotEqual(timeouts_before.icmp, timeouts_after.icmp)
6715 self.assertNotEqual(timeouts_before.tcp_established,
6716 timeouts_after.tcp_established)
6717 self.assertNotEqual(timeouts_before.tcp_transitory,
6718 timeouts_after.tcp_transitory)
6720 def test_det_in(self):
6721 """ Deterministic NAT translation test (TCP, UDP, ICMP) """
6723 nat_ip = "10.0.0.10"
6725 self.vapi.nat_det_add_del_map(self.pg0.remote_ip4n,
6727 socket.inet_aton(nat_ip),
6729 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
6730 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
6734 pkts = self.create_stream_in(self.pg0, self.pg1)
6735 self.pg0.add_stream(pkts)
6736 self.pg_enable_capture(self.pg_interfaces)
6738 capture = self.pg1.get_capture(len(pkts))
6739 self.verify_capture_out(capture, nat_ip)
6742 pkts = self.create_stream_out(self.pg1, nat_ip)
6743 self.pg1.add_stream(pkts)
6744 self.pg_enable_capture(self.pg_interfaces)
6746 capture = self.pg0.get_capture(len(pkts))
6747 self.verify_capture_in(capture, self.pg0)
6750 sessions = self.vapi.nat_det_session_dump(self.pg0.remote_ip4n)
6751 self.assertEqual(len(sessions), 3)
6755 self.assertEqual(s.ext_addr[:4], self.pg1.remote_ip4n)
6756 self.assertEqual(s.in_port, self.tcp_port_in)
6757 self.assertEqual(s.out_port, self.tcp_port_out)
6758 self.assertEqual(s.ext_port, self.tcp_external_port)
6762 self.assertEqual(s.ext_addr[:4], self.pg1.remote_ip4n)
6763 self.assertEqual(s.in_port, self.udp_port_in)
6764 self.assertEqual(s.out_port, self.udp_port_out)
6765 self.assertEqual(s.ext_port, self.udp_external_port)
6769 self.assertEqual(s.ext_addr[:4], self.pg1.remote_ip4n)
6770 self.assertEqual(s.in_port, self.icmp_id_in)
6771 self.assertEqual(s.out_port, self.icmp_external_id)
6773 def test_multiple_users(self):
6774 """ Deterministic NAT multiple users """
6776 nat_ip = "10.0.0.10"
6778 external_port = 6303
6780 host0 = self.pg0.remote_hosts[0]
6781 host1 = self.pg0.remote_hosts[1]
6783 self.vapi.nat_det_add_del_map(host0.ip4n,
6785 socket.inet_aton(nat_ip),
6787 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
6788 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
6792 p = (Ether(src=host0.mac, dst=self.pg0.local_mac) /
6793 IP(src=host0.ip4, dst=self.pg1.remote_ip4) /
6794 TCP(sport=port_in, dport=external_port))
6795 self.pg0.add_stream(p)
6796 self.pg_enable_capture(self.pg_interfaces)
6798 capture = self.pg1.get_capture(1)
6803 self.assertEqual(ip.src, nat_ip)
6804 self.assertEqual(ip.dst, self.pg1.remote_ip4)
6805 self.assertEqual(tcp.dport, external_port)
6806 port_out0 = tcp.sport
6808 self.logger.error(ppp("Unexpected or invalid packet:", p))
6812 p = (Ether(src=host1.mac, dst=self.pg0.local_mac) /
6813 IP(src=host1.ip4, dst=self.pg1.remote_ip4) /
6814 TCP(sport=port_in, dport=external_port))
6815 self.pg0.add_stream(p)
6816 self.pg_enable_capture(self.pg_interfaces)
6818 capture = self.pg1.get_capture(1)
6823 self.assertEqual(ip.src, nat_ip)
6824 self.assertEqual(ip.dst, self.pg1.remote_ip4)
6825 self.assertEqual(tcp.dport, external_port)
6826 port_out1 = tcp.sport
6828 self.logger.error(ppp("Unexpected or invalid packet:", p))
6831 dms = self.vapi.nat_det_map_dump()
6832 self.assertEqual(1, len(dms))
6833 self.assertEqual(2, dms[0].ses_num)
6836 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
6837 IP(src=self.pg1.remote_ip4, dst=nat_ip) /
6838 TCP(sport=external_port, dport=port_out0))
6839 self.pg1.add_stream(p)
6840 self.pg_enable_capture(self.pg_interfaces)
6842 capture = self.pg0.get_capture(1)
6847 self.assertEqual(ip.src, self.pg1.remote_ip4)
6848 self.assertEqual(ip.dst, host0.ip4)
6849 self.assertEqual(tcp.dport, port_in)
6850 self.assertEqual(tcp.sport, external_port)
6852 self.logger.error(ppp("Unexpected or invalid packet:", p))
6856 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
6857 IP(src=self.pg1.remote_ip4, dst=nat_ip) /
6858 TCP(sport=external_port, dport=port_out1))
6859 self.pg1.add_stream(p)
6860 self.pg_enable_capture(self.pg_interfaces)
6862 capture = self.pg0.get_capture(1)
6867 self.assertEqual(ip.src, self.pg1.remote_ip4)
6868 self.assertEqual(ip.dst, host1.ip4)
6869 self.assertEqual(tcp.dport, port_in)
6870 self.assertEqual(tcp.sport, external_port)
6872 self.logger.error(ppp("Unexpected or invalid packet", p))
6875 # session close api test
6876 self.vapi.nat_det_close_session_out(socket.inet_aton(nat_ip),
6878 self.pg1.remote_ip4n,
6880 dms = self.vapi.nat_det_map_dump()
6881 self.assertEqual(dms[0].ses_num, 1)
6883 self.vapi.nat_det_close_session_in(host0.ip4n,
6885 self.pg1.remote_ip4n,
6887 dms = self.vapi.nat_det_map_dump()
6888 self.assertEqual(dms[0].ses_num, 0)
6890 def test_tcp_session_close_detection_in(self):
6891 """ Deterministic NAT TCP session close from inside network """
6892 self.vapi.nat_det_add_del_map(self.pg0.remote_ip4n,
6894 socket.inet_aton(self.nat_addr),
6896 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
6897 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
6900 self.initiate_tcp_session(self.pg0, self.pg1)
6902 # close the session from inside
6904 # FIN packet in -> out
6905 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6906 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6907 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
6909 self.pg0.add_stream(p)
6910 self.pg_enable_capture(self.pg_interfaces)
6912 self.pg1.get_capture(1)
6916 # ACK packet out -> in
6917 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
6918 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
6919 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
6923 # FIN packet out -> in
6924 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
6925 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
6926 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
6930 self.pg1.add_stream(pkts)
6931 self.pg_enable_capture(self.pg_interfaces)
6933 self.pg0.get_capture(2)
6935 # ACK packet in -> out
6936 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6937 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6938 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
6940 self.pg0.add_stream(p)
6941 self.pg_enable_capture(self.pg_interfaces)
6943 self.pg1.get_capture(1)
6945 # Check if deterministic NAT44 closed the session
6946 dms = self.vapi.nat_det_map_dump()
6947 self.assertEqual(0, dms[0].ses_num)
6949 self.logger.error("TCP session termination failed")
6952 def test_tcp_session_close_detection_out(self):
6953 """ Deterministic NAT TCP session close from outside network """
6954 self.vapi.nat_det_add_del_map(self.pg0.remote_ip4n,
6956 socket.inet_aton(self.nat_addr),
6958 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
6959 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
6962 self.initiate_tcp_session(self.pg0, self.pg1)
6964 # close the session from outside
6966 # FIN packet out -> in
6967 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
6968 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
6969 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
6971 self.pg1.add_stream(p)
6972 self.pg_enable_capture(self.pg_interfaces)
6974 self.pg0.get_capture(1)
6978 # ACK packet in -> out
6979 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6980 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6981 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
6985 # ACK packet in -> out
6986 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6987 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6988 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
6992 self.pg0.add_stream(pkts)
6993 self.pg_enable_capture(self.pg_interfaces)
6995 self.pg1.get_capture(2)
6997 # ACK packet out -> in
6998 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
6999 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
7000 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
7002 self.pg1.add_stream(p)
7003 self.pg_enable_capture(self.pg_interfaces)
7005 self.pg0.get_capture(1)
7007 # Check if deterministic NAT44 closed the session
7008 dms = self.vapi.nat_det_map_dump()
7009 self.assertEqual(0, dms[0].ses_num)
7011 self.logger.error("TCP session termination failed")
7014 @unittest.skipUnless(running_extended_tests, "part of extended tests")
7015 def test_session_timeout(self):
7016 """ Deterministic NAT session timeouts """
7017 self.vapi.nat_det_add_del_map(self.pg0.remote_ip4n,
7019 socket.inet_aton(self.nat_addr),
7021 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
7022 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
7025 self.initiate_tcp_session(self.pg0, self.pg1)
7026 self.vapi.nat_set_timeouts(5, 5, 5, 5)
7027 pkts = self.create_stream_in(self.pg0, self.pg1)
7028 self.pg0.add_stream(pkts)
7029 self.pg_enable_capture(self.pg_interfaces)
7031 capture = self.pg1.get_capture(len(pkts))
7034 dms = self.vapi.nat_det_map_dump()
7035 self.assertEqual(0, dms[0].ses_num)
7037 @unittest.skipUnless(running_extended_tests, "part of extended tests")
7038 def test_session_limit_per_user(self):
7039 """ Deterministic NAT maximum sessions per user limit """
7040 self.vapi.nat_det_add_del_map(self.pg0.remote_ip4n,
7042 socket.inet_aton(self.nat_addr),
7044 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
7045 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
7047 self.vapi.set_ipfix_exporter(collector_address=self.pg2.remote_ip4n,
7048 src_address=self.pg2.local_ip4n,
7050 template_interval=10)
7051 self.vapi.nat_ipfix_enable_disable()
7054 for port in range(1025, 2025):
7055 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
7056 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
7057 UDP(sport=port, dport=port))
7060 self.pg0.add_stream(pkts)
7061 self.pg_enable_capture(self.pg_interfaces)
7063 capture = self.pg1.get_capture(len(pkts))
7065 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
7066 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
7067 UDP(sport=3001, dport=3002))
7068 self.pg0.add_stream(p)
7069 self.pg_enable_capture(self.pg_interfaces)
7071 capture = self.pg1.assert_nothing_captured()
7073 # verify ICMP error packet
7074 capture = self.pg0.get_capture(1)
7076 self.assertTrue(p.haslayer(ICMP))
7078 self.assertEqual(icmp.type, 3)
7079 self.assertEqual(icmp.code, 1)
7080 self.assertTrue(icmp.haslayer(IPerror))
7081 inner_ip = icmp[IPerror]
7082 self.assertEqual(inner_ip[UDPerror].sport, 3001)
7083 self.assertEqual(inner_ip[UDPerror].dport, 3002)
7085 dms = self.vapi.nat_det_map_dump()
7087 self.assertEqual(1000, dms[0].ses_num)
7089 # verify IPFIX logging
7090 self.vapi.cli("ipfix flush") # FIXME this should be an API call
7092 capture = self.pg2.get_capture(2)
7093 ipfix = IPFIXDecoder()
7094 # first load template
7096 self.assertTrue(p.haslayer(IPFIX))
7097 if p.haslayer(Template):
7098 ipfix.add_template(p.getlayer(Template))
7099 # verify events in data set
7101 if p.haslayer(Data):
7102 data = ipfix.decode_data_set(p.getlayer(Set))
7103 self.verify_ipfix_max_entries_per_user(data,
7105 self.pg0.remote_ip4n)
7107 def clear_nat_det(self):
7109 Clear deterministic NAT configuration.
7111 self.vapi.nat_ipfix_enable_disable(enable=0)
7112 self.vapi.nat_set_timeouts()
7113 deterministic_mappings = self.vapi.nat_det_map_dump()
7114 for dsm in deterministic_mappings:
7115 self.vapi.nat_det_add_del_map(dsm.in_addr,
7121 interfaces = self.vapi.nat44_interface_dump()
7122 for intf in interfaces:
7123 self.vapi.nat44_interface_add_del_feature(intf.sw_if_index,
7128 super(TestDeterministicNAT, self).tearDown()
7129 if not self.vpp_dead:
7130 self.logger.info(self.vapi.cli("show nat44 interfaces"))
7131 self.logger.info(self.vapi.cli("show nat timeouts"))
7133 self.vapi.cli("show nat44 deterministic mappings"))
7135 self.vapi.cli("show nat44 deterministic sessions"))
7136 self.clear_nat_det()
7139 class TestNAT64(MethodHolder):
7140 """ NAT64 Test Cases """
7143 def setUpConstants(cls):
7144 super(TestNAT64, cls).setUpConstants()
7145 cls.vpp_cmdline.extend(["nat", "{", "nat64 bib hash buckets 128",
7146 "nat64 st hash buckets 256", "}"])
7149 def setUpClass(cls):
7150 super(TestNAT64, cls).setUpClass()
7153 cls.tcp_port_in = 6303
7154 cls.tcp_port_out = 6303
7155 cls.udp_port_in = 6304
7156 cls.udp_port_out = 6304
7157 cls.icmp_id_in = 6305
7158 cls.icmp_id_out = 6305
7159 cls.tcp_external_port = 80
7160 cls.nat_addr = '10.0.0.3'
7161 cls.nat_addr_n = socket.inet_pton(socket.AF_INET, cls.nat_addr)
7163 cls.vrf1_nat_addr = '10.0.10.3'
7164 cls.vrf1_nat_addr_n = socket.inet_pton(socket.AF_INET,
7166 cls.ipfix_src_port = 4739
7167 cls.ipfix_domain_id = 1
7169 cls.create_pg_interfaces(range(6))
7170 cls.ip6_interfaces = list(cls.pg_interfaces[0:1])
7171 cls.ip6_interfaces.append(cls.pg_interfaces[2])
7172 cls.ip4_interfaces = list(cls.pg_interfaces[1:2])
7174 cls.vapi.ip_table_add_del(is_ipv6=1, is_add=1,
7175 table_id=cls.vrf1_id)
7177 cls.pg_interfaces[2].set_table_ip6(cls.vrf1_id)
7179 cls.pg0.generate_remote_hosts(2)
7181 for i in cls.ip6_interfaces:
7184 i.configure_ipv6_neighbors()
7186 for i in cls.ip4_interfaces:
7192 cls.pg3.config_ip4()
7193 cls.pg3.resolve_arp()
7194 cls.pg3.config_ip6()
7195 cls.pg3.configure_ipv6_neighbors()
7198 cls.pg5.config_ip6()
7201 super(TestNAT64, cls).tearDownClass()
7204 def test_nat64_inside_interface_handles_neighbor_advertisement(self):
7205 """ NAT64 inside interface handles Neighbor Advertisement """
7207 self.vapi.nat64_add_del_interface(self.pg5.sw_if_index)
7210 ping = (Ether(dst=self.pg5.local_mac, src=self.pg5.remote_mac) /
7211 IPv6(src=self.pg5.remote_ip6, dst=self.pg5.local_ip6) /
7212 ICMPv6EchoRequest())
7214 self.pg5.add_stream(pkts)
7215 self.pg_enable_capture(self.pg_interfaces)
7218 # Wait for Neighbor Solicitation
7219 capture = self.pg5.get_capture(len(pkts))
7222 self.assertEqual(packet[IPv6].src, self.pg5.local_ip6)
7223 self.assertEqual(packet.haslayer(ICMPv6ND_NS), 1)
7224 tgt = packet[ICMPv6ND_NS].tgt
7226 self.logger.error(ppp("Unexpected or invalid packet:", packet))
7229 # Send Neighbor Advertisement
7230 p = (Ether(dst=self.pg5.local_mac, src=self.pg5.remote_mac) /
7231 IPv6(src=self.pg5.remote_ip6, dst=self.pg5.local_ip6) /
7232 ICMPv6ND_NA(tgt=tgt) /
7233 ICMPv6NDOptDstLLAddr(lladdr=self.pg5.remote_mac))
7235 self.pg5.add_stream(pkts)
7236 self.pg_enable_capture(self.pg_interfaces)
7239 # Try to send ping again
7241 self.pg5.add_stream(pkts)
7242 self.pg_enable_capture(self.pg_interfaces)
7245 # Wait for ping reply
7246 capture = self.pg5.get_capture(len(pkts))
7249 self.assertEqual(packet[IPv6].src, self.pg5.local_ip6)
7250 self.assertEqual(packet[IPv6].dst, self.pg5.remote_ip6)
7251 self.assertEqual(packet.haslayer(ICMPv6EchoReply), 1)
7253 self.logger.error(ppp("Unexpected or invalid packet:", packet))
7256 def test_pool(self):
7257 """ Add/delete address to NAT64 pool """
7258 nat_addr = socket.inet_pton(socket.AF_INET, '1.2.3.4')
7260 self.vapi.nat64_add_del_pool_addr_range(nat_addr, nat_addr)
7262 addresses = self.vapi.nat64_pool_addr_dump()
7263 self.assertEqual(len(addresses), 1)
7264 self.assertEqual(addresses[0].address, nat_addr)
7266 self.vapi.nat64_add_del_pool_addr_range(nat_addr, nat_addr, is_add=0)
7268 addresses = self.vapi.nat64_pool_addr_dump()
7269 self.assertEqual(len(addresses), 0)
7271 def test_interface(self):
7272 """ Enable/disable NAT64 feature on the interface """
7273 self.vapi.nat64_add_del_interface(self.pg0.sw_if_index)
7274 self.vapi.nat64_add_del_interface(self.pg1.sw_if_index, is_inside=0)
7276 interfaces = self.vapi.nat64_interface_dump()
7277 self.assertEqual(len(interfaces), 2)
7280 for intf in interfaces:
7281 if intf.sw_if_index == self.pg0.sw_if_index:
7282 self.assertEqual(intf.is_inside, 1)
7284 elif intf.sw_if_index == self.pg1.sw_if_index:
7285 self.assertEqual(intf.is_inside, 0)
7287 self.assertTrue(pg0_found)
7288 self.assertTrue(pg1_found)
7290 features = self.vapi.cli("show interface features pg0")
7291 self.assertIn('nat64-in2out', features)
7292 features = self.vapi.cli("show interface features pg1")
7293 self.assertIn('nat64-out2in', features)
7295 self.vapi.nat64_add_del_interface(self.pg0.sw_if_index, is_add=0)
7296 self.vapi.nat64_add_del_interface(self.pg1.sw_if_index, is_add=0)
7298 interfaces = self.vapi.nat64_interface_dump()
7299 self.assertEqual(len(interfaces), 0)
7301 def test_static_bib(self):
7302 """ Add/delete static BIB entry """
7303 in_addr = socket.inet_pton(socket.AF_INET6,
7304 '2001:db8:85a3::8a2e:370:7334')
7305 out_addr = socket.inet_pton(socket.AF_INET, '10.1.1.3')
7308 proto = IP_PROTOS.tcp
7310 self.vapi.nat64_add_del_static_bib(in_addr,
7315 bib = self.vapi.nat64_bib_dump(IP_PROTOS.tcp)
7320 self.assertEqual(bibe.i_addr, in_addr)
7321 self.assertEqual(bibe.o_addr, out_addr)
7322 self.assertEqual(bibe.i_port, in_port)
7323 self.assertEqual(bibe.o_port, out_port)
7324 self.assertEqual(static_bib_num, 1)
7325 bibs = self.statistics.get_counter('/nat64/total-bibs')
7326 self.assertEqual(bibs[0][0], 1)
7328 self.vapi.nat64_add_del_static_bib(in_addr,
7334 bib = self.vapi.nat64_bib_dump(IP_PROTOS.tcp)
7339 self.assertEqual(static_bib_num, 0)
7340 bibs = self.statistics.get_counter('/nat64/total-bibs')
7341 self.assertEqual(bibs[0][0], 0)
7343 def test_set_timeouts(self):
7344 """ Set NAT64 timeouts """
7345 # verify default values
7346 timeouts = self.vapi.nat_get_timeouts()
7347 self.assertEqual(timeouts.udp, 300)
7348 self.assertEqual(timeouts.icmp, 60)
7349 self.assertEqual(timeouts.tcp_transitory, 240)
7350 self.assertEqual(timeouts.tcp_established, 7440)
7352 # set and verify custom values
7353 self.vapi.nat_set_timeouts(udp=200, icmp=30, tcp_transitory=250,
7354 tcp_established=7450)
7355 timeouts = self.vapi.nat_get_timeouts()
7356 self.assertEqual(timeouts.udp, 200)
7357 self.assertEqual(timeouts.icmp, 30)
7358 self.assertEqual(timeouts.tcp_transitory, 250)
7359 self.assertEqual(timeouts.tcp_established, 7450)
7361 def test_dynamic(self):
7362 """ NAT64 dynamic translation test """
7363 self.tcp_port_in = 6303
7364 self.udp_port_in = 6304
7365 self.icmp_id_in = 6305
7367 ses_num_start = self.nat64_get_ses_num()
7369 self.vapi.nat64_add_del_pool_addr_range(self.nat_addr_n,
7371 self.vapi.nat64_add_del_interface(self.pg0.sw_if_index)
7372 self.vapi.nat64_add_del_interface(self.pg1.sw_if_index, is_inside=0)
7375 tcpn = self.statistics.get_counter('/err/nat64-in2out/TCP packets')
7376 udpn = self.statistics.get_counter('/err/nat64-in2out/UDP packets')
7377 icmpn = self.statistics.get_counter('/err/nat64-in2out/ICMP packets')
7378 totaln = self.statistics.get_counter(
7379 '/err/nat64-in2out/good in2out packets processed')
7381 pkts = self.create_stream_in_ip6(self.pg0, self.pg1)
7382 self.pg0.add_stream(pkts)
7383 self.pg_enable_capture(self.pg_interfaces)
7385 capture = self.pg1.get_capture(len(pkts))
7386 self.verify_capture_out(capture, nat_ip=self.nat_addr,
7387 dst_ip=self.pg1.remote_ip4)
7389 err = self.statistics.get_counter('/err/nat64-in2out/TCP packets')
7390 self.assertEqual(err - tcpn, 1)
7391 err = self.statistics.get_counter('/err/nat64-in2out/UDP packets')
7392 self.assertEqual(err - udpn, 1)
7393 err = self.statistics.get_counter('/err/nat64-in2out/ICMP packets')
7394 self.assertEqual(err - icmpn, 1)
7395 err = self.statistics.get_counter(
7396 '/err/nat64-in2out/good in2out packets processed')
7397 self.assertEqual(err - totaln, 3)
7400 tcpn = self.statistics.get_counter('/err/nat64-out2in/TCP packets')
7401 udpn = self.statistics.get_counter('/err/nat64-out2in/UDP packets')
7402 icmpn = self.statistics.get_counter('/err/nat64-out2in/ICMP packets')
7403 totaln = self.statistics.get_counter(
7404 '/err/nat64-out2in/good out2in packets processed')
7406 pkts = self.create_stream_out(self.pg1, dst_ip=self.nat_addr)
7407 self.pg1.add_stream(pkts)
7408 self.pg_enable_capture(self.pg_interfaces)
7410 capture = self.pg0.get_capture(len(pkts))
7411 ip = IPv6(src=''.join(['64:ff9b::', self.pg1.remote_ip4]))
7412 self.verify_capture_in_ip6(capture, ip[IPv6].src, self.pg0.remote_ip6)
7414 err = self.statistics.get_counter('/err/nat64-out2in/TCP packets')
7415 self.assertEqual(err - tcpn, 1)
7416 err = self.statistics.get_counter('/err/nat64-out2in/UDP packets')
7417 self.assertEqual(err - udpn, 1)
7418 err = self.statistics.get_counter('/err/nat64-out2in/ICMP packets')
7419 self.assertEqual(err - icmpn, 1)
7420 err = self.statistics.get_counter(
7421 '/err/nat64-out2in/good out2in packets processed')
7422 self.assertEqual(err - totaln, 3)
7424 bibs = self.statistics.get_counter('/nat64/total-bibs')
7425 self.assertEqual(bibs[0][0], 3)
7426 sessions = self.statistics.get_counter('/nat64/total-sessions')
7427 self.assertEqual(sessions[0][0], 3)
7430 pkts = self.create_stream_in_ip6(self.pg0, self.pg1)
7431 self.pg0.add_stream(pkts)
7432 self.pg_enable_capture(self.pg_interfaces)
7434 capture = self.pg1.get_capture(len(pkts))
7435 self.verify_capture_out(capture, nat_ip=self.nat_addr,
7436 dst_ip=self.pg1.remote_ip4)
7439 pkts = self.create_stream_out(self.pg1, dst_ip=self.nat_addr)
7440 self.pg1.add_stream(pkts)
7441 self.pg_enable_capture(self.pg_interfaces)
7443 capture = self.pg0.get_capture(len(pkts))
7444 self.verify_capture_in_ip6(capture, ip[IPv6].src, self.pg0.remote_ip6)
7446 ses_num_end = self.nat64_get_ses_num()
7448 self.assertEqual(ses_num_end - ses_num_start, 3)
7450 # tenant with specific VRF
7451 self.vapi.nat64_add_del_pool_addr_range(self.vrf1_nat_addr_n,
7452 self.vrf1_nat_addr_n,
7453 vrf_id=self.vrf1_id)
7454 self.vapi.nat64_add_del_interface(self.pg2.sw_if_index)
7456 pkts = self.create_stream_in_ip6(self.pg2, self.pg1)
7457 self.pg2.add_stream(pkts)
7458 self.pg_enable_capture(self.pg_interfaces)
7460 capture = self.pg1.get_capture(len(pkts))
7461 self.verify_capture_out(capture, nat_ip=self.vrf1_nat_addr,
7462 dst_ip=self.pg1.remote_ip4)
7464 pkts = self.create_stream_out(self.pg1, dst_ip=self.vrf1_nat_addr)
7465 self.pg1.add_stream(pkts)
7466 self.pg_enable_capture(self.pg_interfaces)
7468 capture = self.pg2.get_capture(len(pkts))
7469 self.verify_capture_in_ip6(capture, ip[IPv6].src, self.pg2.remote_ip6)
7471 def test_static(self):
7472 """ NAT64 static translation test """
7473 self.tcp_port_in = 60303
7474 self.udp_port_in = 60304
7475 self.icmp_id_in = 60305
7476 self.tcp_port_out = 60303
7477 self.udp_port_out = 60304
7478 self.icmp_id_out = 60305
7480 ses_num_start = self.nat64_get_ses_num()
7482 self.vapi.nat64_add_del_pool_addr_range(self.nat_addr_n,
7484 self.vapi.nat64_add_del_interface(self.pg0.sw_if_index)
7485 self.vapi.nat64_add_del_interface(self.pg1.sw_if_index, is_inside=0)
7487 self.vapi.nat64_add_del_static_bib(self.pg0.remote_ip6n,
7492 self.vapi.nat64_add_del_static_bib(self.pg0.remote_ip6n,
7497 self.vapi.nat64_add_del_static_bib(self.pg0.remote_ip6n,
7504 pkts = self.create_stream_in_ip6(self.pg0, self.pg1)
7505 self.pg0.add_stream(pkts)
7506 self.pg_enable_capture(self.pg_interfaces)
7508 capture = self.pg1.get_capture(len(pkts))
7509 self.verify_capture_out(capture, nat_ip=self.nat_addr,
7510 dst_ip=self.pg1.remote_ip4, same_port=True)
7513 pkts = self.create_stream_out(self.pg1, dst_ip=self.nat_addr)
7514 self.pg1.add_stream(pkts)
7515 self.pg_enable_capture(self.pg_interfaces)
7517 capture = self.pg0.get_capture(len(pkts))
7518 ip = IPv6(src=''.join(['64:ff9b::', self.pg1.remote_ip4]))
7519 self.verify_capture_in_ip6(capture, ip[IPv6].src, self.pg0.remote_ip6)
7521 ses_num_end = self.nat64_get_ses_num()
7523 self.assertEqual(ses_num_end - ses_num_start, 3)
7525 @unittest.skipUnless(running_extended_tests, "part of extended tests")
7526 def test_session_timeout(self):
7527 """ NAT64 session timeout """
7528 self.icmp_id_in = 1234
7529 self.vapi.nat64_add_del_pool_addr_range(self.nat_addr_n,
7531 self.vapi.nat64_add_del_interface(self.pg0.sw_if_index)
7532 self.vapi.nat64_add_del_interface(self.pg1.sw_if_index, is_inside=0)
7533 self.vapi.nat_set_timeouts(icmp=5, tcp_transitory=5, tcp_established=5)
7535 pkts = self.create_stream_in_ip6(self.pg0, self.pg1)
7536 self.pg0.add_stream(pkts)
7537 self.pg_enable_capture(self.pg_interfaces)
7539 capture = self.pg1.get_capture(len(pkts))
7541 ses_num_before_timeout = self.nat64_get_ses_num()
7545 # ICMP and TCP session after timeout
7546 ses_num_after_timeout = self.nat64_get_ses_num()
7547 self.assertEqual(ses_num_before_timeout - ses_num_after_timeout, 2)
7549 def test_icmp_error(self):
7550 """ NAT64 ICMP Error message translation """
7551 self.tcp_port_in = 6303
7552 self.udp_port_in = 6304
7553 self.icmp_id_in = 6305
7555 self.vapi.nat64_add_del_pool_addr_range(self.nat_addr_n,
7557 self.vapi.nat64_add_del_interface(self.pg0.sw_if_index)
7558 self.vapi.nat64_add_del_interface(self.pg1.sw_if_index, is_inside=0)
7560 # send some packets to create sessions
7561 pkts = self.create_stream_in_ip6(self.pg0, self.pg1)
7562 self.pg0.add_stream(pkts)
7563 self.pg_enable_capture(self.pg_interfaces)
7565 capture_ip4 = self.pg1.get_capture(len(pkts))
7566 self.verify_capture_out(capture_ip4,
7567 nat_ip=self.nat_addr,
7568 dst_ip=self.pg1.remote_ip4)
7570 pkts = self.create_stream_out(self.pg1, dst_ip=self.nat_addr)
7571 self.pg1.add_stream(pkts)
7572 self.pg_enable_capture(self.pg_interfaces)
7574 capture_ip6 = self.pg0.get_capture(len(pkts))
7575 ip = IPv6(src=''.join(['64:ff9b::', self.pg1.remote_ip4]))
7576 self.verify_capture_in_ip6(capture_ip6, ip[IPv6].src,
7577 self.pg0.remote_ip6)
7580 pkts = [Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
7581 IPv6(src=self.pg0.remote_ip6, dst=ip[IPv6].src) /
7582 ICMPv6DestUnreach(code=1) /
7583 packet[IPv6] for packet in capture_ip6]
7584 self.pg0.add_stream(pkts)
7585 self.pg_enable_capture(self.pg_interfaces)
7587 capture = self.pg1.get_capture(len(pkts))
7588 for packet in capture:
7590 self.assertEqual(packet[IP].src, self.nat_addr)
7591 self.assertEqual(packet[IP].dst, self.pg1.remote_ip4)
7592 self.assertEqual(packet[ICMP].type, 3)
7593 self.assertEqual(packet[ICMP].code, 13)
7594 inner = packet[IPerror]
7595 self.assertEqual(inner.src, self.pg1.remote_ip4)
7596 self.assertEqual(inner.dst, self.nat_addr)
7597 self.assert_packet_checksums_valid(packet)
7598 if inner.haslayer(TCPerror):
7599 self.assertEqual(inner[TCPerror].dport, self.tcp_port_out)
7600 elif inner.haslayer(UDPerror):
7601 self.assertEqual(inner[UDPerror].dport, self.udp_port_out)
7603 self.assertEqual(inner[ICMPerror].id, self.icmp_id_out)
7605 self.logger.error(ppp("Unexpected or invalid packet:", packet))
7609 pkts = [Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
7610 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
7611 ICMP(type=3, code=13) /
7612 packet[IP] for packet in capture_ip4]
7613 self.pg1.add_stream(pkts)
7614 self.pg_enable_capture(self.pg_interfaces)
7616 capture = self.pg0.get_capture(len(pkts))
7617 for packet in capture:
7619 self.assertEqual(packet[IPv6].src, ip.src)
7620 self.assertEqual(packet[IPv6].dst, self.pg0.remote_ip6)
7621 icmp = packet[ICMPv6DestUnreach]
7622 self.assertEqual(icmp.code, 1)
7623 inner = icmp[IPerror6]
7624 self.assertEqual(inner.src, self.pg0.remote_ip6)
7625 self.assertEqual(inner.dst, ip.src)
7626 self.assert_icmpv6_checksum_valid(packet)
7627 if inner.haslayer(TCPerror):
7628 self.assertEqual(inner[TCPerror].sport, self.tcp_port_in)
7629 elif inner.haslayer(UDPerror):
7630 self.assertEqual(inner[UDPerror].sport, self.udp_port_in)
7632 self.assertEqual(inner[ICMPv6EchoRequest].id,
7635 self.logger.error(ppp("Unexpected or invalid packet:", packet))
7638 def test_hairpinning(self):
7639 """ NAT64 hairpinning """
7641 client = self.pg0.remote_hosts[0]
7642 server = self.pg0.remote_hosts[1]
7643 server_tcp_in_port = 22
7644 server_tcp_out_port = 4022
7645 server_udp_in_port = 23
7646 server_udp_out_port = 4023
7647 client_tcp_in_port = 1234
7648 client_udp_in_port = 1235
7649 client_tcp_out_port = 0
7650 client_udp_out_port = 0
7651 ip = IPv6(src=''.join(['64:ff9b::', self.nat_addr]))
7652 nat_addr_ip6 = ip.src
7654 self.vapi.nat64_add_del_pool_addr_range(self.nat_addr_n,
7656 self.vapi.nat64_add_del_interface(self.pg0.sw_if_index)
7657 self.vapi.nat64_add_del_interface(self.pg1.sw_if_index, is_inside=0)
7659 self.vapi.nat64_add_del_static_bib(server.ip6n,
7662 server_tcp_out_port,
7664 self.vapi.nat64_add_del_static_bib(server.ip6n,
7667 server_udp_out_port,
7672 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
7673 IPv6(src=client.ip6, dst=nat_addr_ip6) /
7674 TCP(sport=client_tcp_in_port, dport=server_tcp_out_port))
7676 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
7677 IPv6(src=client.ip6, dst=nat_addr_ip6) /
7678 UDP(sport=client_udp_in_port, dport=server_udp_out_port))
7680 self.pg0.add_stream(pkts)
7681 self.pg_enable_capture(self.pg_interfaces)
7683 capture = self.pg0.get_capture(len(pkts))
7684 for packet in capture:
7686 self.assertEqual(packet[IPv6].src, nat_addr_ip6)
7687 self.assertEqual(packet[IPv6].dst, server.ip6)
7688 self.assert_packet_checksums_valid(packet)
7689 if packet.haslayer(TCP):
7690 self.assertNotEqual(packet[TCP].sport, client_tcp_in_port)
7691 self.assertEqual(packet[TCP].dport, server_tcp_in_port)
7692 client_tcp_out_port = packet[TCP].sport
7694 self.assertNotEqual(packet[UDP].sport, client_udp_in_port)
7695 self.assertEqual(packet[UDP].dport, server_udp_in_port)
7696 client_udp_out_port = packet[UDP].sport
7698 self.logger.error(ppp("Unexpected or invalid packet:", packet))
7703 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
7704 IPv6(src=server.ip6, dst=nat_addr_ip6) /
7705 TCP(sport=server_tcp_in_port, dport=client_tcp_out_port))
7707 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
7708 IPv6(src=server.ip6, dst=nat_addr_ip6) /
7709 UDP(sport=server_udp_in_port, dport=client_udp_out_port))
7711 self.pg0.add_stream(pkts)
7712 self.pg_enable_capture(self.pg_interfaces)
7714 capture = self.pg0.get_capture(len(pkts))
7715 for packet in capture:
7717 self.assertEqual(packet[IPv6].src, nat_addr_ip6)
7718 self.assertEqual(packet[IPv6].dst, client.ip6)
7719 self.assert_packet_checksums_valid(packet)
7720 if packet.haslayer(TCP):
7721 self.assertEqual(packet[TCP].sport, server_tcp_out_port)
7722 self.assertEqual(packet[TCP].dport, client_tcp_in_port)
7724 self.assertEqual(packet[UDP].sport, server_udp_out_port)
7725 self.assertEqual(packet[UDP].dport, client_udp_in_port)
7727 self.logger.error(ppp("Unexpected or invalid packet:", packet))
7732 pkts = [Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
7733 IPv6(src=client.ip6, dst=nat_addr_ip6) /
7734 ICMPv6DestUnreach(code=1) /
7735 packet[IPv6] for packet in capture]
7736 self.pg0.add_stream(pkts)
7737 self.pg_enable_capture(self.pg_interfaces)
7739 capture = self.pg0.get_capture(len(pkts))
7740 for packet in capture:
7742 self.assertEqual(packet[IPv6].src, nat_addr_ip6)
7743 self.assertEqual(packet[IPv6].dst, server.ip6)
7744 icmp = packet[ICMPv6DestUnreach]
7745 self.assertEqual(icmp.code, 1)
7746 inner = icmp[IPerror6]
7747 self.assertEqual(inner.src, server.ip6)
7748 self.assertEqual(inner.dst, nat_addr_ip6)
7749 self.assert_packet_checksums_valid(packet)
7750 if inner.haslayer(TCPerror):
7751 self.assertEqual(inner[TCPerror].sport, server_tcp_in_port)
7752 self.assertEqual(inner[TCPerror].dport,
7753 client_tcp_out_port)
7755 self.assertEqual(inner[UDPerror].sport, server_udp_in_port)
7756 self.assertEqual(inner[UDPerror].dport,
7757 client_udp_out_port)
7759 self.logger.error(ppp("Unexpected or invalid packet:", packet))
7762 def test_prefix(self):
7763 """ NAT64 Network-Specific Prefix """
7765 self.vapi.nat64_add_del_pool_addr_range(self.nat_addr_n,
7767 self.vapi.nat64_add_del_interface(self.pg0.sw_if_index)
7768 self.vapi.nat64_add_del_interface(self.pg1.sw_if_index, is_inside=0)
7769 self.vapi.nat64_add_del_pool_addr_range(self.vrf1_nat_addr_n,
7770 self.vrf1_nat_addr_n,
7771 vrf_id=self.vrf1_id)
7772 self.vapi.nat64_add_del_interface(self.pg2.sw_if_index)
7775 global_pref64 = "2001:db8::"
7776 global_pref64_n = socket.inet_pton(socket.AF_INET6, global_pref64)
7777 global_pref64_len = 32
7778 self.vapi.nat64_add_del_prefix(global_pref64_n, global_pref64_len)
7780 prefix = self.vapi.nat64_prefix_dump()
7781 self.assertEqual(len(prefix), 1)
7782 self.assertEqual(prefix[0].prefix, global_pref64_n)
7783 self.assertEqual(prefix[0].prefix_len, global_pref64_len)
7784 self.assertEqual(prefix[0].vrf_id, 0)
7786 # Add tenant specific prefix
7787 vrf1_pref64 = "2001:db8:122:300::"
7788 vrf1_pref64_n = socket.inet_pton(socket.AF_INET6, vrf1_pref64)
7789 vrf1_pref64_len = 56
7790 self.vapi.nat64_add_del_prefix(vrf1_pref64_n,
7792 vrf_id=self.vrf1_id)
7793 prefix = self.vapi.nat64_prefix_dump()
7794 self.assertEqual(len(prefix), 2)
7797 pkts = self.create_stream_in_ip6(self.pg0,
7800 plen=global_pref64_len)
7801 self.pg0.add_stream(pkts)
7802 self.pg_enable_capture(self.pg_interfaces)
7804 capture = self.pg1.get_capture(len(pkts))
7805 self.verify_capture_out(capture, nat_ip=self.nat_addr,
7806 dst_ip=self.pg1.remote_ip4)
7808 pkts = self.create_stream_out(self.pg1, dst_ip=self.nat_addr)
7809 self.pg1.add_stream(pkts)
7810 self.pg_enable_capture(self.pg_interfaces)
7812 capture = self.pg0.get_capture(len(pkts))
7813 dst_ip = self.compose_ip6(self.pg1.remote_ip4,
7816 self.verify_capture_in_ip6(capture, dst_ip, self.pg0.remote_ip6)
7818 # Tenant specific prefix
7819 pkts = self.create_stream_in_ip6(self.pg2,
7822 plen=vrf1_pref64_len)
7823 self.pg2.add_stream(pkts)
7824 self.pg_enable_capture(self.pg_interfaces)
7826 capture = self.pg1.get_capture(len(pkts))
7827 self.verify_capture_out(capture, nat_ip=self.vrf1_nat_addr,
7828 dst_ip=self.pg1.remote_ip4)
7830 pkts = self.create_stream_out(self.pg1, dst_ip=self.vrf1_nat_addr)
7831 self.pg1.add_stream(pkts)
7832 self.pg_enable_capture(self.pg_interfaces)
7834 capture = self.pg2.get_capture(len(pkts))
7835 dst_ip = self.compose_ip6(self.pg1.remote_ip4,
7838 self.verify_capture_in_ip6(capture, dst_ip, self.pg2.remote_ip6)
7840 def test_unknown_proto(self):
7841 """ NAT64 translate packet with unknown protocol """
7843 self.vapi.nat64_add_del_pool_addr_range(self.nat_addr_n,
7845 self.vapi.nat64_add_del_interface(self.pg0.sw_if_index)
7846 self.vapi.nat64_add_del_interface(self.pg1.sw_if_index, is_inside=0)
7847 remote_ip6 = self.compose_ip6(self.pg1.remote_ip4, '64:ff9b::', 96)
7850 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
7851 IPv6(src=self.pg0.remote_ip6, dst=remote_ip6) /
7852 TCP(sport=self.tcp_port_in, dport=20))
7853 self.pg0.add_stream(p)
7854 self.pg_enable_capture(self.pg_interfaces)
7856 p = self.pg1.get_capture(1)
7858 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
7859 IPv6(src=self.pg0.remote_ip6, dst=remote_ip6, nh=47) /
7861 IP(src=self.pg2.local_ip4, dst=self.pg2.remote_ip4) /
7862 TCP(sport=1234, dport=1234))
7863 self.pg0.add_stream(p)
7864 self.pg_enable_capture(self.pg_interfaces)
7866 p = self.pg1.get_capture(1)
7869 self.assertEqual(packet[IP].src, self.nat_addr)
7870 self.assertEqual(packet[IP].dst, self.pg1.remote_ip4)
7871 self.assertEqual(packet.haslayer(GRE), 1)
7872 self.assert_packet_checksums_valid(packet)
7874 self.logger.error(ppp("Unexpected or invalid packet:", packet))
7878 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
7879 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
7881 IP(src=self.pg2.remote_ip4, dst=self.pg2.local_ip4) /
7882 TCP(sport=1234, dport=1234))
7883 self.pg1.add_stream(p)
7884 self.pg_enable_capture(self.pg_interfaces)
7886 p = self.pg0.get_capture(1)
7889 self.assertEqual(packet[IPv6].src, remote_ip6)
7890 self.assertEqual(packet[IPv6].dst, self.pg0.remote_ip6)
7891 self.assertEqual(packet[IPv6].nh, 47)
7893 self.logger.error(ppp("Unexpected or invalid packet:", packet))
7896 def test_hairpinning_unknown_proto(self):
7897 """ NAT64 translate packet with unknown protocol - hairpinning """
7899 client = self.pg0.remote_hosts[0]
7900 server = self.pg0.remote_hosts[1]
7901 server_tcp_in_port = 22
7902 server_tcp_out_port = 4022
7903 client_tcp_in_port = 1234
7904 client_tcp_out_port = 1235
7905 server_nat_ip = "10.0.0.100"
7906 client_nat_ip = "10.0.0.110"
7907 server_nat_ip_n = socket.inet_pton(socket.AF_INET, server_nat_ip)
7908 client_nat_ip_n = socket.inet_pton(socket.AF_INET, client_nat_ip)
7909 server_nat_ip6 = self.compose_ip6(server_nat_ip, '64:ff9b::', 96)
7910 client_nat_ip6 = self.compose_ip6(client_nat_ip, '64:ff9b::', 96)
7912 self.vapi.nat64_add_del_pool_addr_range(server_nat_ip_n,
7914 self.vapi.nat64_add_del_interface(self.pg0.sw_if_index)
7915 self.vapi.nat64_add_del_interface(self.pg1.sw_if_index, is_inside=0)
7917 self.vapi.nat64_add_del_static_bib(server.ip6n,
7920 server_tcp_out_port,
7923 self.vapi.nat64_add_del_static_bib(server.ip6n,
7929 self.vapi.nat64_add_del_static_bib(client.ip6n,
7932 client_tcp_out_port,
7936 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
7937 IPv6(src=client.ip6, dst=server_nat_ip6) /
7938 TCP(sport=client_tcp_in_port, dport=server_tcp_out_port))
7939 self.pg0.add_stream(p)
7940 self.pg_enable_capture(self.pg_interfaces)
7942 p = self.pg0.get_capture(1)
7944 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
7945 IPv6(src=client.ip6, dst=server_nat_ip6, nh=IP_PROTOS.gre) /
7947 IP(src=self.pg2.local_ip4, dst=self.pg2.remote_ip4) /
7948 TCP(sport=1234, dport=1234))
7949 self.pg0.add_stream(p)
7950 self.pg_enable_capture(self.pg_interfaces)
7952 p = self.pg0.get_capture(1)
7955 self.assertEqual(packet[IPv6].src, client_nat_ip6)
7956 self.assertEqual(packet[IPv6].dst, server.ip6)
7957 self.assertEqual(packet[IPv6].nh, IP_PROTOS.gre)
7959 self.logger.error(ppp("Unexpected or invalid packet:", packet))
7963 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
7964 IPv6(src=server.ip6, dst=client_nat_ip6, nh=IP_PROTOS.gre) /
7966 IP(src=self.pg2.remote_ip4, dst=self.pg2.local_ip4) /
7967 TCP(sport=1234, dport=1234))
7968 self.pg0.add_stream(p)
7969 self.pg_enable_capture(self.pg_interfaces)
7971 p = self.pg0.get_capture(1)
7974 self.assertEqual(packet[IPv6].src, server_nat_ip6)
7975 self.assertEqual(packet[IPv6].dst, client.ip6)
7976 self.assertEqual(packet[IPv6].nh, IP_PROTOS.gre)
7978 self.logger.error(ppp("Unexpected or invalid packet:", packet))
7981 def test_one_armed_nat64(self):
7982 """ One armed NAT64 """
7984 remote_host_ip6 = self.compose_ip6(self.pg3.remote_ip4,
7988 self.vapi.nat64_add_del_pool_addr_range(self.nat_addr_n,
7990 self.vapi.nat64_add_del_interface(self.pg3.sw_if_index)
7991 self.vapi.nat64_add_del_interface(self.pg3.sw_if_index, is_inside=0)
7994 p = (Ether(src=self.pg3.remote_mac, dst=self.pg3.local_mac) /
7995 IPv6(src=self.pg3.remote_ip6, dst=remote_host_ip6) /
7996 TCP(sport=12345, dport=80))
7997 self.pg3.add_stream(p)
7998 self.pg_enable_capture(self.pg_interfaces)
8000 capture = self.pg3.get_capture(1)
8005 self.assertEqual(ip.src, self.nat_addr)
8006 self.assertEqual(ip.dst, self.pg3.remote_ip4)
8007 self.assertNotEqual(tcp.sport, 12345)
8008 external_port = tcp.sport
8009 self.assertEqual(tcp.dport, 80)
8010 self.assert_packet_checksums_valid(p)
8012 self.logger.error(ppp("Unexpected or invalid packet:", p))
8016 p = (Ether(src=self.pg3.remote_mac, dst=self.pg3.local_mac) /
8017 IP(src=self.pg3.remote_ip4, dst=self.nat_addr) /
8018 TCP(sport=80, dport=external_port))
8019 self.pg3.add_stream(p)
8020 self.pg_enable_capture(self.pg_interfaces)
8022 capture = self.pg3.get_capture(1)
8027 self.assertEqual(ip.src, remote_host_ip6)
8028 self.assertEqual(ip.dst, self.pg3.remote_ip6)
8029 self.assertEqual(tcp.sport, 80)
8030 self.assertEqual(tcp.dport, 12345)
8031 self.assert_packet_checksums_valid(p)
8033 self.logger.error(ppp("Unexpected or invalid packet:", p))
8036 def test_frag_in_order(self):
8037 """ NAT64 translate fragments arriving in order """
8038 self.tcp_port_in = random.randint(1025, 65535)
8040 self.vapi.nat64_add_del_pool_addr_range(self.nat_addr_n,
8042 self.vapi.nat64_add_del_interface(self.pg0.sw_if_index)
8043 self.vapi.nat64_add_del_interface(self.pg1.sw_if_index, is_inside=0)
8045 reass = self.vapi.nat_reass_dump()
8046 reass_n_start = len(reass)
8050 pkts = self.create_stream_frag_ip6(self.pg0, self.pg1.remote_ip4,
8051 self.tcp_port_in, 20, data)
8052 self.pg0.add_stream(pkts)
8053 self.pg_enable_capture(self.pg_interfaces)
8055 frags = self.pg1.get_capture(len(pkts))
8056 p = self.reass_frags_and_verify(frags,
8058 self.pg1.remote_ip4)
8059 self.assertEqual(p[TCP].dport, 20)
8060 self.assertNotEqual(p[TCP].sport, self.tcp_port_in)
8061 self.tcp_port_out = p[TCP].sport
8062 self.assertEqual(data, p[Raw].load)
8065 data = b"A" * 4 + b"b" * 16 + b"C" * 3
8066 pkts = self.create_stream_frag(self.pg1,
8071 self.pg1.add_stream(pkts)
8072 self.pg_enable_capture(self.pg_interfaces)
8074 frags = self.pg0.get_capture(len(pkts))
8075 src = self.compose_ip6(self.pg1.remote_ip4, '64:ff9b::', 96)
8076 p = self.reass_frags_and_verify_ip6(frags, src, self.pg0.remote_ip6)
8077 self.assertEqual(p[TCP].sport, 20)
8078 self.assertEqual(p[TCP].dport, self.tcp_port_in)
8079 self.assertEqual(data, p[Raw].load)
8081 reass = self.vapi.nat_reass_dump()
8082 reass_n_end = len(reass)
8084 self.assertEqual(reass_n_end - reass_n_start, 2)
8086 def test_reass_hairpinning(self):
8087 """ NAT64 fragments hairpinning """
8089 server = self.pg0.remote_hosts[1]
8090 server_in_port = random.randint(1025, 65535)
8091 server_out_port = random.randint(1025, 65535)
8092 client_in_port = random.randint(1025, 65535)
8093 ip = IPv6(src=''.join(['64:ff9b::', self.nat_addr]))
8094 nat_addr_ip6 = ip.src
8096 self.vapi.nat64_add_del_pool_addr_range(self.nat_addr_n,
8098 self.vapi.nat64_add_del_interface(self.pg0.sw_if_index)
8099 self.vapi.nat64_add_del_interface(self.pg1.sw_if_index, is_inside=0)
8101 # add static BIB entry for server
8102 self.vapi.nat64_add_del_static_bib(server.ip6n,
8108 # send packet from host to server
8109 pkts = self.create_stream_frag_ip6(self.pg0,
8114 self.pg0.add_stream(pkts)
8115 self.pg_enable_capture(self.pg_interfaces)
8117 frags = self.pg0.get_capture(len(pkts))
8118 p = self.reass_frags_and_verify_ip6(frags, nat_addr_ip6, server.ip6)
8119 self.assertNotEqual(p[TCP].sport, client_in_port)
8120 self.assertEqual(p[TCP].dport, server_in_port)
8121 self.assertEqual(data, p[Raw].load)
8123 def test_frag_out_of_order(self):
8124 """ NAT64 translate fragments arriving out of order """
8125 self.tcp_port_in = random.randint(1025, 65535)
8127 self.vapi.nat64_add_del_pool_addr_range(self.nat_addr_n,
8129 self.vapi.nat64_add_del_interface(self.pg0.sw_if_index)
8130 self.vapi.nat64_add_del_interface(self.pg1.sw_if_index, is_inside=0)
8134 pkts = self.create_stream_frag_ip6(self.pg0, self.pg1.remote_ip4,
8135 self.tcp_port_in, 20, data)
8137 self.pg0.add_stream(pkts)
8138 self.pg_enable_capture(self.pg_interfaces)
8140 frags = self.pg1.get_capture(len(pkts))
8141 p = self.reass_frags_and_verify(frags,
8143 self.pg1.remote_ip4)
8144 self.assertEqual(p[TCP].dport, 20)
8145 self.assertNotEqual(p[TCP].sport, self.tcp_port_in)
8146 self.tcp_port_out = p[TCP].sport
8147 self.assertEqual(data, p[Raw].load)
8150 data = b"A" * 4 + b"B" * 16 + b"C" * 3
8151 pkts = self.create_stream_frag(self.pg1,
8157 self.pg1.add_stream(pkts)
8158 self.pg_enable_capture(self.pg_interfaces)
8160 frags = self.pg0.get_capture(len(pkts))
8161 src = self.compose_ip6(self.pg1.remote_ip4, '64:ff9b::', 96)
8162 p = self.reass_frags_and_verify_ip6(frags, src, self.pg0.remote_ip6)
8163 self.assertEqual(p[TCP].sport, 20)
8164 self.assertEqual(p[TCP].dport, self.tcp_port_in)
8165 self.assertEqual(data, p[Raw].load)
8167 def test_interface_addr(self):
8168 """ Acquire NAT64 pool addresses from interface """
8169 self.vapi.nat64_add_del_interface_addr(self.pg4.sw_if_index)
8171 # no address in NAT64 pool
8172 adresses = self.vapi.nat44_address_dump()
8173 self.assertEqual(0, len(adresses))
8175 # configure interface address and check NAT64 address pool
8176 self.pg4.config_ip4()
8177 addresses = self.vapi.nat64_pool_addr_dump()
8178 self.assertEqual(len(addresses), 1)
8179 self.assertEqual(addresses[0].address, self.pg4.local_ip4n)
8181 # remove interface address and check NAT64 address pool
8182 self.pg4.unconfig_ip4()
8183 addresses = self.vapi.nat64_pool_addr_dump()
8184 self.assertEqual(0, len(adresses))
8186 @unittest.skipUnless(running_extended_tests, "part of extended tests")
8187 def test_ipfix_max_bibs_sessions(self):
8188 """ IPFIX logging maximum session and BIB entries exceeded """
8191 remote_host_ip6 = self.compose_ip6(self.pg1.remote_ip4,
8195 self.vapi.nat64_add_del_pool_addr_range(self.nat_addr_n,
8197 self.vapi.nat64_add_del_interface(self.pg0.sw_if_index)
8198 self.vapi.nat64_add_del_interface(self.pg1.sw_if_index, is_inside=0)
8202 for i in range(0, max_bibs):
8203 src = "fd01:aa::%x" % (i)
8204 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
8205 IPv6(src=src, dst=remote_host_ip6) /
8206 TCP(sport=12345, dport=80))
8208 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
8209 IPv6(src=src, dst=remote_host_ip6) /
8210 TCP(sport=12345, dport=22))
8212 self.pg0.add_stream(pkts)
8213 self.pg_enable_capture(self.pg_interfaces)
8215 self.pg1.get_capture(max_sessions)
8217 self.vapi.set_ipfix_exporter(collector_address=self.pg3.remote_ip4n,
8218 src_address=self.pg3.local_ip4n,
8220 template_interval=10)
8221 self.vapi.nat_ipfix_enable_disable(domain_id=self.ipfix_domain_id,
8222 src_port=self.ipfix_src_port)
8224 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
8225 IPv6(src=src, dst=remote_host_ip6) /
8226 TCP(sport=12345, dport=25))
8227 self.pg0.add_stream(p)
8228 self.pg_enable_capture(self.pg_interfaces)
8230 self.pg1.assert_nothing_captured()
8232 self.vapi.cli("ipfix flush") # FIXME this should be an API call
8233 capture = self.pg3.get_capture(9)
8234 ipfix = IPFIXDecoder()
8235 # first load template
8237 self.assertTrue(p.haslayer(IPFIX))
8238 self.assertEqual(p[IP].src, self.pg3.local_ip4)
8239 self.assertEqual(p[IP].dst, self.pg3.remote_ip4)
8240 self.assertEqual(p[UDP].sport, self.ipfix_src_port)
8241 self.assertEqual(p[UDP].dport, 4739)
8242 self.assertEqual(p[IPFIX].observationDomainID,
8243 self.ipfix_domain_id)
8244 if p.haslayer(Template):
8245 ipfix.add_template(p.getlayer(Template))
8246 # verify events in data set
8248 if p.haslayer(Data):
8249 data = ipfix.decode_data_set(p.getlayer(Set))
8250 self.verify_ipfix_max_sessions(data, max_sessions)
8252 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
8253 IPv6(src=self.pg0.remote_ip6, dst=remote_host_ip6) /
8254 TCP(sport=12345, dport=80))
8255 self.pg0.add_stream(p)
8256 self.pg_enable_capture(self.pg_interfaces)
8258 self.pg1.assert_nothing_captured()
8260 self.vapi.cli("ipfix flush") # FIXME this should be an API call
8261 capture = self.pg3.get_capture(1)
8262 # verify events in data set
8264 self.assertTrue(p.haslayer(IPFIX))
8265 self.assertEqual(p[IP].src, self.pg3.local_ip4)
8266 self.assertEqual(p[IP].dst, self.pg3.remote_ip4)
8267 self.assertEqual(p[UDP].sport, self.ipfix_src_port)
8268 self.assertEqual(p[UDP].dport, 4739)
8269 self.assertEqual(p[IPFIX].observationDomainID,
8270 self.ipfix_domain_id)
8271 if p.haslayer(Data):
8272 data = ipfix.decode_data_set(p.getlayer(Set))
8273 self.verify_ipfix_max_bibs(data, max_bibs)
8275 def test_ipfix_max_frags(self):
8276 """ IPFIX logging maximum fragments pending reassembly exceeded """
8277 self.vapi.nat64_add_del_pool_addr_range(self.nat_addr_n,
8279 self.vapi.nat64_add_del_interface(self.pg0.sw_if_index)
8280 self.vapi.nat64_add_del_interface(self.pg1.sw_if_index, is_inside=0)
8281 self.vapi.nat_set_reass(max_frag=1, is_ip6=1)
8282 self.vapi.set_ipfix_exporter(collector_address=self.pg3.remote_ip4n,
8283 src_address=self.pg3.local_ip4n,
8285 template_interval=10)
8286 self.vapi.nat_ipfix_enable_disable(domain_id=self.ipfix_domain_id,
8287 src_port=self.ipfix_src_port)
8290 pkts = self.create_stream_frag_ip6(self.pg0, self.pg1.remote_ip4,
8291 self.tcp_port_in, 20, data)
8293 self.pg0.add_stream(pkts)
8294 self.pg_enable_capture(self.pg_interfaces)
8296 self.pg1.assert_nothing_captured()
8298 self.vapi.cli("ipfix flush") # FIXME this should be an API call
8299 capture = self.pg3.get_capture(9)
8300 ipfix = IPFIXDecoder()
8301 # first load template
8303 self.assertTrue(p.haslayer(IPFIX))
8304 self.assertEqual(p[IP].src, self.pg3.local_ip4)
8305 self.assertEqual(p[IP].dst, self.pg3.remote_ip4)
8306 self.assertEqual(p[UDP].sport, self.ipfix_src_port)
8307 self.assertEqual(p[UDP].dport, 4739)
8308 self.assertEqual(p[IPFIX].observationDomainID,
8309 self.ipfix_domain_id)
8310 if p.haslayer(Template):
8311 ipfix.add_template(p.getlayer(Template))
8312 # verify events in data set
8314 if p.haslayer(Data):
8315 data = ipfix.decode_data_set(p.getlayer(Set))
8316 self.verify_ipfix_max_fragments_ip6(data, 1,
8317 self.pg0.remote_ip6n)
8319 def test_ipfix_bib_ses(self):
8320 """ IPFIX logging NAT64 BIB/session create and delete events """
8321 self.tcp_port_in = random.randint(1025, 65535)
8322 remote_host_ip6 = self.compose_ip6(self.pg1.remote_ip4,
8326 self.vapi.nat64_add_del_pool_addr_range(self.nat_addr_n,
8328 self.vapi.nat64_add_del_interface(self.pg0.sw_if_index)
8329 self.vapi.nat64_add_del_interface(self.pg1.sw_if_index, is_inside=0)
8330 self.vapi.set_ipfix_exporter(collector_address=self.pg3.remote_ip4n,
8331 src_address=self.pg3.local_ip4n,
8333 template_interval=10)
8334 self.vapi.nat_ipfix_enable_disable(domain_id=self.ipfix_domain_id,
8335 src_port=self.ipfix_src_port)
8338 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
8339 IPv6(src=self.pg0.remote_ip6, dst=remote_host_ip6) /
8340 TCP(sport=self.tcp_port_in, dport=25))
8341 self.pg0.add_stream(p)
8342 self.pg_enable_capture(self.pg_interfaces)
8344 p = self.pg1.get_capture(1)
8345 self.tcp_port_out = p[0][TCP].sport
8346 self.vapi.cli("ipfix flush") # FIXME this should be an API call
8347 capture = self.pg3.get_capture(10)
8348 ipfix = IPFIXDecoder()
8349 # first load template
8351 self.assertTrue(p.haslayer(IPFIX))
8352 self.assertEqual(p[IP].src, self.pg3.local_ip4)
8353 self.assertEqual(p[IP].dst, self.pg3.remote_ip4)
8354 self.assertEqual(p[UDP].sport, self.ipfix_src_port)
8355 self.assertEqual(p[UDP].dport, 4739)
8356 self.assertEqual(p[IPFIX].observationDomainID,
8357 self.ipfix_domain_id)
8358 if p.haslayer(Template):
8359 ipfix.add_template(p.getlayer(Template))
8360 # verify events in data set
8362 if p.haslayer(Data):
8363 data = ipfix.decode_data_set(p.getlayer(Set))
8364 if scapy.compat.orb(data[0][230]) == 10:
8365 self.verify_ipfix_bib(data, 1, self.pg0.remote_ip6n)
8366 elif scapy.compat.orb(data[0][230]) == 6:
8367 self.verify_ipfix_nat64_ses(data,
8369 self.pg0.remote_ip6n,
8370 self.pg1.remote_ip4,
8373 self.logger.error(ppp("Unexpected or invalid packet: ", p))
8376 self.pg_enable_capture(self.pg_interfaces)
8377 self.vapi.nat64_add_del_pool_addr_range(self.nat_addr_n,
8380 self.vapi.cli("ipfix flush") # FIXME this should be an API call
8381 capture = self.pg3.get_capture(2)
8382 # verify events in data set
8384 self.assertTrue(p.haslayer(IPFIX))
8385 self.assertEqual(p[IP].src, self.pg3.local_ip4)
8386 self.assertEqual(p[IP].dst, self.pg3.remote_ip4)
8387 self.assertEqual(p[UDP].sport, self.ipfix_src_port)
8388 self.assertEqual(p[UDP].dport, 4739)
8389 self.assertEqual(p[IPFIX].observationDomainID,
8390 self.ipfix_domain_id)
8391 if p.haslayer(Data):
8392 data = ipfix.decode_data_set(p.getlayer(Set))
8393 if scapy.compat.orb(data[0][230]) == 11:
8394 self.verify_ipfix_bib(data, 0, self.pg0.remote_ip6n)
8395 elif scapy.compat.orb(data[0][230]) == 7:
8396 self.verify_ipfix_nat64_ses(data,
8398 self.pg0.remote_ip6n,
8399 self.pg1.remote_ip4,
8402 self.logger.error(ppp("Unexpected or invalid packet: ", p))
8404 def test_syslog_sess(self):
8405 """ Test syslog session creation and deletion """
8406 self.tcp_port_in = random.randint(1025, 65535)
8407 remote_host_ip6 = self.compose_ip6(self.pg1.remote_ip4,
8411 self.vapi.nat64_add_del_pool_addr_range(self.nat_addr_n,
8413 self.vapi.nat64_add_del_interface(self.pg0.sw_if_index)
8414 self.vapi.nat64_add_del_interface(self.pg1.sw_if_index, is_inside=0)
8415 self.vapi.syslog_set_filter(SYSLOG_SEVERITY.INFO)
8416 self.vapi.syslog_set_sender(self.pg3.local_ip4n, self.pg3.remote_ip4n)
8418 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
8419 IPv6(src=self.pg0.remote_ip6, dst=remote_host_ip6) /
8420 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port))
8421 self.pg0.add_stream(p)
8422 self.pg_enable_capture(self.pg_interfaces)
8424 p = self.pg1.get_capture(1)
8425 self.tcp_port_out = p[0][TCP].sport
8426 capture = self.pg3.get_capture(1)
8427 self.verify_syslog_sess(capture[0][Raw].load, is_ip6=True)
8429 self.pg_enable_capture(self.pg_interfaces)
8431 self.vapi.nat64_add_del_pool_addr_range(self.nat_addr_n,
8434 capture = self.pg3.get_capture(1)
8435 self.verify_syslog_sess(capture[0][Raw].load, False, True)
8437 def nat64_get_ses_num(self):
8439 Return number of active NAT64 sessions.
8441 st = self.vapi.nat64_st_dump()
8444 def clear_nat64(self):
8446 Clear NAT64 configuration.
8448 self.vapi.nat_ipfix_enable_disable(enable=0,
8449 src_port=self.ipfix_src_port,
8450 domain_id=self.ipfix_domain_id)
8451 self.ipfix_src_port = 4739
8452 self.ipfix_domain_id = 1
8454 self.vapi.syslog_set_filter(SYSLOG_SEVERITY.EMERG)
8456 self.vapi.nat_set_timeouts()
8458 interfaces = self.vapi.nat64_interface_dump()
8459 for intf in interfaces:
8460 if intf.is_inside > 1:
8461 self.vapi.nat64_add_del_interface(intf.sw_if_index,
8464 self.vapi.nat64_add_del_interface(intf.sw_if_index,
8468 bib = self.vapi.nat64_bib_dump(255)
8471 self.vapi.nat64_add_del_static_bib(bibe.i_addr,
8479 adresses = self.vapi.nat64_pool_addr_dump()
8480 for addr in adresses:
8481 self.vapi.nat64_add_del_pool_addr_range(addr.address,
8486 prefixes = self.vapi.nat64_prefix_dump()
8487 for prefix in prefixes:
8488 self.vapi.nat64_add_del_prefix(prefix.prefix,
8490 vrf_id=prefix.vrf_id,
8493 bibs = self.statistics.get_counter('/nat64/total-bibs')
8494 self.assertEqual(bibs[0][0], 0)
8495 sessions = self.statistics.get_counter('/nat64/total-sessions')
8496 self.assertEqual(sessions[0][0], 0)
8499 super(TestNAT64, self).tearDown()
8500 if not self.vpp_dead:
8501 self.logger.info(self.vapi.cli("show nat64 pool"))
8502 self.logger.info(self.vapi.cli("show nat64 interfaces"))
8503 self.logger.info(self.vapi.cli("show nat64 prefix"))
8504 self.logger.info(self.vapi.cli("show nat64 bib all"))
8505 self.logger.info(self.vapi.cli("show nat64 session table all"))
8506 self.logger.info(self.vapi.cli("show nat virtual-reassembly"))
8510 class TestDSlite(MethodHolder):
8511 """ DS-Lite Test Cases """
8514 def setUpClass(cls):
8515 super(TestDSlite, cls).setUpClass()
8518 cls.nat_addr = '10.0.0.3'
8519 cls.nat_addr_n = socket.inet_pton(socket.AF_INET, cls.nat_addr)
8521 cls.create_pg_interfaces(range(3))
8523 cls.pg0.config_ip4()
8524 cls.pg0.resolve_arp()
8526 cls.pg1.config_ip6()
8527 cls.pg1.generate_remote_hosts(2)
8528 cls.pg1.configure_ipv6_neighbors()
8530 cls.pg2.config_ip4()
8531 cls.pg2.resolve_arp()
8534 super(TestDSlite, cls).tearDownClass()
8537 def verify_syslog_apmadd(self, data, isaddr, isport, xsaddr, xsport,
8539 message = data.decode('utf-8')
8541 message = SyslogMessage.parse(message)
8542 except ParseError as e:
8543 self.logger.error(e)
8545 self.assertEqual(message.severity, SyslogSeverity.info)
8546 self.assertEqual(message.appname, 'NAT')
8547 self.assertEqual(message.msgid, 'APMADD')
8548 sd_params = message.sd.get('napmap')
8549 self.assertTrue(sd_params is not None)
8550 self.assertEqual(sd_params.get('IATYP'), 'IPv4')
8551 self.assertEqual(sd_params.get('ISADDR'), isaddr)
8552 self.assertEqual(sd_params.get('ISPORT'), "%d" % isport)
8553 self.assertEqual(sd_params.get('XATYP'), 'IPv4')
8554 self.assertEqual(sd_params.get('XSADDR'), xsaddr)
8555 self.assertEqual(sd_params.get('XSPORT'), "%d" % xsport)
8556 self.assertEqual(sd_params.get('PROTO'), "%d" % proto)
8557 self.assertTrue(sd_params.get('SSUBIX') is not None)
8558 self.assertEqual(sd_params.get('SV6ENC'), sv6enc)
8560 def test_dslite(self):
8561 """ Test DS-Lite """
8562 nat_config = self.vapi.nat_show_config()
8563 self.assertEqual(0, nat_config.dslite_ce)
8565 self.vapi.dslite_add_del_pool_addr_range(self.nat_addr_n,
8567 aftr_ip4 = '192.0.0.1'
8568 aftr_ip4_n = socket.inet_pton(socket.AF_INET, aftr_ip4)
8569 aftr_ip6 = '2001:db8:85a3::8a2e:370:1'
8570 aftr_ip6_n = socket.inet_pton(socket.AF_INET6, aftr_ip6)
8571 self.vapi.dslite_set_aftr_addr(aftr_ip6_n, aftr_ip4_n)
8572 self.vapi.syslog_set_sender(self.pg2.local_ip4n, self.pg2.remote_ip4n)
8575 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
8576 IPv6(dst=aftr_ip6, src=self.pg1.remote_hosts[0].ip6) /
8577 IP(dst=self.pg0.remote_ip4, src='192.168.1.1') /
8578 UDP(sport=20000, dport=10000))
8579 self.pg1.add_stream(p)
8580 self.pg_enable_capture(self.pg_interfaces)
8582 capture = self.pg0.get_capture(1)
8583 capture = capture[0]
8584 self.assertFalse(capture.haslayer(IPv6))
8585 self.assertEqual(capture[IP].src, self.nat_addr)
8586 self.assertEqual(capture[IP].dst, self.pg0.remote_ip4)
8587 self.assertNotEqual(capture[UDP].sport, 20000)
8588 self.assertEqual(capture[UDP].dport, 10000)
8589 self.assert_packet_checksums_valid(capture)
8590 out_port = capture[UDP].sport
8591 capture = self.pg2.get_capture(1)
8592 self.verify_syslog_apmadd(capture[0][Raw].load, '192.168.1.1',
8593 20000, self.nat_addr, out_port,
8594 self.pg1.remote_hosts[0].ip6, IP_PROTOS.udp)
8596 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
8597 IP(dst=self.nat_addr, src=self.pg0.remote_ip4) /
8598 UDP(sport=10000, dport=out_port))
8599 self.pg0.add_stream(p)
8600 self.pg_enable_capture(self.pg_interfaces)
8602 capture = self.pg1.get_capture(1)
8603 capture = capture[0]
8604 self.assertEqual(capture[IPv6].src, aftr_ip6)
8605 self.assertEqual(capture[IPv6].dst, self.pg1.remote_hosts[0].ip6)
8606 self.assertEqual(capture[IP].src, self.pg0.remote_ip4)
8607 self.assertEqual(capture[IP].dst, '192.168.1.1')
8608 self.assertEqual(capture[UDP].sport, 10000)
8609 self.assertEqual(capture[UDP].dport, 20000)
8610 self.assert_packet_checksums_valid(capture)
8613 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
8614 IPv6(dst=aftr_ip6, src=self.pg1.remote_hosts[1].ip6) /
8615 IP(dst=self.pg0.remote_ip4, src='192.168.1.1') /
8616 TCP(sport=20001, dport=10001))
8617 self.pg1.add_stream(p)
8618 self.pg_enable_capture(self.pg_interfaces)
8620 capture = self.pg0.get_capture(1)
8621 capture = capture[0]
8622 self.assertFalse(capture.haslayer(IPv6))
8623 self.assertEqual(capture[IP].src, self.nat_addr)
8624 self.assertEqual(capture[IP].dst, self.pg0.remote_ip4)
8625 self.assertNotEqual(capture[TCP].sport, 20001)
8626 self.assertEqual(capture[TCP].dport, 10001)
8627 self.assert_packet_checksums_valid(capture)
8628 out_port = capture[TCP].sport
8630 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
8631 IP(dst=self.nat_addr, src=self.pg0.remote_ip4) /
8632 TCP(sport=10001, dport=out_port))
8633 self.pg0.add_stream(p)
8634 self.pg_enable_capture(self.pg_interfaces)
8636 capture = self.pg1.get_capture(1)
8637 capture = capture[0]
8638 self.assertEqual(capture[IPv6].src, aftr_ip6)
8639 self.assertEqual(capture[IPv6].dst, self.pg1.remote_hosts[1].ip6)
8640 self.assertEqual(capture[IP].src, self.pg0.remote_ip4)
8641 self.assertEqual(capture[IP].dst, '192.168.1.1')
8642 self.assertEqual(capture[TCP].sport, 10001)
8643 self.assertEqual(capture[TCP].dport, 20001)
8644 self.assert_packet_checksums_valid(capture)
8647 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
8648 IPv6(dst=aftr_ip6, src=self.pg1.remote_hosts[1].ip6) /
8649 IP(dst=self.pg0.remote_ip4, src='192.168.1.1') /
8650 ICMP(id=4000, type='echo-request'))
8651 self.pg1.add_stream(p)
8652 self.pg_enable_capture(self.pg_interfaces)
8654 capture = self.pg0.get_capture(1)
8655 capture = capture[0]
8656 self.assertFalse(capture.haslayer(IPv6))
8657 self.assertEqual(capture[IP].src, self.nat_addr)
8658 self.assertEqual(capture[IP].dst, self.pg0.remote_ip4)
8659 self.assertNotEqual(capture[ICMP].id, 4000)
8660 self.assert_packet_checksums_valid(capture)
8661 out_id = capture[ICMP].id
8663 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
8664 IP(dst=self.nat_addr, src=self.pg0.remote_ip4) /
8665 ICMP(id=out_id, type='echo-reply'))
8666 self.pg0.add_stream(p)
8667 self.pg_enable_capture(self.pg_interfaces)
8669 capture = self.pg1.get_capture(1)
8670 capture = capture[0]
8671 self.assertEqual(capture[IPv6].src, aftr_ip6)
8672 self.assertEqual(capture[IPv6].dst, self.pg1.remote_hosts[1].ip6)
8673 self.assertEqual(capture[IP].src, self.pg0.remote_ip4)
8674 self.assertEqual(capture[IP].dst, '192.168.1.1')
8675 self.assertEqual(capture[ICMP].id, 4000)
8676 self.assert_packet_checksums_valid(capture)
8678 # ping DS-Lite AFTR tunnel endpoint address
8679 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
8680 IPv6(src=self.pg1.remote_hosts[1].ip6, dst=aftr_ip6) /
8681 ICMPv6EchoRequest())
8682 self.pg1.add_stream(p)
8683 self.pg_enable_capture(self.pg_interfaces)
8685 capture = self.pg1.get_capture(1)
8686 capture = capture[0]
8687 self.assertEqual(capture[IPv6].src, aftr_ip6)
8688 self.assertEqual(capture[IPv6].dst, self.pg1.remote_hosts[1].ip6)
8689 self.assertTrue(capture.haslayer(ICMPv6EchoReply))
8691 b4s = self.statistics.get_counter('/dslite/total-b4s')
8692 self.assertEqual(b4s[0][0], 2)
8693 sessions = self.statistics.get_counter('/dslite/total-sessions')
8694 self.assertEqual(sessions[0][0], 3)
8697 super(TestDSlite, self).tearDown()
8698 if not self.vpp_dead:
8699 self.logger.info(self.vapi.cli("show dslite pool"))
8701 self.vapi.cli("show dslite aftr-tunnel-endpoint-address"))
8702 self.logger.info(self.vapi.cli("show dslite sessions"))
8705 class TestDSliteCE(MethodHolder):
8706 """ DS-Lite CE Test Cases """
8709 def setUpConstants(cls):
8710 super(TestDSliteCE, cls).setUpConstants()
8711 cls.vpp_cmdline.extend(["nat", "{", "dslite ce", "}"])
8714 def setUpClass(cls):
8715 super(TestDSliteCE, cls).setUpClass()
8718 cls.create_pg_interfaces(range(2))
8720 cls.pg0.config_ip4()
8721 cls.pg0.resolve_arp()
8723 cls.pg1.config_ip6()
8724 cls.pg1.generate_remote_hosts(1)
8725 cls.pg1.configure_ipv6_neighbors()
8728 super(TestDSliteCE, cls).tearDownClass()
8731 def test_dslite_ce(self):
8732 """ Test DS-Lite CE """
8734 nat_config = self.vapi.nat_show_config()
8735 self.assertEqual(1, nat_config.dslite_ce)
8737 b4_ip4 = '192.0.0.2'
8738 b4_ip4_n = socket.inet_pton(socket.AF_INET, b4_ip4)
8739 b4_ip6 = '2001:db8:62aa::375e:f4c1:1'
8740 b4_ip6_n = socket.inet_pton(socket.AF_INET6, b4_ip6)
8741 self.vapi.dslite_set_b4_addr(b4_ip6_n, b4_ip4_n)
8743 aftr_ip4 = '192.0.0.1'
8744 aftr_ip4_n = socket.inet_pton(socket.AF_INET, aftr_ip4)
8745 aftr_ip6 = '2001:db8:85a3::8a2e:370:1'
8746 aftr_ip6_n = socket.inet_pton(socket.AF_INET6, aftr_ip6)
8747 self.vapi.dslite_set_aftr_addr(aftr_ip6_n, aftr_ip4_n)
8749 self.vapi.ip_add_del_route(dst_address=aftr_ip6_n,
8750 dst_address_length=128,
8751 next_hop_address=self.pg1.remote_ip6n,
8752 next_hop_sw_if_index=self.pg1.sw_if_index,
8756 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
8757 IP(dst=self.pg1.remote_ip4, src=self.pg0.remote_ip4) /
8758 UDP(sport=10000, dport=20000))
8759 self.pg0.add_stream(p)
8760 self.pg_enable_capture(self.pg_interfaces)
8762 capture = self.pg1.get_capture(1)
8763 capture = capture[0]
8764 self.assertEqual(capture[IPv6].src, b4_ip6)
8765 self.assertEqual(capture[IPv6].dst, aftr_ip6)
8766 self.assertEqual(capture[IP].src, self.pg0.remote_ip4)
8767 self.assertEqual(capture[IP].dst, self.pg1.remote_ip4)
8768 self.assertEqual(capture[UDP].sport, 10000)
8769 self.assertEqual(capture[UDP].dport, 20000)
8770 self.assert_packet_checksums_valid(capture)
8773 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
8774 IPv6(dst=b4_ip6, src=aftr_ip6) /
8775 IP(dst=self.pg0.remote_ip4, src=self.pg1.remote_ip4) /
8776 UDP(sport=20000, dport=10000))
8777 self.pg1.add_stream(p)
8778 self.pg_enable_capture(self.pg_interfaces)
8780 capture = self.pg0.get_capture(1)
8781 capture = capture[0]
8782 self.assertFalse(capture.haslayer(IPv6))
8783 self.assertEqual(capture[IP].src, self.pg1.remote_ip4)
8784 self.assertEqual(capture[IP].dst, self.pg0.remote_ip4)
8785 self.assertEqual(capture[UDP].sport, 20000)
8786 self.assertEqual(capture[UDP].dport, 10000)
8787 self.assert_packet_checksums_valid(capture)
8789 # ping DS-Lite B4 tunnel endpoint address
8790 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
8791 IPv6(src=self.pg1.remote_hosts[0].ip6, dst=b4_ip6) /
8792 ICMPv6EchoRequest())
8793 self.pg1.add_stream(p)
8794 self.pg_enable_capture(self.pg_interfaces)
8796 capture = self.pg1.get_capture(1)
8797 capture = capture[0]
8798 self.assertEqual(capture[IPv6].src, b4_ip6)
8799 self.assertEqual(capture[IPv6].dst, self.pg1.remote_hosts[0].ip6)
8800 self.assertTrue(capture.haslayer(ICMPv6EchoReply))
8803 super(TestDSliteCE, self).tearDown()
8804 if not self.vpp_dead:
8806 self.vapi.cli("show dslite aftr-tunnel-endpoint-address"))
8808 self.vapi.cli("show dslite b4-tunnel-endpoint-address"))
8811 class TestNAT66(MethodHolder):
8812 """ NAT66 Test Cases """
8815 def setUpClass(cls):
8816 super(TestNAT66, cls).setUpClass()
8819 cls.nat_addr = 'fd01:ff::2'
8820 cls.nat_addr_n = socket.inet_pton(socket.AF_INET6, cls.nat_addr)
8822 cls.create_pg_interfaces(range(2))
8823 cls.interfaces = list(cls.pg_interfaces)
8825 for i in cls.interfaces:
8828 i.configure_ipv6_neighbors()
8831 super(TestNAT66, cls).tearDownClass()
8834 def test_static(self):
8835 """ 1:1 NAT66 test """
8836 self.vapi.nat66_add_del_interface(self.pg0.sw_if_index)
8837 self.vapi.nat66_add_del_interface(self.pg1.sw_if_index, is_inside=0)
8838 self.vapi.nat66_add_del_static_mapping(self.pg0.remote_ip6n,
8843 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
8844 IPv6(src=self.pg0.remote_ip6, dst=self.pg1.remote_ip6) /
8847 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
8848 IPv6(src=self.pg0.remote_ip6, dst=self.pg1.remote_ip6) /
8851 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
8852 IPv6(src=self.pg0.remote_ip6, dst=self.pg1.remote_ip6) /
8853 ICMPv6EchoRequest())
8855 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
8856 IPv6(src=self.pg0.remote_ip6, dst=self.pg1.remote_ip6) /
8857 GRE() / IP() / TCP())
8859 self.pg0.add_stream(pkts)
8860 self.pg_enable_capture(self.pg_interfaces)
8862 capture = self.pg1.get_capture(len(pkts))
8863 for packet in capture:
8865 self.assertEqual(packet[IPv6].src, self.nat_addr)
8866 self.assertEqual(packet[IPv6].dst, self.pg1.remote_ip6)
8867 self.assert_packet_checksums_valid(packet)
8869 self.logger.error(ppp("Unexpected or invalid packet:", packet))
8874 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
8875 IPv6(src=self.pg1.remote_ip6, dst=self.nat_addr) /
8878 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
8879 IPv6(src=self.pg1.remote_ip6, dst=self.nat_addr) /
8882 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
8883 IPv6(src=self.pg1.remote_ip6, dst=self.nat_addr) /
8886 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
8887 IPv6(src=self.pg1.remote_ip6, dst=self.nat_addr) /
8888 GRE() / IP() / TCP())
8890 self.pg1.add_stream(pkts)
8891 self.pg_enable_capture(self.pg_interfaces)
8893 capture = self.pg0.get_capture(len(pkts))
8894 for packet in capture:
8896 self.assertEqual(packet[IPv6].src, self.pg1.remote_ip6)
8897 self.assertEqual(packet[IPv6].dst, self.pg0.remote_ip6)
8898 self.assert_packet_checksums_valid(packet)
8900 self.logger.error(ppp("Unexpected or invalid packet:", packet))
8903 sm = self.vapi.nat66_static_mapping_dump()
8904 self.assertEqual(len(sm), 1)
8905 self.assertEqual(sm[0].total_pkts, 8)
8907 def test_check_no_translate(self):
8908 """ NAT66 translate only when egress interface is outside interface """
8909 self.vapi.nat66_add_del_interface(self.pg0.sw_if_index)
8910 self.vapi.nat66_add_del_interface(self.pg1.sw_if_index)
8911 self.vapi.nat66_add_del_static_mapping(self.pg0.remote_ip6n,
8915 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
8916 IPv6(src=self.pg0.remote_ip6, dst=self.pg1.remote_ip6) /
8918 self.pg0.add_stream([p])
8919 self.pg_enable_capture(self.pg_interfaces)
8921 capture = self.pg1.get_capture(1)
8924 self.assertEqual(packet[IPv6].src, self.pg0.remote_ip6)
8925 self.assertEqual(packet[IPv6].dst, self.pg1.remote_ip6)
8927 self.logger.error(ppp("Unexpected or invalid packet:", packet))
8930 def clear_nat66(self):
8932 Clear NAT66 configuration.
8934 interfaces = self.vapi.nat66_interface_dump()
8935 for intf in interfaces:
8936 self.vapi.nat66_add_del_interface(intf.sw_if_index,
8940 static_mappings = self.vapi.nat66_static_mapping_dump()
8941 for sm in static_mappings:
8942 self.vapi.nat66_add_del_static_mapping(sm.local_ip_address,
8943 sm.external_ip_address,
8948 super(TestNAT66, self).tearDown()
8949 if not self.vpp_dead:
8950 self.logger.info(self.vapi.cli("show nat66 interfaces"))
8951 self.logger.info(self.vapi.cli("show nat66 static mappings"))
8955 if __name__ == '__main__':
8956 unittest.main(testRunner=VppTestRunner)