8 from framework import VppTestCase, VppTestRunner, running_extended_tests
9 from scapy.layers.inet import IP, TCP, UDP, ICMP
10 from scapy.layers.inet import IPerror, TCPerror, UDPerror, ICMPerror
11 from scapy.layers.inet6 import IPv6, ICMPv6EchoRequest, ICMPv6EchoReply, \
12 ICMPv6ND_NS, ICMPv6ND_NA, ICMPv6NDOptDstLLAddr, fragment6
13 from scapy.layers.inet6 import ICMPv6DestUnreach, IPerror6, IPv6ExtHdrFragment
14 from scapy.layers.l2 import Ether, ARP, GRE
15 from scapy.data import IP_PROTOS
16 from scapy.packet import bind_layers, Raw
18 from ipfix import IPFIX, Set, Template, Data, IPFIXDecoder
19 from time import sleep
20 from util import ip4_range
21 from vpp_papi import mac_pton
22 from syslog_rfc5424_parser import SyslogMessage, ParseError
23 from syslog_rfc5424_parser.constants import SyslogFacility, SyslogSeverity
24 from vpp_papi_provider import SYSLOG_SEVERITY
25 from io import BytesIO
28 class MethodHolder(VppTestCase):
29 """ NAT create capture and verify method holder """
31 def clear_nat44(self):
33 Clear NAT44 configuration.
35 if hasattr(self, 'pg7') and hasattr(self, 'pg8'):
36 # I found no elegant way to do this
37 self.vapi.ip_add_del_route(
38 dst_address=self.pg7.remote_ip4n,
39 dst_address_length=32,
40 next_hop_address=self.pg7.remote_ip4n,
41 next_hop_sw_if_index=self.pg7.sw_if_index,
43 self.vapi.ip_add_del_route(
44 dst_address=self.pg8.remote_ip4n,
45 dst_address_length=32,
46 next_hop_address=self.pg8.remote_ip4n,
47 next_hop_sw_if_index=self.pg8.sw_if_index,
50 for intf in [self.pg7, self.pg8]:
51 neighbors = self.vapi.ip_neighbor_dump(intf.sw_if_index)
53 self.vapi.ip_neighbor_add_del(intf.sw_if_index,
58 if self.pg7.has_ip4_config:
59 self.pg7.unconfig_ip4()
61 self.vapi.nat44_forwarding_enable_disable(0)
63 interfaces = self.vapi.nat44_interface_addr_dump()
64 for intf in interfaces:
65 self.vapi.nat44_add_interface_addr(intf.sw_if_index,
66 twice_nat=intf.twice_nat,
69 self.vapi.nat_ipfix(enable=0, src_port=self.ipfix_src_port,
70 domain_id=self.ipfix_domain_id)
71 self.ipfix_src_port = 4739
72 self.ipfix_domain_id = 1
74 self.vapi.syslog_set_filter(SYSLOG_SEVERITY.EMERG)
76 interfaces = self.vapi.nat44_interface_dump()
77 for intf in interfaces:
78 if intf.is_inside > 1:
79 self.vapi.nat44_interface_add_del_feature(intf.sw_if_index,
82 self.vapi.nat44_interface_add_del_feature(intf.sw_if_index,
86 interfaces = self.vapi.nat44_interface_output_feature_dump()
87 for intf in interfaces:
88 self.vapi.nat44_interface_add_del_output_feature(intf.sw_if_index,
92 static_mappings = self.vapi.nat44_static_mapping_dump()
93 for sm in static_mappings:
94 self.vapi.nat44_add_del_static_mapping(
96 sm.external_ip_address,
97 local_port=sm.local_port,
98 external_port=sm.external_port,
99 addr_only=sm.addr_only,
101 protocol=sm.protocol,
102 twice_nat=sm.twice_nat,
103 self_twice_nat=sm.self_twice_nat,
104 out2in_only=sm.out2in_only,
106 external_sw_if_index=sm.external_sw_if_index,
109 lb_static_mappings = self.vapi.nat44_lb_static_mapping_dump()
110 for lb_sm in lb_static_mappings:
111 self.vapi.nat44_add_del_lb_static_mapping(
115 twice_nat=lb_sm.twice_nat,
116 self_twice_nat=lb_sm.self_twice_nat,
117 out2in_only=lb_sm.out2in_only,
123 identity_mappings = self.vapi.nat44_identity_mapping_dump()
124 for id_m in identity_mappings:
125 self.vapi.nat44_add_del_identity_mapping(
126 addr_only=id_m.addr_only,
129 sw_if_index=id_m.sw_if_index,
131 protocol=id_m.protocol,
134 adresses = self.vapi.nat44_address_dump()
135 for addr in adresses:
136 self.vapi.nat44_add_del_address_range(addr.ip_address,
138 twice_nat=addr.twice_nat,
141 self.vapi.nat_set_reass()
142 self.vapi.nat_set_reass(is_ip6=1)
143 self.verify_no_nat44_user()
144 self.vapi.nat_set_timeouts()
145 self.vapi.nat_set_addr_and_port_alloc_alg()
146 self.vapi.nat_set_mss_clamping()
148 def nat44_add_static_mapping(self, local_ip, external_ip='0.0.0.0',
149 local_port=0, external_port=0, vrf_id=0,
150 is_add=1, external_sw_if_index=0xFFFFFFFF,
151 proto=0, twice_nat=0, self_twice_nat=0,
152 out2in_only=0, tag=""):
154 Add/delete NAT44 static mapping
156 :param local_ip: Local IP address
157 :param external_ip: External IP address
158 :param local_port: Local port number (Optional)
159 :param external_port: External port number (Optional)
160 :param vrf_id: VRF ID (Default 0)
161 :param is_add: 1 if add, 0 if delete (Default add)
162 :param external_sw_if_index: External interface instead of IP address
163 :param proto: IP protocol (Mandatory if port specified)
164 :param twice_nat: 1 if translate external host address and port
165 :param self_twice_nat: 1 if translate external host address and port
166 whenever external host address equals
167 local address of internal host
168 :param out2in_only: if 1 rule is matching only out2in direction
169 :param tag: Opaque string tag
172 if local_port and external_port:
174 l_ip = socket.inet_pton(socket.AF_INET, local_ip)
175 e_ip = socket.inet_pton(socket.AF_INET, external_ip)
176 self.vapi.nat44_add_del_static_mapping(
179 external_sw_if_index,
191 def nat44_add_address(self, ip, is_add=1, vrf_id=0xFFFFFFFF, twice_nat=0):
193 Add/delete NAT44 address
195 :param ip: IP address
196 :param is_add: 1 if add, 0 if delete (Default add)
197 :param twice_nat: twice NAT address for extenal hosts
199 nat_addr = socket.inet_pton(socket.AF_INET, ip)
200 self.vapi.nat44_add_del_address_range(nat_addr, nat_addr, is_add,
204 def create_stream_in(self, in_if, out_if, dst_ip=None, ttl=64):
206 Create packet stream for inside network
208 :param in_if: Inside interface
209 :param out_if: Outside interface
210 :param dst_ip: Destination address
211 :param ttl: TTL of generated packets
214 dst_ip = out_if.remote_ip4
218 p = (Ether(dst=in_if.local_mac, src=in_if.remote_mac) /
219 IP(src=in_if.remote_ip4, dst=dst_ip, ttl=ttl) /
220 TCP(sport=self.tcp_port_in, dport=20))
224 p = (Ether(dst=in_if.local_mac, src=in_if.remote_mac) /
225 IP(src=in_if.remote_ip4, dst=dst_ip, ttl=ttl) /
226 UDP(sport=self.udp_port_in, dport=20))
230 p = (Ether(dst=in_if.local_mac, src=in_if.remote_mac) /
231 IP(src=in_if.remote_ip4, dst=dst_ip, ttl=ttl) /
232 ICMP(id=self.icmp_id_in, type='echo-request'))
237 def compose_ip6(self, ip4, pref, plen):
239 Compose IPv4-embedded IPv6 addresses
241 :param ip4: IPv4 address
242 :param pref: IPv6 prefix
243 :param plen: IPv6 prefix length
244 :returns: IPv4-embedded IPv6 addresses
246 pref_n = list(socket.inet_pton(socket.AF_INET6, pref))
247 ip4_n = list(socket.inet_pton(socket.AF_INET, ip4))
262 pref_n[10] = ip4_n[3]
266 pref_n[10] = ip4_n[2]
267 pref_n[11] = ip4_n[3]
270 pref_n[10] = ip4_n[1]
271 pref_n[11] = ip4_n[2]
272 pref_n[12] = ip4_n[3]
274 pref_n[12] = ip4_n[0]
275 pref_n[13] = ip4_n[1]
276 pref_n[14] = ip4_n[2]
277 pref_n[15] = ip4_n[3]
278 return socket.inet_ntop(socket.AF_INET6, ''.join(pref_n))
280 def extract_ip4(self, ip6, plen):
282 Extract IPv4 address embedded in IPv6 addresses
284 :param ip6: IPv6 address
285 :param plen: IPv6 prefix length
286 :returns: extracted IPv4 address
288 ip6_n = list(socket.inet_pton(socket.AF_INET6, ip6))
320 return socket.inet_ntop(socket.AF_INET, ''.join(ip4_n))
322 def create_stream_in_ip6(self, in_if, out_if, hlim=64, pref=None, plen=0):
324 Create IPv6 packet stream for inside network
326 :param in_if: Inside interface
327 :param out_if: Outside interface
328 :param ttl: Hop Limit of generated packets
329 :param pref: NAT64 prefix
330 :param plen: NAT64 prefix length
334 dst = ''.join(['64:ff9b::', out_if.remote_ip4])
336 dst = self.compose_ip6(out_if.remote_ip4, pref, plen)
339 p = (Ether(dst=in_if.local_mac, src=in_if.remote_mac) /
340 IPv6(src=in_if.remote_ip6, dst=dst, hlim=hlim) /
341 TCP(sport=self.tcp_port_in, dport=20))
345 p = (Ether(dst=in_if.local_mac, src=in_if.remote_mac) /
346 IPv6(src=in_if.remote_ip6, dst=dst, hlim=hlim) /
347 UDP(sport=self.udp_port_in, dport=20))
351 p = (Ether(dst=in_if.local_mac, src=in_if.remote_mac) /
352 IPv6(src=in_if.remote_ip6, dst=dst, hlim=hlim) /
353 ICMPv6EchoRequest(id=self.icmp_id_in))
358 def create_stream_out(self, out_if, dst_ip=None, ttl=64,
359 use_inside_ports=False):
361 Create packet stream for outside network
363 :param out_if: Outside interface
364 :param dst_ip: Destination IP address (Default use global NAT address)
365 :param ttl: TTL of generated packets
366 :param use_inside_ports: Use inside NAT ports as destination ports
367 instead of outside ports
370 dst_ip = self.nat_addr
371 if not use_inside_ports:
372 tcp_port = self.tcp_port_out
373 udp_port = self.udp_port_out
374 icmp_id = self.icmp_id_out
376 tcp_port = self.tcp_port_in
377 udp_port = self.udp_port_in
378 icmp_id = self.icmp_id_in
381 p = (Ether(dst=out_if.local_mac, src=out_if.remote_mac) /
382 IP(src=out_if.remote_ip4, dst=dst_ip, ttl=ttl) /
383 TCP(dport=tcp_port, sport=20))
387 p = (Ether(dst=out_if.local_mac, src=out_if.remote_mac) /
388 IP(src=out_if.remote_ip4, dst=dst_ip, ttl=ttl) /
389 UDP(dport=udp_port, sport=20))
393 p = (Ether(dst=out_if.local_mac, src=out_if.remote_mac) /
394 IP(src=out_if.remote_ip4, dst=dst_ip, ttl=ttl) /
395 ICMP(id=icmp_id, type='echo-reply'))
400 def create_stream_out_ip6(self, out_if, src_ip, dst_ip, hl=64):
402 Create packet stream for outside network
404 :param out_if: Outside interface
405 :param dst_ip: Destination IP address (Default use global NAT address)
406 :param hl: HL of generated packets
410 p = (Ether(dst=out_if.local_mac, src=out_if.remote_mac) /
411 IPv6(src=src_ip, dst=dst_ip, hlim=hl) /
412 TCP(dport=self.tcp_port_out, sport=20))
416 p = (Ether(dst=out_if.local_mac, src=out_if.remote_mac) /
417 IPv6(src=src_ip, dst=dst_ip, hlim=hl) /
418 UDP(dport=self.udp_port_out, sport=20))
422 p = (Ether(dst=out_if.local_mac, src=out_if.remote_mac) /
423 IPv6(src=src_ip, dst=dst_ip, hlim=hl) /
424 ICMPv6EchoReply(id=self.icmp_id_out))
429 def verify_capture_out(self, capture, nat_ip=None, same_port=False,
430 dst_ip=None, is_ip6=False):
432 Verify captured packets on outside network
434 :param capture: Captured packets
435 :param nat_ip: Translated IP address (Default use global NAT address)
436 :param same_port: Sorce port number is not translated (Default False)
437 :param dst_ip: Destination IP address (Default do not verify)
438 :param is_ip6: If L3 protocol is IPv6 (Default False)
442 ICMP46 = ICMPv6EchoRequest
447 nat_ip = self.nat_addr
448 for packet in capture:
451 self.assert_packet_checksums_valid(packet)
452 self.assertEqual(packet[IP46].src, nat_ip)
453 if dst_ip is not None:
454 self.assertEqual(packet[IP46].dst, dst_ip)
455 if packet.haslayer(TCP):
457 self.assertEqual(packet[TCP].sport, self.tcp_port_in)
460 packet[TCP].sport, self.tcp_port_in)
461 self.tcp_port_out = packet[TCP].sport
462 self.assert_packet_checksums_valid(packet)
463 elif packet.haslayer(UDP):
465 self.assertEqual(packet[UDP].sport, self.udp_port_in)
468 packet[UDP].sport, self.udp_port_in)
469 self.udp_port_out = packet[UDP].sport
472 self.assertEqual(packet[ICMP46].id, self.icmp_id_in)
474 self.assertNotEqual(packet[ICMP46].id, self.icmp_id_in)
475 self.icmp_id_out = packet[ICMP46].id
476 self.assert_packet_checksums_valid(packet)
478 self.logger.error(ppp("Unexpected or invalid packet "
479 "(outside network):", packet))
482 def verify_capture_out_ip6(self, capture, nat_ip, same_port=False,
485 Verify captured packets on outside network
487 :param capture: Captured packets
488 :param nat_ip: Translated IP address
489 :param same_port: Sorce port number is not translated (Default False)
490 :param dst_ip: Destination IP address (Default do not verify)
492 return self.verify_capture_out(capture, nat_ip, same_port, dst_ip,
495 def verify_capture_in(self, capture, in_if):
497 Verify captured packets on inside network
499 :param capture: Captured packets
500 :param in_if: Inside interface
502 for packet in capture:
504 self.assert_packet_checksums_valid(packet)
505 self.assertEqual(packet[IP].dst, in_if.remote_ip4)
506 if packet.haslayer(TCP):
507 self.assertEqual(packet[TCP].dport, self.tcp_port_in)
508 elif packet.haslayer(UDP):
509 self.assertEqual(packet[UDP].dport, self.udp_port_in)
511 self.assertEqual(packet[ICMP].id, self.icmp_id_in)
513 self.logger.error(ppp("Unexpected or invalid packet "
514 "(inside network):", packet))
517 def verify_capture_in_ip6(self, capture, src_ip, dst_ip):
519 Verify captured IPv6 packets on inside network
521 :param capture: Captured packets
522 :param src_ip: Source IP
523 :param dst_ip: Destination IP address
525 for packet in capture:
527 self.assertEqual(packet[IPv6].src, src_ip)
528 self.assertEqual(packet[IPv6].dst, dst_ip)
529 self.assert_packet_checksums_valid(packet)
530 if packet.haslayer(TCP):
531 self.assertEqual(packet[TCP].dport, self.tcp_port_in)
532 elif packet.haslayer(UDP):
533 self.assertEqual(packet[UDP].dport, self.udp_port_in)
535 self.assertEqual(packet[ICMPv6EchoReply].id,
538 self.logger.error(ppp("Unexpected or invalid packet "
539 "(inside network):", packet))
542 def verify_capture_no_translation(self, capture, ingress_if, egress_if):
544 Verify captured packet that don't have to be translated
546 :param capture: Captured packets
547 :param ingress_if: Ingress interface
548 :param egress_if: Egress interface
550 for packet in capture:
552 self.assertEqual(packet[IP].src, ingress_if.remote_ip4)
553 self.assertEqual(packet[IP].dst, egress_if.remote_ip4)
554 if packet.haslayer(TCP):
555 self.assertEqual(packet[TCP].sport, self.tcp_port_in)
556 elif packet.haslayer(UDP):
557 self.assertEqual(packet[UDP].sport, 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_out_with_icmp_errors(self, capture, src_ip=None,
568 Verify captured packets with ICMP errors on outside network
570 :param capture: Captured packets
571 :param src_ip: Translated IP address or IP address of VPP
572 (Default use global NAT address)
573 :param icmp_type: Type of error ICMP packet
574 we are expecting (Default 11)
577 src_ip = self.nat_addr
578 for packet in capture:
580 self.assertEqual(packet[IP].src, src_ip)
581 self.assertEqual(packet.haslayer(ICMP), 1)
583 self.assertEqual(icmp.type, icmp_type)
584 self.assertTrue(icmp.haslayer(IPerror))
585 inner_ip = icmp[IPerror]
586 if inner_ip.haslayer(TCPerror):
587 self.assertEqual(inner_ip[TCPerror].dport,
589 elif inner_ip.haslayer(UDPerror):
590 self.assertEqual(inner_ip[UDPerror].dport,
593 self.assertEqual(inner_ip[ICMPerror].id, self.icmp_id_out)
595 self.logger.error(ppp("Unexpected or invalid packet "
596 "(outside network):", packet))
599 def verify_capture_in_with_icmp_errors(self, capture, in_if, icmp_type=11):
601 Verify captured packets with ICMP errors on inside network
603 :param capture: Captured packets
604 :param in_if: Inside interface
605 :param icmp_type: Type of error ICMP packet
606 we are expecting (Default 11)
608 for packet in capture:
610 self.assertEqual(packet[IP].dst, in_if.remote_ip4)
611 self.assertEqual(packet.haslayer(ICMP), 1)
613 self.assertEqual(icmp.type, icmp_type)
614 self.assertTrue(icmp.haslayer(IPerror))
615 inner_ip = icmp[IPerror]
616 if inner_ip.haslayer(TCPerror):
617 self.assertEqual(inner_ip[TCPerror].sport,
619 elif inner_ip.haslayer(UDPerror):
620 self.assertEqual(inner_ip[UDPerror].sport,
623 self.assertEqual(inner_ip[ICMPerror].id, self.icmp_id_in)
625 self.logger.error(ppp("Unexpected or invalid packet "
626 "(inside network):", packet))
629 def create_stream_frag(self, src_if, dst, sport, dport, data,
630 proto=IP_PROTOS.tcp, echo_reply=False):
632 Create fragmented packet stream
634 :param src_if: Source interface
635 :param dst: Destination IPv4 address
636 :param sport: Source port
637 :param dport: Destination port
638 :param data: Payload data
639 :param proto: protocol (TCP, UDP, ICMP)
640 :param echo_reply: use echo_reply if protocol is ICMP
643 if proto == IP_PROTOS.tcp:
644 p = (IP(src=src_if.remote_ip4, dst=dst) /
645 TCP(sport=sport, dport=dport) /
647 p = p.__class__(str(p))
648 chksum = p['TCP'].chksum
649 proto_header = TCP(sport=sport, dport=dport, chksum=chksum)
650 elif proto == IP_PROTOS.udp:
651 proto_header = UDP(sport=sport, dport=dport)
652 elif proto == IP_PROTOS.icmp:
654 proto_header = ICMP(id=sport, type='echo-request')
656 proto_header = ICMP(id=sport, type='echo-reply')
658 raise Exception("Unsupported protocol")
659 id = random.randint(0, 65535)
661 if proto == IP_PROTOS.tcp:
664 raw = Raw(data[0:16])
665 p = (Ether(src=src_if.remote_mac, dst=src_if.local_mac) /
666 IP(src=src_if.remote_ip4, dst=dst, flags="MF", frag=0, id=id) /
670 if proto == IP_PROTOS.tcp:
671 raw = Raw(data[4:20])
673 raw = Raw(data[16:32])
674 p = (Ether(src=src_if.remote_mac, dst=src_if.local_mac) /
675 IP(src=src_if.remote_ip4, dst=dst, flags="MF", frag=3, id=id,
679 if proto == IP_PROTOS.tcp:
683 p = (Ether(src=src_if.remote_mac, dst=src_if.local_mac) /
684 IP(src=src_if.remote_ip4, dst=dst, frag=5, proto=proto,
690 def create_stream_frag_ip6(self, src_if, dst, sport, dport, data,
691 pref=None, plen=0, frag_size=128):
693 Create fragmented packet stream
695 :param src_if: Source interface
696 :param dst: Destination IPv4 address
697 :param sport: Source TCP port
698 :param dport: Destination TCP port
699 :param data: Payload data
700 :param pref: NAT64 prefix
701 :param plen: NAT64 prefix length
702 :param fragsize: size of fragments
706 dst_ip6 = ''.join(['64:ff9b::', dst])
708 dst_ip6 = self.compose_ip6(dst, pref, plen)
710 p = (Ether(dst=src_if.local_mac, src=src_if.remote_mac) /
711 IPv6(src=src_if.remote_ip6, dst=dst_ip6) /
712 IPv6ExtHdrFragment(id=random.randint(0, 65535)) /
713 TCP(sport=sport, dport=dport) /
716 return fragment6(p, frag_size)
718 def reass_frags_and_verify(self, frags, src, dst):
720 Reassemble and verify fragmented packet
722 :param frags: Captured fragments
723 :param src: Source IPv4 address to verify
724 :param dst: Destination IPv4 address to verify
726 :returns: Reassembled IPv4 packet
730 self.assertEqual(p[IP].src, src)
731 self.assertEqual(p[IP].dst, dst)
732 self.assert_ip_checksum_valid(p)
733 buffer.seek(p[IP].frag * 8)
734 buffer.write(bytes(p[IP].payload))
735 ip = IP(src=frags[0][IP].src, dst=frags[0][IP].dst,
736 proto=frags[0][IP].proto)
737 if ip.proto == IP_PROTOS.tcp:
738 p = (ip / TCP(buffer.getvalue()))
739 self.assert_tcp_checksum_valid(p)
740 elif ip.proto == IP_PROTOS.udp:
741 p = (ip / UDP(buffer.getvalue()[:8]) /
742 Raw(buffer.getvalue()[8:]))
743 elif ip.proto == IP_PROTOS.icmp:
744 p = (ip / ICMP(buffer.getvalue()))
747 def reass_frags_and_verify_ip6(self, frags, src, dst):
749 Reassemble and verify fragmented packet
751 :param frags: Captured fragments
752 :param src: Source IPv6 address to verify
753 :param dst: Destination IPv6 address to verify
755 :returns: Reassembled IPv6 packet
759 self.assertEqual(p[IPv6].src, src)
760 self.assertEqual(p[IPv6].dst, dst)
761 buffer.seek(p[IPv6ExtHdrFragment].offset * 8)
762 buffer.write(bytes(p[IPv6ExtHdrFragment].payload))
763 ip = IPv6(src=frags[0][IPv6].src, dst=frags[0][IPv6].dst,
764 nh=frags[0][IPv6ExtHdrFragment].nh)
765 if ip.nh == IP_PROTOS.tcp:
766 p = (ip / TCP(buffer.getvalue()))
767 elif ip.nh == IP_PROTOS.udp:
768 p = (ip / UDP(buffer.getvalue()))
769 self.assert_packet_checksums_valid(p)
772 def initiate_tcp_session(self, in_if, out_if):
774 Initiates TCP session
776 :param in_if: Inside interface
777 :param out_if: Outside interface
781 p = (Ether(src=in_if.remote_mac, dst=in_if.local_mac) /
782 IP(src=in_if.remote_ip4, dst=out_if.remote_ip4) /
783 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
786 self.pg_enable_capture(self.pg_interfaces)
788 capture = out_if.get_capture(1)
790 self.tcp_port_out = p[TCP].sport
792 # SYN + ACK packet out->in
793 p = (Ether(src=out_if.remote_mac, dst=out_if.local_mac) /
794 IP(src=out_if.remote_ip4, dst=self.nat_addr) /
795 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
798 self.pg_enable_capture(self.pg_interfaces)
803 p = (Ether(src=in_if.remote_mac, dst=in_if.local_mac) /
804 IP(src=in_if.remote_ip4, dst=out_if.remote_ip4) /
805 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
808 self.pg_enable_capture(self.pg_interfaces)
810 out_if.get_capture(1)
813 self.logger.error("TCP 3 way handshake failed")
816 def verify_ipfix_nat44_ses(self, data):
818 Verify IPFIX NAT44 session create/delete event
820 :param data: Decoded IPFIX data records
822 nat44_ses_create_num = 0
823 nat44_ses_delete_num = 0
824 self.assertEqual(6, len(data))
827 self.assertIn(ord(record[230]), [4, 5])
828 if ord(record[230]) == 4:
829 nat44_ses_create_num += 1
831 nat44_ses_delete_num += 1
833 self.assertEqual(self.pg0.remote_ip4n, record[8])
834 # postNATSourceIPv4Address
835 self.assertEqual(socket.inet_pton(socket.AF_INET, self.nat_addr),
838 self.assertEqual(struct.pack("!I", 0), record[234])
839 # protocolIdentifier/sourceTransportPort/postNAPTSourceTransportPort
840 if IP_PROTOS.icmp == ord(record[4]):
841 self.assertEqual(struct.pack("!H", self.icmp_id_in), record[7])
842 self.assertEqual(struct.pack("!H", self.icmp_id_out),
844 elif IP_PROTOS.tcp == ord(record[4]):
845 self.assertEqual(struct.pack("!H", self.tcp_port_in),
847 self.assertEqual(struct.pack("!H", self.tcp_port_out),
849 elif IP_PROTOS.udp == ord(record[4]):
850 self.assertEqual(struct.pack("!H", self.udp_port_in),
852 self.assertEqual(struct.pack("!H", self.udp_port_out),
855 self.fail("Invalid protocol")
856 self.assertEqual(3, nat44_ses_create_num)
857 self.assertEqual(3, nat44_ses_delete_num)
859 def verify_ipfix_addr_exhausted(self, data):
861 Verify IPFIX NAT addresses event
863 :param data: Decoded IPFIX data records
865 self.assertEqual(1, len(data))
868 self.assertEqual(ord(record[230]), 3)
870 self.assertEqual(struct.pack("!I", 0), record[283])
872 def verify_ipfix_max_sessions(self, data, limit):
874 Verify IPFIX maximum session entries exceeded event
876 :param data: Decoded IPFIX data records
877 :param limit: Number of maximum session entries that can be created.
879 self.assertEqual(1, len(data))
882 self.assertEqual(ord(record[230]), 13)
883 # natQuotaExceededEvent
884 self.assertEqual(struct.pack("I", 1), record[466])
886 self.assertEqual(struct.pack("I", limit), record[471])
888 def verify_ipfix_max_bibs(self, data, limit):
890 Verify IPFIX maximum BIB entries exceeded event
892 :param data: Decoded IPFIX data records
893 :param limit: Number of maximum BIB entries that can be created.
895 self.assertEqual(1, len(data))
898 self.assertEqual(ord(record[230]), 13)
899 # natQuotaExceededEvent
900 self.assertEqual(struct.pack("I", 2), record[466])
902 self.assertEqual(struct.pack("I", limit), record[472])
904 def verify_ipfix_max_fragments_ip6(self, data, limit, src_addr):
906 Verify IPFIX maximum IPv6 fragments pending reassembly exceeded event
908 :param data: Decoded IPFIX data records
909 :param limit: Number of maximum fragments pending reassembly
910 :param src_addr: IPv6 source address
912 self.assertEqual(1, len(data))
915 self.assertEqual(ord(record[230]), 13)
916 # natQuotaExceededEvent
917 self.assertEqual(struct.pack("I", 5), record[466])
918 # maxFragmentsPendingReassembly
919 self.assertEqual(struct.pack("I", limit), record[475])
921 self.assertEqual(src_addr, record[27])
923 def verify_ipfix_max_fragments_ip4(self, data, limit, src_addr):
925 Verify IPFIX maximum IPv4 fragments pending reassembly exceeded event
927 :param data: Decoded IPFIX data records
928 :param limit: Number of maximum fragments pending reassembly
929 :param src_addr: IPv4 source address
931 self.assertEqual(1, len(data))
934 self.assertEqual(ord(record[230]), 13)
935 # natQuotaExceededEvent
936 self.assertEqual(struct.pack("I", 5), record[466])
937 # maxFragmentsPendingReassembly
938 self.assertEqual(struct.pack("I", limit), record[475])
940 self.assertEqual(src_addr, record[8])
942 def verify_ipfix_bib(self, data, is_create, src_addr):
944 Verify IPFIX NAT64 BIB create and delete events
946 :param data: Decoded IPFIX data records
947 :param is_create: Create event if nonzero value otherwise delete event
948 :param src_addr: IPv6 source address
950 self.assertEqual(1, len(data))
954 self.assertEqual(ord(record[230]), 10)
956 self.assertEqual(ord(record[230]), 11)
958 self.assertEqual(src_addr, record[27])
959 # postNATSourceIPv4Address
960 self.assertEqual(self.nat_addr_n, record[225])
962 self.assertEqual(IP_PROTOS.tcp, ord(record[4]))
964 self.assertEqual(struct.pack("!I", 0), record[234])
965 # sourceTransportPort
966 self.assertEqual(struct.pack("!H", self.tcp_port_in), record[7])
967 # postNAPTSourceTransportPort
968 self.assertEqual(struct.pack("!H", self.tcp_port_out), record[227])
970 def verify_ipfix_nat64_ses(self, data, is_create, src_addr, dst_addr,
973 Verify IPFIX NAT64 session create and delete events
975 :param data: Decoded IPFIX data records
976 :param is_create: Create event if nonzero value otherwise delete event
977 :param src_addr: IPv6 source address
978 :param dst_addr: IPv4 destination address
979 :param dst_port: destination TCP port
981 self.assertEqual(1, len(data))
985 self.assertEqual(ord(record[230]), 6)
987 self.assertEqual(ord(record[230]), 7)
989 self.assertEqual(src_addr, record[27])
990 # destinationIPv6Address
991 self.assertEqual(socket.inet_pton(socket.AF_INET6,
992 self.compose_ip6(dst_addr,
996 # postNATSourceIPv4Address
997 self.assertEqual(self.nat_addr_n, record[225])
998 # postNATDestinationIPv4Address
999 self.assertEqual(socket.inet_pton(socket.AF_INET, dst_addr),
1001 # protocolIdentifier
1002 self.assertEqual(IP_PROTOS.tcp, ord(record[4]))
1004 self.assertEqual(struct.pack("!I", 0), record[234])
1005 # sourceTransportPort
1006 self.assertEqual(struct.pack("!H", self.tcp_port_in), record[7])
1007 # postNAPTSourceTransportPort
1008 self.assertEqual(struct.pack("!H", self.tcp_port_out), record[227])
1009 # destinationTransportPort
1010 self.assertEqual(struct.pack("!H", dst_port), record[11])
1011 # postNAPTDestinationTransportPort
1012 self.assertEqual(struct.pack("!H", dst_port), record[228])
1014 def verify_no_nat44_user(self):
1015 """ Verify that there is no NAT44 user """
1016 users = self.vapi.nat44_user_dump()
1017 self.assertEqual(len(users), 0)
1018 users = self.statistics.get_counter('/nat44/total-users')
1019 self.assertEqual(users[0][0], 0)
1020 sessions = self.statistics.get_counter('/nat44/total-sessions')
1021 self.assertEqual(sessions[0][0], 0)
1023 def verify_ipfix_max_entries_per_user(self, data, limit, src_addr):
1025 Verify IPFIX maximum entries per user exceeded event
1027 :param data: Decoded IPFIX data records
1028 :param limit: Number of maximum entries per user
1029 :param src_addr: IPv4 source address
1031 self.assertEqual(1, len(data))
1034 self.assertEqual(ord(record[230]), 13)
1035 # natQuotaExceededEvent
1036 self.assertEqual(struct.pack("I", 3), record[466])
1038 self.assertEqual(struct.pack("I", limit), record[473])
1040 self.assertEqual(src_addr, record[8])
1042 def verify_syslog_apmap(self, data, is_add=True):
1043 message = data.decode('utf-8')
1045 message = SyslogMessage.parse(message)
1046 except ParseError as e:
1047 self.logger.error(e)
1050 self.assertEqual(message.severity, SyslogSeverity.info)
1051 self.assertEqual(message.appname, 'NAT')
1052 self.assertEqual(message.msgid, 'APMADD' if is_add else 'APMDEL')
1053 sd_params = message.sd.get('napmap')
1054 self.assertTrue(sd_params is not None)
1055 self.assertEqual(sd_params.get('IATYP'), 'IPv4')
1056 self.assertEqual(sd_params.get('ISADDR'), self.pg0.remote_ip4)
1057 self.assertEqual(sd_params.get('ISPORT'), "%d" % self.tcp_port_in)
1058 self.assertEqual(sd_params.get('XATYP'), 'IPv4')
1059 self.assertEqual(sd_params.get('XSADDR'), self.nat_addr)
1060 self.assertEqual(sd_params.get('XSPORT'), "%d" % self.tcp_port_out)
1061 self.assertEqual(sd_params.get('PROTO'), "%d" % IP_PROTOS.tcp)
1062 self.assertTrue(sd_params.get('SSUBIX') is not None)
1063 self.assertEqual(sd_params.get('SVLAN'), '0')
1065 def verify_syslog_sess(self, data, is_add=True, is_ip6=False):
1066 message = data.decode('utf-8')
1068 message = SyslogMessage.parse(message)
1069 except ParseError as e:
1070 self.logger.error(e)
1073 self.assertEqual(message.severity, SyslogSeverity.info)
1074 self.assertEqual(message.appname, 'NAT')
1075 self.assertEqual(message.msgid, 'SADD' if is_add else 'SDEL')
1076 sd_params = message.sd.get('nsess')
1077 self.assertTrue(sd_params is not None)
1079 self.assertEqual(sd_params.get('IATYP'), 'IPv6')
1080 self.assertEqual(sd_params.get('ISADDR'), self.pg0.remote_ip6)
1082 self.assertEqual(sd_params.get('IATYP'), 'IPv4')
1083 self.assertEqual(sd_params.get('ISADDR'), self.pg0.remote_ip4)
1084 self.assertTrue(sd_params.get('SSUBIX') is not None)
1085 self.assertEqual(sd_params.get('ISPORT'), "%d" % self.tcp_port_in)
1086 self.assertEqual(sd_params.get('XATYP'), 'IPv4')
1087 self.assertEqual(sd_params.get('XSADDR'), self.nat_addr)
1088 self.assertEqual(sd_params.get('XSPORT'), "%d" % self.tcp_port_out)
1089 self.assertEqual(sd_params.get('PROTO'), "%d" % IP_PROTOS.tcp)
1090 self.assertEqual(sd_params.get('SVLAN'), '0')
1091 self.assertEqual(sd_params.get('XDADDR'), self.pg1.remote_ip4)
1092 self.assertEqual(sd_params.get('XDPORT'),
1093 "%d" % self.tcp_external_port)
1095 def verify_mss_value(self, pkt, mss):
1097 Verify TCP MSS value
1102 if not pkt.haslayer(IP) or not pkt.haslayer(TCP):
1103 raise TypeError("Not a TCP/IP packet")
1105 for option in pkt[TCP].options:
1106 if option[0] == 'MSS':
1107 self.assertEqual(option[1], mss)
1108 self.assert_tcp_checksum_valid(pkt)
1111 def proto2layer(proto):
1112 if proto == IP_PROTOS.tcp:
1114 elif proto == IP_PROTOS.udp:
1116 elif proto == IP_PROTOS.icmp:
1119 raise Exception("Unsupported protocol")
1121 def frag_in_order(self, proto=IP_PROTOS.tcp, dont_translate=False):
1122 layer = self.proto2layer(proto)
1124 if proto == IP_PROTOS.tcp:
1125 data = "A" * 4 + "B" * 16 + "C" * 3
1127 data = "A" * 16 + "B" * 16 + "C" * 3
1128 self.port_in = random.randint(1025, 65535)
1130 reass = self.vapi.nat_reass_dump()
1131 reass_n_start = len(reass)
1134 pkts = self.create_stream_frag(self.pg0,
1135 self.pg1.remote_ip4,
1140 self.pg0.add_stream(pkts)
1141 self.pg_enable_capture(self.pg_interfaces)
1143 frags = self.pg1.get_capture(len(pkts))
1144 if not dont_translate:
1145 p = self.reass_frags_and_verify(frags,
1147 self.pg1.remote_ip4)
1149 p = self.reass_frags_and_verify(frags,
1150 self.pg0.remote_ip4,
1151 self.pg1.remote_ip4)
1152 if proto != IP_PROTOS.icmp:
1153 if not dont_translate:
1154 self.assertEqual(p[layer].dport, 20)
1155 self.assertNotEqual(p[layer].sport, self.port_in)
1157 self.assertEqual(p[layer].sport, self.port_in)
1159 if not dont_translate:
1160 self.assertNotEqual(p[layer].id, self.port_in)
1162 self.assertEqual(p[layer].id, self.port_in)
1163 self.assertEqual(data, p[Raw].load)
1166 if not dont_translate:
1167 dst_addr = self.nat_addr
1169 dst_addr = self.pg0.remote_ip4
1170 if proto != IP_PROTOS.icmp:
1172 dport = p[layer].sport
1176 pkts = self.create_stream_frag(self.pg1,
1183 self.pg1.add_stream(pkts)
1184 self.pg_enable_capture(self.pg_interfaces)
1186 frags = self.pg0.get_capture(len(pkts))
1187 p = self.reass_frags_and_verify(frags,
1188 self.pg1.remote_ip4,
1189 self.pg0.remote_ip4)
1190 if proto != IP_PROTOS.icmp:
1191 self.assertEqual(p[layer].sport, 20)
1192 self.assertEqual(p[layer].dport, self.port_in)
1194 self.assertEqual(p[layer].id, self.port_in)
1195 self.assertEqual(data, p[Raw].load)
1197 reass = self.vapi.nat_reass_dump()
1198 reass_n_end = len(reass)
1200 self.assertEqual(reass_n_end - reass_n_start, 2)
1202 def frag_in_order_in_plus_out(self, proto=IP_PROTOS.tcp):
1203 layer = self.proto2layer(proto)
1205 if proto == IP_PROTOS.tcp:
1206 data = "A" * 4 + "B" * 16 + "C" * 3
1208 data = "A" * 16 + "B" * 16 + "C" * 3
1209 self.port_in = random.randint(1025, 65535)
1212 reass = self.vapi.nat_reass_dump()
1213 reass_n_start = len(reass)
1216 pkts = self.create_stream_frag(self.pg0,
1217 self.server_out_addr,
1219 self.server_out_port,
1222 self.pg0.add_stream(pkts)
1223 self.pg_enable_capture(self.pg_interfaces)
1225 frags = self.pg1.get_capture(len(pkts))
1226 p = self.reass_frags_and_verify(frags,
1227 self.pg0.remote_ip4,
1228 self.server_in_addr)
1229 if proto != IP_PROTOS.icmp:
1230 self.assertEqual(p[layer].sport, self.port_in)
1231 self.assertEqual(p[layer].dport, self.server_in_port)
1233 self.assertEqual(p[layer].id, self.port_in)
1234 self.assertEqual(data, p[Raw].load)
1237 if proto != IP_PROTOS.icmp:
1238 pkts = self.create_stream_frag(self.pg1,
1239 self.pg0.remote_ip4,
1240 self.server_in_port,
1245 pkts = self.create_stream_frag(self.pg1,
1246 self.pg0.remote_ip4,
1252 self.pg1.add_stream(pkts)
1253 self.pg_enable_capture(self.pg_interfaces)
1255 frags = self.pg0.get_capture(len(pkts))
1256 p = self.reass_frags_and_verify(frags,
1257 self.server_out_addr,
1258 self.pg0.remote_ip4)
1259 if proto != IP_PROTOS.icmp:
1260 self.assertEqual(p[layer].sport, self.server_out_port)
1261 self.assertEqual(p[layer].dport, self.port_in)
1263 self.assertEqual(p[layer].id, self.port_in)
1264 self.assertEqual(data, p[Raw].load)
1266 reass = self.vapi.nat_reass_dump()
1267 reass_n_end = len(reass)
1269 self.assertEqual(reass_n_end - reass_n_start, 2)
1271 def reass_hairpinning(self, proto=IP_PROTOS.tcp):
1272 layer = self.proto2layer(proto)
1274 if proto == IP_PROTOS.tcp:
1275 data = "A" * 4 + "B" * 16 + "C" * 3
1277 data = "A" * 16 + "B" * 16 + "C" * 3
1279 # send packet from host to server
1280 pkts = self.create_stream_frag(self.pg0,
1283 self.server_out_port,
1286 self.pg0.add_stream(pkts)
1287 self.pg_enable_capture(self.pg_interfaces)
1289 frags = self.pg0.get_capture(len(pkts))
1290 p = self.reass_frags_and_verify(frags,
1293 if proto != IP_PROTOS.icmp:
1294 self.assertNotEqual(p[layer].sport, self.host_in_port)
1295 self.assertEqual(p[layer].dport, self.server_in_port)
1297 self.assertNotEqual(p[layer].id, self.host_in_port)
1298 self.assertEqual(data, p[Raw].load)
1300 def frag_out_of_order(self, proto=IP_PROTOS.tcp, dont_translate=False):
1301 layer = self.proto2layer(proto)
1303 if proto == IP_PROTOS.tcp:
1304 data = "A" * 4 + "B" * 16 + "C" * 3
1306 data = "A" * 16 + "B" * 16 + "C" * 3
1307 self.port_in = random.randint(1025, 65535)
1311 pkts = self.create_stream_frag(self.pg0,
1312 self.pg1.remote_ip4,
1318 self.pg0.add_stream(pkts)
1319 self.pg_enable_capture(self.pg_interfaces)
1321 frags = self.pg1.get_capture(len(pkts))
1322 if not dont_translate:
1323 p = self.reass_frags_and_verify(frags,
1325 self.pg1.remote_ip4)
1327 p = self.reass_frags_and_verify(frags,
1328 self.pg0.remote_ip4,
1329 self.pg1.remote_ip4)
1330 if proto != IP_PROTOS.icmp:
1331 if not dont_translate:
1332 self.assertEqual(p[layer].dport, 20)
1333 self.assertNotEqual(p[layer].sport, self.port_in)
1335 self.assertEqual(p[layer].sport, self.port_in)
1337 if not dont_translate:
1338 self.assertNotEqual(p[layer].id, self.port_in)
1340 self.assertEqual(p[layer].id, self.port_in)
1341 self.assertEqual(data, p[Raw].load)
1344 if not dont_translate:
1345 dst_addr = self.nat_addr
1347 dst_addr = self.pg0.remote_ip4
1348 if proto != IP_PROTOS.icmp:
1350 dport = p[layer].sport
1354 pkts = self.create_stream_frag(self.pg1,
1362 self.pg1.add_stream(pkts)
1363 self.pg_enable_capture(self.pg_interfaces)
1365 frags = self.pg0.get_capture(len(pkts))
1366 p = self.reass_frags_and_verify(frags,
1367 self.pg1.remote_ip4,
1368 self.pg0.remote_ip4)
1369 if proto != IP_PROTOS.icmp:
1370 self.assertEqual(p[layer].sport, 20)
1371 self.assertEqual(p[layer].dport, self.port_in)
1373 self.assertEqual(p[layer].id, self.port_in)
1374 self.assertEqual(data, p[Raw].load)
1376 def frag_out_of_order_in_plus_out(self, proto=IP_PROTOS.tcp):
1377 layer = self.proto2layer(proto)
1379 if proto == IP_PROTOS.tcp:
1380 data = "A" * 4 + "B" * 16 + "C" * 3
1382 data = "A" * 16 + "B" * 16 + "C" * 3
1383 self.port_in = random.randint(1025, 65535)
1387 pkts = self.create_stream_frag(self.pg0,
1388 self.server_out_addr,
1390 self.server_out_port,
1394 self.pg0.add_stream(pkts)
1395 self.pg_enable_capture(self.pg_interfaces)
1397 frags = self.pg1.get_capture(len(pkts))
1398 p = self.reass_frags_and_verify(frags,
1399 self.pg0.remote_ip4,
1400 self.server_in_addr)
1401 if proto != IP_PROTOS.icmp:
1402 self.assertEqual(p[layer].dport, self.server_in_port)
1403 self.assertEqual(p[layer].sport, self.port_in)
1404 self.assertEqual(p[layer].dport, self.server_in_port)
1406 self.assertEqual(p[layer].id, self.port_in)
1407 self.assertEqual(data, p[Raw].load)
1410 if proto != IP_PROTOS.icmp:
1411 pkts = self.create_stream_frag(self.pg1,
1412 self.pg0.remote_ip4,
1413 self.server_in_port,
1418 pkts = self.create_stream_frag(self.pg1,
1419 self.pg0.remote_ip4,
1426 self.pg1.add_stream(pkts)
1427 self.pg_enable_capture(self.pg_interfaces)
1429 frags = self.pg0.get_capture(len(pkts))
1430 p = self.reass_frags_and_verify(frags,
1431 self.server_out_addr,
1432 self.pg0.remote_ip4)
1433 if proto != IP_PROTOS.icmp:
1434 self.assertEqual(p[layer].sport, self.server_out_port)
1435 self.assertEqual(p[layer].dport, self.port_in)
1437 self.assertEqual(p[layer].id, self.port_in)
1438 self.assertEqual(data, p[Raw].load)
1441 class TestNAT44(MethodHolder):
1442 """ NAT44 Test Cases """
1445 def setUpClass(cls):
1446 super(TestNAT44, cls).setUpClass()
1447 cls.vapi.cli("set log class nat level debug")
1450 cls.tcp_port_in = 6303
1451 cls.tcp_port_out = 6303
1452 cls.udp_port_in = 6304
1453 cls.udp_port_out = 6304
1454 cls.icmp_id_in = 6305
1455 cls.icmp_id_out = 6305
1456 cls.nat_addr = '10.0.0.3'
1457 cls.nat_addr_n = socket.inet_pton(socket.AF_INET, cls.nat_addr)
1458 cls.ipfix_src_port = 4739
1459 cls.ipfix_domain_id = 1
1460 cls.tcp_external_port = 80
1462 cls.create_pg_interfaces(range(10))
1463 cls.interfaces = list(cls.pg_interfaces[0:4])
1465 for i in cls.interfaces:
1470 cls.pg0.generate_remote_hosts(3)
1471 cls.pg0.configure_ipv4_neighbors()
1473 cls.pg1.generate_remote_hosts(1)
1474 cls.pg1.configure_ipv4_neighbors()
1476 cls.overlapping_interfaces = list(list(cls.pg_interfaces[4:7]))
1477 cls.vapi.ip_table_add_del(10, is_add=1)
1478 cls.vapi.ip_table_add_del(20, is_add=1)
1480 cls.pg4._local_ip4 = "172.16.255.1"
1481 cls.pg4._local_ip4n = socket.inet_pton(socket.AF_INET, i.local_ip4)
1482 cls.pg4._remote_hosts[0]._ip4 = "172.16.255.2"
1483 cls.pg4.set_table_ip4(10)
1484 cls.pg5._local_ip4 = "172.17.255.3"
1485 cls.pg5._local_ip4n = socket.inet_pton(socket.AF_INET, i.local_ip4)
1486 cls.pg5._remote_hosts[0]._ip4 = "172.17.255.4"
1487 cls.pg5.set_table_ip4(10)
1488 cls.pg6._local_ip4 = "172.16.255.1"
1489 cls.pg6._local_ip4n = socket.inet_pton(socket.AF_INET, i.local_ip4)
1490 cls.pg6._remote_hosts[0]._ip4 = "172.16.255.2"
1491 cls.pg6.set_table_ip4(20)
1492 for i in cls.overlapping_interfaces:
1500 cls.pg9.generate_remote_hosts(2)
1501 cls.pg9.config_ip4()
1502 ip_addr_n = socket.inet_pton(socket.AF_INET, "10.0.0.1")
1503 cls.vapi.sw_interface_add_del_address(cls.pg9.sw_if_index,
1507 cls.pg9.resolve_arp()
1508 cls.pg9._remote_hosts[1]._ip4 = cls.pg9._remote_hosts[0]._ip4
1509 cls.pg4._remote_ip4 = cls.pg9._remote_hosts[0]._ip4 = "10.0.0.2"
1510 cls.pg9.resolve_arp()
1513 super(TestNAT44, cls).tearDownClass()
1516 def test_dynamic(self):
1517 """ NAT44 dynamic translation test """
1518 self.nat44_add_address(self.nat_addr)
1519 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
1520 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
1524 tcpn = self.statistics.get_counter(
1525 '/err/nat44-in2out-slowpath/TCP packets')
1526 udpn = self.statistics.get_counter(
1527 '/err/nat44-in2out-slowpath/UDP packets')
1528 icmpn = self.statistics.get_counter(
1529 '/err/nat44-in2out-slowpath/ICMP packets')
1530 totaln = self.statistics.get_counter(
1531 '/err/nat44-in2out-slowpath/good in2out packets processed')
1533 pkts = self.create_stream_in(self.pg0, self.pg1)
1534 self.pg0.add_stream(pkts)
1535 self.pg_enable_capture(self.pg_interfaces)
1537 capture = self.pg1.get_capture(len(pkts))
1538 self.verify_capture_out(capture)
1540 err = self.statistics.get_counter(
1541 '/err/nat44-in2out-slowpath/TCP packets')
1542 self.assertEqual(err - tcpn, 1)
1543 err = self.statistics.get_counter(
1544 '/err/nat44-in2out-slowpath/UDP packets')
1545 self.assertEqual(err - udpn, 1)
1546 err = self.statistics.get_counter(
1547 '/err/nat44-in2out-slowpath/ICMP packets')
1548 self.assertEqual(err - icmpn, 1)
1549 err = self.statistics.get_counter(
1550 '/err/nat44-in2out-slowpath/good in2out packets processed')
1551 self.assertEqual(err - totaln, 3)
1554 tcpn = self.statistics.get_counter('/err/nat44-out2in/TCP packets')
1555 udpn = self.statistics.get_counter('/err/nat44-out2in/UDP packets')
1556 icmpn = self.statistics.get_counter('/err/nat44-out2in/ICMP packets')
1557 totaln = self.statistics.get_counter(
1558 '/err/nat44-out2in/good out2in packets processed')
1560 pkts = self.create_stream_out(self.pg1)
1561 self.pg1.add_stream(pkts)
1562 self.pg_enable_capture(self.pg_interfaces)
1564 capture = self.pg0.get_capture(len(pkts))
1565 self.verify_capture_in(capture, self.pg0)
1567 err = self.statistics.get_counter('/err/nat44-out2in/TCP packets')
1568 self.assertEqual(err - tcpn, 1)
1569 err = self.statistics.get_counter('/err/nat44-out2in/UDP packets')
1570 self.assertEqual(err - udpn, 1)
1571 err = self.statistics.get_counter('/err/nat44-out2in/ICMP packets')
1572 self.assertEqual(err - icmpn, 1)
1573 err = self.statistics.get_counter(
1574 '/err/nat44-out2in/good out2in packets processed')
1575 self.assertEqual(err - totaln, 3)
1577 users = self.statistics.get_counter('/nat44/total-users')
1578 self.assertEqual(users[0][0], 1)
1579 sessions = self.statistics.get_counter('/nat44/total-sessions')
1580 self.assertEqual(sessions[0][0], 3)
1582 def test_dynamic_icmp_errors_in2out_ttl_1(self):
1583 """ NAT44 handling of client packets with TTL=1 """
1585 self.nat44_add_address(self.nat_addr)
1586 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
1587 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
1590 # Client side - generate traffic
1591 pkts = self.create_stream_in(self.pg0, self.pg1, ttl=1)
1592 self.pg0.add_stream(pkts)
1593 self.pg_enable_capture(self.pg_interfaces)
1596 # Client side - verify ICMP type 11 packets
1597 capture = self.pg0.get_capture(len(pkts))
1598 self.verify_capture_in_with_icmp_errors(capture, self.pg0)
1600 def test_dynamic_icmp_errors_out2in_ttl_1(self):
1601 """ NAT44 handling of server packets with TTL=1 """
1603 self.nat44_add_address(self.nat_addr)
1604 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
1605 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
1608 # Client side - create sessions
1609 pkts = self.create_stream_in(self.pg0, self.pg1)
1610 self.pg0.add_stream(pkts)
1611 self.pg_enable_capture(self.pg_interfaces)
1614 # Server side - generate traffic
1615 capture = self.pg1.get_capture(len(pkts))
1616 self.verify_capture_out(capture)
1617 pkts = self.create_stream_out(self.pg1, ttl=1)
1618 self.pg1.add_stream(pkts)
1619 self.pg_enable_capture(self.pg_interfaces)
1622 # Server side - verify ICMP type 11 packets
1623 capture = self.pg1.get_capture(len(pkts))
1624 self.verify_capture_out_with_icmp_errors(capture,
1625 src_ip=self.pg1.local_ip4)
1627 def test_dynamic_icmp_errors_in2out_ttl_2(self):
1628 """ NAT44 handling of error responses to client packets with TTL=2 """
1630 self.nat44_add_address(self.nat_addr)
1631 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
1632 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
1635 # Client side - generate traffic
1636 pkts = self.create_stream_in(self.pg0, self.pg1, ttl=2)
1637 self.pg0.add_stream(pkts)
1638 self.pg_enable_capture(self.pg_interfaces)
1641 # Server side - simulate ICMP type 11 response
1642 capture = self.pg1.get_capture(len(pkts))
1643 pkts = [Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
1644 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
1645 ICMP(type=11) / packet[IP] for packet in capture]
1646 self.pg1.add_stream(pkts)
1647 self.pg_enable_capture(self.pg_interfaces)
1650 # Client side - verify ICMP type 11 packets
1651 capture = self.pg0.get_capture(len(pkts))
1652 self.verify_capture_in_with_icmp_errors(capture, self.pg0)
1654 def test_dynamic_icmp_errors_out2in_ttl_2(self):
1655 """ NAT44 handling of error responses to server packets with TTL=2 """
1657 self.nat44_add_address(self.nat_addr)
1658 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
1659 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
1662 # Client side - create sessions
1663 pkts = self.create_stream_in(self.pg0, self.pg1)
1664 self.pg0.add_stream(pkts)
1665 self.pg_enable_capture(self.pg_interfaces)
1668 # Server side - generate traffic
1669 capture = self.pg1.get_capture(len(pkts))
1670 self.verify_capture_out(capture)
1671 pkts = self.create_stream_out(self.pg1, ttl=2)
1672 self.pg1.add_stream(pkts)
1673 self.pg_enable_capture(self.pg_interfaces)
1676 # Client side - simulate ICMP type 11 response
1677 capture = self.pg0.get_capture(len(pkts))
1678 pkts = [Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
1679 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
1680 ICMP(type=11) / packet[IP] for packet in capture]
1681 self.pg0.add_stream(pkts)
1682 self.pg_enable_capture(self.pg_interfaces)
1685 # Server side - verify ICMP type 11 packets
1686 capture = self.pg1.get_capture(len(pkts))
1687 self.verify_capture_out_with_icmp_errors(capture)
1689 def test_ping_out_interface_from_outside(self):
1690 """ Ping NAT44 out interface from outside network """
1692 self.nat44_add_address(self.nat_addr)
1693 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
1694 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
1697 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
1698 IP(src=self.pg1.remote_ip4, dst=self.pg1.local_ip4) /
1699 ICMP(id=self.icmp_id_out, type='echo-request'))
1701 self.pg1.add_stream(pkts)
1702 self.pg_enable_capture(self.pg_interfaces)
1704 capture = self.pg1.get_capture(len(pkts))
1707 self.assertEqual(packet[IP].src, self.pg1.local_ip4)
1708 self.assertEqual(packet[IP].dst, self.pg1.remote_ip4)
1709 self.assertEqual(packet[ICMP].id, self.icmp_id_in)
1710 self.assertEqual(packet[ICMP].type, 0) # echo reply
1712 self.logger.error(ppp("Unexpected or invalid packet "
1713 "(outside network):", packet))
1716 def test_ping_internal_host_from_outside(self):
1717 """ Ping internal host from outside network """
1719 self.nat44_add_static_mapping(self.pg0.remote_ip4, self.nat_addr)
1720 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
1721 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
1725 pkt = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
1726 IP(src=self.pg1.remote_ip4, dst=self.nat_addr, ttl=64) /
1727 ICMP(id=self.icmp_id_out, type='echo-request'))
1728 self.pg1.add_stream(pkt)
1729 self.pg_enable_capture(self.pg_interfaces)
1731 capture = self.pg0.get_capture(1)
1732 self.verify_capture_in(capture, self.pg0)
1733 self.assert_equal(capture[0][IP].proto, IP_PROTOS.icmp)
1736 pkt = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
1737 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4, ttl=64) /
1738 ICMP(id=self.icmp_id_in, type='echo-reply'))
1739 self.pg0.add_stream(pkt)
1740 self.pg_enable_capture(self.pg_interfaces)
1742 capture = self.pg1.get_capture(1)
1743 self.verify_capture_out(capture, same_port=True)
1744 self.assert_equal(capture[0][IP].proto, IP_PROTOS.icmp)
1746 def test_forwarding(self):
1747 """ NAT44 forwarding test """
1749 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
1750 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
1752 self.vapi.nat44_forwarding_enable_disable(1)
1754 real_ip = self.pg0.remote_ip4n
1755 alias_ip = self.nat_addr_n
1756 self.vapi.nat44_add_del_static_mapping(local_ip=real_ip,
1757 external_ip=alias_ip)
1760 # static mapping match
1762 pkts = self.create_stream_out(self.pg1)
1763 self.pg1.add_stream(pkts)
1764 self.pg_enable_capture(self.pg_interfaces)
1766 capture = self.pg0.get_capture(len(pkts))
1767 self.verify_capture_in(capture, self.pg0)
1769 pkts = self.create_stream_in(self.pg0, self.pg1)
1770 self.pg0.add_stream(pkts)
1771 self.pg_enable_capture(self.pg_interfaces)
1773 capture = self.pg1.get_capture(len(pkts))
1774 self.verify_capture_out(capture, same_port=True)
1776 # no static mapping match
1778 host0 = self.pg0.remote_hosts[0]
1779 self.pg0.remote_hosts[0] = self.pg0.remote_hosts[1]
1781 pkts = self.create_stream_out(self.pg1,
1782 dst_ip=self.pg0.remote_ip4,
1783 use_inside_ports=True)
1784 self.pg1.add_stream(pkts)
1785 self.pg_enable_capture(self.pg_interfaces)
1787 capture = self.pg0.get_capture(len(pkts))
1788 self.verify_capture_in(capture, self.pg0)
1790 pkts = self.create_stream_in(self.pg0, self.pg1)
1791 self.pg0.add_stream(pkts)
1792 self.pg_enable_capture(self.pg_interfaces)
1794 capture = self.pg1.get_capture(len(pkts))
1795 self.verify_capture_out(capture, nat_ip=self.pg0.remote_ip4,
1798 self.pg0.remote_hosts[0] = host0
1801 self.vapi.nat44_forwarding_enable_disable(0)
1802 self.vapi.nat44_add_del_static_mapping(local_ip=real_ip,
1803 external_ip=alias_ip,
1806 def test_static_in(self):
1807 """ 1:1 NAT initialized from inside network """
1809 nat_ip = "10.0.0.10"
1810 self.tcp_port_out = 6303
1811 self.udp_port_out = 6304
1812 self.icmp_id_out = 6305
1814 self.nat44_add_static_mapping(self.pg0.remote_ip4, nat_ip)
1815 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
1816 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
1818 sm = self.vapi.nat44_static_mapping_dump()
1819 self.assertEqual(len(sm), 1)
1820 self.assertEqual((sm[0].tag).split('\0', 1)[0], '')
1821 self.assertEqual(sm[0].protocol, 0)
1822 self.assertEqual(sm[0].local_port, 0)
1823 self.assertEqual(sm[0].external_port, 0)
1826 pkts = self.create_stream_in(self.pg0, self.pg1)
1827 self.pg0.add_stream(pkts)
1828 self.pg_enable_capture(self.pg_interfaces)
1830 capture = self.pg1.get_capture(len(pkts))
1831 self.verify_capture_out(capture, nat_ip, True)
1834 pkts = self.create_stream_out(self.pg1, nat_ip)
1835 self.pg1.add_stream(pkts)
1836 self.pg_enable_capture(self.pg_interfaces)
1838 capture = self.pg0.get_capture(len(pkts))
1839 self.verify_capture_in(capture, self.pg0)
1841 def test_static_out(self):
1842 """ 1:1 NAT initialized from outside network """
1844 nat_ip = "10.0.0.20"
1845 self.tcp_port_out = 6303
1846 self.udp_port_out = 6304
1847 self.icmp_id_out = 6305
1850 self.nat44_add_static_mapping(self.pg0.remote_ip4, nat_ip, tag=tag)
1851 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
1852 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
1854 sm = self.vapi.nat44_static_mapping_dump()
1855 self.assertEqual(len(sm), 1)
1856 self.assertEqual((sm[0].tag).split('\0', 1)[0], tag)
1859 pkts = self.create_stream_out(self.pg1, nat_ip)
1860 self.pg1.add_stream(pkts)
1861 self.pg_enable_capture(self.pg_interfaces)
1863 capture = self.pg0.get_capture(len(pkts))
1864 self.verify_capture_in(capture, self.pg0)
1867 pkts = self.create_stream_in(self.pg0, self.pg1)
1868 self.pg0.add_stream(pkts)
1869 self.pg_enable_capture(self.pg_interfaces)
1871 capture = self.pg1.get_capture(len(pkts))
1872 self.verify_capture_out(capture, nat_ip, True)
1874 def test_static_with_port_in(self):
1875 """ 1:1 NAPT initialized from inside network """
1877 self.tcp_port_out = 3606
1878 self.udp_port_out = 3607
1879 self.icmp_id_out = 3608
1881 self.nat44_add_address(self.nat_addr)
1882 self.nat44_add_static_mapping(self.pg0.remote_ip4, self.nat_addr,
1883 self.tcp_port_in, self.tcp_port_out,
1884 proto=IP_PROTOS.tcp)
1885 self.nat44_add_static_mapping(self.pg0.remote_ip4, self.nat_addr,
1886 self.udp_port_in, self.udp_port_out,
1887 proto=IP_PROTOS.udp)
1888 self.nat44_add_static_mapping(self.pg0.remote_ip4, self.nat_addr,
1889 self.icmp_id_in, self.icmp_id_out,
1890 proto=IP_PROTOS.icmp)
1891 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
1892 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
1896 pkts = self.create_stream_in(self.pg0, self.pg1)
1897 self.pg0.add_stream(pkts)
1898 self.pg_enable_capture(self.pg_interfaces)
1900 capture = self.pg1.get_capture(len(pkts))
1901 self.verify_capture_out(capture)
1904 pkts = self.create_stream_out(self.pg1)
1905 self.pg1.add_stream(pkts)
1906 self.pg_enable_capture(self.pg_interfaces)
1908 capture = self.pg0.get_capture(len(pkts))
1909 self.verify_capture_in(capture, self.pg0)
1911 def test_static_with_port_out(self):
1912 """ 1:1 NAPT initialized from outside network """
1914 self.tcp_port_out = 30606
1915 self.udp_port_out = 30607
1916 self.icmp_id_out = 30608
1918 self.nat44_add_address(self.nat_addr)
1919 self.nat44_add_static_mapping(self.pg0.remote_ip4, self.nat_addr,
1920 self.tcp_port_in, self.tcp_port_out,
1921 proto=IP_PROTOS.tcp)
1922 self.nat44_add_static_mapping(self.pg0.remote_ip4, self.nat_addr,
1923 self.udp_port_in, self.udp_port_out,
1924 proto=IP_PROTOS.udp)
1925 self.nat44_add_static_mapping(self.pg0.remote_ip4, self.nat_addr,
1926 self.icmp_id_in, self.icmp_id_out,
1927 proto=IP_PROTOS.icmp)
1928 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
1929 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
1933 pkts = self.create_stream_out(self.pg1)
1934 self.pg1.add_stream(pkts)
1935 self.pg_enable_capture(self.pg_interfaces)
1937 capture = self.pg0.get_capture(len(pkts))
1938 self.verify_capture_in(capture, self.pg0)
1941 pkts = self.create_stream_in(self.pg0, self.pg1)
1942 self.pg0.add_stream(pkts)
1943 self.pg_enable_capture(self.pg_interfaces)
1945 capture = self.pg1.get_capture(len(pkts))
1946 self.verify_capture_out(capture)
1948 def test_static_vrf_aware(self):
1949 """ 1:1 NAT VRF awareness """
1951 nat_ip1 = "10.0.0.30"
1952 nat_ip2 = "10.0.0.40"
1953 self.tcp_port_out = 6303
1954 self.udp_port_out = 6304
1955 self.icmp_id_out = 6305
1957 self.nat44_add_static_mapping(self.pg4.remote_ip4, nat_ip1,
1959 self.nat44_add_static_mapping(self.pg0.remote_ip4, nat_ip2,
1961 self.vapi.nat44_interface_add_del_feature(self.pg3.sw_if_index,
1963 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
1964 self.vapi.nat44_interface_add_del_feature(self.pg4.sw_if_index)
1966 # inside interface VRF match NAT44 static mapping VRF
1967 pkts = self.create_stream_in(self.pg4, self.pg3)
1968 self.pg4.add_stream(pkts)
1969 self.pg_enable_capture(self.pg_interfaces)
1971 capture = self.pg3.get_capture(len(pkts))
1972 self.verify_capture_out(capture, nat_ip1, True)
1974 # inside interface VRF don't match NAT44 static mapping VRF (packets
1976 pkts = self.create_stream_in(self.pg0, self.pg3)
1977 self.pg0.add_stream(pkts)
1978 self.pg_enable_capture(self.pg_interfaces)
1980 self.pg3.assert_nothing_captured()
1982 def test_dynamic_to_static(self):
1983 """ Switch from dynamic translation to 1:1NAT """
1984 nat_ip = "10.0.0.10"
1985 self.tcp_port_out = 6303
1986 self.udp_port_out = 6304
1987 self.icmp_id_out = 6305
1989 self.nat44_add_address(self.nat_addr)
1990 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
1991 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
1995 pkts = self.create_stream_in(self.pg0, self.pg1)
1996 self.pg0.add_stream(pkts)
1997 self.pg_enable_capture(self.pg_interfaces)
1999 capture = self.pg1.get_capture(len(pkts))
2000 self.verify_capture_out(capture)
2003 self.nat44_add_static_mapping(self.pg0.remote_ip4, nat_ip)
2004 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4n, 0)
2005 self.assertEqual(len(sessions), 0)
2006 pkts = self.create_stream_in(self.pg0, self.pg1)
2007 self.pg0.add_stream(pkts)
2008 self.pg_enable_capture(self.pg_interfaces)
2010 capture = self.pg1.get_capture(len(pkts))
2011 self.verify_capture_out(capture, nat_ip, True)
2013 def test_identity_nat(self):
2014 """ Identity NAT """
2016 self.vapi.nat44_add_del_identity_mapping(ip=self.pg0.remote_ip4n)
2017 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
2018 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
2021 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
2022 IP(src=self.pg1.remote_ip4, dst=self.pg0.remote_ip4) /
2023 TCP(sport=12345, dport=56789))
2024 self.pg1.add_stream(p)
2025 self.pg_enable_capture(self.pg_interfaces)
2027 capture = self.pg0.get_capture(1)
2032 self.assertEqual(ip.dst, self.pg0.remote_ip4)
2033 self.assertEqual(ip.src, self.pg1.remote_ip4)
2034 self.assertEqual(tcp.dport, 56789)
2035 self.assertEqual(tcp.sport, 12345)
2036 self.assert_packet_checksums_valid(p)
2038 self.logger.error(ppp("Unexpected or invalid packet:", p))
2041 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4n, 0)
2042 self.assertEqual(len(sessions), 0)
2043 self.vapi.nat44_add_del_identity_mapping(ip=self.pg0.remote_ip4n,
2045 identity_mappings = self.vapi.nat44_identity_mapping_dump()
2046 self.assertEqual(len(identity_mappings), 2)
2048 def test_multiple_inside_interfaces(self):
2049 """ NAT44 multiple non-overlapping address space inside interfaces """
2051 self.nat44_add_address(self.nat_addr)
2052 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
2053 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index)
2054 self.vapi.nat44_interface_add_del_feature(self.pg3.sw_if_index,
2057 # between two NAT44 inside interfaces (no translation)
2058 pkts = self.create_stream_in(self.pg0, self.pg1)
2059 self.pg0.add_stream(pkts)
2060 self.pg_enable_capture(self.pg_interfaces)
2062 capture = self.pg1.get_capture(len(pkts))
2063 self.verify_capture_no_translation(capture, self.pg0, self.pg1)
2065 # from NAT44 inside to interface without NAT44 feature (no translation)
2066 pkts = self.create_stream_in(self.pg0, self.pg2)
2067 self.pg0.add_stream(pkts)
2068 self.pg_enable_capture(self.pg_interfaces)
2070 capture = self.pg2.get_capture(len(pkts))
2071 self.verify_capture_no_translation(capture, self.pg0, self.pg2)
2073 # in2out 1st interface
2074 pkts = self.create_stream_in(self.pg0, self.pg3)
2075 self.pg0.add_stream(pkts)
2076 self.pg_enable_capture(self.pg_interfaces)
2078 capture = self.pg3.get_capture(len(pkts))
2079 self.verify_capture_out(capture)
2081 # out2in 1st interface
2082 pkts = self.create_stream_out(self.pg3)
2083 self.pg3.add_stream(pkts)
2084 self.pg_enable_capture(self.pg_interfaces)
2086 capture = self.pg0.get_capture(len(pkts))
2087 self.verify_capture_in(capture, self.pg0)
2089 # in2out 2nd interface
2090 pkts = self.create_stream_in(self.pg1, self.pg3)
2091 self.pg1.add_stream(pkts)
2092 self.pg_enable_capture(self.pg_interfaces)
2094 capture = self.pg3.get_capture(len(pkts))
2095 self.verify_capture_out(capture)
2097 # out2in 2nd interface
2098 pkts = self.create_stream_out(self.pg3)
2099 self.pg3.add_stream(pkts)
2100 self.pg_enable_capture(self.pg_interfaces)
2102 capture = self.pg1.get_capture(len(pkts))
2103 self.verify_capture_in(capture, self.pg1)
2105 def test_inside_overlapping_interfaces(self):
2106 """ NAT44 multiple inside interfaces with overlapping address space """
2108 static_nat_ip = "10.0.0.10"
2109 self.nat44_add_address(self.nat_addr)
2110 self.vapi.nat44_interface_add_del_feature(self.pg3.sw_if_index,
2112 self.vapi.nat44_interface_add_del_feature(self.pg4.sw_if_index)
2113 self.vapi.nat44_interface_add_del_feature(self.pg5.sw_if_index)
2114 self.vapi.nat44_interface_add_del_feature(self.pg6.sw_if_index)
2115 self.nat44_add_static_mapping(self.pg6.remote_ip4, static_nat_ip,
2118 # between NAT44 inside interfaces with same VRF (no translation)
2119 pkts = self.create_stream_in(self.pg4, self.pg5)
2120 self.pg4.add_stream(pkts)
2121 self.pg_enable_capture(self.pg_interfaces)
2123 capture = self.pg5.get_capture(len(pkts))
2124 self.verify_capture_no_translation(capture, self.pg4, self.pg5)
2126 # between NAT44 inside interfaces with different VRF (hairpinning)
2127 p = (Ether(src=self.pg4.remote_mac, dst=self.pg4.local_mac) /
2128 IP(src=self.pg4.remote_ip4, dst=static_nat_ip) /
2129 TCP(sport=1234, dport=5678))
2130 self.pg4.add_stream(p)
2131 self.pg_enable_capture(self.pg_interfaces)
2133 capture = self.pg6.get_capture(1)
2138 self.assertEqual(ip.src, self.nat_addr)
2139 self.assertEqual(ip.dst, self.pg6.remote_ip4)
2140 self.assertNotEqual(tcp.sport, 1234)
2141 self.assertEqual(tcp.dport, 5678)
2143 self.logger.error(ppp("Unexpected or invalid packet:", p))
2146 # in2out 1st interface
2147 pkts = self.create_stream_in(self.pg4, self.pg3)
2148 self.pg4.add_stream(pkts)
2149 self.pg_enable_capture(self.pg_interfaces)
2151 capture = self.pg3.get_capture(len(pkts))
2152 self.verify_capture_out(capture)
2154 # out2in 1st interface
2155 pkts = self.create_stream_out(self.pg3)
2156 self.pg3.add_stream(pkts)
2157 self.pg_enable_capture(self.pg_interfaces)
2159 capture = self.pg4.get_capture(len(pkts))
2160 self.verify_capture_in(capture, self.pg4)
2162 # in2out 2nd interface
2163 pkts = self.create_stream_in(self.pg5, self.pg3)
2164 self.pg5.add_stream(pkts)
2165 self.pg_enable_capture(self.pg_interfaces)
2167 capture = self.pg3.get_capture(len(pkts))
2168 self.verify_capture_out(capture)
2170 # out2in 2nd interface
2171 pkts = self.create_stream_out(self.pg3)
2172 self.pg3.add_stream(pkts)
2173 self.pg_enable_capture(self.pg_interfaces)
2175 capture = self.pg5.get_capture(len(pkts))
2176 self.verify_capture_in(capture, self.pg5)
2179 addresses = self.vapi.nat44_address_dump()
2180 self.assertEqual(len(addresses), 1)
2181 sessions = self.vapi.nat44_user_session_dump(self.pg5.remote_ip4n, 10)
2182 self.assertEqual(len(sessions), 3)
2183 for session in sessions:
2184 self.assertFalse(session.is_static)
2185 self.assertEqual(session.inside_ip_address[0:4],
2186 self.pg5.remote_ip4n)
2187 self.assertEqual(session.outside_ip_address,
2188 addresses[0].ip_address)
2189 self.assertEqual(sessions[0].protocol, IP_PROTOS.tcp)
2190 self.assertEqual(sessions[1].protocol, IP_PROTOS.udp)
2191 self.assertEqual(sessions[2].protocol, IP_PROTOS.icmp)
2192 self.assertEqual(sessions[0].inside_port, self.tcp_port_in)
2193 self.assertEqual(sessions[1].inside_port, self.udp_port_in)
2194 self.assertEqual(sessions[2].inside_port, self.icmp_id_in)
2195 self.assertEqual(sessions[0].outside_port, self.tcp_port_out)
2196 self.assertEqual(sessions[1].outside_port, self.udp_port_out)
2197 self.assertEqual(sessions[2].outside_port, self.icmp_id_out)
2199 # in2out 3rd interface
2200 pkts = self.create_stream_in(self.pg6, self.pg3)
2201 self.pg6.add_stream(pkts)
2202 self.pg_enable_capture(self.pg_interfaces)
2204 capture = self.pg3.get_capture(len(pkts))
2205 self.verify_capture_out(capture, static_nat_ip, True)
2207 # out2in 3rd interface
2208 pkts = self.create_stream_out(self.pg3, static_nat_ip)
2209 self.pg3.add_stream(pkts)
2210 self.pg_enable_capture(self.pg_interfaces)
2212 capture = self.pg6.get_capture(len(pkts))
2213 self.verify_capture_in(capture, self.pg6)
2215 # general user and session dump verifications
2216 users = self.vapi.nat44_user_dump()
2217 self.assertGreaterEqual(len(users), 3)
2218 addresses = self.vapi.nat44_address_dump()
2219 self.assertEqual(len(addresses), 1)
2221 sessions = self.vapi.nat44_user_session_dump(user.ip_address,
2223 for session in sessions:
2224 self.assertEqual(user.ip_address, session.inside_ip_address)
2225 self.assertTrue(session.total_bytes > session.total_pkts > 0)
2226 self.assertTrue(session.protocol in
2227 [IP_PROTOS.tcp, IP_PROTOS.udp,
2229 self.assertFalse(session.ext_host_valid)
2232 sessions = self.vapi.nat44_user_session_dump(self.pg4.remote_ip4n, 10)
2233 self.assertGreaterEqual(len(sessions), 4)
2234 for session in sessions:
2235 self.assertFalse(session.is_static)
2236 self.assertEqual(session.inside_ip_address[0:4],
2237 self.pg4.remote_ip4n)
2238 self.assertEqual(session.outside_ip_address,
2239 addresses[0].ip_address)
2242 sessions = self.vapi.nat44_user_session_dump(self.pg6.remote_ip4n, 20)
2243 self.assertGreaterEqual(len(sessions), 3)
2244 for session in sessions:
2245 self.assertTrue(session.is_static)
2246 self.assertEqual(session.inside_ip_address[0:4],
2247 self.pg6.remote_ip4n)
2248 self.assertEqual(map(ord, session.outside_ip_address[0:4]),
2249 map(int, static_nat_ip.split('.')))
2250 self.assertTrue(session.inside_port in
2251 [self.tcp_port_in, self.udp_port_in,
2254 def test_hairpinning(self):
2255 """ NAT44 hairpinning - 1:1 NAPT """
2257 host = self.pg0.remote_hosts[0]
2258 server = self.pg0.remote_hosts[1]
2261 server_in_port = 5678
2262 server_out_port = 8765
2264 self.nat44_add_address(self.nat_addr)
2265 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
2266 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
2268 # add static mapping for server
2269 self.nat44_add_static_mapping(server.ip4, self.nat_addr,
2270 server_in_port, server_out_port,
2271 proto=IP_PROTOS.tcp)
2273 # send packet from host to server
2274 p = (Ether(src=host.mac, dst=self.pg0.local_mac) /
2275 IP(src=host.ip4, dst=self.nat_addr) /
2276 TCP(sport=host_in_port, dport=server_out_port))
2277 self.pg0.add_stream(p)
2278 self.pg_enable_capture(self.pg_interfaces)
2280 capture = self.pg0.get_capture(1)
2285 self.assertEqual(ip.src, self.nat_addr)
2286 self.assertEqual(ip.dst, server.ip4)
2287 self.assertNotEqual(tcp.sport, host_in_port)
2288 self.assertEqual(tcp.dport, server_in_port)
2289 self.assert_packet_checksums_valid(p)
2290 host_out_port = tcp.sport
2292 self.logger.error(ppp("Unexpected or invalid packet:", p))
2295 # send reply from server to host
2296 p = (Ether(src=server.mac, dst=self.pg0.local_mac) /
2297 IP(src=server.ip4, dst=self.nat_addr) /
2298 TCP(sport=server_in_port, dport=host_out_port))
2299 self.pg0.add_stream(p)
2300 self.pg_enable_capture(self.pg_interfaces)
2302 capture = self.pg0.get_capture(1)
2307 self.assertEqual(ip.src, self.nat_addr)
2308 self.assertEqual(ip.dst, host.ip4)
2309 self.assertEqual(tcp.sport, server_out_port)
2310 self.assertEqual(tcp.dport, host_in_port)
2311 self.assert_packet_checksums_valid(p)
2313 self.logger.error(ppp("Unexpected or invalid packet:", p))
2316 def test_hairpinning2(self):
2317 """ NAT44 hairpinning - 1:1 NAT"""
2319 server1_nat_ip = "10.0.0.10"
2320 server2_nat_ip = "10.0.0.11"
2321 host = self.pg0.remote_hosts[0]
2322 server1 = self.pg0.remote_hosts[1]
2323 server2 = self.pg0.remote_hosts[2]
2324 server_tcp_port = 22
2325 server_udp_port = 20
2327 self.nat44_add_address(self.nat_addr)
2328 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
2329 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
2332 # add static mapping for servers
2333 self.nat44_add_static_mapping(server1.ip4, server1_nat_ip)
2334 self.nat44_add_static_mapping(server2.ip4, server2_nat_ip)
2338 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2339 IP(src=host.ip4, dst=server1_nat_ip) /
2340 TCP(sport=self.tcp_port_in, dport=server_tcp_port))
2342 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2343 IP(src=host.ip4, dst=server1_nat_ip) /
2344 UDP(sport=self.udp_port_in, dport=server_udp_port))
2346 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2347 IP(src=host.ip4, dst=server1_nat_ip) /
2348 ICMP(id=self.icmp_id_in, type='echo-request'))
2350 self.pg0.add_stream(pkts)
2351 self.pg_enable_capture(self.pg_interfaces)
2353 capture = self.pg0.get_capture(len(pkts))
2354 for packet in capture:
2356 self.assertEqual(packet[IP].src, self.nat_addr)
2357 self.assertEqual(packet[IP].dst, server1.ip4)
2358 if packet.haslayer(TCP):
2359 self.assertNotEqual(packet[TCP].sport, self.tcp_port_in)
2360 self.assertEqual(packet[TCP].dport, server_tcp_port)
2361 self.tcp_port_out = packet[TCP].sport
2362 self.assert_packet_checksums_valid(packet)
2363 elif packet.haslayer(UDP):
2364 self.assertNotEqual(packet[UDP].sport, self.udp_port_in)
2365 self.assertEqual(packet[UDP].dport, server_udp_port)
2366 self.udp_port_out = packet[UDP].sport
2368 self.assertNotEqual(packet[ICMP].id, self.icmp_id_in)
2369 self.icmp_id_out = packet[ICMP].id
2371 self.logger.error(ppp("Unexpected or invalid packet:", packet))
2376 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2377 IP(src=server1.ip4, dst=self.nat_addr) /
2378 TCP(sport=server_tcp_port, dport=self.tcp_port_out))
2380 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2381 IP(src=server1.ip4, dst=self.nat_addr) /
2382 UDP(sport=server_udp_port, dport=self.udp_port_out))
2384 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2385 IP(src=server1.ip4, dst=self.nat_addr) /
2386 ICMP(id=self.icmp_id_out, type='echo-reply'))
2388 self.pg0.add_stream(pkts)
2389 self.pg_enable_capture(self.pg_interfaces)
2391 capture = self.pg0.get_capture(len(pkts))
2392 for packet in capture:
2394 self.assertEqual(packet[IP].src, server1_nat_ip)
2395 self.assertEqual(packet[IP].dst, host.ip4)
2396 if packet.haslayer(TCP):
2397 self.assertEqual(packet[TCP].dport, self.tcp_port_in)
2398 self.assertEqual(packet[TCP].sport, server_tcp_port)
2399 self.assert_packet_checksums_valid(packet)
2400 elif packet.haslayer(UDP):
2401 self.assertEqual(packet[UDP].dport, self.udp_port_in)
2402 self.assertEqual(packet[UDP].sport, server_udp_port)
2404 self.assertEqual(packet[ICMP].id, self.icmp_id_in)
2406 self.logger.error(ppp("Unexpected or invalid packet:", packet))
2409 # server2 to server1
2411 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2412 IP(src=server2.ip4, dst=server1_nat_ip) /
2413 TCP(sport=self.tcp_port_in, dport=server_tcp_port))
2415 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2416 IP(src=server2.ip4, dst=server1_nat_ip) /
2417 UDP(sport=self.udp_port_in, dport=server_udp_port))
2419 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2420 IP(src=server2.ip4, dst=server1_nat_ip) /
2421 ICMP(id=self.icmp_id_in, type='echo-request'))
2423 self.pg0.add_stream(pkts)
2424 self.pg_enable_capture(self.pg_interfaces)
2426 capture = self.pg0.get_capture(len(pkts))
2427 for packet in capture:
2429 self.assertEqual(packet[IP].src, server2_nat_ip)
2430 self.assertEqual(packet[IP].dst, server1.ip4)
2431 if packet.haslayer(TCP):
2432 self.assertEqual(packet[TCP].sport, self.tcp_port_in)
2433 self.assertEqual(packet[TCP].dport, server_tcp_port)
2434 self.tcp_port_out = packet[TCP].sport
2435 self.assert_packet_checksums_valid(packet)
2436 elif packet.haslayer(UDP):
2437 self.assertEqual(packet[UDP].sport, self.udp_port_in)
2438 self.assertEqual(packet[UDP].dport, server_udp_port)
2439 self.udp_port_out = packet[UDP].sport
2441 self.assertEqual(packet[ICMP].id, self.icmp_id_in)
2442 self.icmp_id_out = packet[ICMP].id
2444 self.logger.error(ppp("Unexpected or invalid packet:", packet))
2447 # server1 to server2
2449 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2450 IP(src=server1.ip4, dst=server2_nat_ip) /
2451 TCP(sport=server_tcp_port, dport=self.tcp_port_out))
2453 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2454 IP(src=server1.ip4, dst=server2_nat_ip) /
2455 UDP(sport=server_udp_port, dport=self.udp_port_out))
2457 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2458 IP(src=server1.ip4, dst=server2_nat_ip) /
2459 ICMP(id=self.icmp_id_out, type='echo-reply'))
2461 self.pg0.add_stream(pkts)
2462 self.pg_enable_capture(self.pg_interfaces)
2464 capture = self.pg0.get_capture(len(pkts))
2465 for packet in capture:
2467 self.assertEqual(packet[IP].src, server1_nat_ip)
2468 self.assertEqual(packet[IP].dst, server2.ip4)
2469 if packet.haslayer(TCP):
2470 self.assertEqual(packet[TCP].dport, self.tcp_port_in)
2471 self.assertEqual(packet[TCP].sport, server_tcp_port)
2472 self.assert_packet_checksums_valid(packet)
2473 elif packet.haslayer(UDP):
2474 self.assertEqual(packet[UDP].dport, self.udp_port_in)
2475 self.assertEqual(packet[UDP].sport, server_udp_port)
2477 self.assertEqual(packet[ICMP].id, self.icmp_id_in)
2479 self.logger.error(ppp("Unexpected or invalid packet:", packet))
2482 def test_max_translations_per_user(self):
2483 """ MAX translations per user - recycle the least recently used """
2485 self.nat44_add_address(self.nat_addr)
2486 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
2487 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
2490 # get maximum number of translations per user
2491 nat44_config = self.vapi.nat_show_config()
2493 # send more than maximum number of translations per user packets
2494 pkts_num = nat44_config.max_translations_per_user + 5
2496 for port in range(0, pkts_num):
2497 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2498 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
2499 TCP(sport=1025 + port))
2501 self.pg0.add_stream(pkts)
2502 self.pg_enable_capture(self.pg_interfaces)
2505 # verify number of translated packet
2506 self.pg1.get_capture(pkts_num)
2508 users = self.vapi.nat44_user_dump()
2510 if user.ip_address == self.pg0.remote_ip4n:
2511 self.assertEqual(user.nsessions,
2512 nat44_config.max_translations_per_user)
2513 self.assertEqual(user.nstaticsessions, 0)
2516 self.nat44_add_static_mapping(self.pg0.remote_ip4, self.nat_addr,
2518 proto=IP_PROTOS.tcp)
2519 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2520 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
2521 TCP(sport=tcp_port))
2522 self.pg0.add_stream(p)
2523 self.pg_enable_capture(self.pg_interfaces)
2525 self.pg1.get_capture(1)
2526 users = self.vapi.nat44_user_dump()
2528 if user.ip_address == self.pg0.remote_ip4n:
2529 self.assertEqual(user.nsessions,
2530 nat44_config.max_translations_per_user - 1)
2531 self.assertEqual(user.nstaticsessions, 1)
2533 def test_interface_addr(self):
2534 """ Acquire NAT44 addresses from interface """
2535 self.vapi.nat44_add_interface_addr(self.pg7.sw_if_index)
2537 # no address in NAT pool
2538 adresses = self.vapi.nat44_address_dump()
2539 self.assertEqual(0, len(adresses))
2541 # configure interface address and check NAT address pool
2542 self.pg7.config_ip4()
2543 adresses = self.vapi.nat44_address_dump()
2544 self.assertEqual(1, len(adresses))
2545 self.assertEqual(adresses[0].ip_address[0:4], self.pg7.local_ip4n)
2547 # remove interface address and check NAT address pool
2548 self.pg7.unconfig_ip4()
2549 adresses = self.vapi.nat44_address_dump()
2550 self.assertEqual(0, len(adresses))
2552 def test_interface_addr_static_mapping(self):
2553 """ Static mapping with addresses from interface """
2556 self.vapi.nat44_add_interface_addr(self.pg7.sw_if_index)
2557 self.nat44_add_static_mapping(
2559 external_sw_if_index=self.pg7.sw_if_index,
2562 # static mappings with external interface
2563 static_mappings = self.vapi.nat44_static_mapping_dump()
2564 self.assertEqual(1, len(static_mappings))
2565 self.assertEqual(self.pg7.sw_if_index,
2566 static_mappings[0].external_sw_if_index)
2567 self.assertEqual((static_mappings[0].tag).split('\0', 1)[0], tag)
2569 # configure interface address and check static mappings
2570 self.pg7.config_ip4()
2571 static_mappings = self.vapi.nat44_static_mapping_dump()
2572 self.assertEqual(2, len(static_mappings))
2574 for sm in static_mappings:
2575 if sm.external_sw_if_index == 0xFFFFFFFF:
2576 self.assertEqual(sm.external_ip_address[0:4],
2577 self.pg7.local_ip4n)
2578 self.assertEqual((sm.tag).split('\0', 1)[0], tag)
2580 self.assertTrue(resolved)
2582 # remove interface address and check static mappings
2583 self.pg7.unconfig_ip4()
2584 static_mappings = self.vapi.nat44_static_mapping_dump()
2585 self.assertEqual(1, len(static_mappings))
2586 self.assertEqual(self.pg7.sw_if_index,
2587 static_mappings[0].external_sw_if_index)
2588 self.assertEqual((static_mappings[0].tag).split('\0', 1)[0], tag)
2590 # configure interface address again and check static mappings
2591 self.pg7.config_ip4()
2592 static_mappings = self.vapi.nat44_static_mapping_dump()
2593 self.assertEqual(2, len(static_mappings))
2595 for sm in static_mappings:
2596 if sm.external_sw_if_index == 0xFFFFFFFF:
2597 self.assertEqual(sm.external_ip_address[0:4],
2598 self.pg7.local_ip4n)
2599 self.assertEqual((sm.tag).split('\0', 1)[0], tag)
2601 self.assertTrue(resolved)
2603 # remove static mapping
2604 self.nat44_add_static_mapping(
2606 external_sw_if_index=self.pg7.sw_if_index,
2609 static_mappings = self.vapi.nat44_static_mapping_dump()
2610 self.assertEqual(0, len(static_mappings))
2612 def test_interface_addr_identity_nat(self):
2613 """ Identity NAT with addresses from interface """
2616 self.vapi.nat44_add_interface_addr(self.pg7.sw_if_index)
2617 self.vapi.nat44_add_del_identity_mapping(
2618 sw_if_index=self.pg7.sw_if_index,
2620 protocol=IP_PROTOS.tcp,
2623 # identity mappings with external interface
2624 identity_mappings = self.vapi.nat44_identity_mapping_dump()
2625 self.assertEqual(1, len(identity_mappings))
2626 self.assertEqual(self.pg7.sw_if_index,
2627 identity_mappings[0].sw_if_index)
2629 # configure interface address and check identity mappings
2630 self.pg7.config_ip4()
2631 identity_mappings = self.vapi.nat44_identity_mapping_dump()
2633 self.assertEqual(2, len(identity_mappings))
2634 for sm in identity_mappings:
2635 if sm.sw_if_index == 0xFFFFFFFF:
2636 self.assertEqual(identity_mappings[0].ip_address,
2637 self.pg7.local_ip4n)
2638 self.assertEqual(port, identity_mappings[0].port)
2639 self.assertEqual(IP_PROTOS.tcp, identity_mappings[0].protocol)
2641 self.assertTrue(resolved)
2643 # remove interface address and check identity mappings
2644 self.pg7.unconfig_ip4()
2645 identity_mappings = self.vapi.nat44_identity_mapping_dump()
2646 self.assertEqual(1, len(identity_mappings))
2647 self.assertEqual(self.pg7.sw_if_index,
2648 identity_mappings[0].sw_if_index)
2650 def test_ipfix_nat44_sess(self):
2651 """ IPFIX logging NAT44 session created/delted """
2652 self.ipfix_domain_id = 10
2653 self.ipfix_src_port = 20202
2654 colector_port = 30303
2655 bind_layers(UDP, IPFIX, dport=30303)
2656 self.nat44_add_address(self.nat_addr)
2657 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
2658 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
2660 self.vapi.set_ipfix_exporter(collector_address=self.pg3.remote_ip4n,
2661 src_address=self.pg3.local_ip4n,
2663 template_interval=10,
2664 collector_port=colector_port)
2665 self.vapi.nat_ipfix(domain_id=self.ipfix_domain_id,
2666 src_port=self.ipfix_src_port)
2668 pkts = self.create_stream_in(self.pg0, self.pg1)
2669 self.pg0.add_stream(pkts)
2670 self.pg_enable_capture(self.pg_interfaces)
2672 capture = self.pg1.get_capture(len(pkts))
2673 self.verify_capture_out(capture)
2674 self.nat44_add_address(self.nat_addr, is_add=0)
2675 self.vapi.cli("ipfix flush") # FIXME this should be an API call
2676 capture = self.pg3.get_capture(9)
2677 ipfix = IPFIXDecoder()
2678 # first load template
2680 self.assertTrue(p.haslayer(IPFIX))
2681 self.assertEqual(p[IP].src, self.pg3.local_ip4)
2682 self.assertEqual(p[IP].dst, self.pg3.remote_ip4)
2683 self.assertEqual(p[UDP].sport, self.ipfix_src_port)
2684 self.assertEqual(p[UDP].dport, colector_port)
2685 self.assertEqual(p[IPFIX].observationDomainID,
2686 self.ipfix_domain_id)
2687 if p.haslayer(Template):
2688 ipfix.add_template(p.getlayer(Template))
2689 # verify events in data set
2691 if p.haslayer(Data):
2692 data = ipfix.decode_data_set(p.getlayer(Set))
2693 self.verify_ipfix_nat44_ses(data)
2695 def test_ipfix_addr_exhausted(self):
2696 """ IPFIX logging NAT addresses exhausted """
2697 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
2698 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
2700 self.vapi.set_ipfix_exporter(collector_address=self.pg3.remote_ip4n,
2701 src_address=self.pg3.local_ip4n,
2703 template_interval=10)
2704 self.vapi.nat_ipfix(domain_id=self.ipfix_domain_id,
2705 src_port=self.ipfix_src_port)
2707 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
2708 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
2710 self.pg0.add_stream(p)
2711 self.pg_enable_capture(self.pg_interfaces)
2713 self.pg1.assert_nothing_captured()
2715 self.vapi.cli("ipfix flush") # FIXME this should be an API call
2716 capture = self.pg3.get_capture(9)
2717 ipfix = IPFIXDecoder()
2718 # first load template
2720 self.assertTrue(p.haslayer(IPFIX))
2721 self.assertEqual(p[IP].src, self.pg3.local_ip4)
2722 self.assertEqual(p[IP].dst, self.pg3.remote_ip4)
2723 self.assertEqual(p[UDP].sport, self.ipfix_src_port)
2724 self.assertEqual(p[UDP].dport, 4739)
2725 self.assertEqual(p[IPFIX].observationDomainID,
2726 self.ipfix_domain_id)
2727 if p.haslayer(Template):
2728 ipfix.add_template(p.getlayer(Template))
2729 # verify events in data set
2731 if p.haslayer(Data):
2732 data = ipfix.decode_data_set(p.getlayer(Set))
2733 self.verify_ipfix_addr_exhausted(data)
2735 @unittest.skipUnless(running_extended_tests, "part of extended tests")
2736 def test_ipfix_max_sessions(self):
2737 """ IPFIX logging maximum session entries exceeded """
2738 self.nat44_add_address(self.nat_addr)
2739 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
2740 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
2743 nat44_config = self.vapi.nat_show_config()
2744 max_sessions = 10 * nat44_config.translation_buckets
2747 for i in range(0, max_sessions):
2748 src = "10.10.%u.%u" % ((i & 0xFF00) >> 8, i & 0xFF)
2749 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2750 IP(src=src, dst=self.pg1.remote_ip4) /
2753 self.pg0.add_stream(pkts)
2754 self.pg_enable_capture(self.pg_interfaces)
2757 self.pg1.get_capture(max_sessions)
2758 self.vapi.set_ipfix_exporter(collector_address=self.pg3.remote_ip4n,
2759 src_address=self.pg3.local_ip4n,
2761 template_interval=10)
2762 self.vapi.nat_ipfix(domain_id=self.ipfix_domain_id,
2763 src_port=self.ipfix_src_port)
2765 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2766 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
2768 self.pg0.add_stream(p)
2769 self.pg_enable_capture(self.pg_interfaces)
2771 self.pg1.assert_nothing_captured()
2773 self.vapi.cli("ipfix flush") # FIXME this should be an API call
2774 capture = self.pg3.get_capture(9)
2775 ipfix = IPFIXDecoder()
2776 # first load template
2778 self.assertTrue(p.haslayer(IPFIX))
2779 self.assertEqual(p[IP].src, self.pg3.local_ip4)
2780 self.assertEqual(p[IP].dst, self.pg3.remote_ip4)
2781 self.assertEqual(p[UDP].sport, self.ipfix_src_port)
2782 self.assertEqual(p[UDP].dport, 4739)
2783 self.assertEqual(p[IPFIX].observationDomainID,
2784 self.ipfix_domain_id)
2785 if p.haslayer(Template):
2786 ipfix.add_template(p.getlayer(Template))
2787 # verify events in data set
2789 if p.haslayer(Data):
2790 data = ipfix.decode_data_set(p.getlayer(Set))
2791 self.verify_ipfix_max_sessions(data, max_sessions)
2793 def test_syslog_apmap(self):
2794 """ Test syslog address and port mapping creation and deletion """
2795 self.vapi.syslog_set_filter(SYSLOG_SEVERITY.INFO)
2796 self.vapi.syslog_set_sender(self.pg3.remote_ip4n, self.pg3.local_ip4n)
2797 self.nat44_add_address(self.nat_addr)
2798 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
2799 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
2802 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2803 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
2804 TCP(sport=self.tcp_port_in, dport=20))
2805 self.pg0.add_stream(p)
2806 self.pg_enable_capture(self.pg_interfaces)
2808 capture = self.pg1.get_capture(1)
2809 self.tcp_port_out = capture[0][TCP].sport
2810 capture = self.pg3.get_capture(1)
2811 self.verify_syslog_apmap(capture[0][Raw].load)
2813 self.pg_enable_capture(self.pg_interfaces)
2815 self.nat44_add_address(self.nat_addr, is_add=0)
2816 capture = self.pg3.get_capture(1)
2817 self.verify_syslog_apmap(capture[0][Raw].load, False)
2819 def test_pool_addr_fib(self):
2820 """ NAT44 add pool addresses to FIB """
2821 static_addr = '10.0.0.10'
2822 self.nat44_add_address(self.nat_addr)
2823 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
2824 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
2826 self.nat44_add_static_mapping(self.pg0.remote_ip4, static_addr)
2829 p = (Ether(src=self.pg1.remote_mac, dst='ff:ff:ff:ff:ff:ff') /
2830 ARP(op=ARP.who_has, pdst=self.nat_addr,
2831 psrc=self.pg1.remote_ip4, hwsrc=self.pg1.remote_mac))
2832 self.pg1.add_stream(p)
2833 self.pg_enable_capture(self.pg_interfaces)
2835 capture = self.pg1.get_capture(1)
2836 self.assertTrue(capture[0].haslayer(ARP))
2837 self.assertTrue(capture[0][ARP].op, ARP.is_at)
2840 p = (Ether(src=self.pg1.remote_mac, dst='ff:ff:ff:ff:ff:ff') /
2841 ARP(op=ARP.who_has, pdst=static_addr,
2842 psrc=self.pg1.remote_ip4, hwsrc=self.pg1.remote_mac))
2843 self.pg1.add_stream(p)
2844 self.pg_enable_capture(self.pg_interfaces)
2846 capture = self.pg1.get_capture(1)
2847 self.assertTrue(capture[0].haslayer(ARP))
2848 self.assertTrue(capture[0][ARP].op, ARP.is_at)
2850 # send ARP to non-NAT44 interface
2851 p = (Ether(src=self.pg2.remote_mac, dst='ff:ff:ff:ff:ff:ff') /
2852 ARP(op=ARP.who_has, pdst=self.nat_addr,
2853 psrc=self.pg2.remote_ip4, hwsrc=self.pg2.remote_mac))
2854 self.pg2.add_stream(p)
2855 self.pg_enable_capture(self.pg_interfaces)
2857 self.pg1.assert_nothing_captured()
2859 # remove addresses and verify
2860 self.nat44_add_address(self.nat_addr, is_add=0)
2861 self.nat44_add_static_mapping(self.pg0.remote_ip4, static_addr,
2864 p = (Ether(src=self.pg1.remote_mac, dst='ff:ff:ff:ff:ff:ff') /
2865 ARP(op=ARP.who_has, pdst=self.nat_addr,
2866 psrc=self.pg1.remote_ip4, hwsrc=self.pg1.remote_mac))
2867 self.pg1.add_stream(p)
2868 self.pg_enable_capture(self.pg_interfaces)
2870 self.pg1.assert_nothing_captured()
2872 p = (Ether(src=self.pg1.remote_mac, dst='ff:ff:ff:ff:ff:ff') /
2873 ARP(op=ARP.who_has, pdst=static_addr,
2874 psrc=self.pg1.remote_ip4, hwsrc=self.pg1.remote_mac))
2875 self.pg1.add_stream(p)
2876 self.pg_enable_capture(self.pg_interfaces)
2878 self.pg1.assert_nothing_captured()
2880 def test_vrf_mode(self):
2881 """ NAT44 tenant VRF aware address pool mode """
2885 nat_ip1 = "10.0.0.10"
2886 nat_ip2 = "10.0.0.11"
2888 self.pg0.unconfig_ip4()
2889 self.pg1.unconfig_ip4()
2890 self.vapi.ip_table_add_del(vrf_id1, is_add=1)
2891 self.vapi.ip_table_add_del(vrf_id2, is_add=1)
2892 self.pg0.set_table_ip4(vrf_id1)
2893 self.pg1.set_table_ip4(vrf_id2)
2894 self.pg0.config_ip4()
2895 self.pg1.config_ip4()
2896 self.pg0.resolve_arp()
2897 self.pg1.resolve_arp()
2899 self.nat44_add_address(nat_ip1, vrf_id=vrf_id1)
2900 self.nat44_add_address(nat_ip2, vrf_id=vrf_id2)
2901 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
2902 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index)
2903 self.vapi.nat44_interface_add_del_feature(self.pg2.sw_if_index,
2908 pkts = self.create_stream_in(self.pg0, self.pg2)
2909 self.pg0.add_stream(pkts)
2910 self.pg_enable_capture(self.pg_interfaces)
2912 capture = self.pg2.get_capture(len(pkts))
2913 self.verify_capture_out(capture, nat_ip1)
2916 pkts = self.create_stream_in(self.pg1, self.pg2)
2917 self.pg1.add_stream(pkts)
2918 self.pg_enable_capture(self.pg_interfaces)
2920 capture = self.pg2.get_capture(len(pkts))
2921 self.verify_capture_out(capture, nat_ip2)
2924 self.pg0.unconfig_ip4()
2925 self.pg1.unconfig_ip4()
2926 self.pg0.set_table_ip4(0)
2927 self.pg1.set_table_ip4(0)
2928 self.pg0.config_ip4()
2929 self.pg1.config_ip4()
2930 self.pg0.resolve_arp()
2931 self.pg1.resolve_arp()
2932 self.vapi.ip_table_add_del(vrf_id1, is_add=0)
2933 self.vapi.ip_table_add_del(vrf_id2, is_add=0)
2935 def test_vrf_feature_independent(self):
2936 """ NAT44 tenant VRF independent address pool mode """
2938 nat_ip1 = "10.0.0.10"
2939 nat_ip2 = "10.0.0.11"
2941 self.nat44_add_address(nat_ip1)
2942 self.nat44_add_address(nat_ip2, vrf_id=99)
2943 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
2944 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index)
2945 self.vapi.nat44_interface_add_del_feature(self.pg2.sw_if_index,
2949 pkts = self.create_stream_in(self.pg0, self.pg2)
2950 self.pg0.add_stream(pkts)
2951 self.pg_enable_capture(self.pg_interfaces)
2953 capture = self.pg2.get_capture(len(pkts))
2954 self.verify_capture_out(capture, nat_ip1)
2957 pkts = self.create_stream_in(self.pg1, self.pg2)
2958 self.pg1.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)
2964 def test_dynamic_ipless_interfaces(self):
2965 """ NAT44 interfaces without configured IP address """
2967 self.vapi.ip_neighbor_add_del(self.pg7.sw_if_index,
2968 mac_pton(self.pg7.remote_mac),
2969 self.pg7.remote_ip4n,
2971 self.vapi.ip_neighbor_add_del(self.pg8.sw_if_index,
2972 mac_pton(self.pg8.remote_mac),
2973 self.pg8.remote_ip4n,
2976 self.vapi.ip_add_del_route(dst_address=self.pg7.remote_ip4n,
2977 dst_address_length=32,
2978 next_hop_address=self.pg7.remote_ip4n,
2979 next_hop_sw_if_index=self.pg7.sw_if_index)
2980 self.vapi.ip_add_del_route(dst_address=self.pg8.remote_ip4n,
2981 dst_address_length=32,
2982 next_hop_address=self.pg8.remote_ip4n,
2983 next_hop_sw_if_index=self.pg8.sw_if_index)
2985 self.nat44_add_address(self.nat_addr)
2986 self.vapi.nat44_interface_add_del_feature(self.pg7.sw_if_index)
2987 self.vapi.nat44_interface_add_del_feature(self.pg8.sw_if_index,
2991 pkts = self.create_stream_in(self.pg7, self.pg8)
2992 self.pg7.add_stream(pkts)
2993 self.pg_enable_capture(self.pg_interfaces)
2995 capture = self.pg8.get_capture(len(pkts))
2996 self.verify_capture_out(capture)
2999 pkts = self.create_stream_out(self.pg8, self.nat_addr)
3000 self.pg8.add_stream(pkts)
3001 self.pg_enable_capture(self.pg_interfaces)
3003 capture = self.pg7.get_capture(len(pkts))
3004 self.verify_capture_in(capture, self.pg7)
3006 def test_static_ipless_interfaces(self):
3007 """ NAT44 interfaces without configured IP address - 1:1 NAT """
3009 self.vapi.ip_neighbor_add_del(self.pg7.sw_if_index,
3010 mac_pton(self.pg7.remote_mac),
3011 self.pg7.remote_ip4n,
3013 self.vapi.ip_neighbor_add_del(self.pg8.sw_if_index,
3014 mac_pton(self.pg8.remote_mac),
3015 self.pg8.remote_ip4n,
3018 self.vapi.ip_add_del_route(dst_address=self.pg7.remote_ip4n,
3019 dst_address_length=32,
3020 next_hop_address=self.pg7.remote_ip4n,
3021 next_hop_sw_if_index=self.pg7.sw_if_index)
3022 self.vapi.ip_add_del_route(dst_address=self.pg8.remote_ip4n,
3023 dst_address_length=32,
3024 next_hop_address=self.pg8.remote_ip4n,
3025 next_hop_sw_if_index=self.pg8.sw_if_index)
3027 self.nat44_add_static_mapping(self.pg7.remote_ip4, self.nat_addr)
3028 self.vapi.nat44_interface_add_del_feature(self.pg7.sw_if_index)
3029 self.vapi.nat44_interface_add_del_feature(self.pg8.sw_if_index,
3033 pkts = self.create_stream_out(self.pg8)
3034 self.pg8.add_stream(pkts)
3035 self.pg_enable_capture(self.pg_interfaces)
3037 capture = self.pg7.get_capture(len(pkts))
3038 self.verify_capture_in(capture, self.pg7)
3041 pkts = self.create_stream_in(self.pg7, self.pg8)
3042 self.pg7.add_stream(pkts)
3043 self.pg_enable_capture(self.pg_interfaces)
3045 capture = self.pg8.get_capture(len(pkts))
3046 self.verify_capture_out(capture, self.nat_addr, True)
3048 def test_static_with_port_ipless_interfaces(self):
3049 """ NAT44 interfaces without configured IP address - 1:1 NAPT """
3051 self.tcp_port_out = 30606
3052 self.udp_port_out = 30607
3053 self.icmp_id_out = 30608
3055 self.vapi.ip_neighbor_add_del(self.pg7.sw_if_index,
3056 mac_pton(self.pg7.remote_mac),
3057 self.pg7.remote_ip4n,
3059 self.vapi.ip_neighbor_add_del(self.pg8.sw_if_index,
3060 mac_pton(self.pg8.remote_mac),
3061 self.pg8.remote_ip4n,
3064 self.vapi.ip_add_del_route(dst_address=self.pg7.remote_ip4n,
3065 dst_address_length=32,
3066 next_hop_address=self.pg7.remote_ip4n,
3067 next_hop_sw_if_index=self.pg7.sw_if_index)
3068 self.vapi.ip_add_del_route(dst_address=self.pg8.remote_ip4n,
3069 dst_address_length=32,
3070 next_hop_address=self.pg8.remote_ip4n,
3071 next_hop_sw_if_index=self.pg8.sw_if_index)
3073 self.nat44_add_address(self.nat_addr)
3074 self.nat44_add_static_mapping(self.pg7.remote_ip4, self.nat_addr,
3075 self.tcp_port_in, self.tcp_port_out,
3076 proto=IP_PROTOS.tcp)
3077 self.nat44_add_static_mapping(self.pg7.remote_ip4, self.nat_addr,
3078 self.udp_port_in, self.udp_port_out,
3079 proto=IP_PROTOS.udp)
3080 self.nat44_add_static_mapping(self.pg7.remote_ip4, self.nat_addr,
3081 self.icmp_id_in, self.icmp_id_out,
3082 proto=IP_PROTOS.icmp)
3083 self.vapi.nat44_interface_add_del_feature(self.pg7.sw_if_index)
3084 self.vapi.nat44_interface_add_del_feature(self.pg8.sw_if_index,
3088 pkts = self.create_stream_out(self.pg8)
3089 self.pg8.add_stream(pkts)
3090 self.pg_enable_capture(self.pg_interfaces)
3092 capture = self.pg7.get_capture(len(pkts))
3093 self.verify_capture_in(capture, self.pg7)
3096 pkts = self.create_stream_in(self.pg7, self.pg8)
3097 self.pg7.add_stream(pkts)
3098 self.pg_enable_capture(self.pg_interfaces)
3100 capture = self.pg8.get_capture(len(pkts))
3101 self.verify_capture_out(capture)
3103 def test_static_unknown_proto(self):
3104 """ 1:1 NAT translate packet with unknown protocol """
3105 nat_ip = "10.0.0.10"
3106 self.nat44_add_static_mapping(self.pg0.remote_ip4, nat_ip)
3107 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
3108 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
3112 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
3113 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
3115 IP(src=self.pg2.remote_ip4, dst=self.pg3.remote_ip4) /
3116 TCP(sport=1234, dport=1234))
3117 self.pg0.add_stream(p)
3118 self.pg_enable_capture(self.pg_interfaces)
3120 p = self.pg1.get_capture(1)
3123 self.assertEqual(packet[IP].src, nat_ip)
3124 self.assertEqual(packet[IP].dst, self.pg1.remote_ip4)
3125 self.assertEqual(packet.haslayer(GRE), 1)
3126 self.assert_packet_checksums_valid(packet)
3128 self.logger.error(ppp("Unexpected or invalid packet:", packet))
3132 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
3133 IP(src=self.pg1.remote_ip4, dst=nat_ip) /
3135 IP(src=self.pg3.remote_ip4, dst=self.pg2.remote_ip4) /
3136 TCP(sport=1234, dport=1234))
3137 self.pg1.add_stream(p)
3138 self.pg_enable_capture(self.pg_interfaces)
3140 p = self.pg0.get_capture(1)
3143 self.assertEqual(packet[IP].src, self.pg1.remote_ip4)
3144 self.assertEqual(packet[IP].dst, self.pg0.remote_ip4)
3145 self.assertEqual(packet.haslayer(GRE), 1)
3146 self.assert_packet_checksums_valid(packet)
3148 self.logger.error(ppp("Unexpected or invalid packet:", packet))
3151 def test_hairpinning_static_unknown_proto(self):
3152 """ 1:1 NAT translate packet with unknown protocol - hairpinning """
3154 host = self.pg0.remote_hosts[0]
3155 server = self.pg0.remote_hosts[1]
3157 host_nat_ip = "10.0.0.10"
3158 server_nat_ip = "10.0.0.11"
3160 self.nat44_add_static_mapping(host.ip4, host_nat_ip)
3161 self.nat44_add_static_mapping(server.ip4, server_nat_ip)
3162 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
3163 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
3167 p = (Ether(dst=self.pg0.local_mac, src=host.mac) /
3168 IP(src=host.ip4, dst=server_nat_ip) /
3170 IP(src=self.pg2.remote_ip4, dst=self.pg3.remote_ip4) /
3171 TCP(sport=1234, dport=1234))
3172 self.pg0.add_stream(p)
3173 self.pg_enable_capture(self.pg_interfaces)
3175 p = self.pg0.get_capture(1)
3178 self.assertEqual(packet[IP].src, host_nat_ip)
3179 self.assertEqual(packet[IP].dst, server.ip4)
3180 self.assertEqual(packet.haslayer(GRE), 1)
3181 self.assert_packet_checksums_valid(packet)
3183 self.logger.error(ppp("Unexpected or invalid packet:", packet))
3187 p = (Ether(dst=self.pg0.local_mac, src=server.mac) /
3188 IP(src=server.ip4, dst=host_nat_ip) /
3190 IP(src=self.pg3.remote_ip4, dst=self.pg2.remote_ip4) /
3191 TCP(sport=1234, dport=1234))
3192 self.pg0.add_stream(p)
3193 self.pg_enable_capture(self.pg_interfaces)
3195 p = self.pg0.get_capture(1)
3198 self.assertEqual(packet[IP].src, server_nat_ip)
3199 self.assertEqual(packet[IP].dst, host.ip4)
3200 self.assertEqual(packet.haslayer(GRE), 1)
3201 self.assert_packet_checksums_valid(packet)
3203 self.logger.error(ppp("Unexpected or invalid packet:", packet))
3206 def test_output_feature(self):
3207 """ NAT44 interface output feature (in2out postrouting) """
3208 self.nat44_add_address(self.nat_addr)
3209 self.vapi.nat44_interface_add_del_output_feature(self.pg0.sw_if_index)
3210 self.vapi.nat44_interface_add_del_output_feature(self.pg1.sw_if_index)
3211 self.vapi.nat44_interface_add_del_output_feature(self.pg3.sw_if_index,
3215 pkts = self.create_stream_in(self.pg0, self.pg3)
3216 self.pg0.add_stream(pkts)
3217 self.pg_enable_capture(self.pg_interfaces)
3219 capture = self.pg3.get_capture(len(pkts))
3220 self.verify_capture_out(capture)
3223 pkts = self.create_stream_out(self.pg3)
3224 self.pg3.add_stream(pkts)
3225 self.pg_enable_capture(self.pg_interfaces)
3227 capture = self.pg0.get_capture(len(pkts))
3228 self.verify_capture_in(capture, self.pg0)
3230 # from non-NAT interface to NAT inside interface
3231 pkts = self.create_stream_in(self.pg2, self.pg0)
3232 self.pg2.add_stream(pkts)
3233 self.pg_enable_capture(self.pg_interfaces)
3235 capture = self.pg0.get_capture(len(pkts))
3236 self.verify_capture_no_translation(capture, self.pg2, self.pg0)
3238 def test_output_feature_vrf_aware(self):
3239 """ NAT44 interface output feature VRF aware (in2out postrouting) """
3240 nat_ip_vrf10 = "10.0.0.10"
3241 nat_ip_vrf20 = "10.0.0.20"
3243 self.vapi.ip_add_del_route(dst_address=self.pg3.remote_ip4n,
3244 dst_address_length=32,
3245 next_hop_address=self.pg3.remote_ip4n,
3246 next_hop_sw_if_index=self.pg3.sw_if_index,
3248 self.vapi.ip_add_del_route(dst_address=self.pg3.remote_ip4n,
3249 dst_address_length=32,
3250 next_hop_address=self.pg3.remote_ip4n,
3251 next_hop_sw_if_index=self.pg3.sw_if_index,
3254 self.nat44_add_address(nat_ip_vrf10, vrf_id=10)
3255 self.nat44_add_address(nat_ip_vrf20, vrf_id=20)
3256 self.vapi.nat44_interface_add_del_output_feature(self.pg4.sw_if_index)
3257 self.vapi.nat44_interface_add_del_output_feature(self.pg6.sw_if_index)
3258 self.vapi.nat44_interface_add_del_output_feature(self.pg3.sw_if_index,
3262 pkts = self.create_stream_in(self.pg4, self.pg3)
3263 self.pg4.add_stream(pkts)
3264 self.pg_enable_capture(self.pg_interfaces)
3266 capture = self.pg3.get_capture(len(pkts))
3267 self.verify_capture_out(capture, nat_ip=nat_ip_vrf10)
3270 pkts = self.create_stream_out(self.pg3, dst_ip=nat_ip_vrf10)
3271 self.pg3.add_stream(pkts)
3272 self.pg_enable_capture(self.pg_interfaces)
3274 capture = self.pg4.get_capture(len(pkts))
3275 self.verify_capture_in(capture, self.pg4)
3278 pkts = self.create_stream_in(self.pg6, self.pg3)
3279 self.pg6.add_stream(pkts)
3280 self.pg_enable_capture(self.pg_interfaces)
3282 capture = self.pg3.get_capture(len(pkts))
3283 self.verify_capture_out(capture, nat_ip=nat_ip_vrf20)
3286 pkts = self.create_stream_out(self.pg3, dst_ip=nat_ip_vrf20)
3287 self.pg3.add_stream(pkts)
3288 self.pg_enable_capture(self.pg_interfaces)
3290 capture = self.pg6.get_capture(len(pkts))
3291 self.verify_capture_in(capture, self.pg6)
3293 def test_output_feature_hairpinning(self):
3294 """ NAT44 interface output feature hairpinning (in2out postrouting) """
3295 host = self.pg0.remote_hosts[0]
3296 server = self.pg0.remote_hosts[1]
3299 server_in_port = 5678
3300 server_out_port = 8765
3302 self.nat44_add_address(self.nat_addr)
3303 self.vapi.nat44_interface_add_del_output_feature(self.pg0.sw_if_index)
3304 self.vapi.nat44_interface_add_del_output_feature(self.pg1.sw_if_index,
3307 # add static mapping for server
3308 self.nat44_add_static_mapping(server.ip4, self.nat_addr,
3309 server_in_port, server_out_port,
3310 proto=IP_PROTOS.tcp)
3312 # send packet from host to server
3313 p = (Ether(src=host.mac, dst=self.pg0.local_mac) /
3314 IP(src=host.ip4, dst=self.nat_addr) /
3315 TCP(sport=host_in_port, dport=server_out_port))
3316 self.pg0.add_stream(p)
3317 self.pg_enable_capture(self.pg_interfaces)
3319 capture = self.pg0.get_capture(1)
3324 self.assertEqual(ip.src, self.nat_addr)
3325 self.assertEqual(ip.dst, server.ip4)
3326 self.assertNotEqual(tcp.sport, host_in_port)
3327 self.assertEqual(tcp.dport, server_in_port)
3328 self.assert_packet_checksums_valid(p)
3329 host_out_port = tcp.sport
3331 self.logger.error(ppp("Unexpected or invalid packet:", p))
3334 # send reply from server to host
3335 p = (Ether(src=server.mac, dst=self.pg0.local_mac) /
3336 IP(src=server.ip4, dst=self.nat_addr) /
3337 TCP(sport=server_in_port, dport=host_out_port))
3338 self.pg0.add_stream(p)
3339 self.pg_enable_capture(self.pg_interfaces)
3341 capture = self.pg0.get_capture(1)
3346 self.assertEqual(ip.src, self.nat_addr)
3347 self.assertEqual(ip.dst, host.ip4)
3348 self.assertEqual(tcp.sport, server_out_port)
3349 self.assertEqual(tcp.dport, host_in_port)
3350 self.assert_packet_checksums_valid(p)
3352 self.logger.error(ppp("Unexpected or invalid packet:", p))
3355 def test_one_armed_nat44(self):
3356 """ One armed NAT44 """
3357 remote_host = self.pg9.remote_hosts[0]
3358 local_host = self.pg9.remote_hosts[1]
3361 self.nat44_add_address(self.nat_addr)
3362 self.vapi.nat44_interface_add_del_feature(self.pg9.sw_if_index)
3363 self.vapi.nat44_interface_add_del_feature(self.pg9.sw_if_index,
3367 p = (Ether(src=self.pg9.remote_mac, dst=self.pg9.local_mac) /
3368 IP(src=local_host.ip4, dst=remote_host.ip4) /
3369 TCP(sport=12345, dport=80))
3370 self.pg9.add_stream(p)
3371 self.pg_enable_capture(self.pg_interfaces)
3373 capture = self.pg9.get_capture(1)
3378 self.assertEqual(ip.src, self.nat_addr)
3379 self.assertEqual(ip.dst, remote_host.ip4)
3380 self.assertNotEqual(tcp.sport, 12345)
3381 external_port = tcp.sport
3382 self.assertEqual(tcp.dport, 80)
3383 self.assert_packet_checksums_valid(p)
3385 self.logger.error(ppp("Unexpected or invalid packet:", p))
3389 p = (Ether(src=self.pg9.remote_mac, dst=self.pg9.local_mac) /
3390 IP(src=remote_host.ip4, dst=self.nat_addr) /
3391 TCP(sport=80, dport=external_port))
3392 self.pg9.add_stream(p)
3393 self.pg_enable_capture(self.pg_interfaces)
3395 capture = self.pg9.get_capture(1)
3400 self.assertEqual(ip.src, remote_host.ip4)
3401 self.assertEqual(ip.dst, local_host.ip4)
3402 self.assertEqual(tcp.sport, 80)
3403 self.assertEqual(tcp.dport, 12345)
3404 self.assert_packet_checksums_valid(p)
3406 self.logger.error(ppp("Unexpected or invalid packet:", p))
3409 err = self.statistics.get_counter('/err/nat44-classify/next in2out')
3410 self.assertEqual(err, 1)
3411 err = self.statistics.get_counter('/err/nat44-classify/next out2in')
3412 self.assertEqual(err, 1)
3414 def test_del_session(self):
3415 """ Delete NAT44 session """
3416 self.nat44_add_address(self.nat_addr)
3417 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
3418 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
3421 pkts = self.create_stream_in(self.pg0, self.pg1)
3422 self.pg0.add_stream(pkts)
3423 self.pg_enable_capture(self.pg_interfaces)
3425 self.pg1.get_capture(len(pkts))
3427 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4n, 0)
3428 nsessions = len(sessions)
3430 self.vapi.nat44_del_session(sessions[0].inside_ip_address,
3431 sessions[0].inside_port,
3432 sessions[0].protocol)
3433 self.vapi.nat44_del_session(sessions[1].outside_ip_address,
3434 sessions[1].outside_port,
3435 sessions[1].protocol,
3438 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4n, 0)
3439 self.assertEqual(nsessions - len(sessions), 2)
3441 self.vapi.nat44_del_session(sessions[0].inside_ip_address,
3442 sessions[0].inside_port,
3443 sessions[0].protocol)
3445 self.verify_no_nat44_user()
3447 def test_set_get_reass(self):
3448 """ NAT44 set/get virtual fragmentation reassembly """
3449 reas_cfg1 = self.vapi.nat_get_reass()
3451 self.vapi.nat_set_reass(timeout=reas_cfg1.ip4_timeout + 5,
3452 max_reass=reas_cfg1.ip4_max_reass * 2,
3453 max_frag=reas_cfg1.ip4_max_frag * 2)
3455 reas_cfg2 = self.vapi.nat_get_reass()
3457 self.assertEqual(reas_cfg1.ip4_timeout + 5, reas_cfg2.ip4_timeout)
3458 self.assertEqual(reas_cfg1.ip4_max_reass * 2, reas_cfg2.ip4_max_reass)
3459 self.assertEqual(reas_cfg1.ip4_max_frag * 2, reas_cfg2.ip4_max_frag)
3461 self.vapi.nat_set_reass(drop_frag=1)
3462 self.assertTrue(self.vapi.nat_get_reass().ip4_drop_frag)
3464 def test_frag_in_order(self):
3465 """ NAT44 translate fragments arriving in order """
3467 self.nat44_add_address(self.nat_addr)
3468 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
3469 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
3472 self.frag_in_order(proto=IP_PROTOS.tcp)
3473 self.frag_in_order(proto=IP_PROTOS.udp)
3474 self.frag_in_order(proto=IP_PROTOS.icmp)
3476 def test_frag_forwarding(self):
3477 """ NAT44 forwarding fragment test """
3478 self.vapi.nat44_add_interface_addr(self.pg1.sw_if_index)
3479 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
3480 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
3482 self.vapi.nat44_forwarding_enable_disable(1)
3484 data = "A" * 16 + "B" * 16 + "C" * 3
3485 pkts = self.create_stream_frag(self.pg1,
3486 self.pg0.remote_ip4,
3490 proto=IP_PROTOS.udp)
3491 self.pg1.add_stream(pkts)
3492 self.pg_enable_capture(self.pg_interfaces)
3494 frags = self.pg0.get_capture(len(pkts))
3495 p = self.reass_frags_and_verify(frags,
3496 self.pg1.remote_ip4,
3497 self.pg0.remote_ip4)
3498 self.assertEqual(p[UDP].sport, 4789)
3499 self.assertEqual(p[UDP].dport, 4789)
3500 self.assertEqual(data, p[Raw].load)
3502 def test_reass_hairpinning(self):
3503 """ NAT44 fragments hairpinning """
3505 self.server = self.pg0.remote_hosts[1]
3506 self.host_in_port = random.randint(1025, 65535)
3507 self.server_in_port = random.randint(1025, 65535)
3508 self.server_out_port = random.randint(1025, 65535)
3510 self.nat44_add_address(self.nat_addr)
3511 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
3512 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
3514 # add static mapping for server
3515 self.nat44_add_static_mapping(self.server.ip4, self.nat_addr,
3516 self.server_in_port,
3517 self.server_out_port,
3518 proto=IP_PROTOS.tcp)
3519 self.nat44_add_static_mapping(self.server.ip4, self.nat_addr,
3520 self.server_in_port,
3521 self.server_out_port,
3522 proto=IP_PROTOS.udp)
3523 self.nat44_add_static_mapping(self.server.ip4, self.nat_addr)
3525 self.reass_hairpinning(proto=IP_PROTOS.tcp)
3526 self.reass_hairpinning(proto=IP_PROTOS.udp)
3527 self.reass_hairpinning(proto=IP_PROTOS.icmp)
3529 def test_frag_out_of_order(self):
3530 """ NAT44 translate fragments arriving out of order """
3532 self.nat44_add_address(self.nat_addr)
3533 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
3534 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
3537 self.frag_out_of_order(proto=IP_PROTOS.tcp)
3538 self.frag_out_of_order(proto=IP_PROTOS.udp)
3539 self.frag_out_of_order(proto=IP_PROTOS.icmp)
3541 def test_port_restricted(self):
3542 """ Port restricted NAT44 (MAP-E CE) """
3543 self.nat44_add_address(self.nat_addr)
3544 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
3545 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
3547 self.vapi.nat_set_addr_and_port_alloc_alg(alg=1,
3552 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
3553 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
3554 TCP(sport=4567, dport=22))
3555 self.pg0.add_stream(p)
3556 self.pg_enable_capture(self.pg_interfaces)
3558 capture = self.pg1.get_capture(1)
3563 self.assertEqual(ip.dst, self.pg1.remote_ip4)
3564 self.assertEqual(ip.src, self.nat_addr)
3565 self.assertEqual(tcp.dport, 22)
3566 self.assertNotEqual(tcp.sport, 4567)
3567 self.assertEqual((tcp.sport >> 6) & 63, 10)
3568 self.assert_packet_checksums_valid(p)
3570 self.logger.error(ppp("Unexpected or invalid packet:", p))
3573 def test_port_range(self):
3574 """ External address port range """
3575 self.nat44_add_address(self.nat_addr)
3576 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
3577 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
3579 self.vapi.nat_set_addr_and_port_alloc_alg(alg=2,
3584 for port in range(0, 5):
3585 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
3586 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
3587 TCP(sport=1125 + port))
3589 self.pg0.add_stream(pkts)
3590 self.pg_enable_capture(self.pg_interfaces)
3592 capture = self.pg1.get_capture(3)
3595 self.assertGreaterEqual(tcp.sport, 1025)
3596 self.assertLessEqual(tcp.sport, 1027)
3598 def test_ipfix_max_frags(self):
3599 """ IPFIX logging maximum fragments pending reassembly exceeded """
3600 self.nat44_add_address(self.nat_addr)
3601 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
3602 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
3604 self.vapi.nat_set_reass(max_frag=1)
3605 self.vapi.set_ipfix_exporter(collector_address=self.pg3.remote_ip4n,
3606 src_address=self.pg3.local_ip4n,
3608 template_interval=10)
3609 self.vapi.nat_ipfix(domain_id=self.ipfix_domain_id,
3610 src_port=self.ipfix_src_port)
3612 data = "A" * 4 + "B" * 16 + "C" * 3
3613 self.tcp_port_in = random.randint(1025, 65535)
3614 pkts = self.create_stream_frag(self.pg0,
3615 self.pg1.remote_ip4,
3620 self.pg0.add_stream(pkts)
3621 self.pg_enable_capture(self.pg_interfaces)
3623 self.pg1.assert_nothing_captured()
3625 self.vapi.cli("ipfix flush") # FIXME this should be an API call
3626 capture = self.pg3.get_capture(9)
3627 ipfix = IPFIXDecoder()
3628 # first load template
3630 self.assertTrue(p.haslayer(IPFIX))
3631 self.assertEqual(p[IP].src, self.pg3.local_ip4)
3632 self.assertEqual(p[IP].dst, self.pg3.remote_ip4)
3633 self.assertEqual(p[UDP].sport, self.ipfix_src_port)
3634 self.assertEqual(p[UDP].dport, 4739)
3635 self.assertEqual(p[IPFIX].observationDomainID,
3636 self.ipfix_domain_id)
3637 if p.haslayer(Template):
3638 ipfix.add_template(p.getlayer(Template))
3639 # verify events in data set
3641 if p.haslayer(Data):
3642 data = ipfix.decode_data_set(p.getlayer(Set))
3643 self.verify_ipfix_max_fragments_ip4(data, 1,
3644 self.pg0.remote_ip4n)
3646 def test_multiple_outside_vrf(self):
3647 """ Multiple outside VRF """
3651 self.pg1.unconfig_ip4()
3652 self.pg2.unconfig_ip4()
3653 self.vapi.ip_table_add_del(vrf_id1, is_add=1)
3654 self.vapi.ip_table_add_del(vrf_id2, is_add=1)
3655 self.pg1.set_table_ip4(vrf_id1)
3656 self.pg2.set_table_ip4(vrf_id2)
3657 self.pg1.config_ip4()
3658 self.pg2.config_ip4()
3659 self.pg1.resolve_arp()
3660 self.pg2.resolve_arp()
3662 self.nat44_add_address(self.nat_addr)
3663 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
3664 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
3666 self.vapi.nat44_interface_add_del_feature(self.pg2.sw_if_index,
3671 pkts = self.create_stream_in(self.pg0, self.pg1)
3672 self.pg0.add_stream(pkts)
3673 self.pg_enable_capture(self.pg_interfaces)
3675 capture = self.pg1.get_capture(len(pkts))
3676 self.verify_capture_out(capture, self.nat_addr)
3678 pkts = self.create_stream_out(self.pg1, self.nat_addr)
3679 self.pg1.add_stream(pkts)
3680 self.pg_enable_capture(self.pg_interfaces)
3682 capture = self.pg0.get_capture(len(pkts))
3683 self.verify_capture_in(capture, self.pg0)
3685 self.tcp_port_in = 60303
3686 self.udp_port_in = 60304
3687 self.icmp_id_in = 60305
3690 pkts = self.create_stream_in(self.pg0, self.pg2)
3691 self.pg0.add_stream(pkts)
3692 self.pg_enable_capture(self.pg_interfaces)
3694 capture = self.pg2.get_capture(len(pkts))
3695 self.verify_capture_out(capture, self.nat_addr)
3697 pkts = self.create_stream_out(self.pg2, self.nat_addr)
3698 self.pg2.add_stream(pkts)
3699 self.pg_enable_capture(self.pg_interfaces)
3701 capture = self.pg0.get_capture(len(pkts))
3702 self.verify_capture_in(capture, self.pg0)
3705 self.pg1.unconfig_ip4()
3706 self.pg2.unconfig_ip4()
3707 self.pg1.set_table_ip4(0)
3708 self.pg2.set_table_ip4(0)
3709 self.pg1.config_ip4()
3710 self.pg2.config_ip4()
3711 self.pg1.resolve_arp()
3712 self.pg2.resolve_arp()
3714 @unittest.skipUnless(running_extended_tests, "part of extended tests")
3715 def test_session_timeout(self):
3716 """ NAT44 session timeouts """
3717 self.nat44_add_address(self.nat_addr)
3718 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
3719 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
3721 self.vapi.nat_set_timeouts(udp=5)
3725 for i in range(0, max_sessions):
3726 src = "10.10.%u.%u" % ((i & 0xFF00) >> 8, i & 0xFF)
3727 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
3728 IP(src=src, dst=self.pg1.remote_ip4) /
3729 UDP(sport=1025, dport=53))
3731 self.pg0.add_stream(pkts)
3732 self.pg_enable_capture(self.pg_interfaces)
3734 self.pg1.get_capture(max_sessions)
3739 for i in range(0, max_sessions):
3740 src = "10.10.%u.%u" % ((i & 0xFF00) >> 8, i & 0xFF)
3741 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
3742 IP(src=src, dst=self.pg1.remote_ip4) /
3743 UDP(sport=1026, dport=53))
3745 self.pg0.add_stream(pkts)
3746 self.pg_enable_capture(self.pg_interfaces)
3748 self.pg1.get_capture(max_sessions)
3751 users = self.vapi.nat44_user_dump()
3753 nsessions = nsessions + user.nsessions
3754 self.assertLess(nsessions, 2 * max_sessions)
3756 def test_mss_clamping(self):
3757 """ TCP MSS clamping """
3758 self.nat44_add_address(self.nat_addr)
3759 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
3760 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
3763 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
3764 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
3765 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
3766 flags="S", options=[('MSS', 1400)]))
3768 self.vapi.nat_set_mss_clamping(enable=1, mss_value=1000)
3769 self.pg0.add_stream(p)
3770 self.pg_enable_capture(self.pg_interfaces)
3772 capture = self.pg1.get_capture(1)
3773 # Negotiated MSS value greater than configured - changed
3774 self.verify_mss_value(capture[0], 1000)
3776 self.vapi.nat_set_mss_clamping(enable=0)
3777 self.pg0.add_stream(p)
3778 self.pg_enable_capture(self.pg_interfaces)
3780 capture = self.pg1.get_capture(1)
3781 # MSS clamping disabled - negotiated MSS unchanged
3782 self.verify_mss_value(capture[0], 1400)
3784 self.vapi.nat_set_mss_clamping(enable=1, mss_value=1500)
3785 self.pg0.add_stream(p)
3786 self.pg_enable_capture(self.pg_interfaces)
3788 capture = self.pg1.get_capture(1)
3789 # Negotiated MSS value smaller than configured - unchanged
3790 self.verify_mss_value(capture[0], 1400)
3793 super(TestNAT44, self).tearDown()
3794 if not self.vpp_dead:
3795 self.logger.info(self.vapi.cli("show nat44 addresses"))
3796 self.logger.info(self.vapi.cli("show nat44 interfaces"))
3797 self.logger.info(self.vapi.cli("show nat44 static mappings"))
3798 self.logger.info(self.vapi.cli("show nat44 interface address"))
3799 self.logger.info(self.vapi.cli("show nat44 sessions detail"))
3800 self.logger.info(self.vapi.cli("show nat virtual-reassembly"))
3801 self.logger.info(self.vapi.cli("show nat44 hash tables detail"))
3802 self.logger.info(self.vapi.cli("show nat timeouts"))
3804 self.vapi.cli("show nat addr-port-assignment-alg"))
3806 self.vapi.cli("clear logging")
3809 class TestNAT44EndpointDependent(MethodHolder):
3810 """ Endpoint-Dependent mapping and filtering test cases """
3813 def setUpConstants(cls):
3814 super(TestNAT44EndpointDependent, cls).setUpConstants()
3815 cls.vpp_cmdline.extend(["nat", "{", "endpoint-dependent", "}"])
3818 def setUpClass(cls):
3819 super(TestNAT44EndpointDependent, cls).setUpClass()
3820 cls.vapi.cli("set log class nat level debug")
3822 cls.tcp_port_in = 6303
3823 cls.tcp_port_out = 6303
3824 cls.udp_port_in = 6304
3825 cls.udp_port_out = 6304
3826 cls.icmp_id_in = 6305
3827 cls.icmp_id_out = 6305
3828 cls.nat_addr = '10.0.0.3'
3829 cls.nat_addr_n = socket.inet_pton(socket.AF_INET, cls.nat_addr)
3830 cls.ipfix_src_port = 4739
3831 cls.ipfix_domain_id = 1
3832 cls.tcp_external_port = 80
3834 cls.create_pg_interfaces(range(7))
3835 cls.interfaces = list(cls.pg_interfaces[0:3])
3837 for i in cls.interfaces:
3842 cls.pg0.generate_remote_hosts(3)
3843 cls.pg0.configure_ipv4_neighbors()
3847 cls.pg4.generate_remote_hosts(2)
3848 cls.pg4.config_ip4()
3849 ip_addr_n = socket.inet_pton(socket.AF_INET, "10.0.0.1")
3850 cls.vapi.sw_interface_add_del_address(cls.pg4.sw_if_index,
3854 cls.pg4.resolve_arp()
3855 cls.pg4._remote_hosts[1]._ip4 = cls.pg4._remote_hosts[0]._ip4
3856 cls.pg4.resolve_arp()
3858 zero_ip4n = socket.inet_pton(socket.AF_INET, "0.0.0.0")
3859 cls.vapi.ip_table_add_del(1, is_add=1)
3861 cls.pg5._local_ip4 = "10.1.1.1"
3862 cls.pg5._local_ip4n = socket.inet_pton(socket.AF_INET,
3864 cls.pg5._remote_hosts[0]._ip4 = "10.1.1.2"
3865 cls.pg5._remote_hosts[0]._ip4n = socket.inet_pton(
3866 socket.AF_INET, cls.pg5.remote_ip4)
3867 cls.pg5.set_table_ip4(1)
3868 cls.pg5.config_ip4()
3870 cls.vapi.ip_add_del_route(dst_address=cls.pg5.remote_ip4n,
3871 dst_address_length=32,
3873 next_hop_sw_if_index=cls.pg5.sw_if_index,
3874 next_hop_address=zero_ip4n)
3876 cls.pg6._local_ip4 = "10.1.2.1"
3877 cls.pg6._local_ip4n = socket.inet_pton(socket.AF_INET,
3879 cls.pg6._remote_hosts[0]._ip4 = "10.1.2.2"
3880 cls.pg6._remote_hosts[0]._ip4n = socket.inet_pton(
3881 socket.AF_INET, cls.pg6.remote_ip4)
3882 cls.pg6.set_table_ip4(1)
3883 cls.pg6.config_ip4()
3885 cls.vapi.ip_add_del_route(dst_address=cls.pg6.remote_ip4n,
3886 dst_address_length=32,
3888 next_hop_sw_if_index=cls.pg6.sw_if_index,
3889 next_hop_address=zero_ip4n)
3891 cls.vapi.ip_add_del_route(dst_address=cls.pg6.remote_ip4n,
3892 dst_address_length=16,
3893 next_hop_address=zero_ip4n,
3895 next_hop_table_id=1)
3896 cls.vapi.ip_add_del_route(dst_address=zero_ip4n,
3897 dst_address_length=0,
3898 next_hop_address=zero_ip4n,
3900 next_hop_table_id=0)
3901 cls.vapi.ip_add_del_route(dst_address=zero_ip4n,
3902 dst_address_length=0,
3904 next_hop_sw_if_index=cls.pg1.sw_if_index,
3905 next_hop_address=cls.pg1.local_ip4n)
3907 cls.pg5.resolve_arp()
3908 cls.pg6.resolve_arp()
3911 super(TestNAT44EndpointDependent, cls).tearDownClass()
3914 def test_frag_in_order(self):
3915 """ NAT44 translate fragments arriving in order """
3916 self.nat44_add_address(self.nat_addr)
3917 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
3918 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
3920 self.frag_in_order(proto=IP_PROTOS.tcp)
3921 self.frag_in_order(proto=IP_PROTOS.udp)
3922 self.frag_in_order(proto=IP_PROTOS.icmp)
3924 def test_frag_in_order_dont_translate(self):
3925 """ NAT44 don't translate fragments arriving in order """
3926 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
3927 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
3929 self.vapi.nat44_forwarding_enable_disable(enable=True)
3930 self.frag_in_order(proto=IP_PROTOS.tcp, dont_translate=True)
3932 def test_frag_out_of_order(self):
3933 """ NAT44 translate fragments arriving out of order """
3934 self.nat44_add_address(self.nat_addr)
3935 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
3936 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
3938 self.frag_out_of_order(proto=IP_PROTOS.tcp)
3939 self.frag_out_of_order(proto=IP_PROTOS.udp)
3940 self.frag_out_of_order(proto=IP_PROTOS.icmp)
3942 def test_frag_out_of_order_dont_translate(self):
3943 """ NAT44 don't translate fragments arriving out of order """
3944 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
3945 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
3947 self.vapi.nat44_forwarding_enable_disable(enable=True)
3948 self.frag_out_of_order(proto=IP_PROTOS.tcp, dont_translate=True)
3950 def test_frag_in_order_in_plus_out(self):
3951 """ in+out interface fragments in order """
3952 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
3953 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index,
3955 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index)
3956 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
3959 self.server = self.pg1.remote_hosts[0]
3961 self.server_in_addr = self.server.ip4
3962 self.server_out_addr = '11.11.11.11'
3963 self.server_in_port = random.randint(1025, 65535)
3964 self.server_out_port = random.randint(1025, 65535)
3966 self.nat44_add_address(self.server_out_addr)
3968 # add static mappings for server
3969 self.nat44_add_static_mapping(self.server_in_addr,
3970 self.server_out_addr,
3971 self.server_in_port,
3972 self.server_out_port,
3973 proto=IP_PROTOS.tcp)
3974 self.nat44_add_static_mapping(self.server_in_addr,
3975 self.server_out_addr,
3976 self.server_in_port,
3977 self.server_out_port,
3978 proto=IP_PROTOS.udp)
3979 self.nat44_add_static_mapping(self.server_in_addr,
3980 self.server_out_addr,
3981 proto=IP_PROTOS.icmp)
3983 self.vapi.nat_set_reass(timeout=10)
3985 self.frag_in_order_in_plus_out(proto=IP_PROTOS.tcp)
3986 self.frag_in_order_in_plus_out(proto=IP_PROTOS.udp)
3987 self.frag_in_order_in_plus_out(proto=IP_PROTOS.icmp)
3989 def test_frag_out_of_order_in_plus_out(self):
3990 """ in+out interface fragments out of order """
3991 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
3992 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index,
3994 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index)
3995 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
3998 self.server = self.pg1.remote_hosts[0]
4000 self.server_in_addr = self.server.ip4
4001 self.server_out_addr = '11.11.11.11'
4002 self.server_in_port = random.randint(1025, 65535)
4003 self.server_out_port = random.randint(1025, 65535)
4005 self.nat44_add_address(self.server_out_addr)
4007 # add static mappings for server
4008 self.nat44_add_static_mapping(self.server_in_addr,
4009 self.server_out_addr,
4010 self.server_in_port,
4011 self.server_out_port,
4012 proto=IP_PROTOS.tcp)
4013 self.nat44_add_static_mapping(self.server_in_addr,
4014 self.server_out_addr,
4015 self.server_in_port,
4016 self.server_out_port,
4017 proto=IP_PROTOS.udp)
4018 self.nat44_add_static_mapping(self.server_in_addr,
4019 self.server_out_addr,
4020 proto=IP_PROTOS.icmp)
4022 self.vapi.nat_set_reass(timeout=10)
4024 self.frag_out_of_order_in_plus_out(proto=IP_PROTOS.tcp)
4025 self.frag_out_of_order_in_plus_out(proto=IP_PROTOS.udp)
4026 self.frag_out_of_order_in_plus_out(proto=IP_PROTOS.icmp)
4028 def test_reass_hairpinning(self):
4029 """ NAT44 fragments hairpinning """
4030 self.server = self.pg0.remote_hosts[1]
4031 self.host_in_port = random.randint(1025, 65535)
4032 self.server_in_port = random.randint(1025, 65535)
4033 self.server_out_port = random.randint(1025, 65535)
4035 self.nat44_add_address(self.nat_addr)
4036 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
4037 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
4039 # add static mapping for server
4040 self.nat44_add_static_mapping(self.server.ip4, self.nat_addr,
4041 self.server_in_port,
4042 self.server_out_port,
4043 proto=IP_PROTOS.tcp)
4044 self.nat44_add_static_mapping(self.server.ip4, self.nat_addr,
4045 self.server_in_port,
4046 self.server_out_port,
4047 proto=IP_PROTOS.udp)
4048 self.nat44_add_static_mapping(self.server.ip4, self.nat_addr)
4050 self.reass_hairpinning(proto=IP_PROTOS.tcp)
4051 self.reass_hairpinning(proto=IP_PROTOS.udp)
4052 self.reass_hairpinning(proto=IP_PROTOS.icmp)
4054 def test_dynamic(self):
4055 """ NAT44 dynamic translation test """
4057 self.nat44_add_address(self.nat_addr)
4058 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
4059 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
4062 nat_config = self.vapi.nat_show_config()
4063 self.assertEqual(1, nat_config.endpoint_dependent)
4066 tcpn = self.statistics.get_counter(
4067 '/err/nat44-ed-in2out-slowpath/TCP packets')
4068 udpn = self.statistics.get_counter(
4069 '/err/nat44-ed-in2out-slowpath/UDP packets')
4070 icmpn = self.statistics.get_counter(
4071 '/err/nat44-ed-in2out-slowpath/ICMP packets')
4072 totaln = self.statistics.get_counter(
4073 '/err/nat44-ed-in2out-slowpath/good in2out packets processed')
4075 pkts = self.create_stream_in(self.pg0, self.pg1)
4076 self.pg0.add_stream(pkts)
4077 self.pg_enable_capture(self.pg_interfaces)
4079 capture = self.pg1.get_capture(len(pkts))
4080 self.verify_capture_out(capture)
4082 err = self.statistics.get_counter(
4083 '/err/nat44-ed-in2out-slowpath/TCP packets')
4084 self.assertEqual(err - tcpn, 1)
4085 err = self.statistics.get_counter(
4086 '/err/nat44-ed-in2out-slowpath/UDP packets')
4087 self.assertEqual(err - udpn, 1)
4088 err = self.statistics.get_counter(
4089 '/err/nat44-ed-in2out-slowpath/ICMP packets')
4090 self.assertEqual(err - icmpn, 1)
4091 err = self.statistics.get_counter(
4092 '/err/nat44-ed-in2out-slowpath/good in2out packets processed')
4093 self.assertEqual(err - totaln, 3)
4096 tcpn = self.statistics.get_counter('/err/nat44-ed-out2in/TCP packets')
4097 udpn = self.statistics.get_counter('/err/nat44-ed-out2in/UDP packets')
4098 icmpn = self.statistics.get_counter(
4099 '/err/nat44-ed-out2in-slowpath/ICMP packets')
4100 totaln = self.statistics.get_counter(
4101 '/err/nat44-ed-out2in/good out2in packets processed')
4103 pkts = self.create_stream_out(self.pg1)
4104 self.pg1.add_stream(pkts)
4105 self.pg_enable_capture(self.pg_interfaces)
4107 capture = self.pg0.get_capture(len(pkts))
4108 self.verify_capture_in(capture, self.pg0)
4110 err = self.statistics.get_counter('/err/nat44-ed-out2in/TCP packets')
4111 self.assertEqual(err - tcpn, 1)
4112 err = self.statistics.get_counter('/err/nat44-ed-out2in/UDP packets')
4113 self.assertEqual(err - udpn, 1)
4114 err = self.statistics.get_counter(
4115 '/err/nat44-ed-out2in-slowpath/ICMP packets')
4116 self.assertEqual(err - icmpn, 1)
4117 err = self.statistics.get_counter(
4118 '/err/nat44-ed-out2in/good out2in packets processed')
4119 self.assertEqual(err - totaln, 2)
4121 users = self.statistics.get_counter('/nat44/total-users')
4122 self.assertEqual(users[0][0], 1)
4123 sessions = self.statistics.get_counter('/nat44/total-sessions')
4124 self.assertEqual(sessions[0][0], 3)
4126 def test_forwarding(self):
4127 """ NAT44 forwarding test """
4129 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
4130 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
4132 self.vapi.nat44_forwarding_enable_disable(1)
4134 real_ip = self.pg0.remote_ip4n
4135 alias_ip = self.nat_addr_n
4136 self.vapi.nat44_add_del_static_mapping(local_ip=real_ip,
4137 external_ip=alias_ip)
4140 # in2out - static mapping match
4142 pkts = self.create_stream_out(self.pg1)
4143 self.pg1.add_stream(pkts)
4144 self.pg_enable_capture(self.pg_interfaces)
4146 capture = self.pg0.get_capture(len(pkts))
4147 self.verify_capture_in(capture, self.pg0)
4149 pkts = self.create_stream_in(self.pg0, self.pg1)
4150 self.pg0.add_stream(pkts)
4151 self.pg_enable_capture(self.pg_interfaces)
4153 capture = self.pg1.get_capture(len(pkts))
4154 self.verify_capture_out(capture, same_port=True)
4156 # in2out - no static mapping match
4158 host0 = self.pg0.remote_hosts[0]
4159 self.pg0.remote_hosts[0] = self.pg0.remote_hosts[1]
4161 pkts = self.create_stream_out(self.pg1,
4162 dst_ip=self.pg0.remote_ip4,
4163 use_inside_ports=True)
4164 self.pg1.add_stream(pkts)
4165 self.pg_enable_capture(self.pg_interfaces)
4167 capture = self.pg0.get_capture(len(pkts))
4168 self.verify_capture_in(capture, self.pg0)
4170 pkts = self.create_stream_in(self.pg0, self.pg1)
4171 self.pg0.add_stream(pkts)
4172 self.pg_enable_capture(self.pg_interfaces)
4174 capture = self.pg1.get_capture(len(pkts))
4175 self.verify_capture_out(capture, nat_ip=self.pg0.remote_ip4,
4178 self.pg0.remote_hosts[0] = host0
4180 user = self.pg0.remote_hosts[1]
4181 sessions = self.vapi.nat44_user_session_dump(user.ip4n, 0)
4182 self.assertEqual(len(sessions), 3)
4183 self.assertTrue(sessions[0].ext_host_valid)
4184 self.vapi.nat44_del_session(
4185 sessions[0].inside_ip_address,
4186 sessions[0].inside_port,
4187 sessions[0].protocol,
4188 ext_host_address=sessions[0].ext_host_address,
4189 ext_host_port=sessions[0].ext_host_port)
4190 sessions = self.vapi.nat44_user_session_dump(user.ip4n, 0)
4191 self.assertEqual(len(sessions), 2)
4194 self.vapi.nat44_forwarding_enable_disable(0)
4195 self.vapi.nat44_add_del_static_mapping(local_ip=real_ip,
4196 external_ip=alias_ip,
4199 def test_static_lb(self):
4200 """ NAT44 local service load balancing """
4201 external_addr_n = socket.inet_pton(socket.AF_INET, self.nat_addr)
4204 server1 = self.pg0.remote_hosts[0]
4205 server2 = self.pg0.remote_hosts[1]
4207 locals = [{'addr': server1.ip4n,
4211 {'addr': server2.ip4n,
4216 self.nat44_add_address(self.nat_addr)
4217 self.vapi.nat44_add_del_lb_static_mapping(external_addr_n,
4220 local_num=len(locals),
4222 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
4223 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
4226 # from client to service
4227 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
4228 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
4229 TCP(sport=12345, dport=external_port))
4230 self.pg1.add_stream(p)
4231 self.pg_enable_capture(self.pg_interfaces)
4233 capture = self.pg0.get_capture(1)
4239 self.assertIn(ip.dst, [server1.ip4, server2.ip4])
4240 if ip.dst == server1.ip4:
4244 self.assertEqual(tcp.dport, local_port)
4245 self.assert_packet_checksums_valid(p)
4247 self.logger.error(ppp("Unexpected or invalid packet:", p))
4250 # from service back to client
4251 p = (Ether(src=server.mac, dst=self.pg0.local_mac) /
4252 IP(src=server.ip4, dst=self.pg1.remote_ip4) /
4253 TCP(sport=local_port, dport=12345))
4254 self.pg0.add_stream(p)
4255 self.pg_enable_capture(self.pg_interfaces)
4257 capture = self.pg1.get_capture(1)
4262 self.assertEqual(ip.src, self.nat_addr)
4263 self.assertEqual(tcp.sport, external_port)
4264 self.assert_packet_checksums_valid(p)
4266 self.logger.error(ppp("Unexpected or invalid packet:", p))
4269 sessions = self.vapi.nat44_user_session_dump(server.ip4n, 0)
4270 self.assertEqual(len(sessions), 1)
4271 self.assertTrue(sessions[0].ext_host_valid)
4272 self.vapi.nat44_del_session(
4273 sessions[0].inside_ip_address,
4274 sessions[0].inside_port,
4275 sessions[0].protocol,
4276 ext_host_address=sessions[0].ext_host_address,
4277 ext_host_port=sessions[0].ext_host_port)
4278 sessions = self.vapi.nat44_user_session_dump(server.ip4n, 0)
4279 self.assertEqual(len(sessions), 0)
4281 @unittest.skipUnless(running_extended_tests, "part of extended tests")
4282 def test_static_lb_multi_clients(self):
4283 """ NAT44 local service load balancing - multiple clients"""
4285 external_addr_n = socket.inet_pton(socket.AF_INET, self.nat_addr)
4288 server1 = self.pg0.remote_hosts[0]
4289 server2 = self.pg0.remote_hosts[1]
4290 server3 = self.pg0.remote_hosts[2]
4292 locals = [{'addr': server1.ip4n,
4296 {'addr': server2.ip4n,
4301 self.nat44_add_address(self.nat_addr)
4302 self.vapi.nat44_add_del_lb_static_mapping(external_addr_n,
4305 local_num=len(locals),
4307 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
4308 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
4313 clients = ip4_range(self.pg1.remote_ip4, 10, 50)
4315 for client in clients:
4316 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
4317 IP(src=client, dst=self.nat_addr) /
4318 TCP(sport=12345, dport=external_port))
4320 self.pg1.add_stream(pkts)
4321 self.pg_enable_capture(self.pg_interfaces)
4323 capture = self.pg0.get_capture(len(pkts))
4325 if p[IP].dst == server1.ip4:
4329 self.assertGreater(server1_n, server2_n)
4332 self.vapi.nat44_lb_static_mapping_add_del_local(external_addr_n,
4341 clients = ip4_range(self.pg1.remote_ip4, 60, 110)
4343 for client in clients:
4344 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
4345 IP(src=client, dst=self.nat_addr) /
4346 TCP(sport=12346, dport=external_port))
4348 self.assertGreater(len(pkts), 0)
4349 self.pg1.add_stream(pkts)
4350 self.pg_enable_capture(self.pg_interfaces)
4352 capture = self.pg0.get_capture(len(pkts))
4354 if p[IP].dst == server1.ip4:
4356 elif p[IP].dst == server2.ip4:
4360 self.assertGreater(server1_n, 0)
4361 self.assertGreater(server2_n, 0)
4362 self.assertGreater(server3_n, 0)
4364 # remove one back-end
4365 self.vapi.nat44_lb_static_mapping_add_del_local(external_addr_n,
4375 self.pg1.add_stream(pkts)
4376 self.pg_enable_capture(self.pg_interfaces)
4378 capture = self.pg0.get_capture(len(pkts))
4380 if p[IP].dst == server1.ip4:
4382 elif p[IP].dst == server2.ip4:
4386 self.assertGreater(server1_n, 0)
4387 self.assertEqual(server2_n, 0)
4388 self.assertGreater(server3_n, 0)
4390 def test_static_lb_2(self):
4391 """ NAT44 local service load balancing (asymmetrical rule) """
4392 external_addr_n = socket.inet_pton(socket.AF_INET, self.nat_addr)
4395 server1 = self.pg0.remote_hosts[0]
4396 server2 = self.pg0.remote_hosts[1]
4398 locals = [{'addr': server1.ip4n,
4402 {'addr': server2.ip4n,
4407 self.vapi.nat44_forwarding_enable_disable(1)
4408 self.vapi.nat44_add_del_lb_static_mapping(external_addr_n,
4412 local_num=len(locals),
4414 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
4415 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
4418 # from client to service
4419 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
4420 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
4421 TCP(sport=12345, dport=external_port))
4422 self.pg1.add_stream(p)
4423 self.pg_enable_capture(self.pg_interfaces)
4425 capture = self.pg0.get_capture(1)
4431 self.assertIn(ip.dst, [server1.ip4, server2.ip4])
4432 if ip.dst == server1.ip4:
4436 self.assertEqual(tcp.dport, local_port)
4437 self.assert_packet_checksums_valid(p)
4439 self.logger.error(ppp("Unexpected or invalid packet:", p))
4442 # from service back to client
4443 p = (Ether(src=server.mac, dst=self.pg0.local_mac) /
4444 IP(src=server.ip4, dst=self.pg1.remote_ip4) /
4445 TCP(sport=local_port, dport=12345))
4446 self.pg0.add_stream(p)
4447 self.pg_enable_capture(self.pg_interfaces)
4449 capture = self.pg1.get_capture(1)
4454 self.assertEqual(ip.src, self.nat_addr)
4455 self.assertEqual(tcp.sport, external_port)
4456 self.assert_packet_checksums_valid(p)
4458 self.logger.error(ppp("Unexpected or invalid packet:", p))
4461 # from client to server (no translation)
4462 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
4463 IP(src=self.pg1.remote_ip4, dst=server1.ip4) /
4464 TCP(sport=12346, dport=local_port))
4465 self.pg1.add_stream(p)
4466 self.pg_enable_capture(self.pg_interfaces)
4468 capture = self.pg0.get_capture(1)
4474 self.assertEqual(ip.dst, server1.ip4)
4475 self.assertEqual(tcp.dport, local_port)
4476 self.assert_packet_checksums_valid(p)
4478 self.logger.error(ppp("Unexpected or invalid packet:", p))
4481 # from service back to client (no translation)
4482 p = (Ether(src=server1.mac, dst=self.pg0.local_mac) /
4483 IP(src=server1.ip4, dst=self.pg1.remote_ip4) /
4484 TCP(sport=local_port, dport=12346))
4485 self.pg0.add_stream(p)
4486 self.pg_enable_capture(self.pg_interfaces)
4488 capture = self.pg1.get_capture(1)
4493 self.assertEqual(ip.src, server1.ip4)
4494 self.assertEqual(tcp.sport, local_port)
4495 self.assert_packet_checksums_valid(p)
4497 self.logger.error(ppp("Unexpected or invalid packet:", p))
4500 def test_lb_affinity(self):
4501 """ NAT44 local service load balancing affinity """
4502 external_addr_n = socket.inet_pton(socket.AF_INET, self.nat_addr)
4505 server1 = self.pg0.remote_hosts[0]
4506 server2 = self.pg0.remote_hosts[1]
4508 locals = [{'addr': server1.ip4n,
4512 {'addr': server2.ip4n,
4517 self.nat44_add_address(self.nat_addr)
4518 self.vapi.nat44_add_del_lb_static_mapping(external_addr_n,
4522 local_num=len(locals),
4524 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
4525 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
4528 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
4529 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
4530 TCP(sport=1025, dport=external_port))
4531 self.pg1.add_stream(p)
4532 self.pg_enable_capture(self.pg_interfaces)
4534 capture = self.pg0.get_capture(1)
4535 backend = capture[0][IP].dst
4537 sessions = self.vapi.nat44_user_session_dump(
4538 socket.inet_pton(socket.AF_INET, backend), 0)
4539 self.assertEqual(len(sessions), 1)
4540 self.assertTrue(sessions[0].ext_host_valid)
4541 self.vapi.nat44_del_session(
4542 sessions[0].inside_ip_address,
4543 sessions[0].inside_port,
4544 sessions[0].protocol,
4545 ext_host_address=sessions[0].ext_host_address,
4546 ext_host_port=sessions[0].ext_host_port)
4549 for port in range(1030, 1100):
4550 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
4551 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
4552 TCP(sport=port, dport=external_port))
4554 self.pg1.add_stream(pkts)
4555 self.pg_enable_capture(self.pg_interfaces)
4557 capture = self.pg0.get_capture(len(pkts))
4559 self.assertEqual(p[IP].dst, backend)
4561 def test_unknown_proto(self):
4562 """ NAT44 translate packet with unknown protocol """
4563 self.nat44_add_address(self.nat_addr)
4564 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
4565 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
4569 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
4570 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
4571 TCP(sport=self.tcp_port_in, dport=20))
4572 self.pg0.add_stream(p)
4573 self.pg_enable_capture(self.pg_interfaces)
4575 p = self.pg1.get_capture(1)
4577 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
4578 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
4580 IP(src=self.pg2.remote_ip4, dst=self.pg2.remote_ip4) /
4581 TCP(sport=1234, dport=1234))
4582 self.pg0.add_stream(p)
4583 self.pg_enable_capture(self.pg_interfaces)
4585 p = self.pg1.get_capture(1)
4588 self.assertEqual(packet[IP].src, self.nat_addr)
4589 self.assertEqual(packet[IP].dst, self.pg1.remote_ip4)
4590 self.assertEqual(packet.haslayer(GRE), 1)
4591 self.assert_packet_checksums_valid(packet)
4593 self.logger.error(ppp("Unexpected or invalid packet:", packet))
4597 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
4598 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
4600 IP(src=self.pg2.remote_ip4, dst=self.pg2.remote_ip4) /
4601 TCP(sport=1234, dport=1234))
4602 self.pg1.add_stream(p)
4603 self.pg_enable_capture(self.pg_interfaces)
4605 p = self.pg0.get_capture(1)
4608 self.assertEqual(packet[IP].src, self.pg1.remote_ip4)
4609 self.assertEqual(packet[IP].dst, self.pg0.remote_ip4)
4610 self.assertEqual(packet.haslayer(GRE), 1)
4611 self.assert_packet_checksums_valid(packet)
4613 self.logger.error(ppp("Unexpected or invalid packet:", packet))
4616 def test_hairpinning_unknown_proto(self):
4617 """ NAT44 translate packet with unknown protocol - hairpinning """
4618 host = self.pg0.remote_hosts[0]
4619 server = self.pg0.remote_hosts[1]
4621 server_out_port = 8765
4622 server_nat_ip = "10.0.0.11"
4624 self.nat44_add_address(self.nat_addr)
4625 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
4626 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
4629 # add static mapping for server
4630 self.nat44_add_static_mapping(server.ip4, server_nat_ip)
4633 p = (Ether(src=host.mac, dst=self.pg0.local_mac) /
4634 IP(src=host.ip4, dst=server_nat_ip) /
4635 TCP(sport=host_in_port, dport=server_out_port))
4636 self.pg0.add_stream(p)
4637 self.pg_enable_capture(self.pg_interfaces)
4639 self.pg0.get_capture(1)
4641 p = (Ether(dst=self.pg0.local_mac, src=host.mac) /
4642 IP(src=host.ip4, dst=server_nat_ip) /
4644 IP(src=self.pg2.remote_ip4, dst=self.pg2.remote_ip4) /
4645 TCP(sport=1234, dport=1234))
4646 self.pg0.add_stream(p)
4647 self.pg_enable_capture(self.pg_interfaces)
4649 p = self.pg0.get_capture(1)
4652 self.assertEqual(packet[IP].src, self.nat_addr)
4653 self.assertEqual(packet[IP].dst, server.ip4)
4654 self.assertEqual(packet.haslayer(GRE), 1)
4655 self.assert_packet_checksums_valid(packet)
4657 self.logger.error(ppp("Unexpected or invalid packet:", packet))
4661 p = (Ether(dst=self.pg0.local_mac, src=server.mac) /
4662 IP(src=server.ip4, dst=self.nat_addr) /
4664 IP(src=self.pg2.remote_ip4, dst=self.pg2.remote_ip4) /
4665 TCP(sport=1234, dport=1234))
4666 self.pg0.add_stream(p)
4667 self.pg_enable_capture(self.pg_interfaces)
4669 p = self.pg0.get_capture(1)
4672 self.assertEqual(packet[IP].src, server_nat_ip)
4673 self.assertEqual(packet[IP].dst, host.ip4)
4674 self.assertEqual(packet.haslayer(GRE), 1)
4675 self.assert_packet_checksums_valid(packet)
4677 self.logger.error(ppp("Unexpected or invalid packet:", packet))
4680 def test_output_feature_and_service(self):
4681 """ NAT44 interface output feature and services """
4682 external_addr = '1.2.3.4'
4686 self.vapi.nat44_forwarding_enable_disable(1)
4687 self.nat44_add_address(self.nat_addr)
4688 self.vapi.nat44_add_del_identity_mapping(ip=self.pg1.remote_ip4n)
4689 self.nat44_add_static_mapping(self.pg0.remote_ip4, external_addr,
4690 local_port, external_port,
4691 proto=IP_PROTOS.tcp, out2in_only=1)
4692 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
4693 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index,
4695 self.vapi.nat44_interface_add_del_output_feature(self.pg1.sw_if_index,
4698 # from client to service
4699 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
4700 IP(src=self.pg1.remote_ip4, dst=external_addr) /
4701 TCP(sport=12345, dport=external_port))
4702 self.pg1.add_stream(p)
4703 self.pg_enable_capture(self.pg_interfaces)
4705 capture = self.pg0.get_capture(1)
4710 self.assertEqual(ip.dst, self.pg0.remote_ip4)
4711 self.assertEqual(tcp.dport, local_port)
4712 self.assert_packet_checksums_valid(p)
4714 self.logger.error(ppp("Unexpected or invalid packet:", p))
4717 # from service back to client
4718 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
4719 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
4720 TCP(sport=local_port, dport=12345))
4721 self.pg0.add_stream(p)
4722 self.pg_enable_capture(self.pg_interfaces)
4724 capture = self.pg1.get_capture(1)
4729 self.assertEqual(ip.src, external_addr)
4730 self.assertEqual(tcp.sport, external_port)
4731 self.assert_packet_checksums_valid(p)
4733 self.logger.error(ppp("Unexpected or invalid packet:", p))
4736 # from local network host to external network
4737 pkts = self.create_stream_in(self.pg0, self.pg1)
4738 self.pg0.add_stream(pkts)
4739 self.pg_enable_capture(self.pg_interfaces)
4741 capture = self.pg1.get_capture(len(pkts))
4742 self.verify_capture_out(capture)
4743 pkts = self.create_stream_in(self.pg0, self.pg1)
4744 self.pg0.add_stream(pkts)
4745 self.pg_enable_capture(self.pg_interfaces)
4747 capture = self.pg1.get_capture(len(pkts))
4748 self.verify_capture_out(capture)
4750 # from external network back to local network host
4751 pkts = self.create_stream_out(self.pg1)
4752 self.pg1.add_stream(pkts)
4753 self.pg_enable_capture(self.pg_interfaces)
4755 capture = self.pg0.get_capture(len(pkts))
4756 self.verify_capture_in(capture, self.pg0)
4758 def test_output_feature_and_service2(self):
4759 """ NAT44 interface output feature and service host direct access """
4760 self.vapi.nat44_forwarding_enable_disable(1)
4761 self.nat44_add_address(self.nat_addr)
4762 self.vapi.nat44_interface_add_del_output_feature(self.pg1.sw_if_index,
4765 # session initiaded from service host - translate
4766 pkts = self.create_stream_in(self.pg0, self.pg1)
4767 self.pg0.add_stream(pkts)
4768 self.pg_enable_capture(self.pg_interfaces)
4770 capture = self.pg1.get_capture(len(pkts))
4771 self.verify_capture_out(capture)
4773 pkts = self.create_stream_out(self.pg1)
4774 self.pg1.add_stream(pkts)
4775 self.pg_enable_capture(self.pg_interfaces)
4777 capture = self.pg0.get_capture(len(pkts))
4778 self.verify_capture_in(capture, self.pg0)
4780 # session initiaded from remote host - do not translate
4781 self.tcp_port_in = 60303
4782 self.udp_port_in = 60304
4783 self.icmp_id_in = 60305
4784 pkts = self.create_stream_out(self.pg1,
4785 self.pg0.remote_ip4,
4786 use_inside_ports=True)
4787 self.pg1.add_stream(pkts)
4788 self.pg_enable_capture(self.pg_interfaces)
4790 capture = self.pg0.get_capture(len(pkts))
4791 self.verify_capture_in(capture, self.pg0)
4793 pkts = self.create_stream_in(self.pg0, self.pg1)
4794 self.pg0.add_stream(pkts)
4795 self.pg_enable_capture(self.pg_interfaces)
4797 capture = self.pg1.get_capture(len(pkts))
4798 self.verify_capture_out(capture, nat_ip=self.pg0.remote_ip4,
4801 def test_output_feature_and_service3(self):
4802 """ NAT44 interface output feature and DST NAT """
4803 external_addr = '1.2.3.4'
4807 self.vapi.nat44_forwarding_enable_disable(1)
4808 self.nat44_add_address(self.nat_addr)
4809 self.nat44_add_static_mapping(self.pg1.remote_ip4, external_addr,
4810 local_port, external_port,
4811 proto=IP_PROTOS.tcp, out2in_only=1)
4812 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
4813 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index,
4815 self.vapi.nat44_interface_add_del_output_feature(self.pg1.sw_if_index,
4818 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
4819 IP(src=self.pg0.remote_ip4, dst=external_addr) /
4820 TCP(sport=12345, dport=external_port))
4821 self.pg0.add_stream(p)
4822 self.pg_enable_capture(self.pg_interfaces)
4824 capture = self.pg1.get_capture(1)
4829 self.assertEqual(ip.src, self.pg0.remote_ip4)
4830 self.assertEqual(tcp.sport, 12345)
4831 self.assertEqual(ip.dst, self.pg1.remote_ip4)
4832 self.assertEqual(tcp.dport, local_port)
4833 self.assert_packet_checksums_valid(p)
4835 self.logger.error(ppp("Unexpected or invalid packet:", p))
4838 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
4839 IP(src=self.pg1.remote_ip4, dst=self.pg0.remote_ip4) /
4840 TCP(sport=local_port, dport=12345))
4841 self.pg1.add_stream(p)
4842 self.pg_enable_capture(self.pg_interfaces)
4844 capture = self.pg0.get_capture(1)
4849 self.assertEqual(ip.src, external_addr)
4850 self.assertEqual(tcp.sport, external_port)
4851 self.assertEqual(ip.dst, self.pg0.remote_ip4)
4852 self.assertEqual(tcp.dport, 12345)
4853 self.assert_packet_checksums_valid(p)
4855 self.logger.error(ppp("Unexpected or invalid packet:", p))
4858 def test_next_src_nat(self):
4859 """ On way back forward packet to nat44-in2out node. """
4860 twice_nat_addr = '10.0.1.3'
4863 post_twice_nat_port = 0
4865 self.vapi.nat44_forwarding_enable_disable(1)
4866 self.nat44_add_address(twice_nat_addr, twice_nat=1)
4867 self.nat44_add_static_mapping(self.pg6.remote_ip4, self.pg1.remote_ip4,
4868 local_port, external_port,
4869 proto=IP_PROTOS.tcp, out2in_only=1,
4870 self_twice_nat=1, vrf_id=1)
4871 self.vapi.nat44_interface_add_del_feature(self.pg6.sw_if_index,
4874 p = (Ether(src=self.pg6.remote_mac, dst=self.pg6.local_mac) /
4875 IP(src=self.pg6.remote_ip4, dst=self.pg1.remote_ip4) /
4876 TCP(sport=12345, dport=external_port))
4877 self.pg6.add_stream(p)
4878 self.pg_enable_capture(self.pg_interfaces)
4880 capture = self.pg6.get_capture(1)
4885 self.assertEqual(ip.src, twice_nat_addr)
4886 self.assertNotEqual(tcp.sport, 12345)
4887 post_twice_nat_port = tcp.sport
4888 self.assertEqual(ip.dst, self.pg6.remote_ip4)
4889 self.assertEqual(tcp.dport, local_port)
4890 self.assert_packet_checksums_valid(p)
4892 self.logger.error(ppp("Unexpected or invalid packet:", p))
4895 p = (Ether(src=self.pg6.remote_mac, dst=self.pg6.local_mac) /
4896 IP(src=self.pg6.remote_ip4, dst=twice_nat_addr) /
4897 TCP(sport=local_port, dport=post_twice_nat_port))
4898 self.pg6.add_stream(p)
4899 self.pg_enable_capture(self.pg_interfaces)
4901 capture = self.pg6.get_capture(1)
4906 self.assertEqual(ip.src, self.pg1.remote_ip4)
4907 self.assertEqual(tcp.sport, external_port)
4908 self.assertEqual(ip.dst, self.pg6.remote_ip4)
4909 self.assertEqual(tcp.dport, 12345)
4910 self.assert_packet_checksums_valid(p)
4912 self.logger.error(ppp("Unexpected or invalid packet:", p))
4915 def twice_nat_common(self, self_twice_nat=False, same_pg=False, lb=False,
4917 twice_nat_addr = '10.0.1.3'
4925 port_in1 = port_in+1
4926 port_in2 = port_in+2
4931 server1 = self.pg0.remote_hosts[0]
4932 server2 = self.pg0.remote_hosts[1]
4944 eh_translate = ((not self_twice_nat) or (not lb and same_pg) or
4947 self.nat44_add_address(self.nat_addr)
4948 self.nat44_add_address(twice_nat_addr, twice_nat=1)
4950 self.nat44_add_static_mapping(pg0.remote_ip4, self.nat_addr,
4952 proto=IP_PROTOS.tcp,
4953 twice_nat=int(not self_twice_nat),
4954 self_twice_nat=int(self_twice_nat))
4956 locals = [{'addr': server1.ip4n,
4960 {'addr': server2.ip4n,
4964 out_addr_n = socket.inet_pton(socket.AF_INET, self.nat_addr)
4965 self.vapi.nat44_add_del_lb_static_mapping(out_addr_n,
4969 not self_twice_nat),
4972 local_num=len(locals),
4974 self.vapi.nat44_interface_add_del_feature(pg0.sw_if_index)
4975 self.vapi.nat44_interface_add_del_feature(pg1.sw_if_index,
4982 assert client_id is not None
4984 client = self.pg0.remote_hosts[0]
4985 elif client_id == 2:
4986 client = self.pg0.remote_hosts[1]
4988 client = pg1.remote_hosts[0]
4989 p = (Ether(src=pg1.remote_mac, dst=pg1.local_mac) /
4990 IP(src=client.ip4, dst=self.nat_addr) /
4991 TCP(sport=eh_port_out, dport=port_out))
4993 self.pg_enable_capture(self.pg_interfaces)
4995 capture = pg0.get_capture(1)
5001 if ip.dst == server1.ip4:
5007 self.assertEqual(ip.dst, server.ip4)
5009 self.assertIn(tcp.dport, [port_in1, port_in2])
5011 self.assertEqual(tcp.dport, port_in)
5013 self.assertEqual(ip.src, twice_nat_addr)
5014 self.assertNotEqual(tcp.sport, eh_port_out)
5016 self.assertEqual(ip.src, client.ip4)
5017 self.assertEqual(tcp.sport, eh_port_out)
5019 eh_port_in = tcp.sport
5020 saved_port_in = tcp.dport
5021 self.assert_packet_checksums_valid(p)
5023 self.logger.error(ppp("Unexpected or invalid packet:", p))
5026 p = (Ether(src=server.mac, dst=pg0.local_mac) /
5027 IP(src=server.ip4, dst=eh_addr_in) /
5028 TCP(sport=saved_port_in, dport=eh_port_in))
5030 self.pg_enable_capture(self.pg_interfaces)
5032 capture = pg1.get_capture(1)
5037 self.assertEqual(ip.dst, client.ip4)
5038 self.assertEqual(ip.src, self.nat_addr)
5039 self.assertEqual(tcp.dport, eh_port_out)
5040 self.assertEqual(tcp.sport, port_out)
5041 self.assert_packet_checksums_valid(p)
5043 self.logger.error(ppp("Unexpected or invalid packet:", p))
5047 sessions = self.vapi.nat44_user_session_dump(server.ip4n, 0)
5048 self.assertEqual(len(sessions), 1)
5049 self.assertTrue(sessions[0].ext_host_valid)
5050 self.assertTrue(sessions[0].is_twicenat)
5051 self.vapi.nat44_del_session(
5052 sessions[0].inside_ip_address,
5053 sessions[0].inside_port,
5054 sessions[0].protocol,
5055 ext_host_address=sessions[0].ext_host_nat_address,
5056 ext_host_port=sessions[0].ext_host_nat_port)
5057 sessions = self.vapi.nat44_user_session_dump(server.ip4n, 0)
5058 self.assertEqual(len(sessions), 0)
5060 def test_twice_nat(self):
5062 self.twice_nat_common()
5064 def test_self_twice_nat_positive(self):
5065 """ Self Twice NAT44 (positive test) """
5066 self.twice_nat_common(self_twice_nat=True, same_pg=True)
5068 def test_self_twice_nat_negative(self):
5069 """ Self Twice NAT44 (negative test) """
5070 self.twice_nat_common(self_twice_nat=True)
5072 def test_twice_nat_lb(self):
5073 """ Twice NAT44 local service load balancing """
5074 self.twice_nat_common(lb=True)
5076 def test_self_twice_nat_lb_positive(self):
5077 """ Self Twice NAT44 local service load balancing (positive test) """
5078 self.twice_nat_common(lb=True, self_twice_nat=True, same_pg=True,
5081 def test_self_twice_nat_lb_negative(self):
5082 """ Self Twice NAT44 local service load balancing (negative test) """
5083 self.twice_nat_common(lb=True, self_twice_nat=True, same_pg=True,
5086 def test_twice_nat_interface_addr(self):
5087 """ Acquire twice NAT44 addresses from interface """
5088 self.vapi.nat44_add_interface_addr(self.pg3.sw_if_index, twice_nat=1)
5090 # no address in NAT pool
5091 adresses = self.vapi.nat44_address_dump()
5092 self.assertEqual(0, len(adresses))
5094 # configure interface address and check NAT address pool
5095 self.pg3.config_ip4()
5096 adresses = self.vapi.nat44_address_dump()
5097 self.assertEqual(1, len(adresses))
5098 self.assertEqual(adresses[0].ip_address[0:4], self.pg3.local_ip4n)
5099 self.assertEqual(adresses[0].twice_nat, 1)
5101 # remove interface address and check NAT address pool
5102 self.pg3.unconfig_ip4()
5103 adresses = self.vapi.nat44_address_dump()
5104 self.assertEqual(0, len(adresses))
5106 def test_tcp_close(self):
5107 """ Close TCP session from inside network - output feature """
5108 self.vapi.nat44_forwarding_enable_disable(1)
5109 self.nat44_add_address(self.pg1.local_ip4)
5110 twice_nat_addr = '10.0.1.3'
5111 service_ip = '192.168.16.150'
5112 self.nat44_add_address(twice_nat_addr, twice_nat=1)
5113 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
5114 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index,
5116 self.vapi.nat44_interface_add_del_output_feature(self.pg1.sw_if_index,
5118 self.nat44_add_static_mapping(self.pg0.remote_ip4,
5122 proto=IP_PROTOS.tcp,
5125 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4n, 0)
5126 start_sessnum = len(sessions)
5128 # SYN packet out->in
5129 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
5130 IP(src=self.pg1.remote_ip4, dst=service_ip) /
5131 TCP(sport=33898, dport=80, flags="S"))
5132 self.pg1.add_stream(p)
5133 self.pg_enable_capture(self.pg_interfaces)
5135 capture = self.pg0.get_capture(1)
5137 tcp_port = p[TCP].sport
5139 # SYN + ACK packet in->out
5140 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5141 IP(src=self.pg0.remote_ip4, dst=twice_nat_addr) /
5142 TCP(sport=80, dport=tcp_port, flags="SA"))
5143 self.pg0.add_stream(p)
5144 self.pg_enable_capture(self.pg_interfaces)
5146 self.pg1.get_capture(1)
5148 # ACK packet out->in
5149 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
5150 IP(src=self.pg1.remote_ip4, dst=service_ip) /
5151 TCP(sport=33898, dport=80, flags="A"))
5152 self.pg1.add_stream(p)
5153 self.pg_enable_capture(self.pg_interfaces)
5155 self.pg0.get_capture(1)
5157 # FIN packet in -> out
5158 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5159 IP(src=self.pg0.remote_ip4, dst=twice_nat_addr) /
5160 TCP(sport=80, dport=tcp_port, flags="FA", seq=100, ack=300))
5161 self.pg0.add_stream(p)
5162 self.pg_enable_capture(self.pg_interfaces)
5164 self.pg1.get_capture(1)
5166 # FIN+ACK packet out -> in
5167 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
5168 IP(src=self.pg1.remote_ip4, dst=service_ip) /
5169 TCP(sport=33898, dport=80, flags="FA", seq=300, ack=101))
5170 self.pg1.add_stream(p)
5171 self.pg_enable_capture(self.pg_interfaces)
5173 self.pg0.get_capture(1)
5175 # ACK packet in -> out
5176 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5177 IP(src=self.pg0.remote_ip4, dst=twice_nat_addr) /
5178 TCP(sport=80, dport=tcp_port, flags="A", seq=101, ack=301))
5179 self.pg0.add_stream(p)
5180 self.pg_enable_capture(self.pg_interfaces)
5182 self.pg1.get_capture(1)
5184 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4n,
5186 self.assertEqual(len(sessions) - start_sessnum, 0)
5188 def test_tcp_session_close_in(self):
5189 """ Close TCP session from inside network """
5190 self.tcp_port_out = 10505
5191 self.nat44_add_address(self.nat_addr)
5192 self.nat44_add_static_mapping(self.pg0.remote_ip4,
5196 proto=IP_PROTOS.tcp,
5198 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
5199 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
5202 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4n, 0)
5203 start_sessnum = len(sessions)
5205 self.initiate_tcp_session(self.pg0, self.pg1)
5207 # FIN packet in -> out
5208 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5209 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
5210 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
5211 flags="FA", seq=100, ack=300))
5212 self.pg0.add_stream(p)
5213 self.pg_enable_capture(self.pg_interfaces)
5215 self.pg1.get_capture(1)
5219 # ACK packet out -> in
5220 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
5221 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
5222 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
5223 flags="A", seq=300, ack=101))
5226 # FIN packet out -> in
5227 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
5228 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
5229 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
5230 flags="FA", seq=300, ack=101))
5233 self.pg1.add_stream(pkts)
5234 self.pg_enable_capture(self.pg_interfaces)
5236 self.pg0.get_capture(2)
5238 # ACK packet in -> out
5239 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5240 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
5241 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
5242 flags="A", seq=101, ack=301))
5243 self.pg0.add_stream(p)
5244 self.pg_enable_capture(self.pg_interfaces)
5246 self.pg1.get_capture(1)
5248 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4n,
5250 self.assertEqual(len(sessions) - start_sessnum, 0)
5252 def test_tcp_session_close_out(self):
5253 """ Close TCP session from outside network """
5254 self.tcp_port_out = 10505
5255 self.nat44_add_address(self.nat_addr)
5256 self.nat44_add_static_mapping(self.pg0.remote_ip4,
5260 proto=IP_PROTOS.tcp,
5262 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
5263 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
5266 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4n, 0)
5267 start_sessnum = len(sessions)
5269 self.initiate_tcp_session(self.pg0, self.pg1)
5271 # FIN packet out -> in
5272 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
5273 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
5274 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
5275 flags="FA", seq=100, ack=300))
5276 self.pg1.add_stream(p)
5277 self.pg_enable_capture(self.pg_interfaces)
5279 self.pg0.get_capture(1)
5281 # FIN+ACK packet in -> out
5282 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5283 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
5284 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
5285 flags="FA", seq=300, ack=101))
5287 self.pg0.add_stream(p)
5288 self.pg_enable_capture(self.pg_interfaces)
5290 self.pg1.get_capture(1)
5292 # ACK packet out -> in
5293 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
5294 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
5295 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
5296 flags="A", seq=101, ack=301))
5297 self.pg1.add_stream(p)
5298 self.pg_enable_capture(self.pg_interfaces)
5300 self.pg0.get_capture(1)
5302 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4n,
5304 self.assertEqual(len(sessions) - start_sessnum, 0)
5306 def test_tcp_session_close_simultaneous(self):
5307 """ Close TCP session from inside network """
5308 self.tcp_port_out = 10505
5309 self.nat44_add_address(self.nat_addr)
5310 self.nat44_add_static_mapping(self.pg0.remote_ip4,
5314 proto=IP_PROTOS.tcp,
5316 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
5317 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
5320 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4n, 0)
5321 start_sessnum = len(sessions)
5323 self.initiate_tcp_session(self.pg0, self.pg1)
5325 # FIN packet in -> out
5326 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5327 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
5328 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
5329 flags="FA", seq=100, ack=300))
5330 self.pg0.add_stream(p)
5331 self.pg_enable_capture(self.pg_interfaces)
5333 self.pg1.get_capture(1)
5335 # FIN packet out -> in
5336 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
5337 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
5338 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
5339 flags="FA", seq=300, ack=100))
5340 self.pg1.add_stream(p)
5341 self.pg_enable_capture(self.pg_interfaces)
5343 self.pg0.get_capture(1)
5345 # ACK packet in -> out
5346 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5347 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
5348 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
5349 flags="A", seq=101, ack=301))
5350 self.pg0.add_stream(p)
5351 self.pg_enable_capture(self.pg_interfaces)
5353 self.pg1.get_capture(1)
5355 # ACK packet out -> in
5356 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
5357 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
5358 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
5359 flags="A", seq=301, ack=101))
5360 self.pg1.add_stream(p)
5361 self.pg_enable_capture(self.pg_interfaces)
5363 self.pg0.get_capture(1)
5365 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4n,
5367 self.assertEqual(len(sessions) - start_sessnum, 0)
5369 def test_one_armed_nat44_static(self):
5370 """ One armed NAT44 and 1:1 NAPT asymmetrical rule """
5371 remote_host = self.pg4.remote_hosts[0]
5372 local_host = self.pg4.remote_hosts[1]
5377 self.vapi.nat44_forwarding_enable_disable(1)
5378 self.nat44_add_address(self.nat_addr, twice_nat=1)
5379 self.nat44_add_static_mapping(local_host.ip4, self.nat_addr,
5380 local_port, external_port,
5381 proto=IP_PROTOS.tcp, out2in_only=1,
5383 self.vapi.nat44_interface_add_del_feature(self.pg4.sw_if_index)
5384 self.vapi.nat44_interface_add_del_feature(self.pg4.sw_if_index,
5387 # from client to service
5388 p = (Ether(src=self.pg4.remote_mac, dst=self.pg4.local_mac) /
5389 IP(src=remote_host.ip4, dst=self.nat_addr) /
5390 TCP(sport=12345, dport=external_port))
5391 self.pg4.add_stream(p)
5392 self.pg_enable_capture(self.pg_interfaces)
5394 capture = self.pg4.get_capture(1)
5399 self.assertEqual(ip.dst, local_host.ip4)
5400 self.assertEqual(ip.src, self.nat_addr)
5401 self.assertEqual(tcp.dport, local_port)
5402 self.assertNotEqual(tcp.sport, 12345)
5403 eh_port_in = tcp.sport
5404 self.assert_packet_checksums_valid(p)
5406 self.logger.error(ppp("Unexpected or invalid packet:", p))
5409 # from service back to client
5410 p = (Ether(src=self.pg4.remote_mac, dst=self.pg4.local_mac) /
5411 IP(src=local_host.ip4, dst=self.nat_addr) /
5412 TCP(sport=local_port, dport=eh_port_in))
5413 self.pg4.add_stream(p)
5414 self.pg_enable_capture(self.pg_interfaces)
5416 capture = self.pg4.get_capture(1)
5421 self.assertEqual(ip.src, self.nat_addr)
5422 self.assertEqual(ip.dst, remote_host.ip4)
5423 self.assertEqual(tcp.sport, external_port)
5424 self.assertEqual(tcp.dport, 12345)
5425 self.assert_packet_checksums_valid(p)
5427 self.logger.error(ppp("Unexpected or invalid packet:", p))
5430 def test_static_with_port_out2(self):
5431 """ 1:1 NAPT asymmetrical rule """
5436 self.vapi.nat44_forwarding_enable_disable(1)
5437 self.nat44_add_static_mapping(self.pg0.remote_ip4, self.nat_addr,
5438 local_port, external_port,
5439 proto=IP_PROTOS.tcp, out2in_only=1)
5440 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
5441 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
5444 # from client to service
5445 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
5446 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
5447 TCP(sport=12345, dport=external_port))
5448 self.pg1.add_stream(p)
5449 self.pg_enable_capture(self.pg_interfaces)
5451 capture = self.pg0.get_capture(1)
5456 self.assertEqual(ip.dst, self.pg0.remote_ip4)
5457 self.assertEqual(tcp.dport, local_port)
5458 self.assert_packet_checksums_valid(p)
5460 self.logger.error(ppp("Unexpected or invalid packet:", p))
5464 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
5465 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
5466 ICMP(type=11) / capture[0][IP])
5467 self.pg0.add_stream(p)
5468 self.pg_enable_capture(self.pg_interfaces)
5470 capture = self.pg1.get_capture(1)
5473 self.assertEqual(p[IP].src, self.nat_addr)
5475 self.assertEqual(inner.dst, self.nat_addr)
5476 self.assertEqual(inner[TCPerror].dport, external_port)
5478 self.logger.error(ppp("Unexpected or invalid packet:", p))
5481 # from service back to client
5482 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5483 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
5484 TCP(sport=local_port, dport=12345))
5485 self.pg0.add_stream(p)
5486 self.pg_enable_capture(self.pg_interfaces)
5488 capture = self.pg1.get_capture(1)
5493 self.assertEqual(ip.src, self.nat_addr)
5494 self.assertEqual(tcp.sport, external_port)
5495 self.assert_packet_checksums_valid(p)
5497 self.logger.error(ppp("Unexpected or invalid packet:", p))
5501 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
5502 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
5503 ICMP(type=11) / capture[0][IP])
5504 self.pg1.add_stream(p)
5505 self.pg_enable_capture(self.pg_interfaces)
5507 capture = self.pg0.get_capture(1)
5510 self.assertEqual(p[IP].dst, self.pg0.remote_ip4)
5512 self.assertEqual(inner.src, self.pg0.remote_ip4)
5513 self.assertEqual(inner[TCPerror].sport, local_port)
5515 self.logger.error(ppp("Unexpected or invalid packet:", p))
5518 # from client to server (no translation)
5519 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
5520 IP(src=self.pg1.remote_ip4, dst=self.pg0.remote_ip4) /
5521 TCP(sport=12346, dport=local_port))
5522 self.pg1.add_stream(p)
5523 self.pg_enable_capture(self.pg_interfaces)
5525 capture = self.pg0.get_capture(1)
5530 self.assertEqual(ip.dst, self.pg0.remote_ip4)
5531 self.assertEqual(tcp.dport, local_port)
5532 self.assert_packet_checksums_valid(p)
5534 self.logger.error(ppp("Unexpected or invalid packet:", p))
5537 # from service back to client (no translation)
5538 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5539 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
5540 TCP(sport=local_port, dport=12346))
5541 self.pg0.add_stream(p)
5542 self.pg_enable_capture(self.pg_interfaces)
5544 capture = self.pg1.get_capture(1)
5549 self.assertEqual(ip.src, self.pg0.remote_ip4)
5550 self.assertEqual(tcp.sport, local_port)
5551 self.assert_packet_checksums_valid(p)
5553 self.logger.error(ppp("Unexpected or invalid packet:", p))
5556 def test_output_feature(self):
5557 """ NAT44 interface output feature (in2out postrouting) """
5558 self.vapi.nat44_forwarding_enable_disable(1)
5559 self.nat44_add_address(self.nat_addr)
5560 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index,
5562 self.vapi.nat44_interface_add_del_output_feature(self.pg1.sw_if_index,
5566 pkts = self.create_stream_in(self.pg0, self.pg1)
5567 self.pg0.add_stream(pkts)
5568 self.pg_enable_capture(self.pg_interfaces)
5570 capture = self.pg1.get_capture(len(pkts))
5571 self.verify_capture_out(capture)
5574 pkts = self.create_stream_out(self.pg1)
5575 self.pg1.add_stream(pkts)
5576 self.pg_enable_capture(self.pg_interfaces)
5578 capture = self.pg0.get_capture(len(pkts))
5579 self.verify_capture_in(capture, self.pg0)
5581 def test_multiple_vrf(self):
5582 """ Multiple VRF setup """
5583 external_addr = '1.2.3.4'
5588 self.vapi.nat44_forwarding_enable_disable(1)
5589 self.nat44_add_address(self.nat_addr)
5590 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
5591 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index,
5593 self.vapi.nat44_interface_add_del_output_feature(self.pg1.sw_if_index,
5595 self.vapi.nat44_interface_add_del_feature(self.pg5.sw_if_index)
5596 self.vapi.nat44_interface_add_del_feature(self.pg5.sw_if_index,
5598 self.vapi.nat44_interface_add_del_feature(self.pg6.sw_if_index,
5600 self.nat44_add_static_mapping(self.pg5.remote_ip4, external_addr,
5601 local_port, external_port, vrf_id=1,
5602 proto=IP_PROTOS.tcp, out2in_only=1)
5603 self.nat44_add_static_mapping(
5604 self.pg0.remote_ip4, external_sw_if_index=self.pg0.sw_if_index,
5605 local_port=local_port, vrf_id=0, external_port=external_port,
5606 proto=IP_PROTOS.tcp, out2in_only=1)
5608 # from client to service (both VRF1)
5609 p = (Ether(src=self.pg6.remote_mac, dst=self.pg6.local_mac) /
5610 IP(src=self.pg6.remote_ip4, dst=external_addr) /
5611 TCP(sport=12345, dport=external_port))
5612 self.pg6.add_stream(p)
5613 self.pg_enable_capture(self.pg_interfaces)
5615 capture = self.pg5.get_capture(1)
5620 self.assertEqual(ip.dst, self.pg5.remote_ip4)
5621 self.assertEqual(tcp.dport, local_port)
5622 self.assert_packet_checksums_valid(p)
5624 self.logger.error(ppp("Unexpected or invalid packet:", p))
5627 # from service back to client (both VRF1)
5628 p = (Ether(src=self.pg5.remote_mac, dst=self.pg5.local_mac) /
5629 IP(src=self.pg5.remote_ip4, dst=self.pg6.remote_ip4) /
5630 TCP(sport=local_port, dport=12345))
5631 self.pg5.add_stream(p)
5632 self.pg_enable_capture(self.pg_interfaces)
5634 capture = self.pg6.get_capture(1)
5639 self.assertEqual(ip.src, external_addr)
5640 self.assertEqual(tcp.sport, external_port)
5641 self.assert_packet_checksums_valid(p)
5643 self.logger.error(ppp("Unexpected or invalid packet:", p))
5646 # dynamic NAT from VRF1 to VRF0 (output-feature)
5647 p = (Ether(src=self.pg5.remote_mac, dst=self.pg5.local_mac) /
5648 IP(src=self.pg5.remote_ip4, dst=self.pg1.remote_ip4) /
5649 TCP(sport=2345, dport=22))
5650 self.pg5.add_stream(p)
5651 self.pg_enable_capture(self.pg_interfaces)
5653 capture = self.pg1.get_capture(1)
5658 self.assertEqual(ip.src, self.nat_addr)
5659 self.assertNotEqual(tcp.sport, 2345)
5660 self.assert_packet_checksums_valid(p)
5663 self.logger.error(ppp("Unexpected or invalid packet:", p))
5666 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
5667 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
5668 TCP(sport=22, dport=port))
5669 self.pg1.add_stream(p)
5670 self.pg_enable_capture(self.pg_interfaces)
5672 capture = self.pg5.get_capture(1)
5677 self.assertEqual(ip.dst, self.pg5.remote_ip4)
5678 self.assertEqual(tcp.dport, 2345)
5679 self.assert_packet_checksums_valid(p)
5681 self.logger.error(ppp("Unexpected or invalid packet:", p))
5684 # from client VRF1 to service VRF0
5685 p = (Ether(src=self.pg6.remote_mac, dst=self.pg6.local_mac) /
5686 IP(src=self.pg6.remote_ip4, dst=self.pg0.local_ip4) /
5687 TCP(sport=12346, dport=external_port))
5688 self.pg6.add_stream(p)
5689 self.pg_enable_capture(self.pg_interfaces)
5691 capture = self.pg0.get_capture(1)
5696 self.assertEqual(ip.dst, self.pg0.remote_ip4)
5697 self.assertEqual(tcp.dport, local_port)
5698 self.assert_packet_checksums_valid(p)
5700 self.logger.error(ppp("Unexpected or invalid packet:", p))
5703 # from service VRF0 back to client VRF1
5704 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5705 IP(src=self.pg0.remote_ip4, dst=self.pg6.remote_ip4) /
5706 TCP(sport=local_port, dport=12346))
5707 self.pg0.add_stream(p)
5708 self.pg_enable_capture(self.pg_interfaces)
5710 capture = self.pg6.get_capture(1)
5715 self.assertEqual(ip.src, self.pg0.local_ip4)
5716 self.assertEqual(tcp.sport, external_port)
5717 self.assert_packet_checksums_valid(p)
5719 self.logger.error(ppp("Unexpected or invalid packet:", p))
5722 # from client VRF0 to service VRF1
5723 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5724 IP(src=self.pg0.remote_ip4, dst=external_addr) /
5725 TCP(sport=12347, dport=external_port))
5726 self.pg0.add_stream(p)
5727 self.pg_enable_capture(self.pg_interfaces)
5729 capture = self.pg5.get_capture(1)
5734 self.assertEqual(ip.dst, self.pg5.remote_ip4)
5735 self.assertEqual(tcp.dport, local_port)
5736 self.assert_packet_checksums_valid(p)
5738 self.logger.error(ppp("Unexpected or invalid packet:", p))
5741 # from service VRF1 back to client VRF0
5742 p = (Ether(src=self.pg5.remote_mac, dst=self.pg5.local_mac) /
5743 IP(src=self.pg5.remote_ip4, dst=self.pg0.remote_ip4) /
5744 TCP(sport=local_port, dport=12347))
5745 self.pg5.add_stream(p)
5746 self.pg_enable_capture(self.pg_interfaces)
5748 capture = self.pg0.get_capture(1)
5753 self.assertEqual(ip.src, external_addr)
5754 self.assertEqual(tcp.sport, external_port)
5755 self.assert_packet_checksums_valid(p)
5757 self.logger.error(ppp("Unexpected or invalid packet:", p))
5760 # from client to server (both VRF1, no translation)
5761 p = (Ether(src=self.pg6.remote_mac, dst=self.pg6.local_mac) /
5762 IP(src=self.pg6.remote_ip4, dst=self.pg5.remote_ip4) /
5763 TCP(sport=12348, dport=local_port))
5764 self.pg6.add_stream(p)
5765 self.pg_enable_capture(self.pg_interfaces)
5767 capture = self.pg5.get_capture(1)
5772 self.assertEqual(ip.dst, self.pg5.remote_ip4)
5773 self.assertEqual(tcp.dport, local_port)
5774 self.assert_packet_checksums_valid(p)
5776 self.logger.error(ppp("Unexpected or invalid packet:", p))
5779 # from server back to client (both VRF1, no translation)
5780 p = (Ether(src=self.pg5.remote_mac, dst=self.pg5.local_mac) /
5781 IP(src=self.pg5.remote_ip4, dst=self.pg6.remote_ip4) /
5782 TCP(sport=local_port, dport=12348))
5783 self.pg5.add_stream(p)
5784 self.pg_enable_capture(self.pg_interfaces)
5786 capture = self.pg6.get_capture(1)
5791 self.assertEqual(ip.src, self.pg5.remote_ip4)
5792 self.assertEqual(tcp.sport, local_port)
5793 self.assert_packet_checksums_valid(p)
5795 self.logger.error(ppp("Unexpected or invalid packet:", p))
5798 # from client VRF1 to server VRF0 (no translation)
5799 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5800 IP(src=self.pg0.remote_ip4, dst=self.pg6.remote_ip4) /
5801 TCP(sport=local_port, dport=12349))
5802 self.pg0.add_stream(p)
5803 self.pg_enable_capture(self.pg_interfaces)
5805 capture = self.pg6.get_capture(1)
5810 self.assertEqual(ip.src, self.pg0.remote_ip4)
5811 self.assertEqual(tcp.sport, local_port)
5812 self.assert_packet_checksums_valid(p)
5814 self.logger.error(ppp("Unexpected or invalid packet:", p))
5817 # from server VRF0 back to client VRF1 (no translation)
5818 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5819 IP(src=self.pg0.remote_ip4, dst=self.pg6.remote_ip4) /
5820 TCP(sport=local_port, dport=12349))
5821 self.pg0.add_stream(p)
5822 self.pg_enable_capture(self.pg_interfaces)
5824 capture = self.pg6.get_capture(1)
5829 self.assertEqual(ip.src, self.pg0.remote_ip4)
5830 self.assertEqual(tcp.sport, local_port)
5831 self.assert_packet_checksums_valid(p)
5833 self.logger.error(ppp("Unexpected or invalid packet:", p))
5836 # from client VRF0 to server VRF1 (no translation)
5837 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5838 IP(src=self.pg0.remote_ip4, dst=self.pg5.remote_ip4) /
5839 TCP(sport=12344, dport=local_port))
5840 self.pg0.add_stream(p)
5841 self.pg_enable_capture(self.pg_interfaces)
5843 capture = self.pg5.get_capture(1)
5848 self.assertEqual(ip.dst, self.pg5.remote_ip4)
5849 self.assertEqual(tcp.dport, local_port)
5850 self.assert_packet_checksums_valid(p)
5852 self.logger.error(ppp("Unexpected or invalid packet:", p))
5855 # from server VRF1 back to client VRF0 (no translation)
5856 p = (Ether(src=self.pg5.remote_mac, dst=self.pg5.local_mac) /
5857 IP(src=self.pg5.remote_ip4, dst=self.pg0.remote_ip4) /
5858 TCP(sport=local_port, dport=12344))
5859 self.pg5.add_stream(p)
5860 self.pg_enable_capture(self.pg_interfaces)
5862 capture = self.pg0.get_capture(1)
5867 self.assertEqual(ip.src, self.pg5.remote_ip4)
5868 self.assertEqual(tcp.sport, local_port)
5869 self.assert_packet_checksums_valid(p)
5871 self.logger.error(ppp("Unexpected or invalid packet:", p))
5874 @unittest.skipUnless(running_extended_tests, "part of extended tests")
5875 def test_session_timeout(self):
5876 """ NAT44 session timeouts """
5877 self.nat44_add_address(self.nat_addr)
5878 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
5879 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
5881 self.vapi.nat_set_timeouts(icmp=5)
5885 for i in range(0, max_sessions):
5886 src = "10.10.%u.%u" % ((i & 0xFF00) >> 8, i & 0xFF)
5887 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
5888 IP(src=src, dst=self.pg1.remote_ip4) /
5889 ICMP(id=1025, type='echo-request'))
5891 self.pg0.add_stream(pkts)
5892 self.pg_enable_capture(self.pg_interfaces)
5894 self.pg1.get_capture(max_sessions)
5899 for i in range(0, max_sessions):
5900 src = "10.11.%u.%u" % ((i & 0xFF00) >> 8, i & 0xFF)
5901 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
5902 IP(src=src, dst=self.pg1.remote_ip4) /
5903 ICMP(id=1026, type='echo-request'))
5905 self.pg0.add_stream(pkts)
5906 self.pg_enable_capture(self.pg_interfaces)
5908 self.pg1.get_capture(max_sessions)
5911 users = self.vapi.nat44_user_dump()
5913 nsessions = nsessions + user.nsessions
5914 self.assertLess(nsessions, 2 * max_sessions)
5916 @unittest.skipUnless(running_extended_tests, "part of extended tests")
5917 def test_session_rst_timeout(self):
5918 """ NAT44 session RST timeouts """
5919 self.nat44_add_address(self.nat_addr)
5920 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
5921 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
5923 self.vapi.nat_set_timeouts(tcp_transitory=5)
5925 self.initiate_tcp_session(self.pg0, self.pg1)
5926 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5927 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
5928 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
5930 self.pg0.add_stream(p)
5931 self.pg_enable_capture(self.pg_interfaces)
5933 self.pg1.get_capture(1)
5937 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5938 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
5939 TCP(sport=self.tcp_port_in + 1, dport=self.tcp_external_port + 1,
5941 self.pg0.add_stream(p)
5942 self.pg_enable_capture(self.pg_interfaces)
5944 self.pg1.get_capture(1)
5947 users = self.vapi.nat44_user_dump()
5948 self.assertEqual(len(users), 1)
5949 self.assertEqual(users[0].ip_address, self.pg0.remote_ip4n)
5950 self.assertEqual(users[0].nsessions, 1)
5952 @unittest.skipUnless(running_extended_tests, "part of extended tests")
5953 def test_session_limit_per_user(self):
5954 """ Maximum sessions per user limit """
5955 self.nat44_add_address(self.nat_addr)
5956 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
5957 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
5959 self.vapi.set_ipfix_exporter(collector_address=self.pg2.remote_ip4n,
5960 src_address=self.pg2.local_ip4n,
5962 template_interval=10)
5963 self.vapi.nat_set_timeouts(udp=5)
5965 # get maximum number of translations per user
5966 nat44_config = self.vapi.nat_show_config()
5969 for port in range(0, nat44_config.max_translations_per_user):
5970 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5971 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
5972 UDP(sport=1025 + port, dport=1025 + port))
5975 self.pg0.add_stream(pkts)
5976 self.pg_enable_capture(self.pg_interfaces)
5978 capture = self.pg1.get_capture(len(pkts))
5980 self.vapi.nat_ipfix(domain_id=self.ipfix_domain_id,
5981 src_port=self.ipfix_src_port)
5983 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5984 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
5985 UDP(sport=3001, dport=3002))
5986 self.pg0.add_stream(p)
5987 self.pg_enable_capture(self.pg_interfaces)
5989 capture = self.pg1.assert_nothing_captured()
5991 # verify IPFIX logging
5992 self.vapi.cli("ipfix flush") # FIXME this should be an API call
5994 capture = self.pg2.get_capture(10)
5995 ipfix = IPFIXDecoder()
5996 # first load template
5998 self.assertTrue(p.haslayer(IPFIX))
5999 if p.haslayer(Template):
6000 ipfix.add_template(p.getlayer(Template))
6001 # verify events in data set
6003 if p.haslayer(Data):
6004 data = ipfix.decode_data_set(p.getlayer(Set))
6005 self.verify_ipfix_max_entries_per_user(
6007 nat44_config.max_translations_per_user,
6008 self.pg0.remote_ip4n)
6011 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6012 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6013 UDP(sport=3001, dport=3002))
6014 self.pg0.add_stream(p)
6015 self.pg_enable_capture(self.pg_interfaces)
6017 self.pg1.get_capture(1)
6019 def test_syslog_sess(self):
6020 """ Test syslog session creation and deletion """
6021 self.vapi.syslog_set_filter(SYSLOG_SEVERITY.INFO)
6022 self.vapi.syslog_set_sender(self.pg2.remote_ip4n, self.pg2.local_ip4n)
6023 self.nat44_add_address(self.nat_addr)
6024 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
6025 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
6028 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
6029 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6030 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port))
6031 self.pg0.add_stream(p)
6032 self.pg_enable_capture(self.pg_interfaces)
6034 capture = self.pg1.get_capture(1)
6035 self.tcp_port_out = capture[0][TCP].sport
6036 capture = self.pg2.get_capture(1)
6037 self.verify_syslog_sess(capture[0][Raw].load)
6039 self.pg_enable_capture(self.pg_interfaces)
6041 self.nat44_add_address(self.nat_addr, is_add=0)
6042 capture = self.pg2.get_capture(1)
6043 self.verify_syslog_sess(capture[0][Raw].load, False)
6046 super(TestNAT44EndpointDependent, self).tearDown()
6047 if not self.vpp_dead:
6048 self.logger.info(self.vapi.cli("show nat44 addresses"))
6049 self.logger.info(self.vapi.cli("show nat44 interfaces"))
6050 self.logger.info(self.vapi.cli("show nat44 static mappings"))
6051 self.logger.info(self.vapi.cli("show nat44 interface address"))
6052 self.logger.info(self.vapi.cli("show nat44 sessions detail"))
6053 self.logger.info(self.vapi.cli("show nat44 hash tables detail"))
6054 self.logger.info(self.vapi.cli("show nat timeouts"))
6056 self.vapi.cli("clear logging")
6059 class TestNAT44Out2InDPO(MethodHolder):
6060 """ NAT44 Test Cases using out2in DPO """
6063 def setUpConstants(cls):
6064 super(TestNAT44Out2InDPO, cls).setUpConstants()
6065 cls.vpp_cmdline.extend(["nat", "{", "out2in dpo", "}"])
6068 def setUpClass(cls):
6069 super(TestNAT44Out2InDPO, cls).setUpClass()
6070 cls.vapi.cli("set log class nat level debug")
6073 cls.tcp_port_in = 6303
6074 cls.tcp_port_out = 6303
6075 cls.udp_port_in = 6304
6076 cls.udp_port_out = 6304
6077 cls.icmp_id_in = 6305
6078 cls.icmp_id_out = 6305
6079 cls.nat_addr = '10.0.0.3'
6080 cls.nat_addr_n = socket.inet_pton(socket.AF_INET, cls.nat_addr)
6081 cls.dst_ip4 = '192.168.70.1'
6083 cls.create_pg_interfaces(range(2))
6086 cls.pg0.config_ip4()
6087 cls.pg0.resolve_arp()
6090 cls.pg1.config_ip6()
6091 cls.pg1.resolve_ndp()
6093 cls.vapi.ip_add_del_route(is_ipv6=True, dst_address='\x00'*16,
6094 dst_address_length=0,
6095 next_hop_address=cls.pg1.remote_ip6n,
6096 next_hop_sw_if_index=cls.pg1.sw_if_index)
6099 super(TestNAT44Out2InDPO, cls).tearDownClass()
6102 def configure_xlat(self):
6103 self.dst_ip6_pfx = '1:2:3::'
6104 self.dst_ip6_pfx_n = socket.inet_pton(socket.AF_INET6,
6106 self.dst_ip6_pfx_len = 96
6107 self.src_ip6_pfx = '4:5:6::'
6108 self.src_ip6_pfx_n = socket.inet_pton(socket.AF_INET6,
6110 self.src_ip6_pfx_len = 96
6111 self.vapi.map_add_domain(self.dst_ip6_pfx_n, self.dst_ip6_pfx_len,
6112 self.src_ip6_pfx_n, self.src_ip6_pfx_len,
6113 '\x00\x00\x00\x00', 0)
6115 @unittest.skip('Temporary disabled')
6116 def test_464xlat_ce(self):
6117 """ Test 464XLAT CE with NAT44 """
6119 nat_config = self.vapi.nat_show_config()
6120 self.assertEqual(1, nat_config.out2in_dpo)
6122 self.configure_xlat()
6124 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
6125 self.vapi.nat44_add_del_address_range(self.nat_addr_n, self.nat_addr_n)
6127 out_src_ip6 = self.compose_ip6(self.dst_ip4, self.dst_ip6_pfx,
6128 self.dst_ip6_pfx_len)
6129 out_dst_ip6 = self.compose_ip6(self.nat_addr, self.src_ip6_pfx,
6130 self.src_ip6_pfx_len)
6133 pkts = self.create_stream_in(self.pg0, self.pg1, self.dst_ip4)
6134 self.pg0.add_stream(pkts)
6135 self.pg_enable_capture(self.pg_interfaces)
6137 capture = self.pg1.get_capture(len(pkts))
6138 self.verify_capture_out_ip6(capture, nat_ip=out_dst_ip6,
6141 pkts = self.create_stream_out_ip6(self.pg1, out_src_ip6,
6143 self.pg1.add_stream(pkts)
6144 self.pg_enable_capture(self.pg_interfaces)
6146 capture = self.pg0.get_capture(len(pkts))
6147 self.verify_capture_in(capture, self.pg0)
6149 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index,
6151 self.vapi.nat44_add_del_address_range(self.nat_addr_n,
6152 self.nat_addr_n, is_add=0)
6154 @unittest.skip('Temporary disabled')
6155 def test_464xlat_ce_no_nat(self):
6156 """ Test 464XLAT CE without NAT44 """
6158 self.configure_xlat()
6160 out_src_ip6 = self.compose_ip6(self.dst_ip4, self.dst_ip6_pfx,
6161 self.dst_ip6_pfx_len)
6162 out_dst_ip6 = self.compose_ip6(self.pg0.remote_ip4, self.src_ip6_pfx,
6163 self.src_ip6_pfx_len)
6165 pkts = self.create_stream_in(self.pg0, self.pg1, self.dst_ip4)
6166 self.pg0.add_stream(pkts)
6167 self.pg_enable_capture(self.pg_interfaces)
6169 capture = self.pg1.get_capture(len(pkts))
6170 self.verify_capture_out_ip6(capture, dst_ip=out_src_ip6,
6171 nat_ip=out_dst_ip6, same_port=True)
6173 pkts = self.create_stream_out_ip6(self.pg1, out_src_ip6, out_dst_ip6)
6174 self.pg1.add_stream(pkts)
6175 self.pg_enable_capture(self.pg_interfaces)
6177 capture = self.pg0.get_capture(len(pkts))
6178 self.verify_capture_in(capture, self.pg0)
6181 class TestDeterministicNAT(MethodHolder):
6182 """ Deterministic NAT Test Cases """
6185 def setUpConstants(cls):
6186 super(TestDeterministicNAT, cls).setUpConstants()
6187 cls.vpp_cmdline.extend(["nat", "{", "deterministic", "}"])
6190 def setUpClass(cls):
6191 super(TestDeterministicNAT, cls).setUpClass()
6192 cls.vapi.cli("set log class nat level debug")
6195 cls.tcp_port_in = 6303
6196 cls.tcp_external_port = 6303
6197 cls.udp_port_in = 6304
6198 cls.udp_external_port = 6304
6199 cls.icmp_id_in = 6305
6200 cls.nat_addr = '10.0.0.3'
6202 cls.create_pg_interfaces(range(3))
6203 cls.interfaces = list(cls.pg_interfaces)
6205 for i in cls.interfaces:
6210 cls.pg0.generate_remote_hosts(2)
6211 cls.pg0.configure_ipv4_neighbors()
6214 super(TestDeterministicNAT, cls).tearDownClass()
6217 def create_stream_in(self, in_if, out_if, ttl=64):
6219 Create packet stream for inside network
6221 :param in_if: Inside interface
6222 :param out_if: Outside interface
6223 :param ttl: TTL of generated packets
6227 p = (Ether(dst=in_if.local_mac, src=in_if.remote_mac) /
6228 IP(src=in_if.remote_ip4, dst=out_if.remote_ip4, ttl=ttl) /
6229 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port))
6233 p = (Ether(dst=in_if.local_mac, src=in_if.remote_mac) /
6234 IP(src=in_if.remote_ip4, dst=out_if.remote_ip4, ttl=ttl) /
6235 UDP(sport=self.udp_port_in, dport=self.udp_external_port))
6239 p = (Ether(dst=in_if.local_mac, src=in_if.remote_mac) /
6240 IP(src=in_if.remote_ip4, dst=out_if.remote_ip4, ttl=ttl) /
6241 ICMP(id=self.icmp_id_in, type='echo-request'))
6246 def create_stream_out(self, out_if, dst_ip=None, ttl=64):
6248 Create packet stream for outside network
6250 :param out_if: Outside interface
6251 :param dst_ip: Destination IP address (Default use global NAT address)
6252 :param ttl: TTL of generated packets
6255 dst_ip = self.nat_addr
6258 p = (Ether(dst=out_if.local_mac, src=out_if.remote_mac) /
6259 IP(src=out_if.remote_ip4, dst=dst_ip, ttl=ttl) /
6260 TCP(dport=self.tcp_port_out, sport=self.tcp_external_port))
6264 p = (Ether(dst=out_if.local_mac, src=out_if.remote_mac) /
6265 IP(src=out_if.remote_ip4, dst=dst_ip, ttl=ttl) /
6266 UDP(dport=self.udp_port_out, sport=self.udp_external_port))
6270 p = (Ether(dst=out_if.local_mac, src=out_if.remote_mac) /
6271 IP(src=out_if.remote_ip4, dst=dst_ip, ttl=ttl) /
6272 ICMP(id=self.icmp_external_id, type='echo-reply'))
6277 def verify_capture_out(self, capture, nat_ip=None):
6279 Verify captured packets on outside network
6281 :param capture: Captured packets
6282 :param nat_ip: Translated IP address (Default use global NAT address)
6283 :param same_port: Sorce port number is not translated (Default False)
6286 nat_ip = self.nat_addr
6287 for packet in capture:
6289 self.assertEqual(packet[IP].src, nat_ip)
6290 if packet.haslayer(TCP):
6291 self.tcp_port_out = packet[TCP].sport
6292 elif packet.haslayer(UDP):
6293 self.udp_port_out = packet[UDP].sport
6295 self.icmp_external_id = packet[ICMP].id
6297 self.logger.error(ppp("Unexpected or invalid packet "
6298 "(outside network):", packet))
6301 def test_deterministic_mode(self):
6302 """ NAT plugin run deterministic mode """
6303 in_addr = '172.16.255.0'
6304 out_addr = '172.17.255.50'
6305 in_addr_t = '172.16.255.20'
6306 in_addr_n = socket.inet_aton(in_addr)
6307 out_addr_n = socket.inet_aton(out_addr)
6308 in_addr_t_n = socket.inet_aton(in_addr_t)
6312 nat_config = self.vapi.nat_show_config()
6313 self.assertEqual(1, nat_config.deterministic)
6315 self.vapi.nat_det_add_del_map(in_addr_n, in_plen, out_addr_n, out_plen)
6317 rep1 = self.vapi.nat_det_forward(in_addr_t_n)
6318 self.assertEqual(rep1.out_addr[:4], out_addr_n)
6319 rep2 = self.vapi.nat_det_reverse(out_addr_n, rep1.out_port_hi)
6320 self.assertEqual(rep2.in_addr[:4], in_addr_t_n)
6322 deterministic_mappings = self.vapi.nat_det_map_dump()
6323 self.assertEqual(len(deterministic_mappings), 1)
6324 dsm = deterministic_mappings[0]
6325 self.assertEqual(in_addr_n, dsm.in_addr[:4])
6326 self.assertEqual(in_plen, dsm.in_plen)
6327 self.assertEqual(out_addr_n, dsm.out_addr[:4])
6328 self.assertEqual(out_plen, dsm.out_plen)
6330 self.clear_nat_det()
6331 deterministic_mappings = self.vapi.nat_det_map_dump()
6332 self.assertEqual(len(deterministic_mappings), 0)
6334 def test_set_timeouts(self):
6335 """ Set deterministic NAT timeouts """
6336 timeouts_before = self.vapi.nat_get_timeouts()
6338 self.vapi.nat_set_timeouts(timeouts_before.udp + 10,
6339 timeouts_before.tcp_established + 10,
6340 timeouts_before.tcp_transitory + 10,
6341 timeouts_before.icmp + 10)
6343 timeouts_after = self.vapi.nat_get_timeouts()
6345 self.assertNotEqual(timeouts_before.udp, timeouts_after.udp)
6346 self.assertNotEqual(timeouts_before.icmp, timeouts_after.icmp)
6347 self.assertNotEqual(timeouts_before.tcp_established,
6348 timeouts_after.tcp_established)
6349 self.assertNotEqual(timeouts_before.tcp_transitory,
6350 timeouts_after.tcp_transitory)
6352 def test_det_in(self):
6353 """ Deterministic NAT translation test (TCP, UDP, ICMP) """
6355 nat_ip = "10.0.0.10"
6357 self.vapi.nat_det_add_del_map(self.pg0.remote_ip4n,
6359 socket.inet_aton(nat_ip),
6361 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
6362 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
6366 pkts = self.create_stream_in(self.pg0, self.pg1)
6367 self.pg0.add_stream(pkts)
6368 self.pg_enable_capture(self.pg_interfaces)
6370 capture = self.pg1.get_capture(len(pkts))
6371 self.verify_capture_out(capture, nat_ip)
6374 pkts = self.create_stream_out(self.pg1, nat_ip)
6375 self.pg1.add_stream(pkts)
6376 self.pg_enable_capture(self.pg_interfaces)
6378 capture = self.pg0.get_capture(len(pkts))
6379 self.verify_capture_in(capture, self.pg0)
6382 sessions = self.vapi.nat_det_session_dump(self.pg0.remote_ip4n)
6383 self.assertEqual(len(sessions), 3)
6387 self.assertEqual(s.ext_addr[:4], self.pg1.remote_ip4n)
6388 self.assertEqual(s.in_port, self.tcp_port_in)
6389 self.assertEqual(s.out_port, self.tcp_port_out)
6390 self.assertEqual(s.ext_port, self.tcp_external_port)
6394 self.assertEqual(s.ext_addr[:4], self.pg1.remote_ip4n)
6395 self.assertEqual(s.in_port, self.udp_port_in)
6396 self.assertEqual(s.out_port, self.udp_port_out)
6397 self.assertEqual(s.ext_port, self.udp_external_port)
6401 self.assertEqual(s.ext_addr[:4], self.pg1.remote_ip4n)
6402 self.assertEqual(s.in_port, self.icmp_id_in)
6403 self.assertEqual(s.out_port, self.icmp_external_id)
6405 def test_multiple_users(self):
6406 """ Deterministic NAT multiple users """
6408 nat_ip = "10.0.0.10"
6410 external_port = 6303
6412 host0 = self.pg0.remote_hosts[0]
6413 host1 = self.pg0.remote_hosts[1]
6415 self.vapi.nat_det_add_del_map(host0.ip4n,
6417 socket.inet_aton(nat_ip),
6419 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
6420 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
6424 p = (Ether(src=host0.mac, dst=self.pg0.local_mac) /
6425 IP(src=host0.ip4, dst=self.pg1.remote_ip4) /
6426 TCP(sport=port_in, dport=external_port))
6427 self.pg0.add_stream(p)
6428 self.pg_enable_capture(self.pg_interfaces)
6430 capture = self.pg1.get_capture(1)
6435 self.assertEqual(ip.src, nat_ip)
6436 self.assertEqual(ip.dst, self.pg1.remote_ip4)
6437 self.assertEqual(tcp.dport, external_port)
6438 port_out0 = tcp.sport
6440 self.logger.error(ppp("Unexpected or invalid packet:", p))
6444 p = (Ether(src=host1.mac, dst=self.pg0.local_mac) /
6445 IP(src=host1.ip4, dst=self.pg1.remote_ip4) /
6446 TCP(sport=port_in, dport=external_port))
6447 self.pg0.add_stream(p)
6448 self.pg_enable_capture(self.pg_interfaces)
6450 capture = self.pg1.get_capture(1)
6455 self.assertEqual(ip.src, nat_ip)
6456 self.assertEqual(ip.dst, self.pg1.remote_ip4)
6457 self.assertEqual(tcp.dport, external_port)
6458 port_out1 = tcp.sport
6460 self.logger.error(ppp("Unexpected or invalid packet:", p))
6463 dms = self.vapi.nat_det_map_dump()
6464 self.assertEqual(1, len(dms))
6465 self.assertEqual(2, dms[0].ses_num)
6468 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
6469 IP(src=self.pg1.remote_ip4, dst=nat_ip) /
6470 TCP(sport=external_port, dport=port_out0))
6471 self.pg1.add_stream(p)
6472 self.pg_enable_capture(self.pg_interfaces)
6474 capture = self.pg0.get_capture(1)
6479 self.assertEqual(ip.src, self.pg1.remote_ip4)
6480 self.assertEqual(ip.dst, host0.ip4)
6481 self.assertEqual(tcp.dport, port_in)
6482 self.assertEqual(tcp.sport, external_port)
6484 self.logger.error(ppp("Unexpected or invalid packet:", p))
6488 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
6489 IP(src=self.pg1.remote_ip4, dst=nat_ip) /
6490 TCP(sport=external_port, dport=port_out1))
6491 self.pg1.add_stream(p)
6492 self.pg_enable_capture(self.pg_interfaces)
6494 capture = self.pg0.get_capture(1)
6499 self.assertEqual(ip.src, self.pg1.remote_ip4)
6500 self.assertEqual(ip.dst, host1.ip4)
6501 self.assertEqual(tcp.dport, port_in)
6502 self.assertEqual(tcp.sport, external_port)
6504 self.logger.error(ppp("Unexpected or invalid packet", p))
6507 # session close api test
6508 self.vapi.nat_det_close_session_out(socket.inet_aton(nat_ip),
6510 self.pg1.remote_ip4n,
6512 dms = self.vapi.nat_det_map_dump()
6513 self.assertEqual(dms[0].ses_num, 1)
6515 self.vapi.nat_det_close_session_in(host0.ip4n,
6517 self.pg1.remote_ip4n,
6519 dms = self.vapi.nat_det_map_dump()
6520 self.assertEqual(dms[0].ses_num, 0)
6522 def test_tcp_session_close_detection_in(self):
6523 """ Deterministic NAT TCP session close from inside network """
6524 self.vapi.nat_det_add_del_map(self.pg0.remote_ip4n,
6526 socket.inet_aton(self.nat_addr),
6528 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
6529 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
6532 self.initiate_tcp_session(self.pg0, self.pg1)
6534 # close the session from inside
6536 # FIN packet in -> out
6537 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6538 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6539 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
6541 self.pg0.add_stream(p)
6542 self.pg_enable_capture(self.pg_interfaces)
6544 self.pg1.get_capture(1)
6548 # ACK packet out -> in
6549 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
6550 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
6551 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
6555 # FIN packet out -> in
6556 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
6557 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
6558 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
6562 self.pg1.add_stream(pkts)
6563 self.pg_enable_capture(self.pg_interfaces)
6565 self.pg0.get_capture(2)
6567 # ACK packet in -> out
6568 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6569 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6570 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
6572 self.pg0.add_stream(p)
6573 self.pg_enable_capture(self.pg_interfaces)
6575 self.pg1.get_capture(1)
6577 # Check if deterministic NAT44 closed the session
6578 dms = self.vapi.nat_det_map_dump()
6579 self.assertEqual(0, dms[0].ses_num)
6581 self.logger.error("TCP session termination failed")
6584 def test_tcp_session_close_detection_out(self):
6585 """ Deterministic NAT TCP session close from outside network """
6586 self.vapi.nat_det_add_del_map(self.pg0.remote_ip4n,
6588 socket.inet_aton(self.nat_addr),
6590 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
6591 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
6594 self.initiate_tcp_session(self.pg0, self.pg1)
6596 # close the session from outside
6598 # FIN packet out -> in
6599 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
6600 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
6601 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
6603 self.pg1.add_stream(p)
6604 self.pg_enable_capture(self.pg_interfaces)
6606 self.pg0.get_capture(1)
6610 # ACK packet in -> out
6611 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6612 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6613 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
6617 # ACK packet in -> out
6618 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6619 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6620 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
6624 self.pg0.add_stream(pkts)
6625 self.pg_enable_capture(self.pg_interfaces)
6627 self.pg1.get_capture(2)
6629 # ACK packet out -> in
6630 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
6631 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
6632 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
6634 self.pg1.add_stream(p)
6635 self.pg_enable_capture(self.pg_interfaces)
6637 self.pg0.get_capture(1)
6639 # Check if deterministic NAT44 closed the session
6640 dms = self.vapi.nat_det_map_dump()
6641 self.assertEqual(0, dms[0].ses_num)
6643 self.logger.error("TCP session termination failed")
6646 @unittest.skipUnless(running_extended_tests, "part of extended tests")
6647 def test_session_timeout(self):
6648 """ Deterministic NAT session timeouts """
6649 self.vapi.nat_det_add_del_map(self.pg0.remote_ip4n,
6651 socket.inet_aton(self.nat_addr),
6653 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
6654 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
6657 self.initiate_tcp_session(self.pg0, self.pg1)
6658 self.vapi.nat_set_timeouts(5, 5, 5, 5)
6659 pkts = self.create_stream_in(self.pg0, self.pg1)
6660 self.pg0.add_stream(pkts)
6661 self.pg_enable_capture(self.pg_interfaces)
6663 capture = self.pg1.get_capture(len(pkts))
6666 dms = self.vapi.nat_det_map_dump()
6667 self.assertEqual(0, dms[0].ses_num)
6669 @unittest.skipUnless(running_extended_tests, "part of extended tests")
6670 def test_session_limit_per_user(self):
6671 """ Deterministic NAT maximum sessions per user limit """
6672 self.vapi.nat_det_add_del_map(self.pg0.remote_ip4n,
6674 socket.inet_aton(self.nat_addr),
6676 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
6677 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
6679 self.vapi.set_ipfix_exporter(collector_address=self.pg2.remote_ip4n,
6680 src_address=self.pg2.local_ip4n,
6682 template_interval=10)
6683 self.vapi.nat_ipfix()
6686 for port in range(1025, 2025):
6687 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6688 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6689 UDP(sport=port, dport=port))
6692 self.pg0.add_stream(pkts)
6693 self.pg_enable_capture(self.pg_interfaces)
6695 capture = self.pg1.get_capture(len(pkts))
6697 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6698 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6699 UDP(sport=3001, dport=3002))
6700 self.pg0.add_stream(p)
6701 self.pg_enable_capture(self.pg_interfaces)
6703 capture = self.pg1.assert_nothing_captured()
6705 # verify ICMP error packet
6706 capture = self.pg0.get_capture(1)
6708 self.assertTrue(p.haslayer(ICMP))
6710 self.assertEqual(icmp.type, 3)
6711 self.assertEqual(icmp.code, 1)
6712 self.assertTrue(icmp.haslayer(IPerror))
6713 inner_ip = icmp[IPerror]
6714 self.assertEqual(inner_ip[UDPerror].sport, 3001)
6715 self.assertEqual(inner_ip[UDPerror].dport, 3002)
6717 dms = self.vapi.nat_det_map_dump()
6719 self.assertEqual(1000, dms[0].ses_num)
6721 # verify IPFIX logging
6722 self.vapi.cli("ipfix flush") # FIXME this should be an API call
6724 capture = self.pg2.get_capture(2)
6725 ipfix = IPFIXDecoder()
6726 # first load template
6728 self.assertTrue(p.haslayer(IPFIX))
6729 if p.haslayer(Template):
6730 ipfix.add_template(p.getlayer(Template))
6731 # verify events in data set
6733 if p.haslayer(Data):
6734 data = ipfix.decode_data_set(p.getlayer(Set))
6735 self.verify_ipfix_max_entries_per_user(data,
6737 self.pg0.remote_ip4n)
6739 def clear_nat_det(self):
6741 Clear deterministic NAT configuration.
6743 self.vapi.nat_ipfix(enable=0)
6744 self.vapi.nat_set_timeouts()
6745 deterministic_mappings = self.vapi.nat_det_map_dump()
6746 for dsm in deterministic_mappings:
6747 self.vapi.nat_det_add_del_map(dsm.in_addr,
6753 interfaces = self.vapi.nat44_interface_dump()
6754 for intf in interfaces:
6755 self.vapi.nat44_interface_add_del_feature(intf.sw_if_index,
6760 super(TestDeterministicNAT, self).tearDown()
6761 if not self.vpp_dead:
6762 self.logger.info(self.vapi.cli("show nat44 interfaces"))
6763 self.logger.info(self.vapi.cli("show nat timeouts"))
6765 self.vapi.cli("show nat44 deterministic mappings"))
6767 self.vapi.cli("show nat44 deterministic sessions"))
6768 self.clear_nat_det()
6771 class TestNAT64(MethodHolder):
6772 """ NAT64 Test Cases """
6775 def setUpConstants(cls):
6776 super(TestNAT64, cls).setUpConstants()
6777 cls.vpp_cmdline.extend(["nat", "{", "nat64 bib hash buckets 128",
6778 "nat64 st hash buckets 256", "}"])
6781 def setUpClass(cls):
6782 super(TestNAT64, cls).setUpClass()
6785 cls.tcp_port_in = 6303
6786 cls.tcp_port_out = 6303
6787 cls.udp_port_in = 6304
6788 cls.udp_port_out = 6304
6789 cls.icmp_id_in = 6305
6790 cls.icmp_id_out = 6305
6791 cls.tcp_external_port = 80
6792 cls.nat_addr = '10.0.0.3'
6793 cls.nat_addr_n = socket.inet_pton(socket.AF_INET, cls.nat_addr)
6795 cls.vrf1_nat_addr = '10.0.10.3'
6796 cls.vrf1_nat_addr_n = socket.inet_pton(socket.AF_INET,
6798 cls.ipfix_src_port = 4739
6799 cls.ipfix_domain_id = 1
6801 cls.create_pg_interfaces(range(6))
6802 cls.ip6_interfaces = list(cls.pg_interfaces[0:1])
6803 cls.ip6_interfaces.append(cls.pg_interfaces[2])
6804 cls.ip4_interfaces = list(cls.pg_interfaces[1:2])
6806 cls.vapi.ip_table_add_del(cls.vrf1_id, is_add=1, is_ipv6=1)
6808 cls.pg_interfaces[2].set_table_ip6(cls.vrf1_id)
6810 cls.pg0.generate_remote_hosts(2)
6812 for i in cls.ip6_interfaces:
6815 i.configure_ipv6_neighbors()
6817 for i in cls.ip4_interfaces:
6823 cls.pg3.config_ip4()
6824 cls.pg3.resolve_arp()
6825 cls.pg3.config_ip6()
6826 cls.pg3.configure_ipv6_neighbors()
6829 cls.pg5.config_ip6()
6832 super(TestNAT64, cls).tearDownClass()
6835 def test_nat64_inside_interface_handles_neighbor_advertisement(self):
6836 """ NAT64 inside interface handles Neighbor Advertisement """
6838 self.vapi.nat64_add_del_interface(self.pg5.sw_if_index)
6841 ping = (Ether(dst=self.pg5.local_mac, src=self.pg5.remote_mac) /
6842 IPv6(src=self.pg5.remote_ip6, dst=self.pg5.local_ip6) /
6843 ICMPv6EchoRequest())
6845 self.pg5.add_stream(pkts)
6846 self.pg_enable_capture(self.pg_interfaces)
6849 # Wait for Neighbor Solicitation
6850 capture = self.pg5.get_capture(len(pkts))
6853 self.assertEqual(packet[IPv6].src, self.pg5.local_ip6)
6854 self.assertEqual(packet.haslayer(ICMPv6ND_NS), 1)
6855 tgt = packet[ICMPv6ND_NS].tgt
6857 self.logger.error(ppp("Unexpected or invalid packet:", packet))
6860 # Send Neighbor Advertisement
6861 p = (Ether(dst=self.pg5.local_mac, src=self.pg5.remote_mac) /
6862 IPv6(src=self.pg5.remote_ip6, dst=self.pg5.local_ip6) /
6863 ICMPv6ND_NA(tgt=tgt) /
6864 ICMPv6NDOptDstLLAddr(lladdr=self.pg5.remote_mac))
6866 self.pg5.add_stream(pkts)
6867 self.pg_enable_capture(self.pg_interfaces)
6870 # Try to send ping again
6872 self.pg5.add_stream(pkts)
6873 self.pg_enable_capture(self.pg_interfaces)
6876 # Wait for ping reply
6877 capture = self.pg5.get_capture(len(pkts))
6880 self.assertEqual(packet[IPv6].src, self.pg5.local_ip6)
6881 self.assertEqual(packet[IPv6].dst, self.pg5.remote_ip6)
6882 self.assertEqual(packet.haslayer(ICMPv6EchoReply), 1)
6884 self.logger.error(ppp("Unexpected or invalid packet:", packet))
6887 def test_pool(self):
6888 """ Add/delete address to NAT64 pool """
6889 nat_addr = socket.inet_pton(socket.AF_INET, '1.2.3.4')
6891 self.vapi.nat64_add_del_pool_addr_range(nat_addr, nat_addr)
6893 addresses = self.vapi.nat64_pool_addr_dump()
6894 self.assertEqual(len(addresses), 1)
6895 self.assertEqual(addresses[0].address, nat_addr)
6897 self.vapi.nat64_add_del_pool_addr_range(nat_addr, nat_addr, is_add=0)
6899 addresses = self.vapi.nat64_pool_addr_dump()
6900 self.assertEqual(len(addresses), 0)
6902 def test_interface(self):
6903 """ Enable/disable NAT64 feature on the interface """
6904 self.vapi.nat64_add_del_interface(self.pg0.sw_if_index)
6905 self.vapi.nat64_add_del_interface(self.pg1.sw_if_index, is_inside=0)
6907 interfaces = self.vapi.nat64_interface_dump()
6908 self.assertEqual(len(interfaces), 2)
6911 for intf in interfaces:
6912 if intf.sw_if_index == self.pg0.sw_if_index:
6913 self.assertEqual(intf.is_inside, 1)
6915 elif intf.sw_if_index == self.pg1.sw_if_index:
6916 self.assertEqual(intf.is_inside, 0)
6918 self.assertTrue(pg0_found)
6919 self.assertTrue(pg1_found)
6921 features = self.vapi.cli("show interface features pg0")
6922 self.assertNotEqual(features.find('nat64-in2out'), -1)
6923 features = self.vapi.cli("show interface features pg1")
6924 self.assertNotEqual(features.find('nat64-out2in'), -1)
6926 self.vapi.nat64_add_del_interface(self.pg0.sw_if_index, is_add=0)
6927 self.vapi.nat64_add_del_interface(self.pg1.sw_if_index, is_add=0)
6929 interfaces = self.vapi.nat64_interface_dump()
6930 self.assertEqual(len(interfaces), 0)
6932 def test_static_bib(self):
6933 """ Add/delete static BIB entry """
6934 in_addr = socket.inet_pton(socket.AF_INET6,
6935 '2001:db8:85a3::8a2e:370:7334')
6936 out_addr = socket.inet_pton(socket.AF_INET, '10.1.1.3')
6939 proto = IP_PROTOS.tcp
6941 self.vapi.nat64_add_del_static_bib(in_addr,
6946 bib = self.vapi.nat64_bib_dump(IP_PROTOS.tcp)
6951 self.assertEqual(bibe.i_addr, in_addr)
6952 self.assertEqual(bibe.o_addr, out_addr)
6953 self.assertEqual(bibe.i_port, in_port)
6954 self.assertEqual(bibe.o_port, out_port)
6955 self.assertEqual(static_bib_num, 1)
6956 bibs = self.statistics.get_counter('/nat64/total-bibs')
6957 self.assertEqual(bibs[0][0], 1)
6959 self.vapi.nat64_add_del_static_bib(in_addr,
6965 bib = self.vapi.nat64_bib_dump(IP_PROTOS.tcp)
6970 self.assertEqual(static_bib_num, 0)
6971 bibs = self.statistics.get_counter('/nat64/total-bibs')
6972 self.assertEqual(bibs[0][0], 0)
6974 def test_set_timeouts(self):
6975 """ Set NAT64 timeouts """
6976 # verify default values
6977 timeouts = self.vapi.nat_get_timeouts()
6978 self.assertEqual(timeouts.udp, 300)
6979 self.assertEqual(timeouts.icmp, 60)
6980 self.assertEqual(timeouts.tcp_transitory, 240)
6981 self.assertEqual(timeouts.tcp_established, 7440)
6983 # set and verify custom values
6984 self.vapi.nat_set_timeouts(udp=200, icmp=30, tcp_transitory=250,
6985 tcp_established=7450)
6986 timeouts = self.vapi.nat_get_timeouts()
6987 self.assertEqual(timeouts.udp, 200)
6988 self.assertEqual(timeouts.icmp, 30)
6989 self.assertEqual(timeouts.tcp_transitory, 250)
6990 self.assertEqual(timeouts.tcp_established, 7450)
6992 def test_dynamic(self):
6993 """ NAT64 dynamic translation test """
6994 self.tcp_port_in = 6303
6995 self.udp_port_in = 6304
6996 self.icmp_id_in = 6305
6998 ses_num_start = self.nat64_get_ses_num()
7000 self.vapi.nat64_add_del_pool_addr_range(self.nat_addr_n,
7002 self.vapi.nat64_add_del_interface(self.pg0.sw_if_index)
7003 self.vapi.nat64_add_del_interface(self.pg1.sw_if_index, is_inside=0)
7006 tcpn = self.statistics.get_counter('/err/nat64-in2out/TCP packets')
7007 udpn = self.statistics.get_counter('/err/nat64-in2out/UDP packets')
7008 icmpn = self.statistics.get_counter('/err/nat64-in2out/ICMP packets')
7009 totaln = self.statistics.get_counter(
7010 '/err/nat64-in2out/good in2out packets processed')
7012 pkts = self.create_stream_in_ip6(self.pg0, self.pg1)
7013 self.pg0.add_stream(pkts)
7014 self.pg_enable_capture(self.pg_interfaces)
7016 capture = self.pg1.get_capture(len(pkts))
7017 self.verify_capture_out(capture, nat_ip=self.nat_addr,
7018 dst_ip=self.pg1.remote_ip4)
7020 err = self.statistics.get_counter('/err/nat64-in2out/TCP packets')
7021 self.assertEqual(err - tcpn, 1)
7022 err = self.statistics.get_counter('/err/nat64-in2out/UDP packets')
7023 self.assertEqual(err - udpn, 1)
7024 err = self.statistics.get_counter('/err/nat64-in2out/ICMP packets')
7025 self.assertEqual(err - icmpn, 1)
7026 err = self.statistics.get_counter(
7027 '/err/nat64-in2out/good in2out packets processed')
7028 self.assertEqual(err - totaln, 3)
7031 tcpn = self.statistics.get_counter('/err/nat64-out2in/TCP packets')
7032 udpn = self.statistics.get_counter('/err/nat64-out2in/UDP packets')
7033 icmpn = self.statistics.get_counter('/err/nat64-out2in/ICMP packets')
7034 totaln = self.statistics.get_counter(
7035 '/err/nat64-out2in/good out2in packets processed')
7037 pkts = self.create_stream_out(self.pg1, dst_ip=self.nat_addr)
7038 self.pg1.add_stream(pkts)
7039 self.pg_enable_capture(self.pg_interfaces)
7041 capture = self.pg0.get_capture(len(pkts))
7042 ip = IPv6(src=''.join(['64:ff9b::', self.pg1.remote_ip4]))
7043 self.verify_capture_in_ip6(capture, ip[IPv6].src, self.pg0.remote_ip6)
7045 err = self.statistics.get_counter('/err/nat64-out2in/TCP packets')
7046 self.assertEqual(err - tcpn, 1)
7047 err = self.statistics.get_counter('/err/nat64-out2in/UDP packets')
7048 self.assertEqual(err - udpn, 1)
7049 err = self.statistics.get_counter('/err/nat64-out2in/ICMP packets')
7050 self.assertEqual(err - icmpn, 1)
7051 err = self.statistics.get_counter(
7052 '/err/nat64-out2in/good out2in packets processed')
7053 self.assertEqual(err - totaln, 3)
7055 bibs = self.statistics.get_counter('/nat64/total-bibs')
7056 self.assertEqual(bibs[0][0], 3)
7057 sessions = self.statistics.get_counter('/nat64/total-sessions')
7058 self.assertEqual(sessions[0][0], 3)
7061 pkts = self.create_stream_in_ip6(self.pg0, self.pg1)
7062 self.pg0.add_stream(pkts)
7063 self.pg_enable_capture(self.pg_interfaces)
7065 capture = self.pg1.get_capture(len(pkts))
7066 self.verify_capture_out(capture, nat_ip=self.nat_addr,
7067 dst_ip=self.pg1.remote_ip4)
7070 pkts = self.create_stream_out(self.pg1, dst_ip=self.nat_addr)
7071 self.pg1.add_stream(pkts)
7072 self.pg_enable_capture(self.pg_interfaces)
7074 capture = self.pg0.get_capture(len(pkts))
7075 self.verify_capture_in_ip6(capture, ip[IPv6].src, self.pg0.remote_ip6)
7077 ses_num_end = self.nat64_get_ses_num()
7079 self.assertEqual(ses_num_end - ses_num_start, 3)
7081 # tenant with specific VRF
7082 self.vapi.nat64_add_del_pool_addr_range(self.vrf1_nat_addr_n,
7083 self.vrf1_nat_addr_n,
7084 vrf_id=self.vrf1_id)
7085 self.vapi.nat64_add_del_interface(self.pg2.sw_if_index)
7087 pkts = self.create_stream_in_ip6(self.pg2, self.pg1)
7088 self.pg2.add_stream(pkts)
7089 self.pg_enable_capture(self.pg_interfaces)
7091 capture = self.pg1.get_capture(len(pkts))
7092 self.verify_capture_out(capture, nat_ip=self.vrf1_nat_addr,
7093 dst_ip=self.pg1.remote_ip4)
7095 pkts = self.create_stream_out(self.pg1, dst_ip=self.vrf1_nat_addr)
7096 self.pg1.add_stream(pkts)
7097 self.pg_enable_capture(self.pg_interfaces)
7099 capture = self.pg2.get_capture(len(pkts))
7100 self.verify_capture_in_ip6(capture, ip[IPv6].src, self.pg2.remote_ip6)
7102 def test_static(self):
7103 """ NAT64 static translation test """
7104 self.tcp_port_in = 60303
7105 self.udp_port_in = 60304
7106 self.icmp_id_in = 60305
7107 self.tcp_port_out = 60303
7108 self.udp_port_out = 60304
7109 self.icmp_id_out = 60305
7111 ses_num_start = self.nat64_get_ses_num()
7113 self.vapi.nat64_add_del_pool_addr_range(self.nat_addr_n,
7115 self.vapi.nat64_add_del_interface(self.pg0.sw_if_index)
7116 self.vapi.nat64_add_del_interface(self.pg1.sw_if_index, is_inside=0)
7118 self.vapi.nat64_add_del_static_bib(self.pg0.remote_ip6n,
7123 self.vapi.nat64_add_del_static_bib(self.pg0.remote_ip6n,
7128 self.vapi.nat64_add_del_static_bib(self.pg0.remote_ip6n,
7135 pkts = self.create_stream_in_ip6(self.pg0, self.pg1)
7136 self.pg0.add_stream(pkts)
7137 self.pg_enable_capture(self.pg_interfaces)
7139 capture = self.pg1.get_capture(len(pkts))
7140 self.verify_capture_out(capture, nat_ip=self.nat_addr,
7141 dst_ip=self.pg1.remote_ip4, same_port=True)
7144 pkts = self.create_stream_out(self.pg1, dst_ip=self.nat_addr)
7145 self.pg1.add_stream(pkts)
7146 self.pg_enable_capture(self.pg_interfaces)
7148 capture = self.pg0.get_capture(len(pkts))
7149 ip = IPv6(src=''.join(['64:ff9b::', self.pg1.remote_ip4]))
7150 self.verify_capture_in_ip6(capture, ip[IPv6].src, self.pg0.remote_ip6)
7152 ses_num_end = self.nat64_get_ses_num()
7154 self.assertEqual(ses_num_end - ses_num_start, 3)
7156 @unittest.skipUnless(running_extended_tests, "part of extended tests")
7157 def test_session_timeout(self):
7158 """ NAT64 session timeout """
7159 self.icmp_id_in = 1234
7160 self.vapi.nat64_add_del_pool_addr_range(self.nat_addr_n,
7162 self.vapi.nat64_add_del_interface(self.pg0.sw_if_index)
7163 self.vapi.nat64_add_del_interface(self.pg1.sw_if_index, is_inside=0)
7164 self.vapi.nat_set_timeouts(icmp=5, tcp_transitory=5, tcp_established=5)
7166 pkts = self.create_stream_in_ip6(self.pg0, self.pg1)
7167 self.pg0.add_stream(pkts)
7168 self.pg_enable_capture(self.pg_interfaces)
7170 capture = self.pg1.get_capture(len(pkts))
7172 ses_num_before_timeout = self.nat64_get_ses_num()
7176 # ICMP and TCP session after timeout
7177 ses_num_after_timeout = self.nat64_get_ses_num()
7178 self.assertEqual(ses_num_before_timeout - ses_num_after_timeout, 2)
7180 def test_icmp_error(self):
7181 """ NAT64 ICMP Error message translation """
7182 self.tcp_port_in = 6303
7183 self.udp_port_in = 6304
7184 self.icmp_id_in = 6305
7186 self.vapi.nat64_add_del_pool_addr_range(self.nat_addr_n,
7188 self.vapi.nat64_add_del_interface(self.pg0.sw_if_index)
7189 self.vapi.nat64_add_del_interface(self.pg1.sw_if_index, is_inside=0)
7191 # send some packets to create sessions
7192 pkts = self.create_stream_in_ip6(self.pg0, self.pg1)
7193 self.pg0.add_stream(pkts)
7194 self.pg_enable_capture(self.pg_interfaces)
7196 capture_ip4 = self.pg1.get_capture(len(pkts))
7197 self.verify_capture_out(capture_ip4,
7198 nat_ip=self.nat_addr,
7199 dst_ip=self.pg1.remote_ip4)
7201 pkts = self.create_stream_out(self.pg1, dst_ip=self.nat_addr)
7202 self.pg1.add_stream(pkts)
7203 self.pg_enable_capture(self.pg_interfaces)
7205 capture_ip6 = self.pg0.get_capture(len(pkts))
7206 ip = IPv6(src=''.join(['64:ff9b::', self.pg1.remote_ip4]))
7207 self.verify_capture_in_ip6(capture_ip6, ip[IPv6].src,
7208 self.pg0.remote_ip6)
7211 pkts = [Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
7212 IPv6(src=self.pg0.remote_ip6, dst=ip[IPv6].src) /
7213 ICMPv6DestUnreach(code=1) /
7214 packet[IPv6] for packet in capture_ip6]
7215 self.pg0.add_stream(pkts)
7216 self.pg_enable_capture(self.pg_interfaces)
7218 capture = self.pg1.get_capture(len(pkts))
7219 for packet in capture:
7221 self.assertEqual(packet[IP].src, self.nat_addr)
7222 self.assertEqual(packet[IP].dst, self.pg1.remote_ip4)
7223 self.assertEqual(packet[ICMP].type, 3)
7224 self.assertEqual(packet[ICMP].code, 13)
7225 inner = packet[IPerror]
7226 self.assertEqual(inner.src, self.pg1.remote_ip4)
7227 self.assertEqual(inner.dst, self.nat_addr)
7228 self.assert_packet_checksums_valid(packet)
7229 if inner.haslayer(TCPerror):
7230 self.assertEqual(inner[TCPerror].dport, self.tcp_port_out)
7231 elif inner.haslayer(UDPerror):
7232 self.assertEqual(inner[UDPerror].dport, self.udp_port_out)
7234 self.assertEqual(inner[ICMPerror].id, self.icmp_id_out)
7236 self.logger.error(ppp("Unexpected or invalid packet:", packet))
7240 pkts = [Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
7241 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
7242 ICMP(type=3, code=13) /
7243 packet[IP] for packet in capture_ip4]
7244 self.pg1.add_stream(pkts)
7245 self.pg_enable_capture(self.pg_interfaces)
7247 capture = self.pg0.get_capture(len(pkts))
7248 for packet in capture:
7250 self.assertEqual(packet[IPv6].src, ip.src)
7251 self.assertEqual(packet[IPv6].dst, self.pg0.remote_ip6)
7252 icmp = packet[ICMPv6DestUnreach]
7253 self.assertEqual(icmp.code, 1)
7254 inner = icmp[IPerror6]
7255 self.assertEqual(inner.src, self.pg0.remote_ip6)
7256 self.assertEqual(inner.dst, ip.src)
7257 self.assert_icmpv6_checksum_valid(packet)
7258 if inner.haslayer(TCPerror):
7259 self.assertEqual(inner[TCPerror].sport, self.tcp_port_in)
7260 elif inner.haslayer(UDPerror):
7261 self.assertEqual(inner[UDPerror].sport, self.udp_port_in)
7263 self.assertEqual(inner[ICMPv6EchoRequest].id,
7266 self.logger.error(ppp("Unexpected or invalid packet:", packet))
7269 def test_hairpinning(self):
7270 """ NAT64 hairpinning """
7272 client = self.pg0.remote_hosts[0]
7273 server = self.pg0.remote_hosts[1]
7274 server_tcp_in_port = 22
7275 server_tcp_out_port = 4022
7276 server_udp_in_port = 23
7277 server_udp_out_port = 4023
7278 client_tcp_in_port = 1234
7279 client_udp_in_port = 1235
7280 client_tcp_out_port = 0
7281 client_udp_out_port = 0
7282 ip = IPv6(src=''.join(['64:ff9b::', self.nat_addr]))
7283 nat_addr_ip6 = ip.src
7285 self.vapi.nat64_add_del_pool_addr_range(self.nat_addr_n,
7287 self.vapi.nat64_add_del_interface(self.pg0.sw_if_index)
7288 self.vapi.nat64_add_del_interface(self.pg1.sw_if_index, is_inside=0)
7290 self.vapi.nat64_add_del_static_bib(server.ip6n,
7293 server_tcp_out_port,
7295 self.vapi.nat64_add_del_static_bib(server.ip6n,
7298 server_udp_out_port,
7303 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
7304 IPv6(src=client.ip6, dst=nat_addr_ip6) /
7305 TCP(sport=client_tcp_in_port, dport=server_tcp_out_port))
7307 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
7308 IPv6(src=client.ip6, dst=nat_addr_ip6) /
7309 UDP(sport=client_udp_in_port, dport=server_udp_out_port))
7311 self.pg0.add_stream(pkts)
7312 self.pg_enable_capture(self.pg_interfaces)
7314 capture = self.pg0.get_capture(len(pkts))
7315 for packet in capture:
7317 self.assertEqual(packet[IPv6].src, nat_addr_ip6)
7318 self.assertEqual(packet[IPv6].dst, server.ip6)
7319 self.assert_packet_checksums_valid(packet)
7320 if packet.haslayer(TCP):
7321 self.assertNotEqual(packet[TCP].sport, client_tcp_in_port)
7322 self.assertEqual(packet[TCP].dport, server_tcp_in_port)
7323 client_tcp_out_port = packet[TCP].sport
7325 self.assertNotEqual(packet[UDP].sport, client_udp_in_port)
7326 self.assertEqual(packet[UDP].dport, server_udp_in_port)
7327 client_udp_out_port = packet[UDP].sport
7329 self.logger.error(ppp("Unexpected or invalid packet:", packet))
7334 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
7335 IPv6(src=server.ip6, dst=nat_addr_ip6) /
7336 TCP(sport=server_tcp_in_port, dport=client_tcp_out_port))
7338 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
7339 IPv6(src=server.ip6, dst=nat_addr_ip6) /
7340 UDP(sport=server_udp_in_port, dport=client_udp_out_port))
7342 self.pg0.add_stream(pkts)
7343 self.pg_enable_capture(self.pg_interfaces)
7345 capture = self.pg0.get_capture(len(pkts))
7346 for packet in capture:
7348 self.assertEqual(packet[IPv6].src, nat_addr_ip6)
7349 self.assertEqual(packet[IPv6].dst, client.ip6)
7350 self.assert_packet_checksums_valid(packet)
7351 if packet.haslayer(TCP):
7352 self.assertEqual(packet[TCP].sport, server_tcp_out_port)
7353 self.assertEqual(packet[TCP].dport, client_tcp_in_port)
7355 self.assertEqual(packet[UDP].sport, server_udp_out_port)
7356 self.assertEqual(packet[UDP].dport, client_udp_in_port)
7358 self.logger.error(ppp("Unexpected or invalid packet:", packet))
7363 pkts = [Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
7364 IPv6(src=client.ip6, dst=nat_addr_ip6) /
7365 ICMPv6DestUnreach(code=1) /
7366 packet[IPv6] for packet in capture]
7367 self.pg0.add_stream(pkts)
7368 self.pg_enable_capture(self.pg_interfaces)
7370 capture = self.pg0.get_capture(len(pkts))
7371 for packet in capture:
7373 self.assertEqual(packet[IPv6].src, nat_addr_ip6)
7374 self.assertEqual(packet[IPv6].dst, server.ip6)
7375 icmp = packet[ICMPv6DestUnreach]
7376 self.assertEqual(icmp.code, 1)
7377 inner = icmp[IPerror6]
7378 self.assertEqual(inner.src, server.ip6)
7379 self.assertEqual(inner.dst, nat_addr_ip6)
7380 self.assert_packet_checksums_valid(packet)
7381 if inner.haslayer(TCPerror):
7382 self.assertEqual(inner[TCPerror].sport, server_tcp_in_port)
7383 self.assertEqual(inner[TCPerror].dport,
7384 client_tcp_out_port)
7386 self.assertEqual(inner[UDPerror].sport, server_udp_in_port)
7387 self.assertEqual(inner[UDPerror].dport,
7388 client_udp_out_port)
7390 self.logger.error(ppp("Unexpected or invalid packet:", packet))
7393 def test_prefix(self):
7394 """ NAT64 Network-Specific Prefix """
7396 self.vapi.nat64_add_del_pool_addr_range(self.nat_addr_n,
7398 self.vapi.nat64_add_del_interface(self.pg0.sw_if_index)
7399 self.vapi.nat64_add_del_interface(self.pg1.sw_if_index, is_inside=0)
7400 self.vapi.nat64_add_del_pool_addr_range(self.vrf1_nat_addr_n,
7401 self.vrf1_nat_addr_n,
7402 vrf_id=self.vrf1_id)
7403 self.vapi.nat64_add_del_interface(self.pg2.sw_if_index)
7406 global_pref64 = "2001:db8::"
7407 global_pref64_n = socket.inet_pton(socket.AF_INET6, global_pref64)
7408 global_pref64_len = 32
7409 self.vapi.nat64_add_del_prefix(global_pref64_n, global_pref64_len)
7411 prefix = self.vapi.nat64_prefix_dump()
7412 self.assertEqual(len(prefix), 1)
7413 self.assertEqual(prefix[0].prefix, global_pref64_n)
7414 self.assertEqual(prefix[0].prefix_len, global_pref64_len)
7415 self.assertEqual(prefix[0].vrf_id, 0)
7417 # Add tenant specific prefix
7418 vrf1_pref64 = "2001:db8:122:300::"
7419 vrf1_pref64_n = socket.inet_pton(socket.AF_INET6, vrf1_pref64)
7420 vrf1_pref64_len = 56
7421 self.vapi.nat64_add_del_prefix(vrf1_pref64_n,
7423 vrf_id=self.vrf1_id)
7424 prefix = self.vapi.nat64_prefix_dump()
7425 self.assertEqual(len(prefix), 2)
7428 pkts = self.create_stream_in_ip6(self.pg0,
7431 plen=global_pref64_len)
7432 self.pg0.add_stream(pkts)
7433 self.pg_enable_capture(self.pg_interfaces)
7435 capture = self.pg1.get_capture(len(pkts))
7436 self.verify_capture_out(capture, nat_ip=self.nat_addr,
7437 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 dst_ip = self.compose_ip6(self.pg1.remote_ip4,
7447 self.verify_capture_in_ip6(capture, dst_ip, self.pg0.remote_ip6)
7449 # Tenant specific prefix
7450 pkts = self.create_stream_in_ip6(self.pg2,
7453 plen=vrf1_pref64_len)
7454 self.pg2.add_stream(pkts)
7455 self.pg_enable_capture(self.pg_interfaces)
7457 capture = self.pg1.get_capture(len(pkts))
7458 self.verify_capture_out(capture, nat_ip=self.vrf1_nat_addr,
7459 dst_ip=self.pg1.remote_ip4)
7461 pkts = self.create_stream_out(self.pg1, dst_ip=self.vrf1_nat_addr)
7462 self.pg1.add_stream(pkts)
7463 self.pg_enable_capture(self.pg_interfaces)
7465 capture = self.pg2.get_capture(len(pkts))
7466 dst_ip = self.compose_ip6(self.pg1.remote_ip4,
7469 self.verify_capture_in_ip6(capture, dst_ip, self.pg2.remote_ip6)
7471 def test_unknown_proto(self):
7472 """ NAT64 translate packet with unknown protocol """
7474 self.vapi.nat64_add_del_pool_addr_range(self.nat_addr_n,
7476 self.vapi.nat64_add_del_interface(self.pg0.sw_if_index)
7477 self.vapi.nat64_add_del_interface(self.pg1.sw_if_index, is_inside=0)
7478 remote_ip6 = self.compose_ip6(self.pg1.remote_ip4, '64:ff9b::', 96)
7481 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
7482 IPv6(src=self.pg0.remote_ip6, dst=remote_ip6) /
7483 TCP(sport=self.tcp_port_in, dport=20))
7484 self.pg0.add_stream(p)
7485 self.pg_enable_capture(self.pg_interfaces)
7487 p = self.pg1.get_capture(1)
7489 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
7490 IPv6(src=self.pg0.remote_ip6, dst=remote_ip6, nh=47) /
7492 IP(src=self.pg2.local_ip4, dst=self.pg2.remote_ip4) /
7493 TCP(sport=1234, dport=1234))
7494 self.pg0.add_stream(p)
7495 self.pg_enable_capture(self.pg_interfaces)
7497 p = self.pg1.get_capture(1)
7500 self.assertEqual(packet[IP].src, self.nat_addr)
7501 self.assertEqual(packet[IP].dst, self.pg1.remote_ip4)
7502 self.assertEqual(packet.haslayer(GRE), 1)
7503 self.assert_packet_checksums_valid(packet)
7505 self.logger.error(ppp("Unexpected or invalid packet:", packet))
7509 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
7510 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
7512 IP(src=self.pg2.remote_ip4, dst=self.pg2.local_ip4) /
7513 TCP(sport=1234, dport=1234))
7514 self.pg1.add_stream(p)
7515 self.pg_enable_capture(self.pg_interfaces)
7517 p = self.pg0.get_capture(1)
7520 self.assertEqual(packet[IPv6].src, remote_ip6)
7521 self.assertEqual(packet[IPv6].dst, self.pg0.remote_ip6)
7522 self.assertEqual(packet[IPv6].nh, 47)
7524 self.logger.error(ppp("Unexpected or invalid packet:", packet))
7527 def test_hairpinning_unknown_proto(self):
7528 """ NAT64 translate packet with unknown protocol - hairpinning """
7530 client = self.pg0.remote_hosts[0]
7531 server = self.pg0.remote_hosts[1]
7532 server_tcp_in_port = 22
7533 server_tcp_out_port = 4022
7534 client_tcp_in_port = 1234
7535 client_tcp_out_port = 1235
7536 server_nat_ip = "10.0.0.100"
7537 client_nat_ip = "10.0.0.110"
7538 server_nat_ip_n = socket.inet_pton(socket.AF_INET, server_nat_ip)
7539 client_nat_ip_n = socket.inet_pton(socket.AF_INET, client_nat_ip)
7540 server_nat_ip6 = self.compose_ip6(server_nat_ip, '64:ff9b::', 96)
7541 client_nat_ip6 = self.compose_ip6(client_nat_ip, '64:ff9b::', 96)
7543 self.vapi.nat64_add_del_pool_addr_range(server_nat_ip_n,
7545 self.vapi.nat64_add_del_interface(self.pg0.sw_if_index)
7546 self.vapi.nat64_add_del_interface(self.pg1.sw_if_index, is_inside=0)
7548 self.vapi.nat64_add_del_static_bib(server.ip6n,
7551 server_tcp_out_port,
7554 self.vapi.nat64_add_del_static_bib(server.ip6n,
7560 self.vapi.nat64_add_del_static_bib(client.ip6n,
7563 client_tcp_out_port,
7567 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
7568 IPv6(src=client.ip6, dst=server_nat_ip6) /
7569 TCP(sport=client_tcp_in_port, dport=server_tcp_out_port))
7570 self.pg0.add_stream(p)
7571 self.pg_enable_capture(self.pg_interfaces)
7573 p = self.pg0.get_capture(1)
7575 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
7576 IPv6(src=client.ip6, dst=server_nat_ip6, nh=IP_PROTOS.gre) /
7578 IP(src=self.pg2.local_ip4, dst=self.pg2.remote_ip4) /
7579 TCP(sport=1234, dport=1234))
7580 self.pg0.add_stream(p)
7581 self.pg_enable_capture(self.pg_interfaces)
7583 p = self.pg0.get_capture(1)
7586 self.assertEqual(packet[IPv6].src, client_nat_ip6)
7587 self.assertEqual(packet[IPv6].dst, server.ip6)
7588 self.assertEqual(packet[IPv6].nh, IP_PROTOS.gre)
7590 self.logger.error(ppp("Unexpected or invalid packet:", packet))
7594 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
7595 IPv6(src=server.ip6, dst=client_nat_ip6, nh=IP_PROTOS.gre) /
7597 IP(src=self.pg2.remote_ip4, dst=self.pg2.local_ip4) /
7598 TCP(sport=1234, dport=1234))
7599 self.pg0.add_stream(p)
7600 self.pg_enable_capture(self.pg_interfaces)
7602 p = self.pg0.get_capture(1)
7605 self.assertEqual(packet[IPv6].src, server_nat_ip6)
7606 self.assertEqual(packet[IPv6].dst, client.ip6)
7607 self.assertEqual(packet[IPv6].nh, IP_PROTOS.gre)
7609 self.logger.error(ppp("Unexpected or invalid packet:", packet))
7612 def test_one_armed_nat64(self):
7613 """ One armed NAT64 """
7615 remote_host_ip6 = self.compose_ip6(self.pg3.remote_ip4,
7619 self.vapi.nat64_add_del_pool_addr_range(self.nat_addr_n,
7621 self.vapi.nat64_add_del_interface(self.pg3.sw_if_index)
7622 self.vapi.nat64_add_del_interface(self.pg3.sw_if_index, is_inside=0)
7625 p = (Ether(src=self.pg3.remote_mac, dst=self.pg3.local_mac) /
7626 IPv6(src=self.pg3.remote_ip6, dst=remote_host_ip6) /
7627 TCP(sport=12345, dport=80))
7628 self.pg3.add_stream(p)
7629 self.pg_enable_capture(self.pg_interfaces)
7631 capture = self.pg3.get_capture(1)
7636 self.assertEqual(ip.src, self.nat_addr)
7637 self.assertEqual(ip.dst, self.pg3.remote_ip4)
7638 self.assertNotEqual(tcp.sport, 12345)
7639 external_port = tcp.sport
7640 self.assertEqual(tcp.dport, 80)
7641 self.assert_packet_checksums_valid(p)
7643 self.logger.error(ppp("Unexpected or invalid packet:", p))
7647 p = (Ether(src=self.pg3.remote_mac, dst=self.pg3.local_mac) /
7648 IP(src=self.pg3.remote_ip4, dst=self.nat_addr) /
7649 TCP(sport=80, dport=external_port))
7650 self.pg3.add_stream(p)
7651 self.pg_enable_capture(self.pg_interfaces)
7653 capture = self.pg3.get_capture(1)
7658 self.assertEqual(ip.src, remote_host_ip6)
7659 self.assertEqual(ip.dst, self.pg3.remote_ip6)
7660 self.assertEqual(tcp.sport, 80)
7661 self.assertEqual(tcp.dport, 12345)
7662 self.assert_packet_checksums_valid(p)
7664 self.logger.error(ppp("Unexpected or invalid packet:", p))
7667 def test_frag_in_order(self):
7668 """ NAT64 translate fragments arriving in order """
7669 self.tcp_port_in = random.randint(1025, 65535)
7671 self.vapi.nat64_add_del_pool_addr_range(self.nat_addr_n,
7673 self.vapi.nat64_add_del_interface(self.pg0.sw_if_index)
7674 self.vapi.nat64_add_del_interface(self.pg1.sw_if_index, is_inside=0)
7676 reass = self.vapi.nat_reass_dump()
7677 reass_n_start = len(reass)
7681 pkts = self.create_stream_frag_ip6(self.pg0, self.pg1.remote_ip4,
7682 self.tcp_port_in, 20, data)
7683 self.pg0.add_stream(pkts)
7684 self.pg_enable_capture(self.pg_interfaces)
7686 frags = self.pg1.get_capture(len(pkts))
7687 p = self.reass_frags_and_verify(frags,
7689 self.pg1.remote_ip4)
7690 self.assertEqual(p[TCP].dport, 20)
7691 self.assertNotEqual(p[TCP].sport, self.tcp_port_in)
7692 self.tcp_port_out = p[TCP].sport
7693 self.assertEqual(data, p[Raw].load)
7696 data = "A" * 4 + "b" * 16 + "C" * 3
7697 pkts = self.create_stream_frag(self.pg1,
7702 self.pg1.add_stream(pkts)
7703 self.pg_enable_capture(self.pg_interfaces)
7705 frags = self.pg0.get_capture(len(pkts))
7706 src = self.compose_ip6(self.pg1.remote_ip4, '64:ff9b::', 96)
7707 p = self.reass_frags_and_verify_ip6(frags, src, self.pg0.remote_ip6)
7708 self.assertEqual(p[TCP].sport, 20)
7709 self.assertEqual(p[TCP].dport, self.tcp_port_in)
7710 self.assertEqual(data, p[Raw].load)
7712 reass = self.vapi.nat_reass_dump()
7713 reass_n_end = len(reass)
7715 self.assertEqual(reass_n_end - reass_n_start, 2)
7717 def test_reass_hairpinning(self):
7718 """ NAT64 fragments hairpinning """
7720 server = self.pg0.remote_hosts[1]
7721 server_in_port = random.randint(1025, 65535)
7722 server_out_port = random.randint(1025, 65535)
7723 client_in_port = random.randint(1025, 65535)
7724 ip = IPv6(src=''.join(['64:ff9b::', self.nat_addr]))
7725 nat_addr_ip6 = ip.src
7727 self.vapi.nat64_add_del_pool_addr_range(self.nat_addr_n,
7729 self.vapi.nat64_add_del_interface(self.pg0.sw_if_index)
7730 self.vapi.nat64_add_del_interface(self.pg1.sw_if_index, is_inside=0)
7732 # add static BIB entry for server
7733 self.vapi.nat64_add_del_static_bib(server.ip6n,
7739 # send packet from host to server
7740 pkts = self.create_stream_frag_ip6(self.pg0,
7745 self.pg0.add_stream(pkts)
7746 self.pg_enable_capture(self.pg_interfaces)
7748 frags = self.pg0.get_capture(len(pkts))
7749 p = self.reass_frags_and_verify_ip6(frags, nat_addr_ip6, server.ip6)
7750 self.assertNotEqual(p[TCP].sport, client_in_port)
7751 self.assertEqual(p[TCP].dport, server_in_port)
7752 self.assertEqual(data, p[Raw].load)
7754 def test_frag_out_of_order(self):
7755 """ NAT64 translate fragments arriving out of order """
7756 self.tcp_port_in = random.randint(1025, 65535)
7758 self.vapi.nat64_add_del_pool_addr_range(self.nat_addr_n,
7760 self.vapi.nat64_add_del_interface(self.pg0.sw_if_index)
7761 self.vapi.nat64_add_del_interface(self.pg1.sw_if_index, is_inside=0)
7765 pkts = self.create_stream_frag_ip6(self.pg0, self.pg1.remote_ip4,
7766 self.tcp_port_in, 20, data)
7768 self.pg0.add_stream(pkts)
7769 self.pg_enable_capture(self.pg_interfaces)
7771 frags = self.pg1.get_capture(len(pkts))
7772 p = self.reass_frags_and_verify(frags,
7774 self.pg1.remote_ip4)
7775 self.assertEqual(p[TCP].dport, 20)
7776 self.assertNotEqual(p[TCP].sport, self.tcp_port_in)
7777 self.tcp_port_out = p[TCP].sport
7778 self.assertEqual(data, p[Raw].load)
7781 data = "A" * 4 + "B" * 16 + "C" * 3
7782 pkts = self.create_stream_frag(self.pg1,
7788 self.pg1.add_stream(pkts)
7789 self.pg_enable_capture(self.pg_interfaces)
7791 frags = self.pg0.get_capture(len(pkts))
7792 src = self.compose_ip6(self.pg1.remote_ip4, '64:ff9b::', 96)
7793 p = self.reass_frags_and_verify_ip6(frags, src, self.pg0.remote_ip6)
7794 self.assertEqual(p[TCP].sport, 20)
7795 self.assertEqual(p[TCP].dport, self.tcp_port_in)
7796 self.assertEqual(data, p[Raw].load)
7798 def test_interface_addr(self):
7799 """ Acquire NAT64 pool addresses from interface """
7800 self.vapi.nat64_add_interface_addr(self.pg4.sw_if_index)
7802 # no address in NAT64 pool
7803 adresses = self.vapi.nat44_address_dump()
7804 self.assertEqual(0, len(adresses))
7806 # configure interface address and check NAT64 address pool
7807 self.pg4.config_ip4()
7808 addresses = self.vapi.nat64_pool_addr_dump()
7809 self.assertEqual(len(addresses), 1)
7810 self.assertEqual(addresses[0].address, self.pg4.local_ip4n)
7812 # remove interface address and check NAT64 address pool
7813 self.pg4.unconfig_ip4()
7814 addresses = self.vapi.nat64_pool_addr_dump()
7815 self.assertEqual(0, len(adresses))
7817 @unittest.skipUnless(running_extended_tests, "part of extended tests")
7818 def test_ipfix_max_bibs_sessions(self):
7819 """ IPFIX logging maximum session and BIB entries exceeded """
7822 remote_host_ip6 = self.compose_ip6(self.pg1.remote_ip4,
7826 self.vapi.nat64_add_del_pool_addr_range(self.nat_addr_n,
7828 self.vapi.nat64_add_del_interface(self.pg0.sw_if_index)
7829 self.vapi.nat64_add_del_interface(self.pg1.sw_if_index, is_inside=0)
7833 for i in range(0, max_bibs):
7834 src = "fd01:aa::%x" % (i)
7835 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
7836 IPv6(src=src, dst=remote_host_ip6) /
7837 TCP(sport=12345, dport=80))
7839 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
7840 IPv6(src=src, dst=remote_host_ip6) /
7841 TCP(sport=12345, dport=22))
7843 self.pg0.add_stream(pkts)
7844 self.pg_enable_capture(self.pg_interfaces)
7846 self.pg1.get_capture(max_sessions)
7848 self.vapi.set_ipfix_exporter(collector_address=self.pg3.remote_ip4n,
7849 src_address=self.pg3.local_ip4n,
7851 template_interval=10)
7852 self.vapi.nat_ipfix(domain_id=self.ipfix_domain_id,
7853 src_port=self.ipfix_src_port)
7855 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
7856 IPv6(src=src, dst=remote_host_ip6) /
7857 TCP(sport=12345, dport=25))
7858 self.pg0.add_stream(p)
7859 self.pg_enable_capture(self.pg_interfaces)
7861 self.pg1.assert_nothing_captured()
7863 self.vapi.cli("ipfix flush") # FIXME this should be an API call
7864 capture = self.pg3.get_capture(9)
7865 ipfix = IPFIXDecoder()
7866 # first load template
7868 self.assertTrue(p.haslayer(IPFIX))
7869 self.assertEqual(p[IP].src, self.pg3.local_ip4)
7870 self.assertEqual(p[IP].dst, self.pg3.remote_ip4)
7871 self.assertEqual(p[UDP].sport, self.ipfix_src_port)
7872 self.assertEqual(p[UDP].dport, 4739)
7873 self.assertEqual(p[IPFIX].observationDomainID,
7874 self.ipfix_domain_id)
7875 if p.haslayer(Template):
7876 ipfix.add_template(p.getlayer(Template))
7877 # verify events in data set
7879 if p.haslayer(Data):
7880 data = ipfix.decode_data_set(p.getlayer(Set))
7881 self.verify_ipfix_max_sessions(data, max_sessions)
7883 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
7884 IPv6(src=self.pg0.remote_ip6, dst=remote_host_ip6) /
7885 TCP(sport=12345, dport=80))
7886 self.pg0.add_stream(p)
7887 self.pg_enable_capture(self.pg_interfaces)
7889 self.pg1.assert_nothing_captured()
7891 self.vapi.cli("ipfix flush") # FIXME this should be an API call
7892 capture = self.pg3.get_capture(1)
7893 # verify events in data set
7895 self.assertTrue(p.haslayer(IPFIX))
7896 self.assertEqual(p[IP].src, self.pg3.local_ip4)
7897 self.assertEqual(p[IP].dst, self.pg3.remote_ip4)
7898 self.assertEqual(p[UDP].sport, self.ipfix_src_port)
7899 self.assertEqual(p[UDP].dport, 4739)
7900 self.assertEqual(p[IPFIX].observationDomainID,
7901 self.ipfix_domain_id)
7902 if p.haslayer(Data):
7903 data = ipfix.decode_data_set(p.getlayer(Set))
7904 self.verify_ipfix_max_bibs(data, max_bibs)
7906 def test_ipfix_max_frags(self):
7907 """ IPFIX logging maximum fragments pending reassembly exceeded """
7908 self.vapi.nat64_add_del_pool_addr_range(self.nat_addr_n,
7910 self.vapi.nat64_add_del_interface(self.pg0.sw_if_index)
7911 self.vapi.nat64_add_del_interface(self.pg1.sw_if_index, is_inside=0)
7912 self.vapi.nat_set_reass(max_frag=1, is_ip6=1)
7913 self.vapi.set_ipfix_exporter(collector_address=self.pg3.remote_ip4n,
7914 src_address=self.pg3.local_ip4n,
7916 template_interval=10)
7917 self.vapi.nat_ipfix(domain_id=self.ipfix_domain_id,
7918 src_port=self.ipfix_src_port)
7921 pkts = self.create_stream_frag_ip6(self.pg0, self.pg1.remote_ip4,
7922 self.tcp_port_in, 20, data)
7924 self.pg0.add_stream(pkts)
7925 self.pg_enable_capture(self.pg_interfaces)
7927 self.pg1.assert_nothing_captured()
7929 self.vapi.cli("ipfix flush") # FIXME this should be an API call
7930 capture = self.pg3.get_capture(9)
7931 ipfix = IPFIXDecoder()
7932 # first load template
7934 self.assertTrue(p.haslayer(IPFIX))
7935 self.assertEqual(p[IP].src, self.pg3.local_ip4)
7936 self.assertEqual(p[IP].dst, self.pg3.remote_ip4)
7937 self.assertEqual(p[UDP].sport, self.ipfix_src_port)
7938 self.assertEqual(p[UDP].dport, 4739)
7939 self.assertEqual(p[IPFIX].observationDomainID,
7940 self.ipfix_domain_id)
7941 if p.haslayer(Template):
7942 ipfix.add_template(p.getlayer(Template))
7943 # verify events in data set
7945 if p.haslayer(Data):
7946 data = ipfix.decode_data_set(p.getlayer(Set))
7947 self.verify_ipfix_max_fragments_ip6(data, 1,
7948 self.pg0.remote_ip6n)
7950 def test_ipfix_bib_ses(self):
7951 """ IPFIX logging NAT64 BIB/session create and delete events """
7952 self.tcp_port_in = random.randint(1025, 65535)
7953 remote_host_ip6 = self.compose_ip6(self.pg1.remote_ip4,
7957 self.vapi.nat64_add_del_pool_addr_range(self.nat_addr_n,
7959 self.vapi.nat64_add_del_interface(self.pg0.sw_if_index)
7960 self.vapi.nat64_add_del_interface(self.pg1.sw_if_index, is_inside=0)
7961 self.vapi.set_ipfix_exporter(collector_address=self.pg3.remote_ip4n,
7962 src_address=self.pg3.local_ip4n,
7964 template_interval=10)
7965 self.vapi.nat_ipfix(domain_id=self.ipfix_domain_id,
7966 src_port=self.ipfix_src_port)
7969 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
7970 IPv6(src=self.pg0.remote_ip6, dst=remote_host_ip6) /
7971 TCP(sport=self.tcp_port_in, dport=25))
7972 self.pg0.add_stream(p)
7973 self.pg_enable_capture(self.pg_interfaces)
7975 p = self.pg1.get_capture(1)
7976 self.tcp_port_out = p[0][TCP].sport
7977 self.vapi.cli("ipfix flush") # FIXME this should be an API call
7978 capture = self.pg3.get_capture(10)
7979 ipfix = IPFIXDecoder()
7980 # first load template
7982 self.assertTrue(p.haslayer(IPFIX))
7983 self.assertEqual(p[IP].src, self.pg3.local_ip4)
7984 self.assertEqual(p[IP].dst, self.pg3.remote_ip4)
7985 self.assertEqual(p[UDP].sport, self.ipfix_src_port)
7986 self.assertEqual(p[UDP].dport, 4739)
7987 self.assertEqual(p[IPFIX].observationDomainID,
7988 self.ipfix_domain_id)
7989 if p.haslayer(Template):
7990 ipfix.add_template(p.getlayer(Template))
7991 # verify events in data set
7993 if p.haslayer(Data):
7994 data = ipfix.decode_data_set(p.getlayer(Set))
7995 if ord(data[0][230]) == 10:
7996 self.verify_ipfix_bib(data, 1, self.pg0.remote_ip6n)
7997 elif ord(data[0][230]) == 6:
7998 self.verify_ipfix_nat64_ses(data,
8000 self.pg0.remote_ip6n,
8001 self.pg1.remote_ip4,
8004 self.logger.error(ppp("Unexpected or invalid packet: ", p))
8007 self.pg_enable_capture(self.pg_interfaces)
8008 self.vapi.nat64_add_del_pool_addr_range(self.nat_addr_n,
8011 self.vapi.cli("ipfix flush") # FIXME this should be an API call
8012 capture = self.pg3.get_capture(2)
8013 # verify events in data set
8015 self.assertTrue(p.haslayer(IPFIX))
8016 self.assertEqual(p[IP].src, self.pg3.local_ip4)
8017 self.assertEqual(p[IP].dst, self.pg3.remote_ip4)
8018 self.assertEqual(p[UDP].sport, self.ipfix_src_port)
8019 self.assertEqual(p[UDP].dport, 4739)
8020 self.assertEqual(p[IPFIX].observationDomainID,
8021 self.ipfix_domain_id)
8022 if p.haslayer(Data):
8023 data = ipfix.decode_data_set(p.getlayer(Set))
8024 if ord(data[0][230]) == 11:
8025 self.verify_ipfix_bib(data, 0, self.pg0.remote_ip6n)
8026 elif ord(data[0][230]) == 7:
8027 self.verify_ipfix_nat64_ses(data,
8029 self.pg0.remote_ip6n,
8030 self.pg1.remote_ip4,
8033 self.logger.error(ppp("Unexpected or invalid packet: ", p))
8035 def test_syslog_sess(self):
8036 """ Test syslog session creation and deletion """
8037 self.tcp_port_in = random.randint(1025, 65535)
8038 remote_host_ip6 = self.compose_ip6(self.pg1.remote_ip4,
8042 self.vapi.nat64_add_del_pool_addr_range(self.nat_addr_n,
8044 self.vapi.nat64_add_del_interface(self.pg0.sw_if_index)
8045 self.vapi.nat64_add_del_interface(self.pg1.sw_if_index, is_inside=0)
8046 self.vapi.syslog_set_filter(SYSLOG_SEVERITY.INFO)
8047 self.vapi.syslog_set_sender(self.pg3.remote_ip4n, self.pg3.local_ip4n)
8049 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
8050 IPv6(src=self.pg0.remote_ip6, dst=remote_host_ip6) /
8051 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port))
8052 self.pg0.add_stream(p)
8053 self.pg_enable_capture(self.pg_interfaces)
8055 p = self.pg1.get_capture(1)
8056 self.tcp_port_out = p[0][TCP].sport
8057 capture = self.pg3.get_capture(1)
8058 self.verify_syslog_sess(capture[0][Raw].load, is_ip6=True)
8060 self.pg_enable_capture(self.pg_interfaces)
8062 self.vapi.nat64_add_del_pool_addr_range(self.nat_addr_n,
8065 capture = self.pg3.get_capture(1)
8066 self.verify_syslog_sess(capture[0][Raw].load, False, True)
8068 def nat64_get_ses_num(self):
8070 Return number of active NAT64 sessions.
8072 st = self.vapi.nat64_st_dump()
8075 def clear_nat64(self):
8077 Clear NAT64 configuration.
8079 self.vapi.nat_ipfix(enable=0, src_port=self.ipfix_src_port,
8080 domain_id=self.ipfix_domain_id)
8081 self.ipfix_src_port = 4739
8082 self.ipfix_domain_id = 1
8084 self.vapi.syslog_set_filter(SYSLOG_SEVERITY.EMERG)
8086 self.vapi.nat_set_timeouts()
8088 interfaces = self.vapi.nat64_interface_dump()
8089 for intf in interfaces:
8090 if intf.is_inside > 1:
8091 self.vapi.nat64_add_del_interface(intf.sw_if_index,
8094 self.vapi.nat64_add_del_interface(intf.sw_if_index,
8098 bib = self.vapi.nat64_bib_dump(255)
8101 self.vapi.nat64_add_del_static_bib(bibe.i_addr,
8109 adresses = self.vapi.nat64_pool_addr_dump()
8110 for addr in adresses:
8111 self.vapi.nat64_add_del_pool_addr_range(addr.address,
8116 prefixes = self.vapi.nat64_prefix_dump()
8117 for prefix in prefixes:
8118 self.vapi.nat64_add_del_prefix(prefix.prefix,
8120 vrf_id=prefix.vrf_id,
8123 bibs = self.statistics.get_counter('/nat64/total-bibs')
8124 self.assertEqual(bibs[0][0], 0)
8125 sessions = self.statistics.get_counter('/nat64/total-sessions')
8126 self.assertEqual(sessions[0][0], 0)
8129 super(TestNAT64, self).tearDown()
8130 if not self.vpp_dead:
8131 self.logger.info(self.vapi.cli("show nat64 pool"))
8132 self.logger.info(self.vapi.cli("show nat64 interfaces"))
8133 self.logger.info(self.vapi.cli("show nat64 prefix"))
8134 self.logger.info(self.vapi.cli("show nat64 bib all"))
8135 self.logger.info(self.vapi.cli("show nat64 session table all"))
8136 self.logger.info(self.vapi.cli("show nat virtual-reassembly"))
8140 class TestDSlite(MethodHolder):
8141 """ DS-Lite Test Cases """
8144 def setUpClass(cls):
8145 super(TestDSlite, cls).setUpClass()
8148 cls.nat_addr = '10.0.0.3'
8149 cls.nat_addr_n = socket.inet_pton(socket.AF_INET, cls.nat_addr)
8151 cls.create_pg_interfaces(range(3))
8153 cls.pg0.config_ip4()
8154 cls.pg0.resolve_arp()
8156 cls.pg1.config_ip6()
8157 cls.pg1.generate_remote_hosts(2)
8158 cls.pg1.configure_ipv6_neighbors()
8160 cls.pg2.config_ip4()
8161 cls.pg2.resolve_arp()
8164 super(TestDSlite, cls).tearDownClass()
8167 def verify_syslog_apmadd(self, data, isaddr, isport, xsaddr, xsport,
8169 message = data.decode('utf-8')
8171 message = SyslogMessage.parse(message)
8172 except ParseError as e:
8173 self.logger.error(e)
8175 self.assertEqual(message.severity, SyslogSeverity.info)
8176 self.assertEqual(message.appname, 'NAT')
8177 self.assertEqual(message.msgid, 'APMADD')
8178 sd_params = message.sd.get('napmap')
8179 self.assertTrue(sd_params is not None)
8180 self.assertEqual(sd_params.get('IATYP'), 'IPv4')
8181 self.assertEqual(sd_params.get('ISADDR'), isaddr)
8182 self.assertEqual(sd_params.get('ISPORT'), "%d" % isport)
8183 self.assertEqual(sd_params.get('XATYP'), 'IPv4')
8184 self.assertEqual(sd_params.get('XSADDR'), xsaddr)
8185 self.assertEqual(sd_params.get('XSPORT'), "%d" % xsport)
8186 self.assertEqual(sd_params.get('PROTO'), "%d" % proto)
8187 self.assertTrue(sd_params.get('SSUBIX') is not None)
8188 self.assertEqual(sd_params.get('SV6ENC'), sv6enc)
8190 def test_dslite(self):
8191 """ Test DS-Lite """
8192 nat_config = self.vapi.nat_show_config()
8193 self.assertEqual(0, nat_config.dslite_ce)
8195 self.vapi.dslite_add_del_pool_addr_range(self.nat_addr_n,
8197 aftr_ip4 = '192.0.0.1'
8198 aftr_ip4_n = socket.inet_pton(socket.AF_INET, aftr_ip4)
8199 aftr_ip6 = '2001:db8:85a3::8a2e:370:1'
8200 aftr_ip6_n = socket.inet_pton(socket.AF_INET6, aftr_ip6)
8201 self.vapi.dslite_set_aftr_addr(aftr_ip6_n, aftr_ip4_n)
8202 self.vapi.syslog_set_sender(self.pg2.remote_ip4n, self.pg2.local_ip4n)
8205 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
8206 IPv6(dst=aftr_ip6, src=self.pg1.remote_hosts[0].ip6) /
8207 IP(dst=self.pg0.remote_ip4, src='192.168.1.1') /
8208 UDP(sport=20000, dport=10000))
8209 self.pg1.add_stream(p)
8210 self.pg_enable_capture(self.pg_interfaces)
8212 capture = self.pg0.get_capture(1)
8213 capture = capture[0]
8214 self.assertFalse(capture.haslayer(IPv6))
8215 self.assertEqual(capture[IP].src, self.nat_addr)
8216 self.assertEqual(capture[IP].dst, self.pg0.remote_ip4)
8217 self.assertNotEqual(capture[UDP].sport, 20000)
8218 self.assertEqual(capture[UDP].dport, 10000)
8219 self.assert_packet_checksums_valid(capture)
8220 out_port = capture[UDP].sport
8221 capture = self.pg2.get_capture(1)
8222 self.verify_syslog_apmadd(capture[0][Raw].load, '192.168.1.1',
8223 20000, self.nat_addr, out_port,
8224 self.pg1.remote_hosts[0].ip6, IP_PROTOS.udp)
8226 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
8227 IP(dst=self.nat_addr, src=self.pg0.remote_ip4) /
8228 UDP(sport=10000, dport=out_port))
8229 self.pg0.add_stream(p)
8230 self.pg_enable_capture(self.pg_interfaces)
8232 capture = self.pg1.get_capture(1)
8233 capture = capture[0]
8234 self.assertEqual(capture[IPv6].src, aftr_ip6)
8235 self.assertEqual(capture[IPv6].dst, self.pg1.remote_hosts[0].ip6)
8236 self.assertEqual(capture[IP].src, self.pg0.remote_ip4)
8237 self.assertEqual(capture[IP].dst, '192.168.1.1')
8238 self.assertEqual(capture[UDP].sport, 10000)
8239 self.assertEqual(capture[UDP].dport, 20000)
8240 self.assert_packet_checksums_valid(capture)
8243 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
8244 IPv6(dst=aftr_ip6, src=self.pg1.remote_hosts[1].ip6) /
8245 IP(dst=self.pg0.remote_ip4, src='192.168.1.1') /
8246 TCP(sport=20001, dport=10001))
8247 self.pg1.add_stream(p)
8248 self.pg_enable_capture(self.pg_interfaces)
8250 capture = self.pg0.get_capture(1)
8251 capture = capture[0]
8252 self.assertFalse(capture.haslayer(IPv6))
8253 self.assertEqual(capture[IP].src, self.nat_addr)
8254 self.assertEqual(capture[IP].dst, self.pg0.remote_ip4)
8255 self.assertNotEqual(capture[TCP].sport, 20001)
8256 self.assertEqual(capture[TCP].dport, 10001)
8257 self.assert_packet_checksums_valid(capture)
8258 out_port = capture[TCP].sport
8260 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
8261 IP(dst=self.nat_addr, src=self.pg0.remote_ip4) /
8262 TCP(sport=10001, dport=out_port))
8263 self.pg0.add_stream(p)
8264 self.pg_enable_capture(self.pg_interfaces)
8266 capture = self.pg1.get_capture(1)
8267 capture = capture[0]
8268 self.assertEqual(capture[IPv6].src, aftr_ip6)
8269 self.assertEqual(capture[IPv6].dst, self.pg1.remote_hosts[1].ip6)
8270 self.assertEqual(capture[IP].src, self.pg0.remote_ip4)
8271 self.assertEqual(capture[IP].dst, '192.168.1.1')
8272 self.assertEqual(capture[TCP].sport, 10001)
8273 self.assertEqual(capture[TCP].dport, 20001)
8274 self.assert_packet_checksums_valid(capture)
8277 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
8278 IPv6(dst=aftr_ip6, src=self.pg1.remote_hosts[1].ip6) /
8279 IP(dst=self.pg0.remote_ip4, src='192.168.1.1') /
8280 ICMP(id=4000, type='echo-request'))
8281 self.pg1.add_stream(p)
8282 self.pg_enable_capture(self.pg_interfaces)
8284 capture = self.pg0.get_capture(1)
8285 capture = capture[0]
8286 self.assertFalse(capture.haslayer(IPv6))
8287 self.assertEqual(capture[IP].src, self.nat_addr)
8288 self.assertEqual(capture[IP].dst, self.pg0.remote_ip4)
8289 self.assertNotEqual(capture[ICMP].id, 4000)
8290 self.assert_packet_checksums_valid(capture)
8291 out_id = capture[ICMP].id
8293 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
8294 IP(dst=self.nat_addr, src=self.pg0.remote_ip4) /
8295 ICMP(id=out_id, type='echo-reply'))
8296 self.pg0.add_stream(p)
8297 self.pg_enable_capture(self.pg_interfaces)
8299 capture = self.pg1.get_capture(1)
8300 capture = capture[0]
8301 self.assertEqual(capture[IPv6].src, aftr_ip6)
8302 self.assertEqual(capture[IPv6].dst, self.pg1.remote_hosts[1].ip6)
8303 self.assertEqual(capture[IP].src, self.pg0.remote_ip4)
8304 self.assertEqual(capture[IP].dst, '192.168.1.1')
8305 self.assertEqual(capture[ICMP].id, 4000)
8306 self.assert_packet_checksums_valid(capture)
8308 # ping DS-Lite AFTR tunnel endpoint address
8309 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
8310 IPv6(src=self.pg1.remote_hosts[1].ip6, dst=aftr_ip6) /
8311 ICMPv6EchoRequest())
8312 self.pg1.add_stream(p)
8313 self.pg_enable_capture(self.pg_interfaces)
8315 capture = self.pg1.get_capture(1)
8316 capture = capture[0]
8317 self.assertEqual(capture[IPv6].src, aftr_ip6)
8318 self.assertEqual(capture[IPv6].dst, self.pg1.remote_hosts[1].ip6)
8319 self.assertTrue(capture.haslayer(ICMPv6EchoReply))
8321 b4s = self.statistics.get_counter('/dslite/total-b4s')
8322 self.assertEqual(b4s[0][0], 2)
8323 sessions = self.statistics.get_counter('/dslite/total-sessions')
8324 self.assertEqual(sessions[0][0], 3)
8327 super(TestDSlite, self).tearDown()
8328 if not self.vpp_dead:
8329 self.logger.info(self.vapi.cli("show dslite pool"))
8331 self.vapi.cli("show dslite aftr-tunnel-endpoint-address"))
8332 self.logger.info(self.vapi.cli("show dslite sessions"))
8335 class TestDSliteCE(MethodHolder):
8336 """ DS-Lite CE Test Cases """
8339 def setUpConstants(cls):
8340 super(TestDSliteCE, cls).setUpConstants()
8341 cls.vpp_cmdline.extend(["nat", "{", "dslite ce", "}"])
8344 def setUpClass(cls):
8345 super(TestDSliteCE, cls).setUpClass()
8348 cls.create_pg_interfaces(range(2))
8350 cls.pg0.config_ip4()
8351 cls.pg0.resolve_arp()
8353 cls.pg1.config_ip6()
8354 cls.pg1.generate_remote_hosts(1)
8355 cls.pg1.configure_ipv6_neighbors()
8358 super(TestDSliteCE, cls).tearDownClass()
8361 def test_dslite_ce(self):
8362 """ Test DS-Lite CE """
8364 nat_config = self.vapi.nat_show_config()
8365 self.assertEqual(1, nat_config.dslite_ce)
8367 b4_ip4 = '192.0.0.2'
8368 b4_ip4_n = socket.inet_pton(socket.AF_INET, b4_ip4)
8369 b4_ip6 = '2001:db8:62aa::375e:f4c1:1'
8370 b4_ip6_n = socket.inet_pton(socket.AF_INET6, b4_ip6)
8371 self.vapi.dslite_set_b4_addr(b4_ip6_n, b4_ip4_n)
8373 aftr_ip4 = '192.0.0.1'
8374 aftr_ip4_n = socket.inet_pton(socket.AF_INET, aftr_ip4)
8375 aftr_ip6 = '2001:db8:85a3::8a2e:370:1'
8376 aftr_ip6_n = socket.inet_pton(socket.AF_INET6, aftr_ip6)
8377 self.vapi.dslite_set_aftr_addr(aftr_ip6_n, aftr_ip4_n)
8379 self.vapi.ip_add_del_route(dst_address=aftr_ip6_n,
8380 dst_address_length=128,
8381 next_hop_address=self.pg1.remote_ip6n,
8382 next_hop_sw_if_index=self.pg1.sw_if_index,
8386 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
8387 IP(dst=self.pg1.remote_ip4, src=self.pg0.remote_ip4) /
8388 UDP(sport=10000, dport=20000))
8389 self.pg0.add_stream(p)
8390 self.pg_enable_capture(self.pg_interfaces)
8392 capture = self.pg1.get_capture(1)
8393 capture = capture[0]
8394 self.assertEqual(capture[IPv6].src, b4_ip6)
8395 self.assertEqual(capture[IPv6].dst, aftr_ip6)
8396 self.assertEqual(capture[IP].src, self.pg0.remote_ip4)
8397 self.assertEqual(capture[IP].dst, self.pg1.remote_ip4)
8398 self.assertEqual(capture[UDP].sport, 10000)
8399 self.assertEqual(capture[UDP].dport, 20000)
8400 self.assert_packet_checksums_valid(capture)
8403 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
8404 IPv6(dst=b4_ip6, src=aftr_ip6) /
8405 IP(dst=self.pg0.remote_ip4, src=self.pg1.remote_ip4) /
8406 UDP(sport=20000, dport=10000))
8407 self.pg1.add_stream(p)
8408 self.pg_enable_capture(self.pg_interfaces)
8410 capture = self.pg0.get_capture(1)
8411 capture = capture[0]
8412 self.assertFalse(capture.haslayer(IPv6))
8413 self.assertEqual(capture[IP].src, self.pg1.remote_ip4)
8414 self.assertEqual(capture[IP].dst, self.pg0.remote_ip4)
8415 self.assertEqual(capture[UDP].sport, 20000)
8416 self.assertEqual(capture[UDP].dport, 10000)
8417 self.assert_packet_checksums_valid(capture)
8419 # ping DS-Lite B4 tunnel endpoint address
8420 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
8421 IPv6(src=self.pg1.remote_hosts[0].ip6, dst=b4_ip6) /
8422 ICMPv6EchoRequest())
8423 self.pg1.add_stream(p)
8424 self.pg_enable_capture(self.pg_interfaces)
8426 capture = self.pg1.get_capture(1)
8427 capture = capture[0]
8428 self.assertEqual(capture[IPv6].src, b4_ip6)
8429 self.assertEqual(capture[IPv6].dst, self.pg1.remote_hosts[0].ip6)
8430 self.assertTrue(capture.haslayer(ICMPv6EchoReply))
8433 super(TestDSliteCE, self).tearDown()
8434 if not self.vpp_dead:
8436 self.vapi.cli("show dslite aftr-tunnel-endpoint-address"))
8438 self.vapi.cli("show dslite b4-tunnel-endpoint-address"))
8441 class TestNAT66(MethodHolder):
8442 """ NAT66 Test Cases """
8445 def setUpClass(cls):
8446 super(TestNAT66, cls).setUpClass()
8449 cls.nat_addr = 'fd01:ff::2'
8450 cls.nat_addr_n = socket.inet_pton(socket.AF_INET6, cls.nat_addr)
8452 cls.create_pg_interfaces(range(2))
8453 cls.interfaces = list(cls.pg_interfaces)
8455 for i in cls.interfaces:
8458 i.configure_ipv6_neighbors()
8461 super(TestNAT66, cls).tearDownClass()
8464 def test_static(self):
8465 """ 1:1 NAT66 test """
8466 self.vapi.nat66_add_del_interface(self.pg0.sw_if_index)
8467 self.vapi.nat66_add_del_interface(self.pg1.sw_if_index, is_inside=0)
8468 self.vapi.nat66_add_del_static_mapping(self.pg0.remote_ip6n,
8473 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
8474 IPv6(src=self.pg0.remote_ip6, dst=self.pg1.remote_ip6) /
8477 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
8478 IPv6(src=self.pg0.remote_ip6, dst=self.pg1.remote_ip6) /
8481 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
8482 IPv6(src=self.pg0.remote_ip6, dst=self.pg1.remote_ip6) /
8483 ICMPv6EchoRequest())
8485 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
8486 IPv6(src=self.pg0.remote_ip6, dst=self.pg1.remote_ip6) /
8487 GRE() / IP() / TCP())
8489 self.pg0.add_stream(pkts)
8490 self.pg_enable_capture(self.pg_interfaces)
8492 capture = self.pg1.get_capture(len(pkts))
8493 for packet in capture:
8495 self.assertEqual(packet[IPv6].src, self.nat_addr)
8496 self.assertEqual(packet[IPv6].dst, self.pg1.remote_ip6)
8497 self.assert_packet_checksums_valid(packet)
8499 self.logger.error(ppp("Unexpected or invalid packet:", packet))
8504 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
8505 IPv6(src=self.pg1.remote_ip6, dst=self.nat_addr) /
8508 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
8509 IPv6(src=self.pg1.remote_ip6, dst=self.nat_addr) /
8512 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
8513 IPv6(src=self.pg1.remote_ip6, dst=self.nat_addr) /
8516 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
8517 IPv6(src=self.pg1.remote_ip6, dst=self.nat_addr) /
8518 GRE() / IP() / TCP())
8520 self.pg1.add_stream(pkts)
8521 self.pg_enable_capture(self.pg_interfaces)
8523 capture = self.pg0.get_capture(len(pkts))
8524 for packet in capture:
8526 self.assertEqual(packet[IPv6].src, self.pg1.remote_ip6)
8527 self.assertEqual(packet[IPv6].dst, self.pg0.remote_ip6)
8528 self.assert_packet_checksums_valid(packet)
8530 self.logger.error(ppp("Unexpected or invalid packet:", packet))
8533 sm = self.vapi.nat66_static_mapping_dump()
8534 self.assertEqual(len(sm), 1)
8535 self.assertEqual(sm[0].total_pkts, 8)
8537 def test_check_no_translate(self):
8538 """ NAT66 translate only when egress interface is outside interface """
8539 self.vapi.nat66_add_del_interface(self.pg0.sw_if_index)
8540 self.vapi.nat66_add_del_interface(self.pg1.sw_if_index)
8541 self.vapi.nat66_add_del_static_mapping(self.pg0.remote_ip6n,
8545 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
8546 IPv6(src=self.pg0.remote_ip6, dst=self.pg1.remote_ip6) /
8548 self.pg0.add_stream([p])
8549 self.pg_enable_capture(self.pg_interfaces)
8551 capture = self.pg1.get_capture(1)
8554 self.assertEqual(packet[IPv6].src, self.pg0.remote_ip6)
8555 self.assertEqual(packet[IPv6].dst, self.pg1.remote_ip6)
8557 self.logger.error(ppp("Unexpected or invalid packet:", packet))
8560 def clear_nat66(self):
8562 Clear NAT66 configuration.
8564 interfaces = self.vapi.nat66_interface_dump()
8565 for intf in interfaces:
8566 self.vapi.nat66_add_del_interface(intf.sw_if_index,
8570 static_mappings = self.vapi.nat66_static_mapping_dump()
8571 for sm in static_mappings:
8572 self.vapi.nat66_add_del_static_mapping(sm.local_ip_address,
8573 sm.external_ip_address,
8578 super(TestNAT66, self).tearDown()
8579 if not self.vpp_dead:
8580 self.logger.info(self.vapi.cli("show nat66 interfaces"))
8581 self.logger.info(self.vapi.cli("show nat66 static mappings"))
8585 if __name__ == '__main__':
8586 unittest.main(testRunner=VppTestRunner)