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_mac import mactobinary
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 mactobinary(self.pg7.remote_mac),
2956 self.pg7.remote_ip4n,
2958 self.vapi.ip_neighbor_add_del(self.pg8.sw_if_index,
2959 mactobinary(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 mactobinary(self.pg7.remote_mac),
2998 self.pg7.remote_ip4n,
3000 self.vapi.ip_neighbor_add_del(self.pg8.sw_if_index,
3001 mactobinary(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 mactobinary(self.pg7.remote_mac),
3044 self.pg7.remote_ip4n,
3046 self.vapi.ip_neighbor_add_del(self.pg8.sw_if_index,
3047 mactobinary(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]
4273 locals = [{'addr': server1.ip4n,
4277 {'addr': server2.ip4n,
4282 self.nat44_add_address(self.nat_addr)
4283 self.vapi.nat44_add_del_lb_static_mapping(external_addr_n,
4286 local_num=len(locals),
4288 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
4289 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
4294 clients = ip4_range(self.pg1.remote_ip4, 10, 50)
4296 for client in clients:
4297 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
4298 IP(src=client, dst=self.nat_addr) /
4299 TCP(sport=12345, dport=external_port))
4301 self.pg1.add_stream(pkts)
4302 self.pg_enable_capture(self.pg_interfaces)
4304 capture = self.pg0.get_capture(len(pkts))
4306 if p[IP].dst == server1.ip4:
4310 self.assertGreater(server1_n, server2_n)
4312 def test_static_lb_2(self):
4313 """ NAT44 local service load balancing (asymmetrical rule) """
4314 external_addr_n = socket.inet_pton(socket.AF_INET, self.nat_addr)
4317 server1 = self.pg0.remote_hosts[0]
4318 server2 = self.pg0.remote_hosts[1]
4320 locals = [{'addr': server1.ip4n,
4324 {'addr': server2.ip4n,
4329 self.vapi.nat44_forwarding_enable_disable(1)
4330 self.vapi.nat44_add_del_lb_static_mapping(external_addr_n,
4334 local_num=len(locals),
4336 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
4337 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
4340 # from client to service
4341 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
4342 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
4343 TCP(sport=12345, dport=external_port))
4344 self.pg1.add_stream(p)
4345 self.pg_enable_capture(self.pg_interfaces)
4347 capture = self.pg0.get_capture(1)
4353 self.assertIn(ip.dst, [server1.ip4, server2.ip4])
4354 if ip.dst == server1.ip4:
4358 self.assertEqual(tcp.dport, local_port)
4359 self.assert_packet_checksums_valid(p)
4361 self.logger.error(ppp("Unexpected or invalid packet:", p))
4364 # from service back to client
4365 p = (Ether(src=server.mac, dst=self.pg0.local_mac) /
4366 IP(src=server.ip4, dst=self.pg1.remote_ip4) /
4367 TCP(sport=local_port, dport=12345))
4368 self.pg0.add_stream(p)
4369 self.pg_enable_capture(self.pg_interfaces)
4371 capture = self.pg1.get_capture(1)
4376 self.assertEqual(ip.src, self.nat_addr)
4377 self.assertEqual(tcp.sport, external_port)
4378 self.assert_packet_checksums_valid(p)
4380 self.logger.error(ppp("Unexpected or invalid packet:", p))
4383 # from client to server (no translation)
4384 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
4385 IP(src=self.pg1.remote_ip4, dst=server1.ip4) /
4386 TCP(sport=12346, dport=local_port))
4387 self.pg1.add_stream(p)
4388 self.pg_enable_capture(self.pg_interfaces)
4390 capture = self.pg0.get_capture(1)
4396 self.assertEqual(ip.dst, server1.ip4)
4397 self.assertEqual(tcp.dport, local_port)
4398 self.assert_packet_checksums_valid(p)
4400 self.logger.error(ppp("Unexpected or invalid packet:", p))
4403 # from service back to client (no translation)
4404 p = (Ether(src=server1.mac, dst=self.pg0.local_mac) /
4405 IP(src=server1.ip4, dst=self.pg1.remote_ip4) /
4406 TCP(sport=local_port, dport=12346))
4407 self.pg0.add_stream(p)
4408 self.pg_enable_capture(self.pg_interfaces)
4410 capture = self.pg1.get_capture(1)
4415 self.assertEqual(ip.src, server1.ip4)
4416 self.assertEqual(tcp.sport, local_port)
4417 self.assert_packet_checksums_valid(p)
4419 self.logger.error(ppp("Unexpected or invalid packet:", p))
4422 def test_lb_affinity(self):
4423 """ NAT44 local service load balancing affinity """
4424 external_addr_n = socket.inet_pton(socket.AF_INET, self.nat_addr)
4427 server1 = self.pg0.remote_hosts[0]
4428 server2 = self.pg0.remote_hosts[1]
4430 locals = [{'addr': server1.ip4n,
4434 {'addr': server2.ip4n,
4439 self.nat44_add_address(self.nat_addr)
4440 self.vapi.nat44_add_del_lb_static_mapping(external_addr_n,
4444 local_num=len(locals),
4446 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
4447 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
4450 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
4451 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
4452 TCP(sport=1025, dport=external_port))
4453 self.pg1.add_stream(p)
4454 self.pg_enable_capture(self.pg_interfaces)
4456 capture = self.pg0.get_capture(1)
4457 backend = capture[0][IP].dst
4459 sessions = self.vapi.nat44_user_session_dump(
4460 socket.inet_pton(socket.AF_INET, backend), 0)
4461 self.assertEqual(len(sessions), 1)
4462 self.assertTrue(sessions[0].ext_host_valid)
4463 self.vapi.nat44_del_session(
4464 sessions[0].inside_ip_address,
4465 sessions[0].inside_port,
4466 sessions[0].protocol,
4467 ext_host_address=sessions[0].ext_host_address,
4468 ext_host_port=sessions[0].ext_host_port)
4471 for port in range(1030, 1100):
4472 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
4473 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
4474 TCP(sport=port, dport=external_port))
4476 self.pg1.add_stream(pkts)
4477 self.pg_enable_capture(self.pg_interfaces)
4479 capture = self.pg0.get_capture(len(pkts))
4481 self.assertEqual(p[IP].dst, backend)
4483 def test_unknown_proto(self):
4484 """ NAT44 translate packet with unknown protocol """
4485 self.nat44_add_address(self.nat_addr)
4486 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
4487 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
4491 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
4492 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
4493 TCP(sport=self.tcp_port_in, dport=20))
4494 self.pg0.add_stream(p)
4495 self.pg_enable_capture(self.pg_interfaces)
4497 p = self.pg1.get_capture(1)
4499 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
4500 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
4502 IP(src=self.pg2.remote_ip4, dst=self.pg2.remote_ip4) /
4503 TCP(sport=1234, dport=1234))
4504 self.pg0.add_stream(p)
4505 self.pg_enable_capture(self.pg_interfaces)
4507 p = self.pg1.get_capture(1)
4510 self.assertEqual(packet[IP].src, self.nat_addr)
4511 self.assertEqual(packet[IP].dst, self.pg1.remote_ip4)
4512 self.assertEqual(packet.haslayer(GRE), 1)
4513 self.assert_packet_checksums_valid(packet)
4515 self.logger.error(ppp("Unexpected or invalid packet:", packet))
4519 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
4520 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
4522 IP(src=self.pg2.remote_ip4, dst=self.pg2.remote_ip4) /
4523 TCP(sport=1234, dport=1234))
4524 self.pg1.add_stream(p)
4525 self.pg_enable_capture(self.pg_interfaces)
4527 p = self.pg0.get_capture(1)
4530 self.assertEqual(packet[IP].src, self.pg1.remote_ip4)
4531 self.assertEqual(packet[IP].dst, self.pg0.remote_ip4)
4532 self.assertEqual(packet.haslayer(GRE), 1)
4533 self.assert_packet_checksums_valid(packet)
4535 self.logger.error(ppp("Unexpected or invalid packet:", packet))
4538 def test_hairpinning_unknown_proto(self):
4539 """ NAT44 translate packet with unknown protocol - hairpinning """
4540 host = self.pg0.remote_hosts[0]
4541 server = self.pg0.remote_hosts[1]
4543 server_out_port = 8765
4544 server_nat_ip = "10.0.0.11"
4546 self.nat44_add_address(self.nat_addr)
4547 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
4548 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
4551 # add static mapping for server
4552 self.nat44_add_static_mapping(server.ip4, server_nat_ip)
4555 p = (Ether(src=host.mac, dst=self.pg0.local_mac) /
4556 IP(src=host.ip4, dst=server_nat_ip) /
4557 TCP(sport=host_in_port, dport=server_out_port))
4558 self.pg0.add_stream(p)
4559 self.pg_enable_capture(self.pg_interfaces)
4561 self.pg0.get_capture(1)
4563 p = (Ether(dst=self.pg0.local_mac, src=host.mac) /
4564 IP(src=host.ip4, dst=server_nat_ip) /
4566 IP(src=self.pg2.remote_ip4, dst=self.pg2.remote_ip4) /
4567 TCP(sport=1234, dport=1234))
4568 self.pg0.add_stream(p)
4569 self.pg_enable_capture(self.pg_interfaces)
4571 p = self.pg0.get_capture(1)
4574 self.assertEqual(packet[IP].src, self.nat_addr)
4575 self.assertEqual(packet[IP].dst, server.ip4)
4576 self.assertEqual(packet.haslayer(GRE), 1)
4577 self.assert_packet_checksums_valid(packet)
4579 self.logger.error(ppp("Unexpected or invalid packet:", packet))
4583 p = (Ether(dst=self.pg0.local_mac, src=server.mac) /
4584 IP(src=server.ip4, dst=self.nat_addr) /
4586 IP(src=self.pg2.remote_ip4, dst=self.pg2.remote_ip4) /
4587 TCP(sport=1234, dport=1234))
4588 self.pg0.add_stream(p)
4589 self.pg_enable_capture(self.pg_interfaces)
4591 p = self.pg0.get_capture(1)
4594 self.assertEqual(packet[IP].src, server_nat_ip)
4595 self.assertEqual(packet[IP].dst, host.ip4)
4596 self.assertEqual(packet.haslayer(GRE), 1)
4597 self.assert_packet_checksums_valid(packet)
4599 self.logger.error(ppp("Unexpected or invalid packet:", packet))
4602 def test_output_feature_and_service(self):
4603 """ NAT44 interface output feature and services """
4604 external_addr = '1.2.3.4'
4608 self.vapi.nat44_forwarding_enable_disable(1)
4609 self.nat44_add_address(self.nat_addr)
4610 self.vapi.nat44_add_del_identity_mapping(ip=self.pg1.remote_ip4n)
4611 self.nat44_add_static_mapping(self.pg0.remote_ip4, external_addr,
4612 local_port, external_port,
4613 proto=IP_PROTOS.tcp, out2in_only=1)
4614 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
4615 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index,
4617 self.vapi.nat44_interface_add_del_output_feature(self.pg1.sw_if_index,
4620 # from client to service
4621 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
4622 IP(src=self.pg1.remote_ip4, dst=external_addr) /
4623 TCP(sport=12345, dport=external_port))
4624 self.pg1.add_stream(p)
4625 self.pg_enable_capture(self.pg_interfaces)
4627 capture = self.pg0.get_capture(1)
4632 self.assertEqual(ip.dst, self.pg0.remote_ip4)
4633 self.assertEqual(tcp.dport, local_port)
4634 self.assert_packet_checksums_valid(p)
4636 self.logger.error(ppp("Unexpected or invalid packet:", p))
4639 # from service back to client
4640 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
4641 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
4642 TCP(sport=local_port, dport=12345))
4643 self.pg0.add_stream(p)
4644 self.pg_enable_capture(self.pg_interfaces)
4646 capture = self.pg1.get_capture(1)
4651 self.assertEqual(ip.src, external_addr)
4652 self.assertEqual(tcp.sport, external_port)
4653 self.assert_packet_checksums_valid(p)
4655 self.logger.error(ppp("Unexpected or invalid packet:", p))
4658 # from local network host to external network
4659 pkts = self.create_stream_in(self.pg0, self.pg1)
4660 self.pg0.add_stream(pkts)
4661 self.pg_enable_capture(self.pg_interfaces)
4663 capture = self.pg1.get_capture(len(pkts))
4664 self.verify_capture_out(capture)
4665 pkts = self.create_stream_in(self.pg0, self.pg1)
4666 self.pg0.add_stream(pkts)
4667 self.pg_enable_capture(self.pg_interfaces)
4669 capture = self.pg1.get_capture(len(pkts))
4670 self.verify_capture_out(capture)
4672 # from external network back to local network host
4673 pkts = self.create_stream_out(self.pg1)
4674 self.pg1.add_stream(pkts)
4675 self.pg_enable_capture(self.pg_interfaces)
4677 capture = self.pg0.get_capture(len(pkts))
4678 self.verify_capture_in(capture, self.pg0)
4680 def test_output_feature_and_service2(self):
4681 """ NAT44 interface output feature and service host direct access """
4682 self.vapi.nat44_forwarding_enable_disable(1)
4683 self.nat44_add_address(self.nat_addr)
4684 self.vapi.nat44_interface_add_del_output_feature(self.pg1.sw_if_index,
4687 # session initiaded from service host - translate
4688 pkts = self.create_stream_in(self.pg0, self.pg1)
4689 self.pg0.add_stream(pkts)
4690 self.pg_enable_capture(self.pg_interfaces)
4692 capture = self.pg1.get_capture(len(pkts))
4693 self.verify_capture_out(capture)
4695 pkts = self.create_stream_out(self.pg1)
4696 self.pg1.add_stream(pkts)
4697 self.pg_enable_capture(self.pg_interfaces)
4699 capture = self.pg0.get_capture(len(pkts))
4700 self.verify_capture_in(capture, self.pg0)
4702 # session initiaded from remote host - do not translate
4703 self.tcp_port_in = 60303
4704 self.udp_port_in = 60304
4705 self.icmp_id_in = 60305
4706 pkts = self.create_stream_out(self.pg1,
4707 self.pg0.remote_ip4,
4708 use_inside_ports=True)
4709 self.pg1.add_stream(pkts)
4710 self.pg_enable_capture(self.pg_interfaces)
4712 capture = self.pg0.get_capture(len(pkts))
4713 self.verify_capture_in(capture, self.pg0)
4715 pkts = self.create_stream_in(self.pg0, self.pg1)
4716 self.pg0.add_stream(pkts)
4717 self.pg_enable_capture(self.pg_interfaces)
4719 capture = self.pg1.get_capture(len(pkts))
4720 self.verify_capture_out(capture, nat_ip=self.pg0.remote_ip4,
4723 def test_output_feature_and_service3(self):
4724 """ NAT44 interface output feature and DST NAT """
4725 external_addr = '1.2.3.4'
4729 self.vapi.nat44_forwarding_enable_disable(1)
4730 self.nat44_add_address(self.nat_addr)
4731 self.nat44_add_static_mapping(self.pg1.remote_ip4, external_addr,
4732 local_port, external_port,
4733 proto=IP_PROTOS.tcp, out2in_only=1)
4734 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
4735 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index,
4737 self.vapi.nat44_interface_add_del_output_feature(self.pg1.sw_if_index,
4740 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
4741 IP(src=self.pg0.remote_ip4, dst=external_addr) /
4742 TCP(sport=12345, dport=external_port))
4743 self.pg0.add_stream(p)
4744 self.pg_enable_capture(self.pg_interfaces)
4746 capture = self.pg1.get_capture(1)
4751 self.assertEqual(ip.src, self.pg0.remote_ip4)
4752 self.assertEqual(tcp.sport, 12345)
4753 self.assertEqual(ip.dst, self.pg1.remote_ip4)
4754 self.assertEqual(tcp.dport, local_port)
4755 self.assert_packet_checksums_valid(p)
4757 self.logger.error(ppp("Unexpected or invalid packet:", p))
4760 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
4761 IP(src=self.pg1.remote_ip4, dst=self.pg0.remote_ip4) /
4762 TCP(sport=local_port, dport=12345))
4763 self.pg1.add_stream(p)
4764 self.pg_enable_capture(self.pg_interfaces)
4766 capture = self.pg0.get_capture(1)
4771 self.assertEqual(ip.src, external_addr)
4772 self.assertEqual(tcp.sport, external_port)
4773 self.assertEqual(ip.dst, self.pg0.remote_ip4)
4774 self.assertEqual(tcp.dport, 12345)
4775 self.assert_packet_checksums_valid(p)
4777 self.logger.error(ppp("Unexpected or invalid packet:", p))
4780 def test_next_src_nat(self):
4781 """ On way back forward packet to nat44-in2out node. """
4782 twice_nat_addr = '10.0.1.3'
4785 post_twice_nat_port = 0
4787 self.vapi.nat44_forwarding_enable_disable(1)
4788 self.nat44_add_address(twice_nat_addr, twice_nat=1)
4789 self.nat44_add_static_mapping(self.pg6.remote_ip4, self.pg1.remote_ip4,
4790 local_port, external_port,
4791 proto=IP_PROTOS.tcp, out2in_only=1,
4792 self_twice_nat=1, vrf_id=1)
4793 self.vapi.nat44_interface_add_del_feature(self.pg6.sw_if_index,
4796 p = (Ether(src=self.pg6.remote_mac, dst=self.pg6.local_mac) /
4797 IP(src=self.pg6.remote_ip4, dst=self.pg1.remote_ip4) /
4798 TCP(sport=12345, dport=external_port))
4799 self.pg6.add_stream(p)
4800 self.pg_enable_capture(self.pg_interfaces)
4802 capture = self.pg6.get_capture(1)
4807 self.assertEqual(ip.src, twice_nat_addr)
4808 self.assertNotEqual(tcp.sport, 12345)
4809 post_twice_nat_port = tcp.sport
4810 self.assertEqual(ip.dst, self.pg6.remote_ip4)
4811 self.assertEqual(tcp.dport, local_port)
4812 self.assert_packet_checksums_valid(p)
4814 self.logger.error(ppp("Unexpected or invalid packet:", p))
4817 p = (Ether(src=self.pg6.remote_mac, dst=self.pg6.local_mac) /
4818 IP(src=self.pg6.remote_ip4, dst=twice_nat_addr) /
4819 TCP(sport=local_port, dport=post_twice_nat_port))
4820 self.pg6.add_stream(p)
4821 self.pg_enable_capture(self.pg_interfaces)
4823 capture = self.pg6.get_capture(1)
4828 self.assertEqual(ip.src, self.pg1.remote_ip4)
4829 self.assertEqual(tcp.sport, external_port)
4830 self.assertEqual(ip.dst, self.pg6.remote_ip4)
4831 self.assertEqual(tcp.dport, 12345)
4832 self.assert_packet_checksums_valid(p)
4834 self.logger.error(ppp("Unexpected or invalid packet:", p))
4837 def twice_nat_common(self, self_twice_nat=False, same_pg=False, lb=False,
4839 twice_nat_addr = '10.0.1.3'
4847 port_in1 = port_in+1
4848 port_in2 = port_in+2
4853 server1 = self.pg0.remote_hosts[0]
4854 server2 = self.pg0.remote_hosts[1]
4866 eh_translate = ((not self_twice_nat) or (not lb and same_pg) or
4869 self.nat44_add_address(self.nat_addr)
4870 self.nat44_add_address(twice_nat_addr, twice_nat=1)
4872 self.nat44_add_static_mapping(pg0.remote_ip4, self.nat_addr,
4874 proto=IP_PROTOS.tcp,
4875 twice_nat=int(not self_twice_nat),
4876 self_twice_nat=int(self_twice_nat))
4878 locals = [{'addr': server1.ip4n,
4882 {'addr': server2.ip4n,
4886 out_addr_n = socket.inet_pton(socket.AF_INET, self.nat_addr)
4887 self.vapi.nat44_add_del_lb_static_mapping(out_addr_n,
4891 not self_twice_nat),
4894 local_num=len(locals),
4896 self.vapi.nat44_interface_add_del_feature(pg0.sw_if_index)
4897 self.vapi.nat44_interface_add_del_feature(pg1.sw_if_index,
4904 assert client_id is not None
4906 client = self.pg0.remote_hosts[0]
4907 elif client_id == 2:
4908 client = self.pg0.remote_hosts[1]
4910 client = pg1.remote_hosts[0]
4911 p = (Ether(src=pg1.remote_mac, dst=pg1.local_mac) /
4912 IP(src=client.ip4, dst=self.nat_addr) /
4913 TCP(sport=eh_port_out, dport=port_out))
4915 self.pg_enable_capture(self.pg_interfaces)
4917 capture = pg0.get_capture(1)
4923 if ip.dst == server1.ip4:
4929 self.assertEqual(ip.dst, server.ip4)
4931 self.assertIn(tcp.dport, [port_in1, port_in2])
4933 self.assertEqual(tcp.dport, port_in)
4935 self.assertEqual(ip.src, twice_nat_addr)
4936 self.assertNotEqual(tcp.sport, eh_port_out)
4938 self.assertEqual(ip.src, client.ip4)
4939 self.assertEqual(tcp.sport, eh_port_out)
4941 eh_port_in = tcp.sport
4942 saved_port_in = tcp.dport
4943 self.assert_packet_checksums_valid(p)
4945 self.logger.error(ppp("Unexpected or invalid packet:", p))
4948 p = (Ether(src=server.mac, dst=pg0.local_mac) /
4949 IP(src=server.ip4, dst=eh_addr_in) /
4950 TCP(sport=saved_port_in, dport=eh_port_in))
4952 self.pg_enable_capture(self.pg_interfaces)
4954 capture = pg1.get_capture(1)
4959 self.assertEqual(ip.dst, client.ip4)
4960 self.assertEqual(ip.src, self.nat_addr)
4961 self.assertEqual(tcp.dport, eh_port_out)
4962 self.assertEqual(tcp.sport, port_out)
4963 self.assert_packet_checksums_valid(p)
4965 self.logger.error(ppp("Unexpected or invalid packet:", p))
4969 sessions = self.vapi.nat44_user_session_dump(server.ip4n, 0)
4970 self.assertEqual(len(sessions), 1)
4971 self.assertTrue(sessions[0].ext_host_valid)
4972 self.assertTrue(sessions[0].is_twicenat)
4973 self.vapi.nat44_del_session(
4974 sessions[0].inside_ip_address,
4975 sessions[0].inside_port,
4976 sessions[0].protocol,
4977 ext_host_address=sessions[0].ext_host_nat_address,
4978 ext_host_port=sessions[0].ext_host_nat_port)
4979 sessions = self.vapi.nat44_user_session_dump(server.ip4n, 0)
4980 self.assertEqual(len(sessions), 0)
4982 def test_twice_nat(self):
4984 self.twice_nat_common()
4986 def test_self_twice_nat_positive(self):
4987 """ Self Twice NAT44 (positive test) """
4988 self.twice_nat_common(self_twice_nat=True, same_pg=True)
4990 def test_self_twice_nat_negative(self):
4991 """ Self Twice NAT44 (negative test) """
4992 self.twice_nat_common(self_twice_nat=True)
4994 def test_twice_nat_lb(self):
4995 """ Twice NAT44 local service load balancing """
4996 self.twice_nat_common(lb=True)
4998 def test_self_twice_nat_lb_positive(self):
4999 """ Self Twice NAT44 local service load balancing (positive test) """
5000 self.twice_nat_common(lb=True, self_twice_nat=True, same_pg=True,
5003 def test_self_twice_nat_lb_negative(self):
5004 """ Self Twice NAT44 local service load balancing (negative test) """
5005 self.twice_nat_common(lb=True, self_twice_nat=True, same_pg=True,
5008 def test_twice_nat_interface_addr(self):
5009 """ Acquire twice NAT44 addresses from interface """
5010 self.vapi.nat44_add_interface_addr(self.pg3.sw_if_index, twice_nat=1)
5012 # no address in NAT pool
5013 adresses = self.vapi.nat44_address_dump()
5014 self.assertEqual(0, len(adresses))
5016 # configure interface address and check NAT address pool
5017 self.pg3.config_ip4()
5018 adresses = self.vapi.nat44_address_dump()
5019 self.assertEqual(1, len(adresses))
5020 self.assertEqual(adresses[0].ip_address[0:4], self.pg3.local_ip4n)
5021 self.assertEqual(adresses[0].twice_nat, 1)
5023 # remove interface address and check NAT address pool
5024 self.pg3.unconfig_ip4()
5025 adresses = self.vapi.nat44_address_dump()
5026 self.assertEqual(0, len(adresses))
5028 def test_tcp_close(self):
5029 """ Close TCP session from inside network - output feature """
5030 self.vapi.nat44_forwarding_enable_disable(1)
5031 self.nat44_add_address(self.pg1.local_ip4)
5032 twice_nat_addr = '10.0.1.3'
5033 service_ip = '192.168.16.150'
5034 self.nat44_add_address(twice_nat_addr, twice_nat=1)
5035 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
5036 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index,
5038 self.vapi.nat44_interface_add_del_output_feature(self.pg1.sw_if_index,
5040 self.nat44_add_static_mapping(self.pg0.remote_ip4,
5044 proto=IP_PROTOS.tcp,
5047 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4n, 0)
5048 start_sessnum = len(sessions)
5050 # SYN packet out->in
5051 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
5052 IP(src=self.pg1.remote_ip4, dst=service_ip) /
5053 TCP(sport=33898, dport=80, flags="S"))
5054 self.pg1.add_stream(p)
5055 self.pg_enable_capture(self.pg_interfaces)
5057 capture = self.pg0.get_capture(1)
5059 tcp_port = p[TCP].sport
5061 # SYN + ACK packet in->out
5062 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5063 IP(src=self.pg0.remote_ip4, dst=twice_nat_addr) /
5064 TCP(sport=80, dport=tcp_port, flags="SA"))
5065 self.pg0.add_stream(p)
5066 self.pg_enable_capture(self.pg_interfaces)
5068 self.pg1.get_capture(1)
5070 # ACK packet out->in
5071 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
5072 IP(src=self.pg1.remote_ip4, dst=service_ip) /
5073 TCP(sport=33898, dport=80, flags="A"))
5074 self.pg1.add_stream(p)
5075 self.pg_enable_capture(self.pg_interfaces)
5077 self.pg0.get_capture(1)
5079 # FIN packet in -> out
5080 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5081 IP(src=self.pg0.remote_ip4, dst=twice_nat_addr) /
5082 TCP(sport=80, dport=tcp_port, flags="FA", seq=100, ack=300))
5083 self.pg0.add_stream(p)
5084 self.pg_enable_capture(self.pg_interfaces)
5086 self.pg1.get_capture(1)
5088 # FIN+ACK packet out -> in
5089 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
5090 IP(src=self.pg1.remote_ip4, dst=service_ip) /
5091 TCP(sport=33898, dport=80, flags="FA", seq=300, ack=101))
5092 self.pg1.add_stream(p)
5093 self.pg_enable_capture(self.pg_interfaces)
5095 self.pg0.get_capture(1)
5097 # ACK packet in -> out
5098 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5099 IP(src=self.pg0.remote_ip4, dst=twice_nat_addr) /
5100 TCP(sport=80, dport=tcp_port, flags="A", seq=101, ack=301))
5101 self.pg0.add_stream(p)
5102 self.pg_enable_capture(self.pg_interfaces)
5104 self.pg1.get_capture(1)
5106 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4n,
5108 self.assertEqual(len(sessions) - start_sessnum, 0)
5110 def test_tcp_session_close_in(self):
5111 """ Close TCP session from inside network """
5112 self.tcp_port_out = 10505
5113 self.nat44_add_address(self.nat_addr)
5114 self.nat44_add_static_mapping(self.pg0.remote_ip4,
5118 proto=IP_PROTOS.tcp,
5120 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
5121 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
5124 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4n, 0)
5125 start_sessnum = len(sessions)
5127 self.initiate_tcp_session(self.pg0, self.pg1)
5129 # FIN packet in -> out
5130 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5131 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
5132 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
5133 flags="FA", seq=100, ack=300))
5134 self.pg0.add_stream(p)
5135 self.pg_enable_capture(self.pg_interfaces)
5137 self.pg1.get_capture(1)
5141 # ACK packet out -> in
5142 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
5143 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
5144 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
5145 flags="A", seq=300, ack=101))
5148 # FIN packet out -> in
5149 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
5150 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
5151 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
5152 flags="FA", seq=300, ack=101))
5155 self.pg1.add_stream(pkts)
5156 self.pg_enable_capture(self.pg_interfaces)
5158 self.pg0.get_capture(2)
5160 # ACK packet in -> out
5161 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5162 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
5163 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
5164 flags="A", seq=101, ack=301))
5165 self.pg0.add_stream(p)
5166 self.pg_enable_capture(self.pg_interfaces)
5168 self.pg1.get_capture(1)
5170 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4n,
5172 self.assertEqual(len(sessions) - start_sessnum, 0)
5174 def test_tcp_session_close_out(self):
5175 """ Close TCP session from outside network """
5176 self.tcp_port_out = 10505
5177 self.nat44_add_address(self.nat_addr)
5178 self.nat44_add_static_mapping(self.pg0.remote_ip4,
5182 proto=IP_PROTOS.tcp,
5184 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
5185 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
5188 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4n, 0)
5189 start_sessnum = len(sessions)
5191 self.initiate_tcp_session(self.pg0, self.pg1)
5193 # FIN packet out -> in
5194 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
5195 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
5196 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
5197 flags="FA", seq=100, ack=300))
5198 self.pg1.add_stream(p)
5199 self.pg_enable_capture(self.pg_interfaces)
5201 self.pg0.get_capture(1)
5203 # FIN+ACK packet in -> out
5204 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5205 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
5206 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
5207 flags="FA", seq=300, ack=101))
5209 self.pg0.add_stream(p)
5210 self.pg_enable_capture(self.pg_interfaces)
5212 self.pg1.get_capture(1)
5214 # ACK packet out -> in
5215 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
5216 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
5217 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
5218 flags="A", seq=101, ack=301))
5219 self.pg1.add_stream(p)
5220 self.pg_enable_capture(self.pg_interfaces)
5222 self.pg0.get_capture(1)
5224 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4n,
5226 self.assertEqual(len(sessions) - start_sessnum, 0)
5228 def test_tcp_session_close_simultaneous(self):
5229 """ Close TCP session from inside network """
5230 self.tcp_port_out = 10505
5231 self.nat44_add_address(self.nat_addr)
5232 self.nat44_add_static_mapping(self.pg0.remote_ip4,
5236 proto=IP_PROTOS.tcp,
5238 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
5239 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
5242 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4n, 0)
5243 start_sessnum = len(sessions)
5245 self.initiate_tcp_session(self.pg0, self.pg1)
5247 # FIN packet in -> out
5248 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5249 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
5250 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
5251 flags="FA", seq=100, ack=300))
5252 self.pg0.add_stream(p)
5253 self.pg_enable_capture(self.pg_interfaces)
5255 self.pg1.get_capture(1)
5257 # FIN packet out -> in
5258 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
5259 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
5260 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
5261 flags="FA", seq=300, ack=100))
5262 self.pg1.add_stream(p)
5263 self.pg_enable_capture(self.pg_interfaces)
5265 self.pg0.get_capture(1)
5267 # ACK packet in -> out
5268 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5269 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
5270 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
5271 flags="A", seq=101, ack=301))
5272 self.pg0.add_stream(p)
5273 self.pg_enable_capture(self.pg_interfaces)
5275 self.pg1.get_capture(1)
5277 # ACK packet out -> in
5278 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
5279 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
5280 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
5281 flags="A", seq=301, ack=101))
5282 self.pg1.add_stream(p)
5283 self.pg_enable_capture(self.pg_interfaces)
5285 self.pg0.get_capture(1)
5287 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4n,
5289 self.assertEqual(len(sessions) - start_sessnum, 0)
5291 def test_one_armed_nat44_static(self):
5292 """ One armed NAT44 and 1:1 NAPT asymmetrical rule """
5293 remote_host = self.pg4.remote_hosts[0]
5294 local_host = self.pg4.remote_hosts[1]
5299 self.vapi.nat44_forwarding_enable_disable(1)
5300 self.nat44_add_address(self.nat_addr, twice_nat=1)
5301 self.nat44_add_static_mapping(local_host.ip4, self.nat_addr,
5302 local_port, external_port,
5303 proto=IP_PROTOS.tcp, out2in_only=1,
5305 self.vapi.nat44_interface_add_del_feature(self.pg4.sw_if_index)
5306 self.vapi.nat44_interface_add_del_feature(self.pg4.sw_if_index,
5309 # from client to service
5310 p = (Ether(src=self.pg4.remote_mac, dst=self.pg4.local_mac) /
5311 IP(src=remote_host.ip4, dst=self.nat_addr) /
5312 TCP(sport=12345, dport=external_port))
5313 self.pg4.add_stream(p)
5314 self.pg_enable_capture(self.pg_interfaces)
5316 capture = self.pg4.get_capture(1)
5321 self.assertEqual(ip.dst, local_host.ip4)
5322 self.assertEqual(ip.src, self.nat_addr)
5323 self.assertEqual(tcp.dport, local_port)
5324 self.assertNotEqual(tcp.sport, 12345)
5325 eh_port_in = tcp.sport
5326 self.assert_packet_checksums_valid(p)
5328 self.logger.error(ppp("Unexpected or invalid packet:", p))
5331 # from service back to client
5332 p = (Ether(src=self.pg4.remote_mac, dst=self.pg4.local_mac) /
5333 IP(src=local_host.ip4, dst=self.nat_addr) /
5334 TCP(sport=local_port, dport=eh_port_in))
5335 self.pg4.add_stream(p)
5336 self.pg_enable_capture(self.pg_interfaces)
5338 capture = self.pg4.get_capture(1)
5343 self.assertEqual(ip.src, self.nat_addr)
5344 self.assertEqual(ip.dst, remote_host.ip4)
5345 self.assertEqual(tcp.sport, external_port)
5346 self.assertEqual(tcp.dport, 12345)
5347 self.assert_packet_checksums_valid(p)
5349 self.logger.error(ppp("Unexpected or invalid packet:", p))
5352 def test_static_with_port_out2(self):
5353 """ 1:1 NAPT asymmetrical rule """
5358 self.vapi.nat44_forwarding_enable_disable(1)
5359 self.nat44_add_static_mapping(self.pg0.remote_ip4, self.nat_addr,
5360 local_port, external_port,
5361 proto=IP_PROTOS.tcp, out2in_only=1)
5362 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
5363 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
5366 # from client to service
5367 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
5368 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
5369 TCP(sport=12345, dport=external_port))
5370 self.pg1.add_stream(p)
5371 self.pg_enable_capture(self.pg_interfaces)
5373 capture = self.pg0.get_capture(1)
5378 self.assertEqual(ip.dst, self.pg0.remote_ip4)
5379 self.assertEqual(tcp.dport, local_port)
5380 self.assert_packet_checksums_valid(p)
5382 self.logger.error(ppp("Unexpected or invalid packet:", p))
5386 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
5387 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
5388 ICMP(type=11) / capture[0][IP])
5389 self.pg0.add_stream(p)
5390 self.pg_enable_capture(self.pg_interfaces)
5392 capture = self.pg1.get_capture(1)
5395 self.assertEqual(p[IP].src, self.nat_addr)
5397 self.assertEqual(inner.dst, self.nat_addr)
5398 self.assertEqual(inner[TCPerror].dport, external_port)
5400 self.logger.error(ppp("Unexpected or invalid packet:", p))
5403 # from service back to client
5404 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5405 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
5406 TCP(sport=local_port, dport=12345))
5407 self.pg0.add_stream(p)
5408 self.pg_enable_capture(self.pg_interfaces)
5410 capture = self.pg1.get_capture(1)
5415 self.assertEqual(ip.src, self.nat_addr)
5416 self.assertEqual(tcp.sport, external_port)
5417 self.assert_packet_checksums_valid(p)
5419 self.logger.error(ppp("Unexpected or invalid packet:", p))
5423 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
5424 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
5425 ICMP(type=11) / capture[0][IP])
5426 self.pg1.add_stream(p)
5427 self.pg_enable_capture(self.pg_interfaces)
5429 capture = self.pg0.get_capture(1)
5432 self.assertEqual(p[IP].dst, self.pg0.remote_ip4)
5434 self.assertEqual(inner.src, self.pg0.remote_ip4)
5435 self.assertEqual(inner[TCPerror].sport, local_port)
5437 self.logger.error(ppp("Unexpected or invalid packet:", p))
5440 # from client to server (no translation)
5441 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
5442 IP(src=self.pg1.remote_ip4, dst=self.pg0.remote_ip4) /
5443 TCP(sport=12346, dport=local_port))
5444 self.pg1.add_stream(p)
5445 self.pg_enable_capture(self.pg_interfaces)
5447 capture = self.pg0.get_capture(1)
5452 self.assertEqual(ip.dst, self.pg0.remote_ip4)
5453 self.assertEqual(tcp.dport, local_port)
5454 self.assert_packet_checksums_valid(p)
5456 self.logger.error(ppp("Unexpected or invalid packet:", p))
5459 # from service back to client (no translation)
5460 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5461 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
5462 TCP(sport=local_port, dport=12346))
5463 self.pg0.add_stream(p)
5464 self.pg_enable_capture(self.pg_interfaces)
5466 capture = self.pg1.get_capture(1)
5471 self.assertEqual(ip.src, self.pg0.remote_ip4)
5472 self.assertEqual(tcp.sport, local_port)
5473 self.assert_packet_checksums_valid(p)
5475 self.logger.error(ppp("Unexpected or invalid packet:", p))
5478 def test_output_feature(self):
5479 """ NAT44 interface output feature (in2out postrouting) """
5480 self.vapi.nat44_forwarding_enable_disable(1)
5481 self.nat44_add_address(self.nat_addr)
5482 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index,
5484 self.vapi.nat44_interface_add_del_output_feature(self.pg1.sw_if_index,
5488 pkts = self.create_stream_in(self.pg0, self.pg1)
5489 self.pg0.add_stream(pkts)
5490 self.pg_enable_capture(self.pg_interfaces)
5492 capture = self.pg1.get_capture(len(pkts))
5493 self.verify_capture_out(capture)
5496 pkts = self.create_stream_out(self.pg1)
5497 self.pg1.add_stream(pkts)
5498 self.pg_enable_capture(self.pg_interfaces)
5500 capture = self.pg0.get_capture(len(pkts))
5501 self.verify_capture_in(capture, self.pg0)
5503 def test_multiple_vrf(self):
5504 """ Multiple VRF setup """
5505 external_addr = '1.2.3.4'
5510 self.vapi.nat44_forwarding_enable_disable(1)
5511 self.nat44_add_address(self.nat_addr)
5512 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
5513 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index,
5515 self.vapi.nat44_interface_add_del_output_feature(self.pg1.sw_if_index,
5517 self.vapi.nat44_interface_add_del_feature(self.pg5.sw_if_index)
5518 self.vapi.nat44_interface_add_del_feature(self.pg5.sw_if_index,
5520 self.vapi.nat44_interface_add_del_feature(self.pg6.sw_if_index,
5522 self.nat44_add_static_mapping(self.pg5.remote_ip4, external_addr,
5523 local_port, external_port, vrf_id=1,
5524 proto=IP_PROTOS.tcp, out2in_only=1)
5525 self.nat44_add_static_mapping(
5526 self.pg0.remote_ip4, external_sw_if_index=self.pg0.sw_if_index,
5527 local_port=local_port, vrf_id=0, external_port=external_port,
5528 proto=IP_PROTOS.tcp, out2in_only=1)
5530 # from client to service (both VRF1)
5531 p = (Ether(src=self.pg6.remote_mac, dst=self.pg6.local_mac) /
5532 IP(src=self.pg6.remote_ip4, dst=external_addr) /
5533 TCP(sport=12345, dport=external_port))
5534 self.pg6.add_stream(p)
5535 self.pg_enable_capture(self.pg_interfaces)
5537 capture = self.pg5.get_capture(1)
5542 self.assertEqual(ip.dst, self.pg5.remote_ip4)
5543 self.assertEqual(tcp.dport, local_port)
5544 self.assert_packet_checksums_valid(p)
5546 self.logger.error(ppp("Unexpected or invalid packet:", p))
5549 # from service back to client (both VRF1)
5550 p = (Ether(src=self.pg5.remote_mac, dst=self.pg5.local_mac) /
5551 IP(src=self.pg5.remote_ip4, dst=self.pg6.remote_ip4) /
5552 TCP(sport=local_port, dport=12345))
5553 self.pg5.add_stream(p)
5554 self.pg_enable_capture(self.pg_interfaces)
5556 capture = self.pg6.get_capture(1)
5561 self.assertEqual(ip.src, external_addr)
5562 self.assertEqual(tcp.sport, external_port)
5563 self.assert_packet_checksums_valid(p)
5565 self.logger.error(ppp("Unexpected or invalid packet:", p))
5568 # dynamic NAT from VRF1 to VRF0 (output-feature)
5569 p = (Ether(src=self.pg5.remote_mac, dst=self.pg5.local_mac) /
5570 IP(src=self.pg5.remote_ip4, dst=self.pg1.remote_ip4) /
5571 TCP(sport=2345, dport=22))
5572 self.pg5.add_stream(p)
5573 self.pg_enable_capture(self.pg_interfaces)
5575 capture = self.pg1.get_capture(1)
5580 self.assertEqual(ip.src, self.nat_addr)
5581 self.assertNotEqual(tcp.sport, 2345)
5582 self.assert_packet_checksums_valid(p)
5585 self.logger.error(ppp("Unexpected or invalid packet:", p))
5588 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
5589 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
5590 TCP(sport=22, dport=port))
5591 self.pg1.add_stream(p)
5592 self.pg_enable_capture(self.pg_interfaces)
5594 capture = self.pg5.get_capture(1)
5599 self.assertEqual(ip.dst, self.pg5.remote_ip4)
5600 self.assertEqual(tcp.dport, 2345)
5601 self.assert_packet_checksums_valid(p)
5603 self.logger.error(ppp("Unexpected or invalid packet:", p))
5606 # from client VRF1 to service VRF0
5607 p = (Ether(src=self.pg6.remote_mac, dst=self.pg6.local_mac) /
5608 IP(src=self.pg6.remote_ip4, dst=self.pg0.local_ip4) /
5609 TCP(sport=12346, dport=external_port))
5610 self.pg6.add_stream(p)
5611 self.pg_enable_capture(self.pg_interfaces)
5613 capture = self.pg0.get_capture(1)
5618 self.assertEqual(ip.dst, self.pg0.remote_ip4)
5619 self.assertEqual(tcp.dport, local_port)
5620 self.assert_packet_checksums_valid(p)
5622 self.logger.error(ppp("Unexpected or invalid packet:", p))
5625 # from service VRF0 back to client VRF1
5626 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5627 IP(src=self.pg0.remote_ip4, dst=self.pg6.remote_ip4) /
5628 TCP(sport=local_port, dport=12346))
5629 self.pg0.add_stream(p)
5630 self.pg_enable_capture(self.pg_interfaces)
5632 capture = self.pg6.get_capture(1)
5637 self.assertEqual(ip.src, self.pg0.local_ip4)
5638 self.assertEqual(tcp.sport, external_port)
5639 self.assert_packet_checksums_valid(p)
5641 self.logger.error(ppp("Unexpected or invalid packet:", p))
5644 # from client VRF0 to service VRF1
5645 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5646 IP(src=self.pg0.remote_ip4, dst=external_addr) /
5647 TCP(sport=12347, dport=external_port))
5648 self.pg0.add_stream(p)
5649 self.pg_enable_capture(self.pg_interfaces)
5651 capture = self.pg5.get_capture(1)
5656 self.assertEqual(ip.dst, self.pg5.remote_ip4)
5657 self.assertEqual(tcp.dport, local_port)
5658 self.assert_packet_checksums_valid(p)
5660 self.logger.error(ppp("Unexpected or invalid packet:", p))
5663 # from service VRF1 back to client VRF0
5664 p = (Ether(src=self.pg5.remote_mac, dst=self.pg5.local_mac) /
5665 IP(src=self.pg5.remote_ip4, dst=self.pg0.remote_ip4) /
5666 TCP(sport=local_port, dport=12347))
5667 self.pg5.add_stream(p)
5668 self.pg_enable_capture(self.pg_interfaces)
5670 capture = self.pg0.get_capture(1)
5675 self.assertEqual(ip.src, external_addr)
5676 self.assertEqual(tcp.sport, external_port)
5677 self.assert_packet_checksums_valid(p)
5679 self.logger.error(ppp("Unexpected or invalid packet:", p))
5682 # from client to server (both VRF1, no translation)
5683 p = (Ether(src=self.pg6.remote_mac, dst=self.pg6.local_mac) /
5684 IP(src=self.pg6.remote_ip4, dst=self.pg5.remote_ip4) /
5685 TCP(sport=12348, dport=local_port))
5686 self.pg6.add_stream(p)
5687 self.pg_enable_capture(self.pg_interfaces)
5689 capture = self.pg5.get_capture(1)
5694 self.assertEqual(ip.dst, self.pg5.remote_ip4)
5695 self.assertEqual(tcp.dport, local_port)
5696 self.assert_packet_checksums_valid(p)
5698 self.logger.error(ppp("Unexpected or invalid packet:", p))
5701 # from server back to client (both VRF1, no translation)
5702 p = (Ether(src=self.pg5.remote_mac, dst=self.pg5.local_mac) /
5703 IP(src=self.pg5.remote_ip4, dst=self.pg6.remote_ip4) /
5704 TCP(sport=local_port, dport=12348))
5705 self.pg5.add_stream(p)
5706 self.pg_enable_capture(self.pg_interfaces)
5708 capture = self.pg6.get_capture(1)
5713 self.assertEqual(ip.src, self.pg5.remote_ip4)
5714 self.assertEqual(tcp.sport, local_port)
5715 self.assert_packet_checksums_valid(p)
5717 self.logger.error(ppp("Unexpected or invalid packet:", p))
5720 # from client VRF1 to server VRF0 (no translation)
5721 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5722 IP(src=self.pg0.remote_ip4, dst=self.pg6.remote_ip4) /
5723 TCP(sport=local_port, dport=12349))
5724 self.pg0.add_stream(p)
5725 self.pg_enable_capture(self.pg_interfaces)
5727 capture = self.pg6.get_capture(1)
5732 self.assertEqual(ip.src, self.pg0.remote_ip4)
5733 self.assertEqual(tcp.sport, local_port)
5734 self.assert_packet_checksums_valid(p)
5736 self.logger.error(ppp("Unexpected or invalid packet:", p))
5739 # from server VRF0 back to client VRF1 (no translation)
5740 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5741 IP(src=self.pg0.remote_ip4, dst=self.pg6.remote_ip4) /
5742 TCP(sport=local_port, dport=12349))
5743 self.pg0.add_stream(p)
5744 self.pg_enable_capture(self.pg_interfaces)
5746 capture = self.pg6.get_capture(1)
5751 self.assertEqual(ip.src, self.pg0.remote_ip4)
5752 self.assertEqual(tcp.sport, local_port)
5753 self.assert_packet_checksums_valid(p)
5755 self.logger.error(ppp("Unexpected or invalid packet:", p))
5758 # from client VRF0 to server VRF1 (no translation)
5759 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5760 IP(src=self.pg0.remote_ip4, dst=self.pg5.remote_ip4) /
5761 TCP(sport=12344, dport=local_port))
5762 self.pg0.add_stream(p)
5763 self.pg_enable_capture(self.pg_interfaces)
5765 capture = self.pg5.get_capture(1)
5770 self.assertEqual(ip.dst, self.pg5.remote_ip4)
5771 self.assertEqual(tcp.dport, local_port)
5772 self.assert_packet_checksums_valid(p)
5774 self.logger.error(ppp("Unexpected or invalid packet:", p))
5777 # from server VRF1 back to client VRF0 (no translation)
5778 p = (Ether(src=self.pg5.remote_mac, dst=self.pg5.local_mac) /
5779 IP(src=self.pg5.remote_ip4, dst=self.pg0.remote_ip4) /
5780 TCP(sport=local_port, dport=12344))
5781 self.pg5.add_stream(p)
5782 self.pg_enable_capture(self.pg_interfaces)
5784 capture = self.pg0.get_capture(1)
5789 self.assertEqual(ip.src, self.pg5.remote_ip4)
5790 self.assertEqual(tcp.sport, local_port)
5791 self.assert_packet_checksums_valid(p)
5793 self.logger.error(ppp("Unexpected or invalid packet:", p))
5796 @unittest.skipUnless(running_extended_tests(), "part of extended tests")
5797 def test_session_timeout(self):
5798 """ NAT44 session timeouts """
5799 self.nat44_add_address(self.nat_addr)
5800 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
5801 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
5803 self.vapi.nat_set_timeouts(icmp=5)
5807 for i in range(0, max_sessions):
5808 src = "10.10.%u.%u" % ((i & 0xFF00) >> 8, i & 0xFF)
5809 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
5810 IP(src=src, dst=self.pg1.remote_ip4) /
5811 ICMP(id=1025, type='echo-request'))
5813 self.pg0.add_stream(pkts)
5814 self.pg_enable_capture(self.pg_interfaces)
5816 self.pg1.get_capture(max_sessions)
5821 for i in range(0, max_sessions):
5822 src = "10.11.%u.%u" % ((i & 0xFF00) >> 8, i & 0xFF)
5823 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
5824 IP(src=src, dst=self.pg1.remote_ip4) /
5825 ICMP(id=1026, type='echo-request'))
5827 self.pg0.add_stream(pkts)
5828 self.pg_enable_capture(self.pg_interfaces)
5830 self.pg1.get_capture(max_sessions)
5833 users = self.vapi.nat44_user_dump()
5835 nsessions = nsessions + user.nsessions
5836 self.assertLess(nsessions, 2 * max_sessions)
5838 @unittest.skipUnless(running_extended_tests(), "part of extended tests")
5839 def test_session_rst_timeout(self):
5840 """ NAT44 session RST timeouts """
5841 self.nat44_add_address(self.nat_addr)
5842 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
5843 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
5845 self.vapi.nat_set_timeouts(tcp_transitory=5)
5847 self.initiate_tcp_session(self.pg0, self.pg1)
5848 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5849 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
5850 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
5852 self.pg0.add_stream(p)
5853 self.pg_enable_capture(self.pg_interfaces)
5855 self.pg1.get_capture(1)
5859 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5860 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
5861 TCP(sport=self.tcp_port_in + 1, dport=self.tcp_external_port + 1,
5863 self.pg0.add_stream(p)
5864 self.pg_enable_capture(self.pg_interfaces)
5866 self.pg1.get_capture(1)
5869 users = self.vapi.nat44_user_dump()
5870 self.assertEqual(len(users), 1)
5871 self.assertEqual(users[0].ip_address, self.pg0.remote_ip4n)
5872 self.assertEqual(users[0].nsessions, 1)
5874 @unittest.skipUnless(running_extended_tests(), "part of extended tests")
5875 def test_session_limit_per_user(self):
5876 """ Maximum sessions per user limit """
5877 self.nat44_add_address(self.nat_addr)
5878 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
5879 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
5881 self.vapi.set_ipfix_exporter(collector_address=self.pg2.remote_ip4n,
5882 src_address=self.pg2.local_ip4n,
5884 template_interval=10)
5885 self.vapi.nat_set_timeouts(udp=5)
5887 # get maximum number of translations per user
5888 nat44_config = self.vapi.nat_show_config()
5891 for port in range(0, nat44_config.max_translations_per_user):
5892 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5893 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
5894 UDP(sport=1025 + port, dport=1025 + port))
5897 self.pg0.add_stream(pkts)
5898 self.pg_enable_capture(self.pg_interfaces)
5900 capture = self.pg1.get_capture(len(pkts))
5902 self.vapi.nat_ipfix(domain_id=self.ipfix_domain_id,
5903 src_port=self.ipfix_src_port)
5905 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5906 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
5907 UDP(sport=3001, dport=3002))
5908 self.pg0.add_stream(p)
5909 self.pg_enable_capture(self.pg_interfaces)
5911 capture = self.pg1.assert_nothing_captured()
5913 # verify IPFIX logging
5914 self.vapi.cli("ipfix flush") # FIXME this should be an API call
5916 capture = self.pg2.get_capture(10)
5917 ipfix = IPFIXDecoder()
5918 # first load template
5920 self.assertTrue(p.haslayer(IPFIX))
5921 if p.haslayer(Template):
5922 ipfix.add_template(p.getlayer(Template))
5923 # verify events in data set
5925 if p.haslayer(Data):
5926 data = ipfix.decode_data_set(p.getlayer(Set))
5927 self.verify_ipfix_max_entries_per_user(
5929 nat44_config.max_translations_per_user,
5930 self.pg0.remote_ip4n)
5933 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5934 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
5935 UDP(sport=3001, dport=3002))
5936 self.pg0.add_stream(p)
5937 self.pg_enable_capture(self.pg_interfaces)
5939 self.pg1.get_capture(1)
5941 def test_syslog_sess(self):
5942 """ Test syslog session creation and deletion """
5943 self.vapi.syslog_set_filter(SYSLOG_SEVERITY.INFO)
5944 self.vapi.syslog_set_sender(self.pg2.remote_ip4n, self.pg2.local_ip4n)
5945 self.nat44_add_address(self.nat_addr)
5946 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
5947 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
5950 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
5951 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
5952 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port))
5953 self.pg0.add_stream(p)
5954 self.pg_enable_capture(self.pg_interfaces)
5956 capture = self.pg1.get_capture(1)
5957 self.tcp_port_out = capture[0][TCP].sport
5958 capture = self.pg2.get_capture(1)
5959 self.verify_syslog_sess(capture[0][Raw].load)
5961 self.pg_enable_capture(self.pg_interfaces)
5963 self.nat44_add_address(self.nat_addr, is_add=0)
5964 capture = self.pg2.get_capture(1)
5965 self.verify_syslog_sess(capture[0][Raw].load, False)
5968 super(TestNAT44EndpointDependent, self).tearDown()
5969 if not self.vpp_dead:
5970 self.logger.info(self.vapi.cli("show nat44 addresses"))
5971 self.logger.info(self.vapi.cli("show nat44 interfaces"))
5972 self.logger.info(self.vapi.cli("show nat44 static mappings"))
5973 self.logger.info(self.vapi.cli("show nat44 interface address"))
5974 self.logger.info(self.vapi.cli("show nat44 sessions detail"))
5975 self.logger.info(self.vapi.cli("show nat44 hash tables detail"))
5976 self.logger.info(self.vapi.cli("show nat timeouts"))
5978 self.vapi.cli("clear logging")
5981 class TestNAT44Out2InDPO(MethodHolder):
5982 """ NAT44 Test Cases using out2in DPO """
5985 def setUpConstants(cls):
5986 super(TestNAT44Out2InDPO, cls).setUpConstants()
5987 cls.vpp_cmdline.extend(["nat", "{", "out2in dpo", "}"])
5990 def setUpClass(cls):
5991 super(TestNAT44Out2InDPO, cls).setUpClass()
5992 cls.vapi.cli("set log class nat level debug")
5995 cls.tcp_port_in = 6303
5996 cls.tcp_port_out = 6303
5997 cls.udp_port_in = 6304
5998 cls.udp_port_out = 6304
5999 cls.icmp_id_in = 6305
6000 cls.icmp_id_out = 6305
6001 cls.nat_addr = '10.0.0.3'
6002 cls.nat_addr_n = socket.inet_pton(socket.AF_INET, cls.nat_addr)
6003 cls.dst_ip4 = '192.168.70.1'
6005 cls.create_pg_interfaces(range(2))
6008 cls.pg0.config_ip4()
6009 cls.pg0.resolve_arp()
6012 cls.pg1.config_ip6()
6013 cls.pg1.resolve_ndp()
6015 cls.vapi.ip_add_del_route(is_ipv6=True, dst_address='\x00'*16,
6016 dst_address_length=0,
6017 next_hop_address=cls.pg1.remote_ip6n,
6018 next_hop_sw_if_index=cls.pg1.sw_if_index)
6021 super(TestNAT44Out2InDPO, cls).tearDownClass()
6024 def configure_xlat(self):
6025 self.dst_ip6_pfx = '1:2:3::'
6026 self.dst_ip6_pfx_n = socket.inet_pton(socket.AF_INET6,
6028 self.dst_ip6_pfx_len = 96
6029 self.src_ip6_pfx = '4:5:6::'
6030 self.src_ip6_pfx_n = socket.inet_pton(socket.AF_INET6,
6032 self.src_ip6_pfx_len = 96
6033 self.vapi.map_add_domain(self.dst_ip6_pfx_n, self.dst_ip6_pfx_len,
6034 self.src_ip6_pfx_n, self.src_ip6_pfx_len,
6035 '\x00\x00\x00\x00', 0, is_translation=1,
6038 @unittest.skip('Temporary disabled')
6039 def test_464xlat_ce(self):
6040 """ Test 464XLAT CE with NAT44 """
6042 nat_config = self.vapi.nat_show_config()
6043 self.assertEqual(1, nat_config.out2in_dpo)
6045 self.configure_xlat()
6047 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
6048 self.vapi.nat44_add_del_address_range(self.nat_addr_n, self.nat_addr_n)
6050 out_src_ip6 = self.compose_ip6(self.dst_ip4, self.dst_ip6_pfx,
6051 self.dst_ip6_pfx_len)
6052 out_dst_ip6 = self.compose_ip6(self.nat_addr, self.src_ip6_pfx,
6053 self.src_ip6_pfx_len)
6056 pkts = self.create_stream_in(self.pg0, self.pg1, self.dst_ip4)
6057 self.pg0.add_stream(pkts)
6058 self.pg_enable_capture(self.pg_interfaces)
6060 capture = self.pg1.get_capture(len(pkts))
6061 self.verify_capture_out_ip6(capture, nat_ip=out_dst_ip6,
6064 pkts = self.create_stream_out_ip6(self.pg1, out_src_ip6,
6066 self.pg1.add_stream(pkts)
6067 self.pg_enable_capture(self.pg_interfaces)
6069 capture = self.pg0.get_capture(len(pkts))
6070 self.verify_capture_in(capture, self.pg0)
6072 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index,
6074 self.vapi.nat44_add_del_address_range(self.nat_addr_n,
6075 self.nat_addr_n, is_add=0)
6077 @unittest.skip('Temporary disabled')
6078 def test_464xlat_ce_no_nat(self):
6079 """ Test 464XLAT CE without NAT44 """
6081 self.configure_xlat()
6083 out_src_ip6 = self.compose_ip6(self.dst_ip4, self.dst_ip6_pfx,
6084 self.dst_ip6_pfx_len)
6085 out_dst_ip6 = self.compose_ip6(self.pg0.remote_ip4, self.src_ip6_pfx,
6086 self.src_ip6_pfx_len)
6088 pkts = self.create_stream_in(self.pg0, self.pg1, self.dst_ip4)
6089 self.pg0.add_stream(pkts)
6090 self.pg_enable_capture(self.pg_interfaces)
6092 capture = self.pg1.get_capture(len(pkts))
6093 self.verify_capture_out_ip6(capture, dst_ip=out_src_ip6,
6094 nat_ip=out_dst_ip6, same_port=True)
6096 pkts = self.create_stream_out_ip6(self.pg1, out_src_ip6, out_dst_ip6)
6097 self.pg1.add_stream(pkts)
6098 self.pg_enable_capture(self.pg_interfaces)
6100 capture = self.pg0.get_capture(len(pkts))
6101 self.verify_capture_in(capture, self.pg0)
6104 class TestDeterministicNAT(MethodHolder):
6105 """ Deterministic NAT Test Cases """
6108 def setUpConstants(cls):
6109 super(TestDeterministicNAT, cls).setUpConstants()
6110 cls.vpp_cmdline.extend(["nat", "{", "deterministic", "}"])
6113 def setUpClass(cls):
6114 super(TestDeterministicNAT, cls).setUpClass()
6115 cls.vapi.cli("set log class nat level debug")
6118 cls.tcp_port_in = 6303
6119 cls.tcp_external_port = 6303
6120 cls.udp_port_in = 6304
6121 cls.udp_external_port = 6304
6122 cls.icmp_id_in = 6305
6123 cls.nat_addr = '10.0.0.3'
6125 cls.create_pg_interfaces(range(3))
6126 cls.interfaces = list(cls.pg_interfaces)
6128 for i in cls.interfaces:
6133 cls.pg0.generate_remote_hosts(2)
6134 cls.pg0.configure_ipv4_neighbors()
6137 super(TestDeterministicNAT, cls).tearDownClass()
6140 def create_stream_in(self, in_if, out_if, ttl=64):
6142 Create packet stream for inside network
6144 :param in_if: Inside interface
6145 :param out_if: Outside interface
6146 :param ttl: TTL of generated packets
6150 p = (Ether(dst=in_if.local_mac, src=in_if.remote_mac) /
6151 IP(src=in_if.remote_ip4, dst=out_if.remote_ip4, ttl=ttl) /
6152 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port))
6156 p = (Ether(dst=in_if.local_mac, src=in_if.remote_mac) /
6157 IP(src=in_if.remote_ip4, dst=out_if.remote_ip4, ttl=ttl) /
6158 UDP(sport=self.udp_port_in, dport=self.udp_external_port))
6162 p = (Ether(dst=in_if.local_mac, src=in_if.remote_mac) /
6163 IP(src=in_if.remote_ip4, dst=out_if.remote_ip4, ttl=ttl) /
6164 ICMP(id=self.icmp_id_in, type='echo-request'))
6169 def create_stream_out(self, out_if, dst_ip=None, ttl=64):
6171 Create packet stream for outside network
6173 :param out_if: Outside interface
6174 :param dst_ip: Destination IP address (Default use global NAT address)
6175 :param ttl: TTL of generated packets
6178 dst_ip = self.nat_addr
6181 p = (Ether(dst=out_if.local_mac, src=out_if.remote_mac) /
6182 IP(src=out_if.remote_ip4, dst=dst_ip, ttl=ttl) /
6183 TCP(dport=self.tcp_port_out, sport=self.tcp_external_port))
6187 p = (Ether(dst=out_if.local_mac, src=out_if.remote_mac) /
6188 IP(src=out_if.remote_ip4, dst=dst_ip, ttl=ttl) /
6189 UDP(dport=self.udp_port_out, sport=self.udp_external_port))
6193 p = (Ether(dst=out_if.local_mac, src=out_if.remote_mac) /
6194 IP(src=out_if.remote_ip4, dst=dst_ip, ttl=ttl) /
6195 ICMP(id=self.icmp_external_id, type='echo-reply'))
6200 def verify_capture_out(self, capture, nat_ip=None):
6202 Verify captured packets on outside network
6204 :param capture: Captured packets
6205 :param nat_ip: Translated IP address (Default use global NAT address)
6206 :param same_port: Sorce port number is not translated (Default False)
6209 nat_ip = self.nat_addr
6210 for packet in capture:
6212 self.assertEqual(packet[IP].src, nat_ip)
6213 if packet.haslayer(TCP):
6214 self.tcp_port_out = packet[TCP].sport
6215 elif packet.haslayer(UDP):
6216 self.udp_port_out = packet[UDP].sport
6218 self.icmp_external_id = packet[ICMP].id
6220 self.logger.error(ppp("Unexpected or invalid packet "
6221 "(outside network):", packet))
6224 def test_deterministic_mode(self):
6225 """ NAT plugin run deterministic mode """
6226 in_addr = '172.16.255.0'
6227 out_addr = '172.17.255.50'
6228 in_addr_t = '172.16.255.20'
6229 in_addr_n = socket.inet_aton(in_addr)
6230 out_addr_n = socket.inet_aton(out_addr)
6231 in_addr_t_n = socket.inet_aton(in_addr_t)
6235 nat_config = self.vapi.nat_show_config()
6236 self.assertEqual(1, nat_config.deterministic)
6238 self.vapi.nat_det_add_del_map(in_addr_n, in_plen, out_addr_n, out_plen)
6240 rep1 = self.vapi.nat_det_forward(in_addr_t_n)
6241 self.assertEqual(rep1.out_addr[:4], out_addr_n)
6242 rep2 = self.vapi.nat_det_reverse(out_addr_n, rep1.out_port_hi)
6243 self.assertEqual(rep2.in_addr[:4], in_addr_t_n)
6245 deterministic_mappings = self.vapi.nat_det_map_dump()
6246 self.assertEqual(len(deterministic_mappings), 1)
6247 dsm = deterministic_mappings[0]
6248 self.assertEqual(in_addr_n, dsm.in_addr[:4])
6249 self.assertEqual(in_plen, dsm.in_plen)
6250 self.assertEqual(out_addr_n, dsm.out_addr[:4])
6251 self.assertEqual(out_plen, dsm.out_plen)
6253 self.clear_nat_det()
6254 deterministic_mappings = self.vapi.nat_det_map_dump()
6255 self.assertEqual(len(deterministic_mappings), 0)
6257 def test_set_timeouts(self):
6258 """ Set deterministic NAT timeouts """
6259 timeouts_before = self.vapi.nat_get_timeouts()
6261 self.vapi.nat_set_timeouts(timeouts_before.udp + 10,
6262 timeouts_before.tcp_established + 10,
6263 timeouts_before.tcp_transitory + 10,
6264 timeouts_before.icmp + 10)
6266 timeouts_after = self.vapi.nat_get_timeouts()
6268 self.assertNotEqual(timeouts_before.udp, timeouts_after.udp)
6269 self.assertNotEqual(timeouts_before.icmp, timeouts_after.icmp)
6270 self.assertNotEqual(timeouts_before.tcp_established,
6271 timeouts_after.tcp_established)
6272 self.assertNotEqual(timeouts_before.tcp_transitory,
6273 timeouts_after.tcp_transitory)
6275 def test_det_in(self):
6276 """ Deterministic NAT translation test (TCP, UDP, ICMP) """
6278 nat_ip = "10.0.0.10"
6280 self.vapi.nat_det_add_del_map(self.pg0.remote_ip4n,
6282 socket.inet_aton(nat_ip),
6284 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
6285 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
6289 pkts = self.create_stream_in(self.pg0, self.pg1)
6290 self.pg0.add_stream(pkts)
6291 self.pg_enable_capture(self.pg_interfaces)
6293 capture = self.pg1.get_capture(len(pkts))
6294 self.verify_capture_out(capture, nat_ip)
6297 pkts = self.create_stream_out(self.pg1, nat_ip)
6298 self.pg1.add_stream(pkts)
6299 self.pg_enable_capture(self.pg_interfaces)
6301 capture = self.pg0.get_capture(len(pkts))
6302 self.verify_capture_in(capture, self.pg0)
6305 sessions = self.vapi.nat_det_session_dump(self.pg0.remote_ip4n)
6306 self.assertEqual(len(sessions), 3)
6310 self.assertEqual(s.ext_addr[:4], self.pg1.remote_ip4n)
6311 self.assertEqual(s.in_port, self.tcp_port_in)
6312 self.assertEqual(s.out_port, self.tcp_port_out)
6313 self.assertEqual(s.ext_port, self.tcp_external_port)
6317 self.assertEqual(s.ext_addr[:4], self.pg1.remote_ip4n)
6318 self.assertEqual(s.in_port, self.udp_port_in)
6319 self.assertEqual(s.out_port, self.udp_port_out)
6320 self.assertEqual(s.ext_port, self.udp_external_port)
6324 self.assertEqual(s.ext_addr[:4], self.pg1.remote_ip4n)
6325 self.assertEqual(s.in_port, self.icmp_id_in)
6326 self.assertEqual(s.out_port, self.icmp_external_id)
6328 def test_multiple_users(self):
6329 """ Deterministic NAT multiple users """
6331 nat_ip = "10.0.0.10"
6333 external_port = 6303
6335 host0 = self.pg0.remote_hosts[0]
6336 host1 = self.pg0.remote_hosts[1]
6338 self.vapi.nat_det_add_del_map(host0.ip4n,
6340 socket.inet_aton(nat_ip),
6342 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
6343 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
6347 p = (Ether(src=host0.mac, dst=self.pg0.local_mac) /
6348 IP(src=host0.ip4, dst=self.pg1.remote_ip4) /
6349 TCP(sport=port_in, dport=external_port))
6350 self.pg0.add_stream(p)
6351 self.pg_enable_capture(self.pg_interfaces)
6353 capture = self.pg1.get_capture(1)
6358 self.assertEqual(ip.src, nat_ip)
6359 self.assertEqual(ip.dst, self.pg1.remote_ip4)
6360 self.assertEqual(tcp.dport, external_port)
6361 port_out0 = tcp.sport
6363 self.logger.error(ppp("Unexpected or invalid packet:", p))
6367 p = (Ether(src=host1.mac, dst=self.pg0.local_mac) /
6368 IP(src=host1.ip4, dst=self.pg1.remote_ip4) /
6369 TCP(sport=port_in, dport=external_port))
6370 self.pg0.add_stream(p)
6371 self.pg_enable_capture(self.pg_interfaces)
6373 capture = self.pg1.get_capture(1)
6378 self.assertEqual(ip.src, nat_ip)
6379 self.assertEqual(ip.dst, self.pg1.remote_ip4)
6380 self.assertEqual(tcp.dport, external_port)
6381 port_out1 = tcp.sport
6383 self.logger.error(ppp("Unexpected or invalid packet:", p))
6386 dms = self.vapi.nat_det_map_dump()
6387 self.assertEqual(1, len(dms))
6388 self.assertEqual(2, dms[0].ses_num)
6391 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
6392 IP(src=self.pg1.remote_ip4, dst=nat_ip) /
6393 TCP(sport=external_port, dport=port_out0))
6394 self.pg1.add_stream(p)
6395 self.pg_enable_capture(self.pg_interfaces)
6397 capture = self.pg0.get_capture(1)
6402 self.assertEqual(ip.src, self.pg1.remote_ip4)
6403 self.assertEqual(ip.dst, host0.ip4)
6404 self.assertEqual(tcp.dport, port_in)
6405 self.assertEqual(tcp.sport, external_port)
6407 self.logger.error(ppp("Unexpected or invalid packet:", p))
6411 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
6412 IP(src=self.pg1.remote_ip4, dst=nat_ip) /
6413 TCP(sport=external_port, dport=port_out1))
6414 self.pg1.add_stream(p)
6415 self.pg_enable_capture(self.pg_interfaces)
6417 capture = self.pg0.get_capture(1)
6422 self.assertEqual(ip.src, self.pg1.remote_ip4)
6423 self.assertEqual(ip.dst, host1.ip4)
6424 self.assertEqual(tcp.dport, port_in)
6425 self.assertEqual(tcp.sport, external_port)
6427 self.logger.error(ppp("Unexpected or invalid packet", p))
6430 # session close api test
6431 self.vapi.nat_det_close_session_out(socket.inet_aton(nat_ip),
6433 self.pg1.remote_ip4n,
6435 dms = self.vapi.nat_det_map_dump()
6436 self.assertEqual(dms[0].ses_num, 1)
6438 self.vapi.nat_det_close_session_in(host0.ip4n,
6440 self.pg1.remote_ip4n,
6442 dms = self.vapi.nat_det_map_dump()
6443 self.assertEqual(dms[0].ses_num, 0)
6445 def test_tcp_session_close_detection_in(self):
6446 """ Deterministic NAT TCP session close from inside network """
6447 self.vapi.nat_det_add_del_map(self.pg0.remote_ip4n,
6449 socket.inet_aton(self.nat_addr),
6451 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
6452 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
6455 self.initiate_tcp_session(self.pg0, self.pg1)
6457 # close the session from inside
6459 # FIN packet in -> out
6460 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6461 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6462 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
6464 self.pg0.add_stream(p)
6465 self.pg_enable_capture(self.pg_interfaces)
6467 self.pg1.get_capture(1)
6471 # ACK packet out -> in
6472 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
6473 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
6474 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
6478 # FIN packet out -> in
6479 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
6480 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
6481 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
6485 self.pg1.add_stream(pkts)
6486 self.pg_enable_capture(self.pg_interfaces)
6488 self.pg0.get_capture(2)
6490 # ACK packet in -> out
6491 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6492 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6493 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
6495 self.pg0.add_stream(p)
6496 self.pg_enable_capture(self.pg_interfaces)
6498 self.pg1.get_capture(1)
6500 # Check if deterministic NAT44 closed the session
6501 dms = self.vapi.nat_det_map_dump()
6502 self.assertEqual(0, dms[0].ses_num)
6504 self.logger.error("TCP session termination failed")
6507 def test_tcp_session_close_detection_out(self):
6508 """ Deterministic NAT TCP session close from outside network """
6509 self.vapi.nat_det_add_del_map(self.pg0.remote_ip4n,
6511 socket.inet_aton(self.nat_addr),
6513 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
6514 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
6517 self.initiate_tcp_session(self.pg0, self.pg1)
6519 # close the session from outside
6521 # FIN packet out -> in
6522 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
6523 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
6524 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
6526 self.pg1.add_stream(p)
6527 self.pg_enable_capture(self.pg_interfaces)
6529 self.pg0.get_capture(1)
6533 # ACK packet in -> out
6534 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6535 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6536 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
6540 # ACK packet in -> out
6541 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6542 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6543 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
6547 self.pg0.add_stream(pkts)
6548 self.pg_enable_capture(self.pg_interfaces)
6550 self.pg1.get_capture(2)
6552 # ACK packet out -> in
6553 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
6554 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
6555 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
6557 self.pg1.add_stream(p)
6558 self.pg_enable_capture(self.pg_interfaces)
6560 self.pg0.get_capture(1)
6562 # Check if deterministic NAT44 closed the session
6563 dms = self.vapi.nat_det_map_dump()
6564 self.assertEqual(0, dms[0].ses_num)
6566 self.logger.error("TCP session termination failed")
6569 @unittest.skipUnless(running_extended_tests(), "part of extended tests")
6570 def test_session_timeout(self):
6571 """ Deterministic NAT session timeouts """
6572 self.vapi.nat_det_add_del_map(self.pg0.remote_ip4n,
6574 socket.inet_aton(self.nat_addr),
6576 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
6577 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
6580 self.initiate_tcp_session(self.pg0, self.pg1)
6581 self.vapi.nat_set_timeouts(5, 5, 5, 5)
6582 pkts = self.create_stream_in(self.pg0, self.pg1)
6583 self.pg0.add_stream(pkts)
6584 self.pg_enable_capture(self.pg_interfaces)
6586 capture = self.pg1.get_capture(len(pkts))
6589 dms = self.vapi.nat_det_map_dump()
6590 self.assertEqual(0, dms[0].ses_num)
6592 @unittest.skipUnless(running_extended_tests(), "part of extended tests")
6593 def test_session_limit_per_user(self):
6594 """ Deterministic NAT maximum sessions per user limit """
6595 self.vapi.nat_det_add_del_map(self.pg0.remote_ip4n,
6597 socket.inet_aton(self.nat_addr),
6599 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
6600 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
6602 self.vapi.set_ipfix_exporter(collector_address=self.pg2.remote_ip4n,
6603 src_address=self.pg2.local_ip4n,
6605 template_interval=10)
6606 self.vapi.nat_ipfix()
6609 for port in range(1025, 2025):
6610 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6611 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6612 UDP(sport=port, dport=port))
6615 self.pg0.add_stream(pkts)
6616 self.pg_enable_capture(self.pg_interfaces)
6618 capture = self.pg1.get_capture(len(pkts))
6620 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6621 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6622 UDP(sport=3001, dport=3002))
6623 self.pg0.add_stream(p)
6624 self.pg_enable_capture(self.pg_interfaces)
6626 capture = self.pg1.assert_nothing_captured()
6628 # verify ICMP error packet
6629 capture = self.pg0.get_capture(1)
6631 self.assertTrue(p.haslayer(ICMP))
6633 self.assertEqual(icmp.type, 3)
6634 self.assertEqual(icmp.code, 1)
6635 self.assertTrue(icmp.haslayer(IPerror))
6636 inner_ip = icmp[IPerror]
6637 self.assertEqual(inner_ip[UDPerror].sport, 3001)
6638 self.assertEqual(inner_ip[UDPerror].dport, 3002)
6640 dms = self.vapi.nat_det_map_dump()
6642 self.assertEqual(1000, dms[0].ses_num)
6644 # verify IPFIX logging
6645 self.vapi.cli("ipfix flush") # FIXME this should be an API call
6647 capture = self.pg2.get_capture(2)
6648 ipfix = IPFIXDecoder()
6649 # first load template
6651 self.assertTrue(p.haslayer(IPFIX))
6652 if p.haslayer(Template):
6653 ipfix.add_template(p.getlayer(Template))
6654 # verify events in data set
6656 if p.haslayer(Data):
6657 data = ipfix.decode_data_set(p.getlayer(Set))
6658 self.verify_ipfix_max_entries_per_user(data,
6660 self.pg0.remote_ip4n)
6662 def clear_nat_det(self):
6664 Clear deterministic NAT configuration.
6666 self.vapi.nat_ipfix(enable=0)
6667 self.vapi.nat_set_timeouts()
6668 deterministic_mappings = self.vapi.nat_det_map_dump()
6669 for dsm in deterministic_mappings:
6670 self.vapi.nat_det_add_del_map(dsm.in_addr,
6676 interfaces = self.vapi.nat44_interface_dump()
6677 for intf in interfaces:
6678 self.vapi.nat44_interface_add_del_feature(intf.sw_if_index,
6683 super(TestDeterministicNAT, self).tearDown()
6684 if not self.vpp_dead:
6685 self.logger.info(self.vapi.cli("show nat44 interfaces"))
6686 self.logger.info(self.vapi.cli("show nat timeouts"))
6688 self.vapi.cli("show nat44 deterministic mappings"))
6690 self.vapi.cli("show nat44 deterministic sessions"))
6691 self.clear_nat_det()
6694 class TestNAT64(MethodHolder):
6695 """ NAT64 Test Cases """
6698 def setUpConstants(cls):
6699 super(TestNAT64, cls).setUpConstants()
6700 cls.vpp_cmdline.extend(["nat", "{", "nat64 bib hash buckets 128",
6701 "nat64 st hash buckets 256", "}"])
6704 def setUpClass(cls):
6705 super(TestNAT64, cls).setUpClass()
6708 cls.tcp_port_in = 6303
6709 cls.tcp_port_out = 6303
6710 cls.udp_port_in = 6304
6711 cls.udp_port_out = 6304
6712 cls.icmp_id_in = 6305
6713 cls.icmp_id_out = 6305
6714 cls.tcp_external_port = 80
6715 cls.nat_addr = '10.0.0.3'
6716 cls.nat_addr_n = socket.inet_pton(socket.AF_INET, cls.nat_addr)
6718 cls.vrf1_nat_addr = '10.0.10.3'
6719 cls.vrf1_nat_addr_n = socket.inet_pton(socket.AF_INET,
6721 cls.ipfix_src_port = 4739
6722 cls.ipfix_domain_id = 1
6724 cls.create_pg_interfaces(range(6))
6725 cls.ip6_interfaces = list(cls.pg_interfaces[0:1])
6726 cls.ip6_interfaces.append(cls.pg_interfaces[2])
6727 cls.ip4_interfaces = list(cls.pg_interfaces[1:2])
6729 cls.vapi.ip_table_add_del(cls.vrf1_id, is_add=1, is_ipv6=1)
6731 cls.pg_interfaces[2].set_table_ip6(cls.vrf1_id)
6733 cls.pg0.generate_remote_hosts(2)
6735 for i in cls.ip6_interfaces:
6738 i.configure_ipv6_neighbors()
6740 for i in cls.ip4_interfaces:
6746 cls.pg3.config_ip4()
6747 cls.pg3.resolve_arp()
6748 cls.pg3.config_ip6()
6749 cls.pg3.configure_ipv6_neighbors()
6752 cls.pg5.config_ip6()
6755 super(TestNAT64, cls).tearDownClass()
6758 def test_nat64_inside_interface_handles_neighbor_advertisement(self):
6759 """ NAT64 inside interface handles Neighbor Advertisement """
6761 self.vapi.nat64_add_del_interface(self.pg5.sw_if_index)
6764 ping = (Ether(dst=self.pg5.local_mac, src=self.pg5.remote_mac) /
6765 IPv6(src=self.pg5.remote_ip6, dst=self.pg5.local_ip6) /
6766 ICMPv6EchoRequest())
6768 self.pg5.add_stream(pkts)
6769 self.pg_enable_capture(self.pg_interfaces)
6772 # Wait for Neighbor Solicitation
6773 capture = self.pg5.get_capture(len(pkts))
6776 self.assertEqual(packet[IPv6].src, self.pg5.local_ip6)
6777 self.assertEqual(packet.haslayer(ICMPv6ND_NS), 1)
6778 tgt = packet[ICMPv6ND_NS].tgt
6780 self.logger.error(ppp("Unexpected or invalid packet:", packet))
6783 # Send Neighbor Advertisement
6784 p = (Ether(dst=self.pg5.local_mac, src=self.pg5.remote_mac) /
6785 IPv6(src=self.pg5.remote_ip6, dst=self.pg5.local_ip6) /
6786 ICMPv6ND_NA(tgt=tgt) /
6787 ICMPv6NDOptDstLLAddr(lladdr=self.pg5.remote_mac))
6789 self.pg5.add_stream(pkts)
6790 self.pg_enable_capture(self.pg_interfaces)
6793 # Try to send ping again
6795 self.pg5.add_stream(pkts)
6796 self.pg_enable_capture(self.pg_interfaces)
6799 # Wait for ping reply
6800 capture = self.pg5.get_capture(len(pkts))
6803 self.assertEqual(packet[IPv6].src, self.pg5.local_ip6)
6804 self.assertEqual(packet[IPv6].dst, self.pg5.remote_ip6)
6805 self.assertEqual(packet.haslayer(ICMPv6EchoReply), 1)
6807 self.logger.error(ppp("Unexpected or invalid packet:", packet))
6810 def test_pool(self):
6811 """ Add/delete address to NAT64 pool """
6812 nat_addr = socket.inet_pton(socket.AF_INET, '1.2.3.4')
6814 self.vapi.nat64_add_del_pool_addr_range(nat_addr, nat_addr)
6816 addresses = self.vapi.nat64_pool_addr_dump()
6817 self.assertEqual(len(addresses), 1)
6818 self.assertEqual(addresses[0].address, nat_addr)
6820 self.vapi.nat64_add_del_pool_addr_range(nat_addr, nat_addr, is_add=0)
6822 addresses = self.vapi.nat64_pool_addr_dump()
6823 self.assertEqual(len(addresses), 0)
6825 def test_interface(self):
6826 """ Enable/disable NAT64 feature on the interface """
6827 self.vapi.nat64_add_del_interface(self.pg0.sw_if_index)
6828 self.vapi.nat64_add_del_interface(self.pg1.sw_if_index, is_inside=0)
6830 interfaces = self.vapi.nat64_interface_dump()
6831 self.assertEqual(len(interfaces), 2)
6834 for intf in interfaces:
6835 if intf.sw_if_index == self.pg0.sw_if_index:
6836 self.assertEqual(intf.is_inside, 1)
6838 elif intf.sw_if_index == self.pg1.sw_if_index:
6839 self.assertEqual(intf.is_inside, 0)
6841 self.assertTrue(pg0_found)
6842 self.assertTrue(pg1_found)
6844 features = self.vapi.cli("show interface features pg0")
6845 self.assertNotEqual(features.find('nat64-in2out'), -1)
6846 features = self.vapi.cli("show interface features pg1")
6847 self.assertNotEqual(features.find('nat64-out2in'), -1)
6849 self.vapi.nat64_add_del_interface(self.pg0.sw_if_index, is_add=0)
6850 self.vapi.nat64_add_del_interface(self.pg1.sw_if_index, is_add=0)
6852 interfaces = self.vapi.nat64_interface_dump()
6853 self.assertEqual(len(interfaces), 0)
6855 def test_static_bib(self):
6856 """ Add/delete static BIB entry """
6857 in_addr = socket.inet_pton(socket.AF_INET6,
6858 '2001:db8:85a3::8a2e:370:7334')
6859 out_addr = socket.inet_pton(socket.AF_INET, '10.1.1.3')
6862 proto = IP_PROTOS.tcp
6864 self.vapi.nat64_add_del_static_bib(in_addr,
6869 bib = self.vapi.nat64_bib_dump(IP_PROTOS.tcp)
6874 self.assertEqual(bibe.i_addr, in_addr)
6875 self.assertEqual(bibe.o_addr, out_addr)
6876 self.assertEqual(bibe.i_port, in_port)
6877 self.assertEqual(bibe.o_port, out_port)
6878 self.assertEqual(static_bib_num, 1)
6880 self.vapi.nat64_add_del_static_bib(in_addr,
6886 bib = self.vapi.nat64_bib_dump(IP_PROTOS.tcp)
6891 self.assertEqual(static_bib_num, 0)
6893 def test_set_timeouts(self):
6894 """ Set NAT64 timeouts """
6895 # verify default values
6896 timeouts = self.vapi.nat_get_timeouts()
6897 self.assertEqual(timeouts.udp, 300)
6898 self.assertEqual(timeouts.icmp, 60)
6899 self.assertEqual(timeouts.tcp_transitory, 240)
6900 self.assertEqual(timeouts.tcp_established, 7440)
6902 # set and verify custom values
6903 self.vapi.nat_set_timeouts(udp=200, icmp=30, tcp_transitory=250,
6904 tcp_established=7450)
6905 timeouts = self.vapi.nat_get_timeouts()
6906 self.assertEqual(timeouts.udp, 200)
6907 self.assertEqual(timeouts.icmp, 30)
6908 self.assertEqual(timeouts.tcp_transitory, 250)
6909 self.assertEqual(timeouts.tcp_established, 7450)
6911 def test_dynamic(self):
6912 """ NAT64 dynamic translation test """
6913 self.tcp_port_in = 6303
6914 self.udp_port_in = 6304
6915 self.icmp_id_in = 6305
6917 ses_num_start = self.nat64_get_ses_num()
6919 self.vapi.nat64_add_del_pool_addr_range(self.nat_addr_n,
6921 self.vapi.nat64_add_del_interface(self.pg0.sw_if_index)
6922 self.vapi.nat64_add_del_interface(self.pg1.sw_if_index, is_inside=0)
6925 tcpn = self.statistics.get_counter('/err/nat64-in2out/TCP packets')
6926 udpn = self.statistics.get_counter('/err/nat64-in2out/UDP packets')
6927 icmpn = self.statistics.get_counter('/err/nat64-in2out/ICMP packets')
6928 totaln = self.statistics.get_counter(
6929 '/err/nat64-in2out/good in2out packets processed')
6931 pkts = self.create_stream_in_ip6(self.pg0, self.pg1)
6932 self.pg0.add_stream(pkts)
6933 self.pg_enable_capture(self.pg_interfaces)
6935 capture = self.pg1.get_capture(len(pkts))
6936 self.verify_capture_out(capture, nat_ip=self.nat_addr,
6937 dst_ip=self.pg1.remote_ip4)
6939 err = self.statistics.get_counter('/err/nat64-in2out/TCP packets')
6940 self.assertEqual(err - tcpn, 1)
6941 err = self.statistics.get_counter('/err/nat64-in2out/UDP packets')
6942 self.assertEqual(err - udpn, 1)
6943 err = self.statistics.get_counter('/err/nat64-in2out/ICMP packets')
6944 self.assertEqual(err - icmpn, 1)
6945 err = self.statistics.get_counter(
6946 '/err/nat64-in2out/good in2out packets processed')
6947 self.assertEqual(err - totaln, 3)
6950 tcpn = self.statistics.get_counter('/err/nat64-out2in/TCP packets')
6951 udpn = self.statistics.get_counter('/err/nat64-out2in/UDP packets')
6952 icmpn = self.statistics.get_counter('/err/nat64-out2in/ICMP packets')
6953 totaln = self.statistics.get_counter(
6954 '/err/nat64-out2in/good out2in packets processed')
6956 pkts = self.create_stream_out(self.pg1, dst_ip=self.nat_addr)
6957 self.pg1.add_stream(pkts)
6958 self.pg_enable_capture(self.pg_interfaces)
6960 capture = self.pg0.get_capture(len(pkts))
6961 ip = IPv6(src=''.join(['64:ff9b::', self.pg1.remote_ip4]))
6962 self.verify_capture_in_ip6(capture, ip[IPv6].src, self.pg0.remote_ip6)
6964 err = self.statistics.get_counter('/err/nat64-out2in/TCP packets')
6965 self.assertEqual(err - tcpn, 1)
6966 err = self.statistics.get_counter('/err/nat64-out2in/UDP packets')
6967 self.assertEqual(err - udpn, 1)
6968 err = self.statistics.get_counter('/err/nat64-out2in/ICMP packets')
6969 self.assertEqual(err - icmpn, 1)
6970 err = self.statistics.get_counter(
6971 '/err/nat64-out2in/good out2in packets processed')
6972 self.assertEqual(err - totaln, 3)
6975 pkts = self.create_stream_in_ip6(self.pg0, self.pg1)
6976 self.pg0.add_stream(pkts)
6977 self.pg_enable_capture(self.pg_interfaces)
6979 capture = self.pg1.get_capture(len(pkts))
6980 self.verify_capture_out(capture, nat_ip=self.nat_addr,
6981 dst_ip=self.pg1.remote_ip4)
6984 pkts = self.create_stream_out(self.pg1, dst_ip=self.nat_addr)
6985 self.pg1.add_stream(pkts)
6986 self.pg_enable_capture(self.pg_interfaces)
6988 capture = self.pg0.get_capture(len(pkts))
6989 self.verify_capture_in_ip6(capture, ip[IPv6].src, self.pg0.remote_ip6)
6991 ses_num_end = self.nat64_get_ses_num()
6993 self.assertEqual(ses_num_end - ses_num_start, 3)
6995 # tenant with specific VRF
6996 self.vapi.nat64_add_del_pool_addr_range(self.vrf1_nat_addr_n,
6997 self.vrf1_nat_addr_n,
6998 vrf_id=self.vrf1_id)
6999 self.vapi.nat64_add_del_interface(self.pg2.sw_if_index)
7001 pkts = self.create_stream_in_ip6(self.pg2, self.pg1)
7002 self.pg2.add_stream(pkts)
7003 self.pg_enable_capture(self.pg_interfaces)
7005 capture = self.pg1.get_capture(len(pkts))
7006 self.verify_capture_out(capture, nat_ip=self.vrf1_nat_addr,
7007 dst_ip=self.pg1.remote_ip4)
7009 pkts = self.create_stream_out(self.pg1, dst_ip=self.vrf1_nat_addr)
7010 self.pg1.add_stream(pkts)
7011 self.pg_enable_capture(self.pg_interfaces)
7013 capture = self.pg2.get_capture(len(pkts))
7014 self.verify_capture_in_ip6(capture, ip[IPv6].src, self.pg2.remote_ip6)
7016 def test_static(self):
7017 """ NAT64 static translation test """
7018 self.tcp_port_in = 60303
7019 self.udp_port_in = 60304
7020 self.icmp_id_in = 60305
7021 self.tcp_port_out = 60303
7022 self.udp_port_out = 60304
7023 self.icmp_id_out = 60305
7025 ses_num_start = self.nat64_get_ses_num()
7027 self.vapi.nat64_add_del_pool_addr_range(self.nat_addr_n,
7029 self.vapi.nat64_add_del_interface(self.pg0.sw_if_index)
7030 self.vapi.nat64_add_del_interface(self.pg1.sw_if_index, is_inside=0)
7032 self.vapi.nat64_add_del_static_bib(self.pg0.remote_ip6n,
7037 self.vapi.nat64_add_del_static_bib(self.pg0.remote_ip6n,
7042 self.vapi.nat64_add_del_static_bib(self.pg0.remote_ip6n,
7049 pkts = self.create_stream_in_ip6(self.pg0, self.pg1)
7050 self.pg0.add_stream(pkts)
7051 self.pg_enable_capture(self.pg_interfaces)
7053 capture = self.pg1.get_capture(len(pkts))
7054 self.verify_capture_out(capture, nat_ip=self.nat_addr,
7055 dst_ip=self.pg1.remote_ip4, same_port=True)
7058 pkts = self.create_stream_out(self.pg1, dst_ip=self.nat_addr)
7059 self.pg1.add_stream(pkts)
7060 self.pg_enable_capture(self.pg_interfaces)
7062 capture = self.pg0.get_capture(len(pkts))
7063 ip = IPv6(src=''.join(['64:ff9b::', self.pg1.remote_ip4]))
7064 self.verify_capture_in_ip6(capture, ip[IPv6].src, self.pg0.remote_ip6)
7066 ses_num_end = self.nat64_get_ses_num()
7068 self.assertEqual(ses_num_end - ses_num_start, 3)
7070 @unittest.skipUnless(running_extended_tests(), "part of extended tests")
7071 def test_session_timeout(self):
7072 """ NAT64 session timeout """
7073 self.icmp_id_in = 1234
7074 self.vapi.nat64_add_del_pool_addr_range(self.nat_addr_n,
7076 self.vapi.nat64_add_del_interface(self.pg0.sw_if_index)
7077 self.vapi.nat64_add_del_interface(self.pg1.sw_if_index, is_inside=0)
7078 self.vapi.nat_set_timeouts(icmp=5, tcp_transitory=5, tcp_established=5)
7080 pkts = self.create_stream_in_ip6(self.pg0, self.pg1)
7081 self.pg0.add_stream(pkts)
7082 self.pg_enable_capture(self.pg_interfaces)
7084 capture = self.pg1.get_capture(len(pkts))
7086 ses_num_before_timeout = self.nat64_get_ses_num()
7090 # ICMP and TCP session after timeout
7091 ses_num_after_timeout = self.nat64_get_ses_num()
7092 self.assertEqual(ses_num_before_timeout - ses_num_after_timeout, 2)
7094 def test_icmp_error(self):
7095 """ NAT64 ICMP Error message translation """
7096 self.tcp_port_in = 6303
7097 self.udp_port_in = 6304
7098 self.icmp_id_in = 6305
7100 self.vapi.nat64_add_del_pool_addr_range(self.nat_addr_n,
7102 self.vapi.nat64_add_del_interface(self.pg0.sw_if_index)
7103 self.vapi.nat64_add_del_interface(self.pg1.sw_if_index, is_inside=0)
7105 # send some packets to create sessions
7106 pkts = self.create_stream_in_ip6(self.pg0, self.pg1)
7107 self.pg0.add_stream(pkts)
7108 self.pg_enable_capture(self.pg_interfaces)
7110 capture_ip4 = self.pg1.get_capture(len(pkts))
7111 self.verify_capture_out(capture_ip4,
7112 nat_ip=self.nat_addr,
7113 dst_ip=self.pg1.remote_ip4)
7115 pkts = self.create_stream_out(self.pg1, dst_ip=self.nat_addr)
7116 self.pg1.add_stream(pkts)
7117 self.pg_enable_capture(self.pg_interfaces)
7119 capture_ip6 = self.pg0.get_capture(len(pkts))
7120 ip = IPv6(src=''.join(['64:ff9b::', self.pg1.remote_ip4]))
7121 self.verify_capture_in_ip6(capture_ip6, ip[IPv6].src,
7122 self.pg0.remote_ip6)
7125 pkts = [Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
7126 IPv6(src=self.pg0.remote_ip6, dst=ip[IPv6].src) /
7127 ICMPv6DestUnreach(code=1) /
7128 packet[IPv6] for packet in capture_ip6]
7129 self.pg0.add_stream(pkts)
7130 self.pg_enable_capture(self.pg_interfaces)
7132 capture = self.pg1.get_capture(len(pkts))
7133 for packet in capture:
7135 self.assertEqual(packet[IP].src, self.nat_addr)
7136 self.assertEqual(packet[IP].dst, self.pg1.remote_ip4)
7137 self.assertEqual(packet[ICMP].type, 3)
7138 self.assertEqual(packet[ICMP].code, 13)
7139 inner = packet[IPerror]
7140 self.assertEqual(inner.src, self.pg1.remote_ip4)
7141 self.assertEqual(inner.dst, self.nat_addr)
7142 self.assert_packet_checksums_valid(packet)
7143 if inner.haslayer(TCPerror):
7144 self.assertEqual(inner[TCPerror].dport, self.tcp_port_out)
7145 elif inner.haslayer(UDPerror):
7146 self.assertEqual(inner[UDPerror].dport, self.udp_port_out)
7148 self.assertEqual(inner[ICMPerror].id, self.icmp_id_out)
7150 self.logger.error(ppp("Unexpected or invalid packet:", packet))
7154 pkts = [Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
7155 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
7156 ICMP(type=3, code=13) /
7157 packet[IP] for packet in capture_ip4]
7158 self.pg1.add_stream(pkts)
7159 self.pg_enable_capture(self.pg_interfaces)
7161 capture = self.pg0.get_capture(len(pkts))
7162 for packet in capture:
7164 self.assertEqual(packet[IPv6].src, ip.src)
7165 self.assertEqual(packet[IPv6].dst, self.pg0.remote_ip6)
7166 icmp = packet[ICMPv6DestUnreach]
7167 self.assertEqual(icmp.code, 1)
7168 inner = icmp[IPerror6]
7169 self.assertEqual(inner.src, self.pg0.remote_ip6)
7170 self.assertEqual(inner.dst, ip.src)
7171 self.assert_icmpv6_checksum_valid(packet)
7172 if inner.haslayer(TCPerror):
7173 self.assertEqual(inner[TCPerror].sport, self.tcp_port_in)
7174 elif inner.haslayer(UDPerror):
7175 self.assertEqual(inner[UDPerror].sport, self.udp_port_in)
7177 self.assertEqual(inner[ICMPv6EchoRequest].id,
7180 self.logger.error(ppp("Unexpected or invalid packet:", packet))
7183 def test_hairpinning(self):
7184 """ NAT64 hairpinning """
7186 client = self.pg0.remote_hosts[0]
7187 server = self.pg0.remote_hosts[1]
7188 server_tcp_in_port = 22
7189 server_tcp_out_port = 4022
7190 server_udp_in_port = 23
7191 server_udp_out_port = 4023
7192 client_tcp_in_port = 1234
7193 client_udp_in_port = 1235
7194 client_tcp_out_port = 0
7195 client_udp_out_port = 0
7196 ip = IPv6(src=''.join(['64:ff9b::', self.nat_addr]))
7197 nat_addr_ip6 = ip.src
7199 self.vapi.nat64_add_del_pool_addr_range(self.nat_addr_n,
7201 self.vapi.nat64_add_del_interface(self.pg0.sw_if_index)
7202 self.vapi.nat64_add_del_interface(self.pg1.sw_if_index, is_inside=0)
7204 self.vapi.nat64_add_del_static_bib(server.ip6n,
7207 server_tcp_out_port,
7209 self.vapi.nat64_add_del_static_bib(server.ip6n,
7212 server_udp_out_port,
7217 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
7218 IPv6(src=client.ip6, dst=nat_addr_ip6) /
7219 TCP(sport=client_tcp_in_port, dport=server_tcp_out_port))
7221 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
7222 IPv6(src=client.ip6, dst=nat_addr_ip6) /
7223 UDP(sport=client_udp_in_port, dport=server_udp_out_port))
7225 self.pg0.add_stream(pkts)
7226 self.pg_enable_capture(self.pg_interfaces)
7228 capture = self.pg0.get_capture(len(pkts))
7229 for packet in capture:
7231 self.assertEqual(packet[IPv6].src, nat_addr_ip6)
7232 self.assertEqual(packet[IPv6].dst, server.ip6)
7233 self.assert_packet_checksums_valid(packet)
7234 if packet.haslayer(TCP):
7235 self.assertNotEqual(packet[TCP].sport, client_tcp_in_port)
7236 self.assertEqual(packet[TCP].dport, server_tcp_in_port)
7237 client_tcp_out_port = packet[TCP].sport
7239 self.assertNotEqual(packet[UDP].sport, client_udp_in_port)
7240 self.assertEqual(packet[UDP].dport, server_udp_in_port)
7241 client_udp_out_port = packet[UDP].sport
7243 self.logger.error(ppp("Unexpected or invalid packet:", packet))
7248 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
7249 IPv6(src=server.ip6, dst=nat_addr_ip6) /
7250 TCP(sport=server_tcp_in_port, dport=client_tcp_out_port))
7252 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
7253 IPv6(src=server.ip6, dst=nat_addr_ip6) /
7254 UDP(sport=server_udp_in_port, dport=client_udp_out_port))
7256 self.pg0.add_stream(pkts)
7257 self.pg_enable_capture(self.pg_interfaces)
7259 capture = self.pg0.get_capture(len(pkts))
7260 for packet in capture:
7262 self.assertEqual(packet[IPv6].src, nat_addr_ip6)
7263 self.assertEqual(packet[IPv6].dst, client.ip6)
7264 self.assert_packet_checksums_valid(packet)
7265 if packet.haslayer(TCP):
7266 self.assertEqual(packet[TCP].sport, server_tcp_out_port)
7267 self.assertEqual(packet[TCP].dport, client_tcp_in_port)
7269 self.assertEqual(packet[UDP].sport, server_udp_out_port)
7270 self.assertEqual(packet[UDP].dport, client_udp_in_port)
7272 self.logger.error(ppp("Unexpected or invalid packet:", packet))
7277 pkts = [Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
7278 IPv6(src=client.ip6, dst=nat_addr_ip6) /
7279 ICMPv6DestUnreach(code=1) /
7280 packet[IPv6] for packet in capture]
7281 self.pg0.add_stream(pkts)
7282 self.pg_enable_capture(self.pg_interfaces)
7284 capture = self.pg0.get_capture(len(pkts))
7285 for packet in capture:
7287 self.assertEqual(packet[IPv6].src, nat_addr_ip6)
7288 self.assertEqual(packet[IPv6].dst, server.ip6)
7289 icmp = packet[ICMPv6DestUnreach]
7290 self.assertEqual(icmp.code, 1)
7291 inner = icmp[IPerror6]
7292 self.assertEqual(inner.src, server.ip6)
7293 self.assertEqual(inner.dst, nat_addr_ip6)
7294 self.assert_packet_checksums_valid(packet)
7295 if inner.haslayer(TCPerror):
7296 self.assertEqual(inner[TCPerror].sport, server_tcp_in_port)
7297 self.assertEqual(inner[TCPerror].dport,
7298 client_tcp_out_port)
7300 self.assertEqual(inner[UDPerror].sport, server_udp_in_port)
7301 self.assertEqual(inner[UDPerror].dport,
7302 client_udp_out_port)
7304 self.logger.error(ppp("Unexpected or invalid packet:", packet))
7307 def test_prefix(self):
7308 """ NAT64 Network-Specific Prefix """
7310 self.vapi.nat64_add_del_pool_addr_range(self.nat_addr_n,
7312 self.vapi.nat64_add_del_interface(self.pg0.sw_if_index)
7313 self.vapi.nat64_add_del_interface(self.pg1.sw_if_index, is_inside=0)
7314 self.vapi.nat64_add_del_pool_addr_range(self.vrf1_nat_addr_n,
7315 self.vrf1_nat_addr_n,
7316 vrf_id=self.vrf1_id)
7317 self.vapi.nat64_add_del_interface(self.pg2.sw_if_index)
7320 global_pref64 = "2001:db8::"
7321 global_pref64_n = socket.inet_pton(socket.AF_INET6, global_pref64)
7322 global_pref64_len = 32
7323 self.vapi.nat64_add_del_prefix(global_pref64_n, global_pref64_len)
7325 prefix = self.vapi.nat64_prefix_dump()
7326 self.assertEqual(len(prefix), 1)
7327 self.assertEqual(prefix[0].prefix, global_pref64_n)
7328 self.assertEqual(prefix[0].prefix_len, global_pref64_len)
7329 self.assertEqual(prefix[0].vrf_id, 0)
7331 # Add tenant specific prefix
7332 vrf1_pref64 = "2001:db8:122:300::"
7333 vrf1_pref64_n = socket.inet_pton(socket.AF_INET6, vrf1_pref64)
7334 vrf1_pref64_len = 56
7335 self.vapi.nat64_add_del_prefix(vrf1_pref64_n,
7337 vrf_id=self.vrf1_id)
7338 prefix = self.vapi.nat64_prefix_dump()
7339 self.assertEqual(len(prefix), 2)
7342 pkts = self.create_stream_in_ip6(self.pg0,
7345 plen=global_pref64_len)
7346 self.pg0.add_stream(pkts)
7347 self.pg_enable_capture(self.pg_interfaces)
7349 capture = self.pg1.get_capture(len(pkts))
7350 self.verify_capture_out(capture, nat_ip=self.nat_addr,
7351 dst_ip=self.pg1.remote_ip4)
7353 pkts = self.create_stream_out(self.pg1, dst_ip=self.nat_addr)
7354 self.pg1.add_stream(pkts)
7355 self.pg_enable_capture(self.pg_interfaces)
7357 capture = self.pg0.get_capture(len(pkts))
7358 dst_ip = self.compose_ip6(self.pg1.remote_ip4,
7361 self.verify_capture_in_ip6(capture, dst_ip, self.pg0.remote_ip6)
7363 # Tenant specific prefix
7364 pkts = self.create_stream_in_ip6(self.pg2,
7367 plen=vrf1_pref64_len)
7368 self.pg2.add_stream(pkts)
7369 self.pg_enable_capture(self.pg_interfaces)
7371 capture = self.pg1.get_capture(len(pkts))
7372 self.verify_capture_out(capture, nat_ip=self.vrf1_nat_addr,
7373 dst_ip=self.pg1.remote_ip4)
7375 pkts = self.create_stream_out(self.pg1, dst_ip=self.vrf1_nat_addr)
7376 self.pg1.add_stream(pkts)
7377 self.pg_enable_capture(self.pg_interfaces)
7379 capture = self.pg2.get_capture(len(pkts))
7380 dst_ip = self.compose_ip6(self.pg1.remote_ip4,
7383 self.verify_capture_in_ip6(capture, dst_ip, self.pg2.remote_ip6)
7385 def test_unknown_proto(self):
7386 """ NAT64 translate packet with unknown protocol """
7388 self.vapi.nat64_add_del_pool_addr_range(self.nat_addr_n,
7390 self.vapi.nat64_add_del_interface(self.pg0.sw_if_index)
7391 self.vapi.nat64_add_del_interface(self.pg1.sw_if_index, is_inside=0)
7392 remote_ip6 = self.compose_ip6(self.pg1.remote_ip4, '64:ff9b::', 96)
7395 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
7396 IPv6(src=self.pg0.remote_ip6, dst=remote_ip6) /
7397 TCP(sport=self.tcp_port_in, dport=20))
7398 self.pg0.add_stream(p)
7399 self.pg_enable_capture(self.pg_interfaces)
7401 p = self.pg1.get_capture(1)
7403 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
7404 IPv6(src=self.pg0.remote_ip6, dst=remote_ip6, nh=47) /
7406 IP(src=self.pg2.local_ip4, dst=self.pg2.remote_ip4) /
7407 TCP(sport=1234, dport=1234))
7408 self.pg0.add_stream(p)
7409 self.pg_enable_capture(self.pg_interfaces)
7411 p = self.pg1.get_capture(1)
7414 self.assertEqual(packet[IP].src, self.nat_addr)
7415 self.assertEqual(packet[IP].dst, self.pg1.remote_ip4)
7416 self.assertEqual(packet.haslayer(GRE), 1)
7417 self.assert_packet_checksums_valid(packet)
7419 self.logger.error(ppp("Unexpected or invalid packet:", packet))
7423 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
7424 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
7426 IP(src=self.pg2.remote_ip4, dst=self.pg2.local_ip4) /
7427 TCP(sport=1234, dport=1234))
7428 self.pg1.add_stream(p)
7429 self.pg_enable_capture(self.pg_interfaces)
7431 p = self.pg0.get_capture(1)
7434 self.assertEqual(packet[IPv6].src, remote_ip6)
7435 self.assertEqual(packet[IPv6].dst, self.pg0.remote_ip6)
7436 self.assertEqual(packet[IPv6].nh, 47)
7438 self.logger.error(ppp("Unexpected or invalid packet:", packet))
7441 def test_hairpinning_unknown_proto(self):
7442 """ NAT64 translate packet with unknown protocol - hairpinning """
7444 client = self.pg0.remote_hosts[0]
7445 server = self.pg0.remote_hosts[1]
7446 server_tcp_in_port = 22
7447 server_tcp_out_port = 4022
7448 client_tcp_in_port = 1234
7449 client_tcp_out_port = 1235
7450 server_nat_ip = "10.0.0.100"
7451 client_nat_ip = "10.0.0.110"
7452 server_nat_ip_n = socket.inet_pton(socket.AF_INET, server_nat_ip)
7453 client_nat_ip_n = socket.inet_pton(socket.AF_INET, client_nat_ip)
7454 server_nat_ip6 = self.compose_ip6(server_nat_ip, '64:ff9b::', 96)
7455 client_nat_ip6 = self.compose_ip6(client_nat_ip, '64:ff9b::', 96)
7457 self.vapi.nat64_add_del_pool_addr_range(server_nat_ip_n,
7459 self.vapi.nat64_add_del_interface(self.pg0.sw_if_index)
7460 self.vapi.nat64_add_del_interface(self.pg1.sw_if_index, is_inside=0)
7462 self.vapi.nat64_add_del_static_bib(server.ip6n,
7465 server_tcp_out_port,
7468 self.vapi.nat64_add_del_static_bib(server.ip6n,
7474 self.vapi.nat64_add_del_static_bib(client.ip6n,
7477 client_tcp_out_port,
7481 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
7482 IPv6(src=client.ip6, dst=server_nat_ip6) /
7483 TCP(sport=client_tcp_in_port, dport=server_tcp_out_port))
7484 self.pg0.add_stream(p)
7485 self.pg_enable_capture(self.pg_interfaces)
7487 p = self.pg0.get_capture(1)
7489 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
7490 IPv6(src=client.ip6, dst=server_nat_ip6, nh=IP_PROTOS.gre) /
7492 IP(src=self.pg2.local_ip4, dst=self.pg2.remote_ip4) /
7493 TCP(sport=1234, dport=1234))
7494 self.pg0.add_stream(p)
7495 self.pg_enable_capture(self.pg_interfaces)
7497 p = self.pg0.get_capture(1)
7500 self.assertEqual(packet[IPv6].src, client_nat_ip6)
7501 self.assertEqual(packet[IPv6].dst, server.ip6)
7502 self.assertEqual(packet[IPv6].nh, IP_PROTOS.gre)
7504 self.logger.error(ppp("Unexpected or invalid packet:", packet))
7508 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
7509 IPv6(src=server.ip6, dst=client_nat_ip6, nh=IP_PROTOS.gre) /
7511 IP(src=self.pg2.remote_ip4, dst=self.pg2.local_ip4) /
7512 TCP(sport=1234, dport=1234))
7513 self.pg0.add_stream(p)
7514 self.pg_enable_capture(self.pg_interfaces)
7516 p = self.pg0.get_capture(1)
7519 self.assertEqual(packet[IPv6].src, server_nat_ip6)
7520 self.assertEqual(packet[IPv6].dst, client.ip6)
7521 self.assertEqual(packet[IPv6].nh, IP_PROTOS.gre)
7523 self.logger.error(ppp("Unexpected or invalid packet:", packet))
7526 def test_one_armed_nat64(self):
7527 """ One armed NAT64 """
7529 remote_host_ip6 = self.compose_ip6(self.pg3.remote_ip4,
7533 self.vapi.nat64_add_del_pool_addr_range(self.nat_addr_n,
7535 self.vapi.nat64_add_del_interface(self.pg3.sw_if_index)
7536 self.vapi.nat64_add_del_interface(self.pg3.sw_if_index, is_inside=0)
7539 p = (Ether(src=self.pg3.remote_mac, dst=self.pg3.local_mac) /
7540 IPv6(src=self.pg3.remote_ip6, dst=remote_host_ip6) /
7541 TCP(sport=12345, dport=80))
7542 self.pg3.add_stream(p)
7543 self.pg_enable_capture(self.pg_interfaces)
7545 capture = self.pg3.get_capture(1)
7550 self.assertEqual(ip.src, self.nat_addr)
7551 self.assertEqual(ip.dst, self.pg3.remote_ip4)
7552 self.assertNotEqual(tcp.sport, 12345)
7553 external_port = tcp.sport
7554 self.assertEqual(tcp.dport, 80)
7555 self.assert_packet_checksums_valid(p)
7557 self.logger.error(ppp("Unexpected or invalid packet:", p))
7561 p = (Ether(src=self.pg3.remote_mac, dst=self.pg3.local_mac) /
7562 IP(src=self.pg3.remote_ip4, dst=self.nat_addr) /
7563 TCP(sport=80, dport=external_port))
7564 self.pg3.add_stream(p)
7565 self.pg_enable_capture(self.pg_interfaces)
7567 capture = self.pg3.get_capture(1)
7572 self.assertEqual(ip.src, remote_host_ip6)
7573 self.assertEqual(ip.dst, self.pg3.remote_ip6)
7574 self.assertEqual(tcp.sport, 80)
7575 self.assertEqual(tcp.dport, 12345)
7576 self.assert_packet_checksums_valid(p)
7578 self.logger.error(ppp("Unexpected or invalid packet:", p))
7581 def test_frag_in_order(self):
7582 """ NAT64 translate fragments arriving in order """
7583 self.tcp_port_in = random.randint(1025, 65535)
7585 self.vapi.nat64_add_del_pool_addr_range(self.nat_addr_n,
7587 self.vapi.nat64_add_del_interface(self.pg0.sw_if_index)
7588 self.vapi.nat64_add_del_interface(self.pg1.sw_if_index, is_inside=0)
7590 reass = self.vapi.nat_reass_dump()
7591 reass_n_start = len(reass)
7595 pkts = self.create_stream_frag_ip6(self.pg0, self.pg1.remote_ip4,
7596 self.tcp_port_in, 20, data)
7597 self.pg0.add_stream(pkts)
7598 self.pg_enable_capture(self.pg_interfaces)
7600 frags = self.pg1.get_capture(len(pkts))
7601 p = self.reass_frags_and_verify(frags,
7603 self.pg1.remote_ip4)
7604 self.assertEqual(p[TCP].dport, 20)
7605 self.assertNotEqual(p[TCP].sport, self.tcp_port_in)
7606 self.tcp_port_out = p[TCP].sport
7607 self.assertEqual(data, p[Raw].load)
7610 data = "A" * 4 + "b" * 16 + "C" * 3
7611 pkts = self.create_stream_frag(self.pg1,
7616 self.pg1.add_stream(pkts)
7617 self.pg_enable_capture(self.pg_interfaces)
7619 frags = self.pg0.get_capture(len(pkts))
7620 src = self.compose_ip6(self.pg1.remote_ip4, '64:ff9b::', 96)
7621 p = self.reass_frags_and_verify_ip6(frags, src, self.pg0.remote_ip6)
7622 self.assertEqual(p[TCP].sport, 20)
7623 self.assertEqual(p[TCP].dport, self.tcp_port_in)
7624 self.assertEqual(data, p[Raw].load)
7626 reass = self.vapi.nat_reass_dump()
7627 reass_n_end = len(reass)
7629 self.assertEqual(reass_n_end - reass_n_start, 2)
7631 def test_reass_hairpinning(self):
7632 """ NAT64 fragments hairpinning """
7634 server = self.pg0.remote_hosts[1]
7635 server_in_port = random.randint(1025, 65535)
7636 server_out_port = random.randint(1025, 65535)
7637 client_in_port = random.randint(1025, 65535)
7638 ip = IPv6(src=''.join(['64:ff9b::', self.nat_addr]))
7639 nat_addr_ip6 = ip.src
7641 self.vapi.nat64_add_del_pool_addr_range(self.nat_addr_n,
7643 self.vapi.nat64_add_del_interface(self.pg0.sw_if_index)
7644 self.vapi.nat64_add_del_interface(self.pg1.sw_if_index, is_inside=0)
7646 # add static BIB entry for server
7647 self.vapi.nat64_add_del_static_bib(server.ip6n,
7653 # send packet from host to server
7654 pkts = self.create_stream_frag_ip6(self.pg0,
7659 self.pg0.add_stream(pkts)
7660 self.pg_enable_capture(self.pg_interfaces)
7662 frags = self.pg0.get_capture(len(pkts))
7663 p = self.reass_frags_and_verify_ip6(frags, nat_addr_ip6, server.ip6)
7664 self.assertNotEqual(p[TCP].sport, client_in_port)
7665 self.assertEqual(p[TCP].dport, server_in_port)
7666 self.assertEqual(data, p[Raw].load)
7668 def test_frag_out_of_order(self):
7669 """ NAT64 translate fragments arriving out of order """
7670 self.tcp_port_in = random.randint(1025, 65535)
7672 self.vapi.nat64_add_del_pool_addr_range(self.nat_addr_n,
7674 self.vapi.nat64_add_del_interface(self.pg0.sw_if_index)
7675 self.vapi.nat64_add_del_interface(self.pg1.sw_if_index, is_inside=0)
7679 pkts = self.create_stream_frag_ip6(self.pg0, self.pg1.remote_ip4,
7680 self.tcp_port_in, 20, data)
7682 self.pg0.add_stream(pkts)
7683 self.pg_enable_capture(self.pg_interfaces)
7685 frags = self.pg1.get_capture(len(pkts))
7686 p = self.reass_frags_and_verify(frags,
7688 self.pg1.remote_ip4)
7689 self.assertEqual(p[TCP].dport, 20)
7690 self.assertNotEqual(p[TCP].sport, self.tcp_port_in)
7691 self.tcp_port_out = p[TCP].sport
7692 self.assertEqual(data, p[Raw].load)
7695 data = "A" * 4 + "B" * 16 + "C" * 3
7696 pkts = self.create_stream_frag(self.pg1,
7702 self.pg1.add_stream(pkts)
7703 self.pg_enable_capture(self.pg_interfaces)
7705 frags = self.pg0.get_capture(len(pkts))
7706 src = self.compose_ip6(self.pg1.remote_ip4, '64:ff9b::', 96)
7707 p = self.reass_frags_and_verify_ip6(frags, src, self.pg0.remote_ip6)
7708 self.assertEqual(p[TCP].sport, 20)
7709 self.assertEqual(p[TCP].dport, self.tcp_port_in)
7710 self.assertEqual(data, p[Raw].load)
7712 def test_interface_addr(self):
7713 """ Acquire NAT64 pool addresses from interface """
7714 self.vapi.nat64_add_interface_addr(self.pg4.sw_if_index)
7716 # no address in NAT64 pool
7717 adresses = self.vapi.nat44_address_dump()
7718 self.assertEqual(0, len(adresses))
7720 # configure interface address and check NAT64 address pool
7721 self.pg4.config_ip4()
7722 addresses = self.vapi.nat64_pool_addr_dump()
7723 self.assertEqual(len(addresses), 1)
7724 self.assertEqual(addresses[0].address, self.pg4.local_ip4n)
7726 # remove interface address and check NAT64 address pool
7727 self.pg4.unconfig_ip4()
7728 addresses = self.vapi.nat64_pool_addr_dump()
7729 self.assertEqual(0, len(adresses))
7731 @unittest.skipUnless(running_extended_tests(), "part of extended tests")
7732 def test_ipfix_max_bibs_sessions(self):
7733 """ IPFIX logging maximum session and BIB entries exceeded """
7736 remote_host_ip6 = self.compose_ip6(self.pg1.remote_ip4,
7740 self.vapi.nat64_add_del_pool_addr_range(self.nat_addr_n,
7742 self.vapi.nat64_add_del_interface(self.pg0.sw_if_index)
7743 self.vapi.nat64_add_del_interface(self.pg1.sw_if_index, is_inside=0)
7747 for i in range(0, max_bibs):
7748 src = "fd01:aa::%x" % (i)
7749 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
7750 IPv6(src=src, dst=remote_host_ip6) /
7751 TCP(sport=12345, dport=80))
7753 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
7754 IPv6(src=src, dst=remote_host_ip6) /
7755 TCP(sport=12345, dport=22))
7757 self.pg0.add_stream(pkts)
7758 self.pg_enable_capture(self.pg_interfaces)
7760 self.pg1.get_capture(max_sessions)
7762 self.vapi.set_ipfix_exporter(collector_address=self.pg3.remote_ip4n,
7763 src_address=self.pg3.local_ip4n,
7765 template_interval=10)
7766 self.vapi.nat_ipfix(domain_id=self.ipfix_domain_id,
7767 src_port=self.ipfix_src_port)
7769 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
7770 IPv6(src=src, dst=remote_host_ip6) /
7771 TCP(sport=12345, dport=25))
7772 self.pg0.add_stream(p)
7773 self.pg_enable_capture(self.pg_interfaces)
7775 self.pg1.assert_nothing_captured()
7777 self.vapi.cli("ipfix flush") # FIXME this should be an API call
7778 capture = self.pg3.get_capture(9)
7779 ipfix = IPFIXDecoder()
7780 # first load template
7782 self.assertTrue(p.haslayer(IPFIX))
7783 self.assertEqual(p[IP].src, self.pg3.local_ip4)
7784 self.assertEqual(p[IP].dst, self.pg3.remote_ip4)
7785 self.assertEqual(p[UDP].sport, self.ipfix_src_port)
7786 self.assertEqual(p[UDP].dport, 4739)
7787 self.assertEqual(p[IPFIX].observationDomainID,
7788 self.ipfix_domain_id)
7789 if p.haslayer(Template):
7790 ipfix.add_template(p.getlayer(Template))
7791 # verify events in data set
7793 if p.haslayer(Data):
7794 data = ipfix.decode_data_set(p.getlayer(Set))
7795 self.verify_ipfix_max_sessions(data, max_sessions)
7797 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
7798 IPv6(src=self.pg0.remote_ip6, dst=remote_host_ip6) /
7799 TCP(sport=12345, dport=80))
7800 self.pg0.add_stream(p)
7801 self.pg_enable_capture(self.pg_interfaces)
7803 self.pg1.assert_nothing_captured()
7805 self.vapi.cli("ipfix flush") # FIXME this should be an API call
7806 capture = self.pg3.get_capture(1)
7807 # verify events in data set
7809 self.assertTrue(p.haslayer(IPFIX))
7810 self.assertEqual(p[IP].src, self.pg3.local_ip4)
7811 self.assertEqual(p[IP].dst, self.pg3.remote_ip4)
7812 self.assertEqual(p[UDP].sport, self.ipfix_src_port)
7813 self.assertEqual(p[UDP].dport, 4739)
7814 self.assertEqual(p[IPFIX].observationDomainID,
7815 self.ipfix_domain_id)
7816 if p.haslayer(Data):
7817 data = ipfix.decode_data_set(p.getlayer(Set))
7818 self.verify_ipfix_max_bibs(data, max_bibs)
7820 def test_ipfix_max_frags(self):
7821 """ IPFIX logging maximum fragments pending reassembly exceeded """
7822 self.vapi.nat64_add_del_pool_addr_range(self.nat_addr_n,
7824 self.vapi.nat64_add_del_interface(self.pg0.sw_if_index)
7825 self.vapi.nat64_add_del_interface(self.pg1.sw_if_index, is_inside=0)
7826 self.vapi.nat_set_reass(max_frag=1, is_ip6=1)
7827 self.vapi.set_ipfix_exporter(collector_address=self.pg3.remote_ip4n,
7828 src_address=self.pg3.local_ip4n,
7830 template_interval=10)
7831 self.vapi.nat_ipfix(domain_id=self.ipfix_domain_id,
7832 src_port=self.ipfix_src_port)
7835 pkts = self.create_stream_frag_ip6(self.pg0, self.pg1.remote_ip4,
7836 self.tcp_port_in, 20, data)
7838 self.pg0.add_stream(pkts)
7839 self.pg_enable_capture(self.pg_interfaces)
7841 self.pg1.assert_nothing_captured()
7843 self.vapi.cli("ipfix flush") # FIXME this should be an API call
7844 capture = self.pg3.get_capture(9)
7845 ipfix = IPFIXDecoder()
7846 # first load template
7848 self.assertTrue(p.haslayer(IPFIX))
7849 self.assertEqual(p[IP].src, self.pg3.local_ip4)
7850 self.assertEqual(p[IP].dst, self.pg3.remote_ip4)
7851 self.assertEqual(p[UDP].sport, self.ipfix_src_port)
7852 self.assertEqual(p[UDP].dport, 4739)
7853 self.assertEqual(p[IPFIX].observationDomainID,
7854 self.ipfix_domain_id)
7855 if p.haslayer(Template):
7856 ipfix.add_template(p.getlayer(Template))
7857 # verify events in data set
7859 if p.haslayer(Data):
7860 data = ipfix.decode_data_set(p.getlayer(Set))
7861 self.verify_ipfix_max_fragments_ip6(data, 1,
7862 self.pg0.remote_ip6n)
7864 def test_ipfix_bib_ses(self):
7865 """ IPFIX logging NAT64 BIB/session create and delete events """
7866 self.tcp_port_in = random.randint(1025, 65535)
7867 remote_host_ip6 = self.compose_ip6(self.pg1.remote_ip4,
7871 self.vapi.nat64_add_del_pool_addr_range(self.nat_addr_n,
7873 self.vapi.nat64_add_del_interface(self.pg0.sw_if_index)
7874 self.vapi.nat64_add_del_interface(self.pg1.sw_if_index, is_inside=0)
7875 self.vapi.set_ipfix_exporter(collector_address=self.pg3.remote_ip4n,
7876 src_address=self.pg3.local_ip4n,
7878 template_interval=10)
7879 self.vapi.nat_ipfix(domain_id=self.ipfix_domain_id,
7880 src_port=self.ipfix_src_port)
7883 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
7884 IPv6(src=self.pg0.remote_ip6, dst=remote_host_ip6) /
7885 TCP(sport=self.tcp_port_in, dport=25))
7886 self.pg0.add_stream(p)
7887 self.pg_enable_capture(self.pg_interfaces)
7889 p = self.pg1.get_capture(1)
7890 self.tcp_port_out = p[0][TCP].sport
7891 self.vapi.cli("ipfix flush") # FIXME this should be an API call
7892 capture = self.pg3.get_capture(10)
7893 ipfix = IPFIXDecoder()
7894 # first load template
7896 self.assertTrue(p.haslayer(IPFIX))
7897 self.assertEqual(p[IP].src, self.pg3.local_ip4)
7898 self.assertEqual(p[IP].dst, self.pg3.remote_ip4)
7899 self.assertEqual(p[UDP].sport, self.ipfix_src_port)
7900 self.assertEqual(p[UDP].dport, 4739)
7901 self.assertEqual(p[IPFIX].observationDomainID,
7902 self.ipfix_domain_id)
7903 if p.haslayer(Template):
7904 ipfix.add_template(p.getlayer(Template))
7905 # verify events in data set
7907 if p.haslayer(Data):
7908 data = ipfix.decode_data_set(p.getlayer(Set))
7909 if ord(data[0][230]) == 10:
7910 self.verify_ipfix_bib(data, 1, self.pg0.remote_ip6n)
7911 elif ord(data[0][230]) == 6:
7912 self.verify_ipfix_nat64_ses(data,
7914 self.pg0.remote_ip6n,
7915 self.pg1.remote_ip4,
7918 self.logger.error(ppp("Unexpected or invalid packet: ", p))
7921 self.pg_enable_capture(self.pg_interfaces)
7922 self.vapi.nat64_add_del_pool_addr_range(self.nat_addr_n,
7925 self.vapi.cli("ipfix flush") # FIXME this should be an API call
7926 capture = self.pg3.get_capture(2)
7927 # verify events in data set
7929 self.assertTrue(p.haslayer(IPFIX))
7930 self.assertEqual(p[IP].src, self.pg3.local_ip4)
7931 self.assertEqual(p[IP].dst, self.pg3.remote_ip4)
7932 self.assertEqual(p[UDP].sport, self.ipfix_src_port)
7933 self.assertEqual(p[UDP].dport, 4739)
7934 self.assertEqual(p[IPFIX].observationDomainID,
7935 self.ipfix_domain_id)
7936 if p.haslayer(Data):
7937 data = ipfix.decode_data_set(p.getlayer(Set))
7938 if ord(data[0][230]) == 11:
7939 self.verify_ipfix_bib(data, 0, self.pg0.remote_ip6n)
7940 elif ord(data[0][230]) == 7:
7941 self.verify_ipfix_nat64_ses(data,
7943 self.pg0.remote_ip6n,
7944 self.pg1.remote_ip4,
7947 self.logger.error(ppp("Unexpected or invalid packet: ", p))
7949 def test_syslog_sess(self):
7950 """ Test syslog session creation and deletion """
7951 self.tcp_port_in = random.randint(1025, 65535)
7952 remote_host_ip6 = self.compose_ip6(self.pg1.remote_ip4,
7956 self.vapi.nat64_add_del_pool_addr_range(self.nat_addr_n,
7958 self.vapi.nat64_add_del_interface(self.pg0.sw_if_index)
7959 self.vapi.nat64_add_del_interface(self.pg1.sw_if_index, is_inside=0)
7960 self.vapi.syslog_set_filter(SYSLOG_SEVERITY.INFO)
7961 self.vapi.syslog_set_sender(self.pg3.remote_ip4n, self.pg3.local_ip4n)
7963 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
7964 IPv6(src=self.pg0.remote_ip6, dst=remote_host_ip6) /
7965 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port))
7966 self.pg0.add_stream(p)
7967 self.pg_enable_capture(self.pg_interfaces)
7969 p = self.pg1.get_capture(1)
7970 self.tcp_port_out = p[0][TCP].sport
7971 capture = self.pg3.get_capture(1)
7972 self.verify_syslog_sess(capture[0][Raw].load, is_ip6=True)
7974 self.pg_enable_capture(self.pg_interfaces)
7976 self.vapi.nat64_add_del_pool_addr_range(self.nat_addr_n,
7979 capture = self.pg3.get_capture(1)
7980 self.verify_syslog_sess(capture[0][Raw].load, False, True)
7982 def nat64_get_ses_num(self):
7984 Return number of active NAT64 sessions.
7986 st = self.vapi.nat64_st_dump()
7989 def clear_nat64(self):
7991 Clear NAT64 configuration.
7993 self.vapi.nat_ipfix(enable=0, src_port=self.ipfix_src_port,
7994 domain_id=self.ipfix_domain_id)
7995 self.ipfix_src_port = 4739
7996 self.ipfix_domain_id = 1
7998 self.vapi.syslog_set_filter(SYSLOG_SEVERITY.EMERG)
8000 self.vapi.nat_set_timeouts()
8002 interfaces = self.vapi.nat64_interface_dump()
8003 for intf in interfaces:
8004 if intf.is_inside > 1:
8005 self.vapi.nat64_add_del_interface(intf.sw_if_index,
8008 self.vapi.nat64_add_del_interface(intf.sw_if_index,
8012 bib = self.vapi.nat64_bib_dump(255)
8015 self.vapi.nat64_add_del_static_bib(bibe.i_addr,
8023 adresses = self.vapi.nat64_pool_addr_dump()
8024 for addr in adresses:
8025 self.vapi.nat64_add_del_pool_addr_range(addr.address,
8030 prefixes = self.vapi.nat64_prefix_dump()
8031 for prefix in prefixes:
8032 self.vapi.nat64_add_del_prefix(prefix.prefix,
8034 vrf_id=prefix.vrf_id,
8038 super(TestNAT64, self).tearDown()
8039 if not self.vpp_dead:
8040 self.logger.info(self.vapi.cli("show nat64 pool"))
8041 self.logger.info(self.vapi.cli("show nat64 interfaces"))
8042 self.logger.info(self.vapi.cli("show nat64 prefix"))
8043 self.logger.info(self.vapi.cli("show nat64 bib all"))
8044 self.logger.info(self.vapi.cli("show nat64 session table all"))
8045 self.logger.info(self.vapi.cli("show nat virtual-reassembly"))
8049 class TestDSlite(MethodHolder):
8050 """ DS-Lite Test Cases """
8053 def setUpClass(cls):
8054 super(TestDSlite, cls).setUpClass()
8057 cls.nat_addr = '10.0.0.3'
8058 cls.nat_addr_n = socket.inet_pton(socket.AF_INET, cls.nat_addr)
8060 cls.create_pg_interfaces(range(3))
8062 cls.pg0.config_ip4()
8063 cls.pg0.resolve_arp()
8065 cls.pg1.config_ip6()
8066 cls.pg1.generate_remote_hosts(2)
8067 cls.pg1.configure_ipv6_neighbors()
8069 cls.pg2.config_ip4()
8070 cls.pg2.resolve_arp()
8073 super(TestDSlite, cls).tearDownClass()
8076 def verify_syslog_apmadd(self, data, isaddr, isport, xsaddr, xsport,
8078 message = data.decode('utf-8')
8080 message = SyslogMessage.parse(message)
8081 self.assertEqual(message.severity, SyslogSeverity.info)
8082 self.assertEqual(message.appname, 'NAT')
8083 self.assertEqual(message.msgid, 'APMADD')
8084 sd_params = message.sd.get('napmap')
8085 self.assertTrue(sd_params is not None)
8086 self.assertEqual(sd_params.get('IATYP'), 'IPv4')
8087 self.assertEqual(sd_params.get('ISADDR'), isaddr)
8088 self.assertEqual(sd_params.get('ISPORT'), "%d" % isport)
8089 self.assertEqual(sd_params.get('XATYP'), 'IPv4')
8090 self.assertEqual(sd_params.get('XSADDR'), xsaddr)
8091 self.assertEqual(sd_params.get('XSPORT'), "%d" % xsport)
8092 self.assertEqual(sd_params.get('PROTO'), "%d" % proto)
8093 self.assertTrue(sd_params.get('SSUBIX') is not None)
8094 self.assertEqual(sd_params.get('SV6ENC'), sv6enc)
8095 except ParseError as e:
8096 self.logger.error(e)
8098 def test_dslite(self):
8099 """ Test DS-Lite """
8100 nat_config = self.vapi.nat_show_config()
8101 self.assertEqual(0, nat_config.dslite_ce)
8103 self.vapi.dslite_add_del_pool_addr_range(self.nat_addr_n,
8105 aftr_ip4 = '192.0.0.1'
8106 aftr_ip4_n = socket.inet_pton(socket.AF_INET, aftr_ip4)
8107 aftr_ip6 = '2001:db8:85a3::8a2e:370:1'
8108 aftr_ip6_n = socket.inet_pton(socket.AF_INET6, aftr_ip6)
8109 self.vapi.dslite_set_aftr_addr(aftr_ip6_n, aftr_ip4_n)
8110 self.vapi.syslog_set_sender(self.pg2.remote_ip4n, self.pg2.local_ip4n)
8113 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
8114 IPv6(dst=aftr_ip6, src=self.pg1.remote_hosts[0].ip6) /
8115 IP(dst=self.pg0.remote_ip4, src='192.168.1.1') /
8116 UDP(sport=20000, dport=10000))
8117 self.pg1.add_stream(p)
8118 self.pg_enable_capture(self.pg_interfaces)
8120 capture = self.pg0.get_capture(1)
8121 capture = capture[0]
8122 self.assertFalse(capture.haslayer(IPv6))
8123 self.assertEqual(capture[IP].src, self.nat_addr)
8124 self.assertEqual(capture[IP].dst, self.pg0.remote_ip4)
8125 self.assertNotEqual(capture[UDP].sport, 20000)
8126 self.assertEqual(capture[UDP].dport, 10000)
8127 self.assert_packet_checksums_valid(capture)
8128 out_port = capture[UDP].sport
8129 capture = self.pg2.get_capture(1)
8130 self.verify_syslog_apmadd(capture[0][Raw].load, '192.168.1.1',
8131 20000, self.nat_addr, out_port,
8132 self.pg1.remote_hosts[0].ip6, IP_PROTOS.udp)
8134 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
8135 IP(dst=self.nat_addr, src=self.pg0.remote_ip4) /
8136 UDP(sport=10000, dport=out_port))
8137 self.pg0.add_stream(p)
8138 self.pg_enable_capture(self.pg_interfaces)
8140 capture = self.pg1.get_capture(1)
8141 capture = capture[0]
8142 self.assertEqual(capture[IPv6].src, aftr_ip6)
8143 self.assertEqual(capture[IPv6].dst, self.pg1.remote_hosts[0].ip6)
8144 self.assertEqual(capture[IP].src, self.pg0.remote_ip4)
8145 self.assertEqual(capture[IP].dst, '192.168.1.1')
8146 self.assertEqual(capture[UDP].sport, 10000)
8147 self.assertEqual(capture[UDP].dport, 20000)
8148 self.assert_packet_checksums_valid(capture)
8151 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
8152 IPv6(dst=aftr_ip6, src=self.pg1.remote_hosts[1].ip6) /
8153 IP(dst=self.pg0.remote_ip4, src='192.168.1.1') /
8154 TCP(sport=20001, dport=10001))
8155 self.pg1.add_stream(p)
8156 self.pg_enable_capture(self.pg_interfaces)
8158 capture = self.pg0.get_capture(1)
8159 capture = capture[0]
8160 self.assertFalse(capture.haslayer(IPv6))
8161 self.assertEqual(capture[IP].src, self.nat_addr)
8162 self.assertEqual(capture[IP].dst, self.pg0.remote_ip4)
8163 self.assertNotEqual(capture[TCP].sport, 20001)
8164 self.assertEqual(capture[TCP].dport, 10001)
8165 self.assert_packet_checksums_valid(capture)
8166 out_port = capture[TCP].sport
8168 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
8169 IP(dst=self.nat_addr, src=self.pg0.remote_ip4) /
8170 TCP(sport=10001, dport=out_port))
8171 self.pg0.add_stream(p)
8172 self.pg_enable_capture(self.pg_interfaces)
8174 capture = self.pg1.get_capture(1)
8175 capture = capture[0]
8176 self.assertEqual(capture[IPv6].src, aftr_ip6)
8177 self.assertEqual(capture[IPv6].dst, self.pg1.remote_hosts[1].ip6)
8178 self.assertEqual(capture[IP].src, self.pg0.remote_ip4)
8179 self.assertEqual(capture[IP].dst, '192.168.1.1')
8180 self.assertEqual(capture[TCP].sport, 10001)
8181 self.assertEqual(capture[TCP].dport, 20001)
8182 self.assert_packet_checksums_valid(capture)
8185 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
8186 IPv6(dst=aftr_ip6, src=self.pg1.remote_hosts[1].ip6) /
8187 IP(dst=self.pg0.remote_ip4, src='192.168.1.1') /
8188 ICMP(id=4000, type='echo-request'))
8189 self.pg1.add_stream(p)
8190 self.pg_enable_capture(self.pg_interfaces)
8192 capture = self.pg0.get_capture(1)
8193 capture = capture[0]
8194 self.assertFalse(capture.haslayer(IPv6))
8195 self.assertEqual(capture[IP].src, self.nat_addr)
8196 self.assertEqual(capture[IP].dst, self.pg0.remote_ip4)
8197 self.assertNotEqual(capture[ICMP].id, 4000)
8198 self.assert_packet_checksums_valid(capture)
8199 out_id = capture[ICMP].id
8201 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
8202 IP(dst=self.nat_addr, src=self.pg0.remote_ip4) /
8203 ICMP(id=out_id, type='echo-reply'))
8204 self.pg0.add_stream(p)
8205 self.pg_enable_capture(self.pg_interfaces)
8207 capture = self.pg1.get_capture(1)
8208 capture = capture[0]
8209 self.assertEqual(capture[IPv6].src, aftr_ip6)
8210 self.assertEqual(capture[IPv6].dst, self.pg1.remote_hosts[1].ip6)
8211 self.assertEqual(capture[IP].src, self.pg0.remote_ip4)
8212 self.assertEqual(capture[IP].dst, '192.168.1.1')
8213 self.assertEqual(capture[ICMP].id, 4000)
8214 self.assert_packet_checksums_valid(capture)
8216 # ping DS-Lite AFTR tunnel endpoint address
8217 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
8218 IPv6(src=self.pg1.remote_hosts[1].ip6, dst=aftr_ip6) /
8219 ICMPv6EchoRequest())
8220 self.pg1.add_stream(p)
8221 self.pg_enable_capture(self.pg_interfaces)
8223 capture = self.pg1.get_capture(1)
8224 capture = capture[0]
8225 self.assertEqual(capture[IPv6].src, aftr_ip6)
8226 self.assertEqual(capture[IPv6].dst, self.pg1.remote_hosts[1].ip6)
8227 self.assertTrue(capture.haslayer(ICMPv6EchoReply))
8230 super(TestDSlite, self).tearDown()
8231 if not self.vpp_dead:
8232 self.logger.info(self.vapi.cli("show dslite pool"))
8234 self.vapi.cli("show dslite aftr-tunnel-endpoint-address"))
8235 self.logger.info(self.vapi.cli("show dslite sessions"))
8238 class TestDSliteCE(MethodHolder):
8239 """ DS-Lite CE Test Cases """
8242 def setUpConstants(cls):
8243 super(TestDSliteCE, cls).setUpConstants()
8244 cls.vpp_cmdline.extend(["nat", "{", "dslite ce", "}"])
8247 def setUpClass(cls):
8248 super(TestDSliteCE, cls).setUpClass()
8251 cls.create_pg_interfaces(range(2))
8253 cls.pg0.config_ip4()
8254 cls.pg0.resolve_arp()
8256 cls.pg1.config_ip6()
8257 cls.pg1.generate_remote_hosts(1)
8258 cls.pg1.configure_ipv6_neighbors()
8261 super(TestDSliteCE, cls).tearDownClass()
8264 def test_dslite_ce(self):
8265 """ Test DS-Lite CE """
8267 nat_config = self.vapi.nat_show_config()
8268 self.assertEqual(1, nat_config.dslite_ce)
8270 b4_ip4 = '192.0.0.2'
8271 b4_ip4_n = socket.inet_pton(socket.AF_INET, b4_ip4)
8272 b4_ip6 = '2001:db8:62aa::375e:f4c1:1'
8273 b4_ip6_n = socket.inet_pton(socket.AF_INET6, b4_ip6)
8274 self.vapi.dslite_set_b4_addr(b4_ip6_n, b4_ip4_n)
8276 aftr_ip4 = '192.0.0.1'
8277 aftr_ip4_n = socket.inet_pton(socket.AF_INET, aftr_ip4)
8278 aftr_ip6 = '2001:db8:85a3::8a2e:370:1'
8279 aftr_ip6_n = socket.inet_pton(socket.AF_INET6, aftr_ip6)
8280 self.vapi.dslite_set_aftr_addr(aftr_ip6_n, aftr_ip4_n)
8282 self.vapi.ip_add_del_route(dst_address=aftr_ip6_n,
8283 dst_address_length=128,
8284 next_hop_address=self.pg1.remote_ip6n,
8285 next_hop_sw_if_index=self.pg1.sw_if_index,
8289 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
8290 IP(dst=self.pg1.remote_ip4, src=self.pg0.remote_ip4) /
8291 UDP(sport=10000, dport=20000))
8292 self.pg0.add_stream(p)
8293 self.pg_enable_capture(self.pg_interfaces)
8295 capture = self.pg1.get_capture(1)
8296 capture = capture[0]
8297 self.assertEqual(capture[IPv6].src, b4_ip6)
8298 self.assertEqual(capture[IPv6].dst, aftr_ip6)
8299 self.assertEqual(capture[IP].src, self.pg0.remote_ip4)
8300 self.assertEqual(capture[IP].dst, self.pg1.remote_ip4)
8301 self.assertEqual(capture[UDP].sport, 10000)
8302 self.assertEqual(capture[UDP].dport, 20000)
8303 self.assert_packet_checksums_valid(capture)
8306 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
8307 IPv6(dst=b4_ip6, src=aftr_ip6) /
8308 IP(dst=self.pg0.remote_ip4, src=self.pg1.remote_ip4) /
8309 UDP(sport=20000, dport=10000))
8310 self.pg1.add_stream(p)
8311 self.pg_enable_capture(self.pg_interfaces)
8313 capture = self.pg0.get_capture(1)
8314 capture = capture[0]
8315 self.assertFalse(capture.haslayer(IPv6))
8316 self.assertEqual(capture[IP].src, self.pg1.remote_ip4)
8317 self.assertEqual(capture[IP].dst, self.pg0.remote_ip4)
8318 self.assertEqual(capture[UDP].sport, 20000)
8319 self.assertEqual(capture[UDP].dport, 10000)
8320 self.assert_packet_checksums_valid(capture)
8322 # ping DS-Lite B4 tunnel endpoint address
8323 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
8324 IPv6(src=self.pg1.remote_hosts[0].ip6, dst=b4_ip6) /
8325 ICMPv6EchoRequest())
8326 self.pg1.add_stream(p)
8327 self.pg_enable_capture(self.pg_interfaces)
8329 capture = self.pg1.get_capture(1)
8330 capture = capture[0]
8331 self.assertEqual(capture[IPv6].src, b4_ip6)
8332 self.assertEqual(capture[IPv6].dst, self.pg1.remote_hosts[0].ip6)
8333 self.assertTrue(capture.haslayer(ICMPv6EchoReply))
8336 super(TestDSliteCE, self).tearDown()
8337 if not self.vpp_dead:
8339 self.vapi.cli("show dslite aftr-tunnel-endpoint-address"))
8341 self.vapi.cli("show dslite b4-tunnel-endpoint-address"))
8344 class TestNAT66(MethodHolder):
8345 """ NAT66 Test Cases """
8348 def setUpClass(cls):
8349 super(TestNAT66, cls).setUpClass()
8352 cls.nat_addr = 'fd01:ff::2'
8353 cls.nat_addr_n = socket.inet_pton(socket.AF_INET6, cls.nat_addr)
8355 cls.create_pg_interfaces(range(2))
8356 cls.interfaces = list(cls.pg_interfaces)
8358 for i in cls.interfaces:
8361 i.configure_ipv6_neighbors()
8364 super(TestNAT66, cls).tearDownClass()
8367 def test_static(self):
8368 """ 1:1 NAT66 test """
8369 self.vapi.nat66_add_del_interface(self.pg0.sw_if_index)
8370 self.vapi.nat66_add_del_interface(self.pg1.sw_if_index, is_inside=0)
8371 self.vapi.nat66_add_del_static_mapping(self.pg0.remote_ip6n,
8376 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
8377 IPv6(src=self.pg0.remote_ip6, dst=self.pg1.remote_ip6) /
8380 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
8381 IPv6(src=self.pg0.remote_ip6, dst=self.pg1.remote_ip6) /
8384 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
8385 IPv6(src=self.pg0.remote_ip6, dst=self.pg1.remote_ip6) /
8386 ICMPv6EchoRequest())
8388 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
8389 IPv6(src=self.pg0.remote_ip6, dst=self.pg1.remote_ip6) /
8390 GRE() / IP() / TCP())
8392 self.pg0.add_stream(pkts)
8393 self.pg_enable_capture(self.pg_interfaces)
8395 capture = self.pg1.get_capture(len(pkts))
8396 for packet in capture:
8398 self.assertEqual(packet[IPv6].src, self.nat_addr)
8399 self.assertEqual(packet[IPv6].dst, self.pg1.remote_ip6)
8400 self.assert_packet_checksums_valid(packet)
8402 self.logger.error(ppp("Unexpected or invalid packet:", packet))
8407 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
8408 IPv6(src=self.pg1.remote_ip6, dst=self.nat_addr) /
8411 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
8412 IPv6(src=self.pg1.remote_ip6, dst=self.nat_addr) /
8415 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
8416 IPv6(src=self.pg1.remote_ip6, dst=self.nat_addr) /
8419 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
8420 IPv6(src=self.pg1.remote_ip6, dst=self.nat_addr) /
8421 GRE() / IP() / TCP())
8423 self.pg1.add_stream(pkts)
8424 self.pg_enable_capture(self.pg_interfaces)
8426 capture = self.pg0.get_capture(len(pkts))
8427 for packet in capture:
8429 self.assertEqual(packet[IPv6].src, self.pg1.remote_ip6)
8430 self.assertEqual(packet[IPv6].dst, self.pg0.remote_ip6)
8431 self.assert_packet_checksums_valid(packet)
8433 self.logger.error(ppp("Unexpected or invalid packet:", packet))
8436 sm = self.vapi.nat66_static_mapping_dump()
8437 self.assertEqual(len(sm), 1)
8438 self.assertEqual(sm[0].total_pkts, 8)
8440 def test_check_no_translate(self):
8441 """ NAT66 translate only when egress interface is outside interface """
8442 self.vapi.nat66_add_del_interface(self.pg0.sw_if_index)
8443 self.vapi.nat66_add_del_interface(self.pg1.sw_if_index)
8444 self.vapi.nat66_add_del_static_mapping(self.pg0.remote_ip6n,
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) /
8451 self.pg0.add_stream([p])
8452 self.pg_enable_capture(self.pg_interfaces)
8454 capture = self.pg1.get_capture(1)
8457 self.assertEqual(packet[IPv6].src, self.pg0.remote_ip6)
8458 self.assertEqual(packet[IPv6].dst, self.pg1.remote_ip6)
8460 self.logger.error(ppp("Unexpected or invalid packet:", packet))
8463 def clear_nat66(self):
8465 Clear NAT66 configuration.
8467 interfaces = self.vapi.nat66_interface_dump()
8468 for intf in interfaces:
8469 self.vapi.nat66_add_del_interface(intf.sw_if_index,
8473 static_mappings = self.vapi.nat66_static_mapping_dump()
8474 for sm in static_mappings:
8475 self.vapi.nat66_add_del_static_mapping(sm.local_ip_address,
8476 sm.external_ip_address,
8481 super(TestNAT66, self).tearDown()
8482 if not self.vpp_dead:
8483 self.logger.info(self.vapi.cli("show nat66 interfaces"))
8484 self.logger.info(self.vapi.cli("show nat66 static mappings"))
8488 if __name__ == '__main__':
8489 unittest.main(testRunner=VppTestRunner)