8 from framework import VppTestCase, VppTestRunner, running_extended_tests
9 from scapy.layers.inet import IP, TCP, UDP, ICMP
10 from scapy.layers.inet import IPerror, TCPerror, UDPerror, ICMPerror
11 from scapy.layers.inet6 import IPv6, ICMPv6EchoRequest, ICMPv6EchoReply, \
12 ICMPv6ND_NS, ICMPv6ND_NA, ICMPv6NDOptDstLLAddr, fragment6
13 from scapy.layers.inet6 import ICMPv6DestUnreach, IPerror6, IPv6ExtHdrFragment
14 from scapy.layers.l2 import Ether, ARP, GRE
15 from scapy.data import IP_PROTOS
16 from scapy.packet import bind_layers, Raw
18 from ipfix import IPFIX, Set, Template, Data, IPFIXDecoder
19 from time import sleep
20 from util import ip4_range
21 from vpp_papi import mac_pton
22 from syslog_rfc5424_parser import SyslogMessage, ParseError
23 from syslog_rfc5424_parser.constants import SyslogFacility, SyslogSeverity
24 from vpp_papi_provider import SYSLOG_SEVERITY
25 from io import BytesIO
28 class MethodHolder(VppTestCase):
29 """ NAT create capture and verify method holder """
31 def clear_nat44(self):
33 Clear NAT44 configuration.
35 if hasattr(self, 'pg7') and hasattr(self, 'pg8'):
36 # I found no elegant way to do this
37 self.vapi.ip_add_del_route(
38 dst_address=self.pg7.remote_ip4n,
39 dst_address_length=32,
40 next_hop_address=self.pg7.remote_ip4n,
41 next_hop_sw_if_index=self.pg7.sw_if_index,
43 self.vapi.ip_add_del_route(
44 dst_address=self.pg8.remote_ip4n,
45 dst_address_length=32,
46 next_hop_address=self.pg8.remote_ip4n,
47 next_hop_sw_if_index=self.pg8.sw_if_index,
50 for intf in [self.pg7, self.pg8]:
51 neighbors = self.vapi.ip_neighbor_dump(intf.sw_if_index)
53 self.vapi.ip_neighbor_add_del(intf.sw_if_index,
58 if self.pg7.has_ip4_config:
59 self.pg7.unconfig_ip4()
61 self.vapi.nat44_forwarding_enable_disable(0)
63 interfaces = self.vapi.nat44_interface_addr_dump()
64 for intf in interfaces:
65 self.vapi.nat44_add_interface_addr(intf.sw_if_index,
66 twice_nat=intf.twice_nat,
69 self.vapi.nat_ipfix(enable=0, src_port=self.ipfix_src_port,
70 domain_id=self.ipfix_domain_id)
71 self.ipfix_src_port = 4739
72 self.ipfix_domain_id = 1
74 self.vapi.syslog_set_filter(SYSLOG_SEVERITY.EMERG)
76 interfaces = self.vapi.nat44_interface_dump()
77 for intf in interfaces:
78 if intf.is_inside > 1:
79 self.vapi.nat44_interface_add_del_feature(intf.sw_if_index,
82 self.vapi.nat44_interface_add_del_feature(intf.sw_if_index,
86 interfaces = self.vapi.nat44_interface_output_feature_dump()
87 for intf in interfaces:
88 self.vapi.nat44_interface_add_del_output_feature(intf.sw_if_index,
92 static_mappings = self.vapi.nat44_static_mapping_dump()
93 for sm in static_mappings:
94 self.vapi.nat44_add_del_static_mapping(
96 sm.external_ip_address,
97 local_port=sm.local_port,
98 external_port=sm.external_port,
99 addr_only=sm.addr_only,
101 protocol=sm.protocol,
102 twice_nat=sm.twice_nat,
103 self_twice_nat=sm.self_twice_nat,
104 out2in_only=sm.out2in_only,
106 external_sw_if_index=sm.external_sw_if_index,
109 lb_static_mappings = self.vapi.nat44_lb_static_mapping_dump()
110 for lb_sm in lb_static_mappings:
111 self.vapi.nat44_add_del_lb_static_mapping(
115 twice_nat=lb_sm.twice_nat,
116 self_twice_nat=lb_sm.self_twice_nat,
117 out2in_only=lb_sm.out2in_only,
123 identity_mappings = self.vapi.nat44_identity_mapping_dump()
124 for id_m in identity_mappings:
125 self.vapi.nat44_add_del_identity_mapping(
126 addr_only=id_m.addr_only,
129 sw_if_index=id_m.sw_if_index,
131 protocol=id_m.protocol,
134 adresses = self.vapi.nat44_address_dump()
135 for addr in adresses:
136 self.vapi.nat44_add_del_address_range(addr.ip_address,
138 twice_nat=addr.twice_nat,
141 self.vapi.nat_set_reass()
142 self.vapi.nat_set_reass(is_ip6=1)
143 self.verify_no_nat44_user()
144 self.vapi.nat_set_timeouts()
145 self.vapi.nat_set_addr_and_port_alloc_alg()
146 self.vapi.nat_set_mss_clamping()
148 def nat44_add_static_mapping(self, local_ip, external_ip='0.0.0.0',
149 local_port=0, external_port=0, vrf_id=0,
150 is_add=1, external_sw_if_index=0xFFFFFFFF,
151 proto=0, twice_nat=0, self_twice_nat=0,
152 out2in_only=0, tag=""):
154 Add/delete NAT44 static mapping
156 :param local_ip: Local IP address
157 :param external_ip: External IP address
158 :param local_port: Local port number (Optional)
159 :param external_port: External port number (Optional)
160 :param vrf_id: VRF ID (Default 0)
161 :param is_add: 1 if add, 0 if delete (Default add)
162 :param external_sw_if_index: External interface instead of IP address
163 :param proto: IP protocol (Mandatory if port specified)
164 :param twice_nat: 1 if translate external host address and port
165 :param self_twice_nat: 1 if translate external host address and port
166 whenever external host address equals
167 local address of internal host
168 :param out2in_only: if 1 rule is matching only out2in direction
169 :param tag: Opaque string tag
172 if local_port and external_port:
174 l_ip = socket.inet_pton(socket.AF_INET, local_ip)
175 e_ip = socket.inet_pton(socket.AF_INET, external_ip)
176 self.vapi.nat44_add_del_static_mapping(
179 external_sw_if_index,
191 def nat44_add_address(self, ip, is_add=1, vrf_id=0xFFFFFFFF, twice_nat=0):
193 Add/delete NAT44 address
195 :param ip: IP address
196 :param is_add: 1 if add, 0 if delete (Default add)
197 :param twice_nat: twice NAT address for extenal hosts
199 nat_addr = socket.inet_pton(socket.AF_INET, ip)
200 self.vapi.nat44_add_del_address_range(nat_addr, nat_addr, is_add,
204 def create_stream_in(self, in_if, out_if, dst_ip=None, ttl=64):
206 Create packet stream for inside network
208 :param in_if: Inside interface
209 :param out_if: Outside interface
210 :param dst_ip: Destination address
211 :param ttl: TTL of generated packets
214 dst_ip = out_if.remote_ip4
218 p = (Ether(dst=in_if.local_mac, src=in_if.remote_mac) /
219 IP(src=in_if.remote_ip4, dst=dst_ip, ttl=ttl) /
220 TCP(sport=self.tcp_port_in, dport=20))
224 p = (Ether(dst=in_if.local_mac, src=in_if.remote_mac) /
225 IP(src=in_if.remote_ip4, dst=dst_ip, ttl=ttl) /
226 UDP(sport=self.udp_port_in, dport=20))
230 p = (Ether(dst=in_if.local_mac, src=in_if.remote_mac) /
231 IP(src=in_if.remote_ip4, dst=dst_ip, ttl=ttl) /
232 ICMP(id=self.icmp_id_in, type='echo-request'))
237 def compose_ip6(self, ip4, pref, plen):
239 Compose IPv4-embedded IPv6 addresses
241 :param ip4: IPv4 address
242 :param pref: IPv6 prefix
243 :param plen: IPv6 prefix length
244 :returns: IPv4-embedded IPv6 addresses
246 pref_n = list(socket.inet_pton(socket.AF_INET6, pref))
247 ip4_n = list(socket.inet_pton(socket.AF_INET, ip4))
262 pref_n[10] = ip4_n[3]
266 pref_n[10] = ip4_n[2]
267 pref_n[11] = ip4_n[3]
270 pref_n[10] = ip4_n[1]
271 pref_n[11] = ip4_n[2]
272 pref_n[12] = ip4_n[3]
274 pref_n[12] = ip4_n[0]
275 pref_n[13] = ip4_n[1]
276 pref_n[14] = ip4_n[2]
277 pref_n[15] = ip4_n[3]
278 return socket.inet_ntop(socket.AF_INET6, ''.join(pref_n))
280 def extract_ip4(self, ip6, plen):
282 Extract IPv4 address embedded in IPv6 addresses
284 :param ip6: IPv6 address
285 :param plen: IPv6 prefix length
286 :returns: extracted IPv4 address
288 ip6_n = list(socket.inet_pton(socket.AF_INET6, ip6))
320 return socket.inet_ntop(socket.AF_INET, ''.join(ip4_n))
322 def create_stream_in_ip6(self, in_if, out_if, hlim=64, pref=None, plen=0):
324 Create IPv6 packet stream for inside network
326 :param in_if: Inside interface
327 :param out_if: Outside interface
328 :param ttl: Hop Limit of generated packets
329 :param pref: NAT64 prefix
330 :param plen: NAT64 prefix length
334 dst = ''.join(['64:ff9b::', out_if.remote_ip4])
336 dst = self.compose_ip6(out_if.remote_ip4, pref, plen)
339 p = (Ether(dst=in_if.local_mac, src=in_if.remote_mac) /
340 IPv6(src=in_if.remote_ip6, dst=dst, hlim=hlim) /
341 TCP(sport=self.tcp_port_in, dport=20))
345 p = (Ether(dst=in_if.local_mac, src=in_if.remote_mac) /
346 IPv6(src=in_if.remote_ip6, dst=dst, hlim=hlim) /
347 UDP(sport=self.udp_port_in, dport=20))
351 p = (Ether(dst=in_if.local_mac, src=in_if.remote_mac) /
352 IPv6(src=in_if.remote_ip6, dst=dst, hlim=hlim) /
353 ICMPv6EchoRequest(id=self.icmp_id_in))
358 def create_stream_out(self, out_if, dst_ip=None, ttl=64,
359 use_inside_ports=False):
361 Create packet stream for outside network
363 :param out_if: Outside interface
364 :param dst_ip: Destination IP address (Default use global NAT address)
365 :param ttl: TTL of generated packets
366 :param use_inside_ports: Use inside NAT ports as destination ports
367 instead of outside ports
370 dst_ip = self.nat_addr
371 if not use_inside_ports:
372 tcp_port = self.tcp_port_out
373 udp_port = self.udp_port_out
374 icmp_id = self.icmp_id_out
376 tcp_port = self.tcp_port_in
377 udp_port = self.udp_port_in
378 icmp_id = self.icmp_id_in
381 p = (Ether(dst=out_if.local_mac, src=out_if.remote_mac) /
382 IP(src=out_if.remote_ip4, dst=dst_ip, ttl=ttl) /
383 TCP(dport=tcp_port, sport=20))
387 p = (Ether(dst=out_if.local_mac, src=out_if.remote_mac) /
388 IP(src=out_if.remote_ip4, dst=dst_ip, ttl=ttl) /
389 UDP(dport=udp_port, sport=20))
393 p = (Ether(dst=out_if.local_mac, src=out_if.remote_mac) /
394 IP(src=out_if.remote_ip4, dst=dst_ip, ttl=ttl) /
395 ICMP(id=icmp_id, type='echo-reply'))
400 def create_stream_out_ip6(self, out_if, src_ip, dst_ip, hl=64):
402 Create packet stream for outside network
404 :param out_if: Outside interface
405 :param dst_ip: Destination IP address (Default use global NAT address)
406 :param hl: HL of generated packets
410 p = (Ether(dst=out_if.local_mac, src=out_if.remote_mac) /
411 IPv6(src=src_ip, dst=dst_ip, hlim=hl) /
412 TCP(dport=self.tcp_port_out, sport=20))
416 p = (Ether(dst=out_if.local_mac, src=out_if.remote_mac) /
417 IPv6(src=src_ip, dst=dst_ip, hlim=hl) /
418 UDP(dport=self.udp_port_out, sport=20))
422 p = (Ether(dst=out_if.local_mac, src=out_if.remote_mac) /
423 IPv6(src=src_ip, dst=dst_ip, hlim=hl) /
424 ICMPv6EchoReply(id=self.icmp_id_out))
429 def verify_capture_out(self, capture, nat_ip=None, same_port=False,
430 dst_ip=None, is_ip6=False):
432 Verify captured packets on outside network
434 :param capture: Captured packets
435 :param nat_ip: Translated IP address (Default use global NAT address)
436 :param same_port: Sorce port number is not translated (Default False)
437 :param dst_ip: Destination IP address (Default do not verify)
438 :param is_ip6: If L3 protocol is IPv6 (Default False)
442 ICMP46 = ICMPv6EchoRequest
447 nat_ip = self.nat_addr
448 for packet in capture:
451 self.assert_packet_checksums_valid(packet)
452 self.assertEqual(packet[IP46].src, nat_ip)
453 if dst_ip is not None:
454 self.assertEqual(packet[IP46].dst, dst_ip)
455 if packet.haslayer(TCP):
457 self.assertEqual(packet[TCP].sport, self.tcp_port_in)
460 packet[TCP].sport, self.tcp_port_in)
461 self.tcp_port_out = packet[TCP].sport
462 self.assert_packet_checksums_valid(packet)
463 elif packet.haslayer(UDP):
465 self.assertEqual(packet[UDP].sport, self.udp_port_in)
468 packet[UDP].sport, self.udp_port_in)
469 self.udp_port_out = packet[UDP].sport
472 self.assertEqual(packet[ICMP46].id, self.icmp_id_in)
474 self.assertNotEqual(packet[ICMP46].id, self.icmp_id_in)
475 self.icmp_id_out = packet[ICMP46].id
476 self.assert_packet_checksums_valid(packet)
478 self.logger.error(ppp("Unexpected or invalid packet "
479 "(outside network):", packet))
482 def verify_capture_out_ip6(self, capture, nat_ip, same_port=False,
485 Verify captured packets on outside network
487 :param capture: Captured packets
488 :param nat_ip: Translated IP address
489 :param same_port: Sorce port number is not translated (Default False)
490 :param dst_ip: Destination IP address (Default do not verify)
492 return self.verify_capture_out(capture, nat_ip, same_port, dst_ip,
495 def verify_capture_in(self, capture, in_if):
497 Verify captured packets on inside network
499 :param capture: Captured packets
500 :param in_if: Inside interface
502 for packet in capture:
504 self.assert_packet_checksums_valid(packet)
505 self.assertEqual(packet[IP].dst, in_if.remote_ip4)
506 if packet.haslayer(TCP):
507 self.assertEqual(packet[TCP].dport, self.tcp_port_in)
508 elif packet.haslayer(UDP):
509 self.assertEqual(packet[UDP].dport, self.udp_port_in)
511 self.assertEqual(packet[ICMP].id, self.icmp_id_in)
513 self.logger.error(ppp("Unexpected or invalid packet "
514 "(inside network):", packet))
517 def verify_capture_in_ip6(self, capture, src_ip, dst_ip):
519 Verify captured IPv6 packets on inside network
521 :param capture: Captured packets
522 :param src_ip: Source IP
523 :param dst_ip: Destination IP address
525 for packet in capture:
527 self.assertEqual(packet[IPv6].src, src_ip)
528 self.assertEqual(packet[IPv6].dst, dst_ip)
529 self.assert_packet_checksums_valid(packet)
530 if packet.haslayer(TCP):
531 self.assertEqual(packet[TCP].dport, self.tcp_port_in)
532 elif packet.haslayer(UDP):
533 self.assertEqual(packet[UDP].dport, self.udp_port_in)
535 self.assertEqual(packet[ICMPv6EchoReply].id,
538 self.logger.error(ppp("Unexpected or invalid packet "
539 "(inside network):", packet))
542 def verify_capture_no_translation(self, capture, ingress_if, egress_if):
544 Verify captured packet that don't have to be translated
546 :param capture: Captured packets
547 :param ingress_if: Ingress interface
548 :param egress_if: Egress interface
550 for packet in capture:
552 self.assertEqual(packet[IP].src, ingress_if.remote_ip4)
553 self.assertEqual(packet[IP].dst, egress_if.remote_ip4)
554 if packet.haslayer(TCP):
555 self.assertEqual(packet[TCP].sport, self.tcp_port_in)
556 elif packet.haslayer(UDP):
557 self.assertEqual(packet[UDP].sport, self.udp_port_in)
559 self.assertEqual(packet[ICMP].id, self.icmp_id_in)
561 self.logger.error(ppp("Unexpected or invalid packet "
562 "(inside network):", packet))
565 def verify_capture_out_with_icmp_errors(self, capture, src_ip=None,
568 Verify captured packets with ICMP errors on outside network
570 :param capture: Captured packets
571 :param src_ip: Translated IP address or IP address of VPP
572 (Default use global NAT address)
573 :param icmp_type: Type of error ICMP packet
574 we are expecting (Default 11)
577 src_ip = self.nat_addr
578 for packet in capture:
580 self.assertEqual(packet[IP].src, src_ip)
581 self.assertEqual(packet.haslayer(ICMP), 1)
583 self.assertEqual(icmp.type, icmp_type)
584 self.assertTrue(icmp.haslayer(IPerror))
585 inner_ip = icmp[IPerror]
586 if inner_ip.haslayer(TCPerror):
587 self.assertEqual(inner_ip[TCPerror].dport,
589 elif inner_ip.haslayer(UDPerror):
590 self.assertEqual(inner_ip[UDPerror].dport,
593 self.assertEqual(inner_ip[ICMPerror].id, self.icmp_id_out)
595 self.logger.error(ppp("Unexpected or invalid packet "
596 "(outside network):", packet))
599 def verify_capture_in_with_icmp_errors(self, capture, in_if, icmp_type=11):
601 Verify captured packets with ICMP errors on inside network
603 :param capture: Captured packets
604 :param in_if: Inside interface
605 :param icmp_type: Type of error ICMP packet
606 we are expecting (Default 11)
608 for packet in capture:
610 self.assertEqual(packet[IP].dst, in_if.remote_ip4)
611 self.assertEqual(packet.haslayer(ICMP), 1)
613 self.assertEqual(icmp.type, icmp_type)
614 self.assertTrue(icmp.haslayer(IPerror))
615 inner_ip = icmp[IPerror]
616 if inner_ip.haslayer(TCPerror):
617 self.assertEqual(inner_ip[TCPerror].sport,
619 elif inner_ip.haslayer(UDPerror):
620 self.assertEqual(inner_ip[UDPerror].sport,
623 self.assertEqual(inner_ip[ICMPerror].id, self.icmp_id_in)
625 self.logger.error(ppp("Unexpected or invalid packet "
626 "(inside network):", packet))
629 def create_stream_frag(self, src_if, dst, sport, dport, data,
630 proto=IP_PROTOS.tcp, echo_reply=False):
632 Create fragmented packet stream
634 :param src_if: Source interface
635 :param dst: Destination IPv4 address
636 :param sport: Source port
637 :param dport: Destination port
638 :param data: Payload data
639 :param proto: protocol (TCP, UDP, ICMP)
640 :param echo_reply: use echo_reply if protocol is ICMP
643 if proto == IP_PROTOS.tcp:
644 p = (IP(src=src_if.remote_ip4, dst=dst) /
645 TCP(sport=sport, dport=dport) /
647 p = p.__class__(str(p))
648 chksum = p['TCP'].chksum
649 proto_header = TCP(sport=sport, dport=dport, chksum=chksum)
650 elif proto == IP_PROTOS.udp:
651 proto_header = UDP(sport=sport, dport=dport)
652 elif proto == IP_PROTOS.icmp:
654 proto_header = ICMP(id=sport, type='echo-request')
656 proto_header = ICMP(id=sport, type='echo-reply')
658 raise Exception("Unsupported protocol")
659 id = random.randint(0, 65535)
661 if proto == IP_PROTOS.tcp:
664 raw = Raw(data[0:16])
665 p = (Ether(src=src_if.remote_mac, dst=src_if.local_mac) /
666 IP(src=src_if.remote_ip4, dst=dst, flags="MF", frag=0, id=id) /
670 if proto == IP_PROTOS.tcp:
671 raw = Raw(data[4:20])
673 raw = Raw(data[16:32])
674 p = (Ether(src=src_if.remote_mac, dst=src_if.local_mac) /
675 IP(src=src_if.remote_ip4, dst=dst, flags="MF", frag=3, id=id,
679 if proto == IP_PROTOS.tcp:
683 p = (Ether(src=src_if.remote_mac, dst=src_if.local_mac) /
684 IP(src=src_if.remote_ip4, dst=dst, frag=5, proto=proto,
690 def create_stream_frag_ip6(self, src_if, dst, sport, dport, data,
691 pref=None, plen=0, frag_size=128):
693 Create fragmented packet stream
695 :param src_if: Source interface
696 :param dst: Destination IPv4 address
697 :param sport: Source TCP port
698 :param dport: Destination TCP port
699 :param data: Payload data
700 :param pref: NAT64 prefix
701 :param plen: NAT64 prefix length
702 :param fragsize: size of fragments
706 dst_ip6 = ''.join(['64:ff9b::', dst])
708 dst_ip6 = self.compose_ip6(dst, pref, plen)
710 p = (Ether(dst=src_if.local_mac, src=src_if.remote_mac) /
711 IPv6(src=src_if.remote_ip6, dst=dst_ip6) /
712 IPv6ExtHdrFragment(id=random.randint(0, 65535)) /
713 TCP(sport=sport, dport=dport) /
716 return fragment6(p, frag_size)
718 def reass_frags_and_verify(self, frags, src, dst):
720 Reassemble and verify fragmented packet
722 :param frags: Captured fragments
723 :param src: Source IPv4 address to verify
724 :param dst: Destination IPv4 address to verify
726 :returns: Reassembled IPv4 packet
730 self.assertEqual(p[IP].src, src)
731 self.assertEqual(p[IP].dst, dst)
732 self.assert_ip_checksum_valid(p)
733 buffer.seek(p[IP].frag * 8)
734 buffer.write(bytes(p[IP].payload))
735 ip = IP(src=frags[0][IP].src, dst=frags[0][IP].dst,
736 proto=frags[0][IP].proto)
737 if ip.proto == IP_PROTOS.tcp:
738 p = (ip / TCP(buffer.getvalue()))
739 self.assert_tcp_checksum_valid(p)
740 elif ip.proto == IP_PROTOS.udp:
741 p = (ip / UDP(buffer.getvalue()[:8]) /
742 Raw(buffer.getvalue()[8:]))
743 elif ip.proto == IP_PROTOS.icmp:
744 p = (ip / ICMP(buffer.getvalue()))
747 def reass_frags_and_verify_ip6(self, frags, src, dst):
749 Reassemble and verify fragmented packet
751 :param frags: Captured fragments
752 :param src: Source IPv6 address to verify
753 :param dst: Destination IPv6 address to verify
755 :returns: Reassembled IPv6 packet
759 self.assertEqual(p[IPv6].src, src)
760 self.assertEqual(p[IPv6].dst, dst)
761 buffer.seek(p[IPv6ExtHdrFragment].offset * 8)
762 buffer.write(bytes(p[IPv6ExtHdrFragment].payload))
763 ip = IPv6(src=frags[0][IPv6].src, dst=frags[0][IPv6].dst,
764 nh=frags[0][IPv6ExtHdrFragment].nh)
765 if ip.nh == IP_PROTOS.tcp:
766 p = (ip / TCP(buffer.getvalue()))
767 elif ip.nh == IP_PROTOS.udp:
768 p = (ip / UDP(buffer.getvalue()))
769 self.assert_packet_checksums_valid(p)
772 def initiate_tcp_session(self, in_if, out_if):
774 Initiates TCP session
776 :param in_if: Inside interface
777 :param out_if: Outside interface
781 p = (Ether(src=in_if.remote_mac, dst=in_if.local_mac) /
782 IP(src=in_if.remote_ip4, dst=out_if.remote_ip4) /
783 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
786 self.pg_enable_capture(self.pg_interfaces)
788 capture = out_if.get_capture(1)
790 self.tcp_port_out = p[TCP].sport
792 # SYN + ACK packet out->in
793 p = (Ether(src=out_if.remote_mac, dst=out_if.local_mac) /
794 IP(src=out_if.remote_ip4, dst=self.nat_addr) /
795 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
798 self.pg_enable_capture(self.pg_interfaces)
803 p = (Ether(src=in_if.remote_mac, dst=in_if.local_mac) /
804 IP(src=in_if.remote_ip4, dst=out_if.remote_ip4) /
805 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
808 self.pg_enable_capture(self.pg_interfaces)
810 out_if.get_capture(1)
813 self.logger.error("TCP 3 way handshake failed")
816 def verify_ipfix_nat44_ses(self, data):
818 Verify IPFIX NAT44 session create/delete event
820 :param data: Decoded IPFIX data records
822 nat44_ses_create_num = 0
823 nat44_ses_delete_num = 0
824 self.assertEqual(6, len(data))
827 self.assertIn(ord(record[230]), [4, 5])
828 if ord(record[230]) == 4:
829 nat44_ses_create_num += 1
831 nat44_ses_delete_num += 1
833 self.assertEqual(self.pg0.remote_ip4n, record[8])
834 # postNATSourceIPv4Address
835 self.assertEqual(socket.inet_pton(socket.AF_INET, self.nat_addr),
838 self.assertEqual(struct.pack("!I", 0), record[234])
839 # protocolIdentifier/sourceTransportPort/postNAPTSourceTransportPort
840 if IP_PROTOS.icmp == ord(record[4]):
841 self.assertEqual(struct.pack("!H", self.icmp_id_in), record[7])
842 self.assertEqual(struct.pack("!H", self.icmp_id_out),
844 elif IP_PROTOS.tcp == ord(record[4]):
845 self.assertEqual(struct.pack("!H", self.tcp_port_in),
847 self.assertEqual(struct.pack("!H", self.tcp_port_out),
849 elif IP_PROTOS.udp == ord(record[4]):
850 self.assertEqual(struct.pack("!H", self.udp_port_in),
852 self.assertEqual(struct.pack("!H", self.udp_port_out),
855 self.fail("Invalid protocol")
856 self.assertEqual(3, nat44_ses_create_num)
857 self.assertEqual(3, nat44_ses_delete_num)
859 def verify_ipfix_addr_exhausted(self, data):
861 Verify IPFIX NAT addresses event
863 :param data: Decoded IPFIX data records
865 self.assertEqual(1, len(data))
868 self.assertEqual(ord(record[230]), 3)
870 self.assertEqual(struct.pack("!I", 0), record[283])
872 def verify_ipfix_max_sessions(self, data, limit):
874 Verify IPFIX maximum session entries exceeded event
876 :param data: Decoded IPFIX data records
877 :param limit: Number of maximum session entries that can be created.
879 self.assertEqual(1, len(data))
882 self.assertEqual(ord(record[230]), 13)
883 # natQuotaExceededEvent
884 self.assertEqual(struct.pack("I", 1), record[466])
886 self.assertEqual(struct.pack("I", limit), record[471])
888 def verify_ipfix_max_bibs(self, data, limit):
890 Verify IPFIX maximum BIB entries exceeded event
892 :param data: Decoded IPFIX data records
893 :param limit: Number of maximum BIB entries that can be created.
895 self.assertEqual(1, len(data))
898 self.assertEqual(ord(record[230]), 13)
899 # natQuotaExceededEvent
900 self.assertEqual(struct.pack("I", 2), record[466])
902 self.assertEqual(struct.pack("I", limit), record[472])
904 def verify_ipfix_max_fragments_ip6(self, data, limit, src_addr):
906 Verify IPFIX maximum IPv6 fragments pending reassembly exceeded event
908 :param data: Decoded IPFIX data records
909 :param limit: Number of maximum fragments pending reassembly
910 :param src_addr: IPv6 source address
912 self.assertEqual(1, len(data))
915 self.assertEqual(ord(record[230]), 13)
916 # natQuotaExceededEvent
917 self.assertEqual(struct.pack("I", 5), record[466])
918 # maxFragmentsPendingReassembly
919 self.assertEqual(struct.pack("I", limit), record[475])
921 self.assertEqual(src_addr, record[27])
923 def verify_ipfix_max_fragments_ip4(self, data, limit, src_addr):
925 Verify IPFIX maximum IPv4 fragments pending reassembly exceeded event
927 :param data: Decoded IPFIX data records
928 :param limit: Number of maximum fragments pending reassembly
929 :param src_addr: IPv4 source address
931 self.assertEqual(1, len(data))
934 self.assertEqual(ord(record[230]), 13)
935 # natQuotaExceededEvent
936 self.assertEqual(struct.pack("I", 5), record[466])
937 # maxFragmentsPendingReassembly
938 self.assertEqual(struct.pack("I", limit), record[475])
940 self.assertEqual(src_addr, record[8])
942 def verify_ipfix_bib(self, data, is_create, src_addr):
944 Verify IPFIX NAT64 BIB create and delete events
946 :param data: Decoded IPFIX data records
947 :param is_create: Create event if nonzero value otherwise delete event
948 :param src_addr: IPv6 source address
950 self.assertEqual(1, len(data))
954 self.assertEqual(ord(record[230]), 10)
956 self.assertEqual(ord(record[230]), 11)
958 self.assertEqual(src_addr, record[27])
959 # postNATSourceIPv4Address
960 self.assertEqual(self.nat_addr_n, record[225])
962 self.assertEqual(IP_PROTOS.tcp, ord(record[4]))
964 self.assertEqual(struct.pack("!I", 0), record[234])
965 # sourceTransportPort
966 self.assertEqual(struct.pack("!H", self.tcp_port_in), record[7])
967 # postNAPTSourceTransportPort
968 self.assertEqual(struct.pack("!H", self.tcp_port_out), record[227])
970 def verify_ipfix_nat64_ses(self, data, is_create, src_addr, dst_addr,
973 Verify IPFIX NAT64 session create and delete events
975 :param data: Decoded IPFIX data records
976 :param is_create: Create event if nonzero value otherwise delete event
977 :param src_addr: IPv6 source address
978 :param dst_addr: IPv4 destination address
979 :param dst_port: destination TCP port
981 self.assertEqual(1, len(data))
985 self.assertEqual(ord(record[230]), 6)
987 self.assertEqual(ord(record[230]), 7)
989 self.assertEqual(src_addr, record[27])
990 # destinationIPv6Address
991 self.assertEqual(socket.inet_pton(socket.AF_INET6,
992 self.compose_ip6(dst_addr,
996 # postNATSourceIPv4Address
997 self.assertEqual(self.nat_addr_n, record[225])
998 # postNATDestinationIPv4Address
999 self.assertEqual(socket.inet_pton(socket.AF_INET, dst_addr),
1001 # protocolIdentifier
1002 self.assertEqual(IP_PROTOS.tcp, ord(record[4]))
1004 self.assertEqual(struct.pack("!I", 0), record[234])
1005 # sourceTransportPort
1006 self.assertEqual(struct.pack("!H", self.tcp_port_in), record[7])
1007 # postNAPTSourceTransportPort
1008 self.assertEqual(struct.pack("!H", self.tcp_port_out), record[227])
1009 # destinationTransportPort
1010 self.assertEqual(struct.pack("!H", dst_port), record[11])
1011 # postNAPTDestinationTransportPort
1012 self.assertEqual(struct.pack("!H", dst_port), record[228])
1014 def verify_no_nat44_user(self):
1015 """ Verify that there is no NAT44 user """
1016 users = self.vapi.nat44_user_dump()
1017 self.assertEqual(len(users), 0)
1018 users = self.statistics.get_counter('/nat44/total-users')
1019 self.assertEqual(users[0][0], 0)
1020 sessions = self.statistics.get_counter('/nat44/total-sessions')
1021 self.assertEqual(sessions[0][0], 0)
1023 def verify_ipfix_max_entries_per_user(self, data, limit, src_addr):
1025 Verify IPFIX maximum entries per user exceeded event
1027 :param data: Decoded IPFIX data records
1028 :param limit: Number of maximum entries per user
1029 :param src_addr: IPv4 source address
1031 self.assertEqual(1, len(data))
1034 self.assertEqual(ord(record[230]), 13)
1035 # natQuotaExceededEvent
1036 self.assertEqual(struct.pack("I", 3), record[466])
1038 self.assertEqual(struct.pack("I", limit), record[473])
1040 self.assertEqual(src_addr, record[8])
1042 def verify_syslog_apmap(self, data, is_add=True):
1043 message = data.decode('utf-8')
1045 message = SyslogMessage.parse(message)
1046 self.assertEqual(message.severity, SyslogSeverity.info)
1047 self.assertEqual(message.appname, 'NAT')
1048 self.assertEqual(message.msgid, 'APMADD' if is_add else 'APMDEL')
1049 sd_params = message.sd.get('napmap')
1050 self.assertTrue(sd_params is not None)
1051 self.assertEqual(sd_params.get('IATYP'), 'IPv4')
1052 self.assertEqual(sd_params.get('ISADDR'), self.pg0.remote_ip4)
1053 self.assertEqual(sd_params.get('ISPORT'), "%d" % self.tcp_port_in)
1054 self.assertEqual(sd_params.get('XATYP'), 'IPv4')
1055 self.assertEqual(sd_params.get('XSADDR'), self.nat_addr)
1056 self.assertEqual(sd_params.get('XSPORT'), "%d" % self.tcp_port_out)
1057 self.assertEqual(sd_params.get('PROTO'), "%d" % IP_PROTOS.tcp)
1058 self.assertTrue(sd_params.get('SSUBIX') is not None)
1059 self.assertEqual(sd_params.get('SVLAN'), '0')
1060 except ParseError as e:
1061 self.logger.error(e)
1063 def verify_syslog_sess(self, data, is_add=True, is_ip6=False):
1064 message = data.decode('utf-8')
1066 message = SyslogMessage.parse(message)
1067 self.assertEqual(message.severity, SyslogSeverity.info)
1068 self.assertEqual(message.appname, 'NAT')
1069 self.assertEqual(message.msgid, 'SADD' if is_add else 'SDEL')
1070 sd_params = message.sd.get('nsess')
1071 self.assertTrue(sd_params is not None)
1073 self.assertEqual(sd_params.get('IATYP'), 'IPv6')
1074 self.assertEqual(sd_params.get('ISADDR'), self.pg0.remote_ip6)
1076 self.assertEqual(sd_params.get('IATYP'), 'IPv4')
1077 self.assertEqual(sd_params.get('ISADDR'), self.pg0.remote_ip4)
1078 self.assertTrue(sd_params.get('SSUBIX') is not None)
1079 self.assertEqual(sd_params.get('ISPORT'), "%d" % self.tcp_port_in)
1080 self.assertEqual(sd_params.get('XATYP'), 'IPv4')
1081 self.assertEqual(sd_params.get('XSADDR'), self.nat_addr)
1082 self.assertEqual(sd_params.get('XSPORT'), "%d" % self.tcp_port_out)
1083 self.assertEqual(sd_params.get('PROTO'), "%d" % IP_PROTOS.tcp)
1084 self.assertEqual(sd_params.get('SVLAN'), '0')
1085 self.assertEqual(sd_params.get('XDADDR'), self.pg1.remote_ip4)
1086 self.assertEqual(sd_params.get('XDPORT'),
1087 "%d" % self.tcp_external_port)
1088 except ParseError as e:
1089 self.logger.error(e)
1091 def verify_mss_value(self, pkt, mss):
1093 Verify TCP MSS value
1098 if not pkt.haslayer(IP) or not pkt.haslayer(TCP):
1099 raise TypeError("Not a TCP/IP packet")
1101 for option in pkt[TCP].options:
1102 if option[0] == 'MSS':
1103 self.assertEqual(option[1], mss)
1104 self.assert_tcp_checksum_valid(pkt)
1107 def proto2layer(proto):
1108 if proto == IP_PROTOS.tcp:
1110 elif proto == IP_PROTOS.udp:
1112 elif proto == IP_PROTOS.icmp:
1115 raise Exception("Unsupported protocol")
1117 def frag_in_order(self, proto=IP_PROTOS.tcp, dont_translate=False):
1118 layer = self.proto2layer(proto)
1120 if proto == IP_PROTOS.tcp:
1121 data = "A" * 4 + "B" * 16 + "C" * 3
1123 data = "A" * 16 + "B" * 16 + "C" * 3
1124 self.port_in = random.randint(1025, 65535)
1126 reass = self.vapi.nat_reass_dump()
1127 reass_n_start = len(reass)
1130 pkts = self.create_stream_frag(self.pg0,
1131 self.pg1.remote_ip4,
1136 self.pg0.add_stream(pkts)
1137 self.pg_enable_capture(self.pg_interfaces)
1139 frags = self.pg1.get_capture(len(pkts))
1140 if not dont_translate:
1141 p = self.reass_frags_and_verify(frags,
1143 self.pg1.remote_ip4)
1145 p = self.reass_frags_and_verify(frags,
1146 self.pg0.remote_ip4,
1147 self.pg1.remote_ip4)
1148 if proto != IP_PROTOS.icmp:
1149 if not dont_translate:
1150 self.assertEqual(p[layer].dport, 20)
1151 self.assertNotEqual(p[layer].sport, self.port_in)
1153 self.assertEqual(p[layer].sport, self.port_in)
1155 if not dont_translate:
1156 self.assertNotEqual(p[layer].id, self.port_in)
1158 self.assertEqual(p[layer].id, self.port_in)
1159 self.assertEqual(data, p[Raw].load)
1162 if not dont_translate:
1163 dst_addr = self.nat_addr
1165 dst_addr = self.pg0.remote_ip4
1166 if proto != IP_PROTOS.icmp:
1168 dport = p[layer].sport
1172 pkts = self.create_stream_frag(self.pg1,
1179 self.pg1.add_stream(pkts)
1180 self.pg_enable_capture(self.pg_interfaces)
1182 frags = self.pg0.get_capture(len(pkts))
1183 p = self.reass_frags_and_verify(frags,
1184 self.pg1.remote_ip4,
1185 self.pg0.remote_ip4)
1186 if proto != IP_PROTOS.icmp:
1187 self.assertEqual(p[layer].sport, 20)
1188 self.assertEqual(p[layer].dport, self.port_in)
1190 self.assertEqual(p[layer].id, self.port_in)
1191 self.assertEqual(data, p[Raw].load)
1193 reass = self.vapi.nat_reass_dump()
1194 reass_n_end = len(reass)
1196 self.assertEqual(reass_n_end - reass_n_start, 2)
1198 def frag_in_order_in_plus_out(self, proto=IP_PROTOS.tcp):
1199 layer = self.proto2layer(proto)
1201 if proto == IP_PROTOS.tcp:
1202 data = "A" * 4 + "B" * 16 + "C" * 3
1204 data = "A" * 16 + "B" * 16 + "C" * 3
1205 self.port_in = random.randint(1025, 65535)
1208 reass = self.vapi.nat_reass_dump()
1209 reass_n_start = len(reass)
1212 pkts = self.create_stream_frag(self.pg0,
1213 self.server_out_addr,
1215 self.server_out_port,
1218 self.pg0.add_stream(pkts)
1219 self.pg_enable_capture(self.pg_interfaces)
1221 frags = self.pg1.get_capture(len(pkts))
1222 p = self.reass_frags_and_verify(frags,
1223 self.pg0.remote_ip4,
1224 self.server_in_addr)
1225 if proto != IP_PROTOS.icmp:
1226 self.assertEqual(p[layer].sport, self.port_in)
1227 self.assertEqual(p[layer].dport, self.server_in_port)
1229 self.assertEqual(p[layer].id, self.port_in)
1230 self.assertEqual(data, p[Raw].load)
1233 if proto != IP_PROTOS.icmp:
1234 pkts = self.create_stream_frag(self.pg1,
1235 self.pg0.remote_ip4,
1236 self.server_in_port,
1241 pkts = self.create_stream_frag(self.pg1,
1242 self.pg0.remote_ip4,
1248 self.pg1.add_stream(pkts)
1249 self.pg_enable_capture(self.pg_interfaces)
1251 frags = self.pg0.get_capture(len(pkts))
1252 p = self.reass_frags_and_verify(frags,
1253 self.server_out_addr,
1254 self.pg0.remote_ip4)
1255 if proto != IP_PROTOS.icmp:
1256 self.assertEqual(p[layer].sport, self.server_out_port)
1257 self.assertEqual(p[layer].dport, self.port_in)
1259 self.assertEqual(p[layer].id, self.port_in)
1260 self.assertEqual(data, p[Raw].load)
1262 reass = self.vapi.nat_reass_dump()
1263 reass_n_end = len(reass)
1265 self.assertEqual(reass_n_end - reass_n_start, 2)
1267 def reass_hairpinning(self, proto=IP_PROTOS.tcp):
1268 layer = self.proto2layer(proto)
1270 if proto == IP_PROTOS.tcp:
1271 data = "A" * 4 + "B" * 16 + "C" * 3
1273 data = "A" * 16 + "B" * 16 + "C" * 3
1275 # send packet from host to server
1276 pkts = self.create_stream_frag(self.pg0,
1279 self.server_out_port,
1282 self.pg0.add_stream(pkts)
1283 self.pg_enable_capture(self.pg_interfaces)
1285 frags = self.pg0.get_capture(len(pkts))
1286 p = self.reass_frags_and_verify(frags,
1289 if proto != IP_PROTOS.icmp:
1290 self.assertNotEqual(p[layer].sport, self.host_in_port)
1291 self.assertEqual(p[layer].dport, self.server_in_port)
1293 self.assertNotEqual(p[layer].id, self.host_in_port)
1294 self.assertEqual(data, p[Raw].load)
1296 def frag_out_of_order(self, proto=IP_PROTOS.tcp, dont_translate=False):
1297 layer = self.proto2layer(proto)
1299 if proto == IP_PROTOS.tcp:
1300 data = "A" * 4 + "B" * 16 + "C" * 3
1302 data = "A" * 16 + "B" * 16 + "C" * 3
1303 self.port_in = random.randint(1025, 65535)
1307 pkts = self.create_stream_frag(self.pg0,
1308 self.pg1.remote_ip4,
1314 self.pg0.add_stream(pkts)
1315 self.pg_enable_capture(self.pg_interfaces)
1317 frags = self.pg1.get_capture(len(pkts))
1318 if not dont_translate:
1319 p = self.reass_frags_and_verify(frags,
1321 self.pg1.remote_ip4)
1323 p = self.reass_frags_and_verify(frags,
1324 self.pg0.remote_ip4,
1325 self.pg1.remote_ip4)
1326 if proto != IP_PROTOS.icmp:
1327 if not dont_translate:
1328 self.assertEqual(p[layer].dport, 20)
1329 self.assertNotEqual(p[layer].sport, self.port_in)
1331 self.assertEqual(p[layer].sport, self.port_in)
1333 if not dont_translate:
1334 self.assertNotEqual(p[layer].id, self.port_in)
1336 self.assertEqual(p[layer].id, self.port_in)
1337 self.assertEqual(data, p[Raw].load)
1340 if not dont_translate:
1341 dst_addr = self.nat_addr
1343 dst_addr = self.pg0.remote_ip4
1344 if proto != IP_PROTOS.icmp:
1346 dport = p[layer].sport
1350 pkts = self.create_stream_frag(self.pg1,
1358 self.pg1.add_stream(pkts)
1359 self.pg_enable_capture(self.pg_interfaces)
1361 frags = self.pg0.get_capture(len(pkts))
1362 p = self.reass_frags_and_verify(frags,
1363 self.pg1.remote_ip4,
1364 self.pg0.remote_ip4)
1365 if proto != IP_PROTOS.icmp:
1366 self.assertEqual(p[layer].sport, 20)
1367 self.assertEqual(p[layer].dport, self.port_in)
1369 self.assertEqual(p[layer].id, self.port_in)
1370 self.assertEqual(data, p[Raw].load)
1372 def frag_out_of_order_in_plus_out(self, proto=IP_PROTOS.tcp):
1373 layer = self.proto2layer(proto)
1375 if proto == IP_PROTOS.tcp:
1376 data = "A" * 4 + "B" * 16 + "C" * 3
1378 data = "A" * 16 + "B" * 16 + "C" * 3
1379 self.port_in = random.randint(1025, 65535)
1383 pkts = self.create_stream_frag(self.pg0,
1384 self.server_out_addr,
1386 self.server_out_port,
1390 self.pg0.add_stream(pkts)
1391 self.pg_enable_capture(self.pg_interfaces)
1393 frags = self.pg1.get_capture(len(pkts))
1394 p = self.reass_frags_and_verify(frags,
1395 self.pg0.remote_ip4,
1396 self.server_in_addr)
1397 if proto != IP_PROTOS.icmp:
1398 self.assertEqual(p[layer].dport, self.server_in_port)
1399 self.assertEqual(p[layer].sport, self.port_in)
1400 self.assertEqual(p[layer].dport, self.server_in_port)
1402 self.assertEqual(p[layer].id, self.port_in)
1403 self.assertEqual(data, p[Raw].load)
1406 if proto != IP_PROTOS.icmp:
1407 pkts = self.create_stream_frag(self.pg1,
1408 self.pg0.remote_ip4,
1409 self.server_in_port,
1414 pkts = self.create_stream_frag(self.pg1,
1415 self.pg0.remote_ip4,
1422 self.pg1.add_stream(pkts)
1423 self.pg_enable_capture(self.pg_interfaces)
1425 frags = self.pg0.get_capture(len(pkts))
1426 p = self.reass_frags_and_verify(frags,
1427 self.server_out_addr,
1428 self.pg0.remote_ip4)
1429 if proto != IP_PROTOS.icmp:
1430 self.assertEqual(p[layer].sport, self.server_out_port)
1431 self.assertEqual(p[layer].dport, self.port_in)
1433 self.assertEqual(p[layer].id, self.port_in)
1434 self.assertEqual(data, p[Raw].load)
1437 class TestNAT44(MethodHolder):
1438 """ NAT44 Test Cases """
1441 def setUpClass(cls):
1442 super(TestNAT44, cls).setUpClass()
1443 cls.vapi.cli("set log class nat level debug")
1446 cls.tcp_port_in = 6303
1447 cls.tcp_port_out = 6303
1448 cls.udp_port_in = 6304
1449 cls.udp_port_out = 6304
1450 cls.icmp_id_in = 6305
1451 cls.icmp_id_out = 6305
1452 cls.nat_addr = '10.0.0.3'
1453 cls.nat_addr_n = socket.inet_pton(socket.AF_INET, cls.nat_addr)
1454 cls.ipfix_src_port = 4739
1455 cls.ipfix_domain_id = 1
1456 cls.tcp_external_port = 80
1458 cls.create_pg_interfaces(range(10))
1459 cls.interfaces = list(cls.pg_interfaces[0:4])
1461 for i in cls.interfaces:
1466 cls.pg0.generate_remote_hosts(3)
1467 cls.pg0.configure_ipv4_neighbors()
1469 cls.pg1.generate_remote_hosts(1)
1470 cls.pg1.configure_ipv4_neighbors()
1472 cls.overlapping_interfaces = list(list(cls.pg_interfaces[4:7]))
1473 cls.vapi.ip_table_add_del(10, is_add=1)
1474 cls.vapi.ip_table_add_del(20, is_add=1)
1476 cls.pg4._local_ip4 = "172.16.255.1"
1477 cls.pg4._local_ip4n = socket.inet_pton(socket.AF_INET, i.local_ip4)
1478 cls.pg4._remote_hosts[0]._ip4 = "172.16.255.2"
1479 cls.pg4.set_table_ip4(10)
1480 cls.pg5._local_ip4 = "172.17.255.3"
1481 cls.pg5._local_ip4n = socket.inet_pton(socket.AF_INET, i.local_ip4)
1482 cls.pg5._remote_hosts[0]._ip4 = "172.17.255.4"
1483 cls.pg5.set_table_ip4(10)
1484 cls.pg6._local_ip4 = "172.16.255.1"
1485 cls.pg6._local_ip4n = socket.inet_pton(socket.AF_INET, i.local_ip4)
1486 cls.pg6._remote_hosts[0]._ip4 = "172.16.255.2"
1487 cls.pg6.set_table_ip4(20)
1488 for i in cls.overlapping_interfaces:
1496 cls.pg9.generate_remote_hosts(2)
1497 cls.pg9.config_ip4()
1498 ip_addr_n = socket.inet_pton(socket.AF_INET, "10.0.0.1")
1499 cls.vapi.sw_interface_add_del_address(cls.pg9.sw_if_index,
1503 cls.pg9.resolve_arp()
1504 cls.pg9._remote_hosts[1]._ip4 = cls.pg9._remote_hosts[0]._ip4
1505 cls.pg4._remote_ip4 = cls.pg9._remote_hosts[0]._ip4 = "10.0.0.2"
1506 cls.pg9.resolve_arp()
1509 super(TestNAT44, cls).tearDownClass()
1512 def test_dynamic(self):
1513 """ NAT44 dynamic translation test """
1514 self.nat44_add_address(self.nat_addr)
1515 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
1516 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
1520 tcpn = self.statistics.get_counter(
1521 '/err/nat44-in2out-slowpath/TCP packets')
1522 udpn = self.statistics.get_counter(
1523 '/err/nat44-in2out-slowpath/UDP packets')
1524 icmpn = self.statistics.get_counter(
1525 '/err/nat44-in2out-slowpath/ICMP packets')
1526 totaln = self.statistics.get_counter(
1527 '/err/nat44-in2out-slowpath/good in2out packets processed')
1529 pkts = self.create_stream_in(self.pg0, self.pg1)
1530 self.pg0.add_stream(pkts)
1531 self.pg_enable_capture(self.pg_interfaces)
1533 capture = self.pg1.get_capture(len(pkts))
1534 self.verify_capture_out(capture)
1536 err = self.statistics.get_counter(
1537 '/err/nat44-in2out-slowpath/TCP packets')
1538 self.assertEqual(err - tcpn, 1)
1539 err = self.statistics.get_counter(
1540 '/err/nat44-in2out-slowpath/UDP packets')
1541 self.assertEqual(err - udpn, 1)
1542 err = self.statistics.get_counter(
1543 '/err/nat44-in2out-slowpath/ICMP packets')
1544 self.assertEqual(err - icmpn, 1)
1545 err = self.statistics.get_counter(
1546 '/err/nat44-in2out-slowpath/good in2out packets processed')
1547 self.assertEqual(err - totaln, 3)
1550 tcpn = self.statistics.get_counter('/err/nat44-out2in/TCP packets')
1551 udpn = self.statistics.get_counter('/err/nat44-out2in/UDP packets')
1552 icmpn = self.statistics.get_counter('/err/nat44-out2in/ICMP packets')
1553 totaln = self.statistics.get_counter(
1554 '/err/nat44-out2in/good out2in packets processed')
1556 pkts = self.create_stream_out(self.pg1)
1557 self.pg1.add_stream(pkts)
1558 self.pg_enable_capture(self.pg_interfaces)
1560 capture = self.pg0.get_capture(len(pkts))
1561 self.verify_capture_in(capture, self.pg0)
1563 err = self.statistics.get_counter('/err/nat44-out2in/TCP packets')
1564 self.assertEqual(err - tcpn, 1)
1565 err = self.statistics.get_counter('/err/nat44-out2in/UDP packets')
1566 self.assertEqual(err - udpn, 1)
1567 err = self.statistics.get_counter('/err/nat44-out2in/ICMP packets')
1568 self.assertEqual(err - icmpn, 1)
1569 err = self.statistics.get_counter(
1570 '/err/nat44-out2in/good out2in packets processed')
1571 self.assertEqual(err - totaln, 3)
1573 users = self.statistics.get_counter('/nat44/total-users')
1574 self.assertEqual(users[0][0], 1)
1575 sessions = self.statistics.get_counter('/nat44/total-sessions')
1576 self.assertEqual(sessions[0][0], 3)
1578 def test_dynamic_icmp_errors_in2out_ttl_1(self):
1579 """ NAT44 handling of client packets with TTL=1 """
1581 self.nat44_add_address(self.nat_addr)
1582 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
1583 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
1586 # Client side - generate traffic
1587 pkts = self.create_stream_in(self.pg0, self.pg1, ttl=1)
1588 self.pg0.add_stream(pkts)
1589 self.pg_enable_capture(self.pg_interfaces)
1592 # Client side - verify ICMP type 11 packets
1593 capture = self.pg0.get_capture(len(pkts))
1594 self.verify_capture_in_with_icmp_errors(capture, self.pg0)
1596 def test_dynamic_icmp_errors_out2in_ttl_1(self):
1597 """ NAT44 handling of server packets with TTL=1 """
1599 self.nat44_add_address(self.nat_addr)
1600 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
1601 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
1604 # Client side - create sessions
1605 pkts = self.create_stream_in(self.pg0, self.pg1)
1606 self.pg0.add_stream(pkts)
1607 self.pg_enable_capture(self.pg_interfaces)
1610 # Server side - generate traffic
1611 capture = self.pg1.get_capture(len(pkts))
1612 self.verify_capture_out(capture)
1613 pkts = self.create_stream_out(self.pg1, ttl=1)
1614 self.pg1.add_stream(pkts)
1615 self.pg_enable_capture(self.pg_interfaces)
1618 # Server side - verify ICMP type 11 packets
1619 capture = self.pg1.get_capture(len(pkts))
1620 self.verify_capture_out_with_icmp_errors(capture,
1621 src_ip=self.pg1.local_ip4)
1623 def test_dynamic_icmp_errors_in2out_ttl_2(self):
1624 """ NAT44 handling of error responses to client packets with TTL=2 """
1626 self.nat44_add_address(self.nat_addr)
1627 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
1628 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
1631 # Client side - generate traffic
1632 pkts = self.create_stream_in(self.pg0, self.pg1, ttl=2)
1633 self.pg0.add_stream(pkts)
1634 self.pg_enable_capture(self.pg_interfaces)
1637 # Server side - simulate ICMP type 11 response
1638 capture = self.pg1.get_capture(len(pkts))
1639 pkts = [Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
1640 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
1641 ICMP(type=11) / packet[IP] for packet in capture]
1642 self.pg1.add_stream(pkts)
1643 self.pg_enable_capture(self.pg_interfaces)
1646 # Client side - verify ICMP type 11 packets
1647 capture = self.pg0.get_capture(len(pkts))
1648 self.verify_capture_in_with_icmp_errors(capture, self.pg0)
1650 def test_dynamic_icmp_errors_out2in_ttl_2(self):
1651 """ NAT44 handling of error responses to server packets with TTL=2 """
1653 self.nat44_add_address(self.nat_addr)
1654 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
1655 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
1658 # Client side - create sessions
1659 pkts = self.create_stream_in(self.pg0, self.pg1)
1660 self.pg0.add_stream(pkts)
1661 self.pg_enable_capture(self.pg_interfaces)
1664 # Server side - generate traffic
1665 capture = self.pg1.get_capture(len(pkts))
1666 self.verify_capture_out(capture)
1667 pkts = self.create_stream_out(self.pg1, ttl=2)
1668 self.pg1.add_stream(pkts)
1669 self.pg_enable_capture(self.pg_interfaces)
1672 # Client side - simulate ICMP type 11 response
1673 capture = self.pg0.get_capture(len(pkts))
1674 pkts = [Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
1675 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
1676 ICMP(type=11) / packet[IP] for packet in capture]
1677 self.pg0.add_stream(pkts)
1678 self.pg_enable_capture(self.pg_interfaces)
1681 # Server side - verify ICMP type 11 packets
1682 capture = self.pg1.get_capture(len(pkts))
1683 self.verify_capture_out_with_icmp_errors(capture)
1685 def test_ping_out_interface_from_outside(self):
1686 """ Ping NAT44 out interface from outside network """
1688 self.nat44_add_address(self.nat_addr)
1689 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
1690 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
1693 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
1694 IP(src=self.pg1.remote_ip4, dst=self.pg1.local_ip4) /
1695 ICMP(id=self.icmp_id_out, type='echo-request'))
1697 self.pg1.add_stream(pkts)
1698 self.pg_enable_capture(self.pg_interfaces)
1700 capture = self.pg1.get_capture(len(pkts))
1703 self.assertEqual(packet[IP].src, self.pg1.local_ip4)
1704 self.assertEqual(packet[IP].dst, self.pg1.remote_ip4)
1705 self.assertEqual(packet[ICMP].id, self.icmp_id_in)
1706 self.assertEqual(packet[ICMP].type, 0) # echo reply
1708 self.logger.error(ppp("Unexpected or invalid packet "
1709 "(outside network):", packet))
1712 def test_ping_internal_host_from_outside(self):
1713 """ Ping internal host from outside network """
1715 self.nat44_add_static_mapping(self.pg0.remote_ip4, self.nat_addr)
1716 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
1717 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
1721 pkt = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
1722 IP(src=self.pg1.remote_ip4, dst=self.nat_addr, ttl=64) /
1723 ICMP(id=self.icmp_id_out, type='echo-request'))
1724 self.pg1.add_stream(pkt)
1725 self.pg_enable_capture(self.pg_interfaces)
1727 capture = self.pg0.get_capture(1)
1728 self.verify_capture_in(capture, self.pg0)
1729 self.assert_equal(capture[0][IP].proto, IP_PROTOS.icmp)
1732 pkt = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
1733 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4, ttl=64) /
1734 ICMP(id=self.icmp_id_in, type='echo-reply'))
1735 self.pg0.add_stream(pkt)
1736 self.pg_enable_capture(self.pg_interfaces)
1738 capture = self.pg1.get_capture(1)
1739 self.verify_capture_out(capture, same_port=True)
1740 self.assert_equal(capture[0][IP].proto, IP_PROTOS.icmp)
1742 def test_forwarding(self):
1743 """ NAT44 forwarding test """
1745 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
1746 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
1748 self.vapi.nat44_forwarding_enable_disable(1)
1750 real_ip = self.pg0.remote_ip4n
1751 alias_ip = self.nat_addr_n
1752 self.vapi.nat44_add_del_static_mapping(local_ip=real_ip,
1753 external_ip=alias_ip)
1756 # static mapping match
1758 pkts = self.create_stream_out(self.pg1)
1759 self.pg1.add_stream(pkts)
1760 self.pg_enable_capture(self.pg_interfaces)
1762 capture = self.pg0.get_capture(len(pkts))
1763 self.verify_capture_in(capture, self.pg0)
1765 pkts = self.create_stream_in(self.pg0, self.pg1)
1766 self.pg0.add_stream(pkts)
1767 self.pg_enable_capture(self.pg_interfaces)
1769 capture = self.pg1.get_capture(len(pkts))
1770 self.verify_capture_out(capture, same_port=True)
1772 # no static mapping match
1774 host0 = self.pg0.remote_hosts[0]
1775 self.pg0.remote_hosts[0] = self.pg0.remote_hosts[1]
1777 pkts = self.create_stream_out(self.pg1,
1778 dst_ip=self.pg0.remote_ip4,
1779 use_inside_ports=True)
1780 self.pg1.add_stream(pkts)
1781 self.pg_enable_capture(self.pg_interfaces)
1783 capture = self.pg0.get_capture(len(pkts))
1784 self.verify_capture_in(capture, self.pg0)
1786 pkts = self.create_stream_in(self.pg0, self.pg1)
1787 self.pg0.add_stream(pkts)
1788 self.pg_enable_capture(self.pg_interfaces)
1790 capture = self.pg1.get_capture(len(pkts))
1791 self.verify_capture_out(capture, nat_ip=self.pg0.remote_ip4,
1794 self.pg0.remote_hosts[0] = host0
1797 self.vapi.nat44_forwarding_enable_disable(0)
1798 self.vapi.nat44_add_del_static_mapping(local_ip=real_ip,
1799 external_ip=alias_ip,
1802 def test_static_in(self):
1803 """ 1:1 NAT initialized from inside network """
1805 nat_ip = "10.0.0.10"
1806 self.tcp_port_out = 6303
1807 self.udp_port_out = 6304
1808 self.icmp_id_out = 6305
1810 self.nat44_add_static_mapping(self.pg0.remote_ip4, nat_ip)
1811 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
1812 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
1814 sm = self.vapi.nat44_static_mapping_dump()
1815 self.assertEqual(len(sm), 1)
1816 self.assertEqual((sm[0].tag).split('\0', 1)[0], '')
1817 self.assertEqual(sm[0].protocol, 0)
1818 self.assertEqual(sm[0].local_port, 0)
1819 self.assertEqual(sm[0].external_port, 0)
1822 pkts = self.create_stream_in(self.pg0, self.pg1)
1823 self.pg0.add_stream(pkts)
1824 self.pg_enable_capture(self.pg_interfaces)
1826 capture = self.pg1.get_capture(len(pkts))
1827 self.verify_capture_out(capture, nat_ip, True)
1830 pkts = self.create_stream_out(self.pg1, nat_ip)
1831 self.pg1.add_stream(pkts)
1832 self.pg_enable_capture(self.pg_interfaces)
1834 capture = self.pg0.get_capture(len(pkts))
1835 self.verify_capture_in(capture, self.pg0)
1837 def test_static_out(self):
1838 """ 1:1 NAT initialized from outside network """
1840 nat_ip = "10.0.0.20"
1841 self.tcp_port_out = 6303
1842 self.udp_port_out = 6304
1843 self.icmp_id_out = 6305
1846 self.nat44_add_static_mapping(self.pg0.remote_ip4, nat_ip, tag=tag)
1847 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
1848 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
1850 sm = self.vapi.nat44_static_mapping_dump()
1851 self.assertEqual(len(sm), 1)
1852 self.assertEqual((sm[0].tag).split('\0', 1)[0], tag)
1855 pkts = self.create_stream_out(self.pg1, nat_ip)
1856 self.pg1.add_stream(pkts)
1857 self.pg_enable_capture(self.pg_interfaces)
1859 capture = self.pg0.get_capture(len(pkts))
1860 self.verify_capture_in(capture, self.pg0)
1863 pkts = self.create_stream_in(self.pg0, self.pg1)
1864 self.pg0.add_stream(pkts)
1865 self.pg_enable_capture(self.pg_interfaces)
1867 capture = self.pg1.get_capture(len(pkts))
1868 self.verify_capture_out(capture, nat_ip, True)
1870 def test_static_with_port_in(self):
1871 """ 1:1 NAPT initialized from inside network """
1873 self.tcp_port_out = 3606
1874 self.udp_port_out = 3607
1875 self.icmp_id_out = 3608
1877 self.nat44_add_address(self.nat_addr)
1878 self.nat44_add_static_mapping(self.pg0.remote_ip4, self.nat_addr,
1879 self.tcp_port_in, self.tcp_port_out,
1880 proto=IP_PROTOS.tcp)
1881 self.nat44_add_static_mapping(self.pg0.remote_ip4, self.nat_addr,
1882 self.udp_port_in, self.udp_port_out,
1883 proto=IP_PROTOS.udp)
1884 self.nat44_add_static_mapping(self.pg0.remote_ip4, self.nat_addr,
1885 self.icmp_id_in, self.icmp_id_out,
1886 proto=IP_PROTOS.icmp)
1887 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
1888 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
1892 pkts = self.create_stream_in(self.pg0, self.pg1)
1893 self.pg0.add_stream(pkts)
1894 self.pg_enable_capture(self.pg_interfaces)
1896 capture = self.pg1.get_capture(len(pkts))
1897 self.verify_capture_out(capture)
1900 pkts = self.create_stream_out(self.pg1)
1901 self.pg1.add_stream(pkts)
1902 self.pg_enable_capture(self.pg_interfaces)
1904 capture = self.pg0.get_capture(len(pkts))
1905 self.verify_capture_in(capture, self.pg0)
1907 def test_static_with_port_out(self):
1908 """ 1:1 NAPT initialized from outside network """
1910 self.tcp_port_out = 30606
1911 self.udp_port_out = 30607
1912 self.icmp_id_out = 30608
1914 self.nat44_add_address(self.nat_addr)
1915 self.nat44_add_static_mapping(self.pg0.remote_ip4, self.nat_addr,
1916 self.tcp_port_in, self.tcp_port_out,
1917 proto=IP_PROTOS.tcp)
1918 self.nat44_add_static_mapping(self.pg0.remote_ip4, self.nat_addr,
1919 self.udp_port_in, self.udp_port_out,
1920 proto=IP_PROTOS.udp)
1921 self.nat44_add_static_mapping(self.pg0.remote_ip4, self.nat_addr,
1922 self.icmp_id_in, self.icmp_id_out,
1923 proto=IP_PROTOS.icmp)
1924 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
1925 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
1929 pkts = self.create_stream_out(self.pg1)
1930 self.pg1.add_stream(pkts)
1931 self.pg_enable_capture(self.pg_interfaces)
1933 capture = self.pg0.get_capture(len(pkts))
1934 self.verify_capture_in(capture, self.pg0)
1937 pkts = self.create_stream_in(self.pg0, self.pg1)
1938 self.pg0.add_stream(pkts)
1939 self.pg_enable_capture(self.pg_interfaces)
1941 capture = self.pg1.get_capture(len(pkts))
1942 self.verify_capture_out(capture)
1944 def test_static_vrf_aware(self):
1945 """ 1:1 NAT VRF awareness """
1947 nat_ip1 = "10.0.0.30"
1948 nat_ip2 = "10.0.0.40"
1949 self.tcp_port_out = 6303
1950 self.udp_port_out = 6304
1951 self.icmp_id_out = 6305
1953 self.nat44_add_static_mapping(self.pg4.remote_ip4, nat_ip1,
1955 self.nat44_add_static_mapping(self.pg0.remote_ip4, nat_ip2,
1957 self.vapi.nat44_interface_add_del_feature(self.pg3.sw_if_index,
1959 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
1960 self.vapi.nat44_interface_add_del_feature(self.pg4.sw_if_index)
1962 # inside interface VRF match NAT44 static mapping VRF
1963 pkts = self.create_stream_in(self.pg4, self.pg3)
1964 self.pg4.add_stream(pkts)
1965 self.pg_enable_capture(self.pg_interfaces)
1967 capture = self.pg3.get_capture(len(pkts))
1968 self.verify_capture_out(capture, nat_ip1, True)
1970 # inside interface VRF don't match NAT44 static mapping VRF (packets
1972 pkts = self.create_stream_in(self.pg0, self.pg3)
1973 self.pg0.add_stream(pkts)
1974 self.pg_enable_capture(self.pg_interfaces)
1976 self.pg3.assert_nothing_captured()
1978 def test_dynamic_to_static(self):
1979 """ Switch from dynamic translation to 1:1NAT """
1980 nat_ip = "10.0.0.10"
1981 self.tcp_port_out = 6303
1982 self.udp_port_out = 6304
1983 self.icmp_id_out = 6305
1985 self.nat44_add_address(self.nat_addr)
1986 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
1987 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
1991 pkts = self.create_stream_in(self.pg0, self.pg1)
1992 self.pg0.add_stream(pkts)
1993 self.pg_enable_capture(self.pg_interfaces)
1995 capture = self.pg1.get_capture(len(pkts))
1996 self.verify_capture_out(capture)
1999 self.nat44_add_static_mapping(self.pg0.remote_ip4, nat_ip)
2000 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4n, 0)
2001 self.assertEqual(len(sessions), 0)
2002 pkts = self.create_stream_in(self.pg0, self.pg1)
2003 self.pg0.add_stream(pkts)
2004 self.pg_enable_capture(self.pg_interfaces)
2006 capture = self.pg1.get_capture(len(pkts))
2007 self.verify_capture_out(capture, nat_ip, True)
2009 def test_identity_nat(self):
2010 """ Identity NAT """
2012 self.vapi.nat44_add_del_identity_mapping(ip=self.pg0.remote_ip4n)
2013 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
2014 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
2017 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
2018 IP(src=self.pg1.remote_ip4, dst=self.pg0.remote_ip4) /
2019 TCP(sport=12345, dport=56789))
2020 self.pg1.add_stream(p)
2021 self.pg_enable_capture(self.pg_interfaces)
2023 capture = self.pg0.get_capture(1)
2028 self.assertEqual(ip.dst, self.pg0.remote_ip4)
2029 self.assertEqual(ip.src, self.pg1.remote_ip4)
2030 self.assertEqual(tcp.dport, 56789)
2031 self.assertEqual(tcp.sport, 12345)
2032 self.assert_packet_checksums_valid(p)
2034 self.logger.error(ppp("Unexpected or invalid packet:", p))
2037 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4n, 0)
2038 self.assertEqual(len(sessions), 0)
2039 self.vapi.nat44_add_del_identity_mapping(ip=self.pg0.remote_ip4n,
2041 identity_mappings = self.vapi.nat44_identity_mapping_dump()
2042 self.assertEqual(len(identity_mappings), 2)
2044 def test_multiple_inside_interfaces(self):
2045 """ NAT44 multiple non-overlapping address space inside interfaces """
2047 self.nat44_add_address(self.nat_addr)
2048 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
2049 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index)
2050 self.vapi.nat44_interface_add_del_feature(self.pg3.sw_if_index,
2053 # between two NAT44 inside interfaces (no translation)
2054 pkts = self.create_stream_in(self.pg0, self.pg1)
2055 self.pg0.add_stream(pkts)
2056 self.pg_enable_capture(self.pg_interfaces)
2058 capture = self.pg1.get_capture(len(pkts))
2059 self.verify_capture_no_translation(capture, self.pg0, self.pg1)
2061 # from NAT44 inside to interface without NAT44 feature (no translation)
2062 pkts = self.create_stream_in(self.pg0, self.pg2)
2063 self.pg0.add_stream(pkts)
2064 self.pg_enable_capture(self.pg_interfaces)
2066 capture = self.pg2.get_capture(len(pkts))
2067 self.verify_capture_no_translation(capture, self.pg0, self.pg2)
2069 # in2out 1st interface
2070 pkts = self.create_stream_in(self.pg0, self.pg3)
2071 self.pg0.add_stream(pkts)
2072 self.pg_enable_capture(self.pg_interfaces)
2074 capture = self.pg3.get_capture(len(pkts))
2075 self.verify_capture_out(capture)
2077 # out2in 1st interface
2078 pkts = self.create_stream_out(self.pg3)
2079 self.pg3.add_stream(pkts)
2080 self.pg_enable_capture(self.pg_interfaces)
2082 capture = self.pg0.get_capture(len(pkts))
2083 self.verify_capture_in(capture, self.pg0)
2085 # in2out 2nd interface
2086 pkts = self.create_stream_in(self.pg1, self.pg3)
2087 self.pg1.add_stream(pkts)
2088 self.pg_enable_capture(self.pg_interfaces)
2090 capture = self.pg3.get_capture(len(pkts))
2091 self.verify_capture_out(capture)
2093 # out2in 2nd interface
2094 pkts = self.create_stream_out(self.pg3)
2095 self.pg3.add_stream(pkts)
2096 self.pg_enable_capture(self.pg_interfaces)
2098 capture = self.pg1.get_capture(len(pkts))
2099 self.verify_capture_in(capture, self.pg1)
2101 def test_inside_overlapping_interfaces(self):
2102 """ NAT44 multiple inside interfaces with overlapping address space """
2104 static_nat_ip = "10.0.0.10"
2105 self.nat44_add_address(self.nat_addr)
2106 self.vapi.nat44_interface_add_del_feature(self.pg3.sw_if_index,
2108 self.vapi.nat44_interface_add_del_feature(self.pg4.sw_if_index)
2109 self.vapi.nat44_interface_add_del_feature(self.pg5.sw_if_index)
2110 self.vapi.nat44_interface_add_del_feature(self.pg6.sw_if_index)
2111 self.nat44_add_static_mapping(self.pg6.remote_ip4, static_nat_ip,
2114 # between NAT44 inside interfaces with same VRF (no translation)
2115 pkts = self.create_stream_in(self.pg4, self.pg5)
2116 self.pg4.add_stream(pkts)
2117 self.pg_enable_capture(self.pg_interfaces)
2119 capture = self.pg5.get_capture(len(pkts))
2120 self.verify_capture_no_translation(capture, self.pg4, self.pg5)
2122 # between NAT44 inside interfaces with different VRF (hairpinning)
2123 p = (Ether(src=self.pg4.remote_mac, dst=self.pg4.local_mac) /
2124 IP(src=self.pg4.remote_ip4, dst=static_nat_ip) /
2125 TCP(sport=1234, dport=5678))
2126 self.pg4.add_stream(p)
2127 self.pg_enable_capture(self.pg_interfaces)
2129 capture = self.pg6.get_capture(1)
2134 self.assertEqual(ip.src, self.nat_addr)
2135 self.assertEqual(ip.dst, self.pg6.remote_ip4)
2136 self.assertNotEqual(tcp.sport, 1234)
2137 self.assertEqual(tcp.dport, 5678)
2139 self.logger.error(ppp("Unexpected or invalid packet:", p))
2142 # in2out 1st interface
2143 pkts = self.create_stream_in(self.pg4, self.pg3)
2144 self.pg4.add_stream(pkts)
2145 self.pg_enable_capture(self.pg_interfaces)
2147 capture = self.pg3.get_capture(len(pkts))
2148 self.verify_capture_out(capture)
2150 # out2in 1st interface
2151 pkts = self.create_stream_out(self.pg3)
2152 self.pg3.add_stream(pkts)
2153 self.pg_enable_capture(self.pg_interfaces)
2155 capture = self.pg4.get_capture(len(pkts))
2156 self.verify_capture_in(capture, self.pg4)
2158 # in2out 2nd interface
2159 pkts = self.create_stream_in(self.pg5, self.pg3)
2160 self.pg5.add_stream(pkts)
2161 self.pg_enable_capture(self.pg_interfaces)
2163 capture = self.pg3.get_capture(len(pkts))
2164 self.verify_capture_out(capture)
2166 # out2in 2nd interface
2167 pkts = self.create_stream_out(self.pg3)
2168 self.pg3.add_stream(pkts)
2169 self.pg_enable_capture(self.pg_interfaces)
2171 capture = self.pg5.get_capture(len(pkts))
2172 self.verify_capture_in(capture, self.pg5)
2175 addresses = self.vapi.nat44_address_dump()
2176 self.assertEqual(len(addresses), 1)
2177 sessions = self.vapi.nat44_user_session_dump(self.pg5.remote_ip4n, 10)
2178 self.assertEqual(len(sessions), 3)
2179 for session in sessions:
2180 self.assertFalse(session.is_static)
2181 self.assertEqual(session.inside_ip_address[0:4],
2182 self.pg5.remote_ip4n)
2183 self.assertEqual(session.outside_ip_address,
2184 addresses[0].ip_address)
2185 self.assertEqual(sessions[0].protocol, IP_PROTOS.tcp)
2186 self.assertEqual(sessions[1].protocol, IP_PROTOS.udp)
2187 self.assertEqual(sessions[2].protocol, IP_PROTOS.icmp)
2188 self.assertEqual(sessions[0].inside_port, self.tcp_port_in)
2189 self.assertEqual(sessions[1].inside_port, self.udp_port_in)
2190 self.assertEqual(sessions[2].inside_port, self.icmp_id_in)
2191 self.assertEqual(sessions[0].outside_port, self.tcp_port_out)
2192 self.assertEqual(sessions[1].outside_port, self.udp_port_out)
2193 self.assertEqual(sessions[2].outside_port, self.icmp_id_out)
2195 # in2out 3rd interface
2196 pkts = self.create_stream_in(self.pg6, self.pg3)
2197 self.pg6.add_stream(pkts)
2198 self.pg_enable_capture(self.pg_interfaces)
2200 capture = self.pg3.get_capture(len(pkts))
2201 self.verify_capture_out(capture, static_nat_ip, True)
2203 # out2in 3rd interface
2204 pkts = self.create_stream_out(self.pg3, static_nat_ip)
2205 self.pg3.add_stream(pkts)
2206 self.pg_enable_capture(self.pg_interfaces)
2208 capture = self.pg6.get_capture(len(pkts))
2209 self.verify_capture_in(capture, self.pg6)
2211 # general user and session dump verifications
2212 users = self.vapi.nat44_user_dump()
2213 self.assertGreaterEqual(len(users), 3)
2214 addresses = self.vapi.nat44_address_dump()
2215 self.assertEqual(len(addresses), 1)
2217 sessions = self.vapi.nat44_user_session_dump(user.ip_address,
2219 for session in sessions:
2220 self.assertEqual(user.ip_address, session.inside_ip_address)
2221 self.assertTrue(session.total_bytes > session.total_pkts > 0)
2222 self.assertTrue(session.protocol in
2223 [IP_PROTOS.tcp, IP_PROTOS.udp,
2225 self.assertFalse(session.ext_host_valid)
2228 sessions = self.vapi.nat44_user_session_dump(self.pg4.remote_ip4n, 10)
2229 self.assertGreaterEqual(len(sessions), 4)
2230 for session in sessions:
2231 self.assertFalse(session.is_static)
2232 self.assertEqual(session.inside_ip_address[0:4],
2233 self.pg4.remote_ip4n)
2234 self.assertEqual(session.outside_ip_address,
2235 addresses[0].ip_address)
2238 sessions = self.vapi.nat44_user_session_dump(self.pg6.remote_ip4n, 20)
2239 self.assertGreaterEqual(len(sessions), 3)
2240 for session in sessions:
2241 self.assertTrue(session.is_static)
2242 self.assertEqual(session.inside_ip_address[0:4],
2243 self.pg6.remote_ip4n)
2244 self.assertEqual(map(ord, session.outside_ip_address[0:4]),
2245 map(int, static_nat_ip.split('.')))
2246 self.assertTrue(session.inside_port in
2247 [self.tcp_port_in, self.udp_port_in,
2250 def test_hairpinning(self):
2251 """ NAT44 hairpinning - 1:1 NAPT """
2253 host = self.pg0.remote_hosts[0]
2254 server = self.pg0.remote_hosts[1]
2257 server_in_port = 5678
2258 server_out_port = 8765
2260 self.nat44_add_address(self.nat_addr)
2261 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
2262 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
2264 # add static mapping for server
2265 self.nat44_add_static_mapping(server.ip4, self.nat_addr,
2266 server_in_port, server_out_port,
2267 proto=IP_PROTOS.tcp)
2269 # send packet from host to server
2270 p = (Ether(src=host.mac, dst=self.pg0.local_mac) /
2271 IP(src=host.ip4, dst=self.nat_addr) /
2272 TCP(sport=host_in_port, dport=server_out_port))
2273 self.pg0.add_stream(p)
2274 self.pg_enable_capture(self.pg_interfaces)
2276 capture = self.pg0.get_capture(1)
2281 self.assertEqual(ip.src, self.nat_addr)
2282 self.assertEqual(ip.dst, server.ip4)
2283 self.assertNotEqual(tcp.sport, host_in_port)
2284 self.assertEqual(tcp.dport, server_in_port)
2285 self.assert_packet_checksums_valid(p)
2286 host_out_port = tcp.sport
2288 self.logger.error(ppp("Unexpected or invalid packet:", p))
2291 # send reply from server to host
2292 p = (Ether(src=server.mac, dst=self.pg0.local_mac) /
2293 IP(src=server.ip4, dst=self.nat_addr) /
2294 TCP(sport=server_in_port, dport=host_out_port))
2295 self.pg0.add_stream(p)
2296 self.pg_enable_capture(self.pg_interfaces)
2298 capture = self.pg0.get_capture(1)
2303 self.assertEqual(ip.src, self.nat_addr)
2304 self.assertEqual(ip.dst, host.ip4)
2305 self.assertEqual(tcp.sport, server_out_port)
2306 self.assertEqual(tcp.dport, host_in_port)
2307 self.assert_packet_checksums_valid(p)
2309 self.logger.error(ppp("Unexpected or invalid packet:", p))
2312 def test_hairpinning2(self):
2313 """ NAT44 hairpinning - 1:1 NAT"""
2315 server1_nat_ip = "10.0.0.10"
2316 server2_nat_ip = "10.0.0.11"
2317 host = self.pg0.remote_hosts[0]
2318 server1 = self.pg0.remote_hosts[1]
2319 server2 = self.pg0.remote_hosts[2]
2320 server_tcp_port = 22
2321 server_udp_port = 20
2323 self.nat44_add_address(self.nat_addr)
2324 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
2325 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
2328 # add static mapping for servers
2329 self.nat44_add_static_mapping(server1.ip4, server1_nat_ip)
2330 self.nat44_add_static_mapping(server2.ip4, server2_nat_ip)
2334 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2335 IP(src=host.ip4, dst=server1_nat_ip) /
2336 TCP(sport=self.tcp_port_in, dport=server_tcp_port))
2338 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2339 IP(src=host.ip4, dst=server1_nat_ip) /
2340 UDP(sport=self.udp_port_in, dport=server_udp_port))
2342 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2343 IP(src=host.ip4, dst=server1_nat_ip) /
2344 ICMP(id=self.icmp_id_in, type='echo-request'))
2346 self.pg0.add_stream(pkts)
2347 self.pg_enable_capture(self.pg_interfaces)
2349 capture = self.pg0.get_capture(len(pkts))
2350 for packet in capture:
2352 self.assertEqual(packet[IP].src, self.nat_addr)
2353 self.assertEqual(packet[IP].dst, server1.ip4)
2354 if packet.haslayer(TCP):
2355 self.assertNotEqual(packet[TCP].sport, self.tcp_port_in)
2356 self.assertEqual(packet[TCP].dport, server_tcp_port)
2357 self.tcp_port_out = packet[TCP].sport
2358 self.assert_packet_checksums_valid(packet)
2359 elif packet.haslayer(UDP):
2360 self.assertNotEqual(packet[UDP].sport, self.udp_port_in)
2361 self.assertEqual(packet[UDP].dport, server_udp_port)
2362 self.udp_port_out = packet[UDP].sport
2364 self.assertNotEqual(packet[ICMP].id, self.icmp_id_in)
2365 self.icmp_id_out = packet[ICMP].id
2367 self.logger.error(ppp("Unexpected or invalid packet:", packet))
2372 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2373 IP(src=server1.ip4, dst=self.nat_addr) /
2374 TCP(sport=server_tcp_port, dport=self.tcp_port_out))
2376 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2377 IP(src=server1.ip4, dst=self.nat_addr) /
2378 UDP(sport=server_udp_port, dport=self.udp_port_out))
2380 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2381 IP(src=server1.ip4, dst=self.nat_addr) /
2382 ICMP(id=self.icmp_id_out, type='echo-reply'))
2384 self.pg0.add_stream(pkts)
2385 self.pg_enable_capture(self.pg_interfaces)
2387 capture = self.pg0.get_capture(len(pkts))
2388 for packet in capture:
2390 self.assertEqual(packet[IP].src, server1_nat_ip)
2391 self.assertEqual(packet[IP].dst, host.ip4)
2392 if packet.haslayer(TCP):
2393 self.assertEqual(packet[TCP].dport, self.tcp_port_in)
2394 self.assertEqual(packet[TCP].sport, server_tcp_port)
2395 self.assert_packet_checksums_valid(packet)
2396 elif packet.haslayer(UDP):
2397 self.assertEqual(packet[UDP].dport, self.udp_port_in)
2398 self.assertEqual(packet[UDP].sport, server_udp_port)
2400 self.assertEqual(packet[ICMP].id, self.icmp_id_in)
2402 self.logger.error(ppp("Unexpected or invalid packet:", packet))
2405 # server2 to server1
2407 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2408 IP(src=server2.ip4, dst=server1_nat_ip) /
2409 TCP(sport=self.tcp_port_in, dport=server_tcp_port))
2411 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2412 IP(src=server2.ip4, dst=server1_nat_ip) /
2413 UDP(sport=self.udp_port_in, dport=server_udp_port))
2415 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2416 IP(src=server2.ip4, dst=server1_nat_ip) /
2417 ICMP(id=self.icmp_id_in, type='echo-request'))
2419 self.pg0.add_stream(pkts)
2420 self.pg_enable_capture(self.pg_interfaces)
2422 capture = self.pg0.get_capture(len(pkts))
2423 for packet in capture:
2425 self.assertEqual(packet[IP].src, server2_nat_ip)
2426 self.assertEqual(packet[IP].dst, server1.ip4)
2427 if packet.haslayer(TCP):
2428 self.assertEqual(packet[TCP].sport, self.tcp_port_in)
2429 self.assertEqual(packet[TCP].dport, server_tcp_port)
2430 self.tcp_port_out = packet[TCP].sport
2431 self.assert_packet_checksums_valid(packet)
2432 elif packet.haslayer(UDP):
2433 self.assertEqual(packet[UDP].sport, self.udp_port_in)
2434 self.assertEqual(packet[UDP].dport, server_udp_port)
2435 self.udp_port_out = packet[UDP].sport
2437 self.assertEqual(packet[ICMP].id, self.icmp_id_in)
2438 self.icmp_id_out = packet[ICMP].id
2440 self.logger.error(ppp("Unexpected or invalid packet:", packet))
2443 # server1 to server2
2445 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2446 IP(src=server1.ip4, dst=server2_nat_ip) /
2447 TCP(sport=server_tcp_port, dport=self.tcp_port_out))
2449 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2450 IP(src=server1.ip4, dst=server2_nat_ip) /
2451 UDP(sport=server_udp_port, dport=self.udp_port_out))
2453 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2454 IP(src=server1.ip4, dst=server2_nat_ip) /
2455 ICMP(id=self.icmp_id_out, type='echo-reply'))
2457 self.pg0.add_stream(pkts)
2458 self.pg_enable_capture(self.pg_interfaces)
2460 capture = self.pg0.get_capture(len(pkts))
2461 for packet in capture:
2463 self.assertEqual(packet[IP].src, server1_nat_ip)
2464 self.assertEqual(packet[IP].dst, server2.ip4)
2465 if packet.haslayer(TCP):
2466 self.assertEqual(packet[TCP].dport, self.tcp_port_in)
2467 self.assertEqual(packet[TCP].sport, server_tcp_port)
2468 self.assert_packet_checksums_valid(packet)
2469 elif packet.haslayer(UDP):
2470 self.assertEqual(packet[UDP].dport, self.udp_port_in)
2471 self.assertEqual(packet[UDP].sport, server_udp_port)
2473 self.assertEqual(packet[ICMP].id, self.icmp_id_in)
2475 self.logger.error(ppp("Unexpected or invalid packet:", packet))
2478 def test_max_translations_per_user(self):
2479 """ MAX translations per user - recycle the least recently used """
2481 self.nat44_add_address(self.nat_addr)
2482 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
2483 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
2486 # get maximum number of translations per user
2487 nat44_config = self.vapi.nat_show_config()
2489 # send more than maximum number of translations per user packets
2490 pkts_num = nat44_config.max_translations_per_user + 5
2492 for port in range(0, pkts_num):
2493 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2494 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
2495 TCP(sport=1025 + port))
2497 self.pg0.add_stream(pkts)
2498 self.pg_enable_capture(self.pg_interfaces)
2501 # verify number of translated packet
2502 self.pg1.get_capture(pkts_num)
2504 users = self.vapi.nat44_user_dump()
2506 if user.ip_address == self.pg0.remote_ip4n:
2507 self.assertEqual(user.nsessions,
2508 nat44_config.max_translations_per_user)
2509 self.assertEqual(user.nstaticsessions, 0)
2512 self.nat44_add_static_mapping(self.pg0.remote_ip4, self.nat_addr,
2514 proto=IP_PROTOS.tcp)
2515 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2516 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
2517 TCP(sport=tcp_port))
2518 self.pg0.add_stream(p)
2519 self.pg_enable_capture(self.pg_interfaces)
2521 self.pg1.get_capture(1)
2522 users = self.vapi.nat44_user_dump()
2524 if user.ip_address == self.pg0.remote_ip4n:
2525 self.assertEqual(user.nsessions,
2526 nat44_config.max_translations_per_user - 1)
2527 self.assertEqual(user.nstaticsessions, 1)
2529 def test_interface_addr(self):
2530 """ Acquire NAT44 addresses from interface """
2531 self.vapi.nat44_add_interface_addr(self.pg7.sw_if_index)
2533 # no address in NAT pool
2534 adresses = self.vapi.nat44_address_dump()
2535 self.assertEqual(0, len(adresses))
2537 # configure interface address and check NAT address pool
2538 self.pg7.config_ip4()
2539 adresses = self.vapi.nat44_address_dump()
2540 self.assertEqual(1, len(adresses))
2541 self.assertEqual(adresses[0].ip_address[0:4], self.pg7.local_ip4n)
2543 # remove interface address and check NAT address pool
2544 self.pg7.unconfig_ip4()
2545 adresses = self.vapi.nat44_address_dump()
2546 self.assertEqual(0, len(adresses))
2548 def test_interface_addr_static_mapping(self):
2549 """ Static mapping with addresses from interface """
2552 self.vapi.nat44_add_interface_addr(self.pg7.sw_if_index)
2553 self.nat44_add_static_mapping(
2555 external_sw_if_index=self.pg7.sw_if_index,
2558 # static mappings with external interface
2559 static_mappings = self.vapi.nat44_static_mapping_dump()
2560 self.assertEqual(1, len(static_mappings))
2561 self.assertEqual(self.pg7.sw_if_index,
2562 static_mappings[0].external_sw_if_index)
2563 self.assertEqual((static_mappings[0].tag).split('\0', 1)[0], tag)
2565 # configure interface address and check static mappings
2566 self.pg7.config_ip4()
2567 static_mappings = self.vapi.nat44_static_mapping_dump()
2568 self.assertEqual(2, len(static_mappings))
2570 for sm in static_mappings:
2571 if sm.external_sw_if_index == 0xFFFFFFFF:
2572 self.assertEqual(sm.external_ip_address[0:4],
2573 self.pg7.local_ip4n)
2574 self.assertEqual((sm.tag).split('\0', 1)[0], tag)
2576 self.assertTrue(resolved)
2578 # remove interface address and check static mappings
2579 self.pg7.unconfig_ip4()
2580 static_mappings = self.vapi.nat44_static_mapping_dump()
2581 self.assertEqual(1, len(static_mappings))
2582 self.assertEqual(self.pg7.sw_if_index,
2583 static_mappings[0].external_sw_if_index)
2584 self.assertEqual((static_mappings[0].tag).split('\0', 1)[0], tag)
2586 # configure interface address again and check static mappings
2587 self.pg7.config_ip4()
2588 static_mappings = self.vapi.nat44_static_mapping_dump()
2589 self.assertEqual(2, len(static_mappings))
2591 for sm in static_mappings:
2592 if sm.external_sw_if_index == 0xFFFFFFFF:
2593 self.assertEqual(sm.external_ip_address[0:4],
2594 self.pg7.local_ip4n)
2595 self.assertEqual((sm.tag).split('\0', 1)[0], tag)
2597 self.assertTrue(resolved)
2599 # remove static mapping
2600 self.nat44_add_static_mapping(
2602 external_sw_if_index=self.pg7.sw_if_index,
2605 static_mappings = self.vapi.nat44_static_mapping_dump()
2606 self.assertEqual(0, len(static_mappings))
2608 def test_interface_addr_identity_nat(self):
2609 """ Identity NAT with addresses from interface """
2612 self.vapi.nat44_add_interface_addr(self.pg7.sw_if_index)
2613 self.vapi.nat44_add_del_identity_mapping(
2614 sw_if_index=self.pg7.sw_if_index,
2616 protocol=IP_PROTOS.tcp,
2619 # identity mappings with external interface
2620 identity_mappings = self.vapi.nat44_identity_mapping_dump()
2621 self.assertEqual(1, len(identity_mappings))
2622 self.assertEqual(self.pg7.sw_if_index,
2623 identity_mappings[0].sw_if_index)
2625 # configure interface address and check identity mappings
2626 self.pg7.config_ip4()
2627 identity_mappings = self.vapi.nat44_identity_mapping_dump()
2629 self.assertEqual(2, len(identity_mappings))
2630 for sm in identity_mappings:
2631 if sm.sw_if_index == 0xFFFFFFFF:
2632 self.assertEqual(identity_mappings[0].ip_address,
2633 self.pg7.local_ip4n)
2634 self.assertEqual(port, identity_mappings[0].port)
2635 self.assertEqual(IP_PROTOS.tcp, identity_mappings[0].protocol)
2637 self.assertTrue(resolved)
2639 # remove interface address and check identity mappings
2640 self.pg7.unconfig_ip4()
2641 identity_mappings = self.vapi.nat44_identity_mapping_dump()
2642 self.assertEqual(1, len(identity_mappings))
2643 self.assertEqual(self.pg7.sw_if_index,
2644 identity_mappings[0].sw_if_index)
2646 def test_ipfix_nat44_sess(self):
2647 """ IPFIX logging NAT44 session created/delted """
2648 self.ipfix_domain_id = 10
2649 self.ipfix_src_port = 20202
2650 colector_port = 30303
2651 bind_layers(UDP, IPFIX, dport=30303)
2652 self.nat44_add_address(self.nat_addr)
2653 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
2654 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
2656 self.vapi.set_ipfix_exporter(collector_address=self.pg3.remote_ip4n,
2657 src_address=self.pg3.local_ip4n,
2659 template_interval=10,
2660 collector_port=colector_port)
2661 self.vapi.nat_ipfix(domain_id=self.ipfix_domain_id,
2662 src_port=self.ipfix_src_port)
2664 pkts = self.create_stream_in(self.pg0, self.pg1)
2665 self.pg0.add_stream(pkts)
2666 self.pg_enable_capture(self.pg_interfaces)
2668 capture = self.pg1.get_capture(len(pkts))
2669 self.verify_capture_out(capture)
2670 self.nat44_add_address(self.nat_addr, is_add=0)
2671 self.vapi.cli("ipfix flush") # FIXME this should be an API call
2672 capture = self.pg3.get_capture(9)
2673 ipfix = IPFIXDecoder()
2674 # first load template
2676 self.assertTrue(p.haslayer(IPFIX))
2677 self.assertEqual(p[IP].src, self.pg3.local_ip4)
2678 self.assertEqual(p[IP].dst, self.pg3.remote_ip4)
2679 self.assertEqual(p[UDP].sport, self.ipfix_src_port)
2680 self.assertEqual(p[UDP].dport, colector_port)
2681 self.assertEqual(p[IPFIX].observationDomainID,
2682 self.ipfix_domain_id)
2683 if p.haslayer(Template):
2684 ipfix.add_template(p.getlayer(Template))
2685 # verify events in data set
2687 if p.haslayer(Data):
2688 data = ipfix.decode_data_set(p.getlayer(Set))
2689 self.verify_ipfix_nat44_ses(data)
2691 def test_ipfix_addr_exhausted(self):
2692 """ IPFIX logging NAT addresses exhausted """
2693 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
2694 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
2696 self.vapi.set_ipfix_exporter(collector_address=self.pg3.remote_ip4n,
2697 src_address=self.pg3.local_ip4n,
2699 template_interval=10)
2700 self.vapi.nat_ipfix(domain_id=self.ipfix_domain_id,
2701 src_port=self.ipfix_src_port)
2703 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
2704 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
2706 self.pg0.add_stream(p)
2707 self.pg_enable_capture(self.pg_interfaces)
2709 self.pg1.assert_nothing_captured()
2711 self.vapi.cli("ipfix flush") # FIXME this should be an API call
2712 capture = self.pg3.get_capture(9)
2713 ipfix = IPFIXDecoder()
2714 # first load template
2716 self.assertTrue(p.haslayer(IPFIX))
2717 self.assertEqual(p[IP].src, self.pg3.local_ip4)
2718 self.assertEqual(p[IP].dst, self.pg3.remote_ip4)
2719 self.assertEqual(p[UDP].sport, self.ipfix_src_port)
2720 self.assertEqual(p[UDP].dport, 4739)
2721 self.assertEqual(p[IPFIX].observationDomainID,
2722 self.ipfix_domain_id)
2723 if p.haslayer(Template):
2724 ipfix.add_template(p.getlayer(Template))
2725 # verify events in data set
2727 if p.haslayer(Data):
2728 data = ipfix.decode_data_set(p.getlayer(Set))
2729 self.verify_ipfix_addr_exhausted(data)
2731 @unittest.skipUnless(running_extended_tests, "part of extended tests")
2732 def test_ipfix_max_sessions(self):
2733 """ IPFIX logging maximum session entries exceeded """
2734 self.nat44_add_address(self.nat_addr)
2735 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
2736 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
2739 nat44_config = self.vapi.nat_show_config()
2740 max_sessions = 10 * nat44_config.translation_buckets
2743 for i in range(0, max_sessions):
2744 src = "10.10.%u.%u" % ((i & 0xFF00) >> 8, i & 0xFF)
2745 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2746 IP(src=src, dst=self.pg1.remote_ip4) /
2749 self.pg0.add_stream(pkts)
2750 self.pg_enable_capture(self.pg_interfaces)
2753 self.pg1.get_capture(max_sessions)
2754 self.vapi.set_ipfix_exporter(collector_address=self.pg3.remote_ip4n,
2755 src_address=self.pg3.local_ip4n,
2757 template_interval=10)
2758 self.vapi.nat_ipfix(domain_id=self.ipfix_domain_id,
2759 src_port=self.ipfix_src_port)
2761 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2762 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
2764 self.pg0.add_stream(p)
2765 self.pg_enable_capture(self.pg_interfaces)
2767 self.pg1.assert_nothing_captured()
2769 self.vapi.cli("ipfix flush") # FIXME this should be an API call
2770 capture = self.pg3.get_capture(9)
2771 ipfix = IPFIXDecoder()
2772 # first load template
2774 self.assertTrue(p.haslayer(IPFIX))
2775 self.assertEqual(p[IP].src, self.pg3.local_ip4)
2776 self.assertEqual(p[IP].dst, self.pg3.remote_ip4)
2777 self.assertEqual(p[UDP].sport, self.ipfix_src_port)
2778 self.assertEqual(p[UDP].dport, 4739)
2779 self.assertEqual(p[IPFIX].observationDomainID,
2780 self.ipfix_domain_id)
2781 if p.haslayer(Template):
2782 ipfix.add_template(p.getlayer(Template))
2783 # verify events in data set
2785 if p.haslayer(Data):
2786 data = ipfix.decode_data_set(p.getlayer(Set))
2787 self.verify_ipfix_max_sessions(data, max_sessions)
2789 def test_syslog_apmap(self):
2790 """ Test syslog address and port mapping creation and deletion """
2791 self.vapi.syslog_set_filter(SYSLOG_SEVERITY.INFO)
2792 self.vapi.syslog_set_sender(self.pg3.remote_ip4n, self.pg3.local_ip4n)
2793 self.nat44_add_address(self.nat_addr)
2794 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
2795 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
2798 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2799 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
2800 TCP(sport=self.tcp_port_in, dport=20))
2801 self.pg0.add_stream(p)
2802 self.pg_enable_capture(self.pg_interfaces)
2804 capture = self.pg1.get_capture(1)
2805 self.tcp_port_out = capture[0][TCP].sport
2806 capture = self.pg3.get_capture(1)
2807 self.verify_syslog_apmap(capture[0][Raw].load)
2809 self.pg_enable_capture(self.pg_interfaces)
2811 self.nat44_add_address(self.nat_addr, is_add=0)
2812 capture = self.pg3.get_capture(1)
2813 self.verify_syslog_apmap(capture[0][Raw].load, False)
2815 def test_pool_addr_fib(self):
2816 """ NAT44 add pool addresses to FIB """
2817 static_addr = '10.0.0.10'
2818 self.nat44_add_address(self.nat_addr)
2819 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
2820 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
2822 self.nat44_add_static_mapping(self.pg0.remote_ip4, static_addr)
2825 p = (Ether(src=self.pg1.remote_mac, dst='ff:ff:ff:ff:ff:ff') /
2826 ARP(op=ARP.who_has, pdst=self.nat_addr,
2827 psrc=self.pg1.remote_ip4, hwsrc=self.pg1.remote_mac))
2828 self.pg1.add_stream(p)
2829 self.pg_enable_capture(self.pg_interfaces)
2831 capture = self.pg1.get_capture(1)
2832 self.assertTrue(capture[0].haslayer(ARP))
2833 self.assertTrue(capture[0][ARP].op, ARP.is_at)
2836 p = (Ether(src=self.pg1.remote_mac, dst='ff:ff:ff:ff:ff:ff') /
2837 ARP(op=ARP.who_has, pdst=static_addr,
2838 psrc=self.pg1.remote_ip4, hwsrc=self.pg1.remote_mac))
2839 self.pg1.add_stream(p)
2840 self.pg_enable_capture(self.pg_interfaces)
2842 capture = self.pg1.get_capture(1)
2843 self.assertTrue(capture[0].haslayer(ARP))
2844 self.assertTrue(capture[0][ARP].op, ARP.is_at)
2846 # send ARP to non-NAT44 interface
2847 p = (Ether(src=self.pg2.remote_mac, dst='ff:ff:ff:ff:ff:ff') /
2848 ARP(op=ARP.who_has, pdst=self.nat_addr,
2849 psrc=self.pg2.remote_ip4, hwsrc=self.pg2.remote_mac))
2850 self.pg2.add_stream(p)
2851 self.pg_enable_capture(self.pg_interfaces)
2853 self.pg1.assert_nothing_captured()
2855 # remove addresses and verify
2856 self.nat44_add_address(self.nat_addr, is_add=0)
2857 self.nat44_add_static_mapping(self.pg0.remote_ip4, static_addr,
2860 p = (Ether(src=self.pg1.remote_mac, dst='ff:ff:ff:ff:ff:ff') /
2861 ARP(op=ARP.who_has, pdst=self.nat_addr,
2862 psrc=self.pg1.remote_ip4, hwsrc=self.pg1.remote_mac))
2863 self.pg1.add_stream(p)
2864 self.pg_enable_capture(self.pg_interfaces)
2866 self.pg1.assert_nothing_captured()
2868 p = (Ether(src=self.pg1.remote_mac, dst='ff:ff:ff:ff:ff:ff') /
2869 ARP(op=ARP.who_has, pdst=static_addr,
2870 psrc=self.pg1.remote_ip4, hwsrc=self.pg1.remote_mac))
2871 self.pg1.add_stream(p)
2872 self.pg_enable_capture(self.pg_interfaces)
2874 self.pg1.assert_nothing_captured()
2876 def test_vrf_mode(self):
2877 """ NAT44 tenant VRF aware address pool mode """
2881 nat_ip1 = "10.0.0.10"
2882 nat_ip2 = "10.0.0.11"
2884 self.pg0.unconfig_ip4()
2885 self.pg1.unconfig_ip4()
2886 self.vapi.ip_table_add_del(vrf_id1, is_add=1)
2887 self.vapi.ip_table_add_del(vrf_id2, is_add=1)
2888 self.pg0.set_table_ip4(vrf_id1)
2889 self.pg1.set_table_ip4(vrf_id2)
2890 self.pg0.config_ip4()
2891 self.pg1.config_ip4()
2892 self.pg0.resolve_arp()
2893 self.pg1.resolve_arp()
2895 self.nat44_add_address(nat_ip1, vrf_id=vrf_id1)
2896 self.nat44_add_address(nat_ip2, vrf_id=vrf_id2)
2897 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
2898 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index)
2899 self.vapi.nat44_interface_add_del_feature(self.pg2.sw_if_index,
2904 pkts = self.create_stream_in(self.pg0, self.pg2)
2905 self.pg0.add_stream(pkts)
2906 self.pg_enable_capture(self.pg_interfaces)
2908 capture = self.pg2.get_capture(len(pkts))
2909 self.verify_capture_out(capture, nat_ip1)
2912 pkts = self.create_stream_in(self.pg1, self.pg2)
2913 self.pg1.add_stream(pkts)
2914 self.pg_enable_capture(self.pg_interfaces)
2916 capture = self.pg2.get_capture(len(pkts))
2917 self.verify_capture_out(capture, nat_ip2)
2920 self.pg0.unconfig_ip4()
2921 self.pg1.unconfig_ip4()
2922 self.pg0.set_table_ip4(0)
2923 self.pg1.set_table_ip4(0)
2924 self.pg0.config_ip4()
2925 self.pg1.config_ip4()
2926 self.pg0.resolve_arp()
2927 self.pg1.resolve_arp()
2928 self.vapi.ip_table_add_del(vrf_id1, is_add=0)
2929 self.vapi.ip_table_add_del(vrf_id2, is_add=0)
2931 def test_vrf_feature_independent(self):
2932 """ NAT44 tenant VRF independent address pool mode """
2934 nat_ip1 = "10.0.0.10"
2935 nat_ip2 = "10.0.0.11"
2937 self.nat44_add_address(nat_ip1)
2938 self.nat44_add_address(nat_ip2, vrf_id=99)
2939 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
2940 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index)
2941 self.vapi.nat44_interface_add_del_feature(self.pg2.sw_if_index,
2945 pkts = self.create_stream_in(self.pg0, self.pg2)
2946 self.pg0.add_stream(pkts)
2947 self.pg_enable_capture(self.pg_interfaces)
2949 capture = self.pg2.get_capture(len(pkts))
2950 self.verify_capture_out(capture, nat_ip1)
2953 pkts = self.create_stream_in(self.pg1, self.pg2)
2954 self.pg1.add_stream(pkts)
2955 self.pg_enable_capture(self.pg_interfaces)
2957 capture = self.pg2.get_capture(len(pkts))
2958 self.verify_capture_out(capture, nat_ip1)
2960 def test_dynamic_ipless_interfaces(self):
2961 """ NAT44 interfaces without configured IP address """
2963 self.vapi.ip_neighbor_add_del(self.pg7.sw_if_index,
2964 mac_pton(self.pg7.remote_mac),
2965 self.pg7.remote_ip4n,
2967 self.vapi.ip_neighbor_add_del(self.pg8.sw_if_index,
2968 mac_pton(self.pg8.remote_mac),
2969 self.pg8.remote_ip4n,
2972 self.vapi.ip_add_del_route(dst_address=self.pg7.remote_ip4n,
2973 dst_address_length=32,
2974 next_hop_address=self.pg7.remote_ip4n,
2975 next_hop_sw_if_index=self.pg7.sw_if_index)
2976 self.vapi.ip_add_del_route(dst_address=self.pg8.remote_ip4n,
2977 dst_address_length=32,
2978 next_hop_address=self.pg8.remote_ip4n,
2979 next_hop_sw_if_index=self.pg8.sw_if_index)
2981 self.nat44_add_address(self.nat_addr)
2982 self.vapi.nat44_interface_add_del_feature(self.pg7.sw_if_index)
2983 self.vapi.nat44_interface_add_del_feature(self.pg8.sw_if_index,
2987 pkts = self.create_stream_in(self.pg7, self.pg8)
2988 self.pg7.add_stream(pkts)
2989 self.pg_enable_capture(self.pg_interfaces)
2991 capture = self.pg8.get_capture(len(pkts))
2992 self.verify_capture_out(capture)
2995 pkts = self.create_stream_out(self.pg8, self.nat_addr)
2996 self.pg8.add_stream(pkts)
2997 self.pg_enable_capture(self.pg_interfaces)
2999 capture = self.pg7.get_capture(len(pkts))
3000 self.verify_capture_in(capture, self.pg7)
3002 def test_static_ipless_interfaces(self):
3003 """ NAT44 interfaces without configured IP address - 1:1 NAT """
3005 self.vapi.ip_neighbor_add_del(self.pg7.sw_if_index,
3006 mac_pton(self.pg7.remote_mac),
3007 self.pg7.remote_ip4n,
3009 self.vapi.ip_neighbor_add_del(self.pg8.sw_if_index,
3010 mac_pton(self.pg8.remote_mac),
3011 self.pg8.remote_ip4n,
3014 self.vapi.ip_add_del_route(dst_address=self.pg7.remote_ip4n,
3015 dst_address_length=32,
3016 next_hop_address=self.pg7.remote_ip4n,
3017 next_hop_sw_if_index=self.pg7.sw_if_index)
3018 self.vapi.ip_add_del_route(dst_address=self.pg8.remote_ip4n,
3019 dst_address_length=32,
3020 next_hop_address=self.pg8.remote_ip4n,
3021 next_hop_sw_if_index=self.pg8.sw_if_index)
3023 self.nat44_add_static_mapping(self.pg7.remote_ip4, self.nat_addr)
3024 self.vapi.nat44_interface_add_del_feature(self.pg7.sw_if_index)
3025 self.vapi.nat44_interface_add_del_feature(self.pg8.sw_if_index,
3029 pkts = self.create_stream_out(self.pg8)
3030 self.pg8.add_stream(pkts)
3031 self.pg_enable_capture(self.pg_interfaces)
3033 capture = self.pg7.get_capture(len(pkts))
3034 self.verify_capture_in(capture, self.pg7)
3037 pkts = self.create_stream_in(self.pg7, self.pg8)
3038 self.pg7.add_stream(pkts)
3039 self.pg_enable_capture(self.pg_interfaces)
3041 capture = self.pg8.get_capture(len(pkts))
3042 self.verify_capture_out(capture, self.nat_addr, True)
3044 def test_static_with_port_ipless_interfaces(self):
3045 """ NAT44 interfaces without configured IP address - 1:1 NAPT """
3047 self.tcp_port_out = 30606
3048 self.udp_port_out = 30607
3049 self.icmp_id_out = 30608
3051 self.vapi.ip_neighbor_add_del(self.pg7.sw_if_index,
3052 mac_pton(self.pg7.remote_mac),
3053 self.pg7.remote_ip4n,
3055 self.vapi.ip_neighbor_add_del(self.pg8.sw_if_index,
3056 mac_pton(self.pg8.remote_mac),
3057 self.pg8.remote_ip4n,
3060 self.vapi.ip_add_del_route(dst_address=self.pg7.remote_ip4n,
3061 dst_address_length=32,
3062 next_hop_address=self.pg7.remote_ip4n,
3063 next_hop_sw_if_index=self.pg7.sw_if_index)
3064 self.vapi.ip_add_del_route(dst_address=self.pg8.remote_ip4n,
3065 dst_address_length=32,
3066 next_hop_address=self.pg8.remote_ip4n,
3067 next_hop_sw_if_index=self.pg8.sw_if_index)
3069 self.nat44_add_address(self.nat_addr)
3070 self.nat44_add_static_mapping(self.pg7.remote_ip4, self.nat_addr,
3071 self.tcp_port_in, self.tcp_port_out,
3072 proto=IP_PROTOS.tcp)
3073 self.nat44_add_static_mapping(self.pg7.remote_ip4, self.nat_addr,
3074 self.udp_port_in, self.udp_port_out,
3075 proto=IP_PROTOS.udp)
3076 self.nat44_add_static_mapping(self.pg7.remote_ip4, self.nat_addr,
3077 self.icmp_id_in, self.icmp_id_out,
3078 proto=IP_PROTOS.icmp)
3079 self.vapi.nat44_interface_add_del_feature(self.pg7.sw_if_index)
3080 self.vapi.nat44_interface_add_del_feature(self.pg8.sw_if_index,
3084 pkts = self.create_stream_out(self.pg8)
3085 self.pg8.add_stream(pkts)
3086 self.pg_enable_capture(self.pg_interfaces)
3088 capture = self.pg7.get_capture(len(pkts))
3089 self.verify_capture_in(capture, self.pg7)
3092 pkts = self.create_stream_in(self.pg7, self.pg8)
3093 self.pg7.add_stream(pkts)
3094 self.pg_enable_capture(self.pg_interfaces)
3096 capture = self.pg8.get_capture(len(pkts))
3097 self.verify_capture_out(capture)
3099 def test_static_unknown_proto(self):
3100 """ 1:1 NAT translate packet with unknown protocol """
3101 nat_ip = "10.0.0.10"
3102 self.nat44_add_static_mapping(self.pg0.remote_ip4, nat_ip)
3103 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
3104 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
3108 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
3109 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
3111 IP(src=self.pg2.remote_ip4, dst=self.pg3.remote_ip4) /
3112 TCP(sport=1234, dport=1234))
3113 self.pg0.add_stream(p)
3114 self.pg_enable_capture(self.pg_interfaces)
3116 p = self.pg1.get_capture(1)
3119 self.assertEqual(packet[IP].src, nat_ip)
3120 self.assertEqual(packet[IP].dst, self.pg1.remote_ip4)
3121 self.assertEqual(packet.haslayer(GRE), 1)
3122 self.assert_packet_checksums_valid(packet)
3124 self.logger.error(ppp("Unexpected or invalid packet:", packet))
3128 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
3129 IP(src=self.pg1.remote_ip4, dst=nat_ip) /
3131 IP(src=self.pg3.remote_ip4, dst=self.pg2.remote_ip4) /
3132 TCP(sport=1234, dport=1234))
3133 self.pg1.add_stream(p)
3134 self.pg_enable_capture(self.pg_interfaces)
3136 p = self.pg0.get_capture(1)
3139 self.assertEqual(packet[IP].src, self.pg1.remote_ip4)
3140 self.assertEqual(packet[IP].dst, self.pg0.remote_ip4)
3141 self.assertEqual(packet.haslayer(GRE), 1)
3142 self.assert_packet_checksums_valid(packet)
3144 self.logger.error(ppp("Unexpected or invalid packet:", packet))
3147 def test_hairpinning_static_unknown_proto(self):
3148 """ 1:1 NAT translate packet with unknown protocol - hairpinning """
3150 host = self.pg0.remote_hosts[0]
3151 server = self.pg0.remote_hosts[1]
3153 host_nat_ip = "10.0.0.10"
3154 server_nat_ip = "10.0.0.11"
3156 self.nat44_add_static_mapping(host.ip4, host_nat_ip)
3157 self.nat44_add_static_mapping(server.ip4, server_nat_ip)
3158 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
3159 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
3163 p = (Ether(dst=self.pg0.local_mac, src=host.mac) /
3164 IP(src=host.ip4, dst=server_nat_ip) /
3166 IP(src=self.pg2.remote_ip4, dst=self.pg3.remote_ip4) /
3167 TCP(sport=1234, dport=1234))
3168 self.pg0.add_stream(p)
3169 self.pg_enable_capture(self.pg_interfaces)
3171 p = self.pg0.get_capture(1)
3174 self.assertEqual(packet[IP].src, host_nat_ip)
3175 self.assertEqual(packet[IP].dst, server.ip4)
3176 self.assertEqual(packet.haslayer(GRE), 1)
3177 self.assert_packet_checksums_valid(packet)
3179 self.logger.error(ppp("Unexpected or invalid packet:", packet))
3183 p = (Ether(dst=self.pg0.local_mac, src=server.mac) /
3184 IP(src=server.ip4, dst=host_nat_ip) /
3186 IP(src=self.pg3.remote_ip4, dst=self.pg2.remote_ip4) /
3187 TCP(sport=1234, dport=1234))
3188 self.pg0.add_stream(p)
3189 self.pg_enable_capture(self.pg_interfaces)
3191 p = self.pg0.get_capture(1)
3194 self.assertEqual(packet[IP].src, server_nat_ip)
3195 self.assertEqual(packet[IP].dst, host.ip4)
3196 self.assertEqual(packet.haslayer(GRE), 1)
3197 self.assert_packet_checksums_valid(packet)
3199 self.logger.error(ppp("Unexpected or invalid packet:", packet))
3202 def test_output_feature(self):
3203 """ NAT44 interface output feature (in2out postrouting) """
3204 self.nat44_add_address(self.nat_addr)
3205 self.vapi.nat44_interface_add_del_output_feature(self.pg0.sw_if_index)
3206 self.vapi.nat44_interface_add_del_output_feature(self.pg1.sw_if_index)
3207 self.vapi.nat44_interface_add_del_output_feature(self.pg3.sw_if_index,
3211 pkts = self.create_stream_in(self.pg0, self.pg3)
3212 self.pg0.add_stream(pkts)
3213 self.pg_enable_capture(self.pg_interfaces)
3215 capture = self.pg3.get_capture(len(pkts))
3216 self.verify_capture_out(capture)
3219 pkts = self.create_stream_out(self.pg3)
3220 self.pg3.add_stream(pkts)
3221 self.pg_enable_capture(self.pg_interfaces)
3223 capture = self.pg0.get_capture(len(pkts))
3224 self.verify_capture_in(capture, self.pg0)
3226 # from non-NAT interface to NAT inside interface
3227 pkts = self.create_stream_in(self.pg2, self.pg0)
3228 self.pg2.add_stream(pkts)
3229 self.pg_enable_capture(self.pg_interfaces)
3231 capture = self.pg0.get_capture(len(pkts))
3232 self.verify_capture_no_translation(capture, self.pg2, self.pg0)
3234 def test_output_feature_vrf_aware(self):
3235 """ NAT44 interface output feature VRF aware (in2out postrouting) """
3236 nat_ip_vrf10 = "10.0.0.10"
3237 nat_ip_vrf20 = "10.0.0.20"
3239 self.vapi.ip_add_del_route(dst_address=self.pg3.remote_ip4n,
3240 dst_address_length=32,
3241 next_hop_address=self.pg3.remote_ip4n,
3242 next_hop_sw_if_index=self.pg3.sw_if_index,
3244 self.vapi.ip_add_del_route(dst_address=self.pg3.remote_ip4n,
3245 dst_address_length=32,
3246 next_hop_address=self.pg3.remote_ip4n,
3247 next_hop_sw_if_index=self.pg3.sw_if_index,
3250 self.nat44_add_address(nat_ip_vrf10, vrf_id=10)
3251 self.nat44_add_address(nat_ip_vrf20, vrf_id=20)
3252 self.vapi.nat44_interface_add_del_output_feature(self.pg4.sw_if_index)
3253 self.vapi.nat44_interface_add_del_output_feature(self.pg6.sw_if_index)
3254 self.vapi.nat44_interface_add_del_output_feature(self.pg3.sw_if_index,
3258 pkts = self.create_stream_in(self.pg4, self.pg3)
3259 self.pg4.add_stream(pkts)
3260 self.pg_enable_capture(self.pg_interfaces)
3262 capture = self.pg3.get_capture(len(pkts))
3263 self.verify_capture_out(capture, nat_ip=nat_ip_vrf10)
3266 pkts = self.create_stream_out(self.pg3, dst_ip=nat_ip_vrf10)
3267 self.pg3.add_stream(pkts)
3268 self.pg_enable_capture(self.pg_interfaces)
3270 capture = self.pg4.get_capture(len(pkts))
3271 self.verify_capture_in(capture, self.pg4)
3274 pkts = self.create_stream_in(self.pg6, self.pg3)
3275 self.pg6.add_stream(pkts)
3276 self.pg_enable_capture(self.pg_interfaces)
3278 capture = self.pg3.get_capture(len(pkts))
3279 self.verify_capture_out(capture, nat_ip=nat_ip_vrf20)
3282 pkts = self.create_stream_out(self.pg3, dst_ip=nat_ip_vrf20)
3283 self.pg3.add_stream(pkts)
3284 self.pg_enable_capture(self.pg_interfaces)
3286 capture = self.pg6.get_capture(len(pkts))
3287 self.verify_capture_in(capture, self.pg6)
3289 def test_output_feature_hairpinning(self):
3290 """ NAT44 interface output feature hairpinning (in2out postrouting) """
3291 host = self.pg0.remote_hosts[0]
3292 server = self.pg0.remote_hosts[1]
3295 server_in_port = 5678
3296 server_out_port = 8765
3298 self.nat44_add_address(self.nat_addr)
3299 self.vapi.nat44_interface_add_del_output_feature(self.pg0.sw_if_index)
3300 self.vapi.nat44_interface_add_del_output_feature(self.pg1.sw_if_index,
3303 # add static mapping for server
3304 self.nat44_add_static_mapping(server.ip4, self.nat_addr,
3305 server_in_port, server_out_port,
3306 proto=IP_PROTOS.tcp)
3308 # send packet from host to server
3309 p = (Ether(src=host.mac, dst=self.pg0.local_mac) /
3310 IP(src=host.ip4, dst=self.nat_addr) /
3311 TCP(sport=host_in_port, dport=server_out_port))
3312 self.pg0.add_stream(p)
3313 self.pg_enable_capture(self.pg_interfaces)
3315 capture = self.pg0.get_capture(1)
3320 self.assertEqual(ip.src, self.nat_addr)
3321 self.assertEqual(ip.dst, server.ip4)
3322 self.assertNotEqual(tcp.sport, host_in_port)
3323 self.assertEqual(tcp.dport, server_in_port)
3324 self.assert_packet_checksums_valid(p)
3325 host_out_port = tcp.sport
3327 self.logger.error(ppp("Unexpected or invalid packet:", p))
3330 # send reply from server to host
3331 p = (Ether(src=server.mac, dst=self.pg0.local_mac) /
3332 IP(src=server.ip4, dst=self.nat_addr) /
3333 TCP(sport=server_in_port, dport=host_out_port))
3334 self.pg0.add_stream(p)
3335 self.pg_enable_capture(self.pg_interfaces)
3337 capture = self.pg0.get_capture(1)
3342 self.assertEqual(ip.src, self.nat_addr)
3343 self.assertEqual(ip.dst, host.ip4)
3344 self.assertEqual(tcp.sport, server_out_port)
3345 self.assertEqual(tcp.dport, host_in_port)
3346 self.assert_packet_checksums_valid(p)
3348 self.logger.error(ppp("Unexpected or invalid packet:", p))
3351 def test_one_armed_nat44(self):
3352 """ One armed NAT44 """
3353 remote_host = self.pg9.remote_hosts[0]
3354 local_host = self.pg9.remote_hosts[1]
3357 self.nat44_add_address(self.nat_addr)
3358 self.vapi.nat44_interface_add_del_feature(self.pg9.sw_if_index)
3359 self.vapi.nat44_interface_add_del_feature(self.pg9.sw_if_index,
3363 p = (Ether(src=self.pg9.remote_mac, dst=self.pg9.local_mac) /
3364 IP(src=local_host.ip4, dst=remote_host.ip4) /
3365 TCP(sport=12345, dport=80))
3366 self.pg9.add_stream(p)
3367 self.pg_enable_capture(self.pg_interfaces)
3369 capture = self.pg9.get_capture(1)
3374 self.assertEqual(ip.src, self.nat_addr)
3375 self.assertEqual(ip.dst, remote_host.ip4)
3376 self.assertNotEqual(tcp.sport, 12345)
3377 external_port = tcp.sport
3378 self.assertEqual(tcp.dport, 80)
3379 self.assert_packet_checksums_valid(p)
3381 self.logger.error(ppp("Unexpected or invalid packet:", p))
3385 p = (Ether(src=self.pg9.remote_mac, dst=self.pg9.local_mac) /
3386 IP(src=remote_host.ip4, dst=self.nat_addr) /
3387 TCP(sport=80, dport=external_port))
3388 self.pg9.add_stream(p)
3389 self.pg_enable_capture(self.pg_interfaces)
3391 capture = self.pg9.get_capture(1)
3396 self.assertEqual(ip.src, remote_host.ip4)
3397 self.assertEqual(ip.dst, local_host.ip4)
3398 self.assertEqual(tcp.sport, 80)
3399 self.assertEqual(tcp.dport, 12345)
3400 self.assert_packet_checksums_valid(p)
3402 self.logger.error(ppp("Unexpected or invalid packet:", p))
3405 err = self.statistics.get_counter('/err/nat44-classify/next in2out')
3406 self.assertEqual(err, 1)
3407 err = self.statistics.get_counter('/err/nat44-classify/next out2in')
3408 self.assertEqual(err, 1)
3410 def test_del_session(self):
3411 """ Delete NAT44 session """
3412 self.nat44_add_address(self.nat_addr)
3413 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
3414 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
3417 pkts = self.create_stream_in(self.pg0, self.pg1)
3418 self.pg0.add_stream(pkts)
3419 self.pg_enable_capture(self.pg_interfaces)
3421 self.pg1.get_capture(len(pkts))
3423 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4n, 0)
3424 nsessions = len(sessions)
3426 self.vapi.nat44_del_session(sessions[0].inside_ip_address,
3427 sessions[0].inside_port,
3428 sessions[0].protocol)
3429 self.vapi.nat44_del_session(sessions[1].outside_ip_address,
3430 sessions[1].outside_port,
3431 sessions[1].protocol,
3434 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4n, 0)
3435 self.assertEqual(nsessions - len(sessions), 2)
3437 self.vapi.nat44_del_session(sessions[0].inside_ip_address,
3438 sessions[0].inside_port,
3439 sessions[0].protocol)
3441 self.verify_no_nat44_user()
3443 def test_set_get_reass(self):
3444 """ NAT44 set/get virtual fragmentation reassembly """
3445 reas_cfg1 = self.vapi.nat_get_reass()
3447 self.vapi.nat_set_reass(timeout=reas_cfg1.ip4_timeout + 5,
3448 max_reass=reas_cfg1.ip4_max_reass * 2,
3449 max_frag=reas_cfg1.ip4_max_frag * 2)
3451 reas_cfg2 = self.vapi.nat_get_reass()
3453 self.assertEqual(reas_cfg1.ip4_timeout + 5, reas_cfg2.ip4_timeout)
3454 self.assertEqual(reas_cfg1.ip4_max_reass * 2, reas_cfg2.ip4_max_reass)
3455 self.assertEqual(reas_cfg1.ip4_max_frag * 2, reas_cfg2.ip4_max_frag)
3457 self.vapi.nat_set_reass(drop_frag=1)
3458 self.assertTrue(self.vapi.nat_get_reass().ip4_drop_frag)
3460 def test_frag_in_order(self):
3461 """ NAT44 translate fragments arriving in order """
3463 self.nat44_add_address(self.nat_addr)
3464 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
3465 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
3468 self.frag_in_order(proto=IP_PROTOS.tcp)
3469 self.frag_in_order(proto=IP_PROTOS.udp)
3470 self.frag_in_order(proto=IP_PROTOS.icmp)
3472 def test_frag_forwarding(self):
3473 """ NAT44 forwarding fragment test """
3474 self.vapi.nat44_add_interface_addr(self.pg1.sw_if_index)
3475 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
3476 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
3478 self.vapi.nat44_forwarding_enable_disable(1)
3480 data = "A" * 16 + "B" * 16 + "C" * 3
3481 pkts = self.create_stream_frag(self.pg1,
3482 self.pg0.remote_ip4,
3486 proto=IP_PROTOS.udp)
3487 self.pg1.add_stream(pkts)
3488 self.pg_enable_capture(self.pg_interfaces)
3490 frags = self.pg0.get_capture(len(pkts))
3491 p = self.reass_frags_and_verify(frags,
3492 self.pg1.remote_ip4,
3493 self.pg0.remote_ip4)
3494 self.assertEqual(p[UDP].sport, 4789)
3495 self.assertEqual(p[UDP].dport, 4789)
3496 self.assertEqual(data, p[Raw].load)
3498 def test_reass_hairpinning(self):
3499 """ NAT44 fragments hairpinning """
3501 self.server = self.pg0.remote_hosts[1]
3502 self.host_in_port = random.randint(1025, 65535)
3503 self.server_in_port = random.randint(1025, 65535)
3504 self.server_out_port = random.randint(1025, 65535)
3506 self.nat44_add_address(self.nat_addr)
3507 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
3508 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
3510 # add static mapping for server
3511 self.nat44_add_static_mapping(self.server.ip4, self.nat_addr,
3512 self.server_in_port,
3513 self.server_out_port,
3514 proto=IP_PROTOS.tcp)
3515 self.nat44_add_static_mapping(self.server.ip4, self.nat_addr,
3516 self.server_in_port,
3517 self.server_out_port,
3518 proto=IP_PROTOS.udp)
3519 self.nat44_add_static_mapping(self.server.ip4, self.nat_addr)
3521 self.reass_hairpinning(proto=IP_PROTOS.tcp)
3522 self.reass_hairpinning(proto=IP_PROTOS.udp)
3523 self.reass_hairpinning(proto=IP_PROTOS.icmp)
3525 def test_frag_out_of_order(self):
3526 """ NAT44 translate fragments arriving out of order """
3528 self.nat44_add_address(self.nat_addr)
3529 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
3530 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
3533 self.frag_out_of_order(proto=IP_PROTOS.tcp)
3534 self.frag_out_of_order(proto=IP_PROTOS.udp)
3535 self.frag_out_of_order(proto=IP_PROTOS.icmp)
3537 def test_port_restricted(self):
3538 """ Port restricted NAT44 (MAP-E CE) """
3539 self.nat44_add_address(self.nat_addr)
3540 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
3541 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
3543 self.vapi.nat_set_addr_and_port_alloc_alg(alg=1,
3548 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
3549 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
3550 TCP(sport=4567, dport=22))
3551 self.pg0.add_stream(p)
3552 self.pg_enable_capture(self.pg_interfaces)
3554 capture = self.pg1.get_capture(1)
3559 self.assertEqual(ip.dst, self.pg1.remote_ip4)
3560 self.assertEqual(ip.src, self.nat_addr)
3561 self.assertEqual(tcp.dport, 22)
3562 self.assertNotEqual(tcp.sport, 4567)
3563 self.assertEqual((tcp.sport >> 6) & 63, 10)
3564 self.assert_packet_checksums_valid(p)
3566 self.logger.error(ppp("Unexpected or invalid packet:", p))
3569 def test_port_range(self):
3570 """ External address port range """
3571 self.nat44_add_address(self.nat_addr)
3572 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
3573 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
3575 self.vapi.nat_set_addr_and_port_alloc_alg(alg=2,
3580 for port in range(0, 5):
3581 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
3582 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
3583 TCP(sport=1125 + port))
3585 self.pg0.add_stream(pkts)
3586 self.pg_enable_capture(self.pg_interfaces)
3588 capture = self.pg1.get_capture(3)
3591 self.assertGreaterEqual(tcp.sport, 1025)
3592 self.assertLessEqual(tcp.sport, 1027)
3594 def test_ipfix_max_frags(self):
3595 """ IPFIX logging maximum fragments pending reassembly exceeded """
3596 self.nat44_add_address(self.nat_addr)
3597 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
3598 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
3600 self.vapi.nat_set_reass(max_frag=1)
3601 self.vapi.set_ipfix_exporter(collector_address=self.pg3.remote_ip4n,
3602 src_address=self.pg3.local_ip4n,
3604 template_interval=10)
3605 self.vapi.nat_ipfix(domain_id=self.ipfix_domain_id,
3606 src_port=self.ipfix_src_port)
3608 data = "A" * 4 + "B" * 16 + "C" * 3
3609 self.tcp_port_in = random.randint(1025, 65535)
3610 pkts = self.create_stream_frag(self.pg0,
3611 self.pg1.remote_ip4,
3616 self.pg0.add_stream(pkts)
3617 self.pg_enable_capture(self.pg_interfaces)
3619 self.pg1.assert_nothing_captured()
3621 self.vapi.cli("ipfix flush") # FIXME this should be an API call
3622 capture = self.pg3.get_capture(9)
3623 ipfix = IPFIXDecoder()
3624 # first load template
3626 self.assertTrue(p.haslayer(IPFIX))
3627 self.assertEqual(p[IP].src, self.pg3.local_ip4)
3628 self.assertEqual(p[IP].dst, self.pg3.remote_ip4)
3629 self.assertEqual(p[UDP].sport, self.ipfix_src_port)
3630 self.assertEqual(p[UDP].dport, 4739)
3631 self.assertEqual(p[IPFIX].observationDomainID,
3632 self.ipfix_domain_id)
3633 if p.haslayer(Template):
3634 ipfix.add_template(p.getlayer(Template))
3635 # verify events in data set
3637 if p.haslayer(Data):
3638 data = ipfix.decode_data_set(p.getlayer(Set))
3639 self.verify_ipfix_max_fragments_ip4(data, 1,
3640 self.pg0.remote_ip4n)
3642 def test_multiple_outside_vrf(self):
3643 """ Multiple outside VRF """
3647 self.pg1.unconfig_ip4()
3648 self.pg2.unconfig_ip4()
3649 self.vapi.ip_table_add_del(vrf_id1, is_add=1)
3650 self.vapi.ip_table_add_del(vrf_id2, is_add=1)
3651 self.pg1.set_table_ip4(vrf_id1)
3652 self.pg2.set_table_ip4(vrf_id2)
3653 self.pg1.config_ip4()
3654 self.pg2.config_ip4()
3655 self.pg1.resolve_arp()
3656 self.pg2.resolve_arp()
3658 self.nat44_add_address(self.nat_addr)
3659 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
3660 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
3662 self.vapi.nat44_interface_add_del_feature(self.pg2.sw_if_index,
3667 pkts = self.create_stream_in(self.pg0, self.pg1)
3668 self.pg0.add_stream(pkts)
3669 self.pg_enable_capture(self.pg_interfaces)
3671 capture = self.pg1.get_capture(len(pkts))
3672 self.verify_capture_out(capture, self.nat_addr)
3674 pkts = self.create_stream_out(self.pg1, self.nat_addr)
3675 self.pg1.add_stream(pkts)
3676 self.pg_enable_capture(self.pg_interfaces)
3678 capture = self.pg0.get_capture(len(pkts))
3679 self.verify_capture_in(capture, self.pg0)
3681 self.tcp_port_in = 60303
3682 self.udp_port_in = 60304
3683 self.icmp_id_in = 60305
3686 pkts = self.create_stream_in(self.pg0, self.pg2)
3687 self.pg0.add_stream(pkts)
3688 self.pg_enable_capture(self.pg_interfaces)
3690 capture = self.pg2.get_capture(len(pkts))
3691 self.verify_capture_out(capture, self.nat_addr)
3693 pkts = self.create_stream_out(self.pg2, self.nat_addr)
3694 self.pg2.add_stream(pkts)
3695 self.pg_enable_capture(self.pg_interfaces)
3697 capture = self.pg0.get_capture(len(pkts))
3698 self.verify_capture_in(capture, self.pg0)
3701 self.pg1.unconfig_ip4()
3702 self.pg2.unconfig_ip4()
3703 self.pg1.set_table_ip4(0)
3704 self.pg2.set_table_ip4(0)
3705 self.pg1.config_ip4()
3706 self.pg2.config_ip4()
3707 self.pg1.resolve_arp()
3708 self.pg2.resolve_arp()
3710 @unittest.skipUnless(running_extended_tests, "part of extended tests")
3711 def test_session_timeout(self):
3712 """ NAT44 session timeouts """
3713 self.nat44_add_address(self.nat_addr)
3714 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
3715 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
3717 self.vapi.nat_set_timeouts(udp=5)
3721 for i in range(0, max_sessions):
3722 src = "10.10.%u.%u" % ((i & 0xFF00) >> 8, i & 0xFF)
3723 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
3724 IP(src=src, dst=self.pg1.remote_ip4) /
3725 UDP(sport=1025, dport=53))
3727 self.pg0.add_stream(pkts)
3728 self.pg_enable_capture(self.pg_interfaces)
3730 self.pg1.get_capture(max_sessions)
3735 for i in range(0, max_sessions):
3736 src = "10.10.%u.%u" % ((i & 0xFF00) >> 8, i & 0xFF)
3737 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
3738 IP(src=src, dst=self.pg1.remote_ip4) /
3739 UDP(sport=1026, dport=53))
3741 self.pg0.add_stream(pkts)
3742 self.pg_enable_capture(self.pg_interfaces)
3744 self.pg1.get_capture(max_sessions)
3747 users = self.vapi.nat44_user_dump()
3749 nsessions = nsessions + user.nsessions
3750 self.assertLess(nsessions, 2 * max_sessions)
3752 def test_mss_clamping(self):
3753 """ TCP MSS clamping """
3754 self.nat44_add_address(self.nat_addr)
3755 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
3756 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
3759 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
3760 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
3761 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
3762 flags="S", options=[('MSS', 1400)]))
3764 self.vapi.nat_set_mss_clamping(enable=1, mss_value=1000)
3765 self.pg0.add_stream(p)
3766 self.pg_enable_capture(self.pg_interfaces)
3768 capture = self.pg1.get_capture(1)
3769 # Negotiated MSS value greater than configured - changed
3770 self.verify_mss_value(capture[0], 1000)
3772 self.vapi.nat_set_mss_clamping(enable=0)
3773 self.pg0.add_stream(p)
3774 self.pg_enable_capture(self.pg_interfaces)
3776 capture = self.pg1.get_capture(1)
3777 # MSS clamping disabled - negotiated MSS unchanged
3778 self.verify_mss_value(capture[0], 1400)
3780 self.vapi.nat_set_mss_clamping(enable=1, mss_value=1500)
3781 self.pg0.add_stream(p)
3782 self.pg_enable_capture(self.pg_interfaces)
3784 capture = self.pg1.get_capture(1)
3785 # Negotiated MSS value smaller than configured - unchanged
3786 self.verify_mss_value(capture[0], 1400)
3789 super(TestNAT44, self).tearDown()
3790 if not self.vpp_dead:
3791 self.logger.info(self.vapi.cli("show nat44 addresses"))
3792 self.logger.info(self.vapi.cli("show nat44 interfaces"))
3793 self.logger.info(self.vapi.cli("show nat44 static mappings"))
3794 self.logger.info(self.vapi.cli("show nat44 interface address"))
3795 self.logger.info(self.vapi.cli("show nat44 sessions detail"))
3796 self.logger.info(self.vapi.cli("show nat virtual-reassembly"))
3797 self.logger.info(self.vapi.cli("show nat44 hash tables detail"))
3798 self.logger.info(self.vapi.cli("show nat timeouts"))
3800 self.vapi.cli("show nat addr-port-assignment-alg"))
3802 self.vapi.cli("clear logging")
3805 class TestNAT44EndpointDependent(MethodHolder):
3806 """ Endpoint-Dependent mapping and filtering test cases """
3809 def setUpConstants(cls):
3810 super(TestNAT44EndpointDependent, cls).setUpConstants()
3811 cls.vpp_cmdline.extend(["nat", "{", "endpoint-dependent", "}"])
3814 def setUpClass(cls):
3815 super(TestNAT44EndpointDependent, cls).setUpClass()
3816 cls.vapi.cli("set log class nat level debug")
3818 cls.tcp_port_in = 6303
3819 cls.tcp_port_out = 6303
3820 cls.udp_port_in = 6304
3821 cls.udp_port_out = 6304
3822 cls.icmp_id_in = 6305
3823 cls.icmp_id_out = 6305
3824 cls.nat_addr = '10.0.0.3'
3825 cls.nat_addr_n = socket.inet_pton(socket.AF_INET, cls.nat_addr)
3826 cls.ipfix_src_port = 4739
3827 cls.ipfix_domain_id = 1
3828 cls.tcp_external_port = 80
3830 cls.create_pg_interfaces(range(7))
3831 cls.interfaces = list(cls.pg_interfaces[0:3])
3833 for i in cls.interfaces:
3838 cls.pg0.generate_remote_hosts(3)
3839 cls.pg0.configure_ipv4_neighbors()
3843 cls.pg4.generate_remote_hosts(2)
3844 cls.pg4.config_ip4()
3845 ip_addr_n = socket.inet_pton(socket.AF_INET, "10.0.0.1")
3846 cls.vapi.sw_interface_add_del_address(cls.pg4.sw_if_index,
3850 cls.pg4.resolve_arp()
3851 cls.pg4._remote_hosts[1]._ip4 = cls.pg4._remote_hosts[0]._ip4
3852 cls.pg4.resolve_arp()
3854 zero_ip4n = socket.inet_pton(socket.AF_INET, "0.0.0.0")
3855 cls.vapi.ip_table_add_del(1, is_add=1)
3857 cls.pg5._local_ip4 = "10.1.1.1"
3858 cls.pg5._local_ip4n = socket.inet_pton(socket.AF_INET,
3860 cls.pg5._remote_hosts[0]._ip4 = "10.1.1.2"
3861 cls.pg5._remote_hosts[0]._ip4n = socket.inet_pton(
3862 socket.AF_INET, cls.pg5.remote_ip4)
3863 cls.pg5.set_table_ip4(1)
3864 cls.pg5.config_ip4()
3866 cls.vapi.ip_add_del_route(dst_address=cls.pg5.remote_ip4n,
3867 dst_address_length=32,
3869 next_hop_sw_if_index=cls.pg5.sw_if_index,
3870 next_hop_address=zero_ip4n)
3872 cls.pg6._local_ip4 = "10.1.2.1"
3873 cls.pg6._local_ip4n = socket.inet_pton(socket.AF_INET,
3875 cls.pg6._remote_hosts[0]._ip4 = "10.1.2.2"
3876 cls.pg6._remote_hosts[0]._ip4n = socket.inet_pton(
3877 socket.AF_INET, cls.pg6.remote_ip4)
3878 cls.pg6.set_table_ip4(1)
3879 cls.pg6.config_ip4()
3881 cls.vapi.ip_add_del_route(dst_address=cls.pg6.remote_ip4n,
3882 dst_address_length=32,
3884 next_hop_sw_if_index=cls.pg6.sw_if_index,
3885 next_hop_address=zero_ip4n)
3887 cls.vapi.ip_add_del_route(dst_address=cls.pg6.remote_ip4n,
3888 dst_address_length=16,
3889 next_hop_address=zero_ip4n,
3891 next_hop_table_id=1)
3892 cls.vapi.ip_add_del_route(dst_address=zero_ip4n,
3893 dst_address_length=0,
3894 next_hop_address=zero_ip4n,
3896 next_hop_table_id=0)
3897 cls.vapi.ip_add_del_route(dst_address=zero_ip4n,
3898 dst_address_length=0,
3900 next_hop_sw_if_index=cls.pg1.sw_if_index,
3901 next_hop_address=cls.pg1.local_ip4n)
3903 cls.pg5.resolve_arp()
3904 cls.pg6.resolve_arp()
3907 super(TestNAT44EndpointDependent, cls).tearDownClass()
3910 def test_frag_in_order(self):
3911 """ NAT44 translate fragments arriving in order """
3912 self.nat44_add_address(self.nat_addr)
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.frag_in_order(proto=IP_PROTOS.tcp)
3917 self.frag_in_order(proto=IP_PROTOS.udp)
3918 self.frag_in_order(proto=IP_PROTOS.icmp)
3920 def test_frag_in_order_dont_translate(self):
3921 """ NAT44 don't translate fragments arriving in order """
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.vapi.nat44_forwarding_enable_disable(enable=True)
3926 self.frag_in_order(proto=IP_PROTOS.tcp, dont_translate=True)
3928 def test_frag_out_of_order(self):
3929 """ NAT44 translate fragments arriving out of order """
3930 self.nat44_add_address(self.nat_addr)
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.frag_out_of_order(proto=IP_PROTOS.tcp)
3935 self.frag_out_of_order(proto=IP_PROTOS.udp)
3936 self.frag_out_of_order(proto=IP_PROTOS.icmp)
3938 def test_frag_out_of_order_dont_translate(self):
3939 """ NAT44 don't translate fragments arriving out of order """
3940 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
3941 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
3943 self.vapi.nat44_forwarding_enable_disable(enable=True)
3944 self.frag_out_of_order(proto=IP_PROTOS.tcp, dont_translate=True)
3946 def test_frag_in_order_in_plus_out(self):
3947 """ in+out interface fragments in order """
3948 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
3949 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index,
3951 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index)
3952 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
3955 self.server = self.pg1.remote_hosts[0]
3957 self.server_in_addr = self.server.ip4
3958 self.server_out_addr = '11.11.11.11'
3959 self.server_in_port = random.randint(1025, 65535)
3960 self.server_out_port = random.randint(1025, 65535)
3962 self.nat44_add_address(self.server_out_addr)
3964 # add static mappings for server
3965 self.nat44_add_static_mapping(self.server_in_addr,
3966 self.server_out_addr,
3967 self.server_in_port,
3968 self.server_out_port,
3969 proto=IP_PROTOS.tcp)
3970 self.nat44_add_static_mapping(self.server_in_addr,
3971 self.server_out_addr,
3972 self.server_in_port,
3973 self.server_out_port,
3974 proto=IP_PROTOS.udp)
3975 self.nat44_add_static_mapping(self.server_in_addr,
3976 self.server_out_addr,
3977 proto=IP_PROTOS.icmp)
3979 self.vapi.nat_set_reass(timeout=10)
3981 self.frag_in_order_in_plus_out(proto=IP_PROTOS.tcp)
3982 self.frag_in_order_in_plus_out(proto=IP_PROTOS.udp)
3983 self.frag_in_order_in_plus_out(proto=IP_PROTOS.icmp)
3985 def test_frag_out_of_order_in_plus_out(self):
3986 """ in+out interface fragments out of order """
3987 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
3988 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index,
3990 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index)
3991 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
3994 self.server = self.pg1.remote_hosts[0]
3996 self.server_in_addr = self.server.ip4
3997 self.server_out_addr = '11.11.11.11'
3998 self.server_in_port = random.randint(1025, 65535)
3999 self.server_out_port = random.randint(1025, 65535)
4001 self.nat44_add_address(self.server_out_addr)
4003 # add static mappings for server
4004 self.nat44_add_static_mapping(self.server_in_addr,
4005 self.server_out_addr,
4006 self.server_in_port,
4007 self.server_out_port,
4008 proto=IP_PROTOS.tcp)
4009 self.nat44_add_static_mapping(self.server_in_addr,
4010 self.server_out_addr,
4011 self.server_in_port,
4012 self.server_out_port,
4013 proto=IP_PROTOS.udp)
4014 self.nat44_add_static_mapping(self.server_in_addr,
4015 self.server_out_addr,
4016 proto=IP_PROTOS.icmp)
4018 self.vapi.nat_set_reass(timeout=10)
4020 self.frag_out_of_order_in_plus_out(proto=IP_PROTOS.tcp)
4021 self.frag_out_of_order_in_plus_out(proto=IP_PROTOS.udp)
4022 self.frag_out_of_order_in_plus_out(proto=IP_PROTOS.icmp)
4024 def test_reass_hairpinning(self):
4025 """ NAT44 fragments hairpinning """
4026 self.server = self.pg0.remote_hosts[1]
4027 self.host_in_port = random.randint(1025, 65535)
4028 self.server_in_port = random.randint(1025, 65535)
4029 self.server_out_port = random.randint(1025, 65535)
4031 self.nat44_add_address(self.nat_addr)
4032 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
4033 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
4035 # add static mapping for server
4036 self.nat44_add_static_mapping(self.server.ip4, self.nat_addr,
4037 self.server_in_port,
4038 self.server_out_port,
4039 proto=IP_PROTOS.tcp)
4040 self.nat44_add_static_mapping(self.server.ip4, self.nat_addr,
4041 self.server_in_port,
4042 self.server_out_port,
4043 proto=IP_PROTOS.udp)
4044 self.nat44_add_static_mapping(self.server.ip4, self.nat_addr)
4046 self.reass_hairpinning(proto=IP_PROTOS.tcp)
4047 self.reass_hairpinning(proto=IP_PROTOS.udp)
4048 self.reass_hairpinning(proto=IP_PROTOS.icmp)
4050 def test_dynamic(self):
4051 """ NAT44 dynamic translation test """
4053 self.nat44_add_address(self.nat_addr)
4054 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
4055 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
4058 nat_config = self.vapi.nat_show_config()
4059 self.assertEqual(1, nat_config.endpoint_dependent)
4062 tcpn = self.statistics.get_counter(
4063 '/err/nat44-ed-in2out-slowpath/TCP packets')
4064 udpn = self.statistics.get_counter(
4065 '/err/nat44-ed-in2out-slowpath/UDP packets')
4066 icmpn = self.statistics.get_counter(
4067 '/err/nat44-ed-in2out-slowpath/ICMP packets')
4068 totaln = self.statistics.get_counter(
4069 '/err/nat44-ed-in2out-slowpath/good in2out packets processed')
4071 pkts = self.create_stream_in(self.pg0, self.pg1)
4072 self.pg0.add_stream(pkts)
4073 self.pg_enable_capture(self.pg_interfaces)
4075 capture = self.pg1.get_capture(len(pkts))
4076 self.verify_capture_out(capture)
4078 err = self.statistics.get_counter(
4079 '/err/nat44-ed-in2out-slowpath/TCP packets')
4080 self.assertEqual(err - tcpn, 1)
4081 err = self.statistics.get_counter(
4082 '/err/nat44-ed-in2out-slowpath/UDP packets')
4083 self.assertEqual(err - udpn, 1)
4084 err = self.statistics.get_counter(
4085 '/err/nat44-ed-in2out-slowpath/ICMP packets')
4086 self.assertEqual(err - icmpn, 1)
4087 err = self.statistics.get_counter(
4088 '/err/nat44-ed-in2out-slowpath/good in2out packets processed')
4089 self.assertEqual(err - totaln, 3)
4092 tcpn = self.statistics.get_counter('/err/nat44-ed-out2in/TCP packets')
4093 udpn = self.statistics.get_counter('/err/nat44-ed-out2in/UDP packets')
4094 icmpn = self.statistics.get_counter(
4095 '/err/nat44-ed-out2in-slowpath/ICMP packets')
4096 totaln = self.statistics.get_counter(
4097 '/err/nat44-ed-out2in/good out2in packets processed')
4099 pkts = self.create_stream_out(self.pg1)
4100 self.pg1.add_stream(pkts)
4101 self.pg_enable_capture(self.pg_interfaces)
4103 capture = self.pg0.get_capture(len(pkts))
4104 self.verify_capture_in(capture, self.pg0)
4106 err = self.statistics.get_counter('/err/nat44-ed-out2in/TCP packets')
4107 self.assertEqual(err - tcpn, 1)
4108 err = self.statistics.get_counter('/err/nat44-ed-out2in/UDP packets')
4109 self.assertEqual(err - udpn, 1)
4110 err = self.statistics.get_counter(
4111 '/err/nat44-ed-out2in-slowpath/ICMP packets')
4112 self.assertEqual(err - icmpn, 1)
4113 err = self.statistics.get_counter(
4114 '/err/nat44-ed-out2in/good out2in packets processed')
4115 self.assertEqual(err - totaln, 2)
4117 users = self.statistics.get_counter('/nat44/total-users')
4118 self.assertEqual(users[0][0], 1)
4119 sessions = self.statistics.get_counter('/nat44/total-sessions')
4120 self.assertEqual(sessions[0][0], 3)
4122 def test_forwarding(self):
4123 """ NAT44 forwarding test """
4125 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
4126 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
4128 self.vapi.nat44_forwarding_enable_disable(1)
4130 real_ip = self.pg0.remote_ip4n
4131 alias_ip = self.nat_addr_n
4132 self.vapi.nat44_add_del_static_mapping(local_ip=real_ip,
4133 external_ip=alias_ip)
4136 # in2out - static mapping match
4138 pkts = self.create_stream_out(self.pg1)
4139 self.pg1.add_stream(pkts)
4140 self.pg_enable_capture(self.pg_interfaces)
4142 capture = self.pg0.get_capture(len(pkts))
4143 self.verify_capture_in(capture, self.pg0)
4145 pkts = self.create_stream_in(self.pg0, self.pg1)
4146 self.pg0.add_stream(pkts)
4147 self.pg_enable_capture(self.pg_interfaces)
4149 capture = self.pg1.get_capture(len(pkts))
4150 self.verify_capture_out(capture, same_port=True)
4152 # in2out - no static mapping match
4154 host0 = self.pg0.remote_hosts[0]
4155 self.pg0.remote_hosts[0] = self.pg0.remote_hosts[1]
4157 pkts = self.create_stream_out(self.pg1,
4158 dst_ip=self.pg0.remote_ip4,
4159 use_inside_ports=True)
4160 self.pg1.add_stream(pkts)
4161 self.pg_enable_capture(self.pg_interfaces)
4163 capture = self.pg0.get_capture(len(pkts))
4164 self.verify_capture_in(capture, self.pg0)
4166 pkts = self.create_stream_in(self.pg0, self.pg1)
4167 self.pg0.add_stream(pkts)
4168 self.pg_enable_capture(self.pg_interfaces)
4170 capture = self.pg1.get_capture(len(pkts))
4171 self.verify_capture_out(capture, nat_ip=self.pg0.remote_ip4,
4174 self.pg0.remote_hosts[0] = host0
4176 user = self.pg0.remote_hosts[1]
4177 sessions = self.vapi.nat44_user_session_dump(user.ip4n, 0)
4178 self.assertEqual(len(sessions), 3)
4179 self.assertTrue(sessions[0].ext_host_valid)
4180 self.vapi.nat44_del_session(
4181 sessions[0].inside_ip_address,
4182 sessions[0].inside_port,
4183 sessions[0].protocol,
4184 ext_host_address=sessions[0].ext_host_address,
4185 ext_host_port=sessions[0].ext_host_port)
4186 sessions = self.vapi.nat44_user_session_dump(user.ip4n, 0)
4187 self.assertEqual(len(sessions), 2)
4190 self.vapi.nat44_forwarding_enable_disable(0)
4191 self.vapi.nat44_add_del_static_mapping(local_ip=real_ip,
4192 external_ip=alias_ip,
4195 def test_static_lb(self):
4196 """ NAT44 local service load balancing """
4197 external_addr_n = socket.inet_pton(socket.AF_INET, self.nat_addr)
4200 server1 = self.pg0.remote_hosts[0]
4201 server2 = self.pg0.remote_hosts[1]
4203 locals = [{'addr': server1.ip4n,
4207 {'addr': server2.ip4n,
4212 self.nat44_add_address(self.nat_addr)
4213 self.vapi.nat44_add_del_lb_static_mapping(external_addr_n,
4216 local_num=len(locals),
4218 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
4219 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
4222 # from client to service
4223 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
4224 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
4225 TCP(sport=12345, dport=external_port))
4226 self.pg1.add_stream(p)
4227 self.pg_enable_capture(self.pg_interfaces)
4229 capture = self.pg0.get_capture(1)
4235 self.assertIn(ip.dst, [server1.ip4, server2.ip4])
4236 if ip.dst == server1.ip4:
4240 self.assertEqual(tcp.dport, local_port)
4241 self.assert_packet_checksums_valid(p)
4243 self.logger.error(ppp("Unexpected or invalid packet:", p))
4246 # from service back to client
4247 p = (Ether(src=server.mac, dst=self.pg0.local_mac) /
4248 IP(src=server.ip4, dst=self.pg1.remote_ip4) /
4249 TCP(sport=local_port, dport=12345))
4250 self.pg0.add_stream(p)
4251 self.pg_enable_capture(self.pg_interfaces)
4253 capture = self.pg1.get_capture(1)
4258 self.assertEqual(ip.src, self.nat_addr)
4259 self.assertEqual(tcp.sport, external_port)
4260 self.assert_packet_checksums_valid(p)
4262 self.logger.error(ppp("Unexpected or invalid packet:", p))
4265 sessions = self.vapi.nat44_user_session_dump(server.ip4n, 0)
4266 self.assertEqual(len(sessions), 1)
4267 self.assertTrue(sessions[0].ext_host_valid)
4268 self.vapi.nat44_del_session(
4269 sessions[0].inside_ip_address,
4270 sessions[0].inside_port,
4271 sessions[0].protocol,
4272 ext_host_address=sessions[0].ext_host_address,
4273 ext_host_port=sessions[0].ext_host_port)
4274 sessions = self.vapi.nat44_user_session_dump(server.ip4n, 0)
4275 self.assertEqual(len(sessions), 0)
4277 @unittest.skipUnless(running_extended_tests, "part of extended tests")
4278 def test_static_lb_multi_clients(self):
4279 """ NAT44 local service load balancing - multiple clients"""
4281 external_addr_n = socket.inet_pton(socket.AF_INET, self.nat_addr)
4284 server1 = self.pg0.remote_hosts[0]
4285 server2 = self.pg0.remote_hosts[1]
4286 server3 = self.pg0.remote_hosts[2]
4288 locals = [{'addr': server1.ip4n,
4292 {'addr': server2.ip4n,
4297 self.nat44_add_address(self.nat_addr)
4298 self.vapi.nat44_add_del_lb_static_mapping(external_addr_n,
4301 local_num=len(locals),
4303 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
4304 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
4309 clients = ip4_range(self.pg1.remote_ip4, 10, 50)
4311 for client in clients:
4312 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
4313 IP(src=client, dst=self.nat_addr) /
4314 TCP(sport=12345, dport=external_port))
4316 self.pg1.add_stream(pkts)
4317 self.pg_enable_capture(self.pg_interfaces)
4319 capture = self.pg0.get_capture(len(pkts))
4321 if p[IP].dst == server1.ip4:
4325 self.assertGreater(server1_n, server2_n)
4328 self.vapi.nat44_lb_static_mapping_add_del_local(external_addr_n,
4337 clients = ip4_range(self.pg1.remote_ip4, 60, 110)
4339 for client in clients:
4340 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
4341 IP(src=client, dst=self.nat_addr) /
4342 TCP(sport=12346, dport=external_port))
4344 self.assertGreater(len(pkts), 0)
4345 self.pg1.add_stream(pkts)
4346 self.pg_enable_capture(self.pg_interfaces)
4348 capture = self.pg0.get_capture(len(pkts))
4350 if p[IP].dst == server1.ip4:
4352 elif p[IP].dst == server2.ip4:
4356 self.assertGreater(server1_n, 0)
4357 self.assertGreater(server2_n, 0)
4358 self.assertGreater(server3_n, 0)
4360 # remove one back-end
4361 self.vapi.nat44_lb_static_mapping_add_del_local(external_addr_n,
4371 self.pg1.add_stream(pkts)
4372 self.pg_enable_capture(self.pg_interfaces)
4374 capture = self.pg0.get_capture(len(pkts))
4376 if p[IP].dst == server1.ip4:
4378 elif p[IP].dst == server2.ip4:
4382 self.assertGreater(server1_n, 0)
4383 self.assertEqual(server2_n, 0)
4384 self.assertGreater(server3_n, 0)
4386 def test_static_lb_2(self):
4387 """ NAT44 local service load balancing (asymmetrical rule) """
4388 external_addr_n = socket.inet_pton(socket.AF_INET, self.nat_addr)
4391 server1 = self.pg0.remote_hosts[0]
4392 server2 = self.pg0.remote_hosts[1]
4394 locals = [{'addr': server1.ip4n,
4398 {'addr': server2.ip4n,
4403 self.vapi.nat44_forwarding_enable_disable(1)
4404 self.vapi.nat44_add_del_lb_static_mapping(external_addr_n,
4408 local_num=len(locals),
4410 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
4411 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
4414 # from client to service
4415 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
4416 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
4417 TCP(sport=12345, dport=external_port))
4418 self.pg1.add_stream(p)
4419 self.pg_enable_capture(self.pg_interfaces)
4421 capture = self.pg0.get_capture(1)
4427 self.assertIn(ip.dst, [server1.ip4, server2.ip4])
4428 if ip.dst == server1.ip4:
4432 self.assertEqual(tcp.dport, local_port)
4433 self.assert_packet_checksums_valid(p)
4435 self.logger.error(ppp("Unexpected or invalid packet:", p))
4438 # from service back to client
4439 p = (Ether(src=server.mac, dst=self.pg0.local_mac) /
4440 IP(src=server.ip4, dst=self.pg1.remote_ip4) /
4441 TCP(sport=local_port, dport=12345))
4442 self.pg0.add_stream(p)
4443 self.pg_enable_capture(self.pg_interfaces)
4445 capture = self.pg1.get_capture(1)
4450 self.assertEqual(ip.src, self.nat_addr)
4451 self.assertEqual(tcp.sport, external_port)
4452 self.assert_packet_checksums_valid(p)
4454 self.logger.error(ppp("Unexpected or invalid packet:", p))
4457 # from client to server (no translation)
4458 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
4459 IP(src=self.pg1.remote_ip4, dst=server1.ip4) /
4460 TCP(sport=12346, dport=local_port))
4461 self.pg1.add_stream(p)
4462 self.pg_enable_capture(self.pg_interfaces)
4464 capture = self.pg0.get_capture(1)
4470 self.assertEqual(ip.dst, server1.ip4)
4471 self.assertEqual(tcp.dport, local_port)
4472 self.assert_packet_checksums_valid(p)
4474 self.logger.error(ppp("Unexpected or invalid packet:", p))
4477 # from service back to client (no translation)
4478 p = (Ether(src=server1.mac, dst=self.pg0.local_mac) /
4479 IP(src=server1.ip4, dst=self.pg1.remote_ip4) /
4480 TCP(sport=local_port, dport=12346))
4481 self.pg0.add_stream(p)
4482 self.pg_enable_capture(self.pg_interfaces)
4484 capture = self.pg1.get_capture(1)
4489 self.assertEqual(ip.src, server1.ip4)
4490 self.assertEqual(tcp.sport, local_port)
4491 self.assert_packet_checksums_valid(p)
4493 self.logger.error(ppp("Unexpected or invalid packet:", p))
4496 def test_lb_affinity(self):
4497 """ NAT44 local service load balancing affinity """
4498 external_addr_n = socket.inet_pton(socket.AF_INET, self.nat_addr)
4501 server1 = self.pg0.remote_hosts[0]
4502 server2 = self.pg0.remote_hosts[1]
4504 locals = [{'addr': server1.ip4n,
4508 {'addr': server2.ip4n,
4513 self.nat44_add_address(self.nat_addr)
4514 self.vapi.nat44_add_del_lb_static_mapping(external_addr_n,
4518 local_num=len(locals),
4520 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
4521 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
4524 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
4525 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
4526 TCP(sport=1025, dport=external_port))
4527 self.pg1.add_stream(p)
4528 self.pg_enable_capture(self.pg_interfaces)
4530 capture = self.pg0.get_capture(1)
4531 backend = capture[0][IP].dst
4533 sessions = self.vapi.nat44_user_session_dump(
4534 socket.inet_pton(socket.AF_INET, backend), 0)
4535 self.assertEqual(len(sessions), 1)
4536 self.assertTrue(sessions[0].ext_host_valid)
4537 self.vapi.nat44_del_session(
4538 sessions[0].inside_ip_address,
4539 sessions[0].inside_port,
4540 sessions[0].protocol,
4541 ext_host_address=sessions[0].ext_host_address,
4542 ext_host_port=sessions[0].ext_host_port)
4545 for port in range(1030, 1100):
4546 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
4547 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
4548 TCP(sport=port, dport=external_port))
4550 self.pg1.add_stream(pkts)
4551 self.pg_enable_capture(self.pg_interfaces)
4553 capture = self.pg0.get_capture(len(pkts))
4555 self.assertEqual(p[IP].dst, backend)
4557 def test_unknown_proto(self):
4558 """ NAT44 translate packet with unknown protocol """
4559 self.nat44_add_address(self.nat_addr)
4560 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
4561 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
4565 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
4566 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
4567 TCP(sport=self.tcp_port_in, dport=20))
4568 self.pg0.add_stream(p)
4569 self.pg_enable_capture(self.pg_interfaces)
4571 p = self.pg1.get_capture(1)
4573 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
4574 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
4576 IP(src=self.pg2.remote_ip4, dst=self.pg2.remote_ip4) /
4577 TCP(sport=1234, dport=1234))
4578 self.pg0.add_stream(p)
4579 self.pg_enable_capture(self.pg_interfaces)
4581 p = self.pg1.get_capture(1)
4584 self.assertEqual(packet[IP].src, self.nat_addr)
4585 self.assertEqual(packet[IP].dst, self.pg1.remote_ip4)
4586 self.assertEqual(packet.haslayer(GRE), 1)
4587 self.assert_packet_checksums_valid(packet)
4589 self.logger.error(ppp("Unexpected or invalid packet:", packet))
4593 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
4594 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
4596 IP(src=self.pg2.remote_ip4, dst=self.pg2.remote_ip4) /
4597 TCP(sport=1234, dport=1234))
4598 self.pg1.add_stream(p)
4599 self.pg_enable_capture(self.pg_interfaces)
4601 p = self.pg0.get_capture(1)
4604 self.assertEqual(packet[IP].src, self.pg1.remote_ip4)
4605 self.assertEqual(packet[IP].dst, self.pg0.remote_ip4)
4606 self.assertEqual(packet.haslayer(GRE), 1)
4607 self.assert_packet_checksums_valid(packet)
4609 self.logger.error(ppp("Unexpected or invalid packet:", packet))
4612 def test_hairpinning_unknown_proto(self):
4613 """ NAT44 translate packet with unknown protocol - hairpinning """
4614 host = self.pg0.remote_hosts[0]
4615 server = self.pg0.remote_hosts[1]
4617 server_out_port = 8765
4618 server_nat_ip = "10.0.0.11"
4620 self.nat44_add_address(self.nat_addr)
4621 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
4622 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
4625 # add static mapping for server
4626 self.nat44_add_static_mapping(server.ip4, server_nat_ip)
4629 p = (Ether(src=host.mac, dst=self.pg0.local_mac) /
4630 IP(src=host.ip4, dst=server_nat_ip) /
4631 TCP(sport=host_in_port, dport=server_out_port))
4632 self.pg0.add_stream(p)
4633 self.pg_enable_capture(self.pg_interfaces)
4635 self.pg0.get_capture(1)
4637 p = (Ether(dst=self.pg0.local_mac, src=host.mac) /
4638 IP(src=host.ip4, dst=server_nat_ip) /
4640 IP(src=self.pg2.remote_ip4, dst=self.pg2.remote_ip4) /
4641 TCP(sport=1234, dport=1234))
4642 self.pg0.add_stream(p)
4643 self.pg_enable_capture(self.pg_interfaces)
4645 p = self.pg0.get_capture(1)
4648 self.assertEqual(packet[IP].src, self.nat_addr)
4649 self.assertEqual(packet[IP].dst, server.ip4)
4650 self.assertEqual(packet.haslayer(GRE), 1)
4651 self.assert_packet_checksums_valid(packet)
4653 self.logger.error(ppp("Unexpected or invalid packet:", packet))
4657 p = (Ether(dst=self.pg0.local_mac, src=server.mac) /
4658 IP(src=server.ip4, dst=self.nat_addr) /
4660 IP(src=self.pg2.remote_ip4, dst=self.pg2.remote_ip4) /
4661 TCP(sport=1234, dport=1234))
4662 self.pg0.add_stream(p)
4663 self.pg_enable_capture(self.pg_interfaces)
4665 p = self.pg0.get_capture(1)
4668 self.assertEqual(packet[IP].src, server_nat_ip)
4669 self.assertEqual(packet[IP].dst, host.ip4)
4670 self.assertEqual(packet.haslayer(GRE), 1)
4671 self.assert_packet_checksums_valid(packet)
4673 self.logger.error(ppp("Unexpected or invalid packet:", packet))
4676 def test_output_feature_and_service(self):
4677 """ NAT44 interface output feature and services """
4678 external_addr = '1.2.3.4'
4682 self.vapi.nat44_forwarding_enable_disable(1)
4683 self.nat44_add_address(self.nat_addr)
4684 self.vapi.nat44_add_del_identity_mapping(ip=self.pg1.remote_ip4n)
4685 self.nat44_add_static_mapping(self.pg0.remote_ip4, external_addr,
4686 local_port, external_port,
4687 proto=IP_PROTOS.tcp, out2in_only=1)
4688 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
4689 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index,
4691 self.vapi.nat44_interface_add_del_output_feature(self.pg1.sw_if_index,
4694 # from client to service
4695 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
4696 IP(src=self.pg1.remote_ip4, dst=external_addr) /
4697 TCP(sport=12345, dport=external_port))
4698 self.pg1.add_stream(p)
4699 self.pg_enable_capture(self.pg_interfaces)
4701 capture = self.pg0.get_capture(1)
4706 self.assertEqual(ip.dst, self.pg0.remote_ip4)
4707 self.assertEqual(tcp.dport, local_port)
4708 self.assert_packet_checksums_valid(p)
4710 self.logger.error(ppp("Unexpected or invalid packet:", p))
4713 # from service back to client
4714 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
4715 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
4716 TCP(sport=local_port, dport=12345))
4717 self.pg0.add_stream(p)
4718 self.pg_enable_capture(self.pg_interfaces)
4720 capture = self.pg1.get_capture(1)
4725 self.assertEqual(ip.src, external_addr)
4726 self.assertEqual(tcp.sport, external_port)
4727 self.assert_packet_checksums_valid(p)
4729 self.logger.error(ppp("Unexpected or invalid packet:", p))
4732 # from local network host to external network
4733 pkts = self.create_stream_in(self.pg0, self.pg1)
4734 self.pg0.add_stream(pkts)
4735 self.pg_enable_capture(self.pg_interfaces)
4737 capture = self.pg1.get_capture(len(pkts))
4738 self.verify_capture_out(capture)
4739 pkts = self.create_stream_in(self.pg0, self.pg1)
4740 self.pg0.add_stream(pkts)
4741 self.pg_enable_capture(self.pg_interfaces)
4743 capture = self.pg1.get_capture(len(pkts))
4744 self.verify_capture_out(capture)
4746 # from external network back to local network host
4747 pkts = self.create_stream_out(self.pg1)
4748 self.pg1.add_stream(pkts)
4749 self.pg_enable_capture(self.pg_interfaces)
4751 capture = self.pg0.get_capture(len(pkts))
4752 self.verify_capture_in(capture, self.pg0)
4754 def test_output_feature_and_service2(self):
4755 """ NAT44 interface output feature and service host direct access """
4756 self.vapi.nat44_forwarding_enable_disable(1)
4757 self.nat44_add_address(self.nat_addr)
4758 self.vapi.nat44_interface_add_del_output_feature(self.pg1.sw_if_index,
4761 # session initiaded from service host - translate
4762 pkts = self.create_stream_in(self.pg0, self.pg1)
4763 self.pg0.add_stream(pkts)
4764 self.pg_enable_capture(self.pg_interfaces)
4766 capture = self.pg1.get_capture(len(pkts))
4767 self.verify_capture_out(capture)
4769 pkts = self.create_stream_out(self.pg1)
4770 self.pg1.add_stream(pkts)
4771 self.pg_enable_capture(self.pg_interfaces)
4773 capture = self.pg0.get_capture(len(pkts))
4774 self.verify_capture_in(capture, self.pg0)
4776 # session initiaded from remote host - do not translate
4777 self.tcp_port_in = 60303
4778 self.udp_port_in = 60304
4779 self.icmp_id_in = 60305
4780 pkts = self.create_stream_out(self.pg1,
4781 self.pg0.remote_ip4,
4782 use_inside_ports=True)
4783 self.pg1.add_stream(pkts)
4784 self.pg_enable_capture(self.pg_interfaces)
4786 capture = self.pg0.get_capture(len(pkts))
4787 self.verify_capture_in(capture, self.pg0)
4789 pkts = self.create_stream_in(self.pg0, self.pg1)
4790 self.pg0.add_stream(pkts)
4791 self.pg_enable_capture(self.pg_interfaces)
4793 capture = self.pg1.get_capture(len(pkts))
4794 self.verify_capture_out(capture, nat_ip=self.pg0.remote_ip4,
4797 def test_output_feature_and_service3(self):
4798 """ NAT44 interface output feature and DST NAT """
4799 external_addr = '1.2.3.4'
4803 self.vapi.nat44_forwarding_enable_disable(1)
4804 self.nat44_add_address(self.nat_addr)
4805 self.nat44_add_static_mapping(self.pg1.remote_ip4, external_addr,
4806 local_port, external_port,
4807 proto=IP_PROTOS.tcp, out2in_only=1)
4808 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
4809 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index,
4811 self.vapi.nat44_interface_add_del_output_feature(self.pg1.sw_if_index,
4814 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
4815 IP(src=self.pg0.remote_ip4, dst=external_addr) /
4816 TCP(sport=12345, dport=external_port))
4817 self.pg0.add_stream(p)
4818 self.pg_enable_capture(self.pg_interfaces)
4820 capture = self.pg1.get_capture(1)
4825 self.assertEqual(ip.src, self.pg0.remote_ip4)
4826 self.assertEqual(tcp.sport, 12345)
4827 self.assertEqual(ip.dst, self.pg1.remote_ip4)
4828 self.assertEqual(tcp.dport, local_port)
4829 self.assert_packet_checksums_valid(p)
4831 self.logger.error(ppp("Unexpected or invalid packet:", p))
4834 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
4835 IP(src=self.pg1.remote_ip4, dst=self.pg0.remote_ip4) /
4836 TCP(sport=local_port, dport=12345))
4837 self.pg1.add_stream(p)
4838 self.pg_enable_capture(self.pg_interfaces)
4840 capture = self.pg0.get_capture(1)
4845 self.assertEqual(ip.src, external_addr)
4846 self.assertEqual(tcp.sport, external_port)
4847 self.assertEqual(ip.dst, self.pg0.remote_ip4)
4848 self.assertEqual(tcp.dport, 12345)
4849 self.assert_packet_checksums_valid(p)
4851 self.logger.error(ppp("Unexpected or invalid packet:", p))
4854 def test_next_src_nat(self):
4855 """ On way back forward packet to nat44-in2out node. """
4856 twice_nat_addr = '10.0.1.3'
4859 post_twice_nat_port = 0
4861 self.vapi.nat44_forwarding_enable_disable(1)
4862 self.nat44_add_address(twice_nat_addr, twice_nat=1)
4863 self.nat44_add_static_mapping(self.pg6.remote_ip4, self.pg1.remote_ip4,
4864 local_port, external_port,
4865 proto=IP_PROTOS.tcp, out2in_only=1,
4866 self_twice_nat=1, vrf_id=1)
4867 self.vapi.nat44_interface_add_del_feature(self.pg6.sw_if_index,
4870 p = (Ether(src=self.pg6.remote_mac, dst=self.pg6.local_mac) /
4871 IP(src=self.pg6.remote_ip4, dst=self.pg1.remote_ip4) /
4872 TCP(sport=12345, dport=external_port))
4873 self.pg6.add_stream(p)
4874 self.pg_enable_capture(self.pg_interfaces)
4876 capture = self.pg6.get_capture(1)
4881 self.assertEqual(ip.src, twice_nat_addr)
4882 self.assertNotEqual(tcp.sport, 12345)
4883 post_twice_nat_port = tcp.sport
4884 self.assertEqual(ip.dst, self.pg6.remote_ip4)
4885 self.assertEqual(tcp.dport, local_port)
4886 self.assert_packet_checksums_valid(p)
4888 self.logger.error(ppp("Unexpected or invalid packet:", p))
4891 p = (Ether(src=self.pg6.remote_mac, dst=self.pg6.local_mac) /
4892 IP(src=self.pg6.remote_ip4, dst=twice_nat_addr) /
4893 TCP(sport=local_port, dport=post_twice_nat_port))
4894 self.pg6.add_stream(p)
4895 self.pg_enable_capture(self.pg_interfaces)
4897 capture = self.pg6.get_capture(1)
4902 self.assertEqual(ip.src, self.pg1.remote_ip4)
4903 self.assertEqual(tcp.sport, external_port)
4904 self.assertEqual(ip.dst, self.pg6.remote_ip4)
4905 self.assertEqual(tcp.dport, 12345)
4906 self.assert_packet_checksums_valid(p)
4908 self.logger.error(ppp("Unexpected or invalid packet:", p))
4911 def twice_nat_common(self, self_twice_nat=False, same_pg=False, lb=False,
4913 twice_nat_addr = '10.0.1.3'
4921 port_in1 = port_in+1
4922 port_in2 = port_in+2
4927 server1 = self.pg0.remote_hosts[0]
4928 server2 = self.pg0.remote_hosts[1]
4940 eh_translate = ((not self_twice_nat) or (not lb and same_pg) or
4943 self.nat44_add_address(self.nat_addr)
4944 self.nat44_add_address(twice_nat_addr, twice_nat=1)
4946 self.nat44_add_static_mapping(pg0.remote_ip4, self.nat_addr,
4948 proto=IP_PROTOS.tcp,
4949 twice_nat=int(not self_twice_nat),
4950 self_twice_nat=int(self_twice_nat))
4952 locals = [{'addr': server1.ip4n,
4956 {'addr': server2.ip4n,
4960 out_addr_n = socket.inet_pton(socket.AF_INET, self.nat_addr)
4961 self.vapi.nat44_add_del_lb_static_mapping(out_addr_n,
4965 not self_twice_nat),
4968 local_num=len(locals),
4970 self.vapi.nat44_interface_add_del_feature(pg0.sw_if_index)
4971 self.vapi.nat44_interface_add_del_feature(pg1.sw_if_index,
4978 assert client_id is not None
4980 client = self.pg0.remote_hosts[0]
4981 elif client_id == 2:
4982 client = self.pg0.remote_hosts[1]
4984 client = pg1.remote_hosts[0]
4985 p = (Ether(src=pg1.remote_mac, dst=pg1.local_mac) /
4986 IP(src=client.ip4, dst=self.nat_addr) /
4987 TCP(sport=eh_port_out, dport=port_out))
4989 self.pg_enable_capture(self.pg_interfaces)
4991 capture = pg0.get_capture(1)
4997 if ip.dst == server1.ip4:
5003 self.assertEqual(ip.dst, server.ip4)
5005 self.assertIn(tcp.dport, [port_in1, port_in2])
5007 self.assertEqual(tcp.dport, port_in)
5009 self.assertEqual(ip.src, twice_nat_addr)
5010 self.assertNotEqual(tcp.sport, eh_port_out)
5012 self.assertEqual(ip.src, client.ip4)
5013 self.assertEqual(tcp.sport, eh_port_out)
5015 eh_port_in = tcp.sport
5016 saved_port_in = tcp.dport
5017 self.assert_packet_checksums_valid(p)
5019 self.logger.error(ppp("Unexpected or invalid packet:", p))
5022 p = (Ether(src=server.mac, dst=pg0.local_mac) /
5023 IP(src=server.ip4, dst=eh_addr_in) /
5024 TCP(sport=saved_port_in, dport=eh_port_in))
5026 self.pg_enable_capture(self.pg_interfaces)
5028 capture = pg1.get_capture(1)
5033 self.assertEqual(ip.dst, client.ip4)
5034 self.assertEqual(ip.src, self.nat_addr)
5035 self.assertEqual(tcp.dport, eh_port_out)
5036 self.assertEqual(tcp.sport, port_out)
5037 self.assert_packet_checksums_valid(p)
5039 self.logger.error(ppp("Unexpected or invalid packet:", p))
5043 sessions = self.vapi.nat44_user_session_dump(server.ip4n, 0)
5044 self.assertEqual(len(sessions), 1)
5045 self.assertTrue(sessions[0].ext_host_valid)
5046 self.assertTrue(sessions[0].is_twicenat)
5047 self.vapi.nat44_del_session(
5048 sessions[0].inside_ip_address,
5049 sessions[0].inside_port,
5050 sessions[0].protocol,
5051 ext_host_address=sessions[0].ext_host_nat_address,
5052 ext_host_port=sessions[0].ext_host_nat_port)
5053 sessions = self.vapi.nat44_user_session_dump(server.ip4n, 0)
5054 self.assertEqual(len(sessions), 0)
5056 def test_twice_nat(self):
5058 self.twice_nat_common()
5060 def test_self_twice_nat_positive(self):
5061 """ Self Twice NAT44 (positive test) """
5062 self.twice_nat_common(self_twice_nat=True, same_pg=True)
5064 def test_self_twice_nat_negative(self):
5065 """ Self Twice NAT44 (negative test) """
5066 self.twice_nat_common(self_twice_nat=True)
5068 def test_twice_nat_lb(self):
5069 """ Twice NAT44 local service load balancing """
5070 self.twice_nat_common(lb=True)
5072 def test_self_twice_nat_lb_positive(self):
5073 """ Self Twice NAT44 local service load balancing (positive test) """
5074 self.twice_nat_common(lb=True, self_twice_nat=True, same_pg=True,
5077 def test_self_twice_nat_lb_negative(self):
5078 """ Self Twice NAT44 local service load balancing (negative test) """
5079 self.twice_nat_common(lb=True, self_twice_nat=True, same_pg=True,
5082 def test_twice_nat_interface_addr(self):
5083 """ Acquire twice NAT44 addresses from interface """
5084 self.vapi.nat44_add_interface_addr(self.pg3.sw_if_index, twice_nat=1)
5086 # no address in NAT pool
5087 adresses = self.vapi.nat44_address_dump()
5088 self.assertEqual(0, len(adresses))
5090 # configure interface address and check NAT address pool
5091 self.pg3.config_ip4()
5092 adresses = self.vapi.nat44_address_dump()
5093 self.assertEqual(1, len(adresses))
5094 self.assertEqual(adresses[0].ip_address[0:4], self.pg3.local_ip4n)
5095 self.assertEqual(adresses[0].twice_nat, 1)
5097 # remove interface address and check NAT address pool
5098 self.pg3.unconfig_ip4()
5099 adresses = self.vapi.nat44_address_dump()
5100 self.assertEqual(0, len(adresses))
5102 def test_tcp_close(self):
5103 """ Close TCP session from inside network - output feature """
5104 self.vapi.nat44_forwarding_enable_disable(1)
5105 self.nat44_add_address(self.pg1.local_ip4)
5106 twice_nat_addr = '10.0.1.3'
5107 service_ip = '192.168.16.150'
5108 self.nat44_add_address(twice_nat_addr, twice_nat=1)
5109 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
5110 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index,
5112 self.vapi.nat44_interface_add_del_output_feature(self.pg1.sw_if_index,
5114 self.nat44_add_static_mapping(self.pg0.remote_ip4,
5118 proto=IP_PROTOS.tcp,
5121 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4n, 0)
5122 start_sessnum = len(sessions)
5124 # SYN packet out->in
5125 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
5126 IP(src=self.pg1.remote_ip4, dst=service_ip) /
5127 TCP(sport=33898, dport=80, flags="S"))
5128 self.pg1.add_stream(p)
5129 self.pg_enable_capture(self.pg_interfaces)
5131 capture = self.pg0.get_capture(1)
5133 tcp_port = p[TCP].sport
5135 # SYN + ACK packet in->out
5136 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5137 IP(src=self.pg0.remote_ip4, dst=twice_nat_addr) /
5138 TCP(sport=80, dport=tcp_port, flags="SA"))
5139 self.pg0.add_stream(p)
5140 self.pg_enable_capture(self.pg_interfaces)
5142 self.pg1.get_capture(1)
5144 # ACK packet out->in
5145 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
5146 IP(src=self.pg1.remote_ip4, dst=service_ip) /
5147 TCP(sport=33898, dport=80, flags="A"))
5148 self.pg1.add_stream(p)
5149 self.pg_enable_capture(self.pg_interfaces)
5151 self.pg0.get_capture(1)
5153 # FIN packet in -> out
5154 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5155 IP(src=self.pg0.remote_ip4, dst=twice_nat_addr) /
5156 TCP(sport=80, dport=tcp_port, flags="FA", seq=100, ack=300))
5157 self.pg0.add_stream(p)
5158 self.pg_enable_capture(self.pg_interfaces)
5160 self.pg1.get_capture(1)
5162 # FIN+ACK packet out -> in
5163 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
5164 IP(src=self.pg1.remote_ip4, dst=service_ip) /
5165 TCP(sport=33898, dport=80, flags="FA", seq=300, ack=101))
5166 self.pg1.add_stream(p)
5167 self.pg_enable_capture(self.pg_interfaces)
5169 self.pg0.get_capture(1)
5171 # ACK packet in -> out
5172 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5173 IP(src=self.pg0.remote_ip4, dst=twice_nat_addr) /
5174 TCP(sport=80, dport=tcp_port, flags="A", seq=101, ack=301))
5175 self.pg0.add_stream(p)
5176 self.pg_enable_capture(self.pg_interfaces)
5178 self.pg1.get_capture(1)
5180 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4n,
5182 self.assertEqual(len(sessions) - start_sessnum, 0)
5184 def test_tcp_session_close_in(self):
5185 """ Close TCP session from inside network """
5186 self.tcp_port_out = 10505
5187 self.nat44_add_address(self.nat_addr)
5188 self.nat44_add_static_mapping(self.pg0.remote_ip4,
5192 proto=IP_PROTOS.tcp,
5194 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
5195 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
5198 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4n, 0)
5199 start_sessnum = len(sessions)
5201 self.initiate_tcp_session(self.pg0, self.pg1)
5203 # FIN 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=100, ack=300))
5208 self.pg0.add_stream(p)
5209 self.pg_enable_capture(self.pg_interfaces)
5211 self.pg1.get_capture(1)
5215 # ACK packet out -> in
5216 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
5217 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
5218 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
5219 flags="A", seq=300, ack=101))
5222 # FIN packet out -> in
5223 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
5224 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
5225 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
5226 flags="FA", seq=300, ack=101))
5229 self.pg1.add_stream(pkts)
5230 self.pg_enable_capture(self.pg_interfaces)
5232 self.pg0.get_capture(2)
5234 # ACK packet in -> out
5235 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5236 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
5237 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
5238 flags="A", seq=101, ack=301))
5239 self.pg0.add_stream(p)
5240 self.pg_enable_capture(self.pg_interfaces)
5242 self.pg1.get_capture(1)
5244 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4n,
5246 self.assertEqual(len(sessions) - start_sessnum, 0)
5248 def test_tcp_session_close_out(self):
5249 """ Close TCP session from outside network """
5250 self.tcp_port_out = 10505
5251 self.nat44_add_address(self.nat_addr)
5252 self.nat44_add_static_mapping(self.pg0.remote_ip4,
5256 proto=IP_PROTOS.tcp,
5258 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
5259 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
5262 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4n, 0)
5263 start_sessnum = len(sessions)
5265 self.initiate_tcp_session(self.pg0, self.pg1)
5267 # FIN packet out -> in
5268 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
5269 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
5270 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
5271 flags="FA", seq=100, ack=300))
5272 self.pg1.add_stream(p)
5273 self.pg_enable_capture(self.pg_interfaces)
5275 self.pg0.get_capture(1)
5277 # FIN+ACK packet in -> out
5278 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5279 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
5280 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
5281 flags="FA", seq=300, ack=101))
5283 self.pg0.add_stream(p)
5284 self.pg_enable_capture(self.pg_interfaces)
5286 self.pg1.get_capture(1)
5288 # ACK packet out -> in
5289 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
5290 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
5291 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
5292 flags="A", seq=101, ack=301))
5293 self.pg1.add_stream(p)
5294 self.pg_enable_capture(self.pg_interfaces)
5296 self.pg0.get_capture(1)
5298 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4n,
5300 self.assertEqual(len(sessions) - start_sessnum, 0)
5302 def test_tcp_session_close_simultaneous(self):
5303 """ Close TCP session from inside network """
5304 self.tcp_port_out = 10505
5305 self.nat44_add_address(self.nat_addr)
5306 self.nat44_add_static_mapping(self.pg0.remote_ip4,
5310 proto=IP_PROTOS.tcp,
5312 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
5313 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
5316 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4n, 0)
5317 start_sessnum = len(sessions)
5319 self.initiate_tcp_session(self.pg0, self.pg1)
5321 # FIN packet in -> out
5322 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5323 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
5324 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
5325 flags="FA", seq=100, ack=300))
5326 self.pg0.add_stream(p)
5327 self.pg_enable_capture(self.pg_interfaces)
5329 self.pg1.get_capture(1)
5331 # FIN packet out -> in
5332 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
5333 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
5334 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
5335 flags="FA", seq=300, ack=100))
5336 self.pg1.add_stream(p)
5337 self.pg_enable_capture(self.pg_interfaces)
5339 self.pg0.get_capture(1)
5341 # ACK packet in -> out
5342 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5343 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
5344 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
5345 flags="A", seq=101, ack=301))
5346 self.pg0.add_stream(p)
5347 self.pg_enable_capture(self.pg_interfaces)
5349 self.pg1.get_capture(1)
5351 # ACK packet out -> in
5352 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
5353 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
5354 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
5355 flags="A", seq=301, ack=101))
5356 self.pg1.add_stream(p)
5357 self.pg_enable_capture(self.pg_interfaces)
5359 self.pg0.get_capture(1)
5361 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4n,
5363 self.assertEqual(len(sessions) - start_sessnum, 0)
5365 def test_one_armed_nat44_static(self):
5366 """ One armed NAT44 and 1:1 NAPT asymmetrical rule """
5367 remote_host = self.pg4.remote_hosts[0]
5368 local_host = self.pg4.remote_hosts[1]
5373 self.vapi.nat44_forwarding_enable_disable(1)
5374 self.nat44_add_address(self.nat_addr, twice_nat=1)
5375 self.nat44_add_static_mapping(local_host.ip4, self.nat_addr,
5376 local_port, external_port,
5377 proto=IP_PROTOS.tcp, out2in_only=1,
5379 self.vapi.nat44_interface_add_del_feature(self.pg4.sw_if_index)
5380 self.vapi.nat44_interface_add_del_feature(self.pg4.sw_if_index,
5383 # from client to service
5384 p = (Ether(src=self.pg4.remote_mac, dst=self.pg4.local_mac) /
5385 IP(src=remote_host.ip4, dst=self.nat_addr) /
5386 TCP(sport=12345, dport=external_port))
5387 self.pg4.add_stream(p)
5388 self.pg_enable_capture(self.pg_interfaces)
5390 capture = self.pg4.get_capture(1)
5395 self.assertEqual(ip.dst, local_host.ip4)
5396 self.assertEqual(ip.src, self.nat_addr)
5397 self.assertEqual(tcp.dport, local_port)
5398 self.assertNotEqual(tcp.sport, 12345)
5399 eh_port_in = tcp.sport
5400 self.assert_packet_checksums_valid(p)
5402 self.logger.error(ppp("Unexpected or invalid packet:", p))
5405 # from service back to client
5406 p = (Ether(src=self.pg4.remote_mac, dst=self.pg4.local_mac) /
5407 IP(src=local_host.ip4, dst=self.nat_addr) /
5408 TCP(sport=local_port, dport=eh_port_in))
5409 self.pg4.add_stream(p)
5410 self.pg_enable_capture(self.pg_interfaces)
5412 capture = self.pg4.get_capture(1)
5417 self.assertEqual(ip.src, self.nat_addr)
5418 self.assertEqual(ip.dst, remote_host.ip4)
5419 self.assertEqual(tcp.sport, external_port)
5420 self.assertEqual(tcp.dport, 12345)
5421 self.assert_packet_checksums_valid(p)
5423 self.logger.error(ppp("Unexpected or invalid packet:", p))
5426 def test_static_with_port_out2(self):
5427 """ 1:1 NAPT asymmetrical rule """
5432 self.vapi.nat44_forwarding_enable_disable(1)
5433 self.nat44_add_static_mapping(self.pg0.remote_ip4, self.nat_addr,
5434 local_port, external_port,
5435 proto=IP_PROTOS.tcp, out2in_only=1)
5436 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
5437 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
5440 # from client to service
5441 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
5442 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
5443 TCP(sport=12345, dport=external_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))
5460 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
5461 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
5462 ICMP(type=11) / capture[0][IP])
5463 self.pg0.add_stream(p)
5464 self.pg_enable_capture(self.pg_interfaces)
5466 capture = self.pg1.get_capture(1)
5469 self.assertEqual(p[IP].src, self.nat_addr)
5471 self.assertEqual(inner.dst, self.nat_addr)
5472 self.assertEqual(inner[TCPerror].dport, external_port)
5474 self.logger.error(ppp("Unexpected or invalid packet:", p))
5477 # from service back to client
5478 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5479 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
5480 TCP(sport=local_port, dport=12345))
5481 self.pg0.add_stream(p)
5482 self.pg_enable_capture(self.pg_interfaces)
5484 capture = self.pg1.get_capture(1)
5489 self.assertEqual(ip.src, self.nat_addr)
5490 self.assertEqual(tcp.sport, external_port)
5491 self.assert_packet_checksums_valid(p)
5493 self.logger.error(ppp("Unexpected or invalid packet:", p))
5497 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
5498 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
5499 ICMP(type=11) / capture[0][IP])
5500 self.pg1.add_stream(p)
5501 self.pg_enable_capture(self.pg_interfaces)
5503 capture = self.pg0.get_capture(1)
5506 self.assertEqual(p[IP].dst, self.pg0.remote_ip4)
5508 self.assertEqual(inner.src, self.pg0.remote_ip4)
5509 self.assertEqual(inner[TCPerror].sport, local_port)
5511 self.logger.error(ppp("Unexpected or invalid packet:", p))
5514 # from client to server (no translation)
5515 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
5516 IP(src=self.pg1.remote_ip4, dst=self.pg0.remote_ip4) /
5517 TCP(sport=12346, dport=local_port))
5518 self.pg1.add_stream(p)
5519 self.pg_enable_capture(self.pg_interfaces)
5521 capture = self.pg0.get_capture(1)
5526 self.assertEqual(ip.dst, self.pg0.remote_ip4)
5527 self.assertEqual(tcp.dport, local_port)
5528 self.assert_packet_checksums_valid(p)
5530 self.logger.error(ppp("Unexpected or invalid packet:", p))
5533 # from service back to client (no translation)
5534 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5535 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
5536 TCP(sport=local_port, dport=12346))
5537 self.pg0.add_stream(p)
5538 self.pg_enable_capture(self.pg_interfaces)
5540 capture = self.pg1.get_capture(1)
5545 self.assertEqual(ip.src, self.pg0.remote_ip4)
5546 self.assertEqual(tcp.sport, local_port)
5547 self.assert_packet_checksums_valid(p)
5549 self.logger.error(ppp("Unexpected or invalid packet:", p))
5552 def test_output_feature(self):
5553 """ NAT44 interface output feature (in2out postrouting) """
5554 self.vapi.nat44_forwarding_enable_disable(1)
5555 self.nat44_add_address(self.nat_addr)
5556 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index,
5558 self.vapi.nat44_interface_add_del_output_feature(self.pg1.sw_if_index,
5562 pkts = self.create_stream_in(self.pg0, self.pg1)
5563 self.pg0.add_stream(pkts)
5564 self.pg_enable_capture(self.pg_interfaces)
5566 capture = self.pg1.get_capture(len(pkts))
5567 self.verify_capture_out(capture)
5570 pkts = self.create_stream_out(self.pg1)
5571 self.pg1.add_stream(pkts)
5572 self.pg_enable_capture(self.pg_interfaces)
5574 capture = self.pg0.get_capture(len(pkts))
5575 self.verify_capture_in(capture, self.pg0)
5577 def test_multiple_vrf(self):
5578 """ Multiple VRF setup """
5579 external_addr = '1.2.3.4'
5584 self.vapi.nat44_forwarding_enable_disable(1)
5585 self.nat44_add_address(self.nat_addr)
5586 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
5587 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index,
5589 self.vapi.nat44_interface_add_del_output_feature(self.pg1.sw_if_index,
5591 self.vapi.nat44_interface_add_del_feature(self.pg5.sw_if_index)
5592 self.vapi.nat44_interface_add_del_feature(self.pg5.sw_if_index,
5594 self.vapi.nat44_interface_add_del_feature(self.pg6.sw_if_index,
5596 self.nat44_add_static_mapping(self.pg5.remote_ip4, external_addr,
5597 local_port, external_port, vrf_id=1,
5598 proto=IP_PROTOS.tcp, out2in_only=1)
5599 self.nat44_add_static_mapping(
5600 self.pg0.remote_ip4, external_sw_if_index=self.pg0.sw_if_index,
5601 local_port=local_port, vrf_id=0, external_port=external_port,
5602 proto=IP_PROTOS.tcp, out2in_only=1)
5604 # from client to service (both VRF1)
5605 p = (Ether(src=self.pg6.remote_mac, dst=self.pg6.local_mac) /
5606 IP(src=self.pg6.remote_ip4, dst=external_addr) /
5607 TCP(sport=12345, dport=external_port))
5608 self.pg6.add_stream(p)
5609 self.pg_enable_capture(self.pg_interfaces)
5611 capture = self.pg5.get_capture(1)
5616 self.assertEqual(ip.dst, self.pg5.remote_ip4)
5617 self.assertEqual(tcp.dport, local_port)
5618 self.assert_packet_checksums_valid(p)
5620 self.logger.error(ppp("Unexpected or invalid packet:", p))
5623 # from service back to client (both VRF1)
5624 p = (Ether(src=self.pg5.remote_mac, dst=self.pg5.local_mac) /
5625 IP(src=self.pg5.remote_ip4, dst=self.pg6.remote_ip4) /
5626 TCP(sport=local_port, dport=12345))
5627 self.pg5.add_stream(p)
5628 self.pg_enable_capture(self.pg_interfaces)
5630 capture = self.pg6.get_capture(1)
5635 self.assertEqual(ip.src, external_addr)
5636 self.assertEqual(tcp.sport, external_port)
5637 self.assert_packet_checksums_valid(p)
5639 self.logger.error(ppp("Unexpected or invalid packet:", p))
5642 # dynamic NAT from VRF1 to VRF0 (output-feature)
5643 p = (Ether(src=self.pg5.remote_mac, dst=self.pg5.local_mac) /
5644 IP(src=self.pg5.remote_ip4, dst=self.pg1.remote_ip4) /
5645 TCP(sport=2345, dport=22))
5646 self.pg5.add_stream(p)
5647 self.pg_enable_capture(self.pg_interfaces)
5649 capture = self.pg1.get_capture(1)
5654 self.assertEqual(ip.src, self.nat_addr)
5655 self.assertNotEqual(tcp.sport, 2345)
5656 self.assert_packet_checksums_valid(p)
5659 self.logger.error(ppp("Unexpected or invalid packet:", p))
5662 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
5663 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
5664 TCP(sport=22, dport=port))
5665 self.pg1.add_stream(p)
5666 self.pg_enable_capture(self.pg_interfaces)
5668 capture = self.pg5.get_capture(1)
5673 self.assertEqual(ip.dst, self.pg5.remote_ip4)
5674 self.assertEqual(tcp.dport, 2345)
5675 self.assert_packet_checksums_valid(p)
5677 self.logger.error(ppp("Unexpected or invalid packet:", p))
5680 # from client VRF1 to service VRF0
5681 p = (Ether(src=self.pg6.remote_mac, dst=self.pg6.local_mac) /
5682 IP(src=self.pg6.remote_ip4, dst=self.pg0.local_ip4) /
5683 TCP(sport=12346, dport=external_port))
5684 self.pg6.add_stream(p)
5685 self.pg_enable_capture(self.pg_interfaces)
5687 capture = self.pg0.get_capture(1)
5692 self.assertEqual(ip.dst, self.pg0.remote_ip4)
5693 self.assertEqual(tcp.dport, local_port)
5694 self.assert_packet_checksums_valid(p)
5696 self.logger.error(ppp("Unexpected or invalid packet:", p))
5699 # from service VRF0 back to client VRF1
5700 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5701 IP(src=self.pg0.remote_ip4, dst=self.pg6.remote_ip4) /
5702 TCP(sport=local_port, dport=12346))
5703 self.pg0.add_stream(p)
5704 self.pg_enable_capture(self.pg_interfaces)
5706 capture = self.pg6.get_capture(1)
5711 self.assertEqual(ip.src, self.pg0.local_ip4)
5712 self.assertEqual(tcp.sport, external_port)
5713 self.assert_packet_checksums_valid(p)
5715 self.logger.error(ppp("Unexpected or invalid packet:", p))
5718 # from client VRF0 to service VRF1
5719 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5720 IP(src=self.pg0.remote_ip4, dst=external_addr) /
5721 TCP(sport=12347, dport=external_port))
5722 self.pg0.add_stream(p)
5723 self.pg_enable_capture(self.pg_interfaces)
5725 capture = self.pg5.get_capture(1)
5730 self.assertEqual(ip.dst, self.pg5.remote_ip4)
5731 self.assertEqual(tcp.dport, local_port)
5732 self.assert_packet_checksums_valid(p)
5734 self.logger.error(ppp("Unexpected or invalid packet:", p))
5737 # from service VRF1 back to client VRF0
5738 p = (Ether(src=self.pg5.remote_mac, dst=self.pg5.local_mac) /
5739 IP(src=self.pg5.remote_ip4, dst=self.pg0.remote_ip4) /
5740 TCP(sport=local_port, dport=12347))
5741 self.pg5.add_stream(p)
5742 self.pg_enable_capture(self.pg_interfaces)
5744 capture = self.pg0.get_capture(1)
5749 self.assertEqual(ip.src, external_addr)
5750 self.assertEqual(tcp.sport, external_port)
5751 self.assert_packet_checksums_valid(p)
5753 self.logger.error(ppp("Unexpected or invalid packet:", p))
5756 # from client to server (both VRF1, no translation)
5757 p = (Ether(src=self.pg6.remote_mac, dst=self.pg6.local_mac) /
5758 IP(src=self.pg6.remote_ip4, dst=self.pg5.remote_ip4) /
5759 TCP(sport=12348, dport=local_port))
5760 self.pg6.add_stream(p)
5761 self.pg_enable_capture(self.pg_interfaces)
5763 capture = self.pg5.get_capture(1)
5768 self.assertEqual(ip.dst, self.pg5.remote_ip4)
5769 self.assertEqual(tcp.dport, local_port)
5770 self.assert_packet_checksums_valid(p)
5772 self.logger.error(ppp("Unexpected or invalid packet:", p))
5775 # from server back to client (both VRF1, no translation)
5776 p = (Ether(src=self.pg5.remote_mac, dst=self.pg5.local_mac) /
5777 IP(src=self.pg5.remote_ip4, dst=self.pg6.remote_ip4) /
5778 TCP(sport=local_port, dport=12348))
5779 self.pg5.add_stream(p)
5780 self.pg_enable_capture(self.pg_interfaces)
5782 capture = self.pg6.get_capture(1)
5787 self.assertEqual(ip.src, self.pg5.remote_ip4)
5788 self.assertEqual(tcp.sport, local_port)
5789 self.assert_packet_checksums_valid(p)
5791 self.logger.error(ppp("Unexpected or invalid packet:", p))
5794 # from client VRF1 to server VRF0 (no translation)
5795 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5796 IP(src=self.pg0.remote_ip4, dst=self.pg6.remote_ip4) /
5797 TCP(sport=local_port, dport=12349))
5798 self.pg0.add_stream(p)
5799 self.pg_enable_capture(self.pg_interfaces)
5801 capture = self.pg6.get_capture(1)
5806 self.assertEqual(ip.src, self.pg0.remote_ip4)
5807 self.assertEqual(tcp.sport, local_port)
5808 self.assert_packet_checksums_valid(p)
5810 self.logger.error(ppp("Unexpected or invalid packet:", p))
5813 # from server VRF0 back to client VRF1 (no translation)
5814 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5815 IP(src=self.pg0.remote_ip4, dst=self.pg6.remote_ip4) /
5816 TCP(sport=local_port, dport=12349))
5817 self.pg0.add_stream(p)
5818 self.pg_enable_capture(self.pg_interfaces)
5820 capture = self.pg6.get_capture(1)
5825 self.assertEqual(ip.src, self.pg0.remote_ip4)
5826 self.assertEqual(tcp.sport, local_port)
5827 self.assert_packet_checksums_valid(p)
5829 self.logger.error(ppp("Unexpected or invalid packet:", p))
5832 # from client VRF0 to server VRF1 (no translation)
5833 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5834 IP(src=self.pg0.remote_ip4, dst=self.pg5.remote_ip4) /
5835 TCP(sport=12344, dport=local_port))
5836 self.pg0.add_stream(p)
5837 self.pg_enable_capture(self.pg_interfaces)
5839 capture = self.pg5.get_capture(1)
5844 self.assertEqual(ip.dst, self.pg5.remote_ip4)
5845 self.assertEqual(tcp.dport, local_port)
5846 self.assert_packet_checksums_valid(p)
5848 self.logger.error(ppp("Unexpected or invalid packet:", p))
5851 # from server VRF1 back to client VRF0 (no translation)
5852 p = (Ether(src=self.pg5.remote_mac, dst=self.pg5.local_mac) /
5853 IP(src=self.pg5.remote_ip4, dst=self.pg0.remote_ip4) /
5854 TCP(sport=local_port, dport=12344))
5855 self.pg5.add_stream(p)
5856 self.pg_enable_capture(self.pg_interfaces)
5858 capture = self.pg0.get_capture(1)
5863 self.assertEqual(ip.src, self.pg5.remote_ip4)
5864 self.assertEqual(tcp.sport, local_port)
5865 self.assert_packet_checksums_valid(p)
5867 self.logger.error(ppp("Unexpected or invalid packet:", p))
5870 @unittest.skipUnless(running_extended_tests, "part of extended tests")
5871 def test_session_timeout(self):
5872 """ NAT44 session timeouts """
5873 self.nat44_add_address(self.nat_addr)
5874 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
5875 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
5877 self.vapi.nat_set_timeouts(icmp=5)
5881 for i in range(0, max_sessions):
5882 src = "10.10.%u.%u" % ((i & 0xFF00) >> 8, i & 0xFF)
5883 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
5884 IP(src=src, dst=self.pg1.remote_ip4) /
5885 ICMP(id=1025, type='echo-request'))
5887 self.pg0.add_stream(pkts)
5888 self.pg_enable_capture(self.pg_interfaces)
5890 self.pg1.get_capture(max_sessions)
5895 for i in range(0, max_sessions):
5896 src = "10.11.%u.%u" % ((i & 0xFF00) >> 8, i & 0xFF)
5897 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
5898 IP(src=src, dst=self.pg1.remote_ip4) /
5899 ICMP(id=1026, type='echo-request'))
5901 self.pg0.add_stream(pkts)
5902 self.pg_enable_capture(self.pg_interfaces)
5904 self.pg1.get_capture(max_sessions)
5907 users = self.vapi.nat44_user_dump()
5909 nsessions = nsessions + user.nsessions
5910 self.assertLess(nsessions, 2 * max_sessions)
5912 @unittest.skipUnless(running_extended_tests, "part of extended tests")
5913 def test_session_rst_timeout(self):
5914 """ NAT44 session RST timeouts """
5915 self.nat44_add_address(self.nat_addr)
5916 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
5917 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
5919 self.vapi.nat_set_timeouts(tcp_transitory=5)
5921 self.initiate_tcp_session(self.pg0, self.pg1)
5922 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5923 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
5924 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
5926 self.pg0.add_stream(p)
5927 self.pg_enable_capture(self.pg_interfaces)
5929 self.pg1.get_capture(1)
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 TCP(sport=self.tcp_port_in + 1, dport=self.tcp_external_port + 1,
5937 self.pg0.add_stream(p)
5938 self.pg_enable_capture(self.pg_interfaces)
5940 self.pg1.get_capture(1)
5943 users = self.vapi.nat44_user_dump()
5944 self.assertEqual(len(users), 1)
5945 self.assertEqual(users[0].ip_address, self.pg0.remote_ip4n)
5946 self.assertEqual(users[0].nsessions, 1)
5948 @unittest.skipUnless(running_extended_tests, "part of extended tests")
5949 def test_session_limit_per_user(self):
5950 """ Maximum sessions per user limit """
5951 self.nat44_add_address(self.nat_addr)
5952 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
5953 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
5955 self.vapi.set_ipfix_exporter(collector_address=self.pg2.remote_ip4n,
5956 src_address=self.pg2.local_ip4n,
5958 template_interval=10)
5959 self.vapi.nat_set_timeouts(udp=5)
5961 # get maximum number of translations per user
5962 nat44_config = self.vapi.nat_show_config()
5965 for port in range(0, nat44_config.max_translations_per_user):
5966 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5967 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
5968 UDP(sport=1025 + port, dport=1025 + port))
5971 self.pg0.add_stream(pkts)
5972 self.pg_enable_capture(self.pg_interfaces)
5974 capture = self.pg1.get_capture(len(pkts))
5976 self.vapi.nat_ipfix(domain_id=self.ipfix_domain_id,
5977 src_port=self.ipfix_src_port)
5979 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5980 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
5981 UDP(sport=3001, dport=3002))
5982 self.pg0.add_stream(p)
5983 self.pg_enable_capture(self.pg_interfaces)
5985 capture = self.pg1.assert_nothing_captured()
5987 # verify IPFIX logging
5988 self.vapi.cli("ipfix flush") # FIXME this should be an API call
5990 capture = self.pg2.get_capture(10)
5991 ipfix = IPFIXDecoder()
5992 # first load template
5994 self.assertTrue(p.haslayer(IPFIX))
5995 if p.haslayer(Template):
5996 ipfix.add_template(p.getlayer(Template))
5997 # verify events in data set
5999 if p.haslayer(Data):
6000 data = ipfix.decode_data_set(p.getlayer(Set))
6001 self.verify_ipfix_max_entries_per_user(
6003 nat44_config.max_translations_per_user,
6004 self.pg0.remote_ip4n)
6007 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6008 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6009 UDP(sport=3001, dport=3002))
6010 self.pg0.add_stream(p)
6011 self.pg_enable_capture(self.pg_interfaces)
6013 self.pg1.get_capture(1)
6015 def test_syslog_sess(self):
6016 """ Test syslog session creation and deletion """
6017 self.vapi.syslog_set_filter(SYSLOG_SEVERITY.INFO)
6018 self.vapi.syslog_set_sender(self.pg2.remote_ip4n, self.pg2.local_ip4n)
6019 self.nat44_add_address(self.nat_addr)
6020 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
6021 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
6024 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
6025 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6026 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port))
6027 self.pg0.add_stream(p)
6028 self.pg_enable_capture(self.pg_interfaces)
6030 capture = self.pg1.get_capture(1)
6031 self.tcp_port_out = capture[0][TCP].sport
6032 capture = self.pg2.get_capture(1)
6033 self.verify_syslog_sess(capture[0][Raw].load)
6035 self.pg_enable_capture(self.pg_interfaces)
6037 self.nat44_add_address(self.nat_addr, is_add=0)
6038 capture = self.pg2.get_capture(1)
6039 self.verify_syslog_sess(capture[0][Raw].load, False)
6042 super(TestNAT44EndpointDependent, self).tearDown()
6043 if not self.vpp_dead:
6044 self.logger.info(self.vapi.cli("show nat44 addresses"))
6045 self.logger.info(self.vapi.cli("show nat44 interfaces"))
6046 self.logger.info(self.vapi.cli("show nat44 static mappings"))
6047 self.logger.info(self.vapi.cli("show nat44 interface address"))
6048 self.logger.info(self.vapi.cli("show nat44 sessions detail"))
6049 self.logger.info(self.vapi.cli("show nat44 hash tables detail"))
6050 self.logger.info(self.vapi.cli("show nat timeouts"))
6052 self.vapi.cli("clear logging")
6055 class TestNAT44Out2InDPO(MethodHolder):
6056 """ NAT44 Test Cases using out2in DPO """
6059 def setUpConstants(cls):
6060 super(TestNAT44Out2InDPO, cls).setUpConstants()
6061 cls.vpp_cmdline.extend(["nat", "{", "out2in dpo", "}"])
6064 def setUpClass(cls):
6065 super(TestNAT44Out2InDPO, cls).setUpClass()
6066 cls.vapi.cli("set log class nat level debug")
6069 cls.tcp_port_in = 6303
6070 cls.tcp_port_out = 6303
6071 cls.udp_port_in = 6304
6072 cls.udp_port_out = 6304
6073 cls.icmp_id_in = 6305
6074 cls.icmp_id_out = 6305
6075 cls.nat_addr = '10.0.0.3'
6076 cls.nat_addr_n = socket.inet_pton(socket.AF_INET, cls.nat_addr)
6077 cls.dst_ip4 = '192.168.70.1'
6079 cls.create_pg_interfaces(range(2))
6082 cls.pg0.config_ip4()
6083 cls.pg0.resolve_arp()
6086 cls.pg1.config_ip6()
6087 cls.pg1.resolve_ndp()
6089 cls.vapi.ip_add_del_route(is_ipv6=True, dst_address='\x00'*16,
6090 dst_address_length=0,
6091 next_hop_address=cls.pg1.remote_ip6n,
6092 next_hop_sw_if_index=cls.pg1.sw_if_index)
6095 super(TestNAT44Out2InDPO, cls).tearDownClass()
6098 def configure_xlat(self):
6099 self.dst_ip6_pfx = '1:2:3::'
6100 self.dst_ip6_pfx_n = socket.inet_pton(socket.AF_INET6,
6102 self.dst_ip6_pfx_len = 96
6103 self.src_ip6_pfx = '4:5:6::'
6104 self.src_ip6_pfx_n = socket.inet_pton(socket.AF_INET6,
6106 self.src_ip6_pfx_len = 96
6107 self.vapi.map_add_domain(self.dst_ip6_pfx_n, self.dst_ip6_pfx_len,
6108 self.src_ip6_pfx_n, self.src_ip6_pfx_len,
6109 '\x00\x00\x00\x00', 0, is_translation=1,
6112 @unittest.skip('Temporary disabled')
6113 def test_464xlat_ce(self):
6114 """ Test 464XLAT CE with NAT44 """
6116 nat_config = self.vapi.nat_show_config()
6117 self.assertEqual(1, nat_config.out2in_dpo)
6119 self.configure_xlat()
6121 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
6122 self.vapi.nat44_add_del_address_range(self.nat_addr_n, self.nat_addr_n)
6124 out_src_ip6 = self.compose_ip6(self.dst_ip4, self.dst_ip6_pfx,
6125 self.dst_ip6_pfx_len)
6126 out_dst_ip6 = self.compose_ip6(self.nat_addr, self.src_ip6_pfx,
6127 self.src_ip6_pfx_len)
6130 pkts = self.create_stream_in(self.pg0, self.pg1, self.dst_ip4)
6131 self.pg0.add_stream(pkts)
6132 self.pg_enable_capture(self.pg_interfaces)
6134 capture = self.pg1.get_capture(len(pkts))
6135 self.verify_capture_out_ip6(capture, nat_ip=out_dst_ip6,
6138 pkts = self.create_stream_out_ip6(self.pg1, out_src_ip6,
6140 self.pg1.add_stream(pkts)
6141 self.pg_enable_capture(self.pg_interfaces)
6143 capture = self.pg0.get_capture(len(pkts))
6144 self.verify_capture_in(capture, self.pg0)
6146 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index,
6148 self.vapi.nat44_add_del_address_range(self.nat_addr_n,
6149 self.nat_addr_n, is_add=0)
6151 @unittest.skip('Temporary disabled')
6152 def test_464xlat_ce_no_nat(self):
6153 """ Test 464XLAT CE without NAT44 """
6155 self.configure_xlat()
6157 out_src_ip6 = self.compose_ip6(self.dst_ip4, self.dst_ip6_pfx,
6158 self.dst_ip6_pfx_len)
6159 out_dst_ip6 = self.compose_ip6(self.pg0.remote_ip4, self.src_ip6_pfx,
6160 self.src_ip6_pfx_len)
6162 pkts = self.create_stream_in(self.pg0, self.pg1, self.dst_ip4)
6163 self.pg0.add_stream(pkts)
6164 self.pg_enable_capture(self.pg_interfaces)
6166 capture = self.pg1.get_capture(len(pkts))
6167 self.verify_capture_out_ip6(capture, dst_ip=out_src_ip6,
6168 nat_ip=out_dst_ip6, same_port=True)
6170 pkts = self.create_stream_out_ip6(self.pg1, out_src_ip6, out_dst_ip6)
6171 self.pg1.add_stream(pkts)
6172 self.pg_enable_capture(self.pg_interfaces)
6174 capture = self.pg0.get_capture(len(pkts))
6175 self.verify_capture_in(capture, self.pg0)
6178 class TestDeterministicNAT(MethodHolder):
6179 """ Deterministic NAT Test Cases """
6182 def setUpConstants(cls):
6183 super(TestDeterministicNAT, cls).setUpConstants()
6184 cls.vpp_cmdline.extend(["nat", "{", "deterministic", "}"])
6187 def setUpClass(cls):
6188 super(TestDeterministicNAT, cls).setUpClass()
6189 cls.vapi.cli("set log class nat level debug")
6192 cls.tcp_port_in = 6303
6193 cls.tcp_external_port = 6303
6194 cls.udp_port_in = 6304
6195 cls.udp_external_port = 6304
6196 cls.icmp_id_in = 6305
6197 cls.nat_addr = '10.0.0.3'
6199 cls.create_pg_interfaces(range(3))
6200 cls.interfaces = list(cls.pg_interfaces)
6202 for i in cls.interfaces:
6207 cls.pg0.generate_remote_hosts(2)
6208 cls.pg0.configure_ipv4_neighbors()
6211 super(TestDeterministicNAT, cls).tearDownClass()
6214 def create_stream_in(self, in_if, out_if, ttl=64):
6216 Create packet stream for inside network
6218 :param in_if: Inside interface
6219 :param out_if: Outside interface
6220 :param ttl: TTL of generated packets
6224 p = (Ether(dst=in_if.local_mac, src=in_if.remote_mac) /
6225 IP(src=in_if.remote_ip4, dst=out_if.remote_ip4, ttl=ttl) /
6226 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port))
6230 p = (Ether(dst=in_if.local_mac, src=in_if.remote_mac) /
6231 IP(src=in_if.remote_ip4, dst=out_if.remote_ip4, ttl=ttl) /
6232 UDP(sport=self.udp_port_in, dport=self.udp_external_port))
6236 p = (Ether(dst=in_if.local_mac, src=in_if.remote_mac) /
6237 IP(src=in_if.remote_ip4, dst=out_if.remote_ip4, ttl=ttl) /
6238 ICMP(id=self.icmp_id_in, type='echo-request'))
6243 def create_stream_out(self, out_if, dst_ip=None, ttl=64):
6245 Create packet stream for outside network
6247 :param out_if: Outside interface
6248 :param dst_ip: Destination IP address (Default use global NAT address)
6249 :param ttl: TTL of generated packets
6252 dst_ip = self.nat_addr
6255 p = (Ether(dst=out_if.local_mac, src=out_if.remote_mac) /
6256 IP(src=out_if.remote_ip4, dst=dst_ip, ttl=ttl) /
6257 TCP(dport=self.tcp_port_out, sport=self.tcp_external_port))
6261 p = (Ether(dst=out_if.local_mac, src=out_if.remote_mac) /
6262 IP(src=out_if.remote_ip4, dst=dst_ip, ttl=ttl) /
6263 UDP(dport=self.udp_port_out, sport=self.udp_external_port))
6267 p = (Ether(dst=out_if.local_mac, src=out_if.remote_mac) /
6268 IP(src=out_if.remote_ip4, dst=dst_ip, ttl=ttl) /
6269 ICMP(id=self.icmp_external_id, type='echo-reply'))
6274 def verify_capture_out(self, capture, nat_ip=None):
6276 Verify captured packets on outside network
6278 :param capture: Captured packets
6279 :param nat_ip: Translated IP address (Default use global NAT address)
6280 :param same_port: Sorce port number is not translated (Default False)
6283 nat_ip = self.nat_addr
6284 for packet in capture:
6286 self.assertEqual(packet[IP].src, nat_ip)
6287 if packet.haslayer(TCP):
6288 self.tcp_port_out = packet[TCP].sport
6289 elif packet.haslayer(UDP):
6290 self.udp_port_out = packet[UDP].sport
6292 self.icmp_external_id = packet[ICMP].id
6294 self.logger.error(ppp("Unexpected or invalid packet "
6295 "(outside network):", packet))
6298 def test_deterministic_mode(self):
6299 """ NAT plugin run deterministic mode """
6300 in_addr = '172.16.255.0'
6301 out_addr = '172.17.255.50'
6302 in_addr_t = '172.16.255.20'
6303 in_addr_n = socket.inet_aton(in_addr)
6304 out_addr_n = socket.inet_aton(out_addr)
6305 in_addr_t_n = socket.inet_aton(in_addr_t)
6309 nat_config = self.vapi.nat_show_config()
6310 self.assertEqual(1, nat_config.deterministic)
6312 self.vapi.nat_det_add_del_map(in_addr_n, in_plen, out_addr_n, out_plen)
6314 rep1 = self.vapi.nat_det_forward(in_addr_t_n)
6315 self.assertEqual(rep1.out_addr[:4], out_addr_n)
6316 rep2 = self.vapi.nat_det_reverse(out_addr_n, rep1.out_port_hi)
6317 self.assertEqual(rep2.in_addr[:4], in_addr_t_n)
6319 deterministic_mappings = self.vapi.nat_det_map_dump()
6320 self.assertEqual(len(deterministic_mappings), 1)
6321 dsm = deterministic_mappings[0]
6322 self.assertEqual(in_addr_n, dsm.in_addr[:4])
6323 self.assertEqual(in_plen, dsm.in_plen)
6324 self.assertEqual(out_addr_n, dsm.out_addr[:4])
6325 self.assertEqual(out_plen, dsm.out_plen)
6327 self.clear_nat_det()
6328 deterministic_mappings = self.vapi.nat_det_map_dump()
6329 self.assertEqual(len(deterministic_mappings), 0)
6331 def test_set_timeouts(self):
6332 """ Set deterministic NAT timeouts """
6333 timeouts_before = self.vapi.nat_get_timeouts()
6335 self.vapi.nat_set_timeouts(timeouts_before.udp + 10,
6336 timeouts_before.tcp_established + 10,
6337 timeouts_before.tcp_transitory + 10,
6338 timeouts_before.icmp + 10)
6340 timeouts_after = self.vapi.nat_get_timeouts()
6342 self.assertNotEqual(timeouts_before.udp, timeouts_after.udp)
6343 self.assertNotEqual(timeouts_before.icmp, timeouts_after.icmp)
6344 self.assertNotEqual(timeouts_before.tcp_established,
6345 timeouts_after.tcp_established)
6346 self.assertNotEqual(timeouts_before.tcp_transitory,
6347 timeouts_after.tcp_transitory)
6349 def test_det_in(self):
6350 """ Deterministic NAT translation test (TCP, UDP, ICMP) """
6352 nat_ip = "10.0.0.10"
6354 self.vapi.nat_det_add_del_map(self.pg0.remote_ip4n,
6356 socket.inet_aton(nat_ip),
6358 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
6359 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
6363 pkts = self.create_stream_in(self.pg0, self.pg1)
6364 self.pg0.add_stream(pkts)
6365 self.pg_enable_capture(self.pg_interfaces)
6367 capture = self.pg1.get_capture(len(pkts))
6368 self.verify_capture_out(capture, nat_ip)
6371 pkts = self.create_stream_out(self.pg1, nat_ip)
6372 self.pg1.add_stream(pkts)
6373 self.pg_enable_capture(self.pg_interfaces)
6375 capture = self.pg0.get_capture(len(pkts))
6376 self.verify_capture_in(capture, self.pg0)
6379 sessions = self.vapi.nat_det_session_dump(self.pg0.remote_ip4n)
6380 self.assertEqual(len(sessions), 3)
6384 self.assertEqual(s.ext_addr[:4], self.pg1.remote_ip4n)
6385 self.assertEqual(s.in_port, self.tcp_port_in)
6386 self.assertEqual(s.out_port, self.tcp_port_out)
6387 self.assertEqual(s.ext_port, self.tcp_external_port)
6391 self.assertEqual(s.ext_addr[:4], self.pg1.remote_ip4n)
6392 self.assertEqual(s.in_port, self.udp_port_in)
6393 self.assertEqual(s.out_port, self.udp_port_out)
6394 self.assertEqual(s.ext_port, self.udp_external_port)
6398 self.assertEqual(s.ext_addr[:4], self.pg1.remote_ip4n)
6399 self.assertEqual(s.in_port, self.icmp_id_in)
6400 self.assertEqual(s.out_port, self.icmp_external_id)
6402 def test_multiple_users(self):
6403 """ Deterministic NAT multiple users """
6405 nat_ip = "10.0.0.10"
6407 external_port = 6303
6409 host0 = self.pg0.remote_hosts[0]
6410 host1 = self.pg0.remote_hosts[1]
6412 self.vapi.nat_det_add_del_map(host0.ip4n,
6414 socket.inet_aton(nat_ip),
6416 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
6417 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
6421 p = (Ether(src=host0.mac, dst=self.pg0.local_mac) /
6422 IP(src=host0.ip4, dst=self.pg1.remote_ip4) /
6423 TCP(sport=port_in, dport=external_port))
6424 self.pg0.add_stream(p)
6425 self.pg_enable_capture(self.pg_interfaces)
6427 capture = self.pg1.get_capture(1)
6432 self.assertEqual(ip.src, nat_ip)
6433 self.assertEqual(ip.dst, self.pg1.remote_ip4)
6434 self.assertEqual(tcp.dport, external_port)
6435 port_out0 = tcp.sport
6437 self.logger.error(ppp("Unexpected or invalid packet:", p))
6441 p = (Ether(src=host1.mac, dst=self.pg0.local_mac) /
6442 IP(src=host1.ip4, dst=self.pg1.remote_ip4) /
6443 TCP(sport=port_in, dport=external_port))
6444 self.pg0.add_stream(p)
6445 self.pg_enable_capture(self.pg_interfaces)
6447 capture = self.pg1.get_capture(1)
6452 self.assertEqual(ip.src, nat_ip)
6453 self.assertEqual(ip.dst, self.pg1.remote_ip4)
6454 self.assertEqual(tcp.dport, external_port)
6455 port_out1 = tcp.sport
6457 self.logger.error(ppp("Unexpected or invalid packet:", p))
6460 dms = self.vapi.nat_det_map_dump()
6461 self.assertEqual(1, len(dms))
6462 self.assertEqual(2, dms[0].ses_num)
6465 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
6466 IP(src=self.pg1.remote_ip4, dst=nat_ip) /
6467 TCP(sport=external_port, dport=port_out0))
6468 self.pg1.add_stream(p)
6469 self.pg_enable_capture(self.pg_interfaces)
6471 capture = self.pg0.get_capture(1)
6476 self.assertEqual(ip.src, self.pg1.remote_ip4)
6477 self.assertEqual(ip.dst, host0.ip4)
6478 self.assertEqual(tcp.dport, port_in)
6479 self.assertEqual(tcp.sport, external_port)
6481 self.logger.error(ppp("Unexpected or invalid packet:", p))
6485 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
6486 IP(src=self.pg1.remote_ip4, dst=nat_ip) /
6487 TCP(sport=external_port, dport=port_out1))
6488 self.pg1.add_stream(p)
6489 self.pg_enable_capture(self.pg_interfaces)
6491 capture = self.pg0.get_capture(1)
6496 self.assertEqual(ip.src, self.pg1.remote_ip4)
6497 self.assertEqual(ip.dst, host1.ip4)
6498 self.assertEqual(tcp.dport, port_in)
6499 self.assertEqual(tcp.sport, external_port)
6501 self.logger.error(ppp("Unexpected or invalid packet", p))
6504 # session close api test
6505 self.vapi.nat_det_close_session_out(socket.inet_aton(nat_ip),
6507 self.pg1.remote_ip4n,
6509 dms = self.vapi.nat_det_map_dump()
6510 self.assertEqual(dms[0].ses_num, 1)
6512 self.vapi.nat_det_close_session_in(host0.ip4n,
6514 self.pg1.remote_ip4n,
6516 dms = self.vapi.nat_det_map_dump()
6517 self.assertEqual(dms[0].ses_num, 0)
6519 def test_tcp_session_close_detection_in(self):
6520 """ Deterministic NAT TCP session close from inside network """
6521 self.vapi.nat_det_add_del_map(self.pg0.remote_ip4n,
6523 socket.inet_aton(self.nat_addr),
6525 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
6526 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
6529 self.initiate_tcp_session(self.pg0, self.pg1)
6531 # close the session from inside
6533 # FIN 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,
6538 self.pg0.add_stream(p)
6539 self.pg_enable_capture(self.pg_interfaces)
6541 self.pg1.get_capture(1)
6545 # ACK packet out -> in
6546 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
6547 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
6548 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
6552 # FIN 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,
6559 self.pg1.add_stream(pkts)
6560 self.pg_enable_capture(self.pg_interfaces)
6562 self.pg0.get_capture(2)
6564 # ACK packet in -> out
6565 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6566 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6567 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
6569 self.pg0.add_stream(p)
6570 self.pg_enable_capture(self.pg_interfaces)
6572 self.pg1.get_capture(1)
6574 # Check if deterministic NAT44 closed the session
6575 dms = self.vapi.nat_det_map_dump()
6576 self.assertEqual(0, dms[0].ses_num)
6578 self.logger.error("TCP session termination failed")
6581 def test_tcp_session_close_detection_out(self):
6582 """ Deterministic NAT TCP session close from outside network """
6583 self.vapi.nat_det_add_del_map(self.pg0.remote_ip4n,
6585 socket.inet_aton(self.nat_addr),
6587 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
6588 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
6591 self.initiate_tcp_session(self.pg0, self.pg1)
6593 # close the session from outside
6595 # FIN packet out -> in
6596 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
6597 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
6598 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
6600 self.pg1.add_stream(p)
6601 self.pg_enable_capture(self.pg_interfaces)
6603 self.pg0.get_capture(1)
6607 # ACK packet in -> out
6608 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6609 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6610 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
6614 # ACK packet in -> out
6615 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6616 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6617 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
6621 self.pg0.add_stream(pkts)
6622 self.pg_enable_capture(self.pg_interfaces)
6624 self.pg1.get_capture(2)
6626 # ACK packet out -> in
6627 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
6628 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
6629 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
6631 self.pg1.add_stream(p)
6632 self.pg_enable_capture(self.pg_interfaces)
6634 self.pg0.get_capture(1)
6636 # Check if deterministic NAT44 closed the session
6637 dms = self.vapi.nat_det_map_dump()
6638 self.assertEqual(0, dms[0].ses_num)
6640 self.logger.error("TCP session termination failed")
6643 @unittest.skipUnless(running_extended_tests, "part of extended tests")
6644 def test_session_timeout(self):
6645 """ Deterministic NAT session timeouts """
6646 self.vapi.nat_det_add_del_map(self.pg0.remote_ip4n,
6648 socket.inet_aton(self.nat_addr),
6650 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
6651 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
6654 self.initiate_tcp_session(self.pg0, self.pg1)
6655 self.vapi.nat_set_timeouts(5, 5, 5, 5)
6656 pkts = self.create_stream_in(self.pg0, self.pg1)
6657 self.pg0.add_stream(pkts)
6658 self.pg_enable_capture(self.pg_interfaces)
6660 capture = self.pg1.get_capture(len(pkts))
6663 dms = self.vapi.nat_det_map_dump()
6664 self.assertEqual(0, dms[0].ses_num)
6666 @unittest.skipUnless(running_extended_tests, "part of extended tests")
6667 def test_session_limit_per_user(self):
6668 """ Deterministic NAT maximum sessions per user limit """
6669 self.vapi.nat_det_add_del_map(self.pg0.remote_ip4n,
6671 socket.inet_aton(self.nat_addr),
6673 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
6674 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
6676 self.vapi.set_ipfix_exporter(collector_address=self.pg2.remote_ip4n,
6677 src_address=self.pg2.local_ip4n,
6679 template_interval=10)
6680 self.vapi.nat_ipfix()
6683 for port in range(1025, 2025):
6684 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6685 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6686 UDP(sport=port, dport=port))
6689 self.pg0.add_stream(pkts)
6690 self.pg_enable_capture(self.pg_interfaces)
6692 capture = self.pg1.get_capture(len(pkts))
6694 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6695 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6696 UDP(sport=3001, dport=3002))
6697 self.pg0.add_stream(p)
6698 self.pg_enable_capture(self.pg_interfaces)
6700 capture = self.pg1.assert_nothing_captured()
6702 # verify ICMP error packet
6703 capture = self.pg0.get_capture(1)
6705 self.assertTrue(p.haslayer(ICMP))
6707 self.assertEqual(icmp.type, 3)
6708 self.assertEqual(icmp.code, 1)
6709 self.assertTrue(icmp.haslayer(IPerror))
6710 inner_ip = icmp[IPerror]
6711 self.assertEqual(inner_ip[UDPerror].sport, 3001)
6712 self.assertEqual(inner_ip[UDPerror].dport, 3002)
6714 dms = self.vapi.nat_det_map_dump()
6716 self.assertEqual(1000, dms[0].ses_num)
6718 # verify IPFIX logging
6719 self.vapi.cli("ipfix flush") # FIXME this should be an API call
6721 capture = self.pg2.get_capture(2)
6722 ipfix = IPFIXDecoder()
6723 # first load template
6725 self.assertTrue(p.haslayer(IPFIX))
6726 if p.haslayer(Template):
6727 ipfix.add_template(p.getlayer(Template))
6728 # verify events in data set
6730 if p.haslayer(Data):
6731 data = ipfix.decode_data_set(p.getlayer(Set))
6732 self.verify_ipfix_max_entries_per_user(data,
6734 self.pg0.remote_ip4n)
6736 def clear_nat_det(self):
6738 Clear deterministic NAT configuration.
6740 self.vapi.nat_ipfix(enable=0)
6741 self.vapi.nat_set_timeouts()
6742 deterministic_mappings = self.vapi.nat_det_map_dump()
6743 for dsm in deterministic_mappings:
6744 self.vapi.nat_det_add_del_map(dsm.in_addr,
6750 interfaces = self.vapi.nat44_interface_dump()
6751 for intf in interfaces:
6752 self.vapi.nat44_interface_add_del_feature(intf.sw_if_index,
6757 super(TestDeterministicNAT, self).tearDown()
6758 if not self.vpp_dead:
6759 self.logger.info(self.vapi.cli("show nat44 interfaces"))
6760 self.logger.info(self.vapi.cli("show nat timeouts"))
6762 self.vapi.cli("show nat44 deterministic mappings"))
6764 self.vapi.cli("show nat44 deterministic sessions"))
6765 self.clear_nat_det()
6768 class TestNAT64(MethodHolder):
6769 """ NAT64 Test Cases """
6772 def setUpConstants(cls):
6773 super(TestNAT64, cls).setUpConstants()
6774 cls.vpp_cmdline.extend(["nat", "{", "nat64 bib hash buckets 128",
6775 "nat64 st hash buckets 256", "}"])
6778 def setUpClass(cls):
6779 super(TestNAT64, cls).setUpClass()
6782 cls.tcp_port_in = 6303
6783 cls.tcp_port_out = 6303
6784 cls.udp_port_in = 6304
6785 cls.udp_port_out = 6304
6786 cls.icmp_id_in = 6305
6787 cls.icmp_id_out = 6305
6788 cls.tcp_external_port = 80
6789 cls.nat_addr = '10.0.0.3'
6790 cls.nat_addr_n = socket.inet_pton(socket.AF_INET, cls.nat_addr)
6792 cls.vrf1_nat_addr = '10.0.10.3'
6793 cls.vrf1_nat_addr_n = socket.inet_pton(socket.AF_INET,
6795 cls.ipfix_src_port = 4739
6796 cls.ipfix_domain_id = 1
6798 cls.create_pg_interfaces(range(6))
6799 cls.ip6_interfaces = list(cls.pg_interfaces[0:1])
6800 cls.ip6_interfaces.append(cls.pg_interfaces[2])
6801 cls.ip4_interfaces = list(cls.pg_interfaces[1:2])
6803 cls.vapi.ip_table_add_del(cls.vrf1_id, is_add=1, is_ipv6=1)
6805 cls.pg_interfaces[2].set_table_ip6(cls.vrf1_id)
6807 cls.pg0.generate_remote_hosts(2)
6809 for i in cls.ip6_interfaces:
6812 i.configure_ipv6_neighbors()
6814 for i in cls.ip4_interfaces:
6820 cls.pg3.config_ip4()
6821 cls.pg3.resolve_arp()
6822 cls.pg3.config_ip6()
6823 cls.pg3.configure_ipv6_neighbors()
6826 cls.pg5.config_ip6()
6829 super(TestNAT64, cls).tearDownClass()
6832 def test_nat64_inside_interface_handles_neighbor_advertisement(self):
6833 """ NAT64 inside interface handles Neighbor Advertisement """
6835 self.vapi.nat64_add_del_interface(self.pg5.sw_if_index)
6838 ping = (Ether(dst=self.pg5.local_mac, src=self.pg5.remote_mac) /
6839 IPv6(src=self.pg5.remote_ip6, dst=self.pg5.local_ip6) /
6840 ICMPv6EchoRequest())
6842 self.pg5.add_stream(pkts)
6843 self.pg_enable_capture(self.pg_interfaces)
6846 # Wait for Neighbor Solicitation
6847 capture = self.pg5.get_capture(len(pkts))
6850 self.assertEqual(packet[IPv6].src, self.pg5.local_ip6)
6851 self.assertEqual(packet.haslayer(ICMPv6ND_NS), 1)
6852 tgt = packet[ICMPv6ND_NS].tgt
6854 self.logger.error(ppp("Unexpected or invalid packet:", packet))
6857 # Send Neighbor Advertisement
6858 p = (Ether(dst=self.pg5.local_mac, src=self.pg5.remote_mac) /
6859 IPv6(src=self.pg5.remote_ip6, dst=self.pg5.local_ip6) /
6860 ICMPv6ND_NA(tgt=tgt) /
6861 ICMPv6NDOptDstLLAddr(lladdr=self.pg5.remote_mac))
6863 self.pg5.add_stream(pkts)
6864 self.pg_enable_capture(self.pg_interfaces)
6867 # Try to send ping again
6869 self.pg5.add_stream(pkts)
6870 self.pg_enable_capture(self.pg_interfaces)
6873 # Wait for ping reply
6874 capture = self.pg5.get_capture(len(pkts))
6877 self.assertEqual(packet[IPv6].src, self.pg5.local_ip6)
6878 self.assertEqual(packet[IPv6].dst, self.pg5.remote_ip6)
6879 self.assertEqual(packet.haslayer(ICMPv6EchoReply), 1)
6881 self.logger.error(ppp("Unexpected or invalid packet:", packet))
6884 def test_pool(self):
6885 """ Add/delete address to NAT64 pool """
6886 nat_addr = socket.inet_pton(socket.AF_INET, '1.2.3.4')
6888 self.vapi.nat64_add_del_pool_addr_range(nat_addr, nat_addr)
6890 addresses = self.vapi.nat64_pool_addr_dump()
6891 self.assertEqual(len(addresses), 1)
6892 self.assertEqual(addresses[0].address, nat_addr)
6894 self.vapi.nat64_add_del_pool_addr_range(nat_addr, nat_addr, is_add=0)
6896 addresses = self.vapi.nat64_pool_addr_dump()
6897 self.assertEqual(len(addresses), 0)
6899 def test_interface(self):
6900 """ Enable/disable NAT64 feature on the interface """
6901 self.vapi.nat64_add_del_interface(self.pg0.sw_if_index)
6902 self.vapi.nat64_add_del_interface(self.pg1.sw_if_index, is_inside=0)
6904 interfaces = self.vapi.nat64_interface_dump()
6905 self.assertEqual(len(interfaces), 2)
6908 for intf in interfaces:
6909 if intf.sw_if_index == self.pg0.sw_if_index:
6910 self.assertEqual(intf.is_inside, 1)
6912 elif intf.sw_if_index == self.pg1.sw_if_index:
6913 self.assertEqual(intf.is_inside, 0)
6915 self.assertTrue(pg0_found)
6916 self.assertTrue(pg1_found)
6918 features = self.vapi.cli("show interface features pg0")
6919 self.assertNotEqual(features.find('nat64-in2out'), -1)
6920 features = self.vapi.cli("show interface features pg1")
6921 self.assertNotEqual(features.find('nat64-out2in'), -1)
6923 self.vapi.nat64_add_del_interface(self.pg0.sw_if_index, is_add=0)
6924 self.vapi.nat64_add_del_interface(self.pg1.sw_if_index, is_add=0)
6926 interfaces = self.vapi.nat64_interface_dump()
6927 self.assertEqual(len(interfaces), 0)
6929 def test_static_bib(self):
6930 """ Add/delete static BIB entry """
6931 in_addr = socket.inet_pton(socket.AF_INET6,
6932 '2001:db8:85a3::8a2e:370:7334')
6933 out_addr = socket.inet_pton(socket.AF_INET, '10.1.1.3')
6936 proto = IP_PROTOS.tcp
6938 self.vapi.nat64_add_del_static_bib(in_addr,
6943 bib = self.vapi.nat64_bib_dump(IP_PROTOS.tcp)
6948 self.assertEqual(bibe.i_addr, in_addr)
6949 self.assertEqual(bibe.o_addr, out_addr)
6950 self.assertEqual(bibe.i_port, in_port)
6951 self.assertEqual(bibe.o_port, out_port)
6952 self.assertEqual(static_bib_num, 1)
6953 bibs = self.statistics.get_counter('/nat64/total-bibs')
6954 self.assertEqual(bibs[0][0], 1)
6956 self.vapi.nat64_add_del_static_bib(in_addr,
6962 bib = self.vapi.nat64_bib_dump(IP_PROTOS.tcp)
6967 self.assertEqual(static_bib_num, 0)
6968 bibs = self.statistics.get_counter('/nat64/total-bibs')
6969 self.assertEqual(bibs[0][0], 0)
6971 def test_set_timeouts(self):
6972 """ Set NAT64 timeouts """
6973 # verify default values
6974 timeouts = self.vapi.nat_get_timeouts()
6975 self.assertEqual(timeouts.udp, 300)
6976 self.assertEqual(timeouts.icmp, 60)
6977 self.assertEqual(timeouts.tcp_transitory, 240)
6978 self.assertEqual(timeouts.tcp_established, 7440)
6980 # set and verify custom values
6981 self.vapi.nat_set_timeouts(udp=200, icmp=30, tcp_transitory=250,
6982 tcp_established=7450)
6983 timeouts = self.vapi.nat_get_timeouts()
6984 self.assertEqual(timeouts.udp, 200)
6985 self.assertEqual(timeouts.icmp, 30)
6986 self.assertEqual(timeouts.tcp_transitory, 250)
6987 self.assertEqual(timeouts.tcp_established, 7450)
6989 def test_dynamic(self):
6990 """ NAT64 dynamic translation test """
6991 self.tcp_port_in = 6303
6992 self.udp_port_in = 6304
6993 self.icmp_id_in = 6305
6995 ses_num_start = self.nat64_get_ses_num()
6997 self.vapi.nat64_add_del_pool_addr_range(self.nat_addr_n,
6999 self.vapi.nat64_add_del_interface(self.pg0.sw_if_index)
7000 self.vapi.nat64_add_del_interface(self.pg1.sw_if_index, is_inside=0)
7003 tcpn = self.statistics.get_counter('/err/nat64-in2out/TCP packets')
7004 udpn = self.statistics.get_counter('/err/nat64-in2out/UDP packets')
7005 icmpn = self.statistics.get_counter('/err/nat64-in2out/ICMP packets')
7006 totaln = self.statistics.get_counter(
7007 '/err/nat64-in2out/good in2out packets processed')
7009 pkts = self.create_stream_in_ip6(self.pg0, self.pg1)
7010 self.pg0.add_stream(pkts)
7011 self.pg_enable_capture(self.pg_interfaces)
7013 capture = self.pg1.get_capture(len(pkts))
7014 self.verify_capture_out(capture, nat_ip=self.nat_addr,
7015 dst_ip=self.pg1.remote_ip4)
7017 err = self.statistics.get_counter('/err/nat64-in2out/TCP packets')
7018 self.assertEqual(err - tcpn, 1)
7019 err = self.statistics.get_counter('/err/nat64-in2out/UDP packets')
7020 self.assertEqual(err - udpn, 1)
7021 err = self.statistics.get_counter('/err/nat64-in2out/ICMP packets')
7022 self.assertEqual(err - icmpn, 1)
7023 err = self.statistics.get_counter(
7024 '/err/nat64-in2out/good in2out packets processed')
7025 self.assertEqual(err - totaln, 3)
7028 tcpn = self.statistics.get_counter('/err/nat64-out2in/TCP packets')
7029 udpn = self.statistics.get_counter('/err/nat64-out2in/UDP packets')
7030 icmpn = self.statistics.get_counter('/err/nat64-out2in/ICMP packets')
7031 totaln = self.statistics.get_counter(
7032 '/err/nat64-out2in/good out2in packets processed')
7034 pkts = self.create_stream_out(self.pg1, dst_ip=self.nat_addr)
7035 self.pg1.add_stream(pkts)
7036 self.pg_enable_capture(self.pg_interfaces)
7038 capture = self.pg0.get_capture(len(pkts))
7039 ip = IPv6(src=''.join(['64:ff9b::', self.pg1.remote_ip4]))
7040 self.verify_capture_in_ip6(capture, ip[IPv6].src, self.pg0.remote_ip6)
7042 err = self.statistics.get_counter('/err/nat64-out2in/TCP packets')
7043 self.assertEqual(err - tcpn, 1)
7044 err = self.statistics.get_counter('/err/nat64-out2in/UDP packets')
7045 self.assertEqual(err - udpn, 1)
7046 err = self.statistics.get_counter('/err/nat64-out2in/ICMP packets')
7047 self.assertEqual(err - icmpn, 1)
7048 err = self.statistics.get_counter(
7049 '/err/nat64-out2in/good out2in packets processed')
7050 self.assertEqual(err - totaln, 3)
7052 bibs = self.statistics.get_counter('/nat64/total-bibs')
7053 self.assertEqual(bibs[0][0], 3)
7054 sessions = self.statistics.get_counter('/nat64/total-sessions')
7055 self.assertEqual(sessions[0][0], 3)
7058 pkts = self.create_stream_in_ip6(self.pg0, self.pg1)
7059 self.pg0.add_stream(pkts)
7060 self.pg_enable_capture(self.pg_interfaces)
7062 capture = self.pg1.get_capture(len(pkts))
7063 self.verify_capture_out(capture, nat_ip=self.nat_addr,
7064 dst_ip=self.pg1.remote_ip4)
7067 pkts = self.create_stream_out(self.pg1, dst_ip=self.nat_addr)
7068 self.pg1.add_stream(pkts)
7069 self.pg_enable_capture(self.pg_interfaces)
7071 capture = self.pg0.get_capture(len(pkts))
7072 self.verify_capture_in_ip6(capture, ip[IPv6].src, self.pg0.remote_ip6)
7074 ses_num_end = self.nat64_get_ses_num()
7076 self.assertEqual(ses_num_end - ses_num_start, 3)
7078 # tenant with specific VRF
7079 self.vapi.nat64_add_del_pool_addr_range(self.vrf1_nat_addr_n,
7080 self.vrf1_nat_addr_n,
7081 vrf_id=self.vrf1_id)
7082 self.vapi.nat64_add_del_interface(self.pg2.sw_if_index)
7084 pkts = self.create_stream_in_ip6(self.pg2, self.pg1)
7085 self.pg2.add_stream(pkts)
7086 self.pg_enable_capture(self.pg_interfaces)
7088 capture = self.pg1.get_capture(len(pkts))
7089 self.verify_capture_out(capture, nat_ip=self.vrf1_nat_addr,
7090 dst_ip=self.pg1.remote_ip4)
7092 pkts = self.create_stream_out(self.pg1, dst_ip=self.vrf1_nat_addr)
7093 self.pg1.add_stream(pkts)
7094 self.pg_enable_capture(self.pg_interfaces)
7096 capture = self.pg2.get_capture(len(pkts))
7097 self.verify_capture_in_ip6(capture, ip[IPv6].src, self.pg2.remote_ip6)
7099 def test_static(self):
7100 """ NAT64 static translation test """
7101 self.tcp_port_in = 60303
7102 self.udp_port_in = 60304
7103 self.icmp_id_in = 60305
7104 self.tcp_port_out = 60303
7105 self.udp_port_out = 60304
7106 self.icmp_id_out = 60305
7108 ses_num_start = self.nat64_get_ses_num()
7110 self.vapi.nat64_add_del_pool_addr_range(self.nat_addr_n,
7112 self.vapi.nat64_add_del_interface(self.pg0.sw_if_index)
7113 self.vapi.nat64_add_del_interface(self.pg1.sw_if_index, is_inside=0)
7115 self.vapi.nat64_add_del_static_bib(self.pg0.remote_ip6n,
7120 self.vapi.nat64_add_del_static_bib(self.pg0.remote_ip6n,
7125 self.vapi.nat64_add_del_static_bib(self.pg0.remote_ip6n,
7132 pkts = self.create_stream_in_ip6(self.pg0, self.pg1)
7133 self.pg0.add_stream(pkts)
7134 self.pg_enable_capture(self.pg_interfaces)
7136 capture = self.pg1.get_capture(len(pkts))
7137 self.verify_capture_out(capture, nat_ip=self.nat_addr,
7138 dst_ip=self.pg1.remote_ip4, same_port=True)
7141 pkts = self.create_stream_out(self.pg1, dst_ip=self.nat_addr)
7142 self.pg1.add_stream(pkts)
7143 self.pg_enable_capture(self.pg_interfaces)
7145 capture = self.pg0.get_capture(len(pkts))
7146 ip = IPv6(src=''.join(['64:ff9b::', self.pg1.remote_ip4]))
7147 self.verify_capture_in_ip6(capture, ip[IPv6].src, self.pg0.remote_ip6)
7149 ses_num_end = self.nat64_get_ses_num()
7151 self.assertEqual(ses_num_end - ses_num_start, 3)
7153 @unittest.skipUnless(running_extended_tests, "part of extended tests")
7154 def test_session_timeout(self):
7155 """ NAT64 session timeout """
7156 self.icmp_id_in = 1234
7157 self.vapi.nat64_add_del_pool_addr_range(self.nat_addr_n,
7159 self.vapi.nat64_add_del_interface(self.pg0.sw_if_index)
7160 self.vapi.nat64_add_del_interface(self.pg1.sw_if_index, is_inside=0)
7161 self.vapi.nat_set_timeouts(icmp=5, tcp_transitory=5, tcp_established=5)
7163 pkts = self.create_stream_in_ip6(self.pg0, self.pg1)
7164 self.pg0.add_stream(pkts)
7165 self.pg_enable_capture(self.pg_interfaces)
7167 capture = self.pg1.get_capture(len(pkts))
7169 ses_num_before_timeout = self.nat64_get_ses_num()
7173 # ICMP and TCP session after timeout
7174 ses_num_after_timeout = self.nat64_get_ses_num()
7175 self.assertEqual(ses_num_before_timeout - ses_num_after_timeout, 2)
7177 def test_icmp_error(self):
7178 """ NAT64 ICMP Error message translation """
7179 self.tcp_port_in = 6303
7180 self.udp_port_in = 6304
7181 self.icmp_id_in = 6305
7183 self.vapi.nat64_add_del_pool_addr_range(self.nat_addr_n,
7185 self.vapi.nat64_add_del_interface(self.pg0.sw_if_index)
7186 self.vapi.nat64_add_del_interface(self.pg1.sw_if_index, is_inside=0)
7188 # send some packets to create sessions
7189 pkts = self.create_stream_in_ip6(self.pg0, self.pg1)
7190 self.pg0.add_stream(pkts)
7191 self.pg_enable_capture(self.pg_interfaces)
7193 capture_ip4 = self.pg1.get_capture(len(pkts))
7194 self.verify_capture_out(capture_ip4,
7195 nat_ip=self.nat_addr,
7196 dst_ip=self.pg1.remote_ip4)
7198 pkts = self.create_stream_out(self.pg1, dst_ip=self.nat_addr)
7199 self.pg1.add_stream(pkts)
7200 self.pg_enable_capture(self.pg_interfaces)
7202 capture_ip6 = self.pg0.get_capture(len(pkts))
7203 ip = IPv6(src=''.join(['64:ff9b::', self.pg1.remote_ip4]))
7204 self.verify_capture_in_ip6(capture_ip6, ip[IPv6].src,
7205 self.pg0.remote_ip6)
7208 pkts = [Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
7209 IPv6(src=self.pg0.remote_ip6, dst=ip[IPv6].src) /
7210 ICMPv6DestUnreach(code=1) /
7211 packet[IPv6] for packet in capture_ip6]
7212 self.pg0.add_stream(pkts)
7213 self.pg_enable_capture(self.pg_interfaces)
7215 capture = self.pg1.get_capture(len(pkts))
7216 for packet in capture:
7218 self.assertEqual(packet[IP].src, self.nat_addr)
7219 self.assertEqual(packet[IP].dst, self.pg1.remote_ip4)
7220 self.assertEqual(packet[ICMP].type, 3)
7221 self.assertEqual(packet[ICMP].code, 13)
7222 inner = packet[IPerror]
7223 self.assertEqual(inner.src, self.pg1.remote_ip4)
7224 self.assertEqual(inner.dst, self.nat_addr)
7225 self.assert_packet_checksums_valid(packet)
7226 if inner.haslayer(TCPerror):
7227 self.assertEqual(inner[TCPerror].dport, self.tcp_port_out)
7228 elif inner.haslayer(UDPerror):
7229 self.assertEqual(inner[UDPerror].dport, self.udp_port_out)
7231 self.assertEqual(inner[ICMPerror].id, self.icmp_id_out)
7233 self.logger.error(ppp("Unexpected or invalid packet:", packet))
7237 pkts = [Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
7238 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
7239 ICMP(type=3, code=13) /
7240 packet[IP] for packet in capture_ip4]
7241 self.pg1.add_stream(pkts)
7242 self.pg_enable_capture(self.pg_interfaces)
7244 capture = self.pg0.get_capture(len(pkts))
7245 for packet in capture:
7247 self.assertEqual(packet[IPv6].src, ip.src)
7248 self.assertEqual(packet[IPv6].dst, self.pg0.remote_ip6)
7249 icmp = packet[ICMPv6DestUnreach]
7250 self.assertEqual(icmp.code, 1)
7251 inner = icmp[IPerror6]
7252 self.assertEqual(inner.src, self.pg0.remote_ip6)
7253 self.assertEqual(inner.dst, ip.src)
7254 self.assert_icmpv6_checksum_valid(packet)
7255 if inner.haslayer(TCPerror):
7256 self.assertEqual(inner[TCPerror].sport, self.tcp_port_in)
7257 elif inner.haslayer(UDPerror):
7258 self.assertEqual(inner[UDPerror].sport, self.udp_port_in)
7260 self.assertEqual(inner[ICMPv6EchoRequest].id,
7263 self.logger.error(ppp("Unexpected or invalid packet:", packet))
7266 def test_hairpinning(self):
7267 """ NAT64 hairpinning """
7269 client = self.pg0.remote_hosts[0]
7270 server = self.pg0.remote_hosts[1]
7271 server_tcp_in_port = 22
7272 server_tcp_out_port = 4022
7273 server_udp_in_port = 23
7274 server_udp_out_port = 4023
7275 client_tcp_in_port = 1234
7276 client_udp_in_port = 1235
7277 client_tcp_out_port = 0
7278 client_udp_out_port = 0
7279 ip = IPv6(src=''.join(['64:ff9b::', self.nat_addr]))
7280 nat_addr_ip6 = ip.src
7282 self.vapi.nat64_add_del_pool_addr_range(self.nat_addr_n,
7284 self.vapi.nat64_add_del_interface(self.pg0.sw_if_index)
7285 self.vapi.nat64_add_del_interface(self.pg1.sw_if_index, is_inside=0)
7287 self.vapi.nat64_add_del_static_bib(server.ip6n,
7290 server_tcp_out_port,
7292 self.vapi.nat64_add_del_static_bib(server.ip6n,
7295 server_udp_out_port,
7300 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
7301 IPv6(src=client.ip6, dst=nat_addr_ip6) /
7302 TCP(sport=client_tcp_in_port, dport=server_tcp_out_port))
7304 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
7305 IPv6(src=client.ip6, dst=nat_addr_ip6) /
7306 UDP(sport=client_udp_in_port, dport=server_udp_out_port))
7308 self.pg0.add_stream(pkts)
7309 self.pg_enable_capture(self.pg_interfaces)
7311 capture = self.pg0.get_capture(len(pkts))
7312 for packet in capture:
7314 self.assertEqual(packet[IPv6].src, nat_addr_ip6)
7315 self.assertEqual(packet[IPv6].dst, server.ip6)
7316 self.assert_packet_checksums_valid(packet)
7317 if packet.haslayer(TCP):
7318 self.assertNotEqual(packet[TCP].sport, client_tcp_in_port)
7319 self.assertEqual(packet[TCP].dport, server_tcp_in_port)
7320 client_tcp_out_port = packet[TCP].sport
7322 self.assertNotEqual(packet[UDP].sport, client_udp_in_port)
7323 self.assertEqual(packet[UDP].dport, server_udp_in_port)
7324 client_udp_out_port = packet[UDP].sport
7326 self.logger.error(ppp("Unexpected or invalid packet:", packet))
7331 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
7332 IPv6(src=server.ip6, dst=nat_addr_ip6) /
7333 TCP(sport=server_tcp_in_port, dport=client_tcp_out_port))
7335 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
7336 IPv6(src=server.ip6, dst=nat_addr_ip6) /
7337 UDP(sport=server_udp_in_port, dport=client_udp_out_port))
7339 self.pg0.add_stream(pkts)
7340 self.pg_enable_capture(self.pg_interfaces)
7342 capture = self.pg0.get_capture(len(pkts))
7343 for packet in capture:
7345 self.assertEqual(packet[IPv6].src, nat_addr_ip6)
7346 self.assertEqual(packet[IPv6].dst, client.ip6)
7347 self.assert_packet_checksums_valid(packet)
7348 if packet.haslayer(TCP):
7349 self.assertEqual(packet[TCP].sport, server_tcp_out_port)
7350 self.assertEqual(packet[TCP].dport, client_tcp_in_port)
7352 self.assertEqual(packet[UDP].sport, server_udp_out_port)
7353 self.assertEqual(packet[UDP].dport, client_udp_in_port)
7355 self.logger.error(ppp("Unexpected or invalid packet:", packet))
7360 pkts = [Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
7361 IPv6(src=client.ip6, dst=nat_addr_ip6) /
7362 ICMPv6DestUnreach(code=1) /
7363 packet[IPv6] for packet in capture]
7364 self.pg0.add_stream(pkts)
7365 self.pg_enable_capture(self.pg_interfaces)
7367 capture = self.pg0.get_capture(len(pkts))
7368 for packet in capture:
7370 self.assertEqual(packet[IPv6].src, nat_addr_ip6)
7371 self.assertEqual(packet[IPv6].dst, server.ip6)
7372 icmp = packet[ICMPv6DestUnreach]
7373 self.assertEqual(icmp.code, 1)
7374 inner = icmp[IPerror6]
7375 self.assertEqual(inner.src, server.ip6)
7376 self.assertEqual(inner.dst, nat_addr_ip6)
7377 self.assert_packet_checksums_valid(packet)
7378 if inner.haslayer(TCPerror):
7379 self.assertEqual(inner[TCPerror].sport, server_tcp_in_port)
7380 self.assertEqual(inner[TCPerror].dport,
7381 client_tcp_out_port)
7383 self.assertEqual(inner[UDPerror].sport, server_udp_in_port)
7384 self.assertEqual(inner[UDPerror].dport,
7385 client_udp_out_port)
7387 self.logger.error(ppp("Unexpected or invalid packet:", packet))
7390 def test_prefix(self):
7391 """ NAT64 Network-Specific Prefix """
7393 self.vapi.nat64_add_del_pool_addr_range(self.nat_addr_n,
7395 self.vapi.nat64_add_del_interface(self.pg0.sw_if_index)
7396 self.vapi.nat64_add_del_interface(self.pg1.sw_if_index, is_inside=0)
7397 self.vapi.nat64_add_del_pool_addr_range(self.vrf1_nat_addr_n,
7398 self.vrf1_nat_addr_n,
7399 vrf_id=self.vrf1_id)
7400 self.vapi.nat64_add_del_interface(self.pg2.sw_if_index)
7403 global_pref64 = "2001:db8::"
7404 global_pref64_n = socket.inet_pton(socket.AF_INET6, global_pref64)
7405 global_pref64_len = 32
7406 self.vapi.nat64_add_del_prefix(global_pref64_n, global_pref64_len)
7408 prefix = self.vapi.nat64_prefix_dump()
7409 self.assertEqual(len(prefix), 1)
7410 self.assertEqual(prefix[0].prefix, global_pref64_n)
7411 self.assertEqual(prefix[0].prefix_len, global_pref64_len)
7412 self.assertEqual(prefix[0].vrf_id, 0)
7414 # Add tenant specific prefix
7415 vrf1_pref64 = "2001:db8:122:300::"
7416 vrf1_pref64_n = socket.inet_pton(socket.AF_INET6, vrf1_pref64)
7417 vrf1_pref64_len = 56
7418 self.vapi.nat64_add_del_prefix(vrf1_pref64_n,
7420 vrf_id=self.vrf1_id)
7421 prefix = self.vapi.nat64_prefix_dump()
7422 self.assertEqual(len(prefix), 2)
7425 pkts = self.create_stream_in_ip6(self.pg0,
7428 plen=global_pref64_len)
7429 self.pg0.add_stream(pkts)
7430 self.pg_enable_capture(self.pg_interfaces)
7432 capture = self.pg1.get_capture(len(pkts))
7433 self.verify_capture_out(capture, nat_ip=self.nat_addr,
7434 dst_ip=self.pg1.remote_ip4)
7436 pkts = self.create_stream_out(self.pg1, dst_ip=self.nat_addr)
7437 self.pg1.add_stream(pkts)
7438 self.pg_enable_capture(self.pg_interfaces)
7440 capture = self.pg0.get_capture(len(pkts))
7441 dst_ip = self.compose_ip6(self.pg1.remote_ip4,
7444 self.verify_capture_in_ip6(capture, dst_ip, self.pg0.remote_ip6)
7446 # Tenant specific prefix
7447 pkts = self.create_stream_in_ip6(self.pg2,
7450 plen=vrf1_pref64_len)
7451 self.pg2.add_stream(pkts)
7452 self.pg_enable_capture(self.pg_interfaces)
7454 capture = self.pg1.get_capture(len(pkts))
7455 self.verify_capture_out(capture, nat_ip=self.vrf1_nat_addr,
7456 dst_ip=self.pg1.remote_ip4)
7458 pkts = self.create_stream_out(self.pg1, dst_ip=self.vrf1_nat_addr)
7459 self.pg1.add_stream(pkts)
7460 self.pg_enable_capture(self.pg_interfaces)
7462 capture = self.pg2.get_capture(len(pkts))
7463 dst_ip = self.compose_ip6(self.pg1.remote_ip4,
7466 self.verify_capture_in_ip6(capture, dst_ip, self.pg2.remote_ip6)
7468 def test_unknown_proto(self):
7469 """ NAT64 translate packet with unknown protocol """
7471 self.vapi.nat64_add_del_pool_addr_range(self.nat_addr_n,
7473 self.vapi.nat64_add_del_interface(self.pg0.sw_if_index)
7474 self.vapi.nat64_add_del_interface(self.pg1.sw_if_index, is_inside=0)
7475 remote_ip6 = self.compose_ip6(self.pg1.remote_ip4, '64:ff9b::', 96)
7478 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
7479 IPv6(src=self.pg0.remote_ip6, dst=remote_ip6) /
7480 TCP(sport=self.tcp_port_in, dport=20))
7481 self.pg0.add_stream(p)
7482 self.pg_enable_capture(self.pg_interfaces)
7484 p = self.pg1.get_capture(1)
7486 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
7487 IPv6(src=self.pg0.remote_ip6, dst=remote_ip6, nh=47) /
7489 IP(src=self.pg2.local_ip4, dst=self.pg2.remote_ip4) /
7490 TCP(sport=1234, dport=1234))
7491 self.pg0.add_stream(p)
7492 self.pg_enable_capture(self.pg_interfaces)
7494 p = self.pg1.get_capture(1)
7497 self.assertEqual(packet[IP].src, self.nat_addr)
7498 self.assertEqual(packet[IP].dst, self.pg1.remote_ip4)
7499 self.assertEqual(packet.haslayer(GRE), 1)
7500 self.assert_packet_checksums_valid(packet)
7502 self.logger.error(ppp("Unexpected or invalid packet:", packet))
7506 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
7507 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
7509 IP(src=self.pg2.remote_ip4, dst=self.pg2.local_ip4) /
7510 TCP(sport=1234, dport=1234))
7511 self.pg1.add_stream(p)
7512 self.pg_enable_capture(self.pg_interfaces)
7514 p = self.pg0.get_capture(1)
7517 self.assertEqual(packet[IPv6].src, remote_ip6)
7518 self.assertEqual(packet[IPv6].dst, self.pg0.remote_ip6)
7519 self.assertEqual(packet[IPv6].nh, 47)
7521 self.logger.error(ppp("Unexpected or invalid packet:", packet))
7524 def test_hairpinning_unknown_proto(self):
7525 """ NAT64 translate packet with unknown protocol - hairpinning """
7527 client = self.pg0.remote_hosts[0]
7528 server = self.pg0.remote_hosts[1]
7529 server_tcp_in_port = 22
7530 server_tcp_out_port = 4022
7531 client_tcp_in_port = 1234
7532 client_tcp_out_port = 1235
7533 server_nat_ip = "10.0.0.100"
7534 client_nat_ip = "10.0.0.110"
7535 server_nat_ip_n = socket.inet_pton(socket.AF_INET, server_nat_ip)
7536 client_nat_ip_n = socket.inet_pton(socket.AF_INET, client_nat_ip)
7537 server_nat_ip6 = self.compose_ip6(server_nat_ip, '64:ff9b::', 96)
7538 client_nat_ip6 = self.compose_ip6(client_nat_ip, '64:ff9b::', 96)
7540 self.vapi.nat64_add_del_pool_addr_range(server_nat_ip_n,
7542 self.vapi.nat64_add_del_interface(self.pg0.sw_if_index)
7543 self.vapi.nat64_add_del_interface(self.pg1.sw_if_index, is_inside=0)
7545 self.vapi.nat64_add_del_static_bib(server.ip6n,
7548 server_tcp_out_port,
7551 self.vapi.nat64_add_del_static_bib(server.ip6n,
7557 self.vapi.nat64_add_del_static_bib(client.ip6n,
7560 client_tcp_out_port,
7564 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
7565 IPv6(src=client.ip6, dst=server_nat_ip6) /
7566 TCP(sport=client_tcp_in_port, dport=server_tcp_out_port))
7567 self.pg0.add_stream(p)
7568 self.pg_enable_capture(self.pg_interfaces)
7570 p = self.pg0.get_capture(1)
7572 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
7573 IPv6(src=client.ip6, dst=server_nat_ip6, nh=IP_PROTOS.gre) /
7575 IP(src=self.pg2.local_ip4, dst=self.pg2.remote_ip4) /
7576 TCP(sport=1234, dport=1234))
7577 self.pg0.add_stream(p)
7578 self.pg_enable_capture(self.pg_interfaces)
7580 p = self.pg0.get_capture(1)
7583 self.assertEqual(packet[IPv6].src, client_nat_ip6)
7584 self.assertEqual(packet[IPv6].dst, server.ip6)
7585 self.assertEqual(packet[IPv6].nh, IP_PROTOS.gre)
7587 self.logger.error(ppp("Unexpected or invalid packet:", packet))
7591 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
7592 IPv6(src=server.ip6, dst=client_nat_ip6, nh=IP_PROTOS.gre) /
7594 IP(src=self.pg2.remote_ip4, dst=self.pg2.local_ip4) /
7595 TCP(sport=1234, dport=1234))
7596 self.pg0.add_stream(p)
7597 self.pg_enable_capture(self.pg_interfaces)
7599 p = self.pg0.get_capture(1)
7602 self.assertEqual(packet[IPv6].src, server_nat_ip6)
7603 self.assertEqual(packet[IPv6].dst, client.ip6)
7604 self.assertEqual(packet[IPv6].nh, IP_PROTOS.gre)
7606 self.logger.error(ppp("Unexpected or invalid packet:", packet))
7609 def test_one_armed_nat64(self):
7610 """ One armed NAT64 """
7612 remote_host_ip6 = self.compose_ip6(self.pg3.remote_ip4,
7616 self.vapi.nat64_add_del_pool_addr_range(self.nat_addr_n,
7618 self.vapi.nat64_add_del_interface(self.pg3.sw_if_index)
7619 self.vapi.nat64_add_del_interface(self.pg3.sw_if_index, is_inside=0)
7622 p = (Ether(src=self.pg3.remote_mac, dst=self.pg3.local_mac) /
7623 IPv6(src=self.pg3.remote_ip6, dst=remote_host_ip6) /
7624 TCP(sport=12345, dport=80))
7625 self.pg3.add_stream(p)
7626 self.pg_enable_capture(self.pg_interfaces)
7628 capture = self.pg3.get_capture(1)
7633 self.assertEqual(ip.src, self.nat_addr)
7634 self.assertEqual(ip.dst, self.pg3.remote_ip4)
7635 self.assertNotEqual(tcp.sport, 12345)
7636 external_port = tcp.sport
7637 self.assertEqual(tcp.dport, 80)
7638 self.assert_packet_checksums_valid(p)
7640 self.logger.error(ppp("Unexpected or invalid packet:", p))
7644 p = (Ether(src=self.pg3.remote_mac, dst=self.pg3.local_mac) /
7645 IP(src=self.pg3.remote_ip4, dst=self.nat_addr) /
7646 TCP(sport=80, dport=external_port))
7647 self.pg3.add_stream(p)
7648 self.pg_enable_capture(self.pg_interfaces)
7650 capture = self.pg3.get_capture(1)
7655 self.assertEqual(ip.src, remote_host_ip6)
7656 self.assertEqual(ip.dst, self.pg3.remote_ip6)
7657 self.assertEqual(tcp.sport, 80)
7658 self.assertEqual(tcp.dport, 12345)
7659 self.assert_packet_checksums_valid(p)
7661 self.logger.error(ppp("Unexpected or invalid packet:", p))
7664 def test_frag_in_order(self):
7665 """ NAT64 translate fragments arriving in order """
7666 self.tcp_port_in = random.randint(1025, 65535)
7668 self.vapi.nat64_add_del_pool_addr_range(self.nat_addr_n,
7670 self.vapi.nat64_add_del_interface(self.pg0.sw_if_index)
7671 self.vapi.nat64_add_del_interface(self.pg1.sw_if_index, is_inside=0)
7673 reass = self.vapi.nat_reass_dump()
7674 reass_n_start = len(reass)
7678 pkts = self.create_stream_frag_ip6(self.pg0, self.pg1.remote_ip4,
7679 self.tcp_port_in, 20, data)
7680 self.pg0.add_stream(pkts)
7681 self.pg_enable_capture(self.pg_interfaces)
7683 frags = self.pg1.get_capture(len(pkts))
7684 p = self.reass_frags_and_verify(frags,
7686 self.pg1.remote_ip4)
7687 self.assertEqual(p[TCP].dport, 20)
7688 self.assertNotEqual(p[TCP].sport, self.tcp_port_in)
7689 self.tcp_port_out = p[TCP].sport
7690 self.assertEqual(data, p[Raw].load)
7693 data = "A" * 4 + "b" * 16 + "C" * 3
7694 pkts = self.create_stream_frag(self.pg1,
7699 self.pg1.add_stream(pkts)
7700 self.pg_enable_capture(self.pg_interfaces)
7702 frags = self.pg0.get_capture(len(pkts))
7703 src = self.compose_ip6(self.pg1.remote_ip4, '64:ff9b::', 96)
7704 p = self.reass_frags_and_verify_ip6(frags, src, self.pg0.remote_ip6)
7705 self.assertEqual(p[TCP].sport, 20)
7706 self.assertEqual(p[TCP].dport, self.tcp_port_in)
7707 self.assertEqual(data, p[Raw].load)
7709 reass = self.vapi.nat_reass_dump()
7710 reass_n_end = len(reass)
7712 self.assertEqual(reass_n_end - reass_n_start, 2)
7714 def test_reass_hairpinning(self):
7715 """ NAT64 fragments hairpinning """
7717 server = self.pg0.remote_hosts[1]
7718 server_in_port = random.randint(1025, 65535)
7719 server_out_port = random.randint(1025, 65535)
7720 client_in_port = random.randint(1025, 65535)
7721 ip = IPv6(src=''.join(['64:ff9b::', self.nat_addr]))
7722 nat_addr_ip6 = ip.src
7724 self.vapi.nat64_add_del_pool_addr_range(self.nat_addr_n,
7726 self.vapi.nat64_add_del_interface(self.pg0.sw_if_index)
7727 self.vapi.nat64_add_del_interface(self.pg1.sw_if_index, is_inside=0)
7729 # add static BIB entry for server
7730 self.vapi.nat64_add_del_static_bib(server.ip6n,
7736 # send packet from host to server
7737 pkts = self.create_stream_frag_ip6(self.pg0,
7742 self.pg0.add_stream(pkts)
7743 self.pg_enable_capture(self.pg_interfaces)
7745 frags = self.pg0.get_capture(len(pkts))
7746 p = self.reass_frags_and_verify_ip6(frags, nat_addr_ip6, server.ip6)
7747 self.assertNotEqual(p[TCP].sport, client_in_port)
7748 self.assertEqual(p[TCP].dport, server_in_port)
7749 self.assertEqual(data, p[Raw].load)
7751 def test_frag_out_of_order(self):
7752 """ NAT64 translate fragments arriving out of order """
7753 self.tcp_port_in = random.randint(1025, 65535)
7755 self.vapi.nat64_add_del_pool_addr_range(self.nat_addr_n,
7757 self.vapi.nat64_add_del_interface(self.pg0.sw_if_index)
7758 self.vapi.nat64_add_del_interface(self.pg1.sw_if_index, is_inside=0)
7762 pkts = self.create_stream_frag_ip6(self.pg0, self.pg1.remote_ip4,
7763 self.tcp_port_in, 20, data)
7765 self.pg0.add_stream(pkts)
7766 self.pg_enable_capture(self.pg_interfaces)
7768 frags = self.pg1.get_capture(len(pkts))
7769 p = self.reass_frags_and_verify(frags,
7771 self.pg1.remote_ip4)
7772 self.assertEqual(p[TCP].dport, 20)
7773 self.assertNotEqual(p[TCP].sport, self.tcp_port_in)
7774 self.tcp_port_out = p[TCP].sport
7775 self.assertEqual(data, p[Raw].load)
7778 data = "A" * 4 + "B" * 16 + "C" * 3
7779 pkts = self.create_stream_frag(self.pg1,
7785 self.pg1.add_stream(pkts)
7786 self.pg_enable_capture(self.pg_interfaces)
7788 frags = self.pg0.get_capture(len(pkts))
7789 src = self.compose_ip6(self.pg1.remote_ip4, '64:ff9b::', 96)
7790 p = self.reass_frags_and_verify_ip6(frags, src, self.pg0.remote_ip6)
7791 self.assertEqual(p[TCP].sport, 20)
7792 self.assertEqual(p[TCP].dport, self.tcp_port_in)
7793 self.assertEqual(data, p[Raw].load)
7795 def test_interface_addr(self):
7796 """ Acquire NAT64 pool addresses from interface """
7797 self.vapi.nat64_add_interface_addr(self.pg4.sw_if_index)
7799 # no address in NAT64 pool
7800 adresses = self.vapi.nat44_address_dump()
7801 self.assertEqual(0, len(adresses))
7803 # configure interface address and check NAT64 address pool
7804 self.pg4.config_ip4()
7805 addresses = self.vapi.nat64_pool_addr_dump()
7806 self.assertEqual(len(addresses), 1)
7807 self.assertEqual(addresses[0].address, self.pg4.local_ip4n)
7809 # remove interface address and check NAT64 address pool
7810 self.pg4.unconfig_ip4()
7811 addresses = self.vapi.nat64_pool_addr_dump()
7812 self.assertEqual(0, len(adresses))
7814 @unittest.skipUnless(running_extended_tests, "part of extended tests")
7815 def test_ipfix_max_bibs_sessions(self):
7816 """ IPFIX logging maximum session and BIB entries exceeded """
7819 remote_host_ip6 = self.compose_ip6(self.pg1.remote_ip4,
7823 self.vapi.nat64_add_del_pool_addr_range(self.nat_addr_n,
7825 self.vapi.nat64_add_del_interface(self.pg0.sw_if_index)
7826 self.vapi.nat64_add_del_interface(self.pg1.sw_if_index, is_inside=0)
7830 for i in range(0, max_bibs):
7831 src = "fd01:aa::%x" % (i)
7832 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
7833 IPv6(src=src, dst=remote_host_ip6) /
7834 TCP(sport=12345, dport=80))
7836 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
7837 IPv6(src=src, dst=remote_host_ip6) /
7838 TCP(sport=12345, dport=22))
7840 self.pg0.add_stream(pkts)
7841 self.pg_enable_capture(self.pg_interfaces)
7843 self.pg1.get_capture(max_sessions)
7845 self.vapi.set_ipfix_exporter(collector_address=self.pg3.remote_ip4n,
7846 src_address=self.pg3.local_ip4n,
7848 template_interval=10)
7849 self.vapi.nat_ipfix(domain_id=self.ipfix_domain_id,
7850 src_port=self.ipfix_src_port)
7852 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
7853 IPv6(src=src, dst=remote_host_ip6) /
7854 TCP(sport=12345, dport=25))
7855 self.pg0.add_stream(p)
7856 self.pg_enable_capture(self.pg_interfaces)
7858 self.pg1.assert_nothing_captured()
7860 self.vapi.cli("ipfix flush") # FIXME this should be an API call
7861 capture = self.pg3.get_capture(9)
7862 ipfix = IPFIXDecoder()
7863 # first load template
7865 self.assertTrue(p.haslayer(IPFIX))
7866 self.assertEqual(p[IP].src, self.pg3.local_ip4)
7867 self.assertEqual(p[IP].dst, self.pg3.remote_ip4)
7868 self.assertEqual(p[UDP].sport, self.ipfix_src_port)
7869 self.assertEqual(p[UDP].dport, 4739)
7870 self.assertEqual(p[IPFIX].observationDomainID,
7871 self.ipfix_domain_id)
7872 if p.haslayer(Template):
7873 ipfix.add_template(p.getlayer(Template))
7874 # verify events in data set
7876 if p.haslayer(Data):
7877 data = ipfix.decode_data_set(p.getlayer(Set))
7878 self.verify_ipfix_max_sessions(data, max_sessions)
7880 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
7881 IPv6(src=self.pg0.remote_ip6, dst=remote_host_ip6) /
7882 TCP(sport=12345, dport=80))
7883 self.pg0.add_stream(p)
7884 self.pg_enable_capture(self.pg_interfaces)
7886 self.pg1.assert_nothing_captured()
7888 self.vapi.cli("ipfix flush") # FIXME this should be an API call
7889 capture = self.pg3.get_capture(1)
7890 # verify events in data set
7892 self.assertTrue(p.haslayer(IPFIX))
7893 self.assertEqual(p[IP].src, self.pg3.local_ip4)
7894 self.assertEqual(p[IP].dst, self.pg3.remote_ip4)
7895 self.assertEqual(p[UDP].sport, self.ipfix_src_port)
7896 self.assertEqual(p[UDP].dport, 4739)
7897 self.assertEqual(p[IPFIX].observationDomainID,
7898 self.ipfix_domain_id)
7899 if p.haslayer(Data):
7900 data = ipfix.decode_data_set(p.getlayer(Set))
7901 self.verify_ipfix_max_bibs(data, max_bibs)
7903 def test_ipfix_max_frags(self):
7904 """ IPFIX logging maximum fragments pending reassembly exceeded """
7905 self.vapi.nat64_add_del_pool_addr_range(self.nat_addr_n,
7907 self.vapi.nat64_add_del_interface(self.pg0.sw_if_index)
7908 self.vapi.nat64_add_del_interface(self.pg1.sw_if_index, is_inside=0)
7909 self.vapi.nat_set_reass(max_frag=1, is_ip6=1)
7910 self.vapi.set_ipfix_exporter(collector_address=self.pg3.remote_ip4n,
7911 src_address=self.pg3.local_ip4n,
7913 template_interval=10)
7914 self.vapi.nat_ipfix(domain_id=self.ipfix_domain_id,
7915 src_port=self.ipfix_src_port)
7918 pkts = self.create_stream_frag_ip6(self.pg0, self.pg1.remote_ip4,
7919 self.tcp_port_in, 20, data)
7921 self.pg0.add_stream(pkts)
7922 self.pg_enable_capture(self.pg_interfaces)
7924 self.pg1.assert_nothing_captured()
7926 self.vapi.cli("ipfix flush") # FIXME this should be an API call
7927 capture = self.pg3.get_capture(9)
7928 ipfix = IPFIXDecoder()
7929 # first load template
7931 self.assertTrue(p.haslayer(IPFIX))
7932 self.assertEqual(p[IP].src, self.pg3.local_ip4)
7933 self.assertEqual(p[IP].dst, self.pg3.remote_ip4)
7934 self.assertEqual(p[UDP].sport, self.ipfix_src_port)
7935 self.assertEqual(p[UDP].dport, 4739)
7936 self.assertEqual(p[IPFIX].observationDomainID,
7937 self.ipfix_domain_id)
7938 if p.haslayer(Template):
7939 ipfix.add_template(p.getlayer(Template))
7940 # verify events in data set
7942 if p.haslayer(Data):
7943 data = ipfix.decode_data_set(p.getlayer(Set))
7944 self.verify_ipfix_max_fragments_ip6(data, 1,
7945 self.pg0.remote_ip6n)
7947 def test_ipfix_bib_ses(self):
7948 """ IPFIX logging NAT64 BIB/session create and delete events """
7949 self.tcp_port_in = random.randint(1025, 65535)
7950 remote_host_ip6 = self.compose_ip6(self.pg1.remote_ip4,
7954 self.vapi.nat64_add_del_pool_addr_range(self.nat_addr_n,
7956 self.vapi.nat64_add_del_interface(self.pg0.sw_if_index)
7957 self.vapi.nat64_add_del_interface(self.pg1.sw_if_index, is_inside=0)
7958 self.vapi.set_ipfix_exporter(collector_address=self.pg3.remote_ip4n,
7959 src_address=self.pg3.local_ip4n,
7961 template_interval=10)
7962 self.vapi.nat_ipfix(domain_id=self.ipfix_domain_id,
7963 src_port=self.ipfix_src_port)
7966 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
7967 IPv6(src=self.pg0.remote_ip6, dst=remote_host_ip6) /
7968 TCP(sport=self.tcp_port_in, dport=25))
7969 self.pg0.add_stream(p)
7970 self.pg_enable_capture(self.pg_interfaces)
7972 p = self.pg1.get_capture(1)
7973 self.tcp_port_out = p[0][TCP].sport
7974 self.vapi.cli("ipfix flush") # FIXME this should be an API call
7975 capture = self.pg3.get_capture(10)
7976 ipfix = IPFIXDecoder()
7977 # first load template
7979 self.assertTrue(p.haslayer(IPFIX))
7980 self.assertEqual(p[IP].src, self.pg3.local_ip4)
7981 self.assertEqual(p[IP].dst, self.pg3.remote_ip4)
7982 self.assertEqual(p[UDP].sport, self.ipfix_src_port)
7983 self.assertEqual(p[UDP].dport, 4739)
7984 self.assertEqual(p[IPFIX].observationDomainID,
7985 self.ipfix_domain_id)
7986 if p.haslayer(Template):
7987 ipfix.add_template(p.getlayer(Template))
7988 # verify events in data set
7990 if p.haslayer(Data):
7991 data = ipfix.decode_data_set(p.getlayer(Set))
7992 if ord(data[0][230]) == 10:
7993 self.verify_ipfix_bib(data, 1, self.pg0.remote_ip6n)
7994 elif ord(data[0][230]) == 6:
7995 self.verify_ipfix_nat64_ses(data,
7997 self.pg0.remote_ip6n,
7998 self.pg1.remote_ip4,
8001 self.logger.error(ppp("Unexpected or invalid packet: ", p))
8004 self.pg_enable_capture(self.pg_interfaces)
8005 self.vapi.nat64_add_del_pool_addr_range(self.nat_addr_n,
8008 self.vapi.cli("ipfix flush") # FIXME this should be an API call
8009 capture = self.pg3.get_capture(2)
8010 # verify events in data set
8012 self.assertTrue(p.haslayer(IPFIX))
8013 self.assertEqual(p[IP].src, self.pg3.local_ip4)
8014 self.assertEqual(p[IP].dst, self.pg3.remote_ip4)
8015 self.assertEqual(p[UDP].sport, self.ipfix_src_port)
8016 self.assertEqual(p[UDP].dport, 4739)
8017 self.assertEqual(p[IPFIX].observationDomainID,
8018 self.ipfix_domain_id)
8019 if p.haslayer(Data):
8020 data = ipfix.decode_data_set(p.getlayer(Set))
8021 if ord(data[0][230]) == 11:
8022 self.verify_ipfix_bib(data, 0, self.pg0.remote_ip6n)
8023 elif ord(data[0][230]) == 7:
8024 self.verify_ipfix_nat64_ses(data,
8026 self.pg0.remote_ip6n,
8027 self.pg1.remote_ip4,
8030 self.logger.error(ppp("Unexpected or invalid packet: ", p))
8032 def test_syslog_sess(self):
8033 """ Test syslog session creation and deletion """
8034 self.tcp_port_in = random.randint(1025, 65535)
8035 remote_host_ip6 = self.compose_ip6(self.pg1.remote_ip4,
8039 self.vapi.nat64_add_del_pool_addr_range(self.nat_addr_n,
8041 self.vapi.nat64_add_del_interface(self.pg0.sw_if_index)
8042 self.vapi.nat64_add_del_interface(self.pg1.sw_if_index, is_inside=0)
8043 self.vapi.syslog_set_filter(SYSLOG_SEVERITY.INFO)
8044 self.vapi.syslog_set_sender(self.pg3.remote_ip4n, self.pg3.local_ip4n)
8046 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
8047 IPv6(src=self.pg0.remote_ip6, dst=remote_host_ip6) /
8048 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port))
8049 self.pg0.add_stream(p)
8050 self.pg_enable_capture(self.pg_interfaces)
8052 p = self.pg1.get_capture(1)
8053 self.tcp_port_out = p[0][TCP].sport
8054 capture = self.pg3.get_capture(1)
8055 self.verify_syslog_sess(capture[0][Raw].load, is_ip6=True)
8057 self.pg_enable_capture(self.pg_interfaces)
8059 self.vapi.nat64_add_del_pool_addr_range(self.nat_addr_n,
8062 capture = self.pg3.get_capture(1)
8063 self.verify_syslog_sess(capture[0][Raw].load, False, True)
8065 def nat64_get_ses_num(self):
8067 Return number of active NAT64 sessions.
8069 st = self.vapi.nat64_st_dump()
8072 def clear_nat64(self):
8074 Clear NAT64 configuration.
8076 self.vapi.nat_ipfix(enable=0, src_port=self.ipfix_src_port,
8077 domain_id=self.ipfix_domain_id)
8078 self.ipfix_src_port = 4739
8079 self.ipfix_domain_id = 1
8081 self.vapi.syslog_set_filter(SYSLOG_SEVERITY.EMERG)
8083 self.vapi.nat_set_timeouts()
8085 interfaces = self.vapi.nat64_interface_dump()
8086 for intf in interfaces:
8087 if intf.is_inside > 1:
8088 self.vapi.nat64_add_del_interface(intf.sw_if_index,
8091 self.vapi.nat64_add_del_interface(intf.sw_if_index,
8095 bib = self.vapi.nat64_bib_dump(255)
8098 self.vapi.nat64_add_del_static_bib(bibe.i_addr,
8106 adresses = self.vapi.nat64_pool_addr_dump()
8107 for addr in adresses:
8108 self.vapi.nat64_add_del_pool_addr_range(addr.address,
8113 prefixes = self.vapi.nat64_prefix_dump()
8114 for prefix in prefixes:
8115 self.vapi.nat64_add_del_prefix(prefix.prefix,
8117 vrf_id=prefix.vrf_id,
8120 bibs = self.statistics.get_counter('/nat64/total-bibs')
8121 self.assertEqual(bibs[0][0], 0)
8122 sessions = self.statistics.get_counter('/nat64/total-sessions')
8123 self.assertEqual(sessions[0][0], 0)
8126 super(TestNAT64, self).tearDown()
8127 if not self.vpp_dead:
8128 self.logger.info(self.vapi.cli("show nat64 pool"))
8129 self.logger.info(self.vapi.cli("show nat64 interfaces"))
8130 self.logger.info(self.vapi.cli("show nat64 prefix"))
8131 self.logger.info(self.vapi.cli("show nat64 bib all"))
8132 self.logger.info(self.vapi.cli("show nat64 session table all"))
8133 self.logger.info(self.vapi.cli("show nat virtual-reassembly"))
8137 class TestDSlite(MethodHolder):
8138 """ DS-Lite Test Cases """
8141 def setUpClass(cls):
8142 super(TestDSlite, cls).setUpClass()
8145 cls.nat_addr = '10.0.0.3'
8146 cls.nat_addr_n = socket.inet_pton(socket.AF_INET, cls.nat_addr)
8148 cls.create_pg_interfaces(range(3))
8150 cls.pg0.config_ip4()
8151 cls.pg0.resolve_arp()
8153 cls.pg1.config_ip6()
8154 cls.pg1.generate_remote_hosts(2)
8155 cls.pg1.configure_ipv6_neighbors()
8157 cls.pg2.config_ip4()
8158 cls.pg2.resolve_arp()
8161 super(TestDSlite, cls).tearDownClass()
8164 def verify_syslog_apmadd(self, data, isaddr, isport, xsaddr, xsport,
8166 message = data.decode('utf-8')
8168 message = SyslogMessage.parse(message)
8169 self.assertEqual(message.severity, SyslogSeverity.info)
8170 self.assertEqual(message.appname, 'NAT')
8171 self.assertEqual(message.msgid, 'APMADD')
8172 sd_params = message.sd.get('napmap')
8173 self.assertTrue(sd_params is not None)
8174 self.assertEqual(sd_params.get('IATYP'), 'IPv4')
8175 self.assertEqual(sd_params.get('ISADDR'), isaddr)
8176 self.assertEqual(sd_params.get('ISPORT'), "%d" % isport)
8177 self.assertEqual(sd_params.get('XATYP'), 'IPv4')
8178 self.assertEqual(sd_params.get('XSADDR'), xsaddr)
8179 self.assertEqual(sd_params.get('XSPORT'), "%d" % xsport)
8180 self.assertEqual(sd_params.get('PROTO'), "%d" % proto)
8181 self.assertTrue(sd_params.get('SSUBIX') is not None)
8182 self.assertEqual(sd_params.get('SV6ENC'), sv6enc)
8183 except ParseError as e:
8184 self.logger.error(e)
8186 def test_dslite(self):
8187 """ Test DS-Lite """
8188 nat_config = self.vapi.nat_show_config()
8189 self.assertEqual(0, nat_config.dslite_ce)
8191 self.vapi.dslite_add_del_pool_addr_range(self.nat_addr_n,
8193 aftr_ip4 = '192.0.0.1'
8194 aftr_ip4_n = socket.inet_pton(socket.AF_INET, aftr_ip4)
8195 aftr_ip6 = '2001:db8:85a3::8a2e:370:1'
8196 aftr_ip6_n = socket.inet_pton(socket.AF_INET6, aftr_ip6)
8197 self.vapi.dslite_set_aftr_addr(aftr_ip6_n, aftr_ip4_n)
8198 self.vapi.syslog_set_sender(self.pg2.remote_ip4n, self.pg2.local_ip4n)
8201 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
8202 IPv6(dst=aftr_ip6, src=self.pg1.remote_hosts[0].ip6) /
8203 IP(dst=self.pg0.remote_ip4, src='192.168.1.1') /
8204 UDP(sport=20000, dport=10000))
8205 self.pg1.add_stream(p)
8206 self.pg_enable_capture(self.pg_interfaces)
8208 capture = self.pg0.get_capture(1)
8209 capture = capture[0]
8210 self.assertFalse(capture.haslayer(IPv6))
8211 self.assertEqual(capture[IP].src, self.nat_addr)
8212 self.assertEqual(capture[IP].dst, self.pg0.remote_ip4)
8213 self.assertNotEqual(capture[UDP].sport, 20000)
8214 self.assertEqual(capture[UDP].dport, 10000)
8215 self.assert_packet_checksums_valid(capture)
8216 out_port = capture[UDP].sport
8217 capture = self.pg2.get_capture(1)
8218 self.verify_syslog_apmadd(capture[0][Raw].load, '192.168.1.1',
8219 20000, self.nat_addr, out_port,
8220 self.pg1.remote_hosts[0].ip6, IP_PROTOS.udp)
8222 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
8223 IP(dst=self.nat_addr, src=self.pg0.remote_ip4) /
8224 UDP(sport=10000, dport=out_port))
8225 self.pg0.add_stream(p)
8226 self.pg_enable_capture(self.pg_interfaces)
8228 capture = self.pg1.get_capture(1)
8229 capture = capture[0]
8230 self.assertEqual(capture[IPv6].src, aftr_ip6)
8231 self.assertEqual(capture[IPv6].dst, self.pg1.remote_hosts[0].ip6)
8232 self.assertEqual(capture[IP].src, self.pg0.remote_ip4)
8233 self.assertEqual(capture[IP].dst, '192.168.1.1')
8234 self.assertEqual(capture[UDP].sport, 10000)
8235 self.assertEqual(capture[UDP].dport, 20000)
8236 self.assert_packet_checksums_valid(capture)
8239 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
8240 IPv6(dst=aftr_ip6, src=self.pg1.remote_hosts[1].ip6) /
8241 IP(dst=self.pg0.remote_ip4, src='192.168.1.1') /
8242 TCP(sport=20001, dport=10001))
8243 self.pg1.add_stream(p)
8244 self.pg_enable_capture(self.pg_interfaces)
8246 capture = self.pg0.get_capture(1)
8247 capture = capture[0]
8248 self.assertFalse(capture.haslayer(IPv6))
8249 self.assertEqual(capture[IP].src, self.nat_addr)
8250 self.assertEqual(capture[IP].dst, self.pg0.remote_ip4)
8251 self.assertNotEqual(capture[TCP].sport, 20001)
8252 self.assertEqual(capture[TCP].dport, 10001)
8253 self.assert_packet_checksums_valid(capture)
8254 out_port = capture[TCP].sport
8256 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
8257 IP(dst=self.nat_addr, src=self.pg0.remote_ip4) /
8258 TCP(sport=10001, dport=out_port))
8259 self.pg0.add_stream(p)
8260 self.pg_enable_capture(self.pg_interfaces)
8262 capture = self.pg1.get_capture(1)
8263 capture = capture[0]
8264 self.assertEqual(capture[IPv6].src, aftr_ip6)
8265 self.assertEqual(capture[IPv6].dst, self.pg1.remote_hosts[1].ip6)
8266 self.assertEqual(capture[IP].src, self.pg0.remote_ip4)
8267 self.assertEqual(capture[IP].dst, '192.168.1.1')
8268 self.assertEqual(capture[TCP].sport, 10001)
8269 self.assertEqual(capture[TCP].dport, 20001)
8270 self.assert_packet_checksums_valid(capture)
8273 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
8274 IPv6(dst=aftr_ip6, src=self.pg1.remote_hosts[1].ip6) /
8275 IP(dst=self.pg0.remote_ip4, src='192.168.1.1') /
8276 ICMP(id=4000, type='echo-request'))
8277 self.pg1.add_stream(p)
8278 self.pg_enable_capture(self.pg_interfaces)
8280 capture = self.pg0.get_capture(1)
8281 capture = capture[0]
8282 self.assertFalse(capture.haslayer(IPv6))
8283 self.assertEqual(capture[IP].src, self.nat_addr)
8284 self.assertEqual(capture[IP].dst, self.pg0.remote_ip4)
8285 self.assertNotEqual(capture[ICMP].id, 4000)
8286 self.assert_packet_checksums_valid(capture)
8287 out_id = capture[ICMP].id
8289 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
8290 IP(dst=self.nat_addr, src=self.pg0.remote_ip4) /
8291 ICMP(id=out_id, type='echo-reply'))
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, aftr_ip6)
8298 self.assertEqual(capture[IPv6].dst, self.pg1.remote_hosts[1].ip6)
8299 self.assertEqual(capture[IP].src, self.pg0.remote_ip4)
8300 self.assertEqual(capture[IP].dst, '192.168.1.1')
8301 self.assertEqual(capture[ICMP].id, 4000)
8302 self.assert_packet_checksums_valid(capture)
8304 # ping DS-Lite AFTR tunnel endpoint address
8305 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
8306 IPv6(src=self.pg1.remote_hosts[1].ip6, dst=aftr_ip6) /
8307 ICMPv6EchoRequest())
8308 self.pg1.add_stream(p)
8309 self.pg_enable_capture(self.pg_interfaces)
8311 capture = self.pg1.get_capture(1)
8312 capture = capture[0]
8313 self.assertEqual(capture[IPv6].src, aftr_ip6)
8314 self.assertEqual(capture[IPv6].dst, self.pg1.remote_hosts[1].ip6)
8315 self.assertTrue(capture.haslayer(ICMPv6EchoReply))
8317 b4s = self.statistics.get_counter('/dslite/total-b4s')
8318 self.assertEqual(b4s[0][0], 2)
8319 sessions = self.statistics.get_counter('/dslite/total-sessions')
8320 self.assertEqual(sessions[0][0], 3)
8323 super(TestDSlite, self).tearDown()
8324 if not self.vpp_dead:
8325 self.logger.info(self.vapi.cli("show dslite pool"))
8327 self.vapi.cli("show dslite aftr-tunnel-endpoint-address"))
8328 self.logger.info(self.vapi.cli("show dslite sessions"))
8331 class TestDSliteCE(MethodHolder):
8332 """ DS-Lite CE Test Cases """
8335 def setUpConstants(cls):
8336 super(TestDSliteCE, cls).setUpConstants()
8337 cls.vpp_cmdline.extend(["nat", "{", "dslite ce", "}"])
8340 def setUpClass(cls):
8341 super(TestDSliteCE, cls).setUpClass()
8344 cls.create_pg_interfaces(range(2))
8346 cls.pg0.config_ip4()
8347 cls.pg0.resolve_arp()
8349 cls.pg1.config_ip6()
8350 cls.pg1.generate_remote_hosts(1)
8351 cls.pg1.configure_ipv6_neighbors()
8354 super(TestDSliteCE, cls).tearDownClass()
8357 def test_dslite_ce(self):
8358 """ Test DS-Lite CE """
8360 nat_config = self.vapi.nat_show_config()
8361 self.assertEqual(1, nat_config.dslite_ce)
8363 b4_ip4 = '192.0.0.2'
8364 b4_ip4_n = socket.inet_pton(socket.AF_INET, b4_ip4)
8365 b4_ip6 = '2001:db8:62aa::375e:f4c1:1'
8366 b4_ip6_n = socket.inet_pton(socket.AF_INET6, b4_ip6)
8367 self.vapi.dslite_set_b4_addr(b4_ip6_n, b4_ip4_n)
8369 aftr_ip4 = '192.0.0.1'
8370 aftr_ip4_n = socket.inet_pton(socket.AF_INET, aftr_ip4)
8371 aftr_ip6 = '2001:db8:85a3::8a2e:370:1'
8372 aftr_ip6_n = socket.inet_pton(socket.AF_INET6, aftr_ip6)
8373 self.vapi.dslite_set_aftr_addr(aftr_ip6_n, aftr_ip4_n)
8375 self.vapi.ip_add_del_route(dst_address=aftr_ip6_n,
8376 dst_address_length=128,
8377 next_hop_address=self.pg1.remote_ip6n,
8378 next_hop_sw_if_index=self.pg1.sw_if_index,
8382 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
8383 IP(dst=self.pg1.remote_ip4, src=self.pg0.remote_ip4) /
8384 UDP(sport=10000, dport=20000))
8385 self.pg0.add_stream(p)
8386 self.pg_enable_capture(self.pg_interfaces)
8388 capture = self.pg1.get_capture(1)
8389 capture = capture[0]
8390 self.assertEqual(capture[IPv6].src, b4_ip6)
8391 self.assertEqual(capture[IPv6].dst, aftr_ip6)
8392 self.assertEqual(capture[IP].src, self.pg0.remote_ip4)
8393 self.assertEqual(capture[IP].dst, self.pg1.remote_ip4)
8394 self.assertEqual(capture[UDP].sport, 10000)
8395 self.assertEqual(capture[UDP].dport, 20000)
8396 self.assert_packet_checksums_valid(capture)
8399 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
8400 IPv6(dst=b4_ip6, src=aftr_ip6) /
8401 IP(dst=self.pg0.remote_ip4, src=self.pg1.remote_ip4) /
8402 UDP(sport=20000, dport=10000))
8403 self.pg1.add_stream(p)
8404 self.pg_enable_capture(self.pg_interfaces)
8406 capture = self.pg0.get_capture(1)
8407 capture = capture[0]
8408 self.assertFalse(capture.haslayer(IPv6))
8409 self.assertEqual(capture[IP].src, self.pg1.remote_ip4)
8410 self.assertEqual(capture[IP].dst, self.pg0.remote_ip4)
8411 self.assertEqual(capture[UDP].sport, 20000)
8412 self.assertEqual(capture[UDP].dport, 10000)
8413 self.assert_packet_checksums_valid(capture)
8415 # ping DS-Lite B4 tunnel endpoint address
8416 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
8417 IPv6(src=self.pg1.remote_hosts[0].ip6, dst=b4_ip6) /
8418 ICMPv6EchoRequest())
8419 self.pg1.add_stream(p)
8420 self.pg_enable_capture(self.pg_interfaces)
8422 capture = self.pg1.get_capture(1)
8423 capture = capture[0]
8424 self.assertEqual(capture[IPv6].src, b4_ip6)
8425 self.assertEqual(capture[IPv6].dst, self.pg1.remote_hosts[0].ip6)
8426 self.assertTrue(capture.haslayer(ICMPv6EchoReply))
8429 super(TestDSliteCE, self).tearDown()
8430 if not self.vpp_dead:
8432 self.vapi.cli("show dslite aftr-tunnel-endpoint-address"))
8434 self.vapi.cli("show dslite b4-tunnel-endpoint-address"))
8437 class TestNAT66(MethodHolder):
8438 """ NAT66 Test Cases """
8441 def setUpClass(cls):
8442 super(TestNAT66, cls).setUpClass()
8445 cls.nat_addr = 'fd01:ff::2'
8446 cls.nat_addr_n = socket.inet_pton(socket.AF_INET6, cls.nat_addr)
8448 cls.create_pg_interfaces(range(2))
8449 cls.interfaces = list(cls.pg_interfaces)
8451 for i in cls.interfaces:
8454 i.configure_ipv6_neighbors()
8457 super(TestNAT66, cls).tearDownClass()
8460 def test_static(self):
8461 """ 1:1 NAT66 test """
8462 self.vapi.nat66_add_del_interface(self.pg0.sw_if_index)
8463 self.vapi.nat66_add_del_interface(self.pg1.sw_if_index, is_inside=0)
8464 self.vapi.nat66_add_del_static_mapping(self.pg0.remote_ip6n,
8469 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
8470 IPv6(src=self.pg0.remote_ip6, dst=self.pg1.remote_ip6) /
8473 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
8474 IPv6(src=self.pg0.remote_ip6, dst=self.pg1.remote_ip6) /
8477 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
8478 IPv6(src=self.pg0.remote_ip6, dst=self.pg1.remote_ip6) /
8479 ICMPv6EchoRequest())
8481 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
8482 IPv6(src=self.pg0.remote_ip6, dst=self.pg1.remote_ip6) /
8483 GRE() / IP() / TCP())
8485 self.pg0.add_stream(pkts)
8486 self.pg_enable_capture(self.pg_interfaces)
8488 capture = self.pg1.get_capture(len(pkts))
8489 for packet in capture:
8491 self.assertEqual(packet[IPv6].src, self.nat_addr)
8492 self.assertEqual(packet[IPv6].dst, self.pg1.remote_ip6)
8493 self.assert_packet_checksums_valid(packet)
8495 self.logger.error(ppp("Unexpected or invalid packet:", packet))
8500 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
8501 IPv6(src=self.pg1.remote_ip6, dst=self.nat_addr) /
8504 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
8505 IPv6(src=self.pg1.remote_ip6, dst=self.nat_addr) /
8508 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
8509 IPv6(src=self.pg1.remote_ip6, dst=self.nat_addr) /
8512 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
8513 IPv6(src=self.pg1.remote_ip6, dst=self.nat_addr) /
8514 GRE() / IP() / TCP())
8516 self.pg1.add_stream(pkts)
8517 self.pg_enable_capture(self.pg_interfaces)
8519 capture = self.pg0.get_capture(len(pkts))
8520 for packet in capture:
8522 self.assertEqual(packet[IPv6].src, self.pg1.remote_ip6)
8523 self.assertEqual(packet[IPv6].dst, self.pg0.remote_ip6)
8524 self.assert_packet_checksums_valid(packet)
8526 self.logger.error(ppp("Unexpected or invalid packet:", packet))
8529 sm = self.vapi.nat66_static_mapping_dump()
8530 self.assertEqual(len(sm), 1)
8531 self.assertEqual(sm[0].total_pkts, 8)
8533 def test_check_no_translate(self):
8534 """ NAT66 translate only when egress interface is outside interface """
8535 self.vapi.nat66_add_del_interface(self.pg0.sw_if_index)
8536 self.vapi.nat66_add_del_interface(self.pg1.sw_if_index)
8537 self.vapi.nat66_add_del_static_mapping(self.pg0.remote_ip6n,
8541 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
8542 IPv6(src=self.pg0.remote_ip6, dst=self.pg1.remote_ip6) /
8544 self.pg0.add_stream([p])
8545 self.pg_enable_capture(self.pg_interfaces)
8547 capture = self.pg1.get_capture(1)
8550 self.assertEqual(packet[IPv6].src, self.pg0.remote_ip6)
8551 self.assertEqual(packet[IPv6].dst, self.pg1.remote_ip6)
8553 self.logger.error(ppp("Unexpected or invalid packet:", packet))
8556 def clear_nat66(self):
8558 Clear NAT66 configuration.
8560 interfaces = self.vapi.nat66_interface_dump()
8561 for intf in interfaces:
8562 self.vapi.nat66_add_del_interface(intf.sw_if_index,
8566 static_mappings = self.vapi.nat66_static_mapping_dump()
8567 for sm in static_mappings:
8568 self.vapi.nat66_add_del_static_mapping(sm.local_ip_address,
8569 sm.external_ip_address,
8574 super(TestNAT66, self).tearDown()
8575 if not self.vpp_dead:
8576 self.logger.info(self.vapi.cli("show nat66 interfaces"))
8577 self.logger.info(self.vapi.cli("show nat66 static mappings"))
8581 if __name__ == '__main__':
8582 unittest.main(testRunner=VppTestRunner)