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)
1019 def verify_ipfix_max_entries_per_user(self, data, limit, src_addr):
1021 Verify IPFIX maximum entries per user exceeded event
1023 :param data: Decoded IPFIX data records
1024 :param limit: Number of maximum entries per user
1025 :param src_addr: IPv4 source address
1027 self.assertEqual(1, len(data))
1030 self.assertEqual(ord(record[230]), 13)
1031 # natQuotaExceededEvent
1032 self.assertEqual(struct.pack("I", 3), record[466])
1034 self.assertEqual(struct.pack("I", limit), record[473])
1036 self.assertEqual(src_addr, record[8])
1038 def verify_syslog_apmap(self, data, is_add=True):
1039 message = data.decode('utf-8')
1041 message = SyslogMessage.parse(message)
1042 self.assertEqual(message.severity, SyslogSeverity.info)
1043 self.assertEqual(message.appname, 'NAT')
1044 self.assertEqual(message.msgid, 'APMADD' if is_add else 'APMDEL')
1045 sd_params = message.sd.get('napmap')
1046 self.assertTrue(sd_params is not None)
1047 self.assertEqual(sd_params.get('IATYP'), 'IPv4')
1048 self.assertEqual(sd_params.get('ISADDR'), self.pg0.remote_ip4)
1049 self.assertEqual(sd_params.get('ISPORT'), "%d" % self.tcp_port_in)
1050 self.assertEqual(sd_params.get('XATYP'), 'IPv4')
1051 self.assertEqual(sd_params.get('XSADDR'), self.nat_addr)
1052 self.assertEqual(sd_params.get('XSPORT'), "%d" % self.tcp_port_out)
1053 self.assertEqual(sd_params.get('PROTO'), "%d" % IP_PROTOS.tcp)
1054 self.assertTrue(sd_params.get('SSUBIX') is not None)
1055 self.assertEqual(sd_params.get('SVLAN'), '0')
1056 except ParseError as e:
1057 self.logger.error(e)
1059 def verify_syslog_sess(self, data, is_add=True, is_ip6=False):
1060 message = data.decode('utf-8')
1062 message = SyslogMessage.parse(message)
1063 self.assertEqual(message.severity, SyslogSeverity.info)
1064 self.assertEqual(message.appname, 'NAT')
1065 self.assertEqual(message.msgid, 'SADD' if is_add else 'SDEL')
1066 sd_params = message.sd.get('nsess')
1067 self.assertTrue(sd_params is not None)
1069 self.assertEqual(sd_params.get('IATYP'), 'IPv6')
1070 self.assertEqual(sd_params.get('ISADDR'), self.pg0.remote_ip6)
1072 self.assertEqual(sd_params.get('IATYP'), 'IPv4')
1073 self.assertEqual(sd_params.get('ISADDR'), self.pg0.remote_ip4)
1074 self.assertTrue(sd_params.get('SSUBIX') is not None)
1075 self.assertEqual(sd_params.get('ISPORT'), "%d" % self.tcp_port_in)
1076 self.assertEqual(sd_params.get('XATYP'), 'IPv4')
1077 self.assertEqual(sd_params.get('XSADDR'), self.nat_addr)
1078 self.assertEqual(sd_params.get('XSPORT'), "%d" % self.tcp_port_out)
1079 self.assertEqual(sd_params.get('PROTO'), "%d" % IP_PROTOS.tcp)
1080 self.assertEqual(sd_params.get('SVLAN'), '0')
1081 self.assertEqual(sd_params.get('XDADDR'), self.pg1.remote_ip4)
1082 self.assertEqual(sd_params.get('XDPORT'),
1083 "%d" % self.tcp_external_port)
1084 except ParseError as e:
1085 self.logger.error(e)
1087 def verify_mss_value(self, pkt, mss):
1089 Verify TCP MSS value
1094 if not pkt.haslayer(IP) or not pkt.haslayer(TCP):
1095 raise TypeError("Not a TCP/IP packet")
1097 for option in pkt[TCP].options:
1098 if option[0] == 'MSS':
1099 self.assertEqual(option[1], mss)
1100 self.assert_tcp_checksum_valid(pkt)
1103 def proto2layer(proto):
1104 if proto == IP_PROTOS.tcp:
1106 elif proto == IP_PROTOS.udp:
1108 elif proto == IP_PROTOS.icmp:
1111 raise Exception("Unsupported protocol")
1113 def frag_in_order(self, proto=IP_PROTOS.tcp, dont_translate=False):
1114 layer = self.proto2layer(proto)
1116 if proto == IP_PROTOS.tcp:
1117 data = "A" * 4 + "B" * 16 + "C" * 3
1119 data = "A" * 16 + "B" * 16 + "C" * 3
1120 self.port_in = random.randint(1025, 65535)
1122 reass = self.vapi.nat_reass_dump()
1123 reass_n_start = len(reass)
1126 pkts = self.create_stream_frag(self.pg0,
1127 self.pg1.remote_ip4,
1132 self.pg0.add_stream(pkts)
1133 self.pg_enable_capture(self.pg_interfaces)
1135 frags = self.pg1.get_capture(len(pkts))
1136 if not dont_translate:
1137 p = self.reass_frags_and_verify(frags,
1139 self.pg1.remote_ip4)
1141 p = self.reass_frags_and_verify(frags,
1142 self.pg0.remote_ip4,
1143 self.pg1.remote_ip4)
1144 if proto != IP_PROTOS.icmp:
1145 if not dont_translate:
1146 self.assertEqual(p[layer].dport, 20)
1147 self.assertNotEqual(p[layer].sport, self.port_in)
1149 self.assertEqual(p[layer].sport, self.port_in)
1151 if not dont_translate:
1152 self.assertNotEqual(p[layer].id, self.port_in)
1154 self.assertEqual(p[layer].id, self.port_in)
1155 self.assertEqual(data, p[Raw].load)
1158 if not dont_translate:
1159 dst_addr = self.nat_addr
1161 dst_addr = self.pg0.remote_ip4
1162 if proto != IP_PROTOS.icmp:
1164 dport = p[layer].sport
1168 pkts = self.create_stream_frag(self.pg1,
1175 self.pg1.add_stream(pkts)
1176 self.pg_enable_capture(self.pg_interfaces)
1178 frags = self.pg0.get_capture(len(pkts))
1179 p = self.reass_frags_and_verify(frags,
1180 self.pg1.remote_ip4,
1181 self.pg0.remote_ip4)
1182 if proto != IP_PROTOS.icmp:
1183 self.assertEqual(p[layer].sport, 20)
1184 self.assertEqual(p[layer].dport, self.port_in)
1186 self.assertEqual(p[layer].id, self.port_in)
1187 self.assertEqual(data, p[Raw].load)
1189 reass = self.vapi.nat_reass_dump()
1190 reass_n_end = len(reass)
1192 self.assertEqual(reass_n_end - reass_n_start, 2)
1194 def frag_in_order_in_plus_out(self, proto=IP_PROTOS.tcp):
1195 layer = self.proto2layer(proto)
1197 if proto == IP_PROTOS.tcp:
1198 data = "A" * 4 + "B" * 16 + "C" * 3
1200 data = "A" * 16 + "B" * 16 + "C" * 3
1201 self.port_in = random.randint(1025, 65535)
1204 reass = self.vapi.nat_reass_dump()
1205 reass_n_start = len(reass)
1208 pkts = self.create_stream_frag(self.pg0,
1209 self.server_out_addr,
1211 self.server_out_port,
1214 self.pg0.add_stream(pkts)
1215 self.pg_enable_capture(self.pg_interfaces)
1217 frags = self.pg1.get_capture(len(pkts))
1218 p = self.reass_frags_and_verify(frags,
1219 self.pg0.remote_ip4,
1220 self.server_in_addr)
1221 if proto != IP_PROTOS.icmp:
1222 self.assertEqual(p[layer].sport, self.port_in)
1223 self.assertEqual(p[layer].dport, self.server_in_port)
1225 self.assertEqual(p[layer].id, self.port_in)
1226 self.assertEqual(data, p[Raw].load)
1229 if proto != IP_PROTOS.icmp:
1230 pkts = self.create_stream_frag(self.pg1,
1231 self.pg0.remote_ip4,
1232 self.server_in_port,
1237 pkts = self.create_stream_frag(self.pg1,
1238 self.pg0.remote_ip4,
1244 self.pg1.add_stream(pkts)
1245 self.pg_enable_capture(self.pg_interfaces)
1247 frags = self.pg0.get_capture(len(pkts))
1248 p = self.reass_frags_and_verify(frags,
1249 self.server_out_addr,
1250 self.pg0.remote_ip4)
1251 if proto != IP_PROTOS.icmp:
1252 self.assertEqual(p[layer].sport, self.server_out_port)
1253 self.assertEqual(p[layer].dport, self.port_in)
1255 self.assertEqual(p[layer].id, self.port_in)
1256 self.assertEqual(data, p[Raw].load)
1258 reass = self.vapi.nat_reass_dump()
1259 reass_n_end = len(reass)
1261 self.assertEqual(reass_n_end - reass_n_start, 2)
1263 def reass_hairpinning(self, proto=IP_PROTOS.tcp):
1264 layer = self.proto2layer(proto)
1266 if proto == IP_PROTOS.tcp:
1267 data = "A" * 4 + "B" * 16 + "C" * 3
1269 data = "A" * 16 + "B" * 16 + "C" * 3
1271 # send packet from host to server
1272 pkts = self.create_stream_frag(self.pg0,
1275 self.server_out_port,
1278 self.pg0.add_stream(pkts)
1279 self.pg_enable_capture(self.pg_interfaces)
1281 frags = self.pg0.get_capture(len(pkts))
1282 p = self.reass_frags_and_verify(frags,
1285 if proto != IP_PROTOS.icmp:
1286 self.assertNotEqual(p[layer].sport, self.host_in_port)
1287 self.assertEqual(p[layer].dport, self.server_in_port)
1289 self.assertNotEqual(p[layer].id, self.host_in_port)
1290 self.assertEqual(data, p[Raw].load)
1292 def frag_out_of_order(self, proto=IP_PROTOS.tcp, dont_translate=False):
1293 layer = self.proto2layer(proto)
1295 if proto == IP_PROTOS.tcp:
1296 data = "A" * 4 + "B" * 16 + "C" * 3
1298 data = "A" * 16 + "B" * 16 + "C" * 3
1299 self.port_in = random.randint(1025, 65535)
1303 pkts = self.create_stream_frag(self.pg0,
1304 self.pg1.remote_ip4,
1310 self.pg0.add_stream(pkts)
1311 self.pg_enable_capture(self.pg_interfaces)
1313 frags = self.pg1.get_capture(len(pkts))
1314 if not dont_translate:
1315 p = self.reass_frags_and_verify(frags,
1317 self.pg1.remote_ip4)
1319 p = self.reass_frags_and_verify(frags,
1320 self.pg0.remote_ip4,
1321 self.pg1.remote_ip4)
1322 if proto != IP_PROTOS.icmp:
1323 if not dont_translate:
1324 self.assertEqual(p[layer].dport, 20)
1325 self.assertNotEqual(p[layer].sport, self.port_in)
1327 self.assertEqual(p[layer].sport, self.port_in)
1329 if not dont_translate:
1330 self.assertNotEqual(p[layer].id, self.port_in)
1332 self.assertEqual(p[layer].id, self.port_in)
1333 self.assertEqual(data, p[Raw].load)
1336 if not dont_translate:
1337 dst_addr = self.nat_addr
1339 dst_addr = self.pg0.remote_ip4
1340 if proto != IP_PROTOS.icmp:
1342 dport = p[layer].sport
1346 pkts = self.create_stream_frag(self.pg1,
1354 self.pg1.add_stream(pkts)
1355 self.pg_enable_capture(self.pg_interfaces)
1357 frags = self.pg0.get_capture(len(pkts))
1358 p = self.reass_frags_and_verify(frags,
1359 self.pg1.remote_ip4,
1360 self.pg0.remote_ip4)
1361 if proto != IP_PROTOS.icmp:
1362 self.assertEqual(p[layer].sport, 20)
1363 self.assertEqual(p[layer].dport, self.port_in)
1365 self.assertEqual(p[layer].id, self.port_in)
1366 self.assertEqual(data, p[Raw].load)
1368 def frag_out_of_order_in_plus_out(self, proto=IP_PROTOS.tcp):
1369 layer = self.proto2layer(proto)
1371 if proto == IP_PROTOS.tcp:
1372 data = "A" * 4 + "B" * 16 + "C" * 3
1374 data = "A" * 16 + "B" * 16 + "C" * 3
1375 self.port_in = random.randint(1025, 65535)
1379 pkts = self.create_stream_frag(self.pg0,
1380 self.server_out_addr,
1382 self.server_out_port,
1386 self.pg0.add_stream(pkts)
1387 self.pg_enable_capture(self.pg_interfaces)
1389 frags = self.pg1.get_capture(len(pkts))
1390 p = self.reass_frags_and_verify(frags,
1391 self.pg0.remote_ip4,
1392 self.server_in_addr)
1393 if proto != IP_PROTOS.icmp:
1394 self.assertEqual(p[layer].dport, self.server_in_port)
1395 self.assertEqual(p[layer].sport, self.port_in)
1396 self.assertEqual(p[layer].dport, self.server_in_port)
1398 self.assertEqual(p[layer].id, self.port_in)
1399 self.assertEqual(data, p[Raw].load)
1402 if proto != IP_PROTOS.icmp:
1403 pkts = self.create_stream_frag(self.pg1,
1404 self.pg0.remote_ip4,
1405 self.server_in_port,
1410 pkts = self.create_stream_frag(self.pg1,
1411 self.pg0.remote_ip4,
1418 self.pg1.add_stream(pkts)
1419 self.pg_enable_capture(self.pg_interfaces)
1421 frags = self.pg0.get_capture(len(pkts))
1422 p = self.reass_frags_and_verify(frags,
1423 self.server_out_addr,
1424 self.pg0.remote_ip4)
1425 if proto != IP_PROTOS.icmp:
1426 self.assertEqual(p[layer].sport, self.server_out_port)
1427 self.assertEqual(p[layer].dport, self.port_in)
1429 self.assertEqual(p[layer].id, self.port_in)
1430 self.assertEqual(data, p[Raw].load)
1433 class TestNAT44(MethodHolder):
1434 """ NAT44 Test Cases """
1437 def setUpClass(cls):
1438 super(TestNAT44, cls).setUpClass()
1439 cls.vapi.cli("set log class nat level debug")
1442 cls.tcp_port_in = 6303
1443 cls.tcp_port_out = 6303
1444 cls.udp_port_in = 6304
1445 cls.udp_port_out = 6304
1446 cls.icmp_id_in = 6305
1447 cls.icmp_id_out = 6305
1448 cls.nat_addr = '10.0.0.3'
1449 cls.nat_addr_n = socket.inet_pton(socket.AF_INET, cls.nat_addr)
1450 cls.ipfix_src_port = 4739
1451 cls.ipfix_domain_id = 1
1452 cls.tcp_external_port = 80
1454 cls.create_pg_interfaces(range(10))
1455 cls.interfaces = list(cls.pg_interfaces[0:4])
1457 for i in cls.interfaces:
1462 cls.pg0.generate_remote_hosts(3)
1463 cls.pg0.configure_ipv4_neighbors()
1465 cls.pg1.generate_remote_hosts(1)
1466 cls.pg1.configure_ipv4_neighbors()
1468 cls.overlapping_interfaces = list(list(cls.pg_interfaces[4:7]))
1469 cls.vapi.ip_table_add_del(10, is_add=1)
1470 cls.vapi.ip_table_add_del(20, is_add=1)
1472 cls.pg4._local_ip4 = "172.16.255.1"
1473 cls.pg4._local_ip4n = socket.inet_pton(socket.AF_INET, i.local_ip4)
1474 cls.pg4._remote_hosts[0]._ip4 = "172.16.255.2"
1475 cls.pg4.set_table_ip4(10)
1476 cls.pg5._local_ip4 = "172.17.255.3"
1477 cls.pg5._local_ip4n = socket.inet_pton(socket.AF_INET, i.local_ip4)
1478 cls.pg5._remote_hosts[0]._ip4 = "172.17.255.4"
1479 cls.pg5.set_table_ip4(10)
1480 cls.pg6._local_ip4 = "172.16.255.1"
1481 cls.pg6._local_ip4n = socket.inet_pton(socket.AF_INET, i.local_ip4)
1482 cls.pg6._remote_hosts[0]._ip4 = "172.16.255.2"
1483 cls.pg6.set_table_ip4(20)
1484 for i in cls.overlapping_interfaces:
1492 cls.pg9.generate_remote_hosts(2)
1493 cls.pg9.config_ip4()
1494 ip_addr_n = socket.inet_pton(socket.AF_INET, "10.0.0.1")
1495 cls.vapi.sw_interface_add_del_address(cls.pg9.sw_if_index,
1499 cls.pg9.resolve_arp()
1500 cls.pg9._remote_hosts[1]._ip4 = cls.pg9._remote_hosts[0]._ip4
1501 cls.pg4._remote_ip4 = cls.pg9._remote_hosts[0]._ip4 = "10.0.0.2"
1502 cls.pg9.resolve_arp()
1505 super(TestNAT44, cls).tearDownClass()
1508 def test_dynamic(self):
1509 """ NAT44 dynamic translation test """
1510 self.nat44_add_address(self.nat_addr)
1511 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
1512 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
1516 tcpn = self.statistics.get_counter(
1517 '/err/nat44-in2out-slowpath/TCP packets')
1518 udpn = self.statistics.get_counter(
1519 '/err/nat44-in2out-slowpath/UDP packets')
1520 icmpn = self.statistics.get_counter(
1521 '/err/nat44-in2out-slowpath/ICMP packets')
1522 totaln = self.statistics.get_counter(
1523 '/err/nat44-in2out-slowpath/good in2out packets processed')
1525 pkts = self.create_stream_in(self.pg0, self.pg1)
1526 self.pg0.add_stream(pkts)
1527 self.pg_enable_capture(self.pg_interfaces)
1529 capture = self.pg1.get_capture(len(pkts))
1530 self.verify_capture_out(capture)
1532 err = self.statistics.get_counter(
1533 '/err/nat44-in2out-slowpath/TCP packets')
1534 self.assertEqual(err - tcpn, 1)
1535 err = self.statistics.get_counter(
1536 '/err/nat44-in2out-slowpath/UDP packets')
1537 self.assertEqual(err - udpn, 1)
1538 err = self.statistics.get_counter(
1539 '/err/nat44-in2out-slowpath/ICMP packets')
1540 self.assertEqual(err - icmpn, 1)
1541 err = self.statistics.get_counter(
1542 '/err/nat44-in2out-slowpath/good in2out packets processed')
1543 self.assertEqual(err - totaln, 3)
1546 tcpn = self.statistics.get_counter('/err/nat44-out2in/TCP packets')
1547 udpn = self.statistics.get_counter('/err/nat44-out2in/UDP packets')
1548 icmpn = self.statistics.get_counter('/err/nat44-out2in/ICMP packets')
1549 totaln = self.statistics.get_counter(
1550 '/err/nat44-out2in/good out2in packets processed')
1552 pkts = self.create_stream_out(self.pg1)
1553 self.pg1.add_stream(pkts)
1554 self.pg_enable_capture(self.pg_interfaces)
1556 capture = self.pg0.get_capture(len(pkts))
1557 self.verify_capture_in(capture, self.pg0)
1559 err = self.statistics.get_counter('/err/nat44-out2in/TCP packets')
1560 self.assertEqual(err - tcpn, 1)
1561 err = self.statistics.get_counter('/err/nat44-out2in/UDP packets')
1562 self.assertEqual(err - udpn, 1)
1563 err = self.statistics.get_counter('/err/nat44-out2in/ICMP packets')
1564 self.assertEqual(err - icmpn, 1)
1565 err = self.statistics.get_counter(
1566 '/err/nat44-out2in/good out2in packets processed')
1567 self.assertEqual(err - totaln, 3)
1569 def test_dynamic_icmp_errors_in2out_ttl_1(self):
1570 """ NAT44 handling of client packets with TTL=1 """
1572 self.nat44_add_address(self.nat_addr)
1573 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
1574 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
1577 # Client side - generate traffic
1578 pkts = self.create_stream_in(self.pg0, self.pg1, ttl=1)
1579 self.pg0.add_stream(pkts)
1580 self.pg_enable_capture(self.pg_interfaces)
1583 # Client side - verify ICMP type 11 packets
1584 capture = self.pg0.get_capture(len(pkts))
1585 self.verify_capture_in_with_icmp_errors(capture, self.pg0)
1587 def test_dynamic_icmp_errors_out2in_ttl_1(self):
1588 """ NAT44 handling of server packets with TTL=1 """
1590 self.nat44_add_address(self.nat_addr)
1591 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
1592 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
1595 # Client side - create sessions
1596 pkts = self.create_stream_in(self.pg0, self.pg1)
1597 self.pg0.add_stream(pkts)
1598 self.pg_enable_capture(self.pg_interfaces)
1601 # Server side - generate traffic
1602 capture = self.pg1.get_capture(len(pkts))
1603 self.verify_capture_out(capture)
1604 pkts = self.create_stream_out(self.pg1, ttl=1)
1605 self.pg1.add_stream(pkts)
1606 self.pg_enable_capture(self.pg_interfaces)
1609 # Server side - verify ICMP type 11 packets
1610 capture = self.pg1.get_capture(len(pkts))
1611 self.verify_capture_out_with_icmp_errors(capture,
1612 src_ip=self.pg1.local_ip4)
1614 def test_dynamic_icmp_errors_in2out_ttl_2(self):
1615 """ NAT44 handling of error responses to client packets with TTL=2 """
1617 self.nat44_add_address(self.nat_addr)
1618 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
1619 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
1622 # Client side - generate traffic
1623 pkts = self.create_stream_in(self.pg0, self.pg1, ttl=2)
1624 self.pg0.add_stream(pkts)
1625 self.pg_enable_capture(self.pg_interfaces)
1628 # Server side - simulate ICMP type 11 response
1629 capture = self.pg1.get_capture(len(pkts))
1630 pkts = [Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
1631 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
1632 ICMP(type=11) / packet[IP] for packet in capture]
1633 self.pg1.add_stream(pkts)
1634 self.pg_enable_capture(self.pg_interfaces)
1637 # Client side - verify ICMP type 11 packets
1638 capture = self.pg0.get_capture(len(pkts))
1639 self.verify_capture_in_with_icmp_errors(capture, self.pg0)
1641 def test_dynamic_icmp_errors_out2in_ttl_2(self):
1642 """ NAT44 handling of error responses to server packets with TTL=2 """
1644 self.nat44_add_address(self.nat_addr)
1645 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
1646 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
1649 # Client side - create sessions
1650 pkts = self.create_stream_in(self.pg0, self.pg1)
1651 self.pg0.add_stream(pkts)
1652 self.pg_enable_capture(self.pg_interfaces)
1655 # Server side - generate traffic
1656 capture = self.pg1.get_capture(len(pkts))
1657 self.verify_capture_out(capture)
1658 pkts = self.create_stream_out(self.pg1, ttl=2)
1659 self.pg1.add_stream(pkts)
1660 self.pg_enable_capture(self.pg_interfaces)
1663 # Client side - simulate ICMP type 11 response
1664 capture = self.pg0.get_capture(len(pkts))
1665 pkts = [Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
1666 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
1667 ICMP(type=11) / packet[IP] for packet in capture]
1668 self.pg0.add_stream(pkts)
1669 self.pg_enable_capture(self.pg_interfaces)
1672 # Server side - verify ICMP type 11 packets
1673 capture = self.pg1.get_capture(len(pkts))
1674 self.verify_capture_out_with_icmp_errors(capture)
1676 def test_ping_out_interface_from_outside(self):
1677 """ Ping NAT44 out interface from outside network """
1679 self.nat44_add_address(self.nat_addr)
1680 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
1681 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
1684 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
1685 IP(src=self.pg1.remote_ip4, dst=self.pg1.local_ip4) /
1686 ICMP(id=self.icmp_id_out, type='echo-request'))
1688 self.pg1.add_stream(pkts)
1689 self.pg_enable_capture(self.pg_interfaces)
1691 capture = self.pg1.get_capture(len(pkts))
1694 self.assertEqual(packet[IP].src, self.pg1.local_ip4)
1695 self.assertEqual(packet[IP].dst, self.pg1.remote_ip4)
1696 self.assertEqual(packet[ICMP].id, self.icmp_id_in)
1697 self.assertEqual(packet[ICMP].type, 0) # echo reply
1699 self.logger.error(ppp("Unexpected or invalid packet "
1700 "(outside network):", packet))
1703 def test_ping_internal_host_from_outside(self):
1704 """ Ping internal host from outside network """
1706 self.nat44_add_static_mapping(self.pg0.remote_ip4, self.nat_addr)
1707 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
1708 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
1712 pkt = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
1713 IP(src=self.pg1.remote_ip4, dst=self.nat_addr, ttl=64) /
1714 ICMP(id=self.icmp_id_out, type='echo-request'))
1715 self.pg1.add_stream(pkt)
1716 self.pg_enable_capture(self.pg_interfaces)
1718 capture = self.pg0.get_capture(1)
1719 self.verify_capture_in(capture, self.pg0)
1720 self.assert_equal(capture[0][IP].proto, IP_PROTOS.icmp)
1723 pkt = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
1724 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4, ttl=64) /
1725 ICMP(id=self.icmp_id_in, type='echo-reply'))
1726 self.pg0.add_stream(pkt)
1727 self.pg_enable_capture(self.pg_interfaces)
1729 capture = self.pg1.get_capture(1)
1730 self.verify_capture_out(capture, same_port=True)
1731 self.assert_equal(capture[0][IP].proto, IP_PROTOS.icmp)
1733 def test_forwarding(self):
1734 """ NAT44 forwarding test """
1736 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
1737 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
1739 self.vapi.nat44_forwarding_enable_disable(1)
1741 real_ip = self.pg0.remote_ip4n
1742 alias_ip = self.nat_addr_n
1743 self.vapi.nat44_add_del_static_mapping(local_ip=real_ip,
1744 external_ip=alias_ip)
1747 # static mapping match
1749 pkts = self.create_stream_out(self.pg1)
1750 self.pg1.add_stream(pkts)
1751 self.pg_enable_capture(self.pg_interfaces)
1753 capture = self.pg0.get_capture(len(pkts))
1754 self.verify_capture_in(capture, self.pg0)
1756 pkts = self.create_stream_in(self.pg0, self.pg1)
1757 self.pg0.add_stream(pkts)
1758 self.pg_enable_capture(self.pg_interfaces)
1760 capture = self.pg1.get_capture(len(pkts))
1761 self.verify_capture_out(capture, same_port=True)
1763 # no static mapping match
1765 host0 = self.pg0.remote_hosts[0]
1766 self.pg0.remote_hosts[0] = self.pg0.remote_hosts[1]
1768 pkts = self.create_stream_out(self.pg1,
1769 dst_ip=self.pg0.remote_ip4,
1770 use_inside_ports=True)
1771 self.pg1.add_stream(pkts)
1772 self.pg_enable_capture(self.pg_interfaces)
1774 capture = self.pg0.get_capture(len(pkts))
1775 self.verify_capture_in(capture, self.pg0)
1777 pkts = self.create_stream_in(self.pg0, self.pg1)
1778 self.pg0.add_stream(pkts)
1779 self.pg_enable_capture(self.pg_interfaces)
1781 capture = self.pg1.get_capture(len(pkts))
1782 self.verify_capture_out(capture, nat_ip=self.pg0.remote_ip4,
1785 self.pg0.remote_hosts[0] = host0
1788 self.vapi.nat44_forwarding_enable_disable(0)
1789 self.vapi.nat44_add_del_static_mapping(local_ip=real_ip,
1790 external_ip=alias_ip,
1793 def test_static_in(self):
1794 """ 1:1 NAT initialized from inside network """
1796 nat_ip = "10.0.0.10"
1797 self.tcp_port_out = 6303
1798 self.udp_port_out = 6304
1799 self.icmp_id_out = 6305
1801 self.nat44_add_static_mapping(self.pg0.remote_ip4, nat_ip)
1802 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
1803 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
1805 sm = self.vapi.nat44_static_mapping_dump()
1806 self.assertEqual(len(sm), 1)
1807 self.assertEqual((sm[0].tag).split('\0', 1)[0], '')
1808 self.assertEqual(sm[0].protocol, 0)
1809 self.assertEqual(sm[0].local_port, 0)
1810 self.assertEqual(sm[0].external_port, 0)
1813 pkts = self.create_stream_in(self.pg0, self.pg1)
1814 self.pg0.add_stream(pkts)
1815 self.pg_enable_capture(self.pg_interfaces)
1817 capture = self.pg1.get_capture(len(pkts))
1818 self.verify_capture_out(capture, nat_ip, True)
1821 pkts = self.create_stream_out(self.pg1, nat_ip)
1822 self.pg1.add_stream(pkts)
1823 self.pg_enable_capture(self.pg_interfaces)
1825 capture = self.pg0.get_capture(len(pkts))
1826 self.verify_capture_in(capture, self.pg0)
1828 def test_static_out(self):
1829 """ 1:1 NAT initialized from outside network """
1831 nat_ip = "10.0.0.20"
1832 self.tcp_port_out = 6303
1833 self.udp_port_out = 6304
1834 self.icmp_id_out = 6305
1837 self.nat44_add_static_mapping(self.pg0.remote_ip4, nat_ip, tag=tag)
1838 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
1839 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
1841 sm = self.vapi.nat44_static_mapping_dump()
1842 self.assertEqual(len(sm), 1)
1843 self.assertEqual((sm[0].tag).split('\0', 1)[0], tag)
1846 pkts = self.create_stream_out(self.pg1, nat_ip)
1847 self.pg1.add_stream(pkts)
1848 self.pg_enable_capture(self.pg_interfaces)
1850 capture = self.pg0.get_capture(len(pkts))
1851 self.verify_capture_in(capture, self.pg0)
1854 pkts = self.create_stream_in(self.pg0, self.pg1)
1855 self.pg0.add_stream(pkts)
1856 self.pg_enable_capture(self.pg_interfaces)
1858 capture = self.pg1.get_capture(len(pkts))
1859 self.verify_capture_out(capture, nat_ip, True)
1861 def test_static_with_port_in(self):
1862 """ 1:1 NAPT initialized from inside network """
1864 self.tcp_port_out = 3606
1865 self.udp_port_out = 3607
1866 self.icmp_id_out = 3608
1868 self.nat44_add_address(self.nat_addr)
1869 self.nat44_add_static_mapping(self.pg0.remote_ip4, self.nat_addr,
1870 self.tcp_port_in, self.tcp_port_out,
1871 proto=IP_PROTOS.tcp)
1872 self.nat44_add_static_mapping(self.pg0.remote_ip4, self.nat_addr,
1873 self.udp_port_in, self.udp_port_out,
1874 proto=IP_PROTOS.udp)
1875 self.nat44_add_static_mapping(self.pg0.remote_ip4, self.nat_addr,
1876 self.icmp_id_in, self.icmp_id_out,
1877 proto=IP_PROTOS.icmp)
1878 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
1879 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
1883 pkts = self.create_stream_in(self.pg0, self.pg1)
1884 self.pg0.add_stream(pkts)
1885 self.pg_enable_capture(self.pg_interfaces)
1887 capture = self.pg1.get_capture(len(pkts))
1888 self.verify_capture_out(capture)
1891 pkts = self.create_stream_out(self.pg1)
1892 self.pg1.add_stream(pkts)
1893 self.pg_enable_capture(self.pg_interfaces)
1895 capture = self.pg0.get_capture(len(pkts))
1896 self.verify_capture_in(capture, self.pg0)
1898 def test_static_with_port_out(self):
1899 """ 1:1 NAPT initialized from outside network """
1901 self.tcp_port_out = 30606
1902 self.udp_port_out = 30607
1903 self.icmp_id_out = 30608
1905 self.nat44_add_address(self.nat_addr)
1906 self.nat44_add_static_mapping(self.pg0.remote_ip4, self.nat_addr,
1907 self.tcp_port_in, self.tcp_port_out,
1908 proto=IP_PROTOS.tcp)
1909 self.nat44_add_static_mapping(self.pg0.remote_ip4, self.nat_addr,
1910 self.udp_port_in, self.udp_port_out,
1911 proto=IP_PROTOS.udp)
1912 self.nat44_add_static_mapping(self.pg0.remote_ip4, self.nat_addr,
1913 self.icmp_id_in, self.icmp_id_out,
1914 proto=IP_PROTOS.icmp)
1915 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
1916 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
1920 pkts = self.create_stream_out(self.pg1)
1921 self.pg1.add_stream(pkts)
1922 self.pg_enable_capture(self.pg_interfaces)
1924 capture = self.pg0.get_capture(len(pkts))
1925 self.verify_capture_in(capture, self.pg0)
1928 pkts = self.create_stream_in(self.pg0, self.pg1)
1929 self.pg0.add_stream(pkts)
1930 self.pg_enable_capture(self.pg_interfaces)
1932 capture = self.pg1.get_capture(len(pkts))
1933 self.verify_capture_out(capture)
1935 def test_static_vrf_aware(self):
1936 """ 1:1 NAT VRF awareness """
1938 nat_ip1 = "10.0.0.30"
1939 nat_ip2 = "10.0.0.40"
1940 self.tcp_port_out = 6303
1941 self.udp_port_out = 6304
1942 self.icmp_id_out = 6305
1944 self.nat44_add_static_mapping(self.pg4.remote_ip4, nat_ip1,
1946 self.nat44_add_static_mapping(self.pg0.remote_ip4, nat_ip2,
1948 self.vapi.nat44_interface_add_del_feature(self.pg3.sw_if_index,
1950 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
1951 self.vapi.nat44_interface_add_del_feature(self.pg4.sw_if_index)
1953 # inside interface VRF match NAT44 static mapping VRF
1954 pkts = self.create_stream_in(self.pg4, self.pg3)
1955 self.pg4.add_stream(pkts)
1956 self.pg_enable_capture(self.pg_interfaces)
1958 capture = self.pg3.get_capture(len(pkts))
1959 self.verify_capture_out(capture, nat_ip1, True)
1961 # inside interface VRF don't match NAT44 static mapping VRF (packets
1963 pkts = self.create_stream_in(self.pg0, self.pg3)
1964 self.pg0.add_stream(pkts)
1965 self.pg_enable_capture(self.pg_interfaces)
1967 self.pg3.assert_nothing_captured()
1969 def test_dynamic_to_static(self):
1970 """ Switch from dynamic translation to 1:1NAT """
1971 nat_ip = "10.0.0.10"
1972 self.tcp_port_out = 6303
1973 self.udp_port_out = 6304
1974 self.icmp_id_out = 6305
1976 self.nat44_add_address(self.nat_addr)
1977 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
1978 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
1982 pkts = self.create_stream_in(self.pg0, self.pg1)
1983 self.pg0.add_stream(pkts)
1984 self.pg_enable_capture(self.pg_interfaces)
1986 capture = self.pg1.get_capture(len(pkts))
1987 self.verify_capture_out(capture)
1990 self.nat44_add_static_mapping(self.pg0.remote_ip4, nat_ip)
1991 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4n, 0)
1992 self.assertEqual(len(sessions), 0)
1993 pkts = self.create_stream_in(self.pg0, self.pg1)
1994 self.pg0.add_stream(pkts)
1995 self.pg_enable_capture(self.pg_interfaces)
1997 capture = self.pg1.get_capture(len(pkts))
1998 self.verify_capture_out(capture, nat_ip, True)
2000 def test_identity_nat(self):
2001 """ Identity NAT """
2003 self.vapi.nat44_add_del_identity_mapping(ip=self.pg0.remote_ip4n)
2004 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
2005 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
2008 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
2009 IP(src=self.pg1.remote_ip4, dst=self.pg0.remote_ip4) /
2010 TCP(sport=12345, dport=56789))
2011 self.pg1.add_stream(p)
2012 self.pg_enable_capture(self.pg_interfaces)
2014 capture = self.pg0.get_capture(1)
2019 self.assertEqual(ip.dst, self.pg0.remote_ip4)
2020 self.assertEqual(ip.src, self.pg1.remote_ip4)
2021 self.assertEqual(tcp.dport, 56789)
2022 self.assertEqual(tcp.sport, 12345)
2023 self.assert_packet_checksums_valid(p)
2025 self.logger.error(ppp("Unexpected or invalid packet:", p))
2028 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4n, 0)
2029 self.assertEqual(len(sessions), 0)
2030 self.vapi.nat44_add_del_identity_mapping(ip=self.pg0.remote_ip4n,
2032 identity_mappings = self.vapi.nat44_identity_mapping_dump()
2033 self.assertEqual(len(identity_mappings), 2)
2035 def test_multiple_inside_interfaces(self):
2036 """ NAT44 multiple non-overlapping address space inside interfaces """
2038 self.nat44_add_address(self.nat_addr)
2039 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
2040 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index)
2041 self.vapi.nat44_interface_add_del_feature(self.pg3.sw_if_index,
2044 # between two NAT44 inside interfaces (no translation)
2045 pkts = self.create_stream_in(self.pg0, self.pg1)
2046 self.pg0.add_stream(pkts)
2047 self.pg_enable_capture(self.pg_interfaces)
2049 capture = self.pg1.get_capture(len(pkts))
2050 self.verify_capture_no_translation(capture, self.pg0, self.pg1)
2052 # from NAT44 inside to interface without NAT44 feature (no translation)
2053 pkts = self.create_stream_in(self.pg0, self.pg2)
2054 self.pg0.add_stream(pkts)
2055 self.pg_enable_capture(self.pg_interfaces)
2057 capture = self.pg2.get_capture(len(pkts))
2058 self.verify_capture_no_translation(capture, self.pg0, self.pg2)
2060 # in2out 1st interface
2061 pkts = self.create_stream_in(self.pg0, self.pg3)
2062 self.pg0.add_stream(pkts)
2063 self.pg_enable_capture(self.pg_interfaces)
2065 capture = self.pg3.get_capture(len(pkts))
2066 self.verify_capture_out(capture)
2068 # out2in 1st interface
2069 pkts = self.create_stream_out(self.pg3)
2070 self.pg3.add_stream(pkts)
2071 self.pg_enable_capture(self.pg_interfaces)
2073 capture = self.pg0.get_capture(len(pkts))
2074 self.verify_capture_in(capture, self.pg0)
2076 # in2out 2nd interface
2077 pkts = self.create_stream_in(self.pg1, self.pg3)
2078 self.pg1.add_stream(pkts)
2079 self.pg_enable_capture(self.pg_interfaces)
2081 capture = self.pg3.get_capture(len(pkts))
2082 self.verify_capture_out(capture)
2084 # out2in 2nd interface
2085 pkts = self.create_stream_out(self.pg3)
2086 self.pg3.add_stream(pkts)
2087 self.pg_enable_capture(self.pg_interfaces)
2089 capture = self.pg1.get_capture(len(pkts))
2090 self.verify_capture_in(capture, self.pg1)
2092 def test_inside_overlapping_interfaces(self):
2093 """ NAT44 multiple inside interfaces with overlapping address space """
2095 static_nat_ip = "10.0.0.10"
2096 self.nat44_add_address(self.nat_addr)
2097 self.vapi.nat44_interface_add_del_feature(self.pg3.sw_if_index,
2099 self.vapi.nat44_interface_add_del_feature(self.pg4.sw_if_index)
2100 self.vapi.nat44_interface_add_del_feature(self.pg5.sw_if_index)
2101 self.vapi.nat44_interface_add_del_feature(self.pg6.sw_if_index)
2102 self.nat44_add_static_mapping(self.pg6.remote_ip4, static_nat_ip,
2105 # between NAT44 inside interfaces with same VRF (no translation)
2106 pkts = self.create_stream_in(self.pg4, self.pg5)
2107 self.pg4.add_stream(pkts)
2108 self.pg_enable_capture(self.pg_interfaces)
2110 capture = self.pg5.get_capture(len(pkts))
2111 self.verify_capture_no_translation(capture, self.pg4, self.pg5)
2113 # between NAT44 inside interfaces with different VRF (hairpinning)
2114 p = (Ether(src=self.pg4.remote_mac, dst=self.pg4.local_mac) /
2115 IP(src=self.pg4.remote_ip4, dst=static_nat_ip) /
2116 TCP(sport=1234, dport=5678))
2117 self.pg4.add_stream(p)
2118 self.pg_enable_capture(self.pg_interfaces)
2120 capture = self.pg6.get_capture(1)
2125 self.assertEqual(ip.src, self.nat_addr)
2126 self.assertEqual(ip.dst, self.pg6.remote_ip4)
2127 self.assertNotEqual(tcp.sport, 1234)
2128 self.assertEqual(tcp.dport, 5678)
2130 self.logger.error(ppp("Unexpected or invalid packet:", p))
2133 # in2out 1st interface
2134 pkts = self.create_stream_in(self.pg4, self.pg3)
2135 self.pg4.add_stream(pkts)
2136 self.pg_enable_capture(self.pg_interfaces)
2138 capture = self.pg3.get_capture(len(pkts))
2139 self.verify_capture_out(capture)
2141 # out2in 1st interface
2142 pkts = self.create_stream_out(self.pg3)
2143 self.pg3.add_stream(pkts)
2144 self.pg_enable_capture(self.pg_interfaces)
2146 capture = self.pg4.get_capture(len(pkts))
2147 self.verify_capture_in(capture, self.pg4)
2149 # in2out 2nd interface
2150 pkts = self.create_stream_in(self.pg5, self.pg3)
2151 self.pg5.add_stream(pkts)
2152 self.pg_enable_capture(self.pg_interfaces)
2154 capture = self.pg3.get_capture(len(pkts))
2155 self.verify_capture_out(capture)
2157 # out2in 2nd interface
2158 pkts = self.create_stream_out(self.pg3)
2159 self.pg3.add_stream(pkts)
2160 self.pg_enable_capture(self.pg_interfaces)
2162 capture = self.pg5.get_capture(len(pkts))
2163 self.verify_capture_in(capture, self.pg5)
2166 addresses = self.vapi.nat44_address_dump()
2167 self.assertEqual(len(addresses), 1)
2168 sessions = self.vapi.nat44_user_session_dump(self.pg5.remote_ip4n, 10)
2169 self.assertEqual(len(sessions), 3)
2170 for session in sessions:
2171 self.assertFalse(session.is_static)
2172 self.assertEqual(session.inside_ip_address[0:4],
2173 self.pg5.remote_ip4n)
2174 self.assertEqual(session.outside_ip_address,
2175 addresses[0].ip_address)
2176 self.assertEqual(sessions[0].protocol, IP_PROTOS.tcp)
2177 self.assertEqual(sessions[1].protocol, IP_PROTOS.udp)
2178 self.assertEqual(sessions[2].protocol, IP_PROTOS.icmp)
2179 self.assertEqual(sessions[0].inside_port, self.tcp_port_in)
2180 self.assertEqual(sessions[1].inside_port, self.udp_port_in)
2181 self.assertEqual(sessions[2].inside_port, self.icmp_id_in)
2182 self.assertEqual(sessions[0].outside_port, self.tcp_port_out)
2183 self.assertEqual(sessions[1].outside_port, self.udp_port_out)
2184 self.assertEqual(sessions[2].outside_port, self.icmp_id_out)
2186 # in2out 3rd interface
2187 pkts = self.create_stream_in(self.pg6, self.pg3)
2188 self.pg6.add_stream(pkts)
2189 self.pg_enable_capture(self.pg_interfaces)
2191 capture = self.pg3.get_capture(len(pkts))
2192 self.verify_capture_out(capture, static_nat_ip, True)
2194 # out2in 3rd interface
2195 pkts = self.create_stream_out(self.pg3, static_nat_ip)
2196 self.pg3.add_stream(pkts)
2197 self.pg_enable_capture(self.pg_interfaces)
2199 capture = self.pg6.get_capture(len(pkts))
2200 self.verify_capture_in(capture, self.pg6)
2202 # general user and session dump verifications
2203 users = self.vapi.nat44_user_dump()
2204 self.assertGreaterEqual(len(users), 3)
2205 addresses = self.vapi.nat44_address_dump()
2206 self.assertEqual(len(addresses), 1)
2208 sessions = self.vapi.nat44_user_session_dump(user.ip_address,
2210 for session in sessions:
2211 self.assertEqual(user.ip_address, session.inside_ip_address)
2212 self.assertTrue(session.total_bytes > session.total_pkts > 0)
2213 self.assertTrue(session.protocol in
2214 [IP_PROTOS.tcp, IP_PROTOS.udp,
2216 self.assertFalse(session.ext_host_valid)
2219 sessions = self.vapi.nat44_user_session_dump(self.pg4.remote_ip4n, 10)
2220 self.assertGreaterEqual(len(sessions), 4)
2221 for session in sessions:
2222 self.assertFalse(session.is_static)
2223 self.assertEqual(session.inside_ip_address[0:4],
2224 self.pg4.remote_ip4n)
2225 self.assertEqual(session.outside_ip_address,
2226 addresses[0].ip_address)
2229 sessions = self.vapi.nat44_user_session_dump(self.pg6.remote_ip4n, 20)
2230 self.assertGreaterEqual(len(sessions), 3)
2231 for session in sessions:
2232 self.assertTrue(session.is_static)
2233 self.assertEqual(session.inside_ip_address[0:4],
2234 self.pg6.remote_ip4n)
2235 self.assertEqual(map(ord, session.outside_ip_address[0:4]),
2236 map(int, static_nat_ip.split('.')))
2237 self.assertTrue(session.inside_port in
2238 [self.tcp_port_in, self.udp_port_in,
2241 def test_hairpinning(self):
2242 """ NAT44 hairpinning - 1:1 NAPT """
2244 host = self.pg0.remote_hosts[0]
2245 server = self.pg0.remote_hosts[1]
2248 server_in_port = 5678
2249 server_out_port = 8765
2251 self.nat44_add_address(self.nat_addr)
2252 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
2253 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
2255 # add static mapping for server
2256 self.nat44_add_static_mapping(server.ip4, self.nat_addr,
2257 server_in_port, server_out_port,
2258 proto=IP_PROTOS.tcp)
2260 # send packet from host to server
2261 p = (Ether(src=host.mac, dst=self.pg0.local_mac) /
2262 IP(src=host.ip4, dst=self.nat_addr) /
2263 TCP(sport=host_in_port, dport=server_out_port))
2264 self.pg0.add_stream(p)
2265 self.pg_enable_capture(self.pg_interfaces)
2267 capture = self.pg0.get_capture(1)
2272 self.assertEqual(ip.src, self.nat_addr)
2273 self.assertEqual(ip.dst, server.ip4)
2274 self.assertNotEqual(tcp.sport, host_in_port)
2275 self.assertEqual(tcp.dport, server_in_port)
2276 self.assert_packet_checksums_valid(p)
2277 host_out_port = tcp.sport
2279 self.logger.error(ppp("Unexpected or invalid packet:", p))
2282 # send reply from server to host
2283 p = (Ether(src=server.mac, dst=self.pg0.local_mac) /
2284 IP(src=server.ip4, dst=self.nat_addr) /
2285 TCP(sport=server_in_port, dport=host_out_port))
2286 self.pg0.add_stream(p)
2287 self.pg_enable_capture(self.pg_interfaces)
2289 capture = self.pg0.get_capture(1)
2294 self.assertEqual(ip.src, self.nat_addr)
2295 self.assertEqual(ip.dst, host.ip4)
2296 self.assertEqual(tcp.sport, server_out_port)
2297 self.assertEqual(tcp.dport, host_in_port)
2298 self.assert_packet_checksums_valid(p)
2300 self.logger.error(ppp("Unexpected or invalid packet:", p))
2303 def test_hairpinning2(self):
2304 """ NAT44 hairpinning - 1:1 NAT"""
2306 server1_nat_ip = "10.0.0.10"
2307 server2_nat_ip = "10.0.0.11"
2308 host = self.pg0.remote_hosts[0]
2309 server1 = self.pg0.remote_hosts[1]
2310 server2 = self.pg0.remote_hosts[2]
2311 server_tcp_port = 22
2312 server_udp_port = 20
2314 self.nat44_add_address(self.nat_addr)
2315 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
2316 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
2319 # add static mapping for servers
2320 self.nat44_add_static_mapping(server1.ip4, server1_nat_ip)
2321 self.nat44_add_static_mapping(server2.ip4, server2_nat_ip)
2325 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2326 IP(src=host.ip4, dst=server1_nat_ip) /
2327 TCP(sport=self.tcp_port_in, dport=server_tcp_port))
2329 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2330 IP(src=host.ip4, dst=server1_nat_ip) /
2331 UDP(sport=self.udp_port_in, dport=server_udp_port))
2333 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2334 IP(src=host.ip4, dst=server1_nat_ip) /
2335 ICMP(id=self.icmp_id_in, type='echo-request'))
2337 self.pg0.add_stream(pkts)
2338 self.pg_enable_capture(self.pg_interfaces)
2340 capture = self.pg0.get_capture(len(pkts))
2341 for packet in capture:
2343 self.assertEqual(packet[IP].src, self.nat_addr)
2344 self.assertEqual(packet[IP].dst, server1.ip4)
2345 if packet.haslayer(TCP):
2346 self.assertNotEqual(packet[TCP].sport, self.tcp_port_in)
2347 self.assertEqual(packet[TCP].dport, server_tcp_port)
2348 self.tcp_port_out = packet[TCP].sport
2349 self.assert_packet_checksums_valid(packet)
2350 elif packet.haslayer(UDP):
2351 self.assertNotEqual(packet[UDP].sport, self.udp_port_in)
2352 self.assertEqual(packet[UDP].dport, server_udp_port)
2353 self.udp_port_out = packet[UDP].sport
2355 self.assertNotEqual(packet[ICMP].id, self.icmp_id_in)
2356 self.icmp_id_out = packet[ICMP].id
2358 self.logger.error(ppp("Unexpected or invalid packet:", packet))
2363 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2364 IP(src=server1.ip4, dst=self.nat_addr) /
2365 TCP(sport=server_tcp_port, dport=self.tcp_port_out))
2367 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2368 IP(src=server1.ip4, dst=self.nat_addr) /
2369 UDP(sport=server_udp_port, dport=self.udp_port_out))
2371 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2372 IP(src=server1.ip4, dst=self.nat_addr) /
2373 ICMP(id=self.icmp_id_out, type='echo-reply'))
2375 self.pg0.add_stream(pkts)
2376 self.pg_enable_capture(self.pg_interfaces)
2378 capture = self.pg0.get_capture(len(pkts))
2379 for packet in capture:
2381 self.assertEqual(packet[IP].src, server1_nat_ip)
2382 self.assertEqual(packet[IP].dst, host.ip4)
2383 if packet.haslayer(TCP):
2384 self.assertEqual(packet[TCP].dport, self.tcp_port_in)
2385 self.assertEqual(packet[TCP].sport, server_tcp_port)
2386 self.assert_packet_checksums_valid(packet)
2387 elif packet.haslayer(UDP):
2388 self.assertEqual(packet[UDP].dport, self.udp_port_in)
2389 self.assertEqual(packet[UDP].sport, server_udp_port)
2391 self.assertEqual(packet[ICMP].id, self.icmp_id_in)
2393 self.logger.error(ppp("Unexpected or invalid packet:", packet))
2396 # server2 to server1
2398 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2399 IP(src=server2.ip4, dst=server1_nat_ip) /
2400 TCP(sport=self.tcp_port_in, dport=server_tcp_port))
2402 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2403 IP(src=server2.ip4, dst=server1_nat_ip) /
2404 UDP(sport=self.udp_port_in, dport=server_udp_port))
2406 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2407 IP(src=server2.ip4, dst=server1_nat_ip) /
2408 ICMP(id=self.icmp_id_in, type='echo-request'))
2410 self.pg0.add_stream(pkts)
2411 self.pg_enable_capture(self.pg_interfaces)
2413 capture = self.pg0.get_capture(len(pkts))
2414 for packet in capture:
2416 self.assertEqual(packet[IP].src, server2_nat_ip)
2417 self.assertEqual(packet[IP].dst, server1.ip4)
2418 if packet.haslayer(TCP):
2419 self.assertEqual(packet[TCP].sport, self.tcp_port_in)
2420 self.assertEqual(packet[TCP].dport, server_tcp_port)
2421 self.tcp_port_out = packet[TCP].sport
2422 self.assert_packet_checksums_valid(packet)
2423 elif packet.haslayer(UDP):
2424 self.assertEqual(packet[UDP].sport, self.udp_port_in)
2425 self.assertEqual(packet[UDP].dport, server_udp_port)
2426 self.udp_port_out = packet[UDP].sport
2428 self.assertEqual(packet[ICMP].id, self.icmp_id_in)
2429 self.icmp_id_out = packet[ICMP].id
2431 self.logger.error(ppp("Unexpected or invalid packet:", packet))
2434 # server1 to server2
2436 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2437 IP(src=server1.ip4, dst=server2_nat_ip) /
2438 TCP(sport=server_tcp_port, dport=self.tcp_port_out))
2440 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2441 IP(src=server1.ip4, dst=server2_nat_ip) /
2442 UDP(sport=server_udp_port, dport=self.udp_port_out))
2444 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2445 IP(src=server1.ip4, dst=server2_nat_ip) /
2446 ICMP(id=self.icmp_id_out, type='echo-reply'))
2448 self.pg0.add_stream(pkts)
2449 self.pg_enable_capture(self.pg_interfaces)
2451 capture = self.pg0.get_capture(len(pkts))
2452 for packet in capture:
2454 self.assertEqual(packet[IP].src, server1_nat_ip)
2455 self.assertEqual(packet[IP].dst, server2.ip4)
2456 if packet.haslayer(TCP):
2457 self.assertEqual(packet[TCP].dport, self.tcp_port_in)
2458 self.assertEqual(packet[TCP].sport, server_tcp_port)
2459 self.assert_packet_checksums_valid(packet)
2460 elif packet.haslayer(UDP):
2461 self.assertEqual(packet[UDP].dport, self.udp_port_in)
2462 self.assertEqual(packet[UDP].sport, server_udp_port)
2464 self.assertEqual(packet[ICMP].id, self.icmp_id_in)
2466 self.logger.error(ppp("Unexpected or invalid packet:", packet))
2469 def test_max_translations_per_user(self):
2470 """ MAX translations per user - recycle the least recently used """
2472 self.nat44_add_address(self.nat_addr)
2473 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
2474 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
2477 # get maximum number of translations per user
2478 nat44_config = self.vapi.nat_show_config()
2480 # send more than maximum number of translations per user packets
2481 pkts_num = nat44_config.max_translations_per_user + 5
2483 for port in range(0, pkts_num):
2484 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2485 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
2486 TCP(sport=1025 + port))
2488 self.pg0.add_stream(pkts)
2489 self.pg_enable_capture(self.pg_interfaces)
2492 # verify number of translated packet
2493 self.pg1.get_capture(pkts_num)
2495 users = self.vapi.nat44_user_dump()
2497 if user.ip_address == self.pg0.remote_ip4n:
2498 self.assertEqual(user.nsessions,
2499 nat44_config.max_translations_per_user)
2500 self.assertEqual(user.nstaticsessions, 0)
2503 self.nat44_add_static_mapping(self.pg0.remote_ip4, self.nat_addr,
2505 proto=IP_PROTOS.tcp)
2506 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2507 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
2508 TCP(sport=tcp_port))
2509 self.pg0.add_stream(p)
2510 self.pg_enable_capture(self.pg_interfaces)
2512 self.pg1.get_capture(1)
2513 users = self.vapi.nat44_user_dump()
2515 if user.ip_address == self.pg0.remote_ip4n:
2516 self.assertEqual(user.nsessions,
2517 nat44_config.max_translations_per_user - 1)
2518 self.assertEqual(user.nstaticsessions, 1)
2520 def test_interface_addr(self):
2521 """ Acquire NAT44 addresses from interface """
2522 self.vapi.nat44_add_interface_addr(self.pg7.sw_if_index)
2524 # no address in NAT pool
2525 adresses = self.vapi.nat44_address_dump()
2526 self.assertEqual(0, len(adresses))
2528 # configure interface address and check NAT address pool
2529 self.pg7.config_ip4()
2530 adresses = self.vapi.nat44_address_dump()
2531 self.assertEqual(1, len(adresses))
2532 self.assertEqual(adresses[0].ip_address[0:4], self.pg7.local_ip4n)
2534 # remove interface address and check NAT address pool
2535 self.pg7.unconfig_ip4()
2536 adresses = self.vapi.nat44_address_dump()
2537 self.assertEqual(0, len(adresses))
2539 def test_interface_addr_static_mapping(self):
2540 """ Static mapping with addresses from interface """
2543 self.vapi.nat44_add_interface_addr(self.pg7.sw_if_index)
2544 self.nat44_add_static_mapping(
2546 external_sw_if_index=self.pg7.sw_if_index,
2549 # static mappings with external interface
2550 static_mappings = self.vapi.nat44_static_mapping_dump()
2551 self.assertEqual(1, len(static_mappings))
2552 self.assertEqual(self.pg7.sw_if_index,
2553 static_mappings[0].external_sw_if_index)
2554 self.assertEqual((static_mappings[0].tag).split('\0', 1)[0], tag)
2556 # configure interface address and check static mappings
2557 self.pg7.config_ip4()
2558 static_mappings = self.vapi.nat44_static_mapping_dump()
2559 self.assertEqual(2, len(static_mappings))
2561 for sm in static_mappings:
2562 if sm.external_sw_if_index == 0xFFFFFFFF:
2563 self.assertEqual(sm.external_ip_address[0:4],
2564 self.pg7.local_ip4n)
2565 self.assertEqual((sm.tag).split('\0', 1)[0], tag)
2567 self.assertTrue(resolved)
2569 # remove interface address and check static mappings
2570 self.pg7.unconfig_ip4()
2571 static_mappings = self.vapi.nat44_static_mapping_dump()
2572 self.assertEqual(1, len(static_mappings))
2573 self.assertEqual(self.pg7.sw_if_index,
2574 static_mappings[0].external_sw_if_index)
2575 self.assertEqual((static_mappings[0].tag).split('\0', 1)[0], tag)
2577 # configure interface address again and check static mappings
2578 self.pg7.config_ip4()
2579 static_mappings = self.vapi.nat44_static_mapping_dump()
2580 self.assertEqual(2, len(static_mappings))
2582 for sm in static_mappings:
2583 if sm.external_sw_if_index == 0xFFFFFFFF:
2584 self.assertEqual(sm.external_ip_address[0:4],
2585 self.pg7.local_ip4n)
2586 self.assertEqual((sm.tag).split('\0', 1)[0], tag)
2588 self.assertTrue(resolved)
2590 # remove static mapping
2591 self.nat44_add_static_mapping(
2593 external_sw_if_index=self.pg7.sw_if_index,
2596 static_mappings = self.vapi.nat44_static_mapping_dump()
2597 self.assertEqual(0, len(static_mappings))
2599 def test_interface_addr_identity_nat(self):
2600 """ Identity NAT with addresses from interface """
2603 self.vapi.nat44_add_interface_addr(self.pg7.sw_if_index)
2604 self.vapi.nat44_add_del_identity_mapping(
2605 sw_if_index=self.pg7.sw_if_index,
2607 protocol=IP_PROTOS.tcp,
2610 # identity mappings with external interface
2611 identity_mappings = self.vapi.nat44_identity_mapping_dump()
2612 self.assertEqual(1, len(identity_mappings))
2613 self.assertEqual(self.pg7.sw_if_index,
2614 identity_mappings[0].sw_if_index)
2616 # configure interface address and check identity mappings
2617 self.pg7.config_ip4()
2618 identity_mappings = self.vapi.nat44_identity_mapping_dump()
2620 self.assertEqual(2, len(identity_mappings))
2621 for sm in identity_mappings:
2622 if sm.sw_if_index == 0xFFFFFFFF:
2623 self.assertEqual(identity_mappings[0].ip_address,
2624 self.pg7.local_ip4n)
2625 self.assertEqual(port, identity_mappings[0].port)
2626 self.assertEqual(IP_PROTOS.tcp, identity_mappings[0].protocol)
2628 self.assertTrue(resolved)
2630 # remove interface address and check identity mappings
2631 self.pg7.unconfig_ip4()
2632 identity_mappings = self.vapi.nat44_identity_mapping_dump()
2633 self.assertEqual(1, len(identity_mappings))
2634 self.assertEqual(self.pg7.sw_if_index,
2635 identity_mappings[0].sw_if_index)
2637 def test_ipfix_nat44_sess(self):
2638 """ IPFIX logging NAT44 session created/delted """
2639 self.ipfix_domain_id = 10
2640 self.ipfix_src_port = 20202
2641 colector_port = 30303
2642 bind_layers(UDP, IPFIX, dport=30303)
2643 self.nat44_add_address(self.nat_addr)
2644 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
2645 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
2647 self.vapi.set_ipfix_exporter(collector_address=self.pg3.remote_ip4n,
2648 src_address=self.pg3.local_ip4n,
2650 template_interval=10,
2651 collector_port=colector_port)
2652 self.vapi.nat_ipfix(domain_id=self.ipfix_domain_id,
2653 src_port=self.ipfix_src_port)
2655 pkts = self.create_stream_in(self.pg0, self.pg1)
2656 self.pg0.add_stream(pkts)
2657 self.pg_enable_capture(self.pg_interfaces)
2659 capture = self.pg1.get_capture(len(pkts))
2660 self.verify_capture_out(capture)
2661 self.nat44_add_address(self.nat_addr, is_add=0)
2662 self.vapi.cli("ipfix flush") # FIXME this should be an API call
2663 capture = self.pg3.get_capture(9)
2664 ipfix = IPFIXDecoder()
2665 # first load template
2667 self.assertTrue(p.haslayer(IPFIX))
2668 self.assertEqual(p[IP].src, self.pg3.local_ip4)
2669 self.assertEqual(p[IP].dst, self.pg3.remote_ip4)
2670 self.assertEqual(p[UDP].sport, self.ipfix_src_port)
2671 self.assertEqual(p[UDP].dport, colector_port)
2672 self.assertEqual(p[IPFIX].observationDomainID,
2673 self.ipfix_domain_id)
2674 if p.haslayer(Template):
2675 ipfix.add_template(p.getlayer(Template))
2676 # verify events in data set
2678 if p.haslayer(Data):
2679 data = ipfix.decode_data_set(p.getlayer(Set))
2680 self.verify_ipfix_nat44_ses(data)
2682 def test_ipfix_addr_exhausted(self):
2683 """ IPFIX logging NAT addresses exhausted """
2684 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
2685 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
2687 self.vapi.set_ipfix_exporter(collector_address=self.pg3.remote_ip4n,
2688 src_address=self.pg3.local_ip4n,
2690 template_interval=10)
2691 self.vapi.nat_ipfix(domain_id=self.ipfix_domain_id,
2692 src_port=self.ipfix_src_port)
2694 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
2695 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
2697 self.pg0.add_stream(p)
2698 self.pg_enable_capture(self.pg_interfaces)
2700 self.pg1.assert_nothing_captured()
2702 self.vapi.cli("ipfix flush") # FIXME this should be an API call
2703 capture = self.pg3.get_capture(9)
2704 ipfix = IPFIXDecoder()
2705 # first load template
2707 self.assertTrue(p.haslayer(IPFIX))
2708 self.assertEqual(p[IP].src, self.pg3.local_ip4)
2709 self.assertEqual(p[IP].dst, self.pg3.remote_ip4)
2710 self.assertEqual(p[UDP].sport, self.ipfix_src_port)
2711 self.assertEqual(p[UDP].dport, 4739)
2712 self.assertEqual(p[IPFIX].observationDomainID,
2713 self.ipfix_domain_id)
2714 if p.haslayer(Template):
2715 ipfix.add_template(p.getlayer(Template))
2716 # verify events in data set
2718 if p.haslayer(Data):
2719 data = ipfix.decode_data_set(p.getlayer(Set))
2720 self.verify_ipfix_addr_exhausted(data)
2722 @unittest.skipUnless(running_extended_tests(), "part of extended tests")
2723 def test_ipfix_max_sessions(self):
2724 """ IPFIX logging maximum session entries exceeded """
2725 self.nat44_add_address(self.nat_addr)
2726 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
2727 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
2730 nat44_config = self.vapi.nat_show_config()
2731 max_sessions = 10 * nat44_config.translation_buckets
2734 for i in range(0, max_sessions):
2735 src = "10.10.%u.%u" % ((i & 0xFF00) >> 8, i & 0xFF)
2736 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2737 IP(src=src, dst=self.pg1.remote_ip4) /
2740 self.pg0.add_stream(pkts)
2741 self.pg_enable_capture(self.pg_interfaces)
2744 self.pg1.get_capture(max_sessions)
2745 self.vapi.set_ipfix_exporter(collector_address=self.pg3.remote_ip4n,
2746 src_address=self.pg3.local_ip4n,
2748 template_interval=10)
2749 self.vapi.nat_ipfix(domain_id=self.ipfix_domain_id,
2750 src_port=self.ipfix_src_port)
2752 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2753 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
2755 self.pg0.add_stream(p)
2756 self.pg_enable_capture(self.pg_interfaces)
2758 self.pg1.assert_nothing_captured()
2760 self.vapi.cli("ipfix flush") # FIXME this should be an API call
2761 capture = self.pg3.get_capture(9)
2762 ipfix = IPFIXDecoder()
2763 # first load template
2765 self.assertTrue(p.haslayer(IPFIX))
2766 self.assertEqual(p[IP].src, self.pg3.local_ip4)
2767 self.assertEqual(p[IP].dst, self.pg3.remote_ip4)
2768 self.assertEqual(p[UDP].sport, self.ipfix_src_port)
2769 self.assertEqual(p[UDP].dport, 4739)
2770 self.assertEqual(p[IPFIX].observationDomainID,
2771 self.ipfix_domain_id)
2772 if p.haslayer(Template):
2773 ipfix.add_template(p.getlayer(Template))
2774 # verify events in data set
2776 if p.haslayer(Data):
2777 data = ipfix.decode_data_set(p.getlayer(Set))
2778 self.verify_ipfix_max_sessions(data, max_sessions)
2780 def test_syslog_apmap(self):
2781 """ Test syslog address and port mapping creation and deletion """
2782 self.vapi.syslog_set_filter(SYSLOG_SEVERITY.INFO)
2783 self.vapi.syslog_set_sender(self.pg3.remote_ip4n, self.pg3.local_ip4n)
2784 self.nat44_add_address(self.nat_addr)
2785 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
2786 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
2789 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2790 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
2791 TCP(sport=self.tcp_port_in, dport=20))
2792 self.pg0.add_stream(p)
2793 self.pg_enable_capture(self.pg_interfaces)
2795 capture = self.pg1.get_capture(1)
2796 self.tcp_port_out = capture[0][TCP].sport
2797 capture = self.pg3.get_capture(1)
2798 self.verify_syslog_apmap(capture[0][Raw].load)
2800 self.pg_enable_capture(self.pg_interfaces)
2802 self.nat44_add_address(self.nat_addr, is_add=0)
2803 capture = self.pg3.get_capture(1)
2804 self.verify_syslog_apmap(capture[0][Raw].load, False)
2806 def test_pool_addr_fib(self):
2807 """ NAT44 add pool addresses to FIB """
2808 static_addr = '10.0.0.10'
2809 self.nat44_add_address(self.nat_addr)
2810 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
2811 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
2813 self.nat44_add_static_mapping(self.pg0.remote_ip4, static_addr)
2816 p = (Ether(src=self.pg1.remote_mac, dst='ff:ff:ff:ff:ff:ff') /
2817 ARP(op=ARP.who_has, pdst=self.nat_addr,
2818 psrc=self.pg1.remote_ip4, hwsrc=self.pg1.remote_mac))
2819 self.pg1.add_stream(p)
2820 self.pg_enable_capture(self.pg_interfaces)
2822 capture = self.pg1.get_capture(1)
2823 self.assertTrue(capture[0].haslayer(ARP))
2824 self.assertTrue(capture[0][ARP].op, ARP.is_at)
2827 p = (Ether(src=self.pg1.remote_mac, dst='ff:ff:ff:ff:ff:ff') /
2828 ARP(op=ARP.who_has, pdst=static_addr,
2829 psrc=self.pg1.remote_ip4, hwsrc=self.pg1.remote_mac))
2830 self.pg1.add_stream(p)
2831 self.pg_enable_capture(self.pg_interfaces)
2833 capture = self.pg1.get_capture(1)
2834 self.assertTrue(capture[0].haslayer(ARP))
2835 self.assertTrue(capture[0][ARP].op, ARP.is_at)
2837 # send ARP to non-NAT44 interface
2838 p = (Ether(src=self.pg2.remote_mac, dst='ff:ff:ff:ff:ff:ff') /
2839 ARP(op=ARP.who_has, pdst=self.nat_addr,
2840 psrc=self.pg2.remote_ip4, hwsrc=self.pg2.remote_mac))
2841 self.pg2.add_stream(p)
2842 self.pg_enable_capture(self.pg_interfaces)
2844 self.pg1.assert_nothing_captured()
2846 # remove addresses and verify
2847 self.nat44_add_address(self.nat_addr, is_add=0)
2848 self.nat44_add_static_mapping(self.pg0.remote_ip4, static_addr,
2851 p = (Ether(src=self.pg1.remote_mac, dst='ff:ff:ff:ff:ff:ff') /
2852 ARP(op=ARP.who_has, pdst=self.nat_addr,
2853 psrc=self.pg1.remote_ip4, hwsrc=self.pg1.remote_mac))
2854 self.pg1.add_stream(p)
2855 self.pg_enable_capture(self.pg_interfaces)
2857 self.pg1.assert_nothing_captured()
2859 p = (Ether(src=self.pg1.remote_mac, dst='ff:ff:ff:ff:ff:ff') /
2860 ARP(op=ARP.who_has, pdst=static_addr,
2861 psrc=self.pg1.remote_ip4, hwsrc=self.pg1.remote_mac))
2862 self.pg1.add_stream(p)
2863 self.pg_enable_capture(self.pg_interfaces)
2865 self.pg1.assert_nothing_captured()
2867 def test_vrf_mode(self):
2868 """ NAT44 tenant VRF aware address pool mode """
2872 nat_ip1 = "10.0.0.10"
2873 nat_ip2 = "10.0.0.11"
2875 self.pg0.unconfig_ip4()
2876 self.pg1.unconfig_ip4()
2877 self.vapi.ip_table_add_del(vrf_id1, is_add=1)
2878 self.vapi.ip_table_add_del(vrf_id2, is_add=1)
2879 self.pg0.set_table_ip4(vrf_id1)
2880 self.pg1.set_table_ip4(vrf_id2)
2881 self.pg0.config_ip4()
2882 self.pg1.config_ip4()
2883 self.pg0.resolve_arp()
2884 self.pg1.resolve_arp()
2886 self.nat44_add_address(nat_ip1, vrf_id=vrf_id1)
2887 self.nat44_add_address(nat_ip2, vrf_id=vrf_id2)
2888 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
2889 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index)
2890 self.vapi.nat44_interface_add_del_feature(self.pg2.sw_if_index,
2895 pkts = self.create_stream_in(self.pg0, self.pg2)
2896 self.pg0.add_stream(pkts)
2897 self.pg_enable_capture(self.pg_interfaces)
2899 capture = self.pg2.get_capture(len(pkts))
2900 self.verify_capture_out(capture, nat_ip1)
2903 pkts = self.create_stream_in(self.pg1, self.pg2)
2904 self.pg1.add_stream(pkts)
2905 self.pg_enable_capture(self.pg_interfaces)
2907 capture = self.pg2.get_capture(len(pkts))
2908 self.verify_capture_out(capture, nat_ip2)
2911 self.pg0.unconfig_ip4()
2912 self.pg1.unconfig_ip4()
2913 self.pg0.set_table_ip4(0)
2914 self.pg1.set_table_ip4(0)
2915 self.pg0.config_ip4()
2916 self.pg1.config_ip4()
2917 self.pg0.resolve_arp()
2918 self.pg1.resolve_arp()
2919 self.vapi.ip_table_add_del(vrf_id1, is_add=0)
2920 self.vapi.ip_table_add_del(vrf_id2, is_add=0)
2922 def test_vrf_feature_independent(self):
2923 """ NAT44 tenant VRF independent address pool mode """
2925 nat_ip1 = "10.0.0.10"
2926 nat_ip2 = "10.0.0.11"
2928 self.nat44_add_address(nat_ip1)
2929 self.nat44_add_address(nat_ip2, vrf_id=99)
2930 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
2931 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index)
2932 self.vapi.nat44_interface_add_del_feature(self.pg2.sw_if_index,
2936 pkts = self.create_stream_in(self.pg0, self.pg2)
2937 self.pg0.add_stream(pkts)
2938 self.pg_enable_capture(self.pg_interfaces)
2940 capture = self.pg2.get_capture(len(pkts))
2941 self.verify_capture_out(capture, nat_ip1)
2944 pkts = self.create_stream_in(self.pg1, self.pg2)
2945 self.pg1.add_stream(pkts)
2946 self.pg_enable_capture(self.pg_interfaces)
2948 capture = self.pg2.get_capture(len(pkts))
2949 self.verify_capture_out(capture, nat_ip1)
2951 def test_dynamic_ipless_interfaces(self):
2952 """ NAT44 interfaces without configured IP address """
2954 self.vapi.ip_neighbor_add_del(self.pg7.sw_if_index,
2955 mac_pton(self.pg7.remote_mac),
2956 self.pg7.remote_ip4n,
2958 self.vapi.ip_neighbor_add_del(self.pg8.sw_if_index,
2959 mac_pton(self.pg8.remote_mac),
2960 self.pg8.remote_ip4n,
2963 self.vapi.ip_add_del_route(dst_address=self.pg7.remote_ip4n,
2964 dst_address_length=32,
2965 next_hop_address=self.pg7.remote_ip4n,
2966 next_hop_sw_if_index=self.pg7.sw_if_index)
2967 self.vapi.ip_add_del_route(dst_address=self.pg8.remote_ip4n,
2968 dst_address_length=32,
2969 next_hop_address=self.pg8.remote_ip4n,
2970 next_hop_sw_if_index=self.pg8.sw_if_index)
2972 self.nat44_add_address(self.nat_addr)
2973 self.vapi.nat44_interface_add_del_feature(self.pg7.sw_if_index)
2974 self.vapi.nat44_interface_add_del_feature(self.pg8.sw_if_index,
2978 pkts = self.create_stream_in(self.pg7, self.pg8)
2979 self.pg7.add_stream(pkts)
2980 self.pg_enable_capture(self.pg_interfaces)
2982 capture = self.pg8.get_capture(len(pkts))
2983 self.verify_capture_out(capture)
2986 pkts = self.create_stream_out(self.pg8, self.nat_addr)
2987 self.pg8.add_stream(pkts)
2988 self.pg_enable_capture(self.pg_interfaces)
2990 capture = self.pg7.get_capture(len(pkts))
2991 self.verify_capture_in(capture, self.pg7)
2993 def test_static_ipless_interfaces(self):
2994 """ NAT44 interfaces without configured IP address - 1:1 NAT """
2996 self.vapi.ip_neighbor_add_del(self.pg7.sw_if_index,
2997 mac_pton(self.pg7.remote_mac),
2998 self.pg7.remote_ip4n,
3000 self.vapi.ip_neighbor_add_del(self.pg8.sw_if_index,
3001 mac_pton(self.pg8.remote_mac),
3002 self.pg8.remote_ip4n,
3005 self.vapi.ip_add_del_route(dst_address=self.pg7.remote_ip4n,
3006 dst_address_length=32,
3007 next_hop_address=self.pg7.remote_ip4n,
3008 next_hop_sw_if_index=self.pg7.sw_if_index)
3009 self.vapi.ip_add_del_route(dst_address=self.pg8.remote_ip4n,
3010 dst_address_length=32,
3011 next_hop_address=self.pg8.remote_ip4n,
3012 next_hop_sw_if_index=self.pg8.sw_if_index)
3014 self.nat44_add_static_mapping(self.pg7.remote_ip4, self.nat_addr)
3015 self.vapi.nat44_interface_add_del_feature(self.pg7.sw_if_index)
3016 self.vapi.nat44_interface_add_del_feature(self.pg8.sw_if_index,
3020 pkts = self.create_stream_out(self.pg8)
3021 self.pg8.add_stream(pkts)
3022 self.pg_enable_capture(self.pg_interfaces)
3024 capture = self.pg7.get_capture(len(pkts))
3025 self.verify_capture_in(capture, self.pg7)
3028 pkts = self.create_stream_in(self.pg7, self.pg8)
3029 self.pg7.add_stream(pkts)
3030 self.pg_enable_capture(self.pg_interfaces)
3032 capture = self.pg8.get_capture(len(pkts))
3033 self.verify_capture_out(capture, self.nat_addr, True)
3035 def test_static_with_port_ipless_interfaces(self):
3036 """ NAT44 interfaces without configured IP address - 1:1 NAPT """
3038 self.tcp_port_out = 30606
3039 self.udp_port_out = 30607
3040 self.icmp_id_out = 30608
3042 self.vapi.ip_neighbor_add_del(self.pg7.sw_if_index,
3043 mac_pton(self.pg7.remote_mac),
3044 self.pg7.remote_ip4n,
3046 self.vapi.ip_neighbor_add_del(self.pg8.sw_if_index,
3047 mac_pton(self.pg8.remote_mac),
3048 self.pg8.remote_ip4n,
3051 self.vapi.ip_add_del_route(dst_address=self.pg7.remote_ip4n,
3052 dst_address_length=32,
3053 next_hop_address=self.pg7.remote_ip4n,
3054 next_hop_sw_if_index=self.pg7.sw_if_index)
3055 self.vapi.ip_add_del_route(dst_address=self.pg8.remote_ip4n,
3056 dst_address_length=32,
3057 next_hop_address=self.pg8.remote_ip4n,
3058 next_hop_sw_if_index=self.pg8.sw_if_index)
3060 self.nat44_add_address(self.nat_addr)
3061 self.nat44_add_static_mapping(self.pg7.remote_ip4, self.nat_addr,
3062 self.tcp_port_in, self.tcp_port_out,
3063 proto=IP_PROTOS.tcp)
3064 self.nat44_add_static_mapping(self.pg7.remote_ip4, self.nat_addr,
3065 self.udp_port_in, self.udp_port_out,
3066 proto=IP_PROTOS.udp)
3067 self.nat44_add_static_mapping(self.pg7.remote_ip4, self.nat_addr,
3068 self.icmp_id_in, self.icmp_id_out,
3069 proto=IP_PROTOS.icmp)
3070 self.vapi.nat44_interface_add_del_feature(self.pg7.sw_if_index)
3071 self.vapi.nat44_interface_add_del_feature(self.pg8.sw_if_index,
3075 pkts = self.create_stream_out(self.pg8)
3076 self.pg8.add_stream(pkts)
3077 self.pg_enable_capture(self.pg_interfaces)
3079 capture = self.pg7.get_capture(len(pkts))
3080 self.verify_capture_in(capture, self.pg7)
3083 pkts = self.create_stream_in(self.pg7, self.pg8)
3084 self.pg7.add_stream(pkts)
3085 self.pg_enable_capture(self.pg_interfaces)
3087 capture = self.pg8.get_capture(len(pkts))
3088 self.verify_capture_out(capture)
3090 def test_static_unknown_proto(self):
3091 """ 1:1 NAT translate packet with unknown protocol """
3092 nat_ip = "10.0.0.10"
3093 self.nat44_add_static_mapping(self.pg0.remote_ip4, nat_ip)
3094 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
3095 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
3099 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
3100 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
3102 IP(src=self.pg2.remote_ip4, dst=self.pg3.remote_ip4) /
3103 TCP(sport=1234, dport=1234))
3104 self.pg0.add_stream(p)
3105 self.pg_enable_capture(self.pg_interfaces)
3107 p = self.pg1.get_capture(1)
3110 self.assertEqual(packet[IP].src, nat_ip)
3111 self.assertEqual(packet[IP].dst, self.pg1.remote_ip4)
3112 self.assertEqual(packet.haslayer(GRE), 1)
3113 self.assert_packet_checksums_valid(packet)
3115 self.logger.error(ppp("Unexpected or invalid packet:", packet))
3119 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
3120 IP(src=self.pg1.remote_ip4, dst=nat_ip) /
3122 IP(src=self.pg3.remote_ip4, dst=self.pg2.remote_ip4) /
3123 TCP(sport=1234, dport=1234))
3124 self.pg1.add_stream(p)
3125 self.pg_enable_capture(self.pg_interfaces)
3127 p = self.pg0.get_capture(1)
3130 self.assertEqual(packet[IP].src, self.pg1.remote_ip4)
3131 self.assertEqual(packet[IP].dst, self.pg0.remote_ip4)
3132 self.assertEqual(packet.haslayer(GRE), 1)
3133 self.assert_packet_checksums_valid(packet)
3135 self.logger.error(ppp("Unexpected or invalid packet:", packet))
3138 def test_hairpinning_static_unknown_proto(self):
3139 """ 1:1 NAT translate packet with unknown protocol - hairpinning """
3141 host = self.pg0.remote_hosts[0]
3142 server = self.pg0.remote_hosts[1]
3144 host_nat_ip = "10.0.0.10"
3145 server_nat_ip = "10.0.0.11"
3147 self.nat44_add_static_mapping(host.ip4, host_nat_ip)
3148 self.nat44_add_static_mapping(server.ip4, server_nat_ip)
3149 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
3150 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
3154 p = (Ether(dst=self.pg0.local_mac, src=host.mac) /
3155 IP(src=host.ip4, dst=server_nat_ip) /
3157 IP(src=self.pg2.remote_ip4, dst=self.pg3.remote_ip4) /
3158 TCP(sport=1234, dport=1234))
3159 self.pg0.add_stream(p)
3160 self.pg_enable_capture(self.pg_interfaces)
3162 p = self.pg0.get_capture(1)
3165 self.assertEqual(packet[IP].src, host_nat_ip)
3166 self.assertEqual(packet[IP].dst, server.ip4)
3167 self.assertEqual(packet.haslayer(GRE), 1)
3168 self.assert_packet_checksums_valid(packet)
3170 self.logger.error(ppp("Unexpected or invalid packet:", packet))
3174 p = (Ether(dst=self.pg0.local_mac, src=server.mac) /
3175 IP(src=server.ip4, dst=host_nat_ip) /
3177 IP(src=self.pg3.remote_ip4, dst=self.pg2.remote_ip4) /
3178 TCP(sport=1234, dport=1234))
3179 self.pg0.add_stream(p)
3180 self.pg_enable_capture(self.pg_interfaces)
3182 p = self.pg0.get_capture(1)
3185 self.assertEqual(packet[IP].src, server_nat_ip)
3186 self.assertEqual(packet[IP].dst, host.ip4)
3187 self.assertEqual(packet.haslayer(GRE), 1)
3188 self.assert_packet_checksums_valid(packet)
3190 self.logger.error(ppp("Unexpected or invalid packet:", packet))
3193 def test_output_feature(self):
3194 """ NAT44 interface output feature (in2out postrouting) """
3195 self.nat44_add_address(self.nat_addr)
3196 self.vapi.nat44_interface_add_del_output_feature(self.pg0.sw_if_index)
3197 self.vapi.nat44_interface_add_del_output_feature(self.pg1.sw_if_index)
3198 self.vapi.nat44_interface_add_del_output_feature(self.pg3.sw_if_index,
3202 pkts = self.create_stream_in(self.pg0, self.pg3)
3203 self.pg0.add_stream(pkts)
3204 self.pg_enable_capture(self.pg_interfaces)
3206 capture = self.pg3.get_capture(len(pkts))
3207 self.verify_capture_out(capture)
3210 pkts = self.create_stream_out(self.pg3)
3211 self.pg3.add_stream(pkts)
3212 self.pg_enable_capture(self.pg_interfaces)
3214 capture = self.pg0.get_capture(len(pkts))
3215 self.verify_capture_in(capture, self.pg0)
3217 # from non-NAT interface to NAT inside interface
3218 pkts = self.create_stream_in(self.pg2, self.pg0)
3219 self.pg2.add_stream(pkts)
3220 self.pg_enable_capture(self.pg_interfaces)
3222 capture = self.pg0.get_capture(len(pkts))
3223 self.verify_capture_no_translation(capture, self.pg2, self.pg0)
3225 def test_output_feature_vrf_aware(self):
3226 """ NAT44 interface output feature VRF aware (in2out postrouting) """
3227 nat_ip_vrf10 = "10.0.0.10"
3228 nat_ip_vrf20 = "10.0.0.20"
3230 self.vapi.ip_add_del_route(dst_address=self.pg3.remote_ip4n,
3231 dst_address_length=32,
3232 next_hop_address=self.pg3.remote_ip4n,
3233 next_hop_sw_if_index=self.pg3.sw_if_index,
3235 self.vapi.ip_add_del_route(dst_address=self.pg3.remote_ip4n,
3236 dst_address_length=32,
3237 next_hop_address=self.pg3.remote_ip4n,
3238 next_hop_sw_if_index=self.pg3.sw_if_index,
3241 self.nat44_add_address(nat_ip_vrf10, vrf_id=10)
3242 self.nat44_add_address(nat_ip_vrf20, vrf_id=20)
3243 self.vapi.nat44_interface_add_del_output_feature(self.pg4.sw_if_index)
3244 self.vapi.nat44_interface_add_del_output_feature(self.pg6.sw_if_index)
3245 self.vapi.nat44_interface_add_del_output_feature(self.pg3.sw_if_index,
3249 pkts = self.create_stream_in(self.pg4, self.pg3)
3250 self.pg4.add_stream(pkts)
3251 self.pg_enable_capture(self.pg_interfaces)
3253 capture = self.pg3.get_capture(len(pkts))
3254 self.verify_capture_out(capture, nat_ip=nat_ip_vrf10)
3257 pkts = self.create_stream_out(self.pg3, dst_ip=nat_ip_vrf10)
3258 self.pg3.add_stream(pkts)
3259 self.pg_enable_capture(self.pg_interfaces)
3261 capture = self.pg4.get_capture(len(pkts))
3262 self.verify_capture_in(capture, self.pg4)
3265 pkts = self.create_stream_in(self.pg6, self.pg3)
3266 self.pg6.add_stream(pkts)
3267 self.pg_enable_capture(self.pg_interfaces)
3269 capture = self.pg3.get_capture(len(pkts))
3270 self.verify_capture_out(capture, nat_ip=nat_ip_vrf20)
3273 pkts = self.create_stream_out(self.pg3, dst_ip=nat_ip_vrf20)
3274 self.pg3.add_stream(pkts)
3275 self.pg_enable_capture(self.pg_interfaces)
3277 capture = self.pg6.get_capture(len(pkts))
3278 self.verify_capture_in(capture, self.pg6)
3280 def test_output_feature_hairpinning(self):
3281 """ NAT44 interface output feature hairpinning (in2out postrouting) """
3282 host = self.pg0.remote_hosts[0]
3283 server = self.pg0.remote_hosts[1]
3286 server_in_port = 5678
3287 server_out_port = 8765
3289 self.nat44_add_address(self.nat_addr)
3290 self.vapi.nat44_interface_add_del_output_feature(self.pg0.sw_if_index)
3291 self.vapi.nat44_interface_add_del_output_feature(self.pg1.sw_if_index,
3294 # add static mapping for server
3295 self.nat44_add_static_mapping(server.ip4, self.nat_addr,
3296 server_in_port, server_out_port,
3297 proto=IP_PROTOS.tcp)
3299 # send packet from host to server
3300 p = (Ether(src=host.mac, dst=self.pg0.local_mac) /
3301 IP(src=host.ip4, dst=self.nat_addr) /
3302 TCP(sport=host_in_port, dport=server_out_port))
3303 self.pg0.add_stream(p)
3304 self.pg_enable_capture(self.pg_interfaces)
3306 capture = self.pg0.get_capture(1)
3311 self.assertEqual(ip.src, self.nat_addr)
3312 self.assertEqual(ip.dst, server.ip4)
3313 self.assertNotEqual(tcp.sport, host_in_port)
3314 self.assertEqual(tcp.dport, server_in_port)
3315 self.assert_packet_checksums_valid(p)
3316 host_out_port = tcp.sport
3318 self.logger.error(ppp("Unexpected or invalid packet:", p))
3321 # send reply from server to host
3322 p = (Ether(src=server.mac, dst=self.pg0.local_mac) /
3323 IP(src=server.ip4, dst=self.nat_addr) /
3324 TCP(sport=server_in_port, dport=host_out_port))
3325 self.pg0.add_stream(p)
3326 self.pg_enable_capture(self.pg_interfaces)
3328 capture = self.pg0.get_capture(1)
3333 self.assertEqual(ip.src, self.nat_addr)
3334 self.assertEqual(ip.dst, host.ip4)
3335 self.assertEqual(tcp.sport, server_out_port)
3336 self.assertEqual(tcp.dport, host_in_port)
3337 self.assert_packet_checksums_valid(p)
3339 self.logger.error(ppp("Unexpected or invalid packet:", p))
3342 def test_one_armed_nat44(self):
3343 """ One armed NAT44 """
3344 remote_host = self.pg9.remote_hosts[0]
3345 local_host = self.pg9.remote_hosts[1]
3348 self.nat44_add_address(self.nat_addr)
3349 self.vapi.nat44_interface_add_del_feature(self.pg9.sw_if_index)
3350 self.vapi.nat44_interface_add_del_feature(self.pg9.sw_if_index,
3354 p = (Ether(src=self.pg9.remote_mac, dst=self.pg9.local_mac) /
3355 IP(src=local_host.ip4, dst=remote_host.ip4) /
3356 TCP(sport=12345, dport=80))
3357 self.pg9.add_stream(p)
3358 self.pg_enable_capture(self.pg_interfaces)
3360 capture = self.pg9.get_capture(1)
3365 self.assertEqual(ip.src, self.nat_addr)
3366 self.assertEqual(ip.dst, remote_host.ip4)
3367 self.assertNotEqual(tcp.sport, 12345)
3368 external_port = tcp.sport
3369 self.assertEqual(tcp.dport, 80)
3370 self.assert_packet_checksums_valid(p)
3372 self.logger.error(ppp("Unexpected or invalid packet:", p))
3376 p = (Ether(src=self.pg9.remote_mac, dst=self.pg9.local_mac) /
3377 IP(src=remote_host.ip4, dst=self.nat_addr) /
3378 TCP(sport=80, dport=external_port))
3379 self.pg9.add_stream(p)
3380 self.pg_enable_capture(self.pg_interfaces)
3382 capture = self.pg9.get_capture(1)
3387 self.assertEqual(ip.src, remote_host.ip4)
3388 self.assertEqual(ip.dst, local_host.ip4)
3389 self.assertEqual(tcp.sport, 80)
3390 self.assertEqual(tcp.dport, 12345)
3391 self.assert_packet_checksums_valid(p)
3393 self.logger.error(ppp("Unexpected or invalid packet:", p))
3396 err = self.statistics.get_counter('/err/nat44-classify/next in2out')
3397 self.assertEqual(err, 1)
3398 err = self.statistics.get_counter('/err/nat44-classify/next out2in')
3399 self.assertEqual(err, 1)
3401 def test_del_session(self):
3402 """ Delete NAT44 session """
3403 self.nat44_add_address(self.nat_addr)
3404 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
3405 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
3408 pkts = self.create_stream_in(self.pg0, self.pg1)
3409 self.pg0.add_stream(pkts)
3410 self.pg_enable_capture(self.pg_interfaces)
3412 self.pg1.get_capture(len(pkts))
3414 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4n, 0)
3415 nsessions = len(sessions)
3417 self.vapi.nat44_del_session(sessions[0].inside_ip_address,
3418 sessions[0].inside_port,
3419 sessions[0].protocol)
3420 self.vapi.nat44_del_session(sessions[1].outside_ip_address,
3421 sessions[1].outside_port,
3422 sessions[1].protocol,
3425 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4n, 0)
3426 self.assertEqual(nsessions - len(sessions), 2)
3428 self.vapi.nat44_del_session(sessions[0].inside_ip_address,
3429 sessions[0].inside_port,
3430 sessions[0].protocol)
3432 self.verify_no_nat44_user()
3434 def test_set_get_reass(self):
3435 """ NAT44 set/get virtual fragmentation reassembly """
3436 reas_cfg1 = self.vapi.nat_get_reass()
3438 self.vapi.nat_set_reass(timeout=reas_cfg1.ip4_timeout + 5,
3439 max_reass=reas_cfg1.ip4_max_reass * 2,
3440 max_frag=reas_cfg1.ip4_max_frag * 2)
3442 reas_cfg2 = self.vapi.nat_get_reass()
3444 self.assertEqual(reas_cfg1.ip4_timeout + 5, reas_cfg2.ip4_timeout)
3445 self.assertEqual(reas_cfg1.ip4_max_reass * 2, reas_cfg2.ip4_max_reass)
3446 self.assertEqual(reas_cfg1.ip4_max_frag * 2, reas_cfg2.ip4_max_frag)
3448 self.vapi.nat_set_reass(drop_frag=1)
3449 self.assertTrue(self.vapi.nat_get_reass().ip4_drop_frag)
3451 def test_frag_in_order(self):
3452 """ NAT44 translate fragments arriving in order """
3454 self.nat44_add_address(self.nat_addr)
3455 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
3456 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
3459 self.frag_in_order(proto=IP_PROTOS.tcp)
3460 self.frag_in_order(proto=IP_PROTOS.udp)
3461 self.frag_in_order(proto=IP_PROTOS.icmp)
3463 def test_frag_forwarding(self):
3464 """ NAT44 forwarding fragment test """
3465 self.vapi.nat44_add_interface_addr(self.pg1.sw_if_index)
3466 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
3467 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
3469 self.vapi.nat44_forwarding_enable_disable(1)
3471 data = "A" * 16 + "B" * 16 + "C" * 3
3472 pkts = self.create_stream_frag(self.pg1,
3473 self.pg0.remote_ip4,
3477 proto=IP_PROTOS.udp)
3478 self.pg1.add_stream(pkts)
3479 self.pg_enable_capture(self.pg_interfaces)
3481 frags = self.pg0.get_capture(len(pkts))
3482 p = self.reass_frags_and_verify(frags,
3483 self.pg1.remote_ip4,
3484 self.pg0.remote_ip4)
3485 self.assertEqual(p[UDP].sport, 4789)
3486 self.assertEqual(p[UDP].dport, 4789)
3487 self.assertEqual(data, p[Raw].load)
3489 def test_reass_hairpinning(self):
3490 """ NAT44 fragments hairpinning """
3492 self.server = self.pg0.remote_hosts[1]
3493 self.host_in_port = random.randint(1025, 65535)
3494 self.server_in_port = random.randint(1025, 65535)
3495 self.server_out_port = random.randint(1025, 65535)
3497 self.nat44_add_address(self.nat_addr)
3498 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
3499 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
3501 # add static mapping for server
3502 self.nat44_add_static_mapping(self.server.ip4, self.nat_addr,
3503 self.server_in_port,
3504 self.server_out_port,
3505 proto=IP_PROTOS.tcp)
3506 self.nat44_add_static_mapping(self.server.ip4, self.nat_addr,
3507 self.server_in_port,
3508 self.server_out_port,
3509 proto=IP_PROTOS.udp)
3510 self.nat44_add_static_mapping(self.server.ip4, self.nat_addr)
3512 self.reass_hairpinning(proto=IP_PROTOS.tcp)
3513 self.reass_hairpinning(proto=IP_PROTOS.udp)
3514 self.reass_hairpinning(proto=IP_PROTOS.icmp)
3516 def test_frag_out_of_order(self):
3517 """ NAT44 translate fragments arriving out of order """
3519 self.nat44_add_address(self.nat_addr)
3520 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
3521 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
3524 self.frag_out_of_order(proto=IP_PROTOS.tcp)
3525 self.frag_out_of_order(proto=IP_PROTOS.udp)
3526 self.frag_out_of_order(proto=IP_PROTOS.icmp)
3528 def test_port_restricted(self):
3529 """ Port restricted NAT44 (MAP-E CE) """
3530 self.nat44_add_address(self.nat_addr)
3531 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
3532 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
3534 self.vapi.nat_set_addr_and_port_alloc_alg(alg=1,
3539 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
3540 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
3541 TCP(sport=4567, dport=22))
3542 self.pg0.add_stream(p)
3543 self.pg_enable_capture(self.pg_interfaces)
3545 capture = self.pg1.get_capture(1)
3550 self.assertEqual(ip.dst, self.pg1.remote_ip4)
3551 self.assertEqual(ip.src, self.nat_addr)
3552 self.assertEqual(tcp.dport, 22)
3553 self.assertNotEqual(tcp.sport, 4567)
3554 self.assertEqual((tcp.sport >> 6) & 63, 10)
3555 self.assert_packet_checksums_valid(p)
3557 self.logger.error(ppp("Unexpected or invalid packet:", p))
3560 def test_port_range(self):
3561 """ External address port range """
3562 self.nat44_add_address(self.nat_addr)
3563 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
3564 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
3566 self.vapi.nat_set_addr_and_port_alloc_alg(alg=2,
3571 for port in range(0, 5):
3572 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
3573 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
3574 TCP(sport=1125 + port))
3576 self.pg0.add_stream(pkts)
3577 self.pg_enable_capture(self.pg_interfaces)
3579 capture = self.pg1.get_capture(3)
3582 self.assertGreaterEqual(tcp.sport, 1025)
3583 self.assertLessEqual(tcp.sport, 1027)
3585 def test_ipfix_max_frags(self):
3586 """ IPFIX logging maximum fragments pending reassembly exceeded """
3587 self.nat44_add_address(self.nat_addr)
3588 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
3589 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
3591 self.vapi.nat_set_reass(max_frag=1)
3592 self.vapi.set_ipfix_exporter(collector_address=self.pg3.remote_ip4n,
3593 src_address=self.pg3.local_ip4n,
3595 template_interval=10)
3596 self.vapi.nat_ipfix(domain_id=self.ipfix_domain_id,
3597 src_port=self.ipfix_src_port)
3599 data = "A" * 4 + "B" * 16 + "C" * 3
3600 self.tcp_port_in = random.randint(1025, 65535)
3601 pkts = self.create_stream_frag(self.pg0,
3602 self.pg1.remote_ip4,
3607 self.pg0.add_stream(pkts)
3608 self.pg_enable_capture(self.pg_interfaces)
3610 self.pg1.assert_nothing_captured()
3612 self.vapi.cli("ipfix flush") # FIXME this should be an API call
3613 capture = self.pg3.get_capture(9)
3614 ipfix = IPFIXDecoder()
3615 # first load template
3617 self.assertTrue(p.haslayer(IPFIX))
3618 self.assertEqual(p[IP].src, self.pg3.local_ip4)
3619 self.assertEqual(p[IP].dst, self.pg3.remote_ip4)
3620 self.assertEqual(p[UDP].sport, self.ipfix_src_port)
3621 self.assertEqual(p[UDP].dport, 4739)
3622 self.assertEqual(p[IPFIX].observationDomainID,
3623 self.ipfix_domain_id)
3624 if p.haslayer(Template):
3625 ipfix.add_template(p.getlayer(Template))
3626 # verify events in data set
3628 if p.haslayer(Data):
3629 data = ipfix.decode_data_set(p.getlayer(Set))
3630 self.verify_ipfix_max_fragments_ip4(data, 1,
3631 self.pg0.remote_ip4n)
3633 def test_multiple_outside_vrf(self):
3634 """ Multiple outside VRF """
3638 self.pg1.unconfig_ip4()
3639 self.pg2.unconfig_ip4()
3640 self.vapi.ip_table_add_del(vrf_id1, is_add=1)
3641 self.vapi.ip_table_add_del(vrf_id2, is_add=1)
3642 self.pg1.set_table_ip4(vrf_id1)
3643 self.pg2.set_table_ip4(vrf_id2)
3644 self.pg1.config_ip4()
3645 self.pg2.config_ip4()
3646 self.pg1.resolve_arp()
3647 self.pg2.resolve_arp()
3649 self.nat44_add_address(self.nat_addr)
3650 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
3651 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
3653 self.vapi.nat44_interface_add_del_feature(self.pg2.sw_if_index,
3658 pkts = self.create_stream_in(self.pg0, self.pg1)
3659 self.pg0.add_stream(pkts)
3660 self.pg_enable_capture(self.pg_interfaces)
3662 capture = self.pg1.get_capture(len(pkts))
3663 self.verify_capture_out(capture, self.nat_addr)
3665 pkts = self.create_stream_out(self.pg1, self.nat_addr)
3666 self.pg1.add_stream(pkts)
3667 self.pg_enable_capture(self.pg_interfaces)
3669 capture = self.pg0.get_capture(len(pkts))
3670 self.verify_capture_in(capture, self.pg0)
3672 self.tcp_port_in = 60303
3673 self.udp_port_in = 60304
3674 self.icmp_id_in = 60305
3677 pkts = self.create_stream_in(self.pg0, self.pg2)
3678 self.pg0.add_stream(pkts)
3679 self.pg_enable_capture(self.pg_interfaces)
3681 capture = self.pg2.get_capture(len(pkts))
3682 self.verify_capture_out(capture, self.nat_addr)
3684 pkts = self.create_stream_out(self.pg2, self.nat_addr)
3685 self.pg2.add_stream(pkts)
3686 self.pg_enable_capture(self.pg_interfaces)
3688 capture = self.pg0.get_capture(len(pkts))
3689 self.verify_capture_in(capture, self.pg0)
3692 self.pg1.unconfig_ip4()
3693 self.pg2.unconfig_ip4()
3694 self.pg1.set_table_ip4(0)
3695 self.pg2.set_table_ip4(0)
3696 self.pg1.config_ip4()
3697 self.pg2.config_ip4()
3698 self.pg1.resolve_arp()
3699 self.pg2.resolve_arp()
3701 @unittest.skipUnless(running_extended_tests(), "part of extended tests")
3702 def test_session_timeout(self):
3703 """ NAT44 session timeouts """
3704 self.nat44_add_address(self.nat_addr)
3705 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
3706 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
3708 self.vapi.nat_set_timeouts(udp=5)
3712 for i in range(0, max_sessions):
3713 src = "10.10.%u.%u" % ((i & 0xFF00) >> 8, i & 0xFF)
3714 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
3715 IP(src=src, dst=self.pg1.remote_ip4) /
3716 UDP(sport=1025, dport=53))
3718 self.pg0.add_stream(pkts)
3719 self.pg_enable_capture(self.pg_interfaces)
3721 self.pg1.get_capture(max_sessions)
3726 for i in range(0, max_sessions):
3727 src = "10.10.%u.%u" % ((i & 0xFF00) >> 8, i & 0xFF)
3728 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
3729 IP(src=src, dst=self.pg1.remote_ip4) /
3730 UDP(sport=1026, dport=53))
3732 self.pg0.add_stream(pkts)
3733 self.pg_enable_capture(self.pg_interfaces)
3735 self.pg1.get_capture(max_sessions)
3738 users = self.vapi.nat44_user_dump()
3740 nsessions = nsessions + user.nsessions
3741 self.assertLess(nsessions, 2 * max_sessions)
3743 def test_mss_clamping(self):
3744 """ TCP MSS clamping """
3745 self.nat44_add_address(self.nat_addr)
3746 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
3747 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
3750 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
3751 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
3752 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
3753 flags="S", options=[('MSS', 1400)]))
3755 self.vapi.nat_set_mss_clamping(enable=1, mss_value=1000)
3756 self.pg0.add_stream(p)
3757 self.pg_enable_capture(self.pg_interfaces)
3759 capture = self.pg1.get_capture(1)
3760 # Negotiated MSS value greater than configured - changed
3761 self.verify_mss_value(capture[0], 1000)
3763 self.vapi.nat_set_mss_clamping(enable=0)
3764 self.pg0.add_stream(p)
3765 self.pg_enable_capture(self.pg_interfaces)
3767 capture = self.pg1.get_capture(1)
3768 # MSS clamping disabled - negotiated MSS unchanged
3769 self.verify_mss_value(capture[0], 1400)
3771 self.vapi.nat_set_mss_clamping(enable=1, mss_value=1500)
3772 self.pg0.add_stream(p)
3773 self.pg_enable_capture(self.pg_interfaces)
3775 capture = self.pg1.get_capture(1)
3776 # Negotiated MSS value smaller than configured - unchanged
3777 self.verify_mss_value(capture[0], 1400)
3780 super(TestNAT44, self).tearDown()
3781 if not self.vpp_dead:
3782 self.logger.info(self.vapi.cli("show nat44 addresses"))
3783 self.logger.info(self.vapi.cli("show nat44 interfaces"))
3784 self.logger.info(self.vapi.cli("show nat44 static mappings"))
3785 self.logger.info(self.vapi.cli("show nat44 interface address"))
3786 self.logger.info(self.vapi.cli("show nat44 sessions detail"))
3787 self.logger.info(self.vapi.cli("show nat virtual-reassembly"))
3788 self.logger.info(self.vapi.cli("show nat44 hash tables detail"))
3789 self.logger.info(self.vapi.cli("show nat timeouts"))
3791 self.vapi.cli("show nat addr-port-assignment-alg"))
3793 self.vapi.cli("clear logging")
3796 class TestNAT44EndpointDependent(MethodHolder):
3797 """ Endpoint-Dependent mapping and filtering test cases """
3800 def setUpConstants(cls):
3801 super(TestNAT44EndpointDependent, cls).setUpConstants()
3802 cls.vpp_cmdline.extend(["nat", "{", "endpoint-dependent", "}"])
3805 def setUpClass(cls):
3806 super(TestNAT44EndpointDependent, cls).setUpClass()
3807 cls.vapi.cli("set log class nat level debug")
3809 cls.tcp_port_in = 6303
3810 cls.tcp_port_out = 6303
3811 cls.udp_port_in = 6304
3812 cls.udp_port_out = 6304
3813 cls.icmp_id_in = 6305
3814 cls.icmp_id_out = 6305
3815 cls.nat_addr = '10.0.0.3'
3816 cls.nat_addr_n = socket.inet_pton(socket.AF_INET, cls.nat_addr)
3817 cls.ipfix_src_port = 4739
3818 cls.ipfix_domain_id = 1
3819 cls.tcp_external_port = 80
3821 cls.create_pg_interfaces(range(7))
3822 cls.interfaces = list(cls.pg_interfaces[0:3])
3824 for i in cls.interfaces:
3829 cls.pg0.generate_remote_hosts(3)
3830 cls.pg0.configure_ipv4_neighbors()
3834 cls.pg4.generate_remote_hosts(2)
3835 cls.pg4.config_ip4()
3836 ip_addr_n = socket.inet_pton(socket.AF_INET, "10.0.0.1")
3837 cls.vapi.sw_interface_add_del_address(cls.pg4.sw_if_index,
3841 cls.pg4.resolve_arp()
3842 cls.pg4._remote_hosts[1]._ip4 = cls.pg4._remote_hosts[0]._ip4
3843 cls.pg4.resolve_arp()
3845 zero_ip4n = socket.inet_pton(socket.AF_INET, "0.0.0.0")
3846 cls.vapi.ip_table_add_del(1, is_add=1)
3848 cls.pg5._local_ip4 = "10.1.1.1"
3849 cls.pg5._local_ip4n = socket.inet_pton(socket.AF_INET,
3851 cls.pg5._remote_hosts[0]._ip4 = "10.1.1.2"
3852 cls.pg5._remote_hosts[0]._ip4n = socket.inet_pton(
3853 socket.AF_INET, cls.pg5.remote_ip4)
3854 cls.pg5.set_table_ip4(1)
3855 cls.pg5.config_ip4()
3857 cls.vapi.ip_add_del_route(dst_address=cls.pg5.remote_ip4n,
3858 dst_address_length=32,
3860 next_hop_sw_if_index=cls.pg5.sw_if_index,
3861 next_hop_address=zero_ip4n)
3863 cls.pg6._local_ip4 = "10.1.2.1"
3864 cls.pg6._local_ip4n = socket.inet_pton(socket.AF_INET,
3866 cls.pg6._remote_hosts[0]._ip4 = "10.1.2.2"
3867 cls.pg6._remote_hosts[0]._ip4n = socket.inet_pton(
3868 socket.AF_INET, cls.pg6.remote_ip4)
3869 cls.pg6.set_table_ip4(1)
3870 cls.pg6.config_ip4()
3872 cls.vapi.ip_add_del_route(dst_address=cls.pg6.remote_ip4n,
3873 dst_address_length=32,
3875 next_hop_sw_if_index=cls.pg6.sw_if_index,
3876 next_hop_address=zero_ip4n)
3878 cls.vapi.ip_add_del_route(dst_address=cls.pg6.remote_ip4n,
3879 dst_address_length=16,
3880 next_hop_address=zero_ip4n,
3882 next_hop_table_id=1)
3883 cls.vapi.ip_add_del_route(dst_address=zero_ip4n,
3884 dst_address_length=0,
3885 next_hop_address=zero_ip4n,
3887 next_hop_table_id=0)
3888 cls.vapi.ip_add_del_route(dst_address=zero_ip4n,
3889 dst_address_length=0,
3891 next_hop_sw_if_index=cls.pg1.sw_if_index,
3892 next_hop_address=cls.pg1.local_ip4n)
3894 cls.pg5.resolve_arp()
3895 cls.pg6.resolve_arp()
3898 super(TestNAT44EndpointDependent, cls).tearDownClass()
3901 def test_frag_in_order(self):
3902 """ NAT44 translate fragments arriving in order """
3903 self.nat44_add_address(self.nat_addr)
3904 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
3905 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
3907 self.frag_in_order(proto=IP_PROTOS.tcp)
3908 self.frag_in_order(proto=IP_PROTOS.udp)
3909 self.frag_in_order(proto=IP_PROTOS.icmp)
3911 def test_frag_in_order_dont_translate(self):
3912 """ NAT44 don't translate fragments arriving in order """
3913 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
3914 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
3916 self.vapi.nat44_forwarding_enable_disable(enable=True)
3917 self.frag_in_order(proto=IP_PROTOS.tcp, dont_translate=True)
3919 def test_frag_out_of_order(self):
3920 """ NAT44 translate fragments arriving out of order """
3921 self.nat44_add_address(self.nat_addr)
3922 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
3923 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
3925 self.frag_out_of_order(proto=IP_PROTOS.tcp)
3926 self.frag_out_of_order(proto=IP_PROTOS.udp)
3927 self.frag_out_of_order(proto=IP_PROTOS.icmp)
3929 def test_frag_out_of_order_dont_translate(self):
3930 """ NAT44 don't translate fragments arriving out of order """
3931 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
3932 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
3934 self.vapi.nat44_forwarding_enable_disable(enable=True)
3935 self.frag_out_of_order(proto=IP_PROTOS.tcp, dont_translate=True)
3937 def test_frag_in_order_in_plus_out(self):
3938 """ in+out interface fragments in order """
3939 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
3940 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index,
3942 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index)
3943 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
3946 self.server = self.pg1.remote_hosts[0]
3948 self.server_in_addr = self.server.ip4
3949 self.server_out_addr = '11.11.11.11'
3950 self.server_in_port = random.randint(1025, 65535)
3951 self.server_out_port = random.randint(1025, 65535)
3953 self.nat44_add_address(self.server_out_addr)
3955 # add static mappings for server
3956 self.nat44_add_static_mapping(self.server_in_addr,
3957 self.server_out_addr,
3958 self.server_in_port,
3959 self.server_out_port,
3960 proto=IP_PROTOS.tcp)
3961 self.nat44_add_static_mapping(self.server_in_addr,
3962 self.server_out_addr,
3963 self.server_in_port,
3964 self.server_out_port,
3965 proto=IP_PROTOS.udp)
3966 self.nat44_add_static_mapping(self.server_in_addr,
3967 self.server_out_addr,
3968 proto=IP_PROTOS.icmp)
3970 self.vapi.nat_set_reass(timeout=10)
3972 self.frag_in_order_in_plus_out(proto=IP_PROTOS.tcp)
3973 self.frag_in_order_in_plus_out(proto=IP_PROTOS.udp)
3974 self.frag_in_order_in_plus_out(proto=IP_PROTOS.icmp)
3976 def test_frag_out_of_order_in_plus_out(self):
3977 """ in+out interface fragments out of order """
3978 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
3979 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index,
3981 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index)
3982 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
3985 self.server = self.pg1.remote_hosts[0]
3987 self.server_in_addr = self.server.ip4
3988 self.server_out_addr = '11.11.11.11'
3989 self.server_in_port = random.randint(1025, 65535)
3990 self.server_out_port = random.randint(1025, 65535)
3992 self.nat44_add_address(self.server_out_addr)
3994 # add static mappings for server
3995 self.nat44_add_static_mapping(self.server_in_addr,
3996 self.server_out_addr,
3997 self.server_in_port,
3998 self.server_out_port,
3999 proto=IP_PROTOS.tcp)
4000 self.nat44_add_static_mapping(self.server_in_addr,
4001 self.server_out_addr,
4002 self.server_in_port,
4003 self.server_out_port,
4004 proto=IP_PROTOS.udp)
4005 self.nat44_add_static_mapping(self.server_in_addr,
4006 self.server_out_addr,
4007 proto=IP_PROTOS.icmp)
4009 self.vapi.nat_set_reass(timeout=10)
4011 self.frag_out_of_order_in_plus_out(proto=IP_PROTOS.tcp)
4012 self.frag_out_of_order_in_plus_out(proto=IP_PROTOS.udp)
4013 self.frag_out_of_order_in_plus_out(proto=IP_PROTOS.icmp)
4015 def test_reass_hairpinning(self):
4016 """ NAT44 fragments hairpinning """
4017 self.server = self.pg0.remote_hosts[1]
4018 self.host_in_port = random.randint(1025, 65535)
4019 self.server_in_port = random.randint(1025, 65535)
4020 self.server_out_port = random.randint(1025, 65535)
4022 self.nat44_add_address(self.nat_addr)
4023 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
4024 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
4026 # add static mapping for server
4027 self.nat44_add_static_mapping(self.server.ip4, self.nat_addr,
4028 self.server_in_port,
4029 self.server_out_port,
4030 proto=IP_PROTOS.tcp)
4031 self.nat44_add_static_mapping(self.server.ip4, self.nat_addr,
4032 self.server_in_port,
4033 self.server_out_port,
4034 proto=IP_PROTOS.udp)
4035 self.nat44_add_static_mapping(self.server.ip4, self.nat_addr)
4037 self.reass_hairpinning(proto=IP_PROTOS.tcp)
4038 self.reass_hairpinning(proto=IP_PROTOS.udp)
4039 self.reass_hairpinning(proto=IP_PROTOS.icmp)
4041 def test_dynamic(self):
4042 """ NAT44 dynamic translation test """
4044 self.nat44_add_address(self.nat_addr)
4045 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
4046 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
4049 nat_config = self.vapi.nat_show_config()
4050 self.assertEqual(1, nat_config.endpoint_dependent)
4053 tcpn = self.statistics.get_counter(
4054 '/err/nat44-ed-in2out-slowpath/TCP packets')
4055 udpn = self.statistics.get_counter(
4056 '/err/nat44-ed-in2out-slowpath/UDP packets')
4057 icmpn = self.statistics.get_counter(
4058 '/err/nat44-ed-in2out-slowpath/ICMP packets')
4059 totaln = self.statistics.get_counter(
4060 '/err/nat44-ed-in2out-slowpath/good in2out packets processed')
4062 pkts = self.create_stream_in(self.pg0, self.pg1)
4063 self.pg0.add_stream(pkts)
4064 self.pg_enable_capture(self.pg_interfaces)
4066 capture = self.pg1.get_capture(len(pkts))
4067 self.verify_capture_out(capture)
4069 err = self.statistics.get_counter(
4070 '/err/nat44-ed-in2out-slowpath/TCP packets')
4071 self.assertEqual(err - tcpn, 1)
4072 err = self.statistics.get_counter(
4073 '/err/nat44-ed-in2out-slowpath/UDP packets')
4074 self.assertEqual(err - udpn, 1)
4075 err = self.statistics.get_counter(
4076 '/err/nat44-ed-in2out-slowpath/ICMP packets')
4077 self.assertEqual(err - icmpn, 1)
4078 err = self.statistics.get_counter(
4079 '/err/nat44-ed-in2out-slowpath/good in2out packets processed')
4080 self.assertEqual(err - totaln, 3)
4083 tcpn = self.statistics.get_counter('/err/nat44-ed-out2in/TCP packets')
4084 udpn = self.statistics.get_counter('/err/nat44-ed-out2in/UDP packets')
4085 icmpn = self.statistics.get_counter(
4086 '/err/nat44-ed-out2in-slowpath/ICMP packets')
4087 totaln = self.statistics.get_counter(
4088 '/err/nat44-ed-out2in/good out2in packets processed')
4090 pkts = self.create_stream_out(self.pg1)
4091 self.pg1.add_stream(pkts)
4092 self.pg_enable_capture(self.pg_interfaces)
4094 capture = self.pg0.get_capture(len(pkts))
4095 self.verify_capture_in(capture, self.pg0)
4097 err = self.statistics.get_counter('/err/nat44-ed-out2in/TCP packets')
4098 self.assertEqual(err - tcpn, 1)
4099 err = self.statistics.get_counter('/err/nat44-ed-out2in/UDP packets')
4100 self.assertEqual(err - udpn, 1)
4101 err = self.statistics.get_counter(
4102 '/err/nat44-ed-out2in-slowpath/ICMP packets')
4103 self.assertEqual(err - icmpn, 1)
4104 err = self.statistics.get_counter(
4105 '/err/nat44-ed-out2in/good out2in packets processed')
4106 self.assertEqual(err - totaln, 2)
4108 def test_forwarding(self):
4109 """ NAT44 forwarding test """
4111 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
4112 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
4114 self.vapi.nat44_forwarding_enable_disable(1)
4116 real_ip = self.pg0.remote_ip4n
4117 alias_ip = self.nat_addr_n
4118 self.vapi.nat44_add_del_static_mapping(local_ip=real_ip,
4119 external_ip=alias_ip)
4122 # in2out - static mapping match
4124 pkts = self.create_stream_out(self.pg1)
4125 self.pg1.add_stream(pkts)
4126 self.pg_enable_capture(self.pg_interfaces)
4128 capture = self.pg0.get_capture(len(pkts))
4129 self.verify_capture_in(capture, self.pg0)
4131 pkts = self.create_stream_in(self.pg0, self.pg1)
4132 self.pg0.add_stream(pkts)
4133 self.pg_enable_capture(self.pg_interfaces)
4135 capture = self.pg1.get_capture(len(pkts))
4136 self.verify_capture_out(capture, same_port=True)
4138 # in2out - no static mapping match
4140 host0 = self.pg0.remote_hosts[0]
4141 self.pg0.remote_hosts[0] = self.pg0.remote_hosts[1]
4143 pkts = self.create_stream_out(self.pg1,
4144 dst_ip=self.pg0.remote_ip4,
4145 use_inside_ports=True)
4146 self.pg1.add_stream(pkts)
4147 self.pg_enable_capture(self.pg_interfaces)
4149 capture = self.pg0.get_capture(len(pkts))
4150 self.verify_capture_in(capture, self.pg0)
4152 pkts = self.create_stream_in(self.pg0, self.pg1)
4153 self.pg0.add_stream(pkts)
4154 self.pg_enable_capture(self.pg_interfaces)
4156 capture = self.pg1.get_capture(len(pkts))
4157 self.verify_capture_out(capture, nat_ip=self.pg0.remote_ip4,
4160 self.pg0.remote_hosts[0] = host0
4162 user = self.pg0.remote_hosts[1]
4163 sessions = self.vapi.nat44_user_session_dump(user.ip4n, 0)
4164 self.assertEqual(len(sessions), 3)
4165 self.assertTrue(sessions[0].ext_host_valid)
4166 self.vapi.nat44_del_session(
4167 sessions[0].inside_ip_address,
4168 sessions[0].inside_port,
4169 sessions[0].protocol,
4170 ext_host_address=sessions[0].ext_host_address,
4171 ext_host_port=sessions[0].ext_host_port)
4172 sessions = self.vapi.nat44_user_session_dump(user.ip4n, 0)
4173 self.assertEqual(len(sessions), 2)
4176 self.vapi.nat44_forwarding_enable_disable(0)
4177 self.vapi.nat44_add_del_static_mapping(local_ip=real_ip,
4178 external_ip=alias_ip,
4181 def test_static_lb(self):
4182 """ NAT44 local service load balancing """
4183 external_addr_n = socket.inet_pton(socket.AF_INET, self.nat_addr)
4186 server1 = self.pg0.remote_hosts[0]
4187 server2 = self.pg0.remote_hosts[1]
4189 locals = [{'addr': server1.ip4n,
4193 {'addr': server2.ip4n,
4198 self.nat44_add_address(self.nat_addr)
4199 self.vapi.nat44_add_del_lb_static_mapping(external_addr_n,
4202 local_num=len(locals),
4204 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
4205 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
4208 # from client to service
4209 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
4210 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
4211 TCP(sport=12345, dport=external_port))
4212 self.pg1.add_stream(p)
4213 self.pg_enable_capture(self.pg_interfaces)
4215 capture = self.pg0.get_capture(1)
4221 self.assertIn(ip.dst, [server1.ip4, server2.ip4])
4222 if ip.dst == server1.ip4:
4226 self.assertEqual(tcp.dport, local_port)
4227 self.assert_packet_checksums_valid(p)
4229 self.logger.error(ppp("Unexpected or invalid packet:", p))
4232 # from service back to client
4233 p = (Ether(src=server.mac, dst=self.pg0.local_mac) /
4234 IP(src=server.ip4, dst=self.pg1.remote_ip4) /
4235 TCP(sport=local_port, dport=12345))
4236 self.pg0.add_stream(p)
4237 self.pg_enable_capture(self.pg_interfaces)
4239 capture = self.pg1.get_capture(1)
4244 self.assertEqual(ip.src, self.nat_addr)
4245 self.assertEqual(tcp.sport, external_port)
4246 self.assert_packet_checksums_valid(p)
4248 self.logger.error(ppp("Unexpected or invalid packet:", p))
4251 sessions = self.vapi.nat44_user_session_dump(server.ip4n, 0)
4252 self.assertEqual(len(sessions), 1)
4253 self.assertTrue(sessions[0].ext_host_valid)
4254 self.vapi.nat44_del_session(
4255 sessions[0].inside_ip_address,
4256 sessions[0].inside_port,
4257 sessions[0].protocol,
4258 ext_host_address=sessions[0].ext_host_address,
4259 ext_host_port=sessions[0].ext_host_port)
4260 sessions = self.vapi.nat44_user_session_dump(server.ip4n, 0)
4261 self.assertEqual(len(sessions), 0)
4263 @unittest.skipUnless(running_extended_tests(), "part of extended tests")
4264 def test_static_lb_multi_clients(self):
4265 """ NAT44 local service load balancing - multiple clients"""
4267 external_addr_n = socket.inet_pton(socket.AF_INET, self.nat_addr)
4270 server1 = self.pg0.remote_hosts[0]
4271 server2 = self.pg0.remote_hosts[1]
4272 server3 = self.pg0.remote_hosts[2]
4274 locals = [{'addr': server1.ip4n,
4278 {'addr': server2.ip4n,
4283 self.nat44_add_address(self.nat_addr)
4284 self.vapi.nat44_add_del_lb_static_mapping(external_addr_n,
4287 local_num=len(locals),
4289 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
4290 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
4295 clients = ip4_range(self.pg1.remote_ip4, 10, 50)
4297 for client in clients:
4298 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
4299 IP(src=client, dst=self.nat_addr) /
4300 TCP(sport=12345, dport=external_port))
4302 self.pg1.add_stream(pkts)
4303 self.pg_enable_capture(self.pg_interfaces)
4305 capture = self.pg0.get_capture(len(pkts))
4307 if p[IP].dst == server1.ip4:
4311 self.assertGreater(server1_n, server2_n)
4314 self.vapi.nat44_lb_static_mapping_add_del_local(external_addr_n,
4323 clients = ip4_range(self.pg1.remote_ip4, 60, 110)
4325 for client in clients:
4326 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
4327 IP(src=client, dst=self.nat_addr) /
4328 TCP(sport=12346, dport=external_port))
4330 self.assertGreater(len(pkts), 0)
4331 self.pg1.add_stream(pkts)
4332 self.pg_enable_capture(self.pg_interfaces)
4334 capture = self.pg0.get_capture(len(pkts))
4336 if p[IP].dst == server1.ip4:
4338 elif p[IP].dst == server2.ip4:
4342 self.assertGreater(server1_n, 0)
4343 self.assertGreater(server2_n, 0)
4344 self.assertGreater(server3_n, 0)
4346 # remove one back-end
4347 self.vapi.nat44_lb_static_mapping_add_del_local(external_addr_n,
4357 self.pg1.add_stream(pkts)
4358 self.pg_enable_capture(self.pg_interfaces)
4360 capture = self.pg0.get_capture(len(pkts))
4362 if p[IP].dst == server1.ip4:
4364 elif p[IP].dst == server2.ip4:
4368 self.assertGreater(server1_n, 0)
4369 self.assertEqual(server2_n, 0)
4370 self.assertGreater(server3_n, 0)
4372 def test_static_lb_2(self):
4373 """ NAT44 local service load balancing (asymmetrical rule) """
4374 external_addr_n = socket.inet_pton(socket.AF_INET, self.nat_addr)
4377 server1 = self.pg0.remote_hosts[0]
4378 server2 = self.pg0.remote_hosts[1]
4380 locals = [{'addr': server1.ip4n,
4384 {'addr': server2.ip4n,
4389 self.vapi.nat44_forwarding_enable_disable(1)
4390 self.vapi.nat44_add_del_lb_static_mapping(external_addr_n,
4394 local_num=len(locals),
4396 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
4397 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
4400 # from client to service
4401 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
4402 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
4403 TCP(sport=12345, dport=external_port))
4404 self.pg1.add_stream(p)
4405 self.pg_enable_capture(self.pg_interfaces)
4407 capture = self.pg0.get_capture(1)
4413 self.assertIn(ip.dst, [server1.ip4, server2.ip4])
4414 if ip.dst == server1.ip4:
4418 self.assertEqual(tcp.dport, local_port)
4419 self.assert_packet_checksums_valid(p)
4421 self.logger.error(ppp("Unexpected or invalid packet:", p))
4424 # from service back to client
4425 p = (Ether(src=server.mac, dst=self.pg0.local_mac) /
4426 IP(src=server.ip4, dst=self.pg1.remote_ip4) /
4427 TCP(sport=local_port, dport=12345))
4428 self.pg0.add_stream(p)
4429 self.pg_enable_capture(self.pg_interfaces)
4431 capture = self.pg1.get_capture(1)
4436 self.assertEqual(ip.src, self.nat_addr)
4437 self.assertEqual(tcp.sport, external_port)
4438 self.assert_packet_checksums_valid(p)
4440 self.logger.error(ppp("Unexpected or invalid packet:", p))
4443 # from client to server (no translation)
4444 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
4445 IP(src=self.pg1.remote_ip4, dst=server1.ip4) /
4446 TCP(sport=12346, dport=local_port))
4447 self.pg1.add_stream(p)
4448 self.pg_enable_capture(self.pg_interfaces)
4450 capture = self.pg0.get_capture(1)
4456 self.assertEqual(ip.dst, server1.ip4)
4457 self.assertEqual(tcp.dport, local_port)
4458 self.assert_packet_checksums_valid(p)
4460 self.logger.error(ppp("Unexpected or invalid packet:", p))
4463 # from service back to client (no translation)
4464 p = (Ether(src=server1.mac, dst=self.pg0.local_mac) /
4465 IP(src=server1.ip4, dst=self.pg1.remote_ip4) /
4466 TCP(sport=local_port, dport=12346))
4467 self.pg0.add_stream(p)
4468 self.pg_enable_capture(self.pg_interfaces)
4470 capture = self.pg1.get_capture(1)
4475 self.assertEqual(ip.src, server1.ip4)
4476 self.assertEqual(tcp.sport, local_port)
4477 self.assert_packet_checksums_valid(p)
4479 self.logger.error(ppp("Unexpected or invalid packet:", p))
4482 def test_lb_affinity(self):
4483 """ NAT44 local service load balancing affinity """
4484 external_addr_n = socket.inet_pton(socket.AF_INET, self.nat_addr)
4487 server1 = self.pg0.remote_hosts[0]
4488 server2 = self.pg0.remote_hosts[1]
4490 locals = [{'addr': server1.ip4n,
4494 {'addr': server2.ip4n,
4499 self.nat44_add_address(self.nat_addr)
4500 self.vapi.nat44_add_del_lb_static_mapping(external_addr_n,
4504 local_num=len(locals),
4506 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
4507 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
4510 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
4511 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
4512 TCP(sport=1025, dport=external_port))
4513 self.pg1.add_stream(p)
4514 self.pg_enable_capture(self.pg_interfaces)
4516 capture = self.pg0.get_capture(1)
4517 backend = capture[0][IP].dst
4519 sessions = self.vapi.nat44_user_session_dump(
4520 socket.inet_pton(socket.AF_INET, backend), 0)
4521 self.assertEqual(len(sessions), 1)
4522 self.assertTrue(sessions[0].ext_host_valid)
4523 self.vapi.nat44_del_session(
4524 sessions[0].inside_ip_address,
4525 sessions[0].inside_port,
4526 sessions[0].protocol,
4527 ext_host_address=sessions[0].ext_host_address,
4528 ext_host_port=sessions[0].ext_host_port)
4531 for port in range(1030, 1100):
4532 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
4533 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
4534 TCP(sport=port, dport=external_port))
4536 self.pg1.add_stream(pkts)
4537 self.pg_enable_capture(self.pg_interfaces)
4539 capture = self.pg0.get_capture(len(pkts))
4541 self.assertEqual(p[IP].dst, backend)
4543 def test_unknown_proto(self):
4544 """ NAT44 translate packet with unknown protocol """
4545 self.nat44_add_address(self.nat_addr)
4546 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
4547 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
4551 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
4552 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
4553 TCP(sport=self.tcp_port_in, dport=20))
4554 self.pg0.add_stream(p)
4555 self.pg_enable_capture(self.pg_interfaces)
4557 p = self.pg1.get_capture(1)
4559 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
4560 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
4562 IP(src=self.pg2.remote_ip4, dst=self.pg2.remote_ip4) /
4563 TCP(sport=1234, dport=1234))
4564 self.pg0.add_stream(p)
4565 self.pg_enable_capture(self.pg_interfaces)
4567 p = self.pg1.get_capture(1)
4570 self.assertEqual(packet[IP].src, self.nat_addr)
4571 self.assertEqual(packet[IP].dst, self.pg1.remote_ip4)
4572 self.assertEqual(packet.haslayer(GRE), 1)
4573 self.assert_packet_checksums_valid(packet)
4575 self.logger.error(ppp("Unexpected or invalid packet:", packet))
4579 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
4580 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
4582 IP(src=self.pg2.remote_ip4, dst=self.pg2.remote_ip4) /
4583 TCP(sport=1234, dport=1234))
4584 self.pg1.add_stream(p)
4585 self.pg_enable_capture(self.pg_interfaces)
4587 p = self.pg0.get_capture(1)
4590 self.assertEqual(packet[IP].src, self.pg1.remote_ip4)
4591 self.assertEqual(packet[IP].dst, self.pg0.remote_ip4)
4592 self.assertEqual(packet.haslayer(GRE), 1)
4593 self.assert_packet_checksums_valid(packet)
4595 self.logger.error(ppp("Unexpected or invalid packet:", packet))
4598 def test_hairpinning_unknown_proto(self):
4599 """ NAT44 translate packet with unknown protocol - hairpinning """
4600 host = self.pg0.remote_hosts[0]
4601 server = self.pg0.remote_hosts[1]
4603 server_out_port = 8765
4604 server_nat_ip = "10.0.0.11"
4606 self.nat44_add_address(self.nat_addr)
4607 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
4608 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
4611 # add static mapping for server
4612 self.nat44_add_static_mapping(server.ip4, server_nat_ip)
4615 p = (Ether(src=host.mac, dst=self.pg0.local_mac) /
4616 IP(src=host.ip4, dst=server_nat_ip) /
4617 TCP(sport=host_in_port, dport=server_out_port))
4618 self.pg0.add_stream(p)
4619 self.pg_enable_capture(self.pg_interfaces)
4621 self.pg0.get_capture(1)
4623 p = (Ether(dst=self.pg0.local_mac, src=host.mac) /
4624 IP(src=host.ip4, dst=server_nat_ip) /
4626 IP(src=self.pg2.remote_ip4, dst=self.pg2.remote_ip4) /
4627 TCP(sport=1234, dport=1234))
4628 self.pg0.add_stream(p)
4629 self.pg_enable_capture(self.pg_interfaces)
4631 p = self.pg0.get_capture(1)
4634 self.assertEqual(packet[IP].src, self.nat_addr)
4635 self.assertEqual(packet[IP].dst, server.ip4)
4636 self.assertEqual(packet.haslayer(GRE), 1)
4637 self.assert_packet_checksums_valid(packet)
4639 self.logger.error(ppp("Unexpected or invalid packet:", packet))
4643 p = (Ether(dst=self.pg0.local_mac, src=server.mac) /
4644 IP(src=server.ip4, dst=self.nat_addr) /
4646 IP(src=self.pg2.remote_ip4, dst=self.pg2.remote_ip4) /
4647 TCP(sport=1234, dport=1234))
4648 self.pg0.add_stream(p)
4649 self.pg_enable_capture(self.pg_interfaces)
4651 p = self.pg0.get_capture(1)
4654 self.assertEqual(packet[IP].src, server_nat_ip)
4655 self.assertEqual(packet[IP].dst, host.ip4)
4656 self.assertEqual(packet.haslayer(GRE), 1)
4657 self.assert_packet_checksums_valid(packet)
4659 self.logger.error(ppp("Unexpected or invalid packet:", packet))
4662 def test_output_feature_and_service(self):
4663 """ NAT44 interface output feature and services """
4664 external_addr = '1.2.3.4'
4668 self.vapi.nat44_forwarding_enable_disable(1)
4669 self.nat44_add_address(self.nat_addr)
4670 self.vapi.nat44_add_del_identity_mapping(ip=self.pg1.remote_ip4n)
4671 self.nat44_add_static_mapping(self.pg0.remote_ip4, external_addr,
4672 local_port, external_port,
4673 proto=IP_PROTOS.tcp, out2in_only=1)
4674 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
4675 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index,
4677 self.vapi.nat44_interface_add_del_output_feature(self.pg1.sw_if_index,
4680 # from client to service
4681 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
4682 IP(src=self.pg1.remote_ip4, dst=external_addr) /
4683 TCP(sport=12345, dport=external_port))
4684 self.pg1.add_stream(p)
4685 self.pg_enable_capture(self.pg_interfaces)
4687 capture = self.pg0.get_capture(1)
4692 self.assertEqual(ip.dst, self.pg0.remote_ip4)
4693 self.assertEqual(tcp.dport, local_port)
4694 self.assert_packet_checksums_valid(p)
4696 self.logger.error(ppp("Unexpected or invalid packet:", p))
4699 # from service back to client
4700 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
4701 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
4702 TCP(sport=local_port, dport=12345))
4703 self.pg0.add_stream(p)
4704 self.pg_enable_capture(self.pg_interfaces)
4706 capture = self.pg1.get_capture(1)
4711 self.assertEqual(ip.src, external_addr)
4712 self.assertEqual(tcp.sport, external_port)
4713 self.assert_packet_checksums_valid(p)
4715 self.logger.error(ppp("Unexpected or invalid packet:", p))
4718 # from local network host to external network
4719 pkts = self.create_stream_in(self.pg0, self.pg1)
4720 self.pg0.add_stream(pkts)
4721 self.pg_enable_capture(self.pg_interfaces)
4723 capture = self.pg1.get_capture(len(pkts))
4724 self.verify_capture_out(capture)
4725 pkts = self.create_stream_in(self.pg0, self.pg1)
4726 self.pg0.add_stream(pkts)
4727 self.pg_enable_capture(self.pg_interfaces)
4729 capture = self.pg1.get_capture(len(pkts))
4730 self.verify_capture_out(capture)
4732 # from external network back to local network host
4733 pkts = self.create_stream_out(self.pg1)
4734 self.pg1.add_stream(pkts)
4735 self.pg_enable_capture(self.pg_interfaces)
4737 capture = self.pg0.get_capture(len(pkts))
4738 self.verify_capture_in(capture, self.pg0)
4740 def test_output_feature_and_service2(self):
4741 """ NAT44 interface output feature and service host direct access """
4742 self.vapi.nat44_forwarding_enable_disable(1)
4743 self.nat44_add_address(self.nat_addr)
4744 self.vapi.nat44_interface_add_del_output_feature(self.pg1.sw_if_index,
4747 # session initiaded from service host - translate
4748 pkts = self.create_stream_in(self.pg0, self.pg1)
4749 self.pg0.add_stream(pkts)
4750 self.pg_enable_capture(self.pg_interfaces)
4752 capture = self.pg1.get_capture(len(pkts))
4753 self.verify_capture_out(capture)
4755 pkts = self.create_stream_out(self.pg1)
4756 self.pg1.add_stream(pkts)
4757 self.pg_enable_capture(self.pg_interfaces)
4759 capture = self.pg0.get_capture(len(pkts))
4760 self.verify_capture_in(capture, self.pg0)
4762 # session initiaded from remote host - do not translate
4763 self.tcp_port_in = 60303
4764 self.udp_port_in = 60304
4765 self.icmp_id_in = 60305
4766 pkts = self.create_stream_out(self.pg1,
4767 self.pg0.remote_ip4,
4768 use_inside_ports=True)
4769 self.pg1.add_stream(pkts)
4770 self.pg_enable_capture(self.pg_interfaces)
4772 capture = self.pg0.get_capture(len(pkts))
4773 self.verify_capture_in(capture, self.pg0)
4775 pkts = self.create_stream_in(self.pg0, self.pg1)
4776 self.pg0.add_stream(pkts)
4777 self.pg_enable_capture(self.pg_interfaces)
4779 capture = self.pg1.get_capture(len(pkts))
4780 self.verify_capture_out(capture, nat_ip=self.pg0.remote_ip4,
4783 def test_output_feature_and_service3(self):
4784 """ NAT44 interface output feature and DST NAT """
4785 external_addr = '1.2.3.4'
4789 self.vapi.nat44_forwarding_enable_disable(1)
4790 self.nat44_add_address(self.nat_addr)
4791 self.nat44_add_static_mapping(self.pg1.remote_ip4, external_addr,
4792 local_port, external_port,
4793 proto=IP_PROTOS.tcp, out2in_only=1)
4794 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
4795 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index,
4797 self.vapi.nat44_interface_add_del_output_feature(self.pg1.sw_if_index,
4800 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
4801 IP(src=self.pg0.remote_ip4, dst=external_addr) /
4802 TCP(sport=12345, dport=external_port))
4803 self.pg0.add_stream(p)
4804 self.pg_enable_capture(self.pg_interfaces)
4806 capture = self.pg1.get_capture(1)
4811 self.assertEqual(ip.src, self.pg0.remote_ip4)
4812 self.assertEqual(tcp.sport, 12345)
4813 self.assertEqual(ip.dst, self.pg1.remote_ip4)
4814 self.assertEqual(tcp.dport, local_port)
4815 self.assert_packet_checksums_valid(p)
4817 self.logger.error(ppp("Unexpected or invalid packet:", p))
4820 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
4821 IP(src=self.pg1.remote_ip4, dst=self.pg0.remote_ip4) /
4822 TCP(sport=local_port, dport=12345))
4823 self.pg1.add_stream(p)
4824 self.pg_enable_capture(self.pg_interfaces)
4826 capture = self.pg0.get_capture(1)
4831 self.assertEqual(ip.src, external_addr)
4832 self.assertEqual(tcp.sport, external_port)
4833 self.assertEqual(ip.dst, self.pg0.remote_ip4)
4834 self.assertEqual(tcp.dport, 12345)
4835 self.assert_packet_checksums_valid(p)
4837 self.logger.error(ppp("Unexpected or invalid packet:", p))
4840 def test_next_src_nat(self):
4841 """ On way back forward packet to nat44-in2out node. """
4842 twice_nat_addr = '10.0.1.3'
4845 post_twice_nat_port = 0
4847 self.vapi.nat44_forwarding_enable_disable(1)
4848 self.nat44_add_address(twice_nat_addr, twice_nat=1)
4849 self.nat44_add_static_mapping(self.pg6.remote_ip4, self.pg1.remote_ip4,
4850 local_port, external_port,
4851 proto=IP_PROTOS.tcp, out2in_only=1,
4852 self_twice_nat=1, vrf_id=1)
4853 self.vapi.nat44_interface_add_del_feature(self.pg6.sw_if_index,
4856 p = (Ether(src=self.pg6.remote_mac, dst=self.pg6.local_mac) /
4857 IP(src=self.pg6.remote_ip4, dst=self.pg1.remote_ip4) /
4858 TCP(sport=12345, dport=external_port))
4859 self.pg6.add_stream(p)
4860 self.pg_enable_capture(self.pg_interfaces)
4862 capture = self.pg6.get_capture(1)
4867 self.assertEqual(ip.src, twice_nat_addr)
4868 self.assertNotEqual(tcp.sport, 12345)
4869 post_twice_nat_port = tcp.sport
4870 self.assertEqual(ip.dst, self.pg6.remote_ip4)
4871 self.assertEqual(tcp.dport, local_port)
4872 self.assert_packet_checksums_valid(p)
4874 self.logger.error(ppp("Unexpected or invalid packet:", p))
4877 p = (Ether(src=self.pg6.remote_mac, dst=self.pg6.local_mac) /
4878 IP(src=self.pg6.remote_ip4, dst=twice_nat_addr) /
4879 TCP(sport=local_port, dport=post_twice_nat_port))
4880 self.pg6.add_stream(p)
4881 self.pg_enable_capture(self.pg_interfaces)
4883 capture = self.pg6.get_capture(1)
4888 self.assertEqual(ip.src, self.pg1.remote_ip4)
4889 self.assertEqual(tcp.sport, external_port)
4890 self.assertEqual(ip.dst, self.pg6.remote_ip4)
4891 self.assertEqual(tcp.dport, 12345)
4892 self.assert_packet_checksums_valid(p)
4894 self.logger.error(ppp("Unexpected or invalid packet:", p))
4897 def twice_nat_common(self, self_twice_nat=False, same_pg=False, lb=False,
4899 twice_nat_addr = '10.0.1.3'
4907 port_in1 = port_in+1
4908 port_in2 = port_in+2
4913 server1 = self.pg0.remote_hosts[0]
4914 server2 = self.pg0.remote_hosts[1]
4926 eh_translate = ((not self_twice_nat) or (not lb and same_pg) or
4929 self.nat44_add_address(self.nat_addr)
4930 self.nat44_add_address(twice_nat_addr, twice_nat=1)
4932 self.nat44_add_static_mapping(pg0.remote_ip4, self.nat_addr,
4934 proto=IP_PROTOS.tcp,
4935 twice_nat=int(not self_twice_nat),
4936 self_twice_nat=int(self_twice_nat))
4938 locals = [{'addr': server1.ip4n,
4942 {'addr': server2.ip4n,
4946 out_addr_n = socket.inet_pton(socket.AF_INET, self.nat_addr)
4947 self.vapi.nat44_add_del_lb_static_mapping(out_addr_n,
4951 not self_twice_nat),
4954 local_num=len(locals),
4956 self.vapi.nat44_interface_add_del_feature(pg0.sw_if_index)
4957 self.vapi.nat44_interface_add_del_feature(pg1.sw_if_index,
4964 assert client_id is not None
4966 client = self.pg0.remote_hosts[0]
4967 elif client_id == 2:
4968 client = self.pg0.remote_hosts[1]
4970 client = pg1.remote_hosts[0]
4971 p = (Ether(src=pg1.remote_mac, dst=pg1.local_mac) /
4972 IP(src=client.ip4, dst=self.nat_addr) /
4973 TCP(sport=eh_port_out, dport=port_out))
4975 self.pg_enable_capture(self.pg_interfaces)
4977 capture = pg0.get_capture(1)
4983 if ip.dst == server1.ip4:
4989 self.assertEqual(ip.dst, server.ip4)
4991 self.assertIn(tcp.dport, [port_in1, port_in2])
4993 self.assertEqual(tcp.dport, port_in)
4995 self.assertEqual(ip.src, twice_nat_addr)
4996 self.assertNotEqual(tcp.sport, eh_port_out)
4998 self.assertEqual(ip.src, client.ip4)
4999 self.assertEqual(tcp.sport, eh_port_out)
5001 eh_port_in = tcp.sport
5002 saved_port_in = tcp.dport
5003 self.assert_packet_checksums_valid(p)
5005 self.logger.error(ppp("Unexpected or invalid packet:", p))
5008 p = (Ether(src=server.mac, dst=pg0.local_mac) /
5009 IP(src=server.ip4, dst=eh_addr_in) /
5010 TCP(sport=saved_port_in, dport=eh_port_in))
5012 self.pg_enable_capture(self.pg_interfaces)
5014 capture = pg1.get_capture(1)
5019 self.assertEqual(ip.dst, client.ip4)
5020 self.assertEqual(ip.src, self.nat_addr)
5021 self.assertEqual(tcp.dport, eh_port_out)
5022 self.assertEqual(tcp.sport, port_out)
5023 self.assert_packet_checksums_valid(p)
5025 self.logger.error(ppp("Unexpected or invalid packet:", p))
5029 sessions = self.vapi.nat44_user_session_dump(server.ip4n, 0)
5030 self.assertEqual(len(sessions), 1)
5031 self.assertTrue(sessions[0].ext_host_valid)
5032 self.assertTrue(sessions[0].is_twicenat)
5033 self.vapi.nat44_del_session(
5034 sessions[0].inside_ip_address,
5035 sessions[0].inside_port,
5036 sessions[0].protocol,
5037 ext_host_address=sessions[0].ext_host_nat_address,
5038 ext_host_port=sessions[0].ext_host_nat_port)
5039 sessions = self.vapi.nat44_user_session_dump(server.ip4n, 0)
5040 self.assertEqual(len(sessions), 0)
5042 def test_twice_nat(self):
5044 self.twice_nat_common()
5046 def test_self_twice_nat_positive(self):
5047 """ Self Twice NAT44 (positive test) """
5048 self.twice_nat_common(self_twice_nat=True, same_pg=True)
5050 def test_self_twice_nat_negative(self):
5051 """ Self Twice NAT44 (negative test) """
5052 self.twice_nat_common(self_twice_nat=True)
5054 def test_twice_nat_lb(self):
5055 """ Twice NAT44 local service load balancing """
5056 self.twice_nat_common(lb=True)
5058 def test_self_twice_nat_lb_positive(self):
5059 """ Self Twice NAT44 local service load balancing (positive test) """
5060 self.twice_nat_common(lb=True, self_twice_nat=True, same_pg=True,
5063 def test_self_twice_nat_lb_negative(self):
5064 """ Self Twice NAT44 local service load balancing (negative test) """
5065 self.twice_nat_common(lb=True, self_twice_nat=True, same_pg=True,
5068 def test_twice_nat_interface_addr(self):
5069 """ Acquire twice NAT44 addresses from interface """
5070 self.vapi.nat44_add_interface_addr(self.pg3.sw_if_index, twice_nat=1)
5072 # no address in NAT pool
5073 adresses = self.vapi.nat44_address_dump()
5074 self.assertEqual(0, len(adresses))
5076 # configure interface address and check NAT address pool
5077 self.pg3.config_ip4()
5078 adresses = self.vapi.nat44_address_dump()
5079 self.assertEqual(1, len(adresses))
5080 self.assertEqual(adresses[0].ip_address[0:4], self.pg3.local_ip4n)
5081 self.assertEqual(adresses[0].twice_nat, 1)
5083 # remove interface address and check NAT address pool
5084 self.pg3.unconfig_ip4()
5085 adresses = self.vapi.nat44_address_dump()
5086 self.assertEqual(0, len(adresses))
5088 def test_tcp_close(self):
5089 """ Close TCP session from inside network - output feature """
5090 self.vapi.nat44_forwarding_enable_disable(1)
5091 self.nat44_add_address(self.pg1.local_ip4)
5092 twice_nat_addr = '10.0.1.3'
5093 service_ip = '192.168.16.150'
5094 self.nat44_add_address(twice_nat_addr, twice_nat=1)
5095 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
5096 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index,
5098 self.vapi.nat44_interface_add_del_output_feature(self.pg1.sw_if_index,
5100 self.nat44_add_static_mapping(self.pg0.remote_ip4,
5104 proto=IP_PROTOS.tcp,
5107 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4n, 0)
5108 start_sessnum = len(sessions)
5110 # SYN packet out->in
5111 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
5112 IP(src=self.pg1.remote_ip4, dst=service_ip) /
5113 TCP(sport=33898, dport=80, flags="S"))
5114 self.pg1.add_stream(p)
5115 self.pg_enable_capture(self.pg_interfaces)
5117 capture = self.pg0.get_capture(1)
5119 tcp_port = p[TCP].sport
5121 # SYN + ACK packet in->out
5122 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5123 IP(src=self.pg0.remote_ip4, dst=twice_nat_addr) /
5124 TCP(sport=80, dport=tcp_port, flags="SA"))
5125 self.pg0.add_stream(p)
5126 self.pg_enable_capture(self.pg_interfaces)
5128 self.pg1.get_capture(1)
5130 # ACK packet out->in
5131 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
5132 IP(src=self.pg1.remote_ip4, dst=service_ip) /
5133 TCP(sport=33898, dport=80, flags="A"))
5134 self.pg1.add_stream(p)
5135 self.pg_enable_capture(self.pg_interfaces)
5137 self.pg0.get_capture(1)
5139 # FIN 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="FA", seq=100, ack=300))
5143 self.pg0.add_stream(p)
5144 self.pg_enable_capture(self.pg_interfaces)
5146 self.pg1.get_capture(1)
5148 # FIN+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="FA", seq=300, ack=101))
5152 self.pg1.add_stream(p)
5153 self.pg_enable_capture(self.pg_interfaces)
5155 self.pg0.get_capture(1)
5157 # ACK 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="A", seq=101, ack=301))
5161 self.pg0.add_stream(p)
5162 self.pg_enable_capture(self.pg_interfaces)
5164 self.pg1.get_capture(1)
5166 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4n,
5168 self.assertEqual(len(sessions) - start_sessnum, 0)
5170 def test_tcp_session_close_in(self):
5171 """ Close TCP session from inside network """
5172 self.tcp_port_out = 10505
5173 self.nat44_add_address(self.nat_addr)
5174 self.nat44_add_static_mapping(self.pg0.remote_ip4,
5178 proto=IP_PROTOS.tcp,
5180 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
5181 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
5184 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4n, 0)
5185 start_sessnum = len(sessions)
5187 self.initiate_tcp_session(self.pg0, self.pg1)
5189 # FIN packet in -> out
5190 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5191 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
5192 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
5193 flags="FA", seq=100, ack=300))
5194 self.pg0.add_stream(p)
5195 self.pg_enable_capture(self.pg_interfaces)
5197 self.pg1.get_capture(1)
5201 # ACK packet out -> in
5202 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
5203 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
5204 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
5205 flags="A", seq=300, ack=101))
5208 # FIN packet out -> in
5209 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
5210 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
5211 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
5212 flags="FA", seq=300, ack=101))
5215 self.pg1.add_stream(pkts)
5216 self.pg_enable_capture(self.pg_interfaces)
5218 self.pg0.get_capture(2)
5220 # ACK packet in -> out
5221 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5222 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
5223 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
5224 flags="A", seq=101, ack=301))
5225 self.pg0.add_stream(p)
5226 self.pg_enable_capture(self.pg_interfaces)
5228 self.pg1.get_capture(1)
5230 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4n,
5232 self.assertEqual(len(sessions) - start_sessnum, 0)
5234 def test_tcp_session_close_out(self):
5235 """ Close TCP session from outside network """
5236 self.tcp_port_out = 10505
5237 self.nat44_add_address(self.nat_addr)
5238 self.nat44_add_static_mapping(self.pg0.remote_ip4,
5242 proto=IP_PROTOS.tcp,
5244 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
5245 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
5248 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4n, 0)
5249 start_sessnum = len(sessions)
5251 self.initiate_tcp_session(self.pg0, self.pg1)
5253 # FIN packet out -> in
5254 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
5255 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
5256 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
5257 flags="FA", seq=100, ack=300))
5258 self.pg1.add_stream(p)
5259 self.pg_enable_capture(self.pg_interfaces)
5261 self.pg0.get_capture(1)
5263 # FIN+ACK packet in -> out
5264 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5265 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
5266 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
5267 flags="FA", seq=300, ack=101))
5269 self.pg0.add_stream(p)
5270 self.pg_enable_capture(self.pg_interfaces)
5272 self.pg1.get_capture(1)
5274 # ACK packet out -> in
5275 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
5276 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
5277 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
5278 flags="A", seq=101, ack=301))
5279 self.pg1.add_stream(p)
5280 self.pg_enable_capture(self.pg_interfaces)
5282 self.pg0.get_capture(1)
5284 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4n,
5286 self.assertEqual(len(sessions) - start_sessnum, 0)
5288 def test_tcp_session_close_simultaneous(self):
5289 """ Close TCP session from inside network """
5290 self.tcp_port_out = 10505
5291 self.nat44_add_address(self.nat_addr)
5292 self.nat44_add_static_mapping(self.pg0.remote_ip4,
5296 proto=IP_PROTOS.tcp,
5298 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
5299 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
5302 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4n, 0)
5303 start_sessnum = len(sessions)
5305 self.initiate_tcp_session(self.pg0, self.pg1)
5307 # FIN packet in -> out
5308 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5309 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
5310 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
5311 flags="FA", seq=100, ack=300))
5312 self.pg0.add_stream(p)
5313 self.pg_enable_capture(self.pg_interfaces)
5315 self.pg1.get_capture(1)
5317 # FIN packet out -> in
5318 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
5319 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
5320 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
5321 flags="FA", seq=300, ack=100))
5322 self.pg1.add_stream(p)
5323 self.pg_enable_capture(self.pg_interfaces)
5325 self.pg0.get_capture(1)
5327 # ACK packet in -> out
5328 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5329 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
5330 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
5331 flags="A", seq=101, ack=301))
5332 self.pg0.add_stream(p)
5333 self.pg_enable_capture(self.pg_interfaces)
5335 self.pg1.get_capture(1)
5337 # ACK packet out -> in
5338 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
5339 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
5340 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
5341 flags="A", seq=301, ack=101))
5342 self.pg1.add_stream(p)
5343 self.pg_enable_capture(self.pg_interfaces)
5345 self.pg0.get_capture(1)
5347 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4n,
5349 self.assertEqual(len(sessions) - start_sessnum, 0)
5351 def test_one_armed_nat44_static(self):
5352 """ One armed NAT44 and 1:1 NAPT asymmetrical rule """
5353 remote_host = self.pg4.remote_hosts[0]
5354 local_host = self.pg4.remote_hosts[1]
5359 self.vapi.nat44_forwarding_enable_disable(1)
5360 self.nat44_add_address(self.nat_addr, twice_nat=1)
5361 self.nat44_add_static_mapping(local_host.ip4, self.nat_addr,
5362 local_port, external_port,
5363 proto=IP_PROTOS.tcp, out2in_only=1,
5365 self.vapi.nat44_interface_add_del_feature(self.pg4.sw_if_index)
5366 self.vapi.nat44_interface_add_del_feature(self.pg4.sw_if_index,
5369 # from client to service
5370 p = (Ether(src=self.pg4.remote_mac, dst=self.pg4.local_mac) /
5371 IP(src=remote_host.ip4, dst=self.nat_addr) /
5372 TCP(sport=12345, dport=external_port))
5373 self.pg4.add_stream(p)
5374 self.pg_enable_capture(self.pg_interfaces)
5376 capture = self.pg4.get_capture(1)
5381 self.assertEqual(ip.dst, local_host.ip4)
5382 self.assertEqual(ip.src, self.nat_addr)
5383 self.assertEqual(tcp.dport, local_port)
5384 self.assertNotEqual(tcp.sport, 12345)
5385 eh_port_in = tcp.sport
5386 self.assert_packet_checksums_valid(p)
5388 self.logger.error(ppp("Unexpected or invalid packet:", p))
5391 # from service back to client
5392 p = (Ether(src=self.pg4.remote_mac, dst=self.pg4.local_mac) /
5393 IP(src=local_host.ip4, dst=self.nat_addr) /
5394 TCP(sport=local_port, dport=eh_port_in))
5395 self.pg4.add_stream(p)
5396 self.pg_enable_capture(self.pg_interfaces)
5398 capture = self.pg4.get_capture(1)
5403 self.assertEqual(ip.src, self.nat_addr)
5404 self.assertEqual(ip.dst, remote_host.ip4)
5405 self.assertEqual(tcp.sport, external_port)
5406 self.assertEqual(tcp.dport, 12345)
5407 self.assert_packet_checksums_valid(p)
5409 self.logger.error(ppp("Unexpected or invalid packet:", p))
5412 def test_static_with_port_out2(self):
5413 """ 1:1 NAPT asymmetrical rule """
5418 self.vapi.nat44_forwarding_enable_disable(1)
5419 self.nat44_add_static_mapping(self.pg0.remote_ip4, self.nat_addr,
5420 local_port, external_port,
5421 proto=IP_PROTOS.tcp, out2in_only=1)
5422 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
5423 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
5426 # from client to service
5427 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
5428 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
5429 TCP(sport=12345, dport=external_port))
5430 self.pg1.add_stream(p)
5431 self.pg_enable_capture(self.pg_interfaces)
5433 capture = self.pg0.get_capture(1)
5438 self.assertEqual(ip.dst, self.pg0.remote_ip4)
5439 self.assertEqual(tcp.dport, local_port)
5440 self.assert_packet_checksums_valid(p)
5442 self.logger.error(ppp("Unexpected or invalid packet:", p))
5446 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
5447 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
5448 ICMP(type=11) / capture[0][IP])
5449 self.pg0.add_stream(p)
5450 self.pg_enable_capture(self.pg_interfaces)
5452 capture = self.pg1.get_capture(1)
5455 self.assertEqual(p[IP].src, self.nat_addr)
5457 self.assertEqual(inner.dst, self.nat_addr)
5458 self.assertEqual(inner[TCPerror].dport, external_port)
5460 self.logger.error(ppp("Unexpected or invalid packet:", p))
5463 # from service back to client
5464 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5465 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
5466 TCP(sport=local_port, dport=12345))
5467 self.pg0.add_stream(p)
5468 self.pg_enable_capture(self.pg_interfaces)
5470 capture = self.pg1.get_capture(1)
5475 self.assertEqual(ip.src, self.nat_addr)
5476 self.assertEqual(tcp.sport, external_port)
5477 self.assert_packet_checksums_valid(p)
5479 self.logger.error(ppp("Unexpected or invalid packet:", p))
5483 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
5484 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
5485 ICMP(type=11) / capture[0][IP])
5486 self.pg1.add_stream(p)
5487 self.pg_enable_capture(self.pg_interfaces)
5489 capture = self.pg0.get_capture(1)
5492 self.assertEqual(p[IP].dst, self.pg0.remote_ip4)
5494 self.assertEqual(inner.src, self.pg0.remote_ip4)
5495 self.assertEqual(inner[TCPerror].sport, local_port)
5497 self.logger.error(ppp("Unexpected or invalid packet:", p))
5500 # from client to server (no translation)
5501 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
5502 IP(src=self.pg1.remote_ip4, dst=self.pg0.remote_ip4) /
5503 TCP(sport=12346, dport=local_port))
5504 self.pg1.add_stream(p)
5505 self.pg_enable_capture(self.pg_interfaces)
5507 capture = self.pg0.get_capture(1)
5512 self.assertEqual(ip.dst, self.pg0.remote_ip4)
5513 self.assertEqual(tcp.dport, local_port)
5514 self.assert_packet_checksums_valid(p)
5516 self.logger.error(ppp("Unexpected or invalid packet:", p))
5519 # from service back to client (no translation)
5520 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5521 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
5522 TCP(sport=local_port, dport=12346))
5523 self.pg0.add_stream(p)
5524 self.pg_enable_capture(self.pg_interfaces)
5526 capture = self.pg1.get_capture(1)
5531 self.assertEqual(ip.src, self.pg0.remote_ip4)
5532 self.assertEqual(tcp.sport, local_port)
5533 self.assert_packet_checksums_valid(p)
5535 self.logger.error(ppp("Unexpected or invalid packet:", p))
5538 def test_output_feature(self):
5539 """ NAT44 interface output feature (in2out postrouting) """
5540 self.vapi.nat44_forwarding_enable_disable(1)
5541 self.nat44_add_address(self.nat_addr)
5542 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index,
5544 self.vapi.nat44_interface_add_del_output_feature(self.pg1.sw_if_index,
5548 pkts = self.create_stream_in(self.pg0, self.pg1)
5549 self.pg0.add_stream(pkts)
5550 self.pg_enable_capture(self.pg_interfaces)
5552 capture = self.pg1.get_capture(len(pkts))
5553 self.verify_capture_out(capture)
5556 pkts = self.create_stream_out(self.pg1)
5557 self.pg1.add_stream(pkts)
5558 self.pg_enable_capture(self.pg_interfaces)
5560 capture = self.pg0.get_capture(len(pkts))
5561 self.verify_capture_in(capture, self.pg0)
5563 def test_multiple_vrf(self):
5564 """ Multiple VRF setup """
5565 external_addr = '1.2.3.4'
5570 self.vapi.nat44_forwarding_enable_disable(1)
5571 self.nat44_add_address(self.nat_addr)
5572 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
5573 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index,
5575 self.vapi.nat44_interface_add_del_output_feature(self.pg1.sw_if_index,
5577 self.vapi.nat44_interface_add_del_feature(self.pg5.sw_if_index)
5578 self.vapi.nat44_interface_add_del_feature(self.pg5.sw_if_index,
5580 self.vapi.nat44_interface_add_del_feature(self.pg6.sw_if_index,
5582 self.nat44_add_static_mapping(self.pg5.remote_ip4, external_addr,
5583 local_port, external_port, vrf_id=1,
5584 proto=IP_PROTOS.tcp, out2in_only=1)
5585 self.nat44_add_static_mapping(
5586 self.pg0.remote_ip4, external_sw_if_index=self.pg0.sw_if_index,
5587 local_port=local_port, vrf_id=0, external_port=external_port,
5588 proto=IP_PROTOS.tcp, out2in_only=1)
5590 # from client to service (both VRF1)
5591 p = (Ether(src=self.pg6.remote_mac, dst=self.pg6.local_mac) /
5592 IP(src=self.pg6.remote_ip4, dst=external_addr) /
5593 TCP(sport=12345, dport=external_port))
5594 self.pg6.add_stream(p)
5595 self.pg_enable_capture(self.pg_interfaces)
5597 capture = self.pg5.get_capture(1)
5602 self.assertEqual(ip.dst, self.pg5.remote_ip4)
5603 self.assertEqual(tcp.dport, local_port)
5604 self.assert_packet_checksums_valid(p)
5606 self.logger.error(ppp("Unexpected or invalid packet:", p))
5609 # from service back to client (both VRF1)
5610 p = (Ether(src=self.pg5.remote_mac, dst=self.pg5.local_mac) /
5611 IP(src=self.pg5.remote_ip4, dst=self.pg6.remote_ip4) /
5612 TCP(sport=local_port, dport=12345))
5613 self.pg5.add_stream(p)
5614 self.pg_enable_capture(self.pg_interfaces)
5616 capture = self.pg6.get_capture(1)
5621 self.assertEqual(ip.src, external_addr)
5622 self.assertEqual(tcp.sport, external_port)
5623 self.assert_packet_checksums_valid(p)
5625 self.logger.error(ppp("Unexpected or invalid packet:", p))
5628 # dynamic NAT from VRF1 to VRF0 (output-feature)
5629 p = (Ether(src=self.pg5.remote_mac, dst=self.pg5.local_mac) /
5630 IP(src=self.pg5.remote_ip4, dst=self.pg1.remote_ip4) /
5631 TCP(sport=2345, dport=22))
5632 self.pg5.add_stream(p)
5633 self.pg_enable_capture(self.pg_interfaces)
5635 capture = self.pg1.get_capture(1)
5640 self.assertEqual(ip.src, self.nat_addr)
5641 self.assertNotEqual(tcp.sport, 2345)
5642 self.assert_packet_checksums_valid(p)
5645 self.logger.error(ppp("Unexpected or invalid packet:", p))
5648 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
5649 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
5650 TCP(sport=22, dport=port))
5651 self.pg1.add_stream(p)
5652 self.pg_enable_capture(self.pg_interfaces)
5654 capture = self.pg5.get_capture(1)
5659 self.assertEqual(ip.dst, self.pg5.remote_ip4)
5660 self.assertEqual(tcp.dport, 2345)
5661 self.assert_packet_checksums_valid(p)
5663 self.logger.error(ppp("Unexpected or invalid packet:", p))
5666 # from client VRF1 to service VRF0
5667 p = (Ether(src=self.pg6.remote_mac, dst=self.pg6.local_mac) /
5668 IP(src=self.pg6.remote_ip4, dst=self.pg0.local_ip4) /
5669 TCP(sport=12346, dport=external_port))
5670 self.pg6.add_stream(p)
5671 self.pg_enable_capture(self.pg_interfaces)
5673 capture = self.pg0.get_capture(1)
5678 self.assertEqual(ip.dst, self.pg0.remote_ip4)
5679 self.assertEqual(tcp.dport, local_port)
5680 self.assert_packet_checksums_valid(p)
5682 self.logger.error(ppp("Unexpected or invalid packet:", p))
5685 # from service VRF0 back to client VRF1
5686 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5687 IP(src=self.pg0.remote_ip4, dst=self.pg6.remote_ip4) /
5688 TCP(sport=local_port, dport=12346))
5689 self.pg0.add_stream(p)
5690 self.pg_enable_capture(self.pg_interfaces)
5692 capture = self.pg6.get_capture(1)
5697 self.assertEqual(ip.src, self.pg0.local_ip4)
5698 self.assertEqual(tcp.sport, external_port)
5699 self.assert_packet_checksums_valid(p)
5701 self.logger.error(ppp("Unexpected or invalid packet:", p))
5704 # from client VRF0 to service VRF1
5705 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5706 IP(src=self.pg0.remote_ip4, dst=external_addr) /
5707 TCP(sport=12347, dport=external_port))
5708 self.pg0.add_stream(p)
5709 self.pg_enable_capture(self.pg_interfaces)
5711 capture = self.pg5.get_capture(1)
5716 self.assertEqual(ip.dst, self.pg5.remote_ip4)
5717 self.assertEqual(tcp.dport, local_port)
5718 self.assert_packet_checksums_valid(p)
5720 self.logger.error(ppp("Unexpected or invalid packet:", p))
5723 # from service VRF1 back to client VRF0
5724 p = (Ether(src=self.pg5.remote_mac, dst=self.pg5.local_mac) /
5725 IP(src=self.pg5.remote_ip4, dst=self.pg0.remote_ip4) /
5726 TCP(sport=local_port, dport=12347))
5727 self.pg5.add_stream(p)
5728 self.pg_enable_capture(self.pg_interfaces)
5730 capture = self.pg0.get_capture(1)
5735 self.assertEqual(ip.src, external_addr)
5736 self.assertEqual(tcp.sport, external_port)
5737 self.assert_packet_checksums_valid(p)
5739 self.logger.error(ppp("Unexpected or invalid packet:", p))
5742 # from client to server (both VRF1, no translation)
5743 p = (Ether(src=self.pg6.remote_mac, dst=self.pg6.local_mac) /
5744 IP(src=self.pg6.remote_ip4, dst=self.pg5.remote_ip4) /
5745 TCP(sport=12348, dport=local_port))
5746 self.pg6.add_stream(p)
5747 self.pg_enable_capture(self.pg_interfaces)
5749 capture = self.pg5.get_capture(1)
5754 self.assertEqual(ip.dst, self.pg5.remote_ip4)
5755 self.assertEqual(tcp.dport, local_port)
5756 self.assert_packet_checksums_valid(p)
5758 self.logger.error(ppp("Unexpected or invalid packet:", p))
5761 # from server back to client (both VRF1, no translation)
5762 p = (Ether(src=self.pg5.remote_mac, dst=self.pg5.local_mac) /
5763 IP(src=self.pg5.remote_ip4, dst=self.pg6.remote_ip4) /
5764 TCP(sport=local_port, dport=12348))
5765 self.pg5.add_stream(p)
5766 self.pg_enable_capture(self.pg_interfaces)
5768 capture = self.pg6.get_capture(1)
5773 self.assertEqual(ip.src, self.pg5.remote_ip4)
5774 self.assertEqual(tcp.sport, local_port)
5775 self.assert_packet_checksums_valid(p)
5777 self.logger.error(ppp("Unexpected or invalid packet:", p))
5780 # from client VRF1 to server VRF0 (no translation)
5781 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5782 IP(src=self.pg0.remote_ip4, dst=self.pg6.remote_ip4) /
5783 TCP(sport=local_port, dport=12349))
5784 self.pg0.add_stream(p)
5785 self.pg_enable_capture(self.pg_interfaces)
5787 capture = self.pg6.get_capture(1)
5792 self.assertEqual(ip.src, self.pg0.remote_ip4)
5793 self.assertEqual(tcp.sport, local_port)
5794 self.assert_packet_checksums_valid(p)
5796 self.logger.error(ppp("Unexpected or invalid packet:", p))
5799 # from server VRF0 back to client VRF1 (no translation)
5800 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5801 IP(src=self.pg0.remote_ip4, dst=self.pg6.remote_ip4) /
5802 TCP(sport=local_port, dport=12349))
5803 self.pg0.add_stream(p)
5804 self.pg_enable_capture(self.pg_interfaces)
5806 capture = self.pg6.get_capture(1)
5811 self.assertEqual(ip.src, self.pg0.remote_ip4)
5812 self.assertEqual(tcp.sport, local_port)
5813 self.assert_packet_checksums_valid(p)
5815 self.logger.error(ppp("Unexpected or invalid packet:", p))
5818 # from client VRF0 to server VRF1 (no translation)
5819 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5820 IP(src=self.pg0.remote_ip4, dst=self.pg5.remote_ip4) /
5821 TCP(sport=12344, dport=local_port))
5822 self.pg0.add_stream(p)
5823 self.pg_enable_capture(self.pg_interfaces)
5825 capture = self.pg5.get_capture(1)
5830 self.assertEqual(ip.dst, self.pg5.remote_ip4)
5831 self.assertEqual(tcp.dport, local_port)
5832 self.assert_packet_checksums_valid(p)
5834 self.logger.error(ppp("Unexpected or invalid packet:", p))
5837 # from server VRF1 back to client VRF0 (no translation)
5838 p = (Ether(src=self.pg5.remote_mac, dst=self.pg5.local_mac) /
5839 IP(src=self.pg5.remote_ip4, dst=self.pg0.remote_ip4) /
5840 TCP(sport=local_port, dport=12344))
5841 self.pg5.add_stream(p)
5842 self.pg_enable_capture(self.pg_interfaces)
5844 capture = self.pg0.get_capture(1)
5849 self.assertEqual(ip.src, self.pg5.remote_ip4)
5850 self.assertEqual(tcp.sport, local_port)
5851 self.assert_packet_checksums_valid(p)
5853 self.logger.error(ppp("Unexpected or invalid packet:", p))
5856 @unittest.skipUnless(running_extended_tests(), "part of extended tests")
5857 def test_session_timeout(self):
5858 """ NAT44 session timeouts """
5859 self.nat44_add_address(self.nat_addr)
5860 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
5861 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
5863 self.vapi.nat_set_timeouts(icmp=5)
5867 for i in range(0, max_sessions):
5868 src = "10.10.%u.%u" % ((i & 0xFF00) >> 8, i & 0xFF)
5869 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
5870 IP(src=src, dst=self.pg1.remote_ip4) /
5871 ICMP(id=1025, type='echo-request'))
5873 self.pg0.add_stream(pkts)
5874 self.pg_enable_capture(self.pg_interfaces)
5876 self.pg1.get_capture(max_sessions)
5881 for i in range(0, max_sessions):
5882 src = "10.11.%u.%u" % ((i & 0xFF00) >> 8, i & 0xFF)
5883 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
5884 IP(src=src, dst=self.pg1.remote_ip4) /
5885 ICMP(id=1026, type='echo-request'))
5887 self.pg0.add_stream(pkts)
5888 self.pg_enable_capture(self.pg_interfaces)
5890 self.pg1.get_capture(max_sessions)
5893 users = self.vapi.nat44_user_dump()
5895 nsessions = nsessions + user.nsessions
5896 self.assertLess(nsessions, 2 * max_sessions)
5898 @unittest.skipUnless(running_extended_tests(), "part of extended tests")
5899 def test_session_rst_timeout(self):
5900 """ NAT44 session RST timeouts """
5901 self.nat44_add_address(self.nat_addr)
5902 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
5903 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
5905 self.vapi.nat_set_timeouts(tcp_transitory=5)
5907 self.initiate_tcp_session(self.pg0, self.pg1)
5908 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5909 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
5910 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
5912 self.pg0.add_stream(p)
5913 self.pg_enable_capture(self.pg_interfaces)
5915 self.pg1.get_capture(1)
5919 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5920 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
5921 TCP(sport=self.tcp_port_in + 1, dport=self.tcp_external_port + 1,
5923 self.pg0.add_stream(p)
5924 self.pg_enable_capture(self.pg_interfaces)
5926 self.pg1.get_capture(1)
5929 users = self.vapi.nat44_user_dump()
5930 self.assertEqual(len(users), 1)
5931 self.assertEqual(users[0].ip_address, self.pg0.remote_ip4n)
5932 self.assertEqual(users[0].nsessions, 1)
5934 @unittest.skipUnless(running_extended_tests(), "part of extended tests")
5935 def test_session_limit_per_user(self):
5936 """ Maximum sessions per user limit """
5937 self.nat44_add_address(self.nat_addr)
5938 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
5939 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
5941 self.vapi.set_ipfix_exporter(collector_address=self.pg2.remote_ip4n,
5942 src_address=self.pg2.local_ip4n,
5944 template_interval=10)
5945 self.vapi.nat_set_timeouts(udp=5)
5947 # get maximum number of translations per user
5948 nat44_config = self.vapi.nat_show_config()
5951 for port in range(0, nat44_config.max_translations_per_user):
5952 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5953 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
5954 UDP(sport=1025 + port, dport=1025 + port))
5957 self.pg0.add_stream(pkts)
5958 self.pg_enable_capture(self.pg_interfaces)
5960 capture = self.pg1.get_capture(len(pkts))
5962 self.vapi.nat_ipfix(domain_id=self.ipfix_domain_id,
5963 src_port=self.ipfix_src_port)
5965 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5966 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
5967 UDP(sport=3001, dport=3002))
5968 self.pg0.add_stream(p)
5969 self.pg_enable_capture(self.pg_interfaces)
5971 capture = self.pg1.assert_nothing_captured()
5973 # verify IPFIX logging
5974 self.vapi.cli("ipfix flush") # FIXME this should be an API call
5976 capture = self.pg2.get_capture(10)
5977 ipfix = IPFIXDecoder()
5978 # first load template
5980 self.assertTrue(p.haslayer(IPFIX))
5981 if p.haslayer(Template):
5982 ipfix.add_template(p.getlayer(Template))
5983 # verify events in data set
5985 if p.haslayer(Data):
5986 data = ipfix.decode_data_set(p.getlayer(Set))
5987 self.verify_ipfix_max_entries_per_user(
5989 nat44_config.max_translations_per_user,
5990 self.pg0.remote_ip4n)
5993 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5994 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
5995 UDP(sport=3001, dport=3002))
5996 self.pg0.add_stream(p)
5997 self.pg_enable_capture(self.pg_interfaces)
5999 self.pg1.get_capture(1)
6001 def test_syslog_sess(self):
6002 """ Test syslog session creation and deletion """
6003 self.vapi.syslog_set_filter(SYSLOG_SEVERITY.INFO)
6004 self.vapi.syslog_set_sender(self.pg2.remote_ip4n, self.pg2.local_ip4n)
6005 self.nat44_add_address(self.nat_addr)
6006 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
6007 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
6010 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
6011 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6012 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port))
6013 self.pg0.add_stream(p)
6014 self.pg_enable_capture(self.pg_interfaces)
6016 capture = self.pg1.get_capture(1)
6017 self.tcp_port_out = capture[0][TCP].sport
6018 capture = self.pg2.get_capture(1)
6019 self.verify_syslog_sess(capture[0][Raw].load)
6021 self.pg_enable_capture(self.pg_interfaces)
6023 self.nat44_add_address(self.nat_addr, is_add=0)
6024 capture = self.pg2.get_capture(1)
6025 self.verify_syslog_sess(capture[0][Raw].load, False)
6028 super(TestNAT44EndpointDependent, self).tearDown()
6029 if not self.vpp_dead:
6030 self.logger.info(self.vapi.cli("show nat44 addresses"))
6031 self.logger.info(self.vapi.cli("show nat44 interfaces"))
6032 self.logger.info(self.vapi.cli("show nat44 static mappings"))
6033 self.logger.info(self.vapi.cli("show nat44 interface address"))
6034 self.logger.info(self.vapi.cli("show nat44 sessions detail"))
6035 self.logger.info(self.vapi.cli("show nat44 hash tables detail"))
6036 self.logger.info(self.vapi.cli("show nat timeouts"))
6038 self.vapi.cli("clear logging")
6041 class TestNAT44Out2InDPO(MethodHolder):
6042 """ NAT44 Test Cases using out2in DPO """
6045 def setUpConstants(cls):
6046 super(TestNAT44Out2InDPO, cls).setUpConstants()
6047 cls.vpp_cmdline.extend(["nat", "{", "out2in dpo", "}"])
6050 def setUpClass(cls):
6051 super(TestNAT44Out2InDPO, cls).setUpClass()
6052 cls.vapi.cli("set log class nat level debug")
6055 cls.tcp_port_in = 6303
6056 cls.tcp_port_out = 6303
6057 cls.udp_port_in = 6304
6058 cls.udp_port_out = 6304
6059 cls.icmp_id_in = 6305
6060 cls.icmp_id_out = 6305
6061 cls.nat_addr = '10.0.0.3'
6062 cls.nat_addr_n = socket.inet_pton(socket.AF_INET, cls.nat_addr)
6063 cls.dst_ip4 = '192.168.70.1'
6065 cls.create_pg_interfaces(range(2))
6068 cls.pg0.config_ip4()
6069 cls.pg0.resolve_arp()
6072 cls.pg1.config_ip6()
6073 cls.pg1.resolve_ndp()
6075 cls.vapi.ip_add_del_route(is_ipv6=True, dst_address='\x00'*16,
6076 dst_address_length=0,
6077 next_hop_address=cls.pg1.remote_ip6n,
6078 next_hop_sw_if_index=cls.pg1.sw_if_index)
6081 super(TestNAT44Out2InDPO, cls).tearDownClass()
6084 def configure_xlat(self):
6085 self.dst_ip6_pfx = '1:2:3::'
6086 self.dst_ip6_pfx_n = socket.inet_pton(socket.AF_INET6,
6088 self.dst_ip6_pfx_len = 96
6089 self.src_ip6_pfx = '4:5:6::'
6090 self.src_ip6_pfx_n = socket.inet_pton(socket.AF_INET6,
6092 self.src_ip6_pfx_len = 96
6093 self.vapi.map_add_domain(self.dst_ip6_pfx_n, self.dst_ip6_pfx_len,
6094 self.src_ip6_pfx_n, self.src_ip6_pfx_len,
6095 '\x00\x00\x00\x00', 0, is_translation=1,
6098 @unittest.skip('Temporary disabled')
6099 def test_464xlat_ce(self):
6100 """ Test 464XLAT CE with NAT44 """
6102 nat_config = self.vapi.nat_show_config()
6103 self.assertEqual(1, nat_config.out2in_dpo)
6105 self.configure_xlat()
6107 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
6108 self.vapi.nat44_add_del_address_range(self.nat_addr_n, self.nat_addr_n)
6110 out_src_ip6 = self.compose_ip6(self.dst_ip4, self.dst_ip6_pfx,
6111 self.dst_ip6_pfx_len)
6112 out_dst_ip6 = self.compose_ip6(self.nat_addr, self.src_ip6_pfx,
6113 self.src_ip6_pfx_len)
6116 pkts = self.create_stream_in(self.pg0, self.pg1, self.dst_ip4)
6117 self.pg0.add_stream(pkts)
6118 self.pg_enable_capture(self.pg_interfaces)
6120 capture = self.pg1.get_capture(len(pkts))
6121 self.verify_capture_out_ip6(capture, nat_ip=out_dst_ip6,
6124 pkts = self.create_stream_out_ip6(self.pg1, out_src_ip6,
6126 self.pg1.add_stream(pkts)
6127 self.pg_enable_capture(self.pg_interfaces)
6129 capture = self.pg0.get_capture(len(pkts))
6130 self.verify_capture_in(capture, self.pg0)
6132 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index,
6134 self.vapi.nat44_add_del_address_range(self.nat_addr_n,
6135 self.nat_addr_n, is_add=0)
6137 @unittest.skip('Temporary disabled')
6138 def test_464xlat_ce_no_nat(self):
6139 """ Test 464XLAT CE without NAT44 """
6141 self.configure_xlat()
6143 out_src_ip6 = self.compose_ip6(self.dst_ip4, self.dst_ip6_pfx,
6144 self.dst_ip6_pfx_len)
6145 out_dst_ip6 = self.compose_ip6(self.pg0.remote_ip4, self.src_ip6_pfx,
6146 self.src_ip6_pfx_len)
6148 pkts = self.create_stream_in(self.pg0, self.pg1, self.dst_ip4)
6149 self.pg0.add_stream(pkts)
6150 self.pg_enable_capture(self.pg_interfaces)
6152 capture = self.pg1.get_capture(len(pkts))
6153 self.verify_capture_out_ip6(capture, dst_ip=out_src_ip6,
6154 nat_ip=out_dst_ip6, same_port=True)
6156 pkts = self.create_stream_out_ip6(self.pg1, out_src_ip6, out_dst_ip6)
6157 self.pg1.add_stream(pkts)
6158 self.pg_enable_capture(self.pg_interfaces)
6160 capture = self.pg0.get_capture(len(pkts))
6161 self.verify_capture_in(capture, self.pg0)
6164 class TestDeterministicNAT(MethodHolder):
6165 """ Deterministic NAT Test Cases """
6168 def setUpConstants(cls):
6169 super(TestDeterministicNAT, cls).setUpConstants()
6170 cls.vpp_cmdline.extend(["nat", "{", "deterministic", "}"])
6173 def setUpClass(cls):
6174 super(TestDeterministicNAT, cls).setUpClass()
6175 cls.vapi.cli("set log class nat level debug")
6178 cls.tcp_port_in = 6303
6179 cls.tcp_external_port = 6303
6180 cls.udp_port_in = 6304
6181 cls.udp_external_port = 6304
6182 cls.icmp_id_in = 6305
6183 cls.nat_addr = '10.0.0.3'
6185 cls.create_pg_interfaces(range(3))
6186 cls.interfaces = list(cls.pg_interfaces)
6188 for i in cls.interfaces:
6193 cls.pg0.generate_remote_hosts(2)
6194 cls.pg0.configure_ipv4_neighbors()
6197 super(TestDeterministicNAT, cls).tearDownClass()
6200 def create_stream_in(self, in_if, out_if, ttl=64):
6202 Create packet stream for inside network
6204 :param in_if: Inside interface
6205 :param out_if: Outside interface
6206 :param ttl: TTL of generated packets
6210 p = (Ether(dst=in_if.local_mac, src=in_if.remote_mac) /
6211 IP(src=in_if.remote_ip4, dst=out_if.remote_ip4, ttl=ttl) /
6212 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port))
6216 p = (Ether(dst=in_if.local_mac, src=in_if.remote_mac) /
6217 IP(src=in_if.remote_ip4, dst=out_if.remote_ip4, ttl=ttl) /
6218 UDP(sport=self.udp_port_in, dport=self.udp_external_port))
6222 p = (Ether(dst=in_if.local_mac, src=in_if.remote_mac) /
6223 IP(src=in_if.remote_ip4, dst=out_if.remote_ip4, ttl=ttl) /
6224 ICMP(id=self.icmp_id_in, type='echo-request'))
6229 def create_stream_out(self, out_if, dst_ip=None, ttl=64):
6231 Create packet stream for outside network
6233 :param out_if: Outside interface
6234 :param dst_ip: Destination IP address (Default use global NAT address)
6235 :param ttl: TTL of generated packets
6238 dst_ip = self.nat_addr
6241 p = (Ether(dst=out_if.local_mac, src=out_if.remote_mac) /
6242 IP(src=out_if.remote_ip4, dst=dst_ip, ttl=ttl) /
6243 TCP(dport=self.tcp_port_out, sport=self.tcp_external_port))
6247 p = (Ether(dst=out_if.local_mac, src=out_if.remote_mac) /
6248 IP(src=out_if.remote_ip4, dst=dst_ip, ttl=ttl) /
6249 UDP(dport=self.udp_port_out, sport=self.udp_external_port))
6253 p = (Ether(dst=out_if.local_mac, src=out_if.remote_mac) /
6254 IP(src=out_if.remote_ip4, dst=dst_ip, ttl=ttl) /
6255 ICMP(id=self.icmp_external_id, type='echo-reply'))
6260 def verify_capture_out(self, capture, nat_ip=None):
6262 Verify captured packets on outside network
6264 :param capture: Captured packets
6265 :param nat_ip: Translated IP address (Default use global NAT address)
6266 :param same_port: Sorce port number is not translated (Default False)
6269 nat_ip = self.nat_addr
6270 for packet in capture:
6272 self.assertEqual(packet[IP].src, nat_ip)
6273 if packet.haslayer(TCP):
6274 self.tcp_port_out = packet[TCP].sport
6275 elif packet.haslayer(UDP):
6276 self.udp_port_out = packet[UDP].sport
6278 self.icmp_external_id = packet[ICMP].id
6280 self.logger.error(ppp("Unexpected or invalid packet "
6281 "(outside network):", packet))
6284 def test_deterministic_mode(self):
6285 """ NAT plugin run deterministic mode """
6286 in_addr = '172.16.255.0'
6287 out_addr = '172.17.255.50'
6288 in_addr_t = '172.16.255.20'
6289 in_addr_n = socket.inet_aton(in_addr)
6290 out_addr_n = socket.inet_aton(out_addr)
6291 in_addr_t_n = socket.inet_aton(in_addr_t)
6295 nat_config = self.vapi.nat_show_config()
6296 self.assertEqual(1, nat_config.deterministic)
6298 self.vapi.nat_det_add_del_map(in_addr_n, in_plen, out_addr_n, out_plen)
6300 rep1 = self.vapi.nat_det_forward(in_addr_t_n)
6301 self.assertEqual(rep1.out_addr[:4], out_addr_n)
6302 rep2 = self.vapi.nat_det_reverse(out_addr_n, rep1.out_port_hi)
6303 self.assertEqual(rep2.in_addr[:4], in_addr_t_n)
6305 deterministic_mappings = self.vapi.nat_det_map_dump()
6306 self.assertEqual(len(deterministic_mappings), 1)
6307 dsm = deterministic_mappings[0]
6308 self.assertEqual(in_addr_n, dsm.in_addr[:4])
6309 self.assertEqual(in_plen, dsm.in_plen)
6310 self.assertEqual(out_addr_n, dsm.out_addr[:4])
6311 self.assertEqual(out_plen, dsm.out_plen)
6313 self.clear_nat_det()
6314 deterministic_mappings = self.vapi.nat_det_map_dump()
6315 self.assertEqual(len(deterministic_mappings), 0)
6317 def test_set_timeouts(self):
6318 """ Set deterministic NAT timeouts """
6319 timeouts_before = self.vapi.nat_get_timeouts()
6321 self.vapi.nat_set_timeouts(timeouts_before.udp + 10,
6322 timeouts_before.tcp_established + 10,
6323 timeouts_before.tcp_transitory + 10,
6324 timeouts_before.icmp + 10)
6326 timeouts_after = self.vapi.nat_get_timeouts()
6328 self.assertNotEqual(timeouts_before.udp, timeouts_after.udp)
6329 self.assertNotEqual(timeouts_before.icmp, timeouts_after.icmp)
6330 self.assertNotEqual(timeouts_before.tcp_established,
6331 timeouts_after.tcp_established)
6332 self.assertNotEqual(timeouts_before.tcp_transitory,
6333 timeouts_after.tcp_transitory)
6335 def test_det_in(self):
6336 """ Deterministic NAT translation test (TCP, UDP, ICMP) """
6338 nat_ip = "10.0.0.10"
6340 self.vapi.nat_det_add_del_map(self.pg0.remote_ip4n,
6342 socket.inet_aton(nat_ip),
6344 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
6345 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
6349 pkts = self.create_stream_in(self.pg0, self.pg1)
6350 self.pg0.add_stream(pkts)
6351 self.pg_enable_capture(self.pg_interfaces)
6353 capture = self.pg1.get_capture(len(pkts))
6354 self.verify_capture_out(capture, nat_ip)
6357 pkts = self.create_stream_out(self.pg1, nat_ip)
6358 self.pg1.add_stream(pkts)
6359 self.pg_enable_capture(self.pg_interfaces)
6361 capture = self.pg0.get_capture(len(pkts))
6362 self.verify_capture_in(capture, self.pg0)
6365 sessions = self.vapi.nat_det_session_dump(self.pg0.remote_ip4n)
6366 self.assertEqual(len(sessions), 3)
6370 self.assertEqual(s.ext_addr[:4], self.pg1.remote_ip4n)
6371 self.assertEqual(s.in_port, self.tcp_port_in)
6372 self.assertEqual(s.out_port, self.tcp_port_out)
6373 self.assertEqual(s.ext_port, self.tcp_external_port)
6377 self.assertEqual(s.ext_addr[:4], self.pg1.remote_ip4n)
6378 self.assertEqual(s.in_port, self.udp_port_in)
6379 self.assertEqual(s.out_port, self.udp_port_out)
6380 self.assertEqual(s.ext_port, self.udp_external_port)
6384 self.assertEqual(s.ext_addr[:4], self.pg1.remote_ip4n)
6385 self.assertEqual(s.in_port, self.icmp_id_in)
6386 self.assertEqual(s.out_port, self.icmp_external_id)
6388 def test_multiple_users(self):
6389 """ Deterministic NAT multiple users """
6391 nat_ip = "10.0.0.10"
6393 external_port = 6303
6395 host0 = self.pg0.remote_hosts[0]
6396 host1 = self.pg0.remote_hosts[1]
6398 self.vapi.nat_det_add_del_map(host0.ip4n,
6400 socket.inet_aton(nat_ip),
6402 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
6403 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
6407 p = (Ether(src=host0.mac, dst=self.pg0.local_mac) /
6408 IP(src=host0.ip4, dst=self.pg1.remote_ip4) /
6409 TCP(sport=port_in, dport=external_port))
6410 self.pg0.add_stream(p)
6411 self.pg_enable_capture(self.pg_interfaces)
6413 capture = self.pg1.get_capture(1)
6418 self.assertEqual(ip.src, nat_ip)
6419 self.assertEqual(ip.dst, self.pg1.remote_ip4)
6420 self.assertEqual(tcp.dport, external_port)
6421 port_out0 = tcp.sport
6423 self.logger.error(ppp("Unexpected or invalid packet:", p))
6427 p = (Ether(src=host1.mac, dst=self.pg0.local_mac) /
6428 IP(src=host1.ip4, dst=self.pg1.remote_ip4) /
6429 TCP(sport=port_in, dport=external_port))
6430 self.pg0.add_stream(p)
6431 self.pg_enable_capture(self.pg_interfaces)
6433 capture = self.pg1.get_capture(1)
6438 self.assertEqual(ip.src, nat_ip)
6439 self.assertEqual(ip.dst, self.pg1.remote_ip4)
6440 self.assertEqual(tcp.dport, external_port)
6441 port_out1 = tcp.sport
6443 self.logger.error(ppp("Unexpected or invalid packet:", p))
6446 dms = self.vapi.nat_det_map_dump()
6447 self.assertEqual(1, len(dms))
6448 self.assertEqual(2, dms[0].ses_num)
6451 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
6452 IP(src=self.pg1.remote_ip4, dst=nat_ip) /
6453 TCP(sport=external_port, dport=port_out0))
6454 self.pg1.add_stream(p)
6455 self.pg_enable_capture(self.pg_interfaces)
6457 capture = self.pg0.get_capture(1)
6462 self.assertEqual(ip.src, self.pg1.remote_ip4)
6463 self.assertEqual(ip.dst, host0.ip4)
6464 self.assertEqual(tcp.dport, port_in)
6465 self.assertEqual(tcp.sport, external_port)
6467 self.logger.error(ppp("Unexpected or invalid packet:", p))
6471 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
6472 IP(src=self.pg1.remote_ip4, dst=nat_ip) /
6473 TCP(sport=external_port, dport=port_out1))
6474 self.pg1.add_stream(p)
6475 self.pg_enable_capture(self.pg_interfaces)
6477 capture = self.pg0.get_capture(1)
6482 self.assertEqual(ip.src, self.pg1.remote_ip4)
6483 self.assertEqual(ip.dst, host1.ip4)
6484 self.assertEqual(tcp.dport, port_in)
6485 self.assertEqual(tcp.sport, external_port)
6487 self.logger.error(ppp("Unexpected or invalid packet", p))
6490 # session close api test
6491 self.vapi.nat_det_close_session_out(socket.inet_aton(nat_ip),
6493 self.pg1.remote_ip4n,
6495 dms = self.vapi.nat_det_map_dump()
6496 self.assertEqual(dms[0].ses_num, 1)
6498 self.vapi.nat_det_close_session_in(host0.ip4n,
6500 self.pg1.remote_ip4n,
6502 dms = self.vapi.nat_det_map_dump()
6503 self.assertEqual(dms[0].ses_num, 0)
6505 def test_tcp_session_close_detection_in(self):
6506 """ Deterministic NAT TCP session close from inside network """
6507 self.vapi.nat_det_add_del_map(self.pg0.remote_ip4n,
6509 socket.inet_aton(self.nat_addr),
6511 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
6512 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
6515 self.initiate_tcp_session(self.pg0, self.pg1)
6517 # close the session from inside
6519 # FIN packet in -> out
6520 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6521 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6522 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
6524 self.pg0.add_stream(p)
6525 self.pg_enable_capture(self.pg_interfaces)
6527 self.pg1.get_capture(1)
6531 # ACK packet out -> in
6532 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
6533 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
6534 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
6538 # FIN packet out -> in
6539 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
6540 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
6541 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
6545 self.pg1.add_stream(pkts)
6546 self.pg_enable_capture(self.pg_interfaces)
6548 self.pg0.get_capture(2)
6550 # ACK packet in -> out
6551 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6552 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6553 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
6555 self.pg0.add_stream(p)
6556 self.pg_enable_capture(self.pg_interfaces)
6558 self.pg1.get_capture(1)
6560 # Check if deterministic NAT44 closed the session
6561 dms = self.vapi.nat_det_map_dump()
6562 self.assertEqual(0, dms[0].ses_num)
6564 self.logger.error("TCP session termination failed")
6567 def test_tcp_session_close_detection_out(self):
6568 """ Deterministic NAT TCP session close from outside network """
6569 self.vapi.nat_det_add_del_map(self.pg0.remote_ip4n,
6571 socket.inet_aton(self.nat_addr),
6573 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
6574 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
6577 self.initiate_tcp_session(self.pg0, self.pg1)
6579 # close the session from outside
6581 # FIN packet out -> in
6582 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
6583 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
6584 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
6586 self.pg1.add_stream(p)
6587 self.pg_enable_capture(self.pg_interfaces)
6589 self.pg0.get_capture(1)
6593 # ACK packet in -> out
6594 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6595 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6596 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
6600 # ACK packet in -> out
6601 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6602 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6603 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
6607 self.pg0.add_stream(pkts)
6608 self.pg_enable_capture(self.pg_interfaces)
6610 self.pg1.get_capture(2)
6612 # ACK packet out -> in
6613 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
6614 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
6615 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
6617 self.pg1.add_stream(p)
6618 self.pg_enable_capture(self.pg_interfaces)
6620 self.pg0.get_capture(1)
6622 # Check if deterministic NAT44 closed the session
6623 dms = self.vapi.nat_det_map_dump()
6624 self.assertEqual(0, dms[0].ses_num)
6626 self.logger.error("TCP session termination failed")
6629 @unittest.skipUnless(running_extended_tests(), "part of extended tests")
6630 def test_session_timeout(self):
6631 """ Deterministic NAT session timeouts """
6632 self.vapi.nat_det_add_del_map(self.pg0.remote_ip4n,
6634 socket.inet_aton(self.nat_addr),
6636 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
6637 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
6640 self.initiate_tcp_session(self.pg0, self.pg1)
6641 self.vapi.nat_set_timeouts(5, 5, 5, 5)
6642 pkts = self.create_stream_in(self.pg0, self.pg1)
6643 self.pg0.add_stream(pkts)
6644 self.pg_enable_capture(self.pg_interfaces)
6646 capture = self.pg1.get_capture(len(pkts))
6649 dms = self.vapi.nat_det_map_dump()
6650 self.assertEqual(0, dms[0].ses_num)
6652 @unittest.skipUnless(running_extended_tests(), "part of extended tests")
6653 def test_session_limit_per_user(self):
6654 """ Deterministic NAT maximum sessions per user limit """
6655 self.vapi.nat_det_add_del_map(self.pg0.remote_ip4n,
6657 socket.inet_aton(self.nat_addr),
6659 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
6660 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
6662 self.vapi.set_ipfix_exporter(collector_address=self.pg2.remote_ip4n,
6663 src_address=self.pg2.local_ip4n,
6665 template_interval=10)
6666 self.vapi.nat_ipfix()
6669 for port in range(1025, 2025):
6670 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6671 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6672 UDP(sport=port, dport=port))
6675 self.pg0.add_stream(pkts)
6676 self.pg_enable_capture(self.pg_interfaces)
6678 capture = self.pg1.get_capture(len(pkts))
6680 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6681 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6682 UDP(sport=3001, dport=3002))
6683 self.pg0.add_stream(p)
6684 self.pg_enable_capture(self.pg_interfaces)
6686 capture = self.pg1.assert_nothing_captured()
6688 # verify ICMP error packet
6689 capture = self.pg0.get_capture(1)
6691 self.assertTrue(p.haslayer(ICMP))
6693 self.assertEqual(icmp.type, 3)
6694 self.assertEqual(icmp.code, 1)
6695 self.assertTrue(icmp.haslayer(IPerror))
6696 inner_ip = icmp[IPerror]
6697 self.assertEqual(inner_ip[UDPerror].sport, 3001)
6698 self.assertEqual(inner_ip[UDPerror].dport, 3002)
6700 dms = self.vapi.nat_det_map_dump()
6702 self.assertEqual(1000, dms[0].ses_num)
6704 # verify IPFIX logging
6705 self.vapi.cli("ipfix flush") # FIXME this should be an API call
6707 capture = self.pg2.get_capture(2)
6708 ipfix = IPFIXDecoder()
6709 # first load template
6711 self.assertTrue(p.haslayer(IPFIX))
6712 if p.haslayer(Template):
6713 ipfix.add_template(p.getlayer(Template))
6714 # verify events in data set
6716 if p.haslayer(Data):
6717 data = ipfix.decode_data_set(p.getlayer(Set))
6718 self.verify_ipfix_max_entries_per_user(data,
6720 self.pg0.remote_ip4n)
6722 def clear_nat_det(self):
6724 Clear deterministic NAT configuration.
6726 self.vapi.nat_ipfix(enable=0)
6727 self.vapi.nat_set_timeouts()
6728 deterministic_mappings = self.vapi.nat_det_map_dump()
6729 for dsm in deterministic_mappings:
6730 self.vapi.nat_det_add_del_map(dsm.in_addr,
6736 interfaces = self.vapi.nat44_interface_dump()
6737 for intf in interfaces:
6738 self.vapi.nat44_interface_add_del_feature(intf.sw_if_index,
6743 super(TestDeterministicNAT, self).tearDown()
6744 if not self.vpp_dead:
6745 self.logger.info(self.vapi.cli("show nat44 interfaces"))
6746 self.logger.info(self.vapi.cli("show nat timeouts"))
6748 self.vapi.cli("show nat44 deterministic mappings"))
6750 self.vapi.cli("show nat44 deterministic sessions"))
6751 self.clear_nat_det()
6754 class TestNAT64(MethodHolder):
6755 """ NAT64 Test Cases """
6758 def setUpConstants(cls):
6759 super(TestNAT64, cls).setUpConstants()
6760 cls.vpp_cmdline.extend(["nat", "{", "nat64 bib hash buckets 128",
6761 "nat64 st hash buckets 256", "}"])
6764 def setUpClass(cls):
6765 super(TestNAT64, cls).setUpClass()
6768 cls.tcp_port_in = 6303
6769 cls.tcp_port_out = 6303
6770 cls.udp_port_in = 6304
6771 cls.udp_port_out = 6304
6772 cls.icmp_id_in = 6305
6773 cls.icmp_id_out = 6305
6774 cls.tcp_external_port = 80
6775 cls.nat_addr = '10.0.0.3'
6776 cls.nat_addr_n = socket.inet_pton(socket.AF_INET, cls.nat_addr)
6778 cls.vrf1_nat_addr = '10.0.10.3'
6779 cls.vrf1_nat_addr_n = socket.inet_pton(socket.AF_INET,
6781 cls.ipfix_src_port = 4739
6782 cls.ipfix_domain_id = 1
6784 cls.create_pg_interfaces(range(6))
6785 cls.ip6_interfaces = list(cls.pg_interfaces[0:1])
6786 cls.ip6_interfaces.append(cls.pg_interfaces[2])
6787 cls.ip4_interfaces = list(cls.pg_interfaces[1:2])
6789 cls.vapi.ip_table_add_del(cls.vrf1_id, is_add=1, is_ipv6=1)
6791 cls.pg_interfaces[2].set_table_ip6(cls.vrf1_id)
6793 cls.pg0.generate_remote_hosts(2)
6795 for i in cls.ip6_interfaces:
6798 i.configure_ipv6_neighbors()
6800 for i in cls.ip4_interfaces:
6806 cls.pg3.config_ip4()
6807 cls.pg3.resolve_arp()
6808 cls.pg3.config_ip6()
6809 cls.pg3.configure_ipv6_neighbors()
6812 cls.pg5.config_ip6()
6815 super(TestNAT64, cls).tearDownClass()
6818 def test_nat64_inside_interface_handles_neighbor_advertisement(self):
6819 """ NAT64 inside interface handles Neighbor Advertisement """
6821 self.vapi.nat64_add_del_interface(self.pg5.sw_if_index)
6824 ping = (Ether(dst=self.pg5.local_mac, src=self.pg5.remote_mac) /
6825 IPv6(src=self.pg5.remote_ip6, dst=self.pg5.local_ip6) /
6826 ICMPv6EchoRequest())
6828 self.pg5.add_stream(pkts)
6829 self.pg_enable_capture(self.pg_interfaces)
6832 # Wait for Neighbor Solicitation
6833 capture = self.pg5.get_capture(len(pkts))
6836 self.assertEqual(packet[IPv6].src, self.pg5.local_ip6)
6837 self.assertEqual(packet.haslayer(ICMPv6ND_NS), 1)
6838 tgt = packet[ICMPv6ND_NS].tgt
6840 self.logger.error(ppp("Unexpected or invalid packet:", packet))
6843 # Send Neighbor Advertisement
6844 p = (Ether(dst=self.pg5.local_mac, src=self.pg5.remote_mac) /
6845 IPv6(src=self.pg5.remote_ip6, dst=self.pg5.local_ip6) /
6846 ICMPv6ND_NA(tgt=tgt) /
6847 ICMPv6NDOptDstLLAddr(lladdr=self.pg5.remote_mac))
6849 self.pg5.add_stream(pkts)
6850 self.pg_enable_capture(self.pg_interfaces)
6853 # Try to send ping again
6855 self.pg5.add_stream(pkts)
6856 self.pg_enable_capture(self.pg_interfaces)
6859 # Wait for ping reply
6860 capture = self.pg5.get_capture(len(pkts))
6863 self.assertEqual(packet[IPv6].src, self.pg5.local_ip6)
6864 self.assertEqual(packet[IPv6].dst, self.pg5.remote_ip6)
6865 self.assertEqual(packet.haslayer(ICMPv6EchoReply), 1)
6867 self.logger.error(ppp("Unexpected or invalid packet:", packet))
6870 def test_pool(self):
6871 """ Add/delete address to NAT64 pool """
6872 nat_addr = socket.inet_pton(socket.AF_INET, '1.2.3.4')
6874 self.vapi.nat64_add_del_pool_addr_range(nat_addr, nat_addr)
6876 addresses = self.vapi.nat64_pool_addr_dump()
6877 self.assertEqual(len(addresses), 1)
6878 self.assertEqual(addresses[0].address, nat_addr)
6880 self.vapi.nat64_add_del_pool_addr_range(nat_addr, nat_addr, is_add=0)
6882 addresses = self.vapi.nat64_pool_addr_dump()
6883 self.assertEqual(len(addresses), 0)
6885 def test_interface(self):
6886 """ Enable/disable NAT64 feature on the interface """
6887 self.vapi.nat64_add_del_interface(self.pg0.sw_if_index)
6888 self.vapi.nat64_add_del_interface(self.pg1.sw_if_index, is_inside=0)
6890 interfaces = self.vapi.nat64_interface_dump()
6891 self.assertEqual(len(interfaces), 2)
6894 for intf in interfaces:
6895 if intf.sw_if_index == self.pg0.sw_if_index:
6896 self.assertEqual(intf.is_inside, 1)
6898 elif intf.sw_if_index == self.pg1.sw_if_index:
6899 self.assertEqual(intf.is_inside, 0)
6901 self.assertTrue(pg0_found)
6902 self.assertTrue(pg1_found)
6904 features = self.vapi.cli("show interface features pg0")
6905 self.assertNotEqual(features.find('nat64-in2out'), -1)
6906 features = self.vapi.cli("show interface features pg1")
6907 self.assertNotEqual(features.find('nat64-out2in'), -1)
6909 self.vapi.nat64_add_del_interface(self.pg0.sw_if_index, is_add=0)
6910 self.vapi.nat64_add_del_interface(self.pg1.sw_if_index, is_add=0)
6912 interfaces = self.vapi.nat64_interface_dump()
6913 self.assertEqual(len(interfaces), 0)
6915 def test_static_bib(self):
6916 """ Add/delete static BIB entry """
6917 in_addr = socket.inet_pton(socket.AF_INET6,
6918 '2001:db8:85a3::8a2e:370:7334')
6919 out_addr = socket.inet_pton(socket.AF_INET, '10.1.1.3')
6922 proto = IP_PROTOS.tcp
6924 self.vapi.nat64_add_del_static_bib(in_addr,
6929 bib = self.vapi.nat64_bib_dump(IP_PROTOS.tcp)
6934 self.assertEqual(bibe.i_addr, in_addr)
6935 self.assertEqual(bibe.o_addr, out_addr)
6936 self.assertEqual(bibe.i_port, in_port)
6937 self.assertEqual(bibe.o_port, out_port)
6938 self.assertEqual(static_bib_num, 1)
6940 self.vapi.nat64_add_del_static_bib(in_addr,
6946 bib = self.vapi.nat64_bib_dump(IP_PROTOS.tcp)
6951 self.assertEqual(static_bib_num, 0)
6953 def test_set_timeouts(self):
6954 """ Set NAT64 timeouts """
6955 # verify default values
6956 timeouts = self.vapi.nat_get_timeouts()
6957 self.assertEqual(timeouts.udp, 300)
6958 self.assertEqual(timeouts.icmp, 60)
6959 self.assertEqual(timeouts.tcp_transitory, 240)
6960 self.assertEqual(timeouts.tcp_established, 7440)
6962 # set and verify custom values
6963 self.vapi.nat_set_timeouts(udp=200, icmp=30, tcp_transitory=250,
6964 tcp_established=7450)
6965 timeouts = self.vapi.nat_get_timeouts()
6966 self.assertEqual(timeouts.udp, 200)
6967 self.assertEqual(timeouts.icmp, 30)
6968 self.assertEqual(timeouts.tcp_transitory, 250)
6969 self.assertEqual(timeouts.tcp_established, 7450)
6971 def test_dynamic(self):
6972 """ NAT64 dynamic translation test """
6973 self.tcp_port_in = 6303
6974 self.udp_port_in = 6304
6975 self.icmp_id_in = 6305
6977 ses_num_start = self.nat64_get_ses_num()
6979 self.vapi.nat64_add_del_pool_addr_range(self.nat_addr_n,
6981 self.vapi.nat64_add_del_interface(self.pg0.sw_if_index)
6982 self.vapi.nat64_add_del_interface(self.pg1.sw_if_index, is_inside=0)
6985 tcpn = self.statistics.get_counter('/err/nat64-in2out/TCP packets')
6986 udpn = self.statistics.get_counter('/err/nat64-in2out/UDP packets')
6987 icmpn = self.statistics.get_counter('/err/nat64-in2out/ICMP packets')
6988 totaln = self.statistics.get_counter(
6989 '/err/nat64-in2out/good in2out packets processed')
6991 pkts = self.create_stream_in_ip6(self.pg0, self.pg1)
6992 self.pg0.add_stream(pkts)
6993 self.pg_enable_capture(self.pg_interfaces)
6995 capture = self.pg1.get_capture(len(pkts))
6996 self.verify_capture_out(capture, nat_ip=self.nat_addr,
6997 dst_ip=self.pg1.remote_ip4)
6999 err = self.statistics.get_counter('/err/nat64-in2out/TCP packets')
7000 self.assertEqual(err - tcpn, 1)
7001 err = self.statistics.get_counter('/err/nat64-in2out/UDP packets')
7002 self.assertEqual(err - udpn, 1)
7003 err = self.statistics.get_counter('/err/nat64-in2out/ICMP packets')
7004 self.assertEqual(err - icmpn, 1)
7005 err = self.statistics.get_counter(
7006 '/err/nat64-in2out/good in2out packets processed')
7007 self.assertEqual(err - totaln, 3)
7010 tcpn = self.statistics.get_counter('/err/nat64-out2in/TCP packets')
7011 udpn = self.statistics.get_counter('/err/nat64-out2in/UDP packets')
7012 icmpn = self.statistics.get_counter('/err/nat64-out2in/ICMP packets')
7013 totaln = self.statistics.get_counter(
7014 '/err/nat64-out2in/good out2in packets processed')
7016 pkts = self.create_stream_out(self.pg1, dst_ip=self.nat_addr)
7017 self.pg1.add_stream(pkts)
7018 self.pg_enable_capture(self.pg_interfaces)
7020 capture = self.pg0.get_capture(len(pkts))
7021 ip = IPv6(src=''.join(['64:ff9b::', self.pg1.remote_ip4]))
7022 self.verify_capture_in_ip6(capture, ip[IPv6].src, self.pg0.remote_ip6)
7024 err = self.statistics.get_counter('/err/nat64-out2in/TCP packets')
7025 self.assertEqual(err - tcpn, 1)
7026 err = self.statistics.get_counter('/err/nat64-out2in/UDP packets')
7027 self.assertEqual(err - udpn, 1)
7028 err = self.statistics.get_counter('/err/nat64-out2in/ICMP packets')
7029 self.assertEqual(err - icmpn, 1)
7030 err = self.statistics.get_counter(
7031 '/err/nat64-out2in/good out2in packets processed')
7032 self.assertEqual(err - totaln, 3)
7035 pkts = self.create_stream_in_ip6(self.pg0, self.pg1)
7036 self.pg0.add_stream(pkts)
7037 self.pg_enable_capture(self.pg_interfaces)
7039 capture = self.pg1.get_capture(len(pkts))
7040 self.verify_capture_out(capture, nat_ip=self.nat_addr,
7041 dst_ip=self.pg1.remote_ip4)
7044 pkts = self.create_stream_out(self.pg1, dst_ip=self.nat_addr)
7045 self.pg1.add_stream(pkts)
7046 self.pg_enable_capture(self.pg_interfaces)
7048 capture = self.pg0.get_capture(len(pkts))
7049 self.verify_capture_in_ip6(capture, ip[IPv6].src, self.pg0.remote_ip6)
7051 ses_num_end = self.nat64_get_ses_num()
7053 self.assertEqual(ses_num_end - ses_num_start, 3)
7055 # tenant with specific VRF
7056 self.vapi.nat64_add_del_pool_addr_range(self.vrf1_nat_addr_n,
7057 self.vrf1_nat_addr_n,
7058 vrf_id=self.vrf1_id)
7059 self.vapi.nat64_add_del_interface(self.pg2.sw_if_index)
7061 pkts = self.create_stream_in_ip6(self.pg2, self.pg1)
7062 self.pg2.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.vrf1_nat_addr,
7067 dst_ip=self.pg1.remote_ip4)
7069 pkts = self.create_stream_out(self.pg1, dst_ip=self.vrf1_nat_addr)
7070 self.pg1.add_stream(pkts)
7071 self.pg_enable_capture(self.pg_interfaces)
7073 capture = self.pg2.get_capture(len(pkts))
7074 self.verify_capture_in_ip6(capture, ip[IPv6].src, self.pg2.remote_ip6)
7076 def test_static(self):
7077 """ NAT64 static translation test """
7078 self.tcp_port_in = 60303
7079 self.udp_port_in = 60304
7080 self.icmp_id_in = 60305
7081 self.tcp_port_out = 60303
7082 self.udp_port_out = 60304
7083 self.icmp_id_out = 60305
7085 ses_num_start = self.nat64_get_ses_num()
7087 self.vapi.nat64_add_del_pool_addr_range(self.nat_addr_n,
7089 self.vapi.nat64_add_del_interface(self.pg0.sw_if_index)
7090 self.vapi.nat64_add_del_interface(self.pg1.sw_if_index, is_inside=0)
7092 self.vapi.nat64_add_del_static_bib(self.pg0.remote_ip6n,
7097 self.vapi.nat64_add_del_static_bib(self.pg0.remote_ip6n,
7102 self.vapi.nat64_add_del_static_bib(self.pg0.remote_ip6n,
7109 pkts = self.create_stream_in_ip6(self.pg0, self.pg1)
7110 self.pg0.add_stream(pkts)
7111 self.pg_enable_capture(self.pg_interfaces)
7113 capture = self.pg1.get_capture(len(pkts))
7114 self.verify_capture_out(capture, nat_ip=self.nat_addr,
7115 dst_ip=self.pg1.remote_ip4, same_port=True)
7118 pkts = self.create_stream_out(self.pg1, dst_ip=self.nat_addr)
7119 self.pg1.add_stream(pkts)
7120 self.pg_enable_capture(self.pg_interfaces)
7122 capture = self.pg0.get_capture(len(pkts))
7123 ip = IPv6(src=''.join(['64:ff9b::', self.pg1.remote_ip4]))
7124 self.verify_capture_in_ip6(capture, ip[IPv6].src, self.pg0.remote_ip6)
7126 ses_num_end = self.nat64_get_ses_num()
7128 self.assertEqual(ses_num_end - ses_num_start, 3)
7130 @unittest.skipUnless(running_extended_tests(), "part of extended tests")
7131 def test_session_timeout(self):
7132 """ NAT64 session timeout """
7133 self.icmp_id_in = 1234
7134 self.vapi.nat64_add_del_pool_addr_range(self.nat_addr_n,
7136 self.vapi.nat64_add_del_interface(self.pg0.sw_if_index)
7137 self.vapi.nat64_add_del_interface(self.pg1.sw_if_index, is_inside=0)
7138 self.vapi.nat_set_timeouts(icmp=5, tcp_transitory=5, tcp_established=5)
7140 pkts = self.create_stream_in_ip6(self.pg0, self.pg1)
7141 self.pg0.add_stream(pkts)
7142 self.pg_enable_capture(self.pg_interfaces)
7144 capture = self.pg1.get_capture(len(pkts))
7146 ses_num_before_timeout = self.nat64_get_ses_num()
7150 # ICMP and TCP session after timeout
7151 ses_num_after_timeout = self.nat64_get_ses_num()
7152 self.assertEqual(ses_num_before_timeout - ses_num_after_timeout, 2)
7154 def test_icmp_error(self):
7155 """ NAT64 ICMP Error message translation """
7156 self.tcp_port_in = 6303
7157 self.udp_port_in = 6304
7158 self.icmp_id_in = 6305
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)
7165 # send some packets to create sessions
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_ip4 = self.pg1.get_capture(len(pkts))
7171 self.verify_capture_out(capture_ip4,
7172 nat_ip=self.nat_addr,
7173 dst_ip=self.pg1.remote_ip4)
7175 pkts = self.create_stream_out(self.pg1, dst_ip=self.nat_addr)
7176 self.pg1.add_stream(pkts)
7177 self.pg_enable_capture(self.pg_interfaces)
7179 capture_ip6 = self.pg0.get_capture(len(pkts))
7180 ip = IPv6(src=''.join(['64:ff9b::', self.pg1.remote_ip4]))
7181 self.verify_capture_in_ip6(capture_ip6, ip[IPv6].src,
7182 self.pg0.remote_ip6)
7185 pkts = [Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
7186 IPv6(src=self.pg0.remote_ip6, dst=ip[IPv6].src) /
7187 ICMPv6DestUnreach(code=1) /
7188 packet[IPv6] for packet in capture_ip6]
7189 self.pg0.add_stream(pkts)
7190 self.pg_enable_capture(self.pg_interfaces)
7192 capture = self.pg1.get_capture(len(pkts))
7193 for packet in capture:
7195 self.assertEqual(packet[IP].src, self.nat_addr)
7196 self.assertEqual(packet[IP].dst, self.pg1.remote_ip4)
7197 self.assertEqual(packet[ICMP].type, 3)
7198 self.assertEqual(packet[ICMP].code, 13)
7199 inner = packet[IPerror]
7200 self.assertEqual(inner.src, self.pg1.remote_ip4)
7201 self.assertEqual(inner.dst, self.nat_addr)
7202 self.assert_packet_checksums_valid(packet)
7203 if inner.haslayer(TCPerror):
7204 self.assertEqual(inner[TCPerror].dport, self.tcp_port_out)
7205 elif inner.haslayer(UDPerror):
7206 self.assertEqual(inner[UDPerror].dport, self.udp_port_out)
7208 self.assertEqual(inner[ICMPerror].id, self.icmp_id_out)
7210 self.logger.error(ppp("Unexpected or invalid packet:", packet))
7214 pkts = [Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
7215 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
7216 ICMP(type=3, code=13) /
7217 packet[IP] for packet in capture_ip4]
7218 self.pg1.add_stream(pkts)
7219 self.pg_enable_capture(self.pg_interfaces)
7221 capture = self.pg0.get_capture(len(pkts))
7222 for packet in capture:
7224 self.assertEqual(packet[IPv6].src, ip.src)
7225 self.assertEqual(packet[IPv6].dst, self.pg0.remote_ip6)
7226 icmp = packet[ICMPv6DestUnreach]
7227 self.assertEqual(icmp.code, 1)
7228 inner = icmp[IPerror6]
7229 self.assertEqual(inner.src, self.pg0.remote_ip6)
7230 self.assertEqual(inner.dst, ip.src)
7231 self.assert_icmpv6_checksum_valid(packet)
7232 if inner.haslayer(TCPerror):
7233 self.assertEqual(inner[TCPerror].sport, self.tcp_port_in)
7234 elif inner.haslayer(UDPerror):
7235 self.assertEqual(inner[UDPerror].sport, self.udp_port_in)
7237 self.assertEqual(inner[ICMPv6EchoRequest].id,
7240 self.logger.error(ppp("Unexpected or invalid packet:", packet))
7243 def test_hairpinning(self):
7244 """ NAT64 hairpinning """
7246 client = self.pg0.remote_hosts[0]
7247 server = self.pg0.remote_hosts[1]
7248 server_tcp_in_port = 22
7249 server_tcp_out_port = 4022
7250 server_udp_in_port = 23
7251 server_udp_out_port = 4023
7252 client_tcp_in_port = 1234
7253 client_udp_in_port = 1235
7254 client_tcp_out_port = 0
7255 client_udp_out_port = 0
7256 ip = IPv6(src=''.join(['64:ff9b::', self.nat_addr]))
7257 nat_addr_ip6 = ip.src
7259 self.vapi.nat64_add_del_pool_addr_range(self.nat_addr_n,
7261 self.vapi.nat64_add_del_interface(self.pg0.sw_if_index)
7262 self.vapi.nat64_add_del_interface(self.pg1.sw_if_index, is_inside=0)
7264 self.vapi.nat64_add_del_static_bib(server.ip6n,
7267 server_tcp_out_port,
7269 self.vapi.nat64_add_del_static_bib(server.ip6n,
7272 server_udp_out_port,
7277 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
7278 IPv6(src=client.ip6, dst=nat_addr_ip6) /
7279 TCP(sport=client_tcp_in_port, dport=server_tcp_out_port))
7281 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
7282 IPv6(src=client.ip6, dst=nat_addr_ip6) /
7283 UDP(sport=client_udp_in_port, dport=server_udp_out_port))
7285 self.pg0.add_stream(pkts)
7286 self.pg_enable_capture(self.pg_interfaces)
7288 capture = self.pg0.get_capture(len(pkts))
7289 for packet in capture:
7291 self.assertEqual(packet[IPv6].src, nat_addr_ip6)
7292 self.assertEqual(packet[IPv6].dst, server.ip6)
7293 self.assert_packet_checksums_valid(packet)
7294 if packet.haslayer(TCP):
7295 self.assertNotEqual(packet[TCP].sport, client_tcp_in_port)
7296 self.assertEqual(packet[TCP].dport, server_tcp_in_port)
7297 client_tcp_out_port = packet[TCP].sport
7299 self.assertNotEqual(packet[UDP].sport, client_udp_in_port)
7300 self.assertEqual(packet[UDP].dport, server_udp_in_port)
7301 client_udp_out_port = packet[UDP].sport
7303 self.logger.error(ppp("Unexpected or invalid packet:", packet))
7308 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
7309 IPv6(src=server.ip6, dst=nat_addr_ip6) /
7310 TCP(sport=server_tcp_in_port, dport=client_tcp_out_port))
7312 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
7313 IPv6(src=server.ip6, dst=nat_addr_ip6) /
7314 UDP(sport=server_udp_in_port, dport=client_udp_out_port))
7316 self.pg0.add_stream(pkts)
7317 self.pg_enable_capture(self.pg_interfaces)
7319 capture = self.pg0.get_capture(len(pkts))
7320 for packet in capture:
7322 self.assertEqual(packet[IPv6].src, nat_addr_ip6)
7323 self.assertEqual(packet[IPv6].dst, client.ip6)
7324 self.assert_packet_checksums_valid(packet)
7325 if packet.haslayer(TCP):
7326 self.assertEqual(packet[TCP].sport, server_tcp_out_port)
7327 self.assertEqual(packet[TCP].dport, client_tcp_in_port)
7329 self.assertEqual(packet[UDP].sport, server_udp_out_port)
7330 self.assertEqual(packet[UDP].dport, client_udp_in_port)
7332 self.logger.error(ppp("Unexpected or invalid packet:", packet))
7337 pkts = [Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
7338 IPv6(src=client.ip6, dst=nat_addr_ip6) /
7339 ICMPv6DestUnreach(code=1) /
7340 packet[IPv6] for packet in capture]
7341 self.pg0.add_stream(pkts)
7342 self.pg_enable_capture(self.pg_interfaces)
7344 capture = self.pg0.get_capture(len(pkts))
7345 for packet in capture:
7347 self.assertEqual(packet[IPv6].src, nat_addr_ip6)
7348 self.assertEqual(packet[IPv6].dst, server.ip6)
7349 icmp = packet[ICMPv6DestUnreach]
7350 self.assertEqual(icmp.code, 1)
7351 inner = icmp[IPerror6]
7352 self.assertEqual(inner.src, server.ip6)
7353 self.assertEqual(inner.dst, nat_addr_ip6)
7354 self.assert_packet_checksums_valid(packet)
7355 if inner.haslayer(TCPerror):
7356 self.assertEqual(inner[TCPerror].sport, server_tcp_in_port)
7357 self.assertEqual(inner[TCPerror].dport,
7358 client_tcp_out_port)
7360 self.assertEqual(inner[UDPerror].sport, server_udp_in_port)
7361 self.assertEqual(inner[UDPerror].dport,
7362 client_udp_out_port)
7364 self.logger.error(ppp("Unexpected or invalid packet:", packet))
7367 def test_prefix(self):
7368 """ NAT64 Network-Specific Prefix """
7370 self.vapi.nat64_add_del_pool_addr_range(self.nat_addr_n,
7372 self.vapi.nat64_add_del_interface(self.pg0.sw_if_index)
7373 self.vapi.nat64_add_del_interface(self.pg1.sw_if_index, is_inside=0)
7374 self.vapi.nat64_add_del_pool_addr_range(self.vrf1_nat_addr_n,
7375 self.vrf1_nat_addr_n,
7376 vrf_id=self.vrf1_id)
7377 self.vapi.nat64_add_del_interface(self.pg2.sw_if_index)
7380 global_pref64 = "2001:db8::"
7381 global_pref64_n = socket.inet_pton(socket.AF_INET6, global_pref64)
7382 global_pref64_len = 32
7383 self.vapi.nat64_add_del_prefix(global_pref64_n, global_pref64_len)
7385 prefix = self.vapi.nat64_prefix_dump()
7386 self.assertEqual(len(prefix), 1)
7387 self.assertEqual(prefix[0].prefix, global_pref64_n)
7388 self.assertEqual(prefix[0].prefix_len, global_pref64_len)
7389 self.assertEqual(prefix[0].vrf_id, 0)
7391 # Add tenant specific prefix
7392 vrf1_pref64 = "2001:db8:122:300::"
7393 vrf1_pref64_n = socket.inet_pton(socket.AF_INET6, vrf1_pref64)
7394 vrf1_pref64_len = 56
7395 self.vapi.nat64_add_del_prefix(vrf1_pref64_n,
7397 vrf_id=self.vrf1_id)
7398 prefix = self.vapi.nat64_prefix_dump()
7399 self.assertEqual(len(prefix), 2)
7402 pkts = self.create_stream_in_ip6(self.pg0,
7405 plen=global_pref64_len)
7406 self.pg0.add_stream(pkts)
7407 self.pg_enable_capture(self.pg_interfaces)
7409 capture = self.pg1.get_capture(len(pkts))
7410 self.verify_capture_out(capture, nat_ip=self.nat_addr,
7411 dst_ip=self.pg1.remote_ip4)
7413 pkts = self.create_stream_out(self.pg1, dst_ip=self.nat_addr)
7414 self.pg1.add_stream(pkts)
7415 self.pg_enable_capture(self.pg_interfaces)
7417 capture = self.pg0.get_capture(len(pkts))
7418 dst_ip = self.compose_ip6(self.pg1.remote_ip4,
7421 self.verify_capture_in_ip6(capture, dst_ip, self.pg0.remote_ip6)
7423 # Tenant specific prefix
7424 pkts = self.create_stream_in_ip6(self.pg2,
7427 plen=vrf1_pref64_len)
7428 self.pg2.add_stream(pkts)
7429 self.pg_enable_capture(self.pg_interfaces)
7431 capture = self.pg1.get_capture(len(pkts))
7432 self.verify_capture_out(capture, nat_ip=self.vrf1_nat_addr,
7433 dst_ip=self.pg1.remote_ip4)
7435 pkts = self.create_stream_out(self.pg1, dst_ip=self.vrf1_nat_addr)
7436 self.pg1.add_stream(pkts)
7437 self.pg_enable_capture(self.pg_interfaces)
7439 capture = self.pg2.get_capture(len(pkts))
7440 dst_ip = self.compose_ip6(self.pg1.remote_ip4,
7443 self.verify_capture_in_ip6(capture, dst_ip, self.pg2.remote_ip6)
7445 def test_unknown_proto(self):
7446 """ NAT64 translate packet with unknown protocol """
7448 self.vapi.nat64_add_del_pool_addr_range(self.nat_addr_n,
7450 self.vapi.nat64_add_del_interface(self.pg0.sw_if_index)
7451 self.vapi.nat64_add_del_interface(self.pg1.sw_if_index, is_inside=0)
7452 remote_ip6 = self.compose_ip6(self.pg1.remote_ip4, '64:ff9b::', 96)
7455 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
7456 IPv6(src=self.pg0.remote_ip6, dst=remote_ip6) /
7457 TCP(sport=self.tcp_port_in, dport=20))
7458 self.pg0.add_stream(p)
7459 self.pg_enable_capture(self.pg_interfaces)
7461 p = self.pg1.get_capture(1)
7463 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
7464 IPv6(src=self.pg0.remote_ip6, dst=remote_ip6, nh=47) /
7466 IP(src=self.pg2.local_ip4, dst=self.pg2.remote_ip4) /
7467 TCP(sport=1234, dport=1234))
7468 self.pg0.add_stream(p)
7469 self.pg_enable_capture(self.pg_interfaces)
7471 p = self.pg1.get_capture(1)
7474 self.assertEqual(packet[IP].src, self.nat_addr)
7475 self.assertEqual(packet[IP].dst, self.pg1.remote_ip4)
7476 self.assertEqual(packet.haslayer(GRE), 1)
7477 self.assert_packet_checksums_valid(packet)
7479 self.logger.error(ppp("Unexpected or invalid packet:", packet))
7483 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
7484 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
7486 IP(src=self.pg2.remote_ip4, dst=self.pg2.local_ip4) /
7487 TCP(sport=1234, dport=1234))
7488 self.pg1.add_stream(p)
7489 self.pg_enable_capture(self.pg_interfaces)
7491 p = self.pg0.get_capture(1)
7494 self.assertEqual(packet[IPv6].src, remote_ip6)
7495 self.assertEqual(packet[IPv6].dst, self.pg0.remote_ip6)
7496 self.assertEqual(packet[IPv6].nh, 47)
7498 self.logger.error(ppp("Unexpected or invalid packet:", packet))
7501 def test_hairpinning_unknown_proto(self):
7502 """ NAT64 translate packet with unknown protocol - hairpinning """
7504 client = self.pg0.remote_hosts[0]
7505 server = self.pg0.remote_hosts[1]
7506 server_tcp_in_port = 22
7507 server_tcp_out_port = 4022
7508 client_tcp_in_port = 1234
7509 client_tcp_out_port = 1235
7510 server_nat_ip = "10.0.0.100"
7511 client_nat_ip = "10.0.0.110"
7512 server_nat_ip_n = socket.inet_pton(socket.AF_INET, server_nat_ip)
7513 client_nat_ip_n = socket.inet_pton(socket.AF_INET, client_nat_ip)
7514 server_nat_ip6 = self.compose_ip6(server_nat_ip, '64:ff9b::', 96)
7515 client_nat_ip6 = self.compose_ip6(client_nat_ip, '64:ff9b::', 96)
7517 self.vapi.nat64_add_del_pool_addr_range(server_nat_ip_n,
7519 self.vapi.nat64_add_del_interface(self.pg0.sw_if_index)
7520 self.vapi.nat64_add_del_interface(self.pg1.sw_if_index, is_inside=0)
7522 self.vapi.nat64_add_del_static_bib(server.ip6n,
7525 server_tcp_out_port,
7528 self.vapi.nat64_add_del_static_bib(server.ip6n,
7534 self.vapi.nat64_add_del_static_bib(client.ip6n,
7537 client_tcp_out_port,
7541 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
7542 IPv6(src=client.ip6, dst=server_nat_ip6) /
7543 TCP(sport=client_tcp_in_port, dport=server_tcp_out_port))
7544 self.pg0.add_stream(p)
7545 self.pg_enable_capture(self.pg_interfaces)
7547 p = self.pg0.get_capture(1)
7549 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
7550 IPv6(src=client.ip6, dst=server_nat_ip6, nh=IP_PROTOS.gre) /
7552 IP(src=self.pg2.local_ip4, dst=self.pg2.remote_ip4) /
7553 TCP(sport=1234, dport=1234))
7554 self.pg0.add_stream(p)
7555 self.pg_enable_capture(self.pg_interfaces)
7557 p = self.pg0.get_capture(1)
7560 self.assertEqual(packet[IPv6].src, client_nat_ip6)
7561 self.assertEqual(packet[IPv6].dst, server.ip6)
7562 self.assertEqual(packet[IPv6].nh, IP_PROTOS.gre)
7564 self.logger.error(ppp("Unexpected or invalid packet:", packet))
7568 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
7569 IPv6(src=server.ip6, dst=client_nat_ip6, nh=IP_PROTOS.gre) /
7571 IP(src=self.pg2.remote_ip4, dst=self.pg2.local_ip4) /
7572 TCP(sport=1234, dport=1234))
7573 self.pg0.add_stream(p)
7574 self.pg_enable_capture(self.pg_interfaces)
7576 p = self.pg0.get_capture(1)
7579 self.assertEqual(packet[IPv6].src, server_nat_ip6)
7580 self.assertEqual(packet[IPv6].dst, client.ip6)
7581 self.assertEqual(packet[IPv6].nh, IP_PROTOS.gre)
7583 self.logger.error(ppp("Unexpected or invalid packet:", packet))
7586 def test_one_armed_nat64(self):
7587 """ One armed NAT64 """
7589 remote_host_ip6 = self.compose_ip6(self.pg3.remote_ip4,
7593 self.vapi.nat64_add_del_pool_addr_range(self.nat_addr_n,
7595 self.vapi.nat64_add_del_interface(self.pg3.sw_if_index)
7596 self.vapi.nat64_add_del_interface(self.pg3.sw_if_index, is_inside=0)
7599 p = (Ether(src=self.pg3.remote_mac, dst=self.pg3.local_mac) /
7600 IPv6(src=self.pg3.remote_ip6, dst=remote_host_ip6) /
7601 TCP(sport=12345, dport=80))
7602 self.pg3.add_stream(p)
7603 self.pg_enable_capture(self.pg_interfaces)
7605 capture = self.pg3.get_capture(1)
7610 self.assertEqual(ip.src, self.nat_addr)
7611 self.assertEqual(ip.dst, self.pg3.remote_ip4)
7612 self.assertNotEqual(tcp.sport, 12345)
7613 external_port = tcp.sport
7614 self.assertEqual(tcp.dport, 80)
7615 self.assert_packet_checksums_valid(p)
7617 self.logger.error(ppp("Unexpected or invalid packet:", p))
7621 p = (Ether(src=self.pg3.remote_mac, dst=self.pg3.local_mac) /
7622 IP(src=self.pg3.remote_ip4, dst=self.nat_addr) /
7623 TCP(sport=80, dport=external_port))
7624 self.pg3.add_stream(p)
7625 self.pg_enable_capture(self.pg_interfaces)
7627 capture = self.pg3.get_capture(1)
7632 self.assertEqual(ip.src, remote_host_ip6)
7633 self.assertEqual(ip.dst, self.pg3.remote_ip6)
7634 self.assertEqual(tcp.sport, 80)
7635 self.assertEqual(tcp.dport, 12345)
7636 self.assert_packet_checksums_valid(p)
7638 self.logger.error(ppp("Unexpected or invalid packet:", p))
7641 def test_frag_in_order(self):
7642 """ NAT64 translate fragments arriving in order """
7643 self.tcp_port_in = random.randint(1025, 65535)
7645 self.vapi.nat64_add_del_pool_addr_range(self.nat_addr_n,
7647 self.vapi.nat64_add_del_interface(self.pg0.sw_if_index)
7648 self.vapi.nat64_add_del_interface(self.pg1.sw_if_index, is_inside=0)
7650 reass = self.vapi.nat_reass_dump()
7651 reass_n_start = len(reass)
7655 pkts = self.create_stream_frag_ip6(self.pg0, self.pg1.remote_ip4,
7656 self.tcp_port_in, 20, data)
7657 self.pg0.add_stream(pkts)
7658 self.pg_enable_capture(self.pg_interfaces)
7660 frags = self.pg1.get_capture(len(pkts))
7661 p = self.reass_frags_and_verify(frags,
7663 self.pg1.remote_ip4)
7664 self.assertEqual(p[TCP].dport, 20)
7665 self.assertNotEqual(p[TCP].sport, self.tcp_port_in)
7666 self.tcp_port_out = p[TCP].sport
7667 self.assertEqual(data, p[Raw].load)
7670 data = "A" * 4 + "b" * 16 + "C" * 3
7671 pkts = self.create_stream_frag(self.pg1,
7676 self.pg1.add_stream(pkts)
7677 self.pg_enable_capture(self.pg_interfaces)
7679 frags = self.pg0.get_capture(len(pkts))
7680 src = self.compose_ip6(self.pg1.remote_ip4, '64:ff9b::', 96)
7681 p = self.reass_frags_and_verify_ip6(frags, src, self.pg0.remote_ip6)
7682 self.assertEqual(p[TCP].sport, 20)
7683 self.assertEqual(p[TCP].dport, self.tcp_port_in)
7684 self.assertEqual(data, p[Raw].load)
7686 reass = self.vapi.nat_reass_dump()
7687 reass_n_end = len(reass)
7689 self.assertEqual(reass_n_end - reass_n_start, 2)
7691 def test_reass_hairpinning(self):
7692 """ NAT64 fragments hairpinning """
7694 server = self.pg0.remote_hosts[1]
7695 server_in_port = random.randint(1025, 65535)
7696 server_out_port = random.randint(1025, 65535)
7697 client_in_port = random.randint(1025, 65535)
7698 ip = IPv6(src=''.join(['64:ff9b::', self.nat_addr]))
7699 nat_addr_ip6 = ip.src
7701 self.vapi.nat64_add_del_pool_addr_range(self.nat_addr_n,
7703 self.vapi.nat64_add_del_interface(self.pg0.sw_if_index)
7704 self.vapi.nat64_add_del_interface(self.pg1.sw_if_index, is_inside=0)
7706 # add static BIB entry for server
7707 self.vapi.nat64_add_del_static_bib(server.ip6n,
7713 # send packet from host to server
7714 pkts = self.create_stream_frag_ip6(self.pg0,
7719 self.pg0.add_stream(pkts)
7720 self.pg_enable_capture(self.pg_interfaces)
7722 frags = self.pg0.get_capture(len(pkts))
7723 p = self.reass_frags_and_verify_ip6(frags, nat_addr_ip6, server.ip6)
7724 self.assertNotEqual(p[TCP].sport, client_in_port)
7725 self.assertEqual(p[TCP].dport, server_in_port)
7726 self.assertEqual(data, p[Raw].load)
7728 def test_frag_out_of_order(self):
7729 """ NAT64 translate fragments arriving out of order """
7730 self.tcp_port_in = random.randint(1025, 65535)
7732 self.vapi.nat64_add_del_pool_addr_range(self.nat_addr_n,
7734 self.vapi.nat64_add_del_interface(self.pg0.sw_if_index)
7735 self.vapi.nat64_add_del_interface(self.pg1.sw_if_index, is_inside=0)
7739 pkts = self.create_stream_frag_ip6(self.pg0, self.pg1.remote_ip4,
7740 self.tcp_port_in, 20, data)
7742 self.pg0.add_stream(pkts)
7743 self.pg_enable_capture(self.pg_interfaces)
7745 frags = self.pg1.get_capture(len(pkts))
7746 p = self.reass_frags_and_verify(frags,
7748 self.pg1.remote_ip4)
7749 self.assertEqual(p[TCP].dport, 20)
7750 self.assertNotEqual(p[TCP].sport, self.tcp_port_in)
7751 self.tcp_port_out = p[TCP].sport
7752 self.assertEqual(data, p[Raw].load)
7755 data = "A" * 4 + "B" * 16 + "C" * 3
7756 pkts = self.create_stream_frag(self.pg1,
7762 self.pg1.add_stream(pkts)
7763 self.pg_enable_capture(self.pg_interfaces)
7765 frags = self.pg0.get_capture(len(pkts))
7766 src = self.compose_ip6(self.pg1.remote_ip4, '64:ff9b::', 96)
7767 p = self.reass_frags_and_verify_ip6(frags, src, self.pg0.remote_ip6)
7768 self.assertEqual(p[TCP].sport, 20)
7769 self.assertEqual(p[TCP].dport, self.tcp_port_in)
7770 self.assertEqual(data, p[Raw].load)
7772 def test_interface_addr(self):
7773 """ Acquire NAT64 pool addresses from interface """
7774 self.vapi.nat64_add_interface_addr(self.pg4.sw_if_index)
7776 # no address in NAT64 pool
7777 adresses = self.vapi.nat44_address_dump()
7778 self.assertEqual(0, len(adresses))
7780 # configure interface address and check NAT64 address pool
7781 self.pg4.config_ip4()
7782 addresses = self.vapi.nat64_pool_addr_dump()
7783 self.assertEqual(len(addresses), 1)
7784 self.assertEqual(addresses[0].address, self.pg4.local_ip4n)
7786 # remove interface address and check NAT64 address pool
7787 self.pg4.unconfig_ip4()
7788 addresses = self.vapi.nat64_pool_addr_dump()
7789 self.assertEqual(0, len(adresses))
7791 @unittest.skipUnless(running_extended_tests(), "part of extended tests")
7792 def test_ipfix_max_bibs_sessions(self):
7793 """ IPFIX logging maximum session and BIB entries exceeded """
7796 remote_host_ip6 = self.compose_ip6(self.pg1.remote_ip4,
7800 self.vapi.nat64_add_del_pool_addr_range(self.nat_addr_n,
7802 self.vapi.nat64_add_del_interface(self.pg0.sw_if_index)
7803 self.vapi.nat64_add_del_interface(self.pg1.sw_if_index, is_inside=0)
7807 for i in range(0, max_bibs):
7808 src = "fd01:aa::%x" % (i)
7809 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
7810 IPv6(src=src, dst=remote_host_ip6) /
7811 TCP(sport=12345, dport=80))
7813 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
7814 IPv6(src=src, dst=remote_host_ip6) /
7815 TCP(sport=12345, dport=22))
7817 self.pg0.add_stream(pkts)
7818 self.pg_enable_capture(self.pg_interfaces)
7820 self.pg1.get_capture(max_sessions)
7822 self.vapi.set_ipfix_exporter(collector_address=self.pg3.remote_ip4n,
7823 src_address=self.pg3.local_ip4n,
7825 template_interval=10)
7826 self.vapi.nat_ipfix(domain_id=self.ipfix_domain_id,
7827 src_port=self.ipfix_src_port)
7829 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
7830 IPv6(src=src, dst=remote_host_ip6) /
7831 TCP(sport=12345, dport=25))
7832 self.pg0.add_stream(p)
7833 self.pg_enable_capture(self.pg_interfaces)
7835 self.pg1.assert_nothing_captured()
7837 self.vapi.cli("ipfix flush") # FIXME this should be an API call
7838 capture = self.pg3.get_capture(9)
7839 ipfix = IPFIXDecoder()
7840 # first load template
7842 self.assertTrue(p.haslayer(IPFIX))
7843 self.assertEqual(p[IP].src, self.pg3.local_ip4)
7844 self.assertEqual(p[IP].dst, self.pg3.remote_ip4)
7845 self.assertEqual(p[UDP].sport, self.ipfix_src_port)
7846 self.assertEqual(p[UDP].dport, 4739)
7847 self.assertEqual(p[IPFIX].observationDomainID,
7848 self.ipfix_domain_id)
7849 if p.haslayer(Template):
7850 ipfix.add_template(p.getlayer(Template))
7851 # verify events in data set
7853 if p.haslayer(Data):
7854 data = ipfix.decode_data_set(p.getlayer(Set))
7855 self.verify_ipfix_max_sessions(data, max_sessions)
7857 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
7858 IPv6(src=self.pg0.remote_ip6, dst=remote_host_ip6) /
7859 TCP(sport=12345, dport=80))
7860 self.pg0.add_stream(p)
7861 self.pg_enable_capture(self.pg_interfaces)
7863 self.pg1.assert_nothing_captured()
7865 self.vapi.cli("ipfix flush") # FIXME this should be an API call
7866 capture = self.pg3.get_capture(1)
7867 # verify events in data set
7869 self.assertTrue(p.haslayer(IPFIX))
7870 self.assertEqual(p[IP].src, self.pg3.local_ip4)
7871 self.assertEqual(p[IP].dst, self.pg3.remote_ip4)
7872 self.assertEqual(p[UDP].sport, self.ipfix_src_port)
7873 self.assertEqual(p[UDP].dport, 4739)
7874 self.assertEqual(p[IPFIX].observationDomainID,
7875 self.ipfix_domain_id)
7876 if p.haslayer(Data):
7877 data = ipfix.decode_data_set(p.getlayer(Set))
7878 self.verify_ipfix_max_bibs(data, max_bibs)
7880 def test_ipfix_max_frags(self):
7881 """ IPFIX logging maximum fragments pending reassembly exceeded """
7882 self.vapi.nat64_add_del_pool_addr_range(self.nat_addr_n,
7884 self.vapi.nat64_add_del_interface(self.pg0.sw_if_index)
7885 self.vapi.nat64_add_del_interface(self.pg1.sw_if_index, is_inside=0)
7886 self.vapi.nat_set_reass(max_frag=1, is_ip6=1)
7887 self.vapi.set_ipfix_exporter(collector_address=self.pg3.remote_ip4n,
7888 src_address=self.pg3.local_ip4n,
7890 template_interval=10)
7891 self.vapi.nat_ipfix(domain_id=self.ipfix_domain_id,
7892 src_port=self.ipfix_src_port)
7895 pkts = self.create_stream_frag_ip6(self.pg0, self.pg1.remote_ip4,
7896 self.tcp_port_in, 20, data)
7898 self.pg0.add_stream(pkts)
7899 self.pg_enable_capture(self.pg_interfaces)
7901 self.pg1.assert_nothing_captured()
7903 self.vapi.cli("ipfix flush") # FIXME this should be an API call
7904 capture = self.pg3.get_capture(9)
7905 ipfix = IPFIXDecoder()
7906 # first load template
7908 self.assertTrue(p.haslayer(IPFIX))
7909 self.assertEqual(p[IP].src, self.pg3.local_ip4)
7910 self.assertEqual(p[IP].dst, self.pg3.remote_ip4)
7911 self.assertEqual(p[UDP].sport, self.ipfix_src_port)
7912 self.assertEqual(p[UDP].dport, 4739)
7913 self.assertEqual(p[IPFIX].observationDomainID,
7914 self.ipfix_domain_id)
7915 if p.haslayer(Template):
7916 ipfix.add_template(p.getlayer(Template))
7917 # verify events in data set
7919 if p.haslayer(Data):
7920 data = ipfix.decode_data_set(p.getlayer(Set))
7921 self.verify_ipfix_max_fragments_ip6(data, 1,
7922 self.pg0.remote_ip6n)
7924 def test_ipfix_bib_ses(self):
7925 """ IPFIX logging NAT64 BIB/session create and delete events """
7926 self.tcp_port_in = random.randint(1025, 65535)
7927 remote_host_ip6 = self.compose_ip6(self.pg1.remote_ip4,
7931 self.vapi.nat64_add_del_pool_addr_range(self.nat_addr_n,
7933 self.vapi.nat64_add_del_interface(self.pg0.sw_if_index)
7934 self.vapi.nat64_add_del_interface(self.pg1.sw_if_index, is_inside=0)
7935 self.vapi.set_ipfix_exporter(collector_address=self.pg3.remote_ip4n,
7936 src_address=self.pg3.local_ip4n,
7938 template_interval=10)
7939 self.vapi.nat_ipfix(domain_id=self.ipfix_domain_id,
7940 src_port=self.ipfix_src_port)
7943 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
7944 IPv6(src=self.pg0.remote_ip6, dst=remote_host_ip6) /
7945 TCP(sport=self.tcp_port_in, dport=25))
7946 self.pg0.add_stream(p)
7947 self.pg_enable_capture(self.pg_interfaces)
7949 p = self.pg1.get_capture(1)
7950 self.tcp_port_out = p[0][TCP].sport
7951 self.vapi.cli("ipfix flush") # FIXME this should be an API call
7952 capture = self.pg3.get_capture(10)
7953 ipfix = IPFIXDecoder()
7954 # first load template
7956 self.assertTrue(p.haslayer(IPFIX))
7957 self.assertEqual(p[IP].src, self.pg3.local_ip4)
7958 self.assertEqual(p[IP].dst, self.pg3.remote_ip4)
7959 self.assertEqual(p[UDP].sport, self.ipfix_src_port)
7960 self.assertEqual(p[UDP].dport, 4739)
7961 self.assertEqual(p[IPFIX].observationDomainID,
7962 self.ipfix_domain_id)
7963 if p.haslayer(Template):
7964 ipfix.add_template(p.getlayer(Template))
7965 # verify events in data set
7967 if p.haslayer(Data):
7968 data = ipfix.decode_data_set(p.getlayer(Set))
7969 if ord(data[0][230]) == 10:
7970 self.verify_ipfix_bib(data, 1, self.pg0.remote_ip6n)
7971 elif ord(data[0][230]) == 6:
7972 self.verify_ipfix_nat64_ses(data,
7974 self.pg0.remote_ip6n,
7975 self.pg1.remote_ip4,
7978 self.logger.error(ppp("Unexpected or invalid packet: ", p))
7981 self.pg_enable_capture(self.pg_interfaces)
7982 self.vapi.nat64_add_del_pool_addr_range(self.nat_addr_n,
7985 self.vapi.cli("ipfix flush") # FIXME this should be an API call
7986 capture = self.pg3.get_capture(2)
7987 # verify events in data set
7989 self.assertTrue(p.haslayer(IPFIX))
7990 self.assertEqual(p[IP].src, self.pg3.local_ip4)
7991 self.assertEqual(p[IP].dst, self.pg3.remote_ip4)
7992 self.assertEqual(p[UDP].sport, self.ipfix_src_port)
7993 self.assertEqual(p[UDP].dport, 4739)
7994 self.assertEqual(p[IPFIX].observationDomainID,
7995 self.ipfix_domain_id)
7996 if p.haslayer(Data):
7997 data = ipfix.decode_data_set(p.getlayer(Set))
7998 if ord(data[0][230]) == 11:
7999 self.verify_ipfix_bib(data, 0, self.pg0.remote_ip6n)
8000 elif ord(data[0][230]) == 7:
8001 self.verify_ipfix_nat64_ses(data,
8003 self.pg0.remote_ip6n,
8004 self.pg1.remote_ip4,
8007 self.logger.error(ppp("Unexpected or invalid packet: ", p))
8009 def test_syslog_sess(self):
8010 """ Test syslog session creation and deletion """
8011 self.tcp_port_in = random.randint(1025, 65535)
8012 remote_host_ip6 = self.compose_ip6(self.pg1.remote_ip4,
8016 self.vapi.nat64_add_del_pool_addr_range(self.nat_addr_n,
8018 self.vapi.nat64_add_del_interface(self.pg0.sw_if_index)
8019 self.vapi.nat64_add_del_interface(self.pg1.sw_if_index, is_inside=0)
8020 self.vapi.syslog_set_filter(SYSLOG_SEVERITY.INFO)
8021 self.vapi.syslog_set_sender(self.pg3.remote_ip4n, self.pg3.local_ip4n)
8023 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
8024 IPv6(src=self.pg0.remote_ip6, dst=remote_host_ip6) /
8025 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port))
8026 self.pg0.add_stream(p)
8027 self.pg_enable_capture(self.pg_interfaces)
8029 p = self.pg1.get_capture(1)
8030 self.tcp_port_out = p[0][TCP].sport
8031 capture = self.pg3.get_capture(1)
8032 self.verify_syslog_sess(capture[0][Raw].load, is_ip6=True)
8034 self.pg_enable_capture(self.pg_interfaces)
8036 self.vapi.nat64_add_del_pool_addr_range(self.nat_addr_n,
8039 capture = self.pg3.get_capture(1)
8040 self.verify_syslog_sess(capture[0][Raw].load, False, True)
8042 def nat64_get_ses_num(self):
8044 Return number of active NAT64 sessions.
8046 st = self.vapi.nat64_st_dump()
8049 def clear_nat64(self):
8051 Clear NAT64 configuration.
8053 self.vapi.nat_ipfix(enable=0, src_port=self.ipfix_src_port,
8054 domain_id=self.ipfix_domain_id)
8055 self.ipfix_src_port = 4739
8056 self.ipfix_domain_id = 1
8058 self.vapi.syslog_set_filter(SYSLOG_SEVERITY.EMERG)
8060 self.vapi.nat_set_timeouts()
8062 interfaces = self.vapi.nat64_interface_dump()
8063 for intf in interfaces:
8064 if intf.is_inside > 1:
8065 self.vapi.nat64_add_del_interface(intf.sw_if_index,
8068 self.vapi.nat64_add_del_interface(intf.sw_if_index,
8072 bib = self.vapi.nat64_bib_dump(255)
8075 self.vapi.nat64_add_del_static_bib(bibe.i_addr,
8083 adresses = self.vapi.nat64_pool_addr_dump()
8084 for addr in adresses:
8085 self.vapi.nat64_add_del_pool_addr_range(addr.address,
8090 prefixes = self.vapi.nat64_prefix_dump()
8091 for prefix in prefixes:
8092 self.vapi.nat64_add_del_prefix(prefix.prefix,
8094 vrf_id=prefix.vrf_id,
8098 super(TestNAT64, self).tearDown()
8099 if not self.vpp_dead:
8100 self.logger.info(self.vapi.cli("show nat64 pool"))
8101 self.logger.info(self.vapi.cli("show nat64 interfaces"))
8102 self.logger.info(self.vapi.cli("show nat64 prefix"))
8103 self.logger.info(self.vapi.cli("show nat64 bib all"))
8104 self.logger.info(self.vapi.cli("show nat64 session table all"))
8105 self.logger.info(self.vapi.cli("show nat virtual-reassembly"))
8109 class TestDSlite(MethodHolder):
8110 """ DS-Lite Test Cases """
8113 def setUpClass(cls):
8114 super(TestDSlite, cls).setUpClass()
8117 cls.nat_addr = '10.0.0.3'
8118 cls.nat_addr_n = socket.inet_pton(socket.AF_INET, cls.nat_addr)
8120 cls.create_pg_interfaces(range(3))
8122 cls.pg0.config_ip4()
8123 cls.pg0.resolve_arp()
8125 cls.pg1.config_ip6()
8126 cls.pg1.generate_remote_hosts(2)
8127 cls.pg1.configure_ipv6_neighbors()
8129 cls.pg2.config_ip4()
8130 cls.pg2.resolve_arp()
8133 super(TestDSlite, cls).tearDownClass()
8136 def verify_syslog_apmadd(self, data, isaddr, isport, xsaddr, xsport,
8138 message = data.decode('utf-8')
8140 message = SyslogMessage.parse(message)
8141 self.assertEqual(message.severity, SyslogSeverity.info)
8142 self.assertEqual(message.appname, 'NAT')
8143 self.assertEqual(message.msgid, 'APMADD')
8144 sd_params = message.sd.get('napmap')
8145 self.assertTrue(sd_params is not None)
8146 self.assertEqual(sd_params.get('IATYP'), 'IPv4')
8147 self.assertEqual(sd_params.get('ISADDR'), isaddr)
8148 self.assertEqual(sd_params.get('ISPORT'), "%d" % isport)
8149 self.assertEqual(sd_params.get('XATYP'), 'IPv4')
8150 self.assertEqual(sd_params.get('XSADDR'), xsaddr)
8151 self.assertEqual(sd_params.get('XSPORT'), "%d" % xsport)
8152 self.assertEqual(sd_params.get('PROTO'), "%d" % proto)
8153 self.assertTrue(sd_params.get('SSUBIX') is not None)
8154 self.assertEqual(sd_params.get('SV6ENC'), sv6enc)
8155 except ParseError as e:
8156 self.logger.error(e)
8158 def test_dslite(self):
8159 """ Test DS-Lite """
8160 nat_config = self.vapi.nat_show_config()
8161 self.assertEqual(0, nat_config.dslite_ce)
8163 self.vapi.dslite_add_del_pool_addr_range(self.nat_addr_n,
8165 aftr_ip4 = '192.0.0.1'
8166 aftr_ip4_n = socket.inet_pton(socket.AF_INET, aftr_ip4)
8167 aftr_ip6 = '2001:db8:85a3::8a2e:370:1'
8168 aftr_ip6_n = socket.inet_pton(socket.AF_INET6, aftr_ip6)
8169 self.vapi.dslite_set_aftr_addr(aftr_ip6_n, aftr_ip4_n)
8170 self.vapi.syslog_set_sender(self.pg2.remote_ip4n, self.pg2.local_ip4n)
8173 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
8174 IPv6(dst=aftr_ip6, src=self.pg1.remote_hosts[0].ip6) /
8175 IP(dst=self.pg0.remote_ip4, src='192.168.1.1') /
8176 UDP(sport=20000, dport=10000))
8177 self.pg1.add_stream(p)
8178 self.pg_enable_capture(self.pg_interfaces)
8180 capture = self.pg0.get_capture(1)
8181 capture = capture[0]
8182 self.assertFalse(capture.haslayer(IPv6))
8183 self.assertEqual(capture[IP].src, self.nat_addr)
8184 self.assertEqual(capture[IP].dst, self.pg0.remote_ip4)
8185 self.assertNotEqual(capture[UDP].sport, 20000)
8186 self.assertEqual(capture[UDP].dport, 10000)
8187 self.assert_packet_checksums_valid(capture)
8188 out_port = capture[UDP].sport
8189 capture = self.pg2.get_capture(1)
8190 self.verify_syslog_apmadd(capture[0][Raw].load, '192.168.1.1',
8191 20000, self.nat_addr, out_port,
8192 self.pg1.remote_hosts[0].ip6, IP_PROTOS.udp)
8194 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
8195 IP(dst=self.nat_addr, src=self.pg0.remote_ip4) /
8196 UDP(sport=10000, dport=out_port))
8197 self.pg0.add_stream(p)
8198 self.pg_enable_capture(self.pg_interfaces)
8200 capture = self.pg1.get_capture(1)
8201 capture = capture[0]
8202 self.assertEqual(capture[IPv6].src, aftr_ip6)
8203 self.assertEqual(capture[IPv6].dst, self.pg1.remote_hosts[0].ip6)
8204 self.assertEqual(capture[IP].src, self.pg0.remote_ip4)
8205 self.assertEqual(capture[IP].dst, '192.168.1.1')
8206 self.assertEqual(capture[UDP].sport, 10000)
8207 self.assertEqual(capture[UDP].dport, 20000)
8208 self.assert_packet_checksums_valid(capture)
8211 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
8212 IPv6(dst=aftr_ip6, src=self.pg1.remote_hosts[1].ip6) /
8213 IP(dst=self.pg0.remote_ip4, src='192.168.1.1') /
8214 TCP(sport=20001, dport=10001))
8215 self.pg1.add_stream(p)
8216 self.pg_enable_capture(self.pg_interfaces)
8218 capture = self.pg0.get_capture(1)
8219 capture = capture[0]
8220 self.assertFalse(capture.haslayer(IPv6))
8221 self.assertEqual(capture[IP].src, self.nat_addr)
8222 self.assertEqual(capture[IP].dst, self.pg0.remote_ip4)
8223 self.assertNotEqual(capture[TCP].sport, 20001)
8224 self.assertEqual(capture[TCP].dport, 10001)
8225 self.assert_packet_checksums_valid(capture)
8226 out_port = capture[TCP].sport
8228 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
8229 IP(dst=self.nat_addr, src=self.pg0.remote_ip4) /
8230 TCP(sport=10001, dport=out_port))
8231 self.pg0.add_stream(p)
8232 self.pg_enable_capture(self.pg_interfaces)
8234 capture = self.pg1.get_capture(1)
8235 capture = capture[0]
8236 self.assertEqual(capture[IPv6].src, aftr_ip6)
8237 self.assertEqual(capture[IPv6].dst, self.pg1.remote_hosts[1].ip6)
8238 self.assertEqual(capture[IP].src, self.pg0.remote_ip4)
8239 self.assertEqual(capture[IP].dst, '192.168.1.1')
8240 self.assertEqual(capture[TCP].sport, 10001)
8241 self.assertEqual(capture[TCP].dport, 20001)
8242 self.assert_packet_checksums_valid(capture)
8245 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
8246 IPv6(dst=aftr_ip6, src=self.pg1.remote_hosts[1].ip6) /
8247 IP(dst=self.pg0.remote_ip4, src='192.168.1.1') /
8248 ICMP(id=4000, type='echo-request'))
8249 self.pg1.add_stream(p)
8250 self.pg_enable_capture(self.pg_interfaces)
8252 capture = self.pg0.get_capture(1)
8253 capture = capture[0]
8254 self.assertFalse(capture.haslayer(IPv6))
8255 self.assertEqual(capture[IP].src, self.nat_addr)
8256 self.assertEqual(capture[IP].dst, self.pg0.remote_ip4)
8257 self.assertNotEqual(capture[ICMP].id, 4000)
8258 self.assert_packet_checksums_valid(capture)
8259 out_id = capture[ICMP].id
8261 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
8262 IP(dst=self.nat_addr, src=self.pg0.remote_ip4) /
8263 ICMP(id=out_id, type='echo-reply'))
8264 self.pg0.add_stream(p)
8265 self.pg_enable_capture(self.pg_interfaces)
8267 capture = self.pg1.get_capture(1)
8268 capture = capture[0]
8269 self.assertEqual(capture[IPv6].src, aftr_ip6)
8270 self.assertEqual(capture[IPv6].dst, self.pg1.remote_hosts[1].ip6)
8271 self.assertEqual(capture[IP].src, self.pg0.remote_ip4)
8272 self.assertEqual(capture[IP].dst, '192.168.1.1')
8273 self.assertEqual(capture[ICMP].id, 4000)
8274 self.assert_packet_checksums_valid(capture)
8276 # ping DS-Lite AFTR tunnel endpoint address
8277 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
8278 IPv6(src=self.pg1.remote_hosts[1].ip6, dst=aftr_ip6) /
8279 ICMPv6EchoRequest())
8280 self.pg1.add_stream(p)
8281 self.pg_enable_capture(self.pg_interfaces)
8283 capture = self.pg1.get_capture(1)
8284 capture = capture[0]
8285 self.assertEqual(capture[IPv6].src, aftr_ip6)
8286 self.assertEqual(capture[IPv6].dst, self.pg1.remote_hosts[1].ip6)
8287 self.assertTrue(capture.haslayer(ICMPv6EchoReply))
8290 super(TestDSlite, self).tearDown()
8291 if not self.vpp_dead:
8292 self.logger.info(self.vapi.cli("show dslite pool"))
8294 self.vapi.cli("show dslite aftr-tunnel-endpoint-address"))
8295 self.logger.info(self.vapi.cli("show dslite sessions"))
8298 class TestDSliteCE(MethodHolder):
8299 """ DS-Lite CE Test Cases """
8302 def setUpConstants(cls):
8303 super(TestDSliteCE, cls).setUpConstants()
8304 cls.vpp_cmdline.extend(["nat", "{", "dslite ce", "}"])
8307 def setUpClass(cls):
8308 super(TestDSliteCE, cls).setUpClass()
8311 cls.create_pg_interfaces(range(2))
8313 cls.pg0.config_ip4()
8314 cls.pg0.resolve_arp()
8316 cls.pg1.config_ip6()
8317 cls.pg1.generate_remote_hosts(1)
8318 cls.pg1.configure_ipv6_neighbors()
8321 super(TestDSliteCE, cls).tearDownClass()
8324 def test_dslite_ce(self):
8325 """ Test DS-Lite CE """
8327 nat_config = self.vapi.nat_show_config()
8328 self.assertEqual(1, nat_config.dslite_ce)
8330 b4_ip4 = '192.0.0.2'
8331 b4_ip4_n = socket.inet_pton(socket.AF_INET, b4_ip4)
8332 b4_ip6 = '2001:db8:62aa::375e:f4c1:1'
8333 b4_ip6_n = socket.inet_pton(socket.AF_INET6, b4_ip6)
8334 self.vapi.dslite_set_b4_addr(b4_ip6_n, b4_ip4_n)
8336 aftr_ip4 = '192.0.0.1'
8337 aftr_ip4_n = socket.inet_pton(socket.AF_INET, aftr_ip4)
8338 aftr_ip6 = '2001:db8:85a3::8a2e:370:1'
8339 aftr_ip6_n = socket.inet_pton(socket.AF_INET6, aftr_ip6)
8340 self.vapi.dslite_set_aftr_addr(aftr_ip6_n, aftr_ip4_n)
8342 self.vapi.ip_add_del_route(dst_address=aftr_ip6_n,
8343 dst_address_length=128,
8344 next_hop_address=self.pg1.remote_ip6n,
8345 next_hop_sw_if_index=self.pg1.sw_if_index,
8349 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
8350 IP(dst=self.pg1.remote_ip4, src=self.pg0.remote_ip4) /
8351 UDP(sport=10000, dport=20000))
8352 self.pg0.add_stream(p)
8353 self.pg_enable_capture(self.pg_interfaces)
8355 capture = self.pg1.get_capture(1)
8356 capture = capture[0]
8357 self.assertEqual(capture[IPv6].src, b4_ip6)
8358 self.assertEqual(capture[IPv6].dst, aftr_ip6)
8359 self.assertEqual(capture[IP].src, self.pg0.remote_ip4)
8360 self.assertEqual(capture[IP].dst, self.pg1.remote_ip4)
8361 self.assertEqual(capture[UDP].sport, 10000)
8362 self.assertEqual(capture[UDP].dport, 20000)
8363 self.assert_packet_checksums_valid(capture)
8366 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
8367 IPv6(dst=b4_ip6, src=aftr_ip6) /
8368 IP(dst=self.pg0.remote_ip4, src=self.pg1.remote_ip4) /
8369 UDP(sport=20000, dport=10000))
8370 self.pg1.add_stream(p)
8371 self.pg_enable_capture(self.pg_interfaces)
8373 capture = self.pg0.get_capture(1)
8374 capture = capture[0]
8375 self.assertFalse(capture.haslayer(IPv6))
8376 self.assertEqual(capture[IP].src, self.pg1.remote_ip4)
8377 self.assertEqual(capture[IP].dst, self.pg0.remote_ip4)
8378 self.assertEqual(capture[UDP].sport, 20000)
8379 self.assertEqual(capture[UDP].dport, 10000)
8380 self.assert_packet_checksums_valid(capture)
8382 # ping DS-Lite B4 tunnel endpoint address
8383 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
8384 IPv6(src=self.pg1.remote_hosts[0].ip6, dst=b4_ip6) /
8385 ICMPv6EchoRequest())
8386 self.pg1.add_stream(p)
8387 self.pg_enable_capture(self.pg_interfaces)
8389 capture = self.pg1.get_capture(1)
8390 capture = capture[0]
8391 self.assertEqual(capture[IPv6].src, b4_ip6)
8392 self.assertEqual(capture[IPv6].dst, self.pg1.remote_hosts[0].ip6)
8393 self.assertTrue(capture.haslayer(ICMPv6EchoReply))
8396 super(TestDSliteCE, self).tearDown()
8397 if not self.vpp_dead:
8399 self.vapi.cli("show dslite aftr-tunnel-endpoint-address"))
8401 self.vapi.cli("show dslite b4-tunnel-endpoint-address"))
8404 class TestNAT66(MethodHolder):
8405 """ NAT66 Test Cases """
8408 def setUpClass(cls):
8409 super(TestNAT66, cls).setUpClass()
8412 cls.nat_addr = 'fd01:ff::2'
8413 cls.nat_addr_n = socket.inet_pton(socket.AF_INET6, cls.nat_addr)
8415 cls.create_pg_interfaces(range(2))
8416 cls.interfaces = list(cls.pg_interfaces)
8418 for i in cls.interfaces:
8421 i.configure_ipv6_neighbors()
8424 super(TestNAT66, cls).tearDownClass()
8427 def test_static(self):
8428 """ 1:1 NAT66 test """
8429 self.vapi.nat66_add_del_interface(self.pg0.sw_if_index)
8430 self.vapi.nat66_add_del_interface(self.pg1.sw_if_index, is_inside=0)
8431 self.vapi.nat66_add_del_static_mapping(self.pg0.remote_ip6n,
8436 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
8437 IPv6(src=self.pg0.remote_ip6, dst=self.pg1.remote_ip6) /
8440 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
8441 IPv6(src=self.pg0.remote_ip6, dst=self.pg1.remote_ip6) /
8444 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
8445 IPv6(src=self.pg0.remote_ip6, dst=self.pg1.remote_ip6) /
8446 ICMPv6EchoRequest())
8448 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
8449 IPv6(src=self.pg0.remote_ip6, dst=self.pg1.remote_ip6) /
8450 GRE() / IP() / TCP())
8452 self.pg0.add_stream(pkts)
8453 self.pg_enable_capture(self.pg_interfaces)
8455 capture = self.pg1.get_capture(len(pkts))
8456 for packet in capture:
8458 self.assertEqual(packet[IPv6].src, self.nat_addr)
8459 self.assertEqual(packet[IPv6].dst, self.pg1.remote_ip6)
8460 self.assert_packet_checksums_valid(packet)
8462 self.logger.error(ppp("Unexpected or invalid packet:", packet))
8467 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
8468 IPv6(src=self.pg1.remote_ip6, dst=self.nat_addr) /
8471 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
8472 IPv6(src=self.pg1.remote_ip6, dst=self.nat_addr) /
8475 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
8476 IPv6(src=self.pg1.remote_ip6, dst=self.nat_addr) /
8479 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
8480 IPv6(src=self.pg1.remote_ip6, dst=self.nat_addr) /
8481 GRE() / IP() / TCP())
8483 self.pg1.add_stream(pkts)
8484 self.pg_enable_capture(self.pg_interfaces)
8486 capture = self.pg0.get_capture(len(pkts))
8487 for packet in capture:
8489 self.assertEqual(packet[IPv6].src, self.pg1.remote_ip6)
8490 self.assertEqual(packet[IPv6].dst, self.pg0.remote_ip6)
8491 self.assert_packet_checksums_valid(packet)
8493 self.logger.error(ppp("Unexpected or invalid packet:", packet))
8496 sm = self.vapi.nat66_static_mapping_dump()
8497 self.assertEqual(len(sm), 1)
8498 self.assertEqual(sm[0].total_pkts, 8)
8500 def test_check_no_translate(self):
8501 """ NAT66 translate only when egress interface is outside interface """
8502 self.vapi.nat66_add_del_interface(self.pg0.sw_if_index)
8503 self.vapi.nat66_add_del_interface(self.pg1.sw_if_index)
8504 self.vapi.nat66_add_del_static_mapping(self.pg0.remote_ip6n,
8508 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
8509 IPv6(src=self.pg0.remote_ip6, dst=self.pg1.remote_ip6) /
8511 self.pg0.add_stream([p])
8512 self.pg_enable_capture(self.pg_interfaces)
8514 capture = self.pg1.get_capture(1)
8517 self.assertEqual(packet[IPv6].src, self.pg0.remote_ip6)
8518 self.assertEqual(packet[IPv6].dst, self.pg1.remote_ip6)
8520 self.logger.error(ppp("Unexpected or invalid packet:", packet))
8523 def clear_nat66(self):
8525 Clear NAT66 configuration.
8527 interfaces = self.vapi.nat66_interface_dump()
8528 for intf in interfaces:
8529 self.vapi.nat66_add_del_interface(intf.sw_if_index,
8533 static_mappings = self.vapi.nat66_static_mapping_dump()
8534 for sm in static_mappings:
8535 self.vapi.nat66_add_del_static_mapping(sm.local_ip_address,
8536 sm.external_ip_address,
8541 super(TestNAT66, self).tearDown()
8542 if not self.vpp_dead:
8543 self.logger.info(self.vapi.cli("show nat66 interfaces"))
8544 self.logger.info(self.vapi.cli("show nat66 static mappings"))
8548 if __name__ == '__main__':
8549 unittest.main(testRunner=VppTestRunner)