9 from framework import VppTestCase, VppTestRunner, running_extended_tests
10 from scapy.layers.inet import IP, TCP, UDP, ICMP
11 from scapy.layers.inet import IPerror, TCPerror, UDPerror, ICMPerror
12 from scapy.layers.inet6 import IPv6, ICMPv6EchoRequest, ICMPv6EchoReply, \
13 ICMPv6ND_NS, ICMPv6ND_NA, ICMPv6NDOptDstLLAddr, fragment6
14 from scapy.layers.inet6 import ICMPv6DestUnreach, IPerror6, IPv6ExtHdrFragment
15 from scapy.layers.l2 import Ether, ARP, GRE
16 from scapy.data import IP_PROTOS
17 from scapy.packet import bind_layers, Raw
19 from ipfix import IPFIX, Set, Template, Data, IPFIXDecoder
20 from time import sleep
21 from util import ip4_range
22 from util import mactobinary
23 from syslog_rfc5424_parser import SyslogMessage, ParseError
24 from syslog_rfc5424_parser.constants import SyslogFacility, SyslogSeverity
25 from vpp_papi_provider import SYSLOG_SEVERITY
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
728 buffer = StringIO.StringIO()
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(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
757 buffer = StringIO.StringIO()
759 self.assertEqual(p[IPv6].src, src)
760 self.assertEqual(p[IPv6].dst, dst)
761 buffer.seek(p[IPv6ExtHdrFragment].offset * 8)
762 buffer.write(p[IPv6ExtHdrFragment].payload)
763 ip = IPv6(src=frags[0][IPv6].src, dst=frags[0][IPv6].dst,
764 nh=frags[0][IPv6ExtHdrFragment].nh)
765 if ip.nh == IP_PROTOS.tcp:
766 p = (ip / TCP(buffer.getvalue()))
767 elif ip.nh == IP_PROTOS.udp:
768 p = (ip / UDP(buffer.getvalue()))
769 self.assert_packet_checksums_valid(p)
772 def initiate_tcp_session(self, in_if, out_if):
774 Initiates TCP session
776 :param in_if: Inside interface
777 :param out_if: Outside interface
781 p = (Ether(src=in_if.remote_mac, dst=in_if.local_mac) /
782 IP(src=in_if.remote_ip4, dst=out_if.remote_ip4) /
783 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
786 self.pg_enable_capture(self.pg_interfaces)
788 capture = out_if.get_capture(1)
790 self.tcp_port_out = p[TCP].sport
792 # SYN + ACK packet out->in
793 p = (Ether(src=out_if.remote_mac, dst=out_if.local_mac) /
794 IP(src=out_if.remote_ip4, dst=self.nat_addr) /
795 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
798 self.pg_enable_capture(self.pg_interfaces)
803 p = (Ether(src=in_if.remote_mac, dst=in_if.local_mac) /
804 IP(src=in_if.remote_ip4, dst=out_if.remote_ip4) /
805 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
808 self.pg_enable_capture(self.pg_interfaces)
810 out_if.get_capture(1)
813 self.logger.error("TCP 3 way handshake failed")
816 def verify_ipfix_nat44_ses(self, data):
818 Verify IPFIX NAT44 session create/delete event
820 :param data: Decoded IPFIX data records
822 nat44_ses_create_num = 0
823 nat44_ses_delete_num = 0
824 self.assertEqual(6, len(data))
827 self.assertIn(ord(record[230]), [4, 5])
828 if ord(record[230]) == 4:
829 nat44_ses_create_num += 1
831 nat44_ses_delete_num += 1
833 self.assertEqual(self.pg0.remote_ip4n, record[8])
834 # postNATSourceIPv4Address
835 self.assertEqual(socket.inet_pton(socket.AF_INET, self.nat_addr),
838 self.assertEqual(struct.pack("!I", 0), record[234])
839 # protocolIdentifier/sourceTransportPort/postNAPTSourceTransportPort
840 if IP_PROTOS.icmp == ord(record[4]):
841 self.assertEqual(struct.pack("!H", self.icmp_id_in), record[7])
842 self.assertEqual(struct.pack("!H", self.icmp_id_out),
844 elif IP_PROTOS.tcp == ord(record[4]):
845 self.assertEqual(struct.pack("!H", self.tcp_port_in),
847 self.assertEqual(struct.pack("!H", self.tcp_port_out),
849 elif IP_PROTOS.udp == ord(record[4]):
850 self.assertEqual(struct.pack("!H", self.udp_port_in),
852 self.assertEqual(struct.pack("!H", self.udp_port_out),
855 self.fail("Invalid protocol")
856 self.assertEqual(3, nat44_ses_create_num)
857 self.assertEqual(3, nat44_ses_delete_num)
859 def verify_ipfix_addr_exhausted(self, data):
861 Verify IPFIX NAT addresses event
863 :param data: Decoded IPFIX data records
865 self.assertEqual(1, len(data))
868 self.assertEqual(ord(record[230]), 3)
870 self.assertEqual(struct.pack("!I", 0), record[283])
872 def verify_ipfix_max_sessions(self, data, limit):
874 Verify IPFIX maximum session entries exceeded event
876 :param data: Decoded IPFIX data records
877 :param limit: Number of maximum session entries that can be created.
879 self.assertEqual(1, len(data))
882 self.assertEqual(ord(record[230]), 13)
883 # natQuotaExceededEvent
884 self.assertEqual(struct.pack("I", 1), record[466])
886 self.assertEqual(struct.pack("I", limit), record[471])
888 def verify_ipfix_max_bibs(self, data, limit):
890 Verify IPFIX maximum BIB entries exceeded event
892 :param data: Decoded IPFIX data records
893 :param limit: Number of maximum BIB entries that can be created.
895 self.assertEqual(1, len(data))
898 self.assertEqual(ord(record[230]), 13)
899 # natQuotaExceededEvent
900 self.assertEqual(struct.pack("I", 2), record[466])
902 self.assertEqual(struct.pack("I", limit), record[472])
904 def verify_ipfix_max_fragments_ip6(self, data, limit, src_addr):
906 Verify IPFIX maximum IPv6 fragments pending reassembly exceeded event
908 :param data: Decoded IPFIX data records
909 :param limit: Number of maximum fragments pending reassembly
910 :param src_addr: IPv6 source address
912 self.assertEqual(1, len(data))
915 self.assertEqual(ord(record[230]), 13)
916 # natQuotaExceededEvent
917 self.assertEqual(struct.pack("I", 5), record[466])
918 # maxFragmentsPendingReassembly
919 self.assertEqual(struct.pack("I", limit), record[475])
921 self.assertEqual(src_addr, record[27])
923 def verify_ipfix_max_fragments_ip4(self, data, limit, src_addr):
925 Verify IPFIX maximum IPv4 fragments pending reassembly exceeded event
927 :param data: Decoded IPFIX data records
928 :param limit: Number of maximum fragments pending reassembly
929 :param src_addr: IPv4 source address
931 self.assertEqual(1, len(data))
934 self.assertEqual(ord(record[230]), 13)
935 # natQuotaExceededEvent
936 self.assertEqual(struct.pack("I", 5), record[466])
937 # maxFragmentsPendingReassembly
938 self.assertEqual(struct.pack("I", limit), record[475])
940 self.assertEqual(src_addr, record[8])
942 def verify_ipfix_bib(self, data, is_create, src_addr):
944 Verify IPFIX NAT64 BIB create and delete events
946 :param data: Decoded IPFIX data records
947 :param is_create: Create event if nonzero value otherwise delete event
948 :param src_addr: IPv6 source address
950 self.assertEqual(1, len(data))
954 self.assertEqual(ord(record[230]), 10)
956 self.assertEqual(ord(record[230]), 11)
958 self.assertEqual(src_addr, record[27])
959 # postNATSourceIPv4Address
960 self.assertEqual(self.nat_addr_n, record[225])
962 self.assertEqual(IP_PROTOS.tcp, ord(record[4]))
964 self.assertEqual(struct.pack("!I", 0), record[234])
965 # sourceTransportPort
966 self.assertEqual(struct.pack("!H", self.tcp_port_in), record[7])
967 # postNAPTSourceTransportPort
968 self.assertEqual(struct.pack("!H", self.tcp_port_out), record[227])
970 def verify_ipfix_nat64_ses(self, data, is_create, src_addr, dst_addr,
973 Verify IPFIX NAT64 session create and delete events
975 :param data: Decoded IPFIX data records
976 :param is_create: Create event if nonzero value otherwise delete event
977 :param src_addr: IPv6 source address
978 :param dst_addr: IPv4 destination address
979 :param dst_port: destination TCP port
981 self.assertEqual(1, len(data))
985 self.assertEqual(ord(record[230]), 6)
987 self.assertEqual(ord(record[230]), 7)
989 self.assertEqual(src_addr, record[27])
990 # destinationIPv6Address
991 self.assertEqual(socket.inet_pton(socket.AF_INET6,
992 self.compose_ip6(dst_addr,
996 # postNATSourceIPv4Address
997 self.assertEqual(self.nat_addr_n, record[225])
998 # postNATDestinationIPv4Address
999 self.assertEqual(socket.inet_pton(socket.AF_INET, dst_addr),
1001 # protocolIdentifier
1002 self.assertEqual(IP_PROTOS.tcp, ord(record[4]))
1004 self.assertEqual(struct.pack("!I", 0), record[234])
1005 # sourceTransportPort
1006 self.assertEqual(struct.pack("!H", self.tcp_port_in), record[7])
1007 # postNAPTSourceTransportPort
1008 self.assertEqual(struct.pack("!H", self.tcp_port_out), record[227])
1009 # destinationTransportPort
1010 self.assertEqual(struct.pack("!H", dst_port), record[11])
1011 # postNAPTDestinationTransportPort
1012 self.assertEqual(struct.pack("!H", dst_port), record[228])
1014 def verify_no_nat44_user(self):
1015 """ Verify that there is no NAT44 user """
1016 users = self.vapi.nat44_user_dump()
1017 self.assertEqual(len(users), 0)
1019 def verify_ipfix_max_entries_per_user(self, data, limit, src_addr):
1021 Verify IPFIX maximum entries per user exceeded event
1023 :param data: Decoded IPFIX data records
1024 :param limit: Number of maximum entries per user
1025 :param src_addr: IPv4 source address
1027 self.assertEqual(1, len(data))
1030 self.assertEqual(ord(record[230]), 13)
1031 # natQuotaExceededEvent
1032 self.assertEqual(struct.pack("I", 3), record[466])
1034 self.assertEqual(struct.pack("I", limit), record[473])
1036 self.assertEqual(src_addr, record[8])
1038 def verify_syslog_apmap(self, data, is_add=True):
1039 message = data.decode('utf-8')
1041 message = SyslogMessage.parse(message)
1042 self.assertEqual(message.severity, SyslogSeverity.info)
1043 self.assertEqual(message.appname, 'NAT')
1044 self.assertEqual(message.msgid, 'APMADD' if is_add else 'APMDEL')
1045 sd_params = message.sd.get('napmap')
1046 self.assertTrue(sd_params is not None)
1047 self.assertEqual(sd_params.get('IATYP'), 'IPv4')
1048 self.assertEqual(sd_params.get('ISADDR'), self.pg0.remote_ip4)
1049 self.assertEqual(sd_params.get('ISPORT'), "%d" % self.tcp_port_in)
1050 self.assertEqual(sd_params.get('XATYP'), 'IPv4')
1051 self.assertEqual(sd_params.get('XSADDR'), self.nat_addr)
1052 self.assertEqual(sd_params.get('XSPORT'), "%d" % self.tcp_port_out)
1053 self.assertEqual(sd_params.get('PROTO'), "%d" % IP_PROTOS.tcp)
1054 self.assertTrue(sd_params.get('SSUBIX') is not None)
1055 self.assertEqual(sd_params.get('SVLAN'), '0')
1056 except ParseError as e:
1057 self.logger.error(e)
1059 def verify_syslog_sess(self, data, is_add=True, is_ip6=False):
1060 message = data.decode('utf-8')
1062 message = SyslogMessage.parse(message)
1063 self.assertEqual(message.severity, SyslogSeverity.info)
1064 self.assertEqual(message.appname, 'NAT')
1065 self.assertEqual(message.msgid, 'SADD' if is_add else 'SDEL')
1066 sd_params = message.sd.get('nsess')
1067 self.assertTrue(sd_params is not None)
1069 self.assertEqual(sd_params.get('IATYP'), 'IPv6')
1070 self.assertEqual(sd_params.get('ISADDR'), self.pg0.remote_ip6)
1072 self.assertEqual(sd_params.get('IATYP'), 'IPv4')
1073 self.assertEqual(sd_params.get('ISADDR'), self.pg0.remote_ip4)
1074 self.assertTrue(sd_params.get('SSUBIX') is not None)
1075 self.assertEqual(sd_params.get('ISPORT'), "%d" % self.tcp_port_in)
1076 self.assertEqual(sd_params.get('XATYP'), 'IPv4')
1077 self.assertEqual(sd_params.get('XSADDR'), self.nat_addr)
1078 self.assertEqual(sd_params.get('XSPORT'), "%d" % self.tcp_port_out)
1079 self.assertEqual(sd_params.get('PROTO'), "%d" % IP_PROTOS.tcp)
1080 self.assertEqual(sd_params.get('SVLAN'), '0')
1081 self.assertEqual(sd_params.get('XDADDR'), self.pg1.remote_ip4)
1082 self.assertEqual(sd_params.get('XDPORT'),
1083 "%d" % self.tcp_external_port)
1084 except ParseError as e:
1085 self.logger.error(e)
1087 def verify_mss_value(self, pkt, mss):
1089 Verify TCP MSS value
1094 if not pkt.haslayer(IP) or not pkt.haslayer(TCP):
1095 raise TypeError("Not a TCP/IP packet")
1097 for option in pkt[TCP].options:
1098 if option[0] == 'MSS':
1099 self.assertEqual(option[1], mss)
1100 self.assert_tcp_checksum_valid(pkt)
1103 def proto2layer(proto):
1104 if proto == IP_PROTOS.tcp:
1106 elif proto == IP_PROTOS.udp:
1108 elif proto == IP_PROTOS.icmp:
1111 raise Exception("Unsupported protocol")
1113 def frag_in_order(self, proto=IP_PROTOS.tcp, dont_translate=False):
1114 layer = self.proto2layer(proto)
1116 if proto == IP_PROTOS.tcp:
1117 data = "A" * 4 + "B" * 16 + "C" * 3
1119 data = "A" * 16 + "B" * 16 + "C" * 3
1120 self.port_in = random.randint(1025, 65535)
1122 reass = self.vapi.nat_reass_dump()
1123 reass_n_start = len(reass)
1126 pkts = self.create_stream_frag(self.pg0,
1127 self.pg1.remote_ip4,
1132 self.pg0.add_stream(pkts)
1133 self.pg_enable_capture(self.pg_interfaces)
1135 frags = self.pg1.get_capture(len(pkts))
1136 if not dont_translate:
1137 p = self.reass_frags_and_verify(frags,
1139 self.pg1.remote_ip4)
1141 p = self.reass_frags_and_verify(frags,
1142 self.pg0.remote_ip4,
1143 self.pg1.remote_ip4)
1144 if proto != IP_PROTOS.icmp:
1145 if not dont_translate:
1146 self.assertEqual(p[layer].dport, 20)
1147 self.assertNotEqual(p[layer].sport, self.port_in)
1149 self.assertEqual(p[layer].sport, self.port_in)
1151 if not dont_translate:
1152 self.assertNotEqual(p[layer].id, self.port_in)
1154 self.assertEqual(p[layer].id, self.port_in)
1155 self.assertEqual(data, p[Raw].load)
1158 if not dont_translate:
1159 dst_addr = self.nat_addr
1161 dst_addr = self.pg0.remote_ip4
1162 if proto != IP_PROTOS.icmp:
1164 dport = p[layer].sport
1168 pkts = self.create_stream_frag(self.pg1,
1175 self.pg1.add_stream(pkts)
1176 self.pg_enable_capture(self.pg_interfaces)
1178 frags = self.pg0.get_capture(len(pkts))
1179 p = self.reass_frags_and_verify(frags,
1180 self.pg1.remote_ip4,
1181 self.pg0.remote_ip4)
1182 if proto != IP_PROTOS.icmp:
1183 self.assertEqual(p[layer].sport, 20)
1184 self.assertEqual(p[layer].dport, self.port_in)
1186 self.assertEqual(p[layer].id, self.port_in)
1187 self.assertEqual(data, p[Raw].load)
1189 reass = self.vapi.nat_reass_dump()
1190 reass_n_end = len(reass)
1192 self.assertEqual(reass_n_end - reass_n_start, 2)
1194 def frag_in_order_in_plus_out(self, proto=IP_PROTOS.tcp):
1195 layer = self.proto2layer(proto)
1197 if proto == IP_PROTOS.tcp:
1198 data = "A" * 4 + "B" * 16 + "C" * 3
1200 data = "A" * 16 + "B" * 16 + "C" * 3
1201 self.port_in = random.randint(1025, 65535)
1204 reass = self.vapi.nat_reass_dump()
1205 reass_n_start = len(reass)
1208 pkts = self.create_stream_frag(self.pg0,
1209 self.server_out_addr,
1211 self.server_out_port,
1214 self.pg0.add_stream(pkts)
1215 self.pg_enable_capture(self.pg_interfaces)
1217 frags = self.pg1.get_capture(len(pkts))
1218 p = self.reass_frags_and_verify(frags,
1219 self.pg0.remote_ip4,
1220 self.server_in_addr)
1221 if proto != IP_PROTOS.icmp:
1222 self.assertEqual(p[layer].sport, self.port_in)
1223 self.assertEqual(p[layer].dport, self.server_in_port)
1225 self.assertEqual(p[layer].id, self.port_in)
1226 self.assertEqual(data, p[Raw].load)
1229 if proto != IP_PROTOS.icmp:
1230 pkts = self.create_stream_frag(self.pg1,
1231 self.pg0.remote_ip4,
1232 self.server_in_port,
1237 pkts = self.create_stream_frag(self.pg1,
1238 self.pg0.remote_ip4,
1244 self.pg1.add_stream(pkts)
1245 self.pg_enable_capture(self.pg_interfaces)
1247 frags = self.pg0.get_capture(len(pkts))
1248 p = self.reass_frags_and_verify(frags,
1249 self.server_out_addr,
1250 self.pg0.remote_ip4)
1251 if proto != IP_PROTOS.icmp:
1252 self.assertEqual(p[layer].sport, self.server_out_port)
1253 self.assertEqual(p[layer].dport, self.port_in)
1255 self.assertEqual(p[layer].id, self.port_in)
1256 self.assertEqual(data, p[Raw].load)
1258 reass = self.vapi.nat_reass_dump()
1259 reass_n_end = len(reass)
1261 self.assertEqual(reass_n_end - reass_n_start, 2)
1263 def reass_hairpinning(self, proto=IP_PROTOS.tcp):
1264 layer = self.proto2layer(proto)
1266 if proto == IP_PROTOS.tcp:
1267 data = "A" * 4 + "B" * 16 + "C" * 3
1269 data = "A" * 16 + "B" * 16 + "C" * 3
1271 # send packet from host to server
1272 pkts = self.create_stream_frag(self.pg0,
1275 self.server_out_port,
1278 self.pg0.add_stream(pkts)
1279 self.pg_enable_capture(self.pg_interfaces)
1281 frags = self.pg0.get_capture(len(pkts))
1282 p = self.reass_frags_and_verify(frags,
1285 if proto != IP_PROTOS.icmp:
1286 self.assertNotEqual(p[layer].sport, self.host_in_port)
1287 self.assertEqual(p[layer].dport, self.server_in_port)
1289 self.assertNotEqual(p[layer].id, self.host_in_port)
1290 self.assertEqual(data, p[Raw].load)
1292 def frag_out_of_order(self, proto=IP_PROTOS.tcp, dont_translate=False):
1293 layer = self.proto2layer(proto)
1295 if proto == IP_PROTOS.tcp:
1296 data = "A" * 4 + "B" * 16 + "C" * 3
1298 data = "A" * 16 + "B" * 16 + "C" * 3
1299 self.port_in = random.randint(1025, 65535)
1303 pkts = self.create_stream_frag(self.pg0,
1304 self.pg1.remote_ip4,
1310 self.pg0.add_stream(pkts)
1311 self.pg_enable_capture(self.pg_interfaces)
1313 frags = self.pg1.get_capture(len(pkts))
1314 if not dont_translate:
1315 p = self.reass_frags_and_verify(frags,
1317 self.pg1.remote_ip4)
1319 p = self.reass_frags_and_verify(frags,
1320 self.pg0.remote_ip4,
1321 self.pg1.remote_ip4)
1322 if proto != IP_PROTOS.icmp:
1323 if not dont_translate:
1324 self.assertEqual(p[layer].dport, 20)
1325 self.assertNotEqual(p[layer].sport, self.port_in)
1327 self.assertEqual(p[layer].sport, self.port_in)
1329 if not dont_translate:
1330 self.assertNotEqual(p[layer].id, self.port_in)
1332 self.assertEqual(p[layer].id, self.port_in)
1333 self.assertEqual(data, p[Raw].load)
1336 if not dont_translate:
1337 dst_addr = self.nat_addr
1339 dst_addr = self.pg0.remote_ip4
1340 if proto != IP_PROTOS.icmp:
1342 dport = p[layer].sport
1346 pkts = self.create_stream_frag(self.pg1,
1354 self.pg1.add_stream(pkts)
1355 self.pg_enable_capture(self.pg_interfaces)
1357 frags = self.pg0.get_capture(len(pkts))
1358 p = self.reass_frags_and_verify(frags,
1359 self.pg1.remote_ip4,
1360 self.pg0.remote_ip4)
1361 if proto != IP_PROTOS.icmp:
1362 self.assertEqual(p[layer].sport, 20)
1363 self.assertEqual(p[layer].dport, self.port_in)
1365 self.assertEqual(p[layer].id, self.port_in)
1366 self.assertEqual(data, p[Raw].load)
1368 def frag_out_of_order_in_plus_out(self, proto=IP_PROTOS.tcp):
1369 layer = self.proto2layer(proto)
1371 if proto == IP_PROTOS.tcp:
1372 data = "A" * 4 + "B" * 16 + "C" * 3
1374 data = "A" * 16 + "B" * 16 + "C" * 3
1375 self.port_in = random.randint(1025, 65535)
1379 pkts = self.create_stream_frag(self.pg0,
1380 self.server_out_addr,
1382 self.server_out_port,
1386 self.pg0.add_stream(pkts)
1387 self.pg_enable_capture(self.pg_interfaces)
1389 frags = self.pg1.get_capture(len(pkts))
1390 p = self.reass_frags_and_verify(frags,
1391 self.pg0.remote_ip4,
1392 self.server_in_addr)
1393 if proto != IP_PROTOS.icmp:
1394 self.assertEqual(p[layer].dport, self.server_in_port)
1395 self.assertEqual(p[layer].sport, self.port_in)
1396 self.assertEqual(p[layer].dport, self.server_in_port)
1398 self.assertEqual(p[layer].id, self.port_in)
1399 self.assertEqual(data, p[Raw].load)
1402 if proto != IP_PROTOS.icmp:
1403 pkts = self.create_stream_frag(self.pg1,
1404 self.pg0.remote_ip4,
1405 self.server_in_port,
1410 pkts = self.create_stream_frag(self.pg1,
1411 self.pg0.remote_ip4,
1418 self.pg1.add_stream(pkts)
1419 self.pg_enable_capture(self.pg_interfaces)
1421 frags = self.pg0.get_capture(len(pkts))
1422 p = self.reass_frags_and_verify(frags,
1423 self.server_out_addr,
1424 self.pg0.remote_ip4)
1425 if proto != IP_PROTOS.icmp:
1426 self.assertEqual(p[layer].sport, self.server_out_port)
1427 self.assertEqual(p[layer].dport, self.port_in)
1429 self.assertEqual(p[layer].id, self.port_in)
1430 self.assertEqual(data, p[Raw].load)
1433 class TestNAT44(MethodHolder):
1434 """ NAT44 Test Cases """
1437 def setUpClass(cls):
1438 super(TestNAT44, cls).setUpClass()
1439 cls.vapi.cli("set log class nat level debug")
1442 cls.tcp_port_in = 6303
1443 cls.tcp_port_out = 6303
1444 cls.udp_port_in = 6304
1445 cls.udp_port_out = 6304
1446 cls.icmp_id_in = 6305
1447 cls.icmp_id_out = 6305
1448 cls.nat_addr = '10.0.0.3'
1449 cls.nat_addr_n = socket.inet_pton(socket.AF_INET, cls.nat_addr)
1450 cls.ipfix_src_port = 4739
1451 cls.ipfix_domain_id = 1
1452 cls.tcp_external_port = 80
1454 cls.create_pg_interfaces(range(10))
1455 cls.interfaces = list(cls.pg_interfaces[0:4])
1457 for i in cls.interfaces:
1462 cls.pg0.generate_remote_hosts(3)
1463 cls.pg0.configure_ipv4_neighbors()
1465 cls.pg1.generate_remote_hosts(1)
1466 cls.pg1.configure_ipv4_neighbors()
1468 cls.overlapping_interfaces = list(list(cls.pg_interfaces[4:7]))
1469 cls.vapi.ip_table_add_del(10, is_add=1)
1470 cls.vapi.ip_table_add_del(20, is_add=1)
1472 cls.pg4._local_ip4 = "172.16.255.1"
1473 cls.pg4._local_ip4n = socket.inet_pton(socket.AF_INET, i.local_ip4)
1474 cls.pg4._remote_hosts[0]._ip4 = "172.16.255.2"
1475 cls.pg4.set_table_ip4(10)
1476 cls.pg5._local_ip4 = "172.17.255.3"
1477 cls.pg5._local_ip4n = socket.inet_pton(socket.AF_INET, i.local_ip4)
1478 cls.pg5._remote_hosts[0]._ip4 = "172.17.255.4"
1479 cls.pg5.set_table_ip4(10)
1480 cls.pg6._local_ip4 = "172.16.255.1"
1481 cls.pg6._local_ip4n = socket.inet_pton(socket.AF_INET, i.local_ip4)
1482 cls.pg6._remote_hosts[0]._ip4 = "172.16.255.2"
1483 cls.pg6.set_table_ip4(20)
1484 for i in cls.overlapping_interfaces:
1492 cls.pg9.generate_remote_hosts(2)
1493 cls.pg9.config_ip4()
1494 ip_addr_n = socket.inet_pton(socket.AF_INET, "10.0.0.1")
1495 cls.vapi.sw_interface_add_del_address(cls.pg9.sw_if_index,
1499 cls.pg9.resolve_arp()
1500 cls.pg9._remote_hosts[1]._ip4 = cls.pg9._remote_hosts[0]._ip4
1501 cls.pg4._remote_ip4 = cls.pg9._remote_hosts[0]._ip4 = "10.0.0.2"
1502 cls.pg9.resolve_arp()
1505 super(TestNAT44, cls).tearDownClass()
1508 def test_dynamic(self):
1509 """ NAT44 dynamic translation test """
1511 self.nat44_add_address(self.nat_addr)
1512 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
1513 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
1517 pkts = self.create_stream_in(self.pg0, self.pg1)
1518 self.pg0.add_stream(pkts)
1519 self.pg_enable_capture(self.pg_interfaces)
1521 capture = self.pg1.get_capture(len(pkts))
1522 self.verify_capture_out(capture)
1525 pkts = self.create_stream_out(self.pg1)
1526 self.pg1.add_stream(pkts)
1527 self.pg_enable_capture(self.pg_interfaces)
1529 capture = self.pg0.get_capture(len(pkts))
1530 self.verify_capture_in(capture, self.pg0)
1532 def test_dynamic_icmp_errors_in2out_ttl_1(self):
1533 """ NAT44 handling of client packets with TTL=1 """
1535 self.nat44_add_address(self.nat_addr)
1536 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
1537 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
1540 # Client side - generate traffic
1541 pkts = self.create_stream_in(self.pg0, self.pg1, ttl=1)
1542 self.pg0.add_stream(pkts)
1543 self.pg_enable_capture(self.pg_interfaces)
1546 # Client side - verify ICMP type 11 packets
1547 capture = self.pg0.get_capture(len(pkts))
1548 self.verify_capture_in_with_icmp_errors(capture, self.pg0)
1550 def test_dynamic_icmp_errors_out2in_ttl_1(self):
1551 """ NAT44 handling of server packets with TTL=1 """
1553 self.nat44_add_address(self.nat_addr)
1554 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
1555 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
1558 # Client side - create sessions
1559 pkts = self.create_stream_in(self.pg0, self.pg1)
1560 self.pg0.add_stream(pkts)
1561 self.pg_enable_capture(self.pg_interfaces)
1564 # Server side - generate traffic
1565 capture = self.pg1.get_capture(len(pkts))
1566 self.verify_capture_out(capture)
1567 pkts = self.create_stream_out(self.pg1, ttl=1)
1568 self.pg1.add_stream(pkts)
1569 self.pg_enable_capture(self.pg_interfaces)
1572 # Server side - verify ICMP type 11 packets
1573 capture = self.pg1.get_capture(len(pkts))
1574 self.verify_capture_out_with_icmp_errors(capture,
1575 src_ip=self.pg1.local_ip4)
1577 def test_dynamic_icmp_errors_in2out_ttl_2(self):
1578 """ NAT44 handling of error responses to client packets with TTL=2 """
1580 self.nat44_add_address(self.nat_addr)
1581 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
1582 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
1585 # Client side - generate traffic
1586 pkts = self.create_stream_in(self.pg0, self.pg1, ttl=2)
1587 self.pg0.add_stream(pkts)
1588 self.pg_enable_capture(self.pg_interfaces)
1591 # Server side - simulate ICMP type 11 response
1592 capture = self.pg1.get_capture(len(pkts))
1593 pkts = [Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
1594 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
1595 ICMP(type=11) / packet[IP] for packet in capture]
1596 self.pg1.add_stream(pkts)
1597 self.pg_enable_capture(self.pg_interfaces)
1600 # Client side - verify ICMP type 11 packets
1601 capture = self.pg0.get_capture(len(pkts))
1602 self.verify_capture_in_with_icmp_errors(capture, self.pg0)
1604 def test_dynamic_icmp_errors_out2in_ttl_2(self):
1605 """ NAT44 handling of error responses to server packets with TTL=2 """
1607 self.nat44_add_address(self.nat_addr)
1608 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
1609 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
1612 # Client side - create sessions
1613 pkts = self.create_stream_in(self.pg0, self.pg1)
1614 self.pg0.add_stream(pkts)
1615 self.pg_enable_capture(self.pg_interfaces)
1618 # Server side - generate traffic
1619 capture = self.pg1.get_capture(len(pkts))
1620 self.verify_capture_out(capture)
1621 pkts = self.create_stream_out(self.pg1, ttl=2)
1622 self.pg1.add_stream(pkts)
1623 self.pg_enable_capture(self.pg_interfaces)
1626 # Client side - simulate ICMP type 11 response
1627 capture = self.pg0.get_capture(len(pkts))
1628 pkts = [Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
1629 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
1630 ICMP(type=11) / packet[IP] for packet in capture]
1631 self.pg0.add_stream(pkts)
1632 self.pg_enable_capture(self.pg_interfaces)
1635 # Server side - verify ICMP type 11 packets
1636 capture = self.pg1.get_capture(len(pkts))
1637 self.verify_capture_out_with_icmp_errors(capture)
1639 def test_ping_out_interface_from_outside(self):
1640 """ Ping NAT44 out interface from outside network """
1642 self.nat44_add_address(self.nat_addr)
1643 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
1644 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
1647 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
1648 IP(src=self.pg1.remote_ip4, dst=self.pg1.local_ip4) /
1649 ICMP(id=self.icmp_id_out, type='echo-request'))
1651 self.pg1.add_stream(pkts)
1652 self.pg_enable_capture(self.pg_interfaces)
1654 capture = self.pg1.get_capture(len(pkts))
1657 self.assertEqual(packet[IP].src, self.pg1.local_ip4)
1658 self.assertEqual(packet[IP].dst, self.pg1.remote_ip4)
1659 self.assertEqual(packet[ICMP].id, self.icmp_id_in)
1660 self.assertEqual(packet[ICMP].type, 0) # echo reply
1662 self.logger.error(ppp("Unexpected or invalid packet "
1663 "(outside network):", packet))
1666 def test_ping_internal_host_from_outside(self):
1667 """ Ping internal host from outside network """
1669 self.nat44_add_static_mapping(self.pg0.remote_ip4, self.nat_addr)
1670 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
1671 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
1675 pkt = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
1676 IP(src=self.pg1.remote_ip4, dst=self.nat_addr, ttl=64) /
1677 ICMP(id=self.icmp_id_out, type='echo-request'))
1678 self.pg1.add_stream(pkt)
1679 self.pg_enable_capture(self.pg_interfaces)
1681 capture = self.pg0.get_capture(1)
1682 self.verify_capture_in(capture, self.pg0)
1683 self.assert_equal(capture[0][IP].proto, IP_PROTOS.icmp)
1686 pkt = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
1687 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4, ttl=64) /
1688 ICMP(id=self.icmp_id_in, type='echo-reply'))
1689 self.pg0.add_stream(pkt)
1690 self.pg_enable_capture(self.pg_interfaces)
1692 capture = self.pg1.get_capture(1)
1693 self.verify_capture_out(capture, same_port=True)
1694 self.assert_equal(capture[0][IP].proto, IP_PROTOS.icmp)
1696 def test_forwarding(self):
1697 """ NAT44 forwarding test """
1699 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
1700 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
1702 self.vapi.nat44_forwarding_enable_disable(1)
1704 real_ip = self.pg0.remote_ip4n
1705 alias_ip = self.nat_addr_n
1706 self.vapi.nat44_add_del_static_mapping(local_ip=real_ip,
1707 external_ip=alias_ip)
1710 # static mapping match
1712 pkts = self.create_stream_out(self.pg1)
1713 self.pg1.add_stream(pkts)
1714 self.pg_enable_capture(self.pg_interfaces)
1716 capture = self.pg0.get_capture(len(pkts))
1717 self.verify_capture_in(capture, self.pg0)
1719 pkts = self.create_stream_in(self.pg0, self.pg1)
1720 self.pg0.add_stream(pkts)
1721 self.pg_enable_capture(self.pg_interfaces)
1723 capture = self.pg1.get_capture(len(pkts))
1724 self.verify_capture_out(capture, same_port=True)
1726 # no static mapping match
1728 host0 = self.pg0.remote_hosts[0]
1729 self.pg0.remote_hosts[0] = self.pg0.remote_hosts[1]
1731 pkts = self.create_stream_out(self.pg1,
1732 dst_ip=self.pg0.remote_ip4,
1733 use_inside_ports=True)
1734 self.pg1.add_stream(pkts)
1735 self.pg_enable_capture(self.pg_interfaces)
1737 capture = self.pg0.get_capture(len(pkts))
1738 self.verify_capture_in(capture, self.pg0)
1740 pkts = self.create_stream_in(self.pg0, self.pg1)
1741 self.pg0.add_stream(pkts)
1742 self.pg_enable_capture(self.pg_interfaces)
1744 capture = self.pg1.get_capture(len(pkts))
1745 self.verify_capture_out(capture, nat_ip=self.pg0.remote_ip4,
1748 self.pg0.remote_hosts[0] = host0
1751 self.vapi.nat44_forwarding_enable_disable(0)
1752 self.vapi.nat44_add_del_static_mapping(local_ip=real_ip,
1753 external_ip=alias_ip,
1756 def test_static_in(self):
1757 """ 1:1 NAT initialized from inside network """
1759 nat_ip = "10.0.0.10"
1760 self.tcp_port_out = 6303
1761 self.udp_port_out = 6304
1762 self.icmp_id_out = 6305
1764 self.nat44_add_static_mapping(self.pg0.remote_ip4, nat_ip)
1765 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
1766 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
1768 sm = self.vapi.nat44_static_mapping_dump()
1769 self.assertEqual(len(sm), 1)
1770 self.assertEqual((sm[0].tag).split('\0', 1)[0], '')
1771 self.assertEqual(sm[0].protocol, 0)
1772 self.assertEqual(sm[0].local_port, 0)
1773 self.assertEqual(sm[0].external_port, 0)
1776 pkts = self.create_stream_in(self.pg0, self.pg1)
1777 self.pg0.add_stream(pkts)
1778 self.pg_enable_capture(self.pg_interfaces)
1780 capture = self.pg1.get_capture(len(pkts))
1781 self.verify_capture_out(capture, nat_ip, True)
1784 pkts = self.create_stream_out(self.pg1, nat_ip)
1785 self.pg1.add_stream(pkts)
1786 self.pg_enable_capture(self.pg_interfaces)
1788 capture = self.pg0.get_capture(len(pkts))
1789 self.verify_capture_in(capture, self.pg0)
1791 def test_static_out(self):
1792 """ 1:1 NAT initialized from outside network """
1794 nat_ip = "10.0.0.20"
1795 self.tcp_port_out = 6303
1796 self.udp_port_out = 6304
1797 self.icmp_id_out = 6305
1800 self.nat44_add_static_mapping(self.pg0.remote_ip4, nat_ip, tag=tag)
1801 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
1802 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
1804 sm = self.vapi.nat44_static_mapping_dump()
1805 self.assertEqual(len(sm), 1)
1806 self.assertEqual((sm[0].tag).split('\0', 1)[0], tag)
1809 pkts = self.create_stream_out(self.pg1, nat_ip)
1810 self.pg1.add_stream(pkts)
1811 self.pg_enable_capture(self.pg_interfaces)
1813 capture = self.pg0.get_capture(len(pkts))
1814 self.verify_capture_in(capture, self.pg0)
1817 pkts = self.create_stream_in(self.pg0, self.pg1)
1818 self.pg0.add_stream(pkts)
1819 self.pg_enable_capture(self.pg_interfaces)
1821 capture = self.pg1.get_capture(len(pkts))
1822 self.verify_capture_out(capture, nat_ip, True)
1824 def test_static_with_port_in(self):
1825 """ 1:1 NAPT initialized from inside network """
1827 self.tcp_port_out = 3606
1828 self.udp_port_out = 3607
1829 self.icmp_id_out = 3608
1831 self.nat44_add_address(self.nat_addr)
1832 self.nat44_add_static_mapping(self.pg0.remote_ip4, self.nat_addr,
1833 self.tcp_port_in, self.tcp_port_out,
1834 proto=IP_PROTOS.tcp)
1835 self.nat44_add_static_mapping(self.pg0.remote_ip4, self.nat_addr,
1836 self.udp_port_in, self.udp_port_out,
1837 proto=IP_PROTOS.udp)
1838 self.nat44_add_static_mapping(self.pg0.remote_ip4, self.nat_addr,
1839 self.icmp_id_in, self.icmp_id_out,
1840 proto=IP_PROTOS.icmp)
1841 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
1842 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
1846 pkts = self.create_stream_in(self.pg0, self.pg1)
1847 self.pg0.add_stream(pkts)
1848 self.pg_enable_capture(self.pg_interfaces)
1850 capture = self.pg1.get_capture(len(pkts))
1851 self.verify_capture_out(capture)
1854 pkts = self.create_stream_out(self.pg1)
1855 self.pg1.add_stream(pkts)
1856 self.pg_enable_capture(self.pg_interfaces)
1858 capture = self.pg0.get_capture(len(pkts))
1859 self.verify_capture_in(capture, self.pg0)
1861 def test_static_with_port_out(self):
1862 """ 1:1 NAPT initialized from outside network """
1864 self.tcp_port_out = 30606
1865 self.udp_port_out = 30607
1866 self.icmp_id_out = 30608
1868 self.nat44_add_address(self.nat_addr)
1869 self.nat44_add_static_mapping(self.pg0.remote_ip4, self.nat_addr,
1870 self.tcp_port_in, self.tcp_port_out,
1871 proto=IP_PROTOS.tcp)
1872 self.nat44_add_static_mapping(self.pg0.remote_ip4, self.nat_addr,
1873 self.udp_port_in, self.udp_port_out,
1874 proto=IP_PROTOS.udp)
1875 self.nat44_add_static_mapping(self.pg0.remote_ip4, self.nat_addr,
1876 self.icmp_id_in, self.icmp_id_out,
1877 proto=IP_PROTOS.icmp)
1878 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
1879 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
1883 pkts = self.create_stream_out(self.pg1)
1884 self.pg1.add_stream(pkts)
1885 self.pg_enable_capture(self.pg_interfaces)
1887 capture = self.pg0.get_capture(len(pkts))
1888 self.verify_capture_in(capture, self.pg0)
1891 pkts = self.create_stream_in(self.pg0, self.pg1)
1892 self.pg0.add_stream(pkts)
1893 self.pg_enable_capture(self.pg_interfaces)
1895 capture = self.pg1.get_capture(len(pkts))
1896 self.verify_capture_out(capture)
1898 def test_static_vrf_aware(self):
1899 """ 1:1 NAT VRF awareness """
1901 nat_ip1 = "10.0.0.30"
1902 nat_ip2 = "10.0.0.40"
1903 self.tcp_port_out = 6303
1904 self.udp_port_out = 6304
1905 self.icmp_id_out = 6305
1907 self.nat44_add_static_mapping(self.pg4.remote_ip4, nat_ip1,
1909 self.nat44_add_static_mapping(self.pg0.remote_ip4, nat_ip2,
1911 self.vapi.nat44_interface_add_del_feature(self.pg3.sw_if_index,
1913 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
1914 self.vapi.nat44_interface_add_del_feature(self.pg4.sw_if_index)
1916 # inside interface VRF match NAT44 static mapping VRF
1917 pkts = self.create_stream_in(self.pg4, self.pg3)
1918 self.pg4.add_stream(pkts)
1919 self.pg_enable_capture(self.pg_interfaces)
1921 capture = self.pg3.get_capture(len(pkts))
1922 self.verify_capture_out(capture, nat_ip1, True)
1924 # inside interface VRF don't match NAT44 static mapping VRF (packets
1926 pkts = self.create_stream_in(self.pg0, self.pg3)
1927 self.pg0.add_stream(pkts)
1928 self.pg_enable_capture(self.pg_interfaces)
1930 self.pg3.assert_nothing_captured()
1932 def test_dynamic_to_static(self):
1933 """ Switch from dynamic translation to 1:1NAT """
1934 nat_ip = "10.0.0.10"
1935 self.tcp_port_out = 6303
1936 self.udp_port_out = 6304
1937 self.icmp_id_out = 6305
1939 self.nat44_add_address(self.nat_addr)
1940 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
1941 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
1945 pkts = self.create_stream_in(self.pg0, self.pg1)
1946 self.pg0.add_stream(pkts)
1947 self.pg_enable_capture(self.pg_interfaces)
1949 capture = self.pg1.get_capture(len(pkts))
1950 self.verify_capture_out(capture)
1953 self.nat44_add_static_mapping(self.pg0.remote_ip4, nat_ip)
1954 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4n, 0)
1955 self.assertEqual(len(sessions), 0)
1956 pkts = self.create_stream_in(self.pg0, self.pg1)
1957 self.pg0.add_stream(pkts)
1958 self.pg_enable_capture(self.pg_interfaces)
1960 capture = self.pg1.get_capture(len(pkts))
1961 self.verify_capture_out(capture, nat_ip, True)
1963 def test_identity_nat(self):
1964 """ Identity NAT """
1966 self.vapi.nat44_add_del_identity_mapping(ip=self.pg0.remote_ip4n)
1967 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
1968 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
1971 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
1972 IP(src=self.pg1.remote_ip4, dst=self.pg0.remote_ip4) /
1973 TCP(sport=12345, dport=56789))
1974 self.pg1.add_stream(p)
1975 self.pg_enable_capture(self.pg_interfaces)
1977 capture = self.pg0.get_capture(1)
1982 self.assertEqual(ip.dst, self.pg0.remote_ip4)
1983 self.assertEqual(ip.src, self.pg1.remote_ip4)
1984 self.assertEqual(tcp.dport, 56789)
1985 self.assertEqual(tcp.sport, 12345)
1986 self.assert_packet_checksums_valid(p)
1988 self.logger.error(ppp("Unexpected or invalid packet:", p))
1991 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4n, 0)
1992 self.assertEqual(len(sessions), 0)
1993 self.vapi.nat44_add_del_identity_mapping(ip=self.pg0.remote_ip4n,
1995 identity_mappings = self.vapi.nat44_identity_mapping_dump()
1996 self.assertEqual(len(identity_mappings), 2)
1998 def test_multiple_inside_interfaces(self):
1999 """ NAT44 multiple non-overlapping address space inside interfaces """
2001 self.nat44_add_address(self.nat_addr)
2002 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
2003 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index)
2004 self.vapi.nat44_interface_add_del_feature(self.pg3.sw_if_index,
2007 # between two NAT44 inside interfaces (no translation)
2008 pkts = self.create_stream_in(self.pg0, self.pg1)
2009 self.pg0.add_stream(pkts)
2010 self.pg_enable_capture(self.pg_interfaces)
2012 capture = self.pg1.get_capture(len(pkts))
2013 self.verify_capture_no_translation(capture, self.pg0, self.pg1)
2015 # from NAT44 inside to interface without NAT44 feature (no translation)
2016 pkts = self.create_stream_in(self.pg0, self.pg2)
2017 self.pg0.add_stream(pkts)
2018 self.pg_enable_capture(self.pg_interfaces)
2020 capture = self.pg2.get_capture(len(pkts))
2021 self.verify_capture_no_translation(capture, self.pg0, self.pg2)
2023 # in2out 1st interface
2024 pkts = self.create_stream_in(self.pg0, self.pg3)
2025 self.pg0.add_stream(pkts)
2026 self.pg_enable_capture(self.pg_interfaces)
2028 capture = self.pg3.get_capture(len(pkts))
2029 self.verify_capture_out(capture)
2031 # out2in 1st interface
2032 pkts = self.create_stream_out(self.pg3)
2033 self.pg3.add_stream(pkts)
2034 self.pg_enable_capture(self.pg_interfaces)
2036 capture = self.pg0.get_capture(len(pkts))
2037 self.verify_capture_in(capture, self.pg0)
2039 # in2out 2nd interface
2040 pkts = self.create_stream_in(self.pg1, self.pg3)
2041 self.pg1.add_stream(pkts)
2042 self.pg_enable_capture(self.pg_interfaces)
2044 capture = self.pg3.get_capture(len(pkts))
2045 self.verify_capture_out(capture)
2047 # out2in 2nd interface
2048 pkts = self.create_stream_out(self.pg3)
2049 self.pg3.add_stream(pkts)
2050 self.pg_enable_capture(self.pg_interfaces)
2052 capture = self.pg1.get_capture(len(pkts))
2053 self.verify_capture_in(capture, self.pg1)
2055 def test_inside_overlapping_interfaces(self):
2056 """ NAT44 multiple inside interfaces with overlapping address space """
2058 static_nat_ip = "10.0.0.10"
2059 self.nat44_add_address(self.nat_addr)
2060 self.vapi.nat44_interface_add_del_feature(self.pg3.sw_if_index,
2062 self.vapi.nat44_interface_add_del_feature(self.pg4.sw_if_index)
2063 self.vapi.nat44_interface_add_del_feature(self.pg5.sw_if_index)
2064 self.vapi.nat44_interface_add_del_feature(self.pg6.sw_if_index)
2065 self.nat44_add_static_mapping(self.pg6.remote_ip4, static_nat_ip,
2068 # between NAT44 inside interfaces with same VRF (no translation)
2069 pkts = self.create_stream_in(self.pg4, self.pg5)
2070 self.pg4.add_stream(pkts)
2071 self.pg_enable_capture(self.pg_interfaces)
2073 capture = self.pg5.get_capture(len(pkts))
2074 self.verify_capture_no_translation(capture, self.pg4, self.pg5)
2076 # between NAT44 inside interfaces with different VRF (hairpinning)
2077 p = (Ether(src=self.pg4.remote_mac, dst=self.pg4.local_mac) /
2078 IP(src=self.pg4.remote_ip4, dst=static_nat_ip) /
2079 TCP(sport=1234, dport=5678))
2080 self.pg4.add_stream(p)
2081 self.pg_enable_capture(self.pg_interfaces)
2083 capture = self.pg6.get_capture(1)
2088 self.assertEqual(ip.src, self.nat_addr)
2089 self.assertEqual(ip.dst, self.pg6.remote_ip4)
2090 self.assertNotEqual(tcp.sport, 1234)
2091 self.assertEqual(tcp.dport, 5678)
2093 self.logger.error(ppp("Unexpected or invalid packet:", p))
2096 # in2out 1st interface
2097 pkts = self.create_stream_in(self.pg4, self.pg3)
2098 self.pg4.add_stream(pkts)
2099 self.pg_enable_capture(self.pg_interfaces)
2101 capture = self.pg3.get_capture(len(pkts))
2102 self.verify_capture_out(capture)
2104 # out2in 1st interface
2105 pkts = self.create_stream_out(self.pg3)
2106 self.pg3.add_stream(pkts)
2107 self.pg_enable_capture(self.pg_interfaces)
2109 capture = self.pg4.get_capture(len(pkts))
2110 self.verify_capture_in(capture, self.pg4)
2112 # in2out 2nd interface
2113 pkts = self.create_stream_in(self.pg5, self.pg3)
2114 self.pg5.add_stream(pkts)
2115 self.pg_enable_capture(self.pg_interfaces)
2117 capture = self.pg3.get_capture(len(pkts))
2118 self.verify_capture_out(capture)
2120 # out2in 2nd interface
2121 pkts = self.create_stream_out(self.pg3)
2122 self.pg3.add_stream(pkts)
2123 self.pg_enable_capture(self.pg_interfaces)
2125 capture = self.pg5.get_capture(len(pkts))
2126 self.verify_capture_in(capture, self.pg5)
2129 addresses = self.vapi.nat44_address_dump()
2130 self.assertEqual(len(addresses), 1)
2131 sessions = self.vapi.nat44_user_session_dump(self.pg5.remote_ip4n, 10)
2132 self.assertEqual(len(sessions), 3)
2133 for session in sessions:
2134 self.assertFalse(session.is_static)
2135 self.assertEqual(session.inside_ip_address[0:4],
2136 self.pg5.remote_ip4n)
2137 self.assertEqual(session.outside_ip_address,
2138 addresses[0].ip_address)
2139 self.assertEqual(sessions[0].protocol, IP_PROTOS.tcp)
2140 self.assertEqual(sessions[1].protocol, IP_PROTOS.udp)
2141 self.assertEqual(sessions[2].protocol, IP_PROTOS.icmp)
2142 self.assertEqual(sessions[0].inside_port, self.tcp_port_in)
2143 self.assertEqual(sessions[1].inside_port, self.udp_port_in)
2144 self.assertEqual(sessions[2].inside_port, self.icmp_id_in)
2145 self.assertEqual(sessions[0].outside_port, self.tcp_port_out)
2146 self.assertEqual(sessions[1].outside_port, self.udp_port_out)
2147 self.assertEqual(sessions[2].outside_port, self.icmp_id_out)
2149 # in2out 3rd interface
2150 pkts = self.create_stream_in(self.pg6, self.pg3)
2151 self.pg6.add_stream(pkts)
2152 self.pg_enable_capture(self.pg_interfaces)
2154 capture = self.pg3.get_capture(len(pkts))
2155 self.verify_capture_out(capture, static_nat_ip, True)
2157 # out2in 3rd interface
2158 pkts = self.create_stream_out(self.pg3, static_nat_ip)
2159 self.pg3.add_stream(pkts)
2160 self.pg_enable_capture(self.pg_interfaces)
2162 capture = self.pg6.get_capture(len(pkts))
2163 self.verify_capture_in(capture, self.pg6)
2165 # general user and session dump verifications
2166 users = self.vapi.nat44_user_dump()
2167 self.assertGreaterEqual(len(users), 3)
2168 addresses = self.vapi.nat44_address_dump()
2169 self.assertEqual(len(addresses), 1)
2171 sessions = self.vapi.nat44_user_session_dump(user.ip_address,
2173 for session in sessions:
2174 self.assertEqual(user.ip_address, session.inside_ip_address)
2175 self.assertTrue(session.total_bytes > session.total_pkts > 0)
2176 self.assertTrue(session.protocol in
2177 [IP_PROTOS.tcp, IP_PROTOS.udp,
2179 self.assertFalse(session.ext_host_valid)
2182 sessions = self.vapi.nat44_user_session_dump(self.pg4.remote_ip4n, 10)
2183 self.assertGreaterEqual(len(sessions), 4)
2184 for session in sessions:
2185 self.assertFalse(session.is_static)
2186 self.assertEqual(session.inside_ip_address[0:4],
2187 self.pg4.remote_ip4n)
2188 self.assertEqual(session.outside_ip_address,
2189 addresses[0].ip_address)
2192 sessions = self.vapi.nat44_user_session_dump(self.pg6.remote_ip4n, 20)
2193 self.assertGreaterEqual(len(sessions), 3)
2194 for session in sessions:
2195 self.assertTrue(session.is_static)
2196 self.assertEqual(session.inside_ip_address[0:4],
2197 self.pg6.remote_ip4n)
2198 self.assertEqual(map(ord, session.outside_ip_address[0:4]),
2199 map(int, static_nat_ip.split('.')))
2200 self.assertTrue(session.inside_port in
2201 [self.tcp_port_in, self.udp_port_in,
2204 def test_hairpinning(self):
2205 """ NAT44 hairpinning - 1:1 NAPT """
2207 host = self.pg0.remote_hosts[0]
2208 server = self.pg0.remote_hosts[1]
2211 server_in_port = 5678
2212 server_out_port = 8765
2214 self.nat44_add_address(self.nat_addr)
2215 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
2216 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
2218 # add static mapping for server
2219 self.nat44_add_static_mapping(server.ip4, self.nat_addr,
2220 server_in_port, server_out_port,
2221 proto=IP_PROTOS.tcp)
2223 # send packet from host to server
2224 p = (Ether(src=host.mac, dst=self.pg0.local_mac) /
2225 IP(src=host.ip4, dst=self.nat_addr) /
2226 TCP(sport=host_in_port, dport=server_out_port))
2227 self.pg0.add_stream(p)
2228 self.pg_enable_capture(self.pg_interfaces)
2230 capture = self.pg0.get_capture(1)
2235 self.assertEqual(ip.src, self.nat_addr)
2236 self.assertEqual(ip.dst, server.ip4)
2237 self.assertNotEqual(tcp.sport, host_in_port)
2238 self.assertEqual(tcp.dport, server_in_port)
2239 self.assert_packet_checksums_valid(p)
2240 host_out_port = tcp.sport
2242 self.logger.error(ppp("Unexpected or invalid packet:", p))
2245 # send reply from server to host
2246 p = (Ether(src=server.mac, dst=self.pg0.local_mac) /
2247 IP(src=server.ip4, dst=self.nat_addr) /
2248 TCP(sport=server_in_port, dport=host_out_port))
2249 self.pg0.add_stream(p)
2250 self.pg_enable_capture(self.pg_interfaces)
2252 capture = self.pg0.get_capture(1)
2257 self.assertEqual(ip.src, self.nat_addr)
2258 self.assertEqual(ip.dst, host.ip4)
2259 self.assertEqual(tcp.sport, server_out_port)
2260 self.assertEqual(tcp.dport, host_in_port)
2261 self.assert_packet_checksums_valid(p)
2263 self.logger.error(ppp("Unexpected or invalid packet:", p))
2266 def test_hairpinning2(self):
2267 """ NAT44 hairpinning - 1:1 NAT"""
2269 server1_nat_ip = "10.0.0.10"
2270 server2_nat_ip = "10.0.0.11"
2271 host = self.pg0.remote_hosts[0]
2272 server1 = self.pg0.remote_hosts[1]
2273 server2 = self.pg0.remote_hosts[2]
2274 server_tcp_port = 22
2275 server_udp_port = 20
2277 self.nat44_add_address(self.nat_addr)
2278 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
2279 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
2282 # add static mapping for servers
2283 self.nat44_add_static_mapping(server1.ip4, server1_nat_ip)
2284 self.nat44_add_static_mapping(server2.ip4, server2_nat_ip)
2288 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2289 IP(src=host.ip4, dst=server1_nat_ip) /
2290 TCP(sport=self.tcp_port_in, dport=server_tcp_port))
2292 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2293 IP(src=host.ip4, dst=server1_nat_ip) /
2294 UDP(sport=self.udp_port_in, dport=server_udp_port))
2296 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2297 IP(src=host.ip4, dst=server1_nat_ip) /
2298 ICMP(id=self.icmp_id_in, type='echo-request'))
2300 self.pg0.add_stream(pkts)
2301 self.pg_enable_capture(self.pg_interfaces)
2303 capture = self.pg0.get_capture(len(pkts))
2304 for packet in capture:
2306 self.assertEqual(packet[IP].src, self.nat_addr)
2307 self.assertEqual(packet[IP].dst, server1.ip4)
2308 if packet.haslayer(TCP):
2309 self.assertNotEqual(packet[TCP].sport, self.tcp_port_in)
2310 self.assertEqual(packet[TCP].dport, server_tcp_port)
2311 self.tcp_port_out = packet[TCP].sport
2312 self.assert_packet_checksums_valid(packet)
2313 elif packet.haslayer(UDP):
2314 self.assertNotEqual(packet[UDP].sport, self.udp_port_in)
2315 self.assertEqual(packet[UDP].dport, server_udp_port)
2316 self.udp_port_out = packet[UDP].sport
2318 self.assertNotEqual(packet[ICMP].id, self.icmp_id_in)
2319 self.icmp_id_out = packet[ICMP].id
2321 self.logger.error(ppp("Unexpected or invalid packet:", packet))
2326 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2327 IP(src=server1.ip4, dst=self.nat_addr) /
2328 TCP(sport=server_tcp_port, dport=self.tcp_port_out))
2330 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2331 IP(src=server1.ip4, dst=self.nat_addr) /
2332 UDP(sport=server_udp_port, dport=self.udp_port_out))
2334 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2335 IP(src=server1.ip4, dst=self.nat_addr) /
2336 ICMP(id=self.icmp_id_out, type='echo-reply'))
2338 self.pg0.add_stream(pkts)
2339 self.pg_enable_capture(self.pg_interfaces)
2341 capture = self.pg0.get_capture(len(pkts))
2342 for packet in capture:
2344 self.assertEqual(packet[IP].src, server1_nat_ip)
2345 self.assertEqual(packet[IP].dst, host.ip4)
2346 if packet.haslayer(TCP):
2347 self.assertEqual(packet[TCP].dport, self.tcp_port_in)
2348 self.assertEqual(packet[TCP].sport, server_tcp_port)
2349 self.assert_packet_checksums_valid(packet)
2350 elif packet.haslayer(UDP):
2351 self.assertEqual(packet[UDP].dport, self.udp_port_in)
2352 self.assertEqual(packet[UDP].sport, server_udp_port)
2354 self.assertEqual(packet[ICMP].id, self.icmp_id_in)
2356 self.logger.error(ppp("Unexpected or invalid packet:", packet))
2359 # server2 to server1
2361 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2362 IP(src=server2.ip4, dst=server1_nat_ip) /
2363 TCP(sport=self.tcp_port_in, dport=server_tcp_port))
2365 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2366 IP(src=server2.ip4, dst=server1_nat_ip) /
2367 UDP(sport=self.udp_port_in, dport=server_udp_port))
2369 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2370 IP(src=server2.ip4, dst=server1_nat_ip) /
2371 ICMP(id=self.icmp_id_in, type='echo-request'))
2373 self.pg0.add_stream(pkts)
2374 self.pg_enable_capture(self.pg_interfaces)
2376 capture = self.pg0.get_capture(len(pkts))
2377 for packet in capture:
2379 self.assertEqual(packet[IP].src, server2_nat_ip)
2380 self.assertEqual(packet[IP].dst, server1.ip4)
2381 if packet.haslayer(TCP):
2382 self.assertEqual(packet[TCP].sport, self.tcp_port_in)
2383 self.assertEqual(packet[TCP].dport, server_tcp_port)
2384 self.tcp_port_out = packet[TCP].sport
2385 self.assert_packet_checksums_valid(packet)
2386 elif packet.haslayer(UDP):
2387 self.assertEqual(packet[UDP].sport, self.udp_port_in)
2388 self.assertEqual(packet[UDP].dport, server_udp_port)
2389 self.udp_port_out = packet[UDP].sport
2391 self.assertEqual(packet[ICMP].id, self.icmp_id_in)
2392 self.icmp_id_out = packet[ICMP].id
2394 self.logger.error(ppp("Unexpected or invalid packet:", packet))
2397 # server1 to server2
2399 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2400 IP(src=server1.ip4, dst=server2_nat_ip) /
2401 TCP(sport=server_tcp_port, dport=self.tcp_port_out))
2403 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2404 IP(src=server1.ip4, dst=server2_nat_ip) /
2405 UDP(sport=server_udp_port, dport=self.udp_port_out))
2407 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2408 IP(src=server1.ip4, dst=server2_nat_ip) /
2409 ICMP(id=self.icmp_id_out, type='echo-reply'))
2411 self.pg0.add_stream(pkts)
2412 self.pg_enable_capture(self.pg_interfaces)
2414 capture = self.pg0.get_capture(len(pkts))
2415 for packet in capture:
2417 self.assertEqual(packet[IP].src, server1_nat_ip)
2418 self.assertEqual(packet[IP].dst, server2.ip4)
2419 if packet.haslayer(TCP):
2420 self.assertEqual(packet[TCP].dport, self.tcp_port_in)
2421 self.assertEqual(packet[TCP].sport, server_tcp_port)
2422 self.assert_packet_checksums_valid(packet)
2423 elif packet.haslayer(UDP):
2424 self.assertEqual(packet[UDP].dport, self.udp_port_in)
2425 self.assertEqual(packet[UDP].sport, server_udp_port)
2427 self.assertEqual(packet[ICMP].id, self.icmp_id_in)
2429 self.logger.error(ppp("Unexpected or invalid packet:", packet))
2432 def test_max_translations_per_user(self):
2433 """ MAX translations per user - recycle the least recently used """
2435 self.nat44_add_address(self.nat_addr)
2436 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
2437 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
2440 # get maximum number of translations per user
2441 nat44_config = self.vapi.nat_show_config()
2443 # send more than maximum number of translations per user packets
2444 pkts_num = nat44_config.max_translations_per_user + 5
2446 for port in range(0, pkts_num):
2447 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2448 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
2449 TCP(sport=1025 + port))
2451 self.pg0.add_stream(pkts)
2452 self.pg_enable_capture(self.pg_interfaces)
2455 # verify number of translated packet
2456 self.pg1.get_capture(pkts_num)
2458 users = self.vapi.nat44_user_dump()
2460 if user.ip_address == self.pg0.remote_ip4n:
2461 self.assertEqual(user.nsessions,
2462 nat44_config.max_translations_per_user)
2463 self.assertEqual(user.nstaticsessions, 0)
2466 self.nat44_add_static_mapping(self.pg0.remote_ip4, self.nat_addr,
2468 proto=IP_PROTOS.tcp)
2469 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2470 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
2471 TCP(sport=tcp_port))
2472 self.pg0.add_stream(p)
2473 self.pg_enable_capture(self.pg_interfaces)
2475 self.pg1.get_capture(1)
2476 users = self.vapi.nat44_user_dump()
2478 if user.ip_address == self.pg0.remote_ip4n:
2479 self.assertEqual(user.nsessions,
2480 nat44_config.max_translations_per_user - 1)
2481 self.assertEqual(user.nstaticsessions, 1)
2483 def test_interface_addr(self):
2484 """ Acquire NAT44 addresses from interface """
2485 self.vapi.nat44_add_interface_addr(self.pg7.sw_if_index)
2487 # no address in NAT pool
2488 adresses = self.vapi.nat44_address_dump()
2489 self.assertEqual(0, len(adresses))
2491 # configure interface address and check NAT address pool
2492 self.pg7.config_ip4()
2493 adresses = self.vapi.nat44_address_dump()
2494 self.assertEqual(1, len(adresses))
2495 self.assertEqual(adresses[0].ip_address[0:4], self.pg7.local_ip4n)
2497 # remove interface address and check NAT address pool
2498 self.pg7.unconfig_ip4()
2499 adresses = self.vapi.nat44_address_dump()
2500 self.assertEqual(0, len(adresses))
2502 def test_interface_addr_static_mapping(self):
2503 """ Static mapping with addresses from interface """
2506 self.vapi.nat44_add_interface_addr(self.pg7.sw_if_index)
2507 self.nat44_add_static_mapping(
2509 external_sw_if_index=self.pg7.sw_if_index,
2512 # static mappings with external interface
2513 static_mappings = self.vapi.nat44_static_mapping_dump()
2514 self.assertEqual(1, len(static_mappings))
2515 self.assertEqual(self.pg7.sw_if_index,
2516 static_mappings[0].external_sw_if_index)
2517 self.assertEqual((static_mappings[0].tag).split('\0', 1)[0], tag)
2519 # configure interface address and check static mappings
2520 self.pg7.config_ip4()
2521 static_mappings = self.vapi.nat44_static_mapping_dump()
2522 self.assertEqual(2, len(static_mappings))
2524 for sm in static_mappings:
2525 if sm.external_sw_if_index == 0xFFFFFFFF:
2526 self.assertEqual(sm.external_ip_address[0:4],
2527 self.pg7.local_ip4n)
2528 self.assertEqual((sm.tag).split('\0', 1)[0], tag)
2530 self.assertTrue(resolved)
2532 # remove interface address and check static mappings
2533 self.pg7.unconfig_ip4()
2534 static_mappings = self.vapi.nat44_static_mapping_dump()
2535 self.assertEqual(1, len(static_mappings))
2536 self.assertEqual(self.pg7.sw_if_index,
2537 static_mappings[0].external_sw_if_index)
2538 self.assertEqual((static_mappings[0].tag).split('\0', 1)[0], tag)
2540 # configure interface address again and check static mappings
2541 self.pg7.config_ip4()
2542 static_mappings = self.vapi.nat44_static_mapping_dump()
2543 self.assertEqual(2, len(static_mappings))
2545 for sm in static_mappings:
2546 if sm.external_sw_if_index == 0xFFFFFFFF:
2547 self.assertEqual(sm.external_ip_address[0:4],
2548 self.pg7.local_ip4n)
2549 self.assertEqual((sm.tag).split('\0', 1)[0], tag)
2551 self.assertTrue(resolved)
2553 # remove static mapping
2554 self.nat44_add_static_mapping(
2556 external_sw_if_index=self.pg7.sw_if_index,
2559 static_mappings = self.vapi.nat44_static_mapping_dump()
2560 self.assertEqual(0, len(static_mappings))
2562 def test_interface_addr_identity_nat(self):
2563 """ Identity NAT with addresses from interface """
2566 self.vapi.nat44_add_interface_addr(self.pg7.sw_if_index)
2567 self.vapi.nat44_add_del_identity_mapping(
2568 sw_if_index=self.pg7.sw_if_index,
2570 protocol=IP_PROTOS.tcp,
2573 # identity mappings with external interface
2574 identity_mappings = self.vapi.nat44_identity_mapping_dump()
2575 self.assertEqual(1, len(identity_mappings))
2576 self.assertEqual(self.pg7.sw_if_index,
2577 identity_mappings[0].sw_if_index)
2579 # configure interface address and check identity mappings
2580 self.pg7.config_ip4()
2581 identity_mappings = self.vapi.nat44_identity_mapping_dump()
2583 self.assertEqual(2, len(identity_mappings))
2584 for sm in identity_mappings:
2585 if sm.sw_if_index == 0xFFFFFFFF:
2586 self.assertEqual(identity_mappings[0].ip_address,
2587 self.pg7.local_ip4n)
2588 self.assertEqual(port, identity_mappings[0].port)
2589 self.assertEqual(IP_PROTOS.tcp, identity_mappings[0].protocol)
2591 self.assertTrue(resolved)
2593 # remove interface address and check identity mappings
2594 self.pg7.unconfig_ip4()
2595 identity_mappings = self.vapi.nat44_identity_mapping_dump()
2596 self.assertEqual(1, len(identity_mappings))
2597 self.assertEqual(self.pg7.sw_if_index,
2598 identity_mappings[0].sw_if_index)
2600 def test_ipfix_nat44_sess(self):
2601 """ IPFIX logging NAT44 session created/delted """
2602 self.ipfix_domain_id = 10
2603 self.ipfix_src_port = 20202
2604 colector_port = 30303
2605 bind_layers(UDP, IPFIX, dport=30303)
2606 self.nat44_add_address(self.nat_addr)
2607 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
2608 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
2610 self.vapi.set_ipfix_exporter(collector_address=self.pg3.remote_ip4n,
2611 src_address=self.pg3.local_ip4n,
2613 template_interval=10,
2614 collector_port=colector_port)
2615 self.vapi.nat_ipfix(domain_id=self.ipfix_domain_id,
2616 src_port=self.ipfix_src_port)
2618 pkts = self.create_stream_in(self.pg0, self.pg1)
2619 self.pg0.add_stream(pkts)
2620 self.pg_enable_capture(self.pg_interfaces)
2622 capture = self.pg1.get_capture(len(pkts))
2623 self.verify_capture_out(capture)
2624 self.nat44_add_address(self.nat_addr, is_add=0)
2625 self.vapi.cli("ipfix flush") # FIXME this should be an API call
2626 capture = self.pg3.get_capture(9)
2627 ipfix = IPFIXDecoder()
2628 # first load template
2630 self.assertTrue(p.haslayer(IPFIX))
2631 self.assertEqual(p[IP].src, self.pg3.local_ip4)
2632 self.assertEqual(p[IP].dst, self.pg3.remote_ip4)
2633 self.assertEqual(p[UDP].sport, self.ipfix_src_port)
2634 self.assertEqual(p[UDP].dport, colector_port)
2635 self.assertEqual(p[IPFIX].observationDomainID,
2636 self.ipfix_domain_id)
2637 if p.haslayer(Template):
2638 ipfix.add_template(p.getlayer(Template))
2639 # verify events in data set
2641 if p.haslayer(Data):
2642 data = ipfix.decode_data_set(p.getlayer(Set))
2643 self.verify_ipfix_nat44_ses(data)
2645 def test_ipfix_addr_exhausted(self):
2646 """ IPFIX logging NAT addresses exhausted """
2647 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
2648 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
2650 self.vapi.set_ipfix_exporter(collector_address=self.pg3.remote_ip4n,
2651 src_address=self.pg3.local_ip4n,
2653 template_interval=10)
2654 self.vapi.nat_ipfix(domain_id=self.ipfix_domain_id,
2655 src_port=self.ipfix_src_port)
2657 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
2658 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
2660 self.pg0.add_stream(p)
2661 self.pg_enable_capture(self.pg_interfaces)
2663 self.pg1.assert_nothing_captured()
2665 self.vapi.cli("ipfix flush") # FIXME this should be an API call
2666 capture = self.pg3.get_capture(9)
2667 ipfix = IPFIXDecoder()
2668 # first load template
2670 self.assertTrue(p.haslayer(IPFIX))
2671 self.assertEqual(p[IP].src, self.pg3.local_ip4)
2672 self.assertEqual(p[IP].dst, self.pg3.remote_ip4)
2673 self.assertEqual(p[UDP].sport, self.ipfix_src_port)
2674 self.assertEqual(p[UDP].dport, 4739)
2675 self.assertEqual(p[IPFIX].observationDomainID,
2676 self.ipfix_domain_id)
2677 if p.haslayer(Template):
2678 ipfix.add_template(p.getlayer(Template))
2679 # verify events in data set
2681 if p.haslayer(Data):
2682 data = ipfix.decode_data_set(p.getlayer(Set))
2683 self.verify_ipfix_addr_exhausted(data)
2685 @unittest.skipUnless(running_extended_tests(), "part of extended tests")
2686 def test_ipfix_max_sessions(self):
2687 """ IPFIX logging maximum session entries exceeded """
2688 self.nat44_add_address(self.nat_addr)
2689 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
2690 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
2693 nat44_config = self.vapi.nat_show_config()
2694 max_sessions = 10 * nat44_config.translation_buckets
2697 for i in range(0, max_sessions):
2698 src = "10.10.%u.%u" % ((i & 0xFF00) >> 8, i & 0xFF)
2699 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2700 IP(src=src, dst=self.pg1.remote_ip4) /
2703 self.pg0.add_stream(pkts)
2704 self.pg_enable_capture(self.pg_interfaces)
2707 self.pg1.get_capture(max_sessions)
2708 self.vapi.set_ipfix_exporter(collector_address=self.pg3.remote_ip4n,
2709 src_address=self.pg3.local_ip4n,
2711 template_interval=10)
2712 self.vapi.nat_ipfix(domain_id=self.ipfix_domain_id,
2713 src_port=self.ipfix_src_port)
2715 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2716 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
2718 self.pg0.add_stream(p)
2719 self.pg_enable_capture(self.pg_interfaces)
2721 self.pg1.assert_nothing_captured()
2723 self.vapi.cli("ipfix flush") # FIXME this should be an API call
2724 capture = self.pg3.get_capture(9)
2725 ipfix = IPFIXDecoder()
2726 # first load template
2728 self.assertTrue(p.haslayer(IPFIX))
2729 self.assertEqual(p[IP].src, self.pg3.local_ip4)
2730 self.assertEqual(p[IP].dst, self.pg3.remote_ip4)
2731 self.assertEqual(p[UDP].sport, self.ipfix_src_port)
2732 self.assertEqual(p[UDP].dport, 4739)
2733 self.assertEqual(p[IPFIX].observationDomainID,
2734 self.ipfix_domain_id)
2735 if p.haslayer(Template):
2736 ipfix.add_template(p.getlayer(Template))
2737 # verify events in data set
2739 if p.haslayer(Data):
2740 data = ipfix.decode_data_set(p.getlayer(Set))
2741 self.verify_ipfix_max_sessions(data, max_sessions)
2743 def test_syslog_apmap(self):
2744 """ Test syslog address and port mapping creation and deletion """
2745 self.vapi.syslog_set_filter(SYSLOG_SEVERITY.INFO)
2746 self.vapi.syslog_set_sender(self.pg3.remote_ip4n, self.pg3.local_ip4n)
2747 self.nat44_add_address(self.nat_addr)
2748 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
2749 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
2752 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2753 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
2754 TCP(sport=self.tcp_port_in, dport=20))
2755 self.pg0.add_stream(p)
2756 self.pg_enable_capture(self.pg_interfaces)
2758 capture = self.pg1.get_capture(1)
2759 self.tcp_port_out = capture[0][TCP].sport
2760 capture = self.pg3.get_capture(1)
2761 self.verify_syslog_apmap(capture[0][Raw].load)
2763 self.pg_enable_capture(self.pg_interfaces)
2765 self.nat44_add_address(self.nat_addr, is_add=0)
2766 capture = self.pg3.get_capture(1)
2767 self.verify_syslog_apmap(capture[0][Raw].load, False)
2769 def test_pool_addr_fib(self):
2770 """ NAT44 add pool addresses to FIB """
2771 static_addr = '10.0.0.10'
2772 self.nat44_add_address(self.nat_addr)
2773 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
2774 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
2776 self.nat44_add_static_mapping(self.pg0.remote_ip4, static_addr)
2779 p = (Ether(src=self.pg1.remote_mac, dst='ff:ff:ff:ff:ff:ff') /
2780 ARP(op=ARP.who_has, pdst=self.nat_addr,
2781 psrc=self.pg1.remote_ip4, hwsrc=self.pg1.remote_mac))
2782 self.pg1.add_stream(p)
2783 self.pg_enable_capture(self.pg_interfaces)
2785 capture = self.pg1.get_capture(1)
2786 self.assertTrue(capture[0].haslayer(ARP))
2787 self.assertTrue(capture[0][ARP].op, ARP.is_at)
2790 p = (Ether(src=self.pg1.remote_mac, dst='ff:ff:ff:ff:ff:ff') /
2791 ARP(op=ARP.who_has, pdst=static_addr,
2792 psrc=self.pg1.remote_ip4, hwsrc=self.pg1.remote_mac))
2793 self.pg1.add_stream(p)
2794 self.pg_enable_capture(self.pg_interfaces)
2796 capture = self.pg1.get_capture(1)
2797 self.assertTrue(capture[0].haslayer(ARP))
2798 self.assertTrue(capture[0][ARP].op, ARP.is_at)
2800 # send ARP to non-NAT44 interface
2801 p = (Ether(src=self.pg2.remote_mac, dst='ff:ff:ff:ff:ff:ff') /
2802 ARP(op=ARP.who_has, pdst=self.nat_addr,
2803 psrc=self.pg2.remote_ip4, hwsrc=self.pg2.remote_mac))
2804 self.pg2.add_stream(p)
2805 self.pg_enable_capture(self.pg_interfaces)
2807 self.pg1.assert_nothing_captured()
2809 # remove addresses and verify
2810 self.nat44_add_address(self.nat_addr, is_add=0)
2811 self.nat44_add_static_mapping(self.pg0.remote_ip4, static_addr,
2814 p = (Ether(src=self.pg1.remote_mac, dst='ff:ff:ff:ff:ff:ff') /
2815 ARP(op=ARP.who_has, pdst=self.nat_addr,
2816 psrc=self.pg1.remote_ip4, hwsrc=self.pg1.remote_mac))
2817 self.pg1.add_stream(p)
2818 self.pg_enable_capture(self.pg_interfaces)
2820 self.pg1.assert_nothing_captured()
2822 p = (Ether(src=self.pg1.remote_mac, dst='ff:ff:ff:ff:ff:ff') /
2823 ARP(op=ARP.who_has, pdst=static_addr,
2824 psrc=self.pg1.remote_ip4, hwsrc=self.pg1.remote_mac))
2825 self.pg1.add_stream(p)
2826 self.pg_enable_capture(self.pg_interfaces)
2828 self.pg1.assert_nothing_captured()
2830 def test_vrf_mode(self):
2831 """ NAT44 tenant VRF aware address pool mode """
2835 nat_ip1 = "10.0.0.10"
2836 nat_ip2 = "10.0.0.11"
2838 self.pg0.unconfig_ip4()
2839 self.pg1.unconfig_ip4()
2840 self.vapi.ip_table_add_del(vrf_id1, is_add=1)
2841 self.vapi.ip_table_add_del(vrf_id2, is_add=1)
2842 self.pg0.set_table_ip4(vrf_id1)
2843 self.pg1.set_table_ip4(vrf_id2)
2844 self.pg0.config_ip4()
2845 self.pg1.config_ip4()
2846 self.pg0.resolve_arp()
2847 self.pg1.resolve_arp()
2849 self.nat44_add_address(nat_ip1, vrf_id=vrf_id1)
2850 self.nat44_add_address(nat_ip2, vrf_id=vrf_id2)
2851 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
2852 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index)
2853 self.vapi.nat44_interface_add_del_feature(self.pg2.sw_if_index,
2858 pkts = self.create_stream_in(self.pg0, self.pg2)
2859 self.pg0.add_stream(pkts)
2860 self.pg_enable_capture(self.pg_interfaces)
2862 capture = self.pg2.get_capture(len(pkts))
2863 self.verify_capture_out(capture, nat_ip1)
2866 pkts = self.create_stream_in(self.pg1, self.pg2)
2867 self.pg1.add_stream(pkts)
2868 self.pg_enable_capture(self.pg_interfaces)
2870 capture = self.pg2.get_capture(len(pkts))
2871 self.verify_capture_out(capture, nat_ip2)
2874 self.pg0.unconfig_ip4()
2875 self.pg1.unconfig_ip4()
2876 self.pg0.set_table_ip4(0)
2877 self.pg1.set_table_ip4(0)
2878 self.pg0.config_ip4()
2879 self.pg1.config_ip4()
2880 self.pg0.resolve_arp()
2881 self.pg1.resolve_arp()
2882 self.vapi.ip_table_add_del(vrf_id1, is_add=0)
2883 self.vapi.ip_table_add_del(vrf_id2, is_add=0)
2885 def test_vrf_feature_independent(self):
2886 """ NAT44 tenant VRF independent address pool mode """
2888 nat_ip1 = "10.0.0.10"
2889 nat_ip2 = "10.0.0.11"
2891 self.nat44_add_address(nat_ip1)
2892 self.nat44_add_address(nat_ip2, vrf_id=99)
2893 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
2894 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index)
2895 self.vapi.nat44_interface_add_del_feature(self.pg2.sw_if_index,
2899 pkts = self.create_stream_in(self.pg0, self.pg2)
2900 self.pg0.add_stream(pkts)
2901 self.pg_enable_capture(self.pg_interfaces)
2903 capture = self.pg2.get_capture(len(pkts))
2904 self.verify_capture_out(capture, nat_ip1)
2907 pkts = self.create_stream_in(self.pg1, self.pg2)
2908 self.pg1.add_stream(pkts)
2909 self.pg_enable_capture(self.pg_interfaces)
2911 capture = self.pg2.get_capture(len(pkts))
2912 self.verify_capture_out(capture, nat_ip1)
2914 def test_dynamic_ipless_interfaces(self):
2915 """ NAT44 interfaces without configured IP address """
2917 self.vapi.ip_neighbor_add_del(self.pg7.sw_if_index,
2918 mactobinary(self.pg7.remote_mac),
2919 self.pg7.remote_ip4n,
2921 self.vapi.ip_neighbor_add_del(self.pg8.sw_if_index,
2922 mactobinary(self.pg8.remote_mac),
2923 self.pg8.remote_ip4n,
2926 self.vapi.ip_add_del_route(dst_address=self.pg7.remote_ip4n,
2927 dst_address_length=32,
2928 next_hop_address=self.pg7.remote_ip4n,
2929 next_hop_sw_if_index=self.pg7.sw_if_index)
2930 self.vapi.ip_add_del_route(dst_address=self.pg8.remote_ip4n,
2931 dst_address_length=32,
2932 next_hop_address=self.pg8.remote_ip4n,
2933 next_hop_sw_if_index=self.pg8.sw_if_index)
2935 self.nat44_add_address(self.nat_addr)
2936 self.vapi.nat44_interface_add_del_feature(self.pg7.sw_if_index)
2937 self.vapi.nat44_interface_add_del_feature(self.pg8.sw_if_index,
2941 pkts = self.create_stream_in(self.pg7, self.pg8)
2942 self.pg7.add_stream(pkts)
2943 self.pg_enable_capture(self.pg_interfaces)
2945 capture = self.pg8.get_capture(len(pkts))
2946 self.verify_capture_out(capture)
2949 pkts = self.create_stream_out(self.pg8, self.nat_addr)
2950 self.pg8.add_stream(pkts)
2951 self.pg_enable_capture(self.pg_interfaces)
2953 capture = self.pg7.get_capture(len(pkts))
2954 self.verify_capture_in(capture, self.pg7)
2956 def test_static_ipless_interfaces(self):
2957 """ NAT44 interfaces without configured IP address - 1:1 NAT """
2959 self.vapi.ip_neighbor_add_del(self.pg7.sw_if_index,
2960 mactobinary(self.pg7.remote_mac),
2961 self.pg7.remote_ip4n,
2963 self.vapi.ip_neighbor_add_del(self.pg8.sw_if_index,
2964 mactobinary(self.pg8.remote_mac),
2965 self.pg8.remote_ip4n,
2968 self.vapi.ip_add_del_route(dst_address=self.pg7.remote_ip4n,
2969 dst_address_length=32,
2970 next_hop_address=self.pg7.remote_ip4n,
2971 next_hop_sw_if_index=self.pg7.sw_if_index)
2972 self.vapi.ip_add_del_route(dst_address=self.pg8.remote_ip4n,
2973 dst_address_length=32,
2974 next_hop_address=self.pg8.remote_ip4n,
2975 next_hop_sw_if_index=self.pg8.sw_if_index)
2977 self.nat44_add_static_mapping(self.pg7.remote_ip4, self.nat_addr)
2978 self.vapi.nat44_interface_add_del_feature(self.pg7.sw_if_index)
2979 self.vapi.nat44_interface_add_del_feature(self.pg8.sw_if_index,
2983 pkts = self.create_stream_out(self.pg8)
2984 self.pg8.add_stream(pkts)
2985 self.pg_enable_capture(self.pg_interfaces)
2987 capture = self.pg7.get_capture(len(pkts))
2988 self.verify_capture_in(capture, self.pg7)
2991 pkts = self.create_stream_in(self.pg7, self.pg8)
2992 self.pg7.add_stream(pkts)
2993 self.pg_enable_capture(self.pg_interfaces)
2995 capture = self.pg8.get_capture(len(pkts))
2996 self.verify_capture_out(capture, self.nat_addr, True)
2998 def test_static_with_port_ipless_interfaces(self):
2999 """ NAT44 interfaces without configured IP address - 1:1 NAPT """
3001 self.tcp_port_out = 30606
3002 self.udp_port_out = 30607
3003 self.icmp_id_out = 30608
3005 self.vapi.ip_neighbor_add_del(self.pg7.sw_if_index,
3006 mactobinary(self.pg7.remote_mac),
3007 self.pg7.remote_ip4n,
3009 self.vapi.ip_neighbor_add_del(self.pg8.sw_if_index,
3010 mactobinary(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_address(self.nat_addr)
3024 self.nat44_add_static_mapping(self.pg7.remote_ip4, self.nat_addr,
3025 self.tcp_port_in, self.tcp_port_out,
3026 proto=IP_PROTOS.tcp)
3027 self.nat44_add_static_mapping(self.pg7.remote_ip4, self.nat_addr,
3028 self.udp_port_in, self.udp_port_out,
3029 proto=IP_PROTOS.udp)
3030 self.nat44_add_static_mapping(self.pg7.remote_ip4, self.nat_addr,
3031 self.icmp_id_in, self.icmp_id_out,
3032 proto=IP_PROTOS.icmp)
3033 self.vapi.nat44_interface_add_del_feature(self.pg7.sw_if_index)
3034 self.vapi.nat44_interface_add_del_feature(self.pg8.sw_if_index,
3038 pkts = self.create_stream_out(self.pg8)
3039 self.pg8.add_stream(pkts)
3040 self.pg_enable_capture(self.pg_interfaces)
3042 capture = self.pg7.get_capture(len(pkts))
3043 self.verify_capture_in(capture, self.pg7)
3046 pkts = self.create_stream_in(self.pg7, self.pg8)
3047 self.pg7.add_stream(pkts)
3048 self.pg_enable_capture(self.pg_interfaces)
3050 capture = self.pg8.get_capture(len(pkts))
3051 self.verify_capture_out(capture)
3053 def test_static_unknown_proto(self):
3054 """ 1:1 NAT translate packet with unknown protocol """
3055 nat_ip = "10.0.0.10"
3056 self.nat44_add_static_mapping(self.pg0.remote_ip4, nat_ip)
3057 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
3058 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
3062 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
3063 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
3065 IP(src=self.pg2.remote_ip4, dst=self.pg3.remote_ip4) /
3066 TCP(sport=1234, dport=1234))
3067 self.pg0.add_stream(p)
3068 self.pg_enable_capture(self.pg_interfaces)
3070 p = self.pg1.get_capture(1)
3073 self.assertEqual(packet[IP].src, nat_ip)
3074 self.assertEqual(packet[IP].dst, self.pg1.remote_ip4)
3075 self.assertEqual(packet.haslayer(GRE), 1)
3076 self.assert_packet_checksums_valid(packet)
3078 self.logger.error(ppp("Unexpected or invalid packet:", packet))
3082 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
3083 IP(src=self.pg1.remote_ip4, dst=nat_ip) /
3085 IP(src=self.pg3.remote_ip4, dst=self.pg2.remote_ip4) /
3086 TCP(sport=1234, dport=1234))
3087 self.pg1.add_stream(p)
3088 self.pg_enable_capture(self.pg_interfaces)
3090 p = self.pg0.get_capture(1)
3093 self.assertEqual(packet[IP].src, self.pg1.remote_ip4)
3094 self.assertEqual(packet[IP].dst, self.pg0.remote_ip4)
3095 self.assertEqual(packet.haslayer(GRE), 1)
3096 self.assert_packet_checksums_valid(packet)
3098 self.logger.error(ppp("Unexpected or invalid packet:", packet))
3101 def test_hairpinning_static_unknown_proto(self):
3102 """ 1:1 NAT translate packet with unknown protocol - hairpinning """
3104 host = self.pg0.remote_hosts[0]
3105 server = self.pg0.remote_hosts[1]
3107 host_nat_ip = "10.0.0.10"
3108 server_nat_ip = "10.0.0.11"
3110 self.nat44_add_static_mapping(host.ip4, host_nat_ip)
3111 self.nat44_add_static_mapping(server.ip4, server_nat_ip)
3112 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
3113 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
3117 p = (Ether(dst=self.pg0.local_mac, src=host.mac) /
3118 IP(src=host.ip4, dst=server_nat_ip) /
3120 IP(src=self.pg2.remote_ip4, dst=self.pg3.remote_ip4) /
3121 TCP(sport=1234, dport=1234))
3122 self.pg0.add_stream(p)
3123 self.pg_enable_capture(self.pg_interfaces)
3125 p = self.pg0.get_capture(1)
3128 self.assertEqual(packet[IP].src, host_nat_ip)
3129 self.assertEqual(packet[IP].dst, server.ip4)
3130 self.assertEqual(packet.haslayer(GRE), 1)
3131 self.assert_packet_checksums_valid(packet)
3133 self.logger.error(ppp("Unexpected or invalid packet:", packet))
3137 p = (Ether(dst=self.pg0.local_mac, src=server.mac) /
3138 IP(src=server.ip4, dst=host_nat_ip) /
3140 IP(src=self.pg3.remote_ip4, dst=self.pg2.remote_ip4) /
3141 TCP(sport=1234, dport=1234))
3142 self.pg0.add_stream(p)
3143 self.pg_enable_capture(self.pg_interfaces)
3145 p = self.pg0.get_capture(1)
3148 self.assertEqual(packet[IP].src, server_nat_ip)
3149 self.assertEqual(packet[IP].dst, host.ip4)
3150 self.assertEqual(packet.haslayer(GRE), 1)
3151 self.assert_packet_checksums_valid(packet)
3153 self.logger.error(ppp("Unexpected or invalid packet:", packet))
3156 def test_output_feature(self):
3157 """ NAT44 interface output feature (in2out postrouting) """
3158 self.nat44_add_address(self.nat_addr)
3159 self.vapi.nat44_interface_add_del_output_feature(self.pg0.sw_if_index)
3160 self.vapi.nat44_interface_add_del_output_feature(self.pg1.sw_if_index)
3161 self.vapi.nat44_interface_add_del_output_feature(self.pg3.sw_if_index,
3165 pkts = self.create_stream_in(self.pg0, self.pg3)
3166 self.pg0.add_stream(pkts)
3167 self.pg_enable_capture(self.pg_interfaces)
3169 capture = self.pg3.get_capture(len(pkts))
3170 self.verify_capture_out(capture)
3173 pkts = self.create_stream_out(self.pg3)
3174 self.pg3.add_stream(pkts)
3175 self.pg_enable_capture(self.pg_interfaces)
3177 capture = self.pg0.get_capture(len(pkts))
3178 self.verify_capture_in(capture, self.pg0)
3180 # from non-NAT interface to NAT inside interface
3181 pkts = self.create_stream_in(self.pg2, self.pg0)
3182 self.pg2.add_stream(pkts)
3183 self.pg_enable_capture(self.pg_interfaces)
3185 capture = self.pg0.get_capture(len(pkts))
3186 self.verify_capture_no_translation(capture, self.pg2, self.pg0)
3188 def test_output_feature_vrf_aware(self):
3189 """ NAT44 interface output feature VRF aware (in2out postrouting) """
3190 nat_ip_vrf10 = "10.0.0.10"
3191 nat_ip_vrf20 = "10.0.0.20"
3193 self.vapi.ip_add_del_route(dst_address=self.pg3.remote_ip4n,
3194 dst_address_length=32,
3195 next_hop_address=self.pg3.remote_ip4n,
3196 next_hop_sw_if_index=self.pg3.sw_if_index,
3198 self.vapi.ip_add_del_route(dst_address=self.pg3.remote_ip4n,
3199 dst_address_length=32,
3200 next_hop_address=self.pg3.remote_ip4n,
3201 next_hop_sw_if_index=self.pg3.sw_if_index,
3204 self.nat44_add_address(nat_ip_vrf10, vrf_id=10)
3205 self.nat44_add_address(nat_ip_vrf20, vrf_id=20)
3206 self.vapi.nat44_interface_add_del_output_feature(self.pg4.sw_if_index)
3207 self.vapi.nat44_interface_add_del_output_feature(self.pg6.sw_if_index)
3208 self.vapi.nat44_interface_add_del_output_feature(self.pg3.sw_if_index,
3212 pkts = self.create_stream_in(self.pg4, self.pg3)
3213 self.pg4.add_stream(pkts)
3214 self.pg_enable_capture(self.pg_interfaces)
3216 capture = self.pg3.get_capture(len(pkts))
3217 self.verify_capture_out(capture, nat_ip=nat_ip_vrf10)
3220 pkts = self.create_stream_out(self.pg3, dst_ip=nat_ip_vrf10)
3221 self.pg3.add_stream(pkts)
3222 self.pg_enable_capture(self.pg_interfaces)
3224 capture = self.pg4.get_capture(len(pkts))
3225 self.verify_capture_in(capture, self.pg4)
3228 pkts = self.create_stream_in(self.pg6, self.pg3)
3229 self.pg6.add_stream(pkts)
3230 self.pg_enable_capture(self.pg_interfaces)
3232 capture = self.pg3.get_capture(len(pkts))
3233 self.verify_capture_out(capture, nat_ip=nat_ip_vrf20)
3236 pkts = self.create_stream_out(self.pg3, dst_ip=nat_ip_vrf20)
3237 self.pg3.add_stream(pkts)
3238 self.pg_enable_capture(self.pg_interfaces)
3240 capture = self.pg6.get_capture(len(pkts))
3241 self.verify_capture_in(capture, self.pg6)
3243 def test_output_feature_hairpinning(self):
3244 """ NAT44 interface output feature hairpinning (in2out postrouting) """
3245 host = self.pg0.remote_hosts[0]
3246 server = self.pg0.remote_hosts[1]
3249 server_in_port = 5678
3250 server_out_port = 8765
3252 self.nat44_add_address(self.nat_addr)
3253 self.vapi.nat44_interface_add_del_output_feature(self.pg0.sw_if_index)
3254 self.vapi.nat44_interface_add_del_output_feature(self.pg1.sw_if_index,
3257 # add static mapping for server
3258 self.nat44_add_static_mapping(server.ip4, self.nat_addr,
3259 server_in_port, server_out_port,
3260 proto=IP_PROTOS.tcp)
3262 # send packet from host to server
3263 p = (Ether(src=host.mac, dst=self.pg0.local_mac) /
3264 IP(src=host.ip4, dst=self.nat_addr) /
3265 TCP(sport=host_in_port, dport=server_out_port))
3266 self.pg0.add_stream(p)
3267 self.pg_enable_capture(self.pg_interfaces)
3269 capture = self.pg0.get_capture(1)
3274 self.assertEqual(ip.src, self.nat_addr)
3275 self.assertEqual(ip.dst, server.ip4)
3276 self.assertNotEqual(tcp.sport, host_in_port)
3277 self.assertEqual(tcp.dport, server_in_port)
3278 self.assert_packet_checksums_valid(p)
3279 host_out_port = tcp.sport
3281 self.logger.error(ppp("Unexpected or invalid packet:", p))
3284 # send reply from server to host
3285 p = (Ether(src=server.mac, dst=self.pg0.local_mac) /
3286 IP(src=server.ip4, dst=self.nat_addr) /
3287 TCP(sport=server_in_port, dport=host_out_port))
3288 self.pg0.add_stream(p)
3289 self.pg_enable_capture(self.pg_interfaces)
3291 capture = self.pg0.get_capture(1)
3296 self.assertEqual(ip.src, self.nat_addr)
3297 self.assertEqual(ip.dst, host.ip4)
3298 self.assertEqual(tcp.sport, server_out_port)
3299 self.assertEqual(tcp.dport, host_in_port)
3300 self.assert_packet_checksums_valid(p)
3302 self.logger.error(ppp("Unexpected or invalid packet:", p))
3305 def test_one_armed_nat44(self):
3306 """ One armed NAT44 """
3307 remote_host = self.pg9.remote_hosts[0]
3308 local_host = self.pg9.remote_hosts[1]
3311 self.nat44_add_address(self.nat_addr)
3312 self.vapi.nat44_interface_add_del_feature(self.pg9.sw_if_index)
3313 self.vapi.nat44_interface_add_del_feature(self.pg9.sw_if_index,
3317 p = (Ether(src=self.pg9.remote_mac, dst=self.pg9.local_mac) /
3318 IP(src=local_host.ip4, dst=remote_host.ip4) /
3319 TCP(sport=12345, dport=80))
3320 self.pg9.add_stream(p)
3321 self.pg_enable_capture(self.pg_interfaces)
3323 capture = self.pg9.get_capture(1)
3328 self.assertEqual(ip.src, self.nat_addr)
3329 self.assertEqual(ip.dst, remote_host.ip4)
3330 self.assertNotEqual(tcp.sport, 12345)
3331 external_port = tcp.sport
3332 self.assertEqual(tcp.dport, 80)
3333 self.assert_packet_checksums_valid(p)
3335 self.logger.error(ppp("Unexpected or invalid packet:", p))
3339 p = (Ether(src=self.pg9.remote_mac, dst=self.pg9.local_mac) /
3340 IP(src=remote_host.ip4, dst=self.nat_addr) /
3341 TCP(sport=80, dport=external_port))
3342 self.pg9.add_stream(p)
3343 self.pg_enable_capture(self.pg_interfaces)
3345 capture = self.pg9.get_capture(1)
3350 self.assertEqual(ip.src, remote_host.ip4)
3351 self.assertEqual(ip.dst, local_host.ip4)
3352 self.assertEqual(tcp.sport, 80)
3353 self.assertEqual(tcp.dport, 12345)
3354 self.assert_packet_checksums_valid(p)
3356 self.logger.error(ppp("Unexpected or invalid packet:", p))
3359 def test_del_session(self):
3360 """ Delete NAT44 session """
3361 self.nat44_add_address(self.nat_addr)
3362 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
3363 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
3366 pkts = self.create_stream_in(self.pg0, self.pg1)
3367 self.pg0.add_stream(pkts)
3368 self.pg_enable_capture(self.pg_interfaces)
3370 self.pg1.get_capture(len(pkts))
3372 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4n, 0)
3373 nsessions = len(sessions)
3375 self.vapi.nat44_del_session(sessions[0].inside_ip_address,
3376 sessions[0].inside_port,
3377 sessions[0].protocol)
3378 self.vapi.nat44_del_session(sessions[1].outside_ip_address,
3379 sessions[1].outside_port,
3380 sessions[1].protocol,
3383 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4n, 0)
3384 self.assertEqual(nsessions - len(sessions), 2)
3386 self.vapi.nat44_del_session(sessions[0].inside_ip_address,
3387 sessions[0].inside_port,
3388 sessions[0].protocol)
3390 self.verify_no_nat44_user()
3392 def test_set_get_reass(self):
3393 """ NAT44 set/get virtual fragmentation reassembly """
3394 reas_cfg1 = self.vapi.nat_get_reass()
3396 self.vapi.nat_set_reass(timeout=reas_cfg1.ip4_timeout + 5,
3397 max_reass=reas_cfg1.ip4_max_reass * 2,
3398 max_frag=reas_cfg1.ip4_max_frag * 2)
3400 reas_cfg2 = self.vapi.nat_get_reass()
3402 self.assertEqual(reas_cfg1.ip4_timeout + 5, reas_cfg2.ip4_timeout)
3403 self.assertEqual(reas_cfg1.ip4_max_reass * 2, reas_cfg2.ip4_max_reass)
3404 self.assertEqual(reas_cfg1.ip4_max_frag * 2, reas_cfg2.ip4_max_frag)
3406 self.vapi.nat_set_reass(drop_frag=1)
3407 self.assertTrue(self.vapi.nat_get_reass().ip4_drop_frag)
3409 def test_frag_in_order(self):
3410 """ NAT44 translate fragments arriving in order """
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 self.frag_in_order(proto=IP_PROTOS.tcp)
3418 self.frag_in_order(proto=IP_PROTOS.udp)
3419 self.frag_in_order(proto=IP_PROTOS.icmp)
3421 def test_frag_forwarding(self):
3422 """ NAT44 forwarding fragment test """
3423 self.vapi.nat44_add_interface_addr(self.pg1.sw_if_index)
3424 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
3425 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
3427 self.vapi.nat44_forwarding_enable_disable(1)
3429 data = "A" * 16 + "B" * 16 + "C" * 3
3430 pkts = self.create_stream_frag(self.pg1,
3431 self.pg0.remote_ip4,
3435 proto=IP_PROTOS.udp)
3436 self.pg1.add_stream(pkts)
3437 self.pg_enable_capture(self.pg_interfaces)
3439 frags = self.pg0.get_capture(len(pkts))
3440 p = self.reass_frags_and_verify(frags,
3441 self.pg1.remote_ip4,
3442 self.pg0.remote_ip4)
3443 self.assertEqual(p[UDP].sport, 4789)
3444 self.assertEqual(p[UDP].dport, 4789)
3445 self.assertEqual(data, p[Raw].load)
3447 def test_reass_hairpinning(self):
3448 """ NAT44 fragments hairpinning """
3450 self.server = self.pg0.remote_hosts[1]
3451 self.host_in_port = random.randint(1025, 65535)
3452 self.server_in_port = random.randint(1025, 65535)
3453 self.server_out_port = random.randint(1025, 65535)
3455 self.nat44_add_address(self.nat_addr)
3456 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
3457 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
3459 # add static mapping for server
3460 self.nat44_add_static_mapping(self.server.ip4, self.nat_addr,
3461 self.server_in_port,
3462 self.server_out_port,
3463 proto=IP_PROTOS.tcp)
3464 self.nat44_add_static_mapping(self.server.ip4, self.nat_addr,
3465 self.server_in_port,
3466 self.server_out_port,
3467 proto=IP_PROTOS.udp)
3468 self.nat44_add_static_mapping(self.server.ip4, self.nat_addr)
3470 self.reass_hairpinning(proto=IP_PROTOS.tcp)
3471 self.reass_hairpinning(proto=IP_PROTOS.udp)
3472 self.reass_hairpinning(proto=IP_PROTOS.icmp)
3474 def test_frag_out_of_order(self):
3475 """ NAT44 translate fragments arriving out of order """
3477 self.nat44_add_address(self.nat_addr)
3478 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
3479 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
3482 self.frag_out_of_order(proto=IP_PROTOS.tcp)
3483 self.frag_out_of_order(proto=IP_PROTOS.udp)
3484 self.frag_out_of_order(proto=IP_PROTOS.icmp)
3486 def test_port_restricted(self):
3487 """ Port restricted NAT44 (MAP-E CE) """
3488 self.nat44_add_address(self.nat_addr)
3489 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
3490 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
3492 self.vapi.nat_set_addr_and_port_alloc_alg(alg=1,
3497 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
3498 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
3499 TCP(sport=4567, dport=22))
3500 self.pg0.add_stream(p)
3501 self.pg_enable_capture(self.pg_interfaces)
3503 capture = self.pg1.get_capture(1)
3508 self.assertEqual(ip.dst, self.pg1.remote_ip4)
3509 self.assertEqual(ip.src, self.nat_addr)
3510 self.assertEqual(tcp.dport, 22)
3511 self.assertNotEqual(tcp.sport, 4567)
3512 self.assertEqual((tcp.sport >> 6) & 63, 10)
3513 self.assert_packet_checksums_valid(p)
3515 self.logger.error(ppp("Unexpected or invalid packet:", p))
3518 def test_port_range(self):
3519 """ External address port range """
3520 self.nat44_add_address(self.nat_addr)
3521 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
3522 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
3524 self.vapi.nat_set_addr_and_port_alloc_alg(alg=2,
3529 for port in range(0, 5):
3530 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
3531 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
3532 TCP(sport=1125 + port))
3534 self.pg0.add_stream(pkts)
3535 self.pg_enable_capture(self.pg_interfaces)
3537 capture = self.pg1.get_capture(3)
3540 self.assertGreaterEqual(tcp.sport, 1025)
3541 self.assertLessEqual(tcp.sport, 1027)
3543 def test_ipfix_max_frags(self):
3544 """ IPFIX logging maximum fragments pending reassembly exceeded """
3545 self.nat44_add_address(self.nat_addr)
3546 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
3547 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
3549 self.vapi.nat_set_reass(max_frag=1)
3550 self.vapi.set_ipfix_exporter(collector_address=self.pg3.remote_ip4n,
3551 src_address=self.pg3.local_ip4n,
3553 template_interval=10)
3554 self.vapi.nat_ipfix(domain_id=self.ipfix_domain_id,
3555 src_port=self.ipfix_src_port)
3557 data = "A" * 4 + "B" * 16 + "C" * 3
3558 self.tcp_port_in = random.randint(1025, 65535)
3559 pkts = self.create_stream_frag(self.pg0,
3560 self.pg1.remote_ip4,
3565 self.pg0.add_stream(pkts)
3566 self.pg_enable_capture(self.pg_interfaces)
3568 self.pg1.assert_nothing_captured()
3570 self.vapi.cli("ipfix flush") # FIXME this should be an API call
3571 capture = self.pg3.get_capture(9)
3572 ipfix = IPFIXDecoder()
3573 # first load template
3575 self.assertTrue(p.haslayer(IPFIX))
3576 self.assertEqual(p[IP].src, self.pg3.local_ip4)
3577 self.assertEqual(p[IP].dst, self.pg3.remote_ip4)
3578 self.assertEqual(p[UDP].sport, self.ipfix_src_port)
3579 self.assertEqual(p[UDP].dport, 4739)
3580 self.assertEqual(p[IPFIX].observationDomainID,
3581 self.ipfix_domain_id)
3582 if p.haslayer(Template):
3583 ipfix.add_template(p.getlayer(Template))
3584 # verify events in data set
3586 if p.haslayer(Data):
3587 data = ipfix.decode_data_set(p.getlayer(Set))
3588 self.verify_ipfix_max_fragments_ip4(data, 1,
3589 self.pg0.remote_ip4n)
3591 def test_multiple_outside_vrf(self):
3592 """ Multiple outside VRF """
3596 self.pg1.unconfig_ip4()
3597 self.pg2.unconfig_ip4()
3598 self.vapi.ip_table_add_del(vrf_id1, is_add=1)
3599 self.vapi.ip_table_add_del(vrf_id2, is_add=1)
3600 self.pg1.set_table_ip4(vrf_id1)
3601 self.pg2.set_table_ip4(vrf_id2)
3602 self.pg1.config_ip4()
3603 self.pg2.config_ip4()
3604 self.pg1.resolve_arp()
3605 self.pg2.resolve_arp()
3607 self.nat44_add_address(self.nat_addr)
3608 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
3609 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
3611 self.vapi.nat44_interface_add_del_feature(self.pg2.sw_if_index,
3616 pkts = self.create_stream_in(self.pg0, self.pg1)
3617 self.pg0.add_stream(pkts)
3618 self.pg_enable_capture(self.pg_interfaces)
3620 capture = self.pg1.get_capture(len(pkts))
3621 self.verify_capture_out(capture, self.nat_addr)
3623 pkts = self.create_stream_out(self.pg1, self.nat_addr)
3624 self.pg1.add_stream(pkts)
3625 self.pg_enable_capture(self.pg_interfaces)
3627 capture = self.pg0.get_capture(len(pkts))
3628 self.verify_capture_in(capture, self.pg0)
3630 self.tcp_port_in = 60303
3631 self.udp_port_in = 60304
3632 self.icmp_id_in = 60305
3635 pkts = self.create_stream_in(self.pg0, self.pg2)
3636 self.pg0.add_stream(pkts)
3637 self.pg_enable_capture(self.pg_interfaces)
3639 capture = self.pg2.get_capture(len(pkts))
3640 self.verify_capture_out(capture, self.nat_addr)
3642 pkts = self.create_stream_out(self.pg2, self.nat_addr)
3643 self.pg2.add_stream(pkts)
3644 self.pg_enable_capture(self.pg_interfaces)
3646 capture = self.pg0.get_capture(len(pkts))
3647 self.verify_capture_in(capture, self.pg0)
3650 self.pg1.unconfig_ip4()
3651 self.pg2.unconfig_ip4()
3652 self.pg1.set_table_ip4(0)
3653 self.pg2.set_table_ip4(0)
3654 self.pg1.config_ip4()
3655 self.pg2.config_ip4()
3656 self.pg1.resolve_arp()
3657 self.pg2.resolve_arp()
3659 @unittest.skipUnless(running_extended_tests(), "part of extended tests")
3660 def test_session_timeout(self):
3661 """ NAT44 session timeouts """
3662 self.nat44_add_address(self.nat_addr)
3663 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
3664 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
3666 self.vapi.nat_set_timeouts(udp=5)
3670 for i in range(0, max_sessions):
3671 src = "10.10.%u.%u" % ((i & 0xFF00) >> 8, i & 0xFF)
3672 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
3673 IP(src=src, dst=self.pg1.remote_ip4) /
3674 UDP(sport=1025, dport=53))
3676 self.pg0.add_stream(pkts)
3677 self.pg_enable_capture(self.pg_interfaces)
3679 self.pg1.get_capture(max_sessions)
3684 for i in range(0, max_sessions):
3685 src = "10.10.%u.%u" % ((i & 0xFF00) >> 8, i & 0xFF)
3686 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
3687 IP(src=src, dst=self.pg1.remote_ip4) /
3688 UDP(sport=1026, dport=53))
3690 self.pg0.add_stream(pkts)
3691 self.pg_enable_capture(self.pg_interfaces)
3693 self.pg1.get_capture(max_sessions)
3696 users = self.vapi.nat44_user_dump()
3698 nsessions = nsessions + user.nsessions
3699 self.assertLess(nsessions, 2 * max_sessions)
3701 def test_mss_clamping(self):
3702 """ TCP MSS clamping """
3703 self.nat44_add_address(self.nat_addr)
3704 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
3705 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
3708 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
3709 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
3710 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
3711 flags="S", options=[('MSS', 1400)]))
3713 self.vapi.nat_set_mss_clamping(enable=1, mss_value=1000)
3714 self.pg0.add_stream(p)
3715 self.pg_enable_capture(self.pg_interfaces)
3717 capture = self.pg1.get_capture(1)
3718 # Negotiated MSS value greater than configured - changed
3719 self.verify_mss_value(capture[0], 1000)
3721 self.vapi.nat_set_mss_clamping(enable=0)
3722 self.pg0.add_stream(p)
3723 self.pg_enable_capture(self.pg_interfaces)
3725 capture = self.pg1.get_capture(1)
3726 # MSS clamping disabled - negotiated MSS unchanged
3727 self.verify_mss_value(capture[0], 1400)
3729 self.vapi.nat_set_mss_clamping(enable=1, mss_value=1500)
3730 self.pg0.add_stream(p)
3731 self.pg_enable_capture(self.pg_interfaces)
3733 capture = self.pg1.get_capture(1)
3734 # Negotiated MSS value smaller than configured - unchanged
3735 self.verify_mss_value(capture[0], 1400)
3738 super(TestNAT44, self).tearDown()
3739 if not self.vpp_dead:
3740 self.logger.info(self.vapi.cli("show nat44 addresses"))
3741 self.logger.info(self.vapi.cli("show nat44 interfaces"))
3742 self.logger.info(self.vapi.cli("show nat44 static mappings"))
3743 self.logger.info(self.vapi.cli("show nat44 interface address"))
3744 self.logger.info(self.vapi.cli("show nat44 sessions detail"))
3745 self.logger.info(self.vapi.cli("show nat virtual-reassembly"))
3746 self.logger.info(self.vapi.cli("show nat44 hash tables detail"))
3747 self.logger.info(self.vapi.cli("show nat timeouts"))
3749 self.vapi.cli("show nat addr-port-assignment-alg"))
3751 self.vapi.cli("clear logging")
3754 class TestNAT44EndpointDependent(MethodHolder):
3755 """ Endpoint-Dependent mapping and filtering test cases """
3758 def setUpConstants(cls):
3759 super(TestNAT44EndpointDependent, cls).setUpConstants()
3760 cls.vpp_cmdline.extend(["nat", "{", "endpoint-dependent", "}"])
3763 def setUpClass(cls):
3764 super(TestNAT44EndpointDependent, cls).setUpClass()
3765 cls.vapi.cli("set log class nat level debug")
3767 cls.tcp_port_in = 6303
3768 cls.tcp_port_out = 6303
3769 cls.udp_port_in = 6304
3770 cls.udp_port_out = 6304
3771 cls.icmp_id_in = 6305
3772 cls.icmp_id_out = 6305
3773 cls.nat_addr = '10.0.0.3'
3774 cls.nat_addr_n = socket.inet_pton(socket.AF_INET, cls.nat_addr)
3775 cls.ipfix_src_port = 4739
3776 cls.ipfix_domain_id = 1
3777 cls.tcp_external_port = 80
3779 cls.create_pg_interfaces(range(7))
3780 cls.interfaces = list(cls.pg_interfaces[0:3])
3782 for i in cls.interfaces:
3787 cls.pg0.generate_remote_hosts(3)
3788 cls.pg0.configure_ipv4_neighbors()
3792 cls.pg4.generate_remote_hosts(2)
3793 cls.pg4.config_ip4()
3794 ip_addr_n = socket.inet_pton(socket.AF_INET, "10.0.0.1")
3795 cls.vapi.sw_interface_add_del_address(cls.pg4.sw_if_index,
3799 cls.pg4.resolve_arp()
3800 cls.pg4._remote_hosts[1]._ip4 = cls.pg4._remote_hosts[0]._ip4
3801 cls.pg4.resolve_arp()
3803 zero_ip4n = socket.inet_pton(socket.AF_INET, "0.0.0.0")
3804 cls.vapi.ip_table_add_del(1, is_add=1)
3806 cls.pg5._local_ip4 = "10.1.1.1"
3807 cls.pg5._local_ip4n = socket.inet_pton(socket.AF_INET,
3809 cls.pg5._remote_hosts[0]._ip4 = "10.1.1.2"
3810 cls.pg5._remote_hosts[0]._ip4n = socket.inet_pton(
3811 socket.AF_INET, cls.pg5.remote_ip4)
3812 cls.pg5.set_table_ip4(1)
3813 cls.pg5.config_ip4()
3815 cls.vapi.ip_add_del_route(dst_address=cls.pg5.remote_ip4n,
3816 dst_address_length=32,
3818 next_hop_sw_if_index=cls.pg5.sw_if_index,
3819 next_hop_address=zero_ip4n)
3821 cls.pg6._local_ip4 = "10.1.2.1"
3822 cls.pg6._local_ip4n = socket.inet_pton(socket.AF_INET,
3824 cls.pg6._remote_hosts[0]._ip4 = "10.1.2.2"
3825 cls.pg6._remote_hosts[0]._ip4n = socket.inet_pton(
3826 socket.AF_INET, cls.pg6.remote_ip4)
3827 cls.pg6.set_table_ip4(1)
3828 cls.pg6.config_ip4()
3830 cls.vapi.ip_add_del_route(dst_address=cls.pg6.remote_ip4n,
3831 dst_address_length=32,
3833 next_hop_sw_if_index=cls.pg6.sw_if_index,
3834 next_hop_address=zero_ip4n)
3836 cls.vapi.ip_add_del_route(dst_address=cls.pg6.remote_ip4n,
3837 dst_address_length=16,
3838 next_hop_address=zero_ip4n,
3840 next_hop_table_id=1)
3841 cls.vapi.ip_add_del_route(dst_address=zero_ip4n,
3842 dst_address_length=0,
3843 next_hop_address=zero_ip4n,
3845 next_hop_table_id=0)
3846 cls.vapi.ip_add_del_route(dst_address=zero_ip4n,
3847 dst_address_length=0,
3849 next_hop_sw_if_index=cls.pg1.sw_if_index,
3850 next_hop_address=cls.pg1.local_ip4n)
3852 cls.pg5.resolve_arp()
3853 cls.pg6.resolve_arp()
3856 super(TestNAT44EndpointDependent, cls).tearDownClass()
3859 def test_frag_in_order(self):
3860 """ NAT44 translate fragments arriving in order """
3861 self.nat44_add_address(self.nat_addr)
3862 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
3863 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
3865 self.frag_in_order(proto=IP_PROTOS.tcp)
3866 self.frag_in_order(proto=IP_PROTOS.udp)
3867 self.frag_in_order(proto=IP_PROTOS.icmp)
3869 def test_frag_in_order_dont_translate(self):
3870 """ NAT44 don't translate fragments arriving in order """
3871 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
3872 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
3874 self.vapi.nat44_forwarding_enable_disable(enable=True)
3875 self.frag_in_order(proto=IP_PROTOS.tcp, dont_translate=True)
3877 def test_frag_out_of_order(self):
3878 """ NAT44 translate fragments arriving out of order """
3879 self.nat44_add_address(self.nat_addr)
3880 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
3881 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
3883 self.frag_out_of_order(proto=IP_PROTOS.tcp)
3884 self.frag_out_of_order(proto=IP_PROTOS.udp)
3885 self.frag_out_of_order(proto=IP_PROTOS.icmp)
3887 def test_frag_out_of_order_dont_translate(self):
3888 """ NAT44 don't translate fragments arriving out of order """
3889 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
3890 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
3892 self.vapi.nat44_forwarding_enable_disable(enable=True)
3893 self.frag_out_of_order(proto=IP_PROTOS.tcp, dont_translate=True)
3895 def test_frag_in_order_in_plus_out(self):
3896 """ in+out interface fragments in order """
3897 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
3898 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index,
3900 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index)
3901 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
3904 self.server = self.pg1.remote_hosts[0]
3906 self.server_in_addr = self.server.ip4
3907 self.server_out_addr = '11.11.11.11'
3908 self.server_in_port = random.randint(1025, 65535)
3909 self.server_out_port = random.randint(1025, 65535)
3911 self.nat44_add_address(self.server_out_addr)
3913 # add static mappings for server
3914 self.nat44_add_static_mapping(self.server_in_addr,
3915 self.server_out_addr,
3916 self.server_in_port,
3917 self.server_out_port,
3918 proto=IP_PROTOS.tcp)
3919 self.nat44_add_static_mapping(self.server_in_addr,
3920 self.server_out_addr,
3921 self.server_in_port,
3922 self.server_out_port,
3923 proto=IP_PROTOS.udp)
3924 self.nat44_add_static_mapping(self.server_in_addr,
3925 self.server_out_addr,
3926 proto=IP_PROTOS.icmp)
3928 self.vapi.nat_set_reass(timeout=10)
3930 self.frag_in_order_in_plus_out(proto=IP_PROTOS.tcp)
3931 self.frag_in_order_in_plus_out(proto=IP_PROTOS.udp)
3932 self.frag_in_order_in_plus_out(proto=IP_PROTOS.icmp)
3934 def test_frag_out_of_order_in_plus_out(self):
3935 """ in+out interface fragments out of order """
3936 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
3937 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index,
3939 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index)
3940 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
3943 self.server = self.pg1.remote_hosts[0]
3945 self.server_in_addr = self.server.ip4
3946 self.server_out_addr = '11.11.11.11'
3947 self.server_in_port = random.randint(1025, 65535)
3948 self.server_out_port = random.randint(1025, 65535)
3950 self.nat44_add_address(self.server_out_addr)
3952 # add static mappings for server
3953 self.nat44_add_static_mapping(self.server_in_addr,
3954 self.server_out_addr,
3955 self.server_in_port,
3956 self.server_out_port,
3957 proto=IP_PROTOS.tcp)
3958 self.nat44_add_static_mapping(self.server_in_addr,
3959 self.server_out_addr,
3960 self.server_in_port,
3961 self.server_out_port,
3962 proto=IP_PROTOS.udp)
3963 self.nat44_add_static_mapping(self.server_in_addr,
3964 self.server_out_addr,
3965 proto=IP_PROTOS.icmp)
3967 self.vapi.nat_set_reass(timeout=10)
3969 self.frag_out_of_order_in_plus_out(proto=IP_PROTOS.tcp)
3970 self.frag_out_of_order_in_plus_out(proto=IP_PROTOS.udp)
3971 self.frag_out_of_order_in_plus_out(proto=IP_PROTOS.icmp)
3973 def test_reass_hairpinning(self):
3974 """ NAT44 fragments hairpinning """
3975 self.server = self.pg0.remote_hosts[1]
3976 self.host_in_port = random.randint(1025, 65535)
3977 self.server_in_port = random.randint(1025, 65535)
3978 self.server_out_port = random.randint(1025, 65535)
3980 self.nat44_add_address(self.nat_addr)
3981 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
3982 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
3984 # add static mapping for server
3985 self.nat44_add_static_mapping(self.server.ip4, self.nat_addr,
3986 self.server_in_port,
3987 self.server_out_port,
3988 proto=IP_PROTOS.tcp)
3989 self.nat44_add_static_mapping(self.server.ip4, self.nat_addr,
3990 self.server_in_port,
3991 self.server_out_port,
3992 proto=IP_PROTOS.udp)
3993 self.nat44_add_static_mapping(self.server.ip4, self.nat_addr)
3995 self.reass_hairpinning(proto=IP_PROTOS.tcp)
3996 self.reass_hairpinning(proto=IP_PROTOS.udp)
3997 self.reass_hairpinning(proto=IP_PROTOS.icmp)
3999 def test_dynamic(self):
4000 """ NAT44 dynamic translation test """
4002 self.nat44_add_address(self.nat_addr)
4003 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
4004 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
4007 nat_config = self.vapi.nat_show_config()
4008 self.assertEqual(1, nat_config.endpoint_dependent)
4011 pkts = self.create_stream_in(self.pg0, self.pg1)
4012 self.pg0.add_stream(pkts)
4013 self.pg_enable_capture(self.pg_interfaces)
4015 capture = self.pg1.get_capture(len(pkts))
4016 self.verify_capture_out(capture)
4019 pkts = self.create_stream_out(self.pg1)
4020 self.pg1.add_stream(pkts)
4021 self.pg_enable_capture(self.pg_interfaces)
4023 capture = self.pg0.get_capture(len(pkts))
4024 self.verify_capture_in(capture, self.pg0)
4026 def test_forwarding(self):
4027 """ NAT44 forwarding test """
4029 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
4030 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
4032 self.vapi.nat44_forwarding_enable_disable(1)
4034 real_ip = self.pg0.remote_ip4n
4035 alias_ip = self.nat_addr_n
4036 self.vapi.nat44_add_del_static_mapping(local_ip=real_ip,
4037 external_ip=alias_ip)
4040 # in2out - static mapping match
4042 pkts = self.create_stream_out(self.pg1)
4043 self.pg1.add_stream(pkts)
4044 self.pg_enable_capture(self.pg_interfaces)
4046 capture = self.pg0.get_capture(len(pkts))
4047 self.verify_capture_in(capture, self.pg0)
4049 pkts = self.create_stream_in(self.pg0, self.pg1)
4050 self.pg0.add_stream(pkts)
4051 self.pg_enable_capture(self.pg_interfaces)
4053 capture = self.pg1.get_capture(len(pkts))
4054 self.verify_capture_out(capture, same_port=True)
4056 # in2out - no static mapping match
4058 host0 = self.pg0.remote_hosts[0]
4059 self.pg0.remote_hosts[0] = self.pg0.remote_hosts[1]
4061 pkts = self.create_stream_out(self.pg1,
4062 dst_ip=self.pg0.remote_ip4,
4063 use_inside_ports=True)
4064 self.pg1.add_stream(pkts)
4065 self.pg_enable_capture(self.pg_interfaces)
4067 capture = self.pg0.get_capture(len(pkts))
4068 self.verify_capture_in(capture, self.pg0)
4070 pkts = self.create_stream_in(self.pg0, self.pg1)
4071 self.pg0.add_stream(pkts)
4072 self.pg_enable_capture(self.pg_interfaces)
4074 capture = self.pg1.get_capture(len(pkts))
4075 self.verify_capture_out(capture, nat_ip=self.pg0.remote_ip4,
4078 self.pg0.remote_hosts[0] = host0
4080 user = self.pg0.remote_hosts[1]
4081 sessions = self.vapi.nat44_user_session_dump(user.ip4n, 0)
4082 self.assertEqual(len(sessions), 3)
4083 self.assertTrue(sessions[0].ext_host_valid)
4084 self.vapi.nat44_del_session(
4085 sessions[0].inside_ip_address,
4086 sessions[0].inside_port,
4087 sessions[0].protocol,
4088 ext_host_address=sessions[0].ext_host_address,
4089 ext_host_port=sessions[0].ext_host_port)
4090 sessions = self.vapi.nat44_user_session_dump(user.ip4n, 0)
4091 self.assertEqual(len(sessions), 2)
4094 self.vapi.nat44_forwarding_enable_disable(0)
4095 self.vapi.nat44_add_del_static_mapping(local_ip=real_ip,
4096 external_ip=alias_ip,
4099 def test_static_lb(self):
4100 """ NAT44 local service load balancing """
4101 external_addr_n = socket.inet_pton(socket.AF_INET, self.nat_addr)
4104 server1 = self.pg0.remote_hosts[0]
4105 server2 = self.pg0.remote_hosts[1]
4107 locals = [{'addr': server1.ip4n,
4111 {'addr': server2.ip4n,
4116 self.nat44_add_address(self.nat_addr)
4117 self.vapi.nat44_add_del_lb_static_mapping(external_addr_n,
4120 local_num=len(locals),
4122 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
4123 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
4126 # from client to service
4127 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
4128 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
4129 TCP(sport=12345, dport=external_port))
4130 self.pg1.add_stream(p)
4131 self.pg_enable_capture(self.pg_interfaces)
4133 capture = self.pg0.get_capture(1)
4139 self.assertIn(ip.dst, [server1.ip4, server2.ip4])
4140 if ip.dst == server1.ip4:
4144 self.assertEqual(tcp.dport, local_port)
4145 self.assert_packet_checksums_valid(p)
4147 self.logger.error(ppp("Unexpected or invalid packet:", p))
4150 # from service back to client
4151 p = (Ether(src=server.mac, dst=self.pg0.local_mac) /
4152 IP(src=server.ip4, dst=self.pg1.remote_ip4) /
4153 TCP(sport=local_port, dport=12345))
4154 self.pg0.add_stream(p)
4155 self.pg_enable_capture(self.pg_interfaces)
4157 capture = self.pg1.get_capture(1)
4162 self.assertEqual(ip.src, self.nat_addr)
4163 self.assertEqual(tcp.sport, external_port)
4164 self.assert_packet_checksums_valid(p)
4166 self.logger.error(ppp("Unexpected or invalid packet:", p))
4169 sessions = self.vapi.nat44_user_session_dump(server.ip4n, 0)
4170 self.assertEqual(len(sessions), 1)
4171 self.assertTrue(sessions[0].ext_host_valid)
4172 self.vapi.nat44_del_session(
4173 sessions[0].inside_ip_address,
4174 sessions[0].inside_port,
4175 sessions[0].protocol,
4176 ext_host_address=sessions[0].ext_host_address,
4177 ext_host_port=sessions[0].ext_host_port)
4178 sessions = self.vapi.nat44_user_session_dump(server.ip4n, 0)
4179 self.assertEqual(len(sessions), 0)
4181 @unittest.skipUnless(running_extended_tests(), "part of extended tests")
4182 def test_static_lb_multi_clients(self):
4183 """ NAT44 local service load balancing - multiple clients"""
4185 external_addr_n = socket.inet_pton(socket.AF_INET, self.nat_addr)
4188 server1 = self.pg0.remote_hosts[0]
4189 server2 = self.pg0.remote_hosts[1]
4191 locals = [{'addr': server1.ip4n,
4195 {'addr': server2.ip4n,
4200 self.nat44_add_address(self.nat_addr)
4201 self.vapi.nat44_add_del_lb_static_mapping(external_addr_n,
4204 local_num=len(locals),
4206 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
4207 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
4212 clients = ip4_range(self.pg1.remote_ip4, 10, 50)
4214 for client in clients:
4215 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
4216 IP(src=client, dst=self.nat_addr) /
4217 TCP(sport=12345, dport=external_port))
4219 self.pg1.add_stream(pkts)
4220 self.pg_enable_capture(self.pg_interfaces)
4222 capture = self.pg0.get_capture(len(pkts))
4224 if p[IP].dst == server1.ip4:
4228 self.assertGreater(server1_n, server2_n)
4230 def test_static_lb_2(self):
4231 """ NAT44 local service load balancing (asymmetrical rule) """
4232 external_addr_n = socket.inet_pton(socket.AF_INET, self.nat_addr)
4235 server1 = self.pg0.remote_hosts[0]
4236 server2 = self.pg0.remote_hosts[1]
4238 locals = [{'addr': server1.ip4n,
4242 {'addr': server2.ip4n,
4247 self.vapi.nat44_forwarding_enable_disable(1)
4248 self.vapi.nat44_add_del_lb_static_mapping(external_addr_n,
4252 local_num=len(locals),
4254 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
4255 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
4258 # from client to service
4259 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
4260 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
4261 TCP(sport=12345, dport=external_port))
4262 self.pg1.add_stream(p)
4263 self.pg_enable_capture(self.pg_interfaces)
4265 capture = self.pg0.get_capture(1)
4271 self.assertIn(ip.dst, [server1.ip4, server2.ip4])
4272 if ip.dst == server1.ip4:
4276 self.assertEqual(tcp.dport, local_port)
4277 self.assert_packet_checksums_valid(p)
4279 self.logger.error(ppp("Unexpected or invalid packet:", p))
4282 # from service back to client
4283 p = (Ether(src=server.mac, dst=self.pg0.local_mac) /
4284 IP(src=server.ip4, dst=self.pg1.remote_ip4) /
4285 TCP(sport=local_port, dport=12345))
4286 self.pg0.add_stream(p)
4287 self.pg_enable_capture(self.pg_interfaces)
4289 capture = self.pg1.get_capture(1)
4294 self.assertEqual(ip.src, self.nat_addr)
4295 self.assertEqual(tcp.sport, external_port)
4296 self.assert_packet_checksums_valid(p)
4298 self.logger.error(ppp("Unexpected or invalid packet:", p))
4301 # from client to server (no translation)
4302 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
4303 IP(src=self.pg1.remote_ip4, dst=server1.ip4) /
4304 TCP(sport=12346, dport=local_port))
4305 self.pg1.add_stream(p)
4306 self.pg_enable_capture(self.pg_interfaces)
4308 capture = self.pg0.get_capture(1)
4314 self.assertEqual(ip.dst, server1.ip4)
4315 self.assertEqual(tcp.dport, local_port)
4316 self.assert_packet_checksums_valid(p)
4318 self.logger.error(ppp("Unexpected or invalid packet:", p))
4321 # from service back to client (no translation)
4322 p = (Ether(src=server1.mac, dst=self.pg0.local_mac) /
4323 IP(src=server1.ip4, dst=self.pg1.remote_ip4) /
4324 TCP(sport=local_port, dport=12346))
4325 self.pg0.add_stream(p)
4326 self.pg_enable_capture(self.pg_interfaces)
4328 capture = self.pg1.get_capture(1)
4333 self.assertEqual(ip.src, server1.ip4)
4334 self.assertEqual(tcp.sport, local_port)
4335 self.assert_packet_checksums_valid(p)
4337 self.logger.error(ppp("Unexpected or invalid packet:", p))
4340 def test_lb_affinity(self):
4341 """ NAT44 local service load balancing affinity """
4342 external_addr_n = socket.inet_pton(socket.AF_INET, self.nat_addr)
4345 server1 = self.pg0.remote_hosts[0]
4346 server2 = self.pg0.remote_hosts[1]
4348 locals = [{'addr': server1.ip4n,
4352 {'addr': server2.ip4n,
4357 self.nat44_add_address(self.nat_addr)
4358 self.vapi.nat44_add_del_lb_static_mapping(external_addr_n,
4362 local_num=len(locals),
4364 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
4365 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
4368 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
4369 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
4370 TCP(sport=1025, dport=external_port))
4371 self.pg1.add_stream(p)
4372 self.pg_enable_capture(self.pg_interfaces)
4374 capture = self.pg0.get_capture(1)
4375 backend = capture[0][IP].dst
4377 sessions = self.vapi.nat44_user_session_dump(
4378 socket.inet_pton(socket.AF_INET, backend), 0)
4379 self.assertEqual(len(sessions), 1)
4380 self.assertTrue(sessions[0].ext_host_valid)
4381 self.vapi.nat44_del_session(
4382 sessions[0].inside_ip_address,
4383 sessions[0].inside_port,
4384 sessions[0].protocol,
4385 ext_host_address=sessions[0].ext_host_address,
4386 ext_host_port=sessions[0].ext_host_port)
4389 for port in range(1030, 1100):
4390 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
4391 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
4392 TCP(sport=port, dport=external_port))
4394 self.pg1.add_stream(pkts)
4395 self.pg_enable_capture(self.pg_interfaces)
4397 capture = self.pg0.get_capture(len(pkts))
4399 self.assertEqual(p[IP].dst, backend)
4401 def test_unknown_proto(self):
4402 """ NAT44 translate packet with unknown protocol """
4403 self.nat44_add_address(self.nat_addr)
4404 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
4405 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
4409 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
4410 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
4411 TCP(sport=self.tcp_port_in, dport=20))
4412 self.pg0.add_stream(p)
4413 self.pg_enable_capture(self.pg_interfaces)
4415 p = self.pg1.get_capture(1)
4417 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
4418 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
4420 IP(src=self.pg2.remote_ip4, dst=self.pg2.remote_ip4) /
4421 TCP(sport=1234, dport=1234))
4422 self.pg0.add_stream(p)
4423 self.pg_enable_capture(self.pg_interfaces)
4425 p = self.pg1.get_capture(1)
4428 self.assertEqual(packet[IP].src, self.nat_addr)
4429 self.assertEqual(packet[IP].dst, self.pg1.remote_ip4)
4430 self.assertEqual(packet.haslayer(GRE), 1)
4431 self.assert_packet_checksums_valid(packet)
4433 self.logger.error(ppp("Unexpected or invalid packet:", packet))
4437 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
4438 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
4440 IP(src=self.pg2.remote_ip4, dst=self.pg2.remote_ip4) /
4441 TCP(sport=1234, dport=1234))
4442 self.pg1.add_stream(p)
4443 self.pg_enable_capture(self.pg_interfaces)
4445 p = self.pg0.get_capture(1)
4448 self.assertEqual(packet[IP].src, self.pg1.remote_ip4)
4449 self.assertEqual(packet[IP].dst, self.pg0.remote_ip4)
4450 self.assertEqual(packet.haslayer(GRE), 1)
4451 self.assert_packet_checksums_valid(packet)
4453 self.logger.error(ppp("Unexpected or invalid packet:", packet))
4456 def test_hairpinning_unknown_proto(self):
4457 """ NAT44 translate packet with unknown protocol - hairpinning """
4458 host = self.pg0.remote_hosts[0]
4459 server = self.pg0.remote_hosts[1]
4461 server_out_port = 8765
4462 server_nat_ip = "10.0.0.11"
4464 self.nat44_add_address(self.nat_addr)
4465 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
4466 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
4469 # add static mapping for server
4470 self.nat44_add_static_mapping(server.ip4, server_nat_ip)
4473 p = (Ether(src=host.mac, dst=self.pg0.local_mac) /
4474 IP(src=host.ip4, dst=server_nat_ip) /
4475 TCP(sport=host_in_port, dport=server_out_port))
4476 self.pg0.add_stream(p)
4477 self.pg_enable_capture(self.pg_interfaces)
4479 self.pg0.get_capture(1)
4481 p = (Ether(dst=self.pg0.local_mac, src=host.mac) /
4482 IP(src=host.ip4, dst=server_nat_ip) /
4484 IP(src=self.pg2.remote_ip4, dst=self.pg2.remote_ip4) /
4485 TCP(sport=1234, dport=1234))
4486 self.pg0.add_stream(p)
4487 self.pg_enable_capture(self.pg_interfaces)
4489 p = self.pg0.get_capture(1)
4492 self.assertEqual(packet[IP].src, self.nat_addr)
4493 self.assertEqual(packet[IP].dst, server.ip4)
4494 self.assertEqual(packet.haslayer(GRE), 1)
4495 self.assert_packet_checksums_valid(packet)
4497 self.logger.error(ppp("Unexpected or invalid packet:", packet))
4501 p = (Ether(dst=self.pg0.local_mac, src=server.mac) /
4502 IP(src=server.ip4, dst=self.nat_addr) /
4504 IP(src=self.pg2.remote_ip4, dst=self.pg2.remote_ip4) /
4505 TCP(sport=1234, dport=1234))
4506 self.pg0.add_stream(p)
4507 self.pg_enable_capture(self.pg_interfaces)
4509 p = self.pg0.get_capture(1)
4512 self.assertEqual(packet[IP].src, server_nat_ip)
4513 self.assertEqual(packet[IP].dst, host.ip4)
4514 self.assertEqual(packet.haslayer(GRE), 1)
4515 self.assert_packet_checksums_valid(packet)
4517 self.logger.error(ppp("Unexpected or invalid packet:", packet))
4520 def test_output_feature_and_service(self):
4521 """ NAT44 interface output feature and services """
4522 external_addr = '1.2.3.4'
4526 self.vapi.nat44_forwarding_enable_disable(1)
4527 self.nat44_add_address(self.nat_addr)
4528 self.vapi.nat44_add_del_identity_mapping(ip=self.pg1.remote_ip4n)
4529 self.nat44_add_static_mapping(self.pg0.remote_ip4, external_addr,
4530 local_port, external_port,
4531 proto=IP_PROTOS.tcp, out2in_only=1)
4532 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
4533 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index,
4535 self.vapi.nat44_interface_add_del_output_feature(self.pg1.sw_if_index,
4538 # from client to service
4539 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
4540 IP(src=self.pg1.remote_ip4, dst=external_addr) /
4541 TCP(sport=12345, dport=external_port))
4542 self.pg1.add_stream(p)
4543 self.pg_enable_capture(self.pg_interfaces)
4545 capture = self.pg0.get_capture(1)
4550 self.assertEqual(ip.dst, self.pg0.remote_ip4)
4551 self.assertEqual(tcp.dport, local_port)
4552 self.assert_packet_checksums_valid(p)
4554 self.logger.error(ppp("Unexpected or invalid packet:", p))
4557 # from service back to client
4558 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
4559 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
4560 TCP(sport=local_port, dport=12345))
4561 self.pg0.add_stream(p)
4562 self.pg_enable_capture(self.pg_interfaces)
4564 capture = self.pg1.get_capture(1)
4569 self.assertEqual(ip.src, external_addr)
4570 self.assertEqual(tcp.sport, external_port)
4571 self.assert_packet_checksums_valid(p)
4573 self.logger.error(ppp("Unexpected or invalid packet:", p))
4576 # from local network host to external network
4577 pkts = self.create_stream_in(self.pg0, self.pg1)
4578 self.pg0.add_stream(pkts)
4579 self.pg_enable_capture(self.pg_interfaces)
4581 capture = self.pg1.get_capture(len(pkts))
4582 self.verify_capture_out(capture)
4583 pkts = self.create_stream_in(self.pg0, self.pg1)
4584 self.pg0.add_stream(pkts)
4585 self.pg_enable_capture(self.pg_interfaces)
4587 capture = self.pg1.get_capture(len(pkts))
4588 self.verify_capture_out(capture)
4590 # from external network back to local network host
4591 pkts = self.create_stream_out(self.pg1)
4592 self.pg1.add_stream(pkts)
4593 self.pg_enable_capture(self.pg_interfaces)
4595 capture = self.pg0.get_capture(len(pkts))
4596 self.verify_capture_in(capture, self.pg0)
4598 def test_output_feature_and_service2(self):
4599 """ NAT44 interface output feature and service host direct access """
4600 self.vapi.nat44_forwarding_enable_disable(1)
4601 self.nat44_add_address(self.nat_addr)
4602 self.vapi.nat44_interface_add_del_output_feature(self.pg1.sw_if_index,
4605 # session initiaded from service host - translate
4606 pkts = self.create_stream_in(self.pg0, self.pg1)
4607 self.pg0.add_stream(pkts)
4608 self.pg_enable_capture(self.pg_interfaces)
4610 capture = self.pg1.get_capture(len(pkts))
4611 self.verify_capture_out(capture)
4613 pkts = self.create_stream_out(self.pg1)
4614 self.pg1.add_stream(pkts)
4615 self.pg_enable_capture(self.pg_interfaces)
4617 capture = self.pg0.get_capture(len(pkts))
4618 self.verify_capture_in(capture, self.pg0)
4620 # session initiaded from remote host - do not translate
4621 self.tcp_port_in = 60303
4622 self.udp_port_in = 60304
4623 self.icmp_id_in = 60305
4624 pkts = self.create_stream_out(self.pg1,
4625 self.pg0.remote_ip4,
4626 use_inside_ports=True)
4627 self.pg1.add_stream(pkts)
4628 self.pg_enable_capture(self.pg_interfaces)
4630 capture = self.pg0.get_capture(len(pkts))
4631 self.verify_capture_in(capture, self.pg0)
4633 pkts = self.create_stream_in(self.pg0, self.pg1)
4634 self.pg0.add_stream(pkts)
4635 self.pg_enable_capture(self.pg_interfaces)
4637 capture = self.pg1.get_capture(len(pkts))
4638 self.verify_capture_out(capture, nat_ip=self.pg0.remote_ip4,
4641 def test_output_feature_and_service3(self):
4642 """ NAT44 interface output feature and DST NAT """
4643 external_addr = '1.2.3.4'
4647 self.vapi.nat44_forwarding_enable_disable(1)
4648 self.nat44_add_address(self.nat_addr)
4649 self.nat44_add_static_mapping(self.pg1.remote_ip4, external_addr,
4650 local_port, external_port,
4651 proto=IP_PROTOS.tcp, out2in_only=1)
4652 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
4653 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index,
4655 self.vapi.nat44_interface_add_del_output_feature(self.pg1.sw_if_index,
4658 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
4659 IP(src=self.pg0.remote_ip4, dst=external_addr) /
4660 TCP(sport=12345, dport=external_port))
4661 self.pg0.add_stream(p)
4662 self.pg_enable_capture(self.pg_interfaces)
4664 capture = self.pg1.get_capture(1)
4669 self.assertEqual(ip.src, self.pg0.remote_ip4)
4670 self.assertEqual(tcp.sport, 12345)
4671 self.assertEqual(ip.dst, self.pg1.remote_ip4)
4672 self.assertEqual(tcp.dport, local_port)
4673 self.assert_packet_checksums_valid(p)
4675 self.logger.error(ppp("Unexpected or invalid packet:", p))
4678 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
4679 IP(src=self.pg1.remote_ip4, dst=self.pg0.remote_ip4) /
4680 TCP(sport=local_port, dport=12345))
4681 self.pg1.add_stream(p)
4682 self.pg_enable_capture(self.pg_interfaces)
4684 capture = self.pg0.get_capture(1)
4689 self.assertEqual(ip.src, external_addr)
4690 self.assertEqual(tcp.sport, external_port)
4691 self.assertEqual(ip.dst, self.pg0.remote_ip4)
4692 self.assertEqual(tcp.dport, 12345)
4693 self.assert_packet_checksums_valid(p)
4695 self.logger.error(ppp("Unexpected or invalid packet:", p))
4698 def test_next_src_nat(self):
4699 """ On way back forward packet to nat44-in2out node. """
4700 twice_nat_addr = '10.0.1.3'
4703 post_twice_nat_port = 0
4705 self.vapi.nat44_forwarding_enable_disable(1)
4706 self.nat44_add_address(twice_nat_addr, twice_nat=1)
4707 self.nat44_add_static_mapping(self.pg6.remote_ip4, self.pg1.remote_ip4,
4708 local_port, external_port,
4709 proto=IP_PROTOS.tcp, out2in_only=1,
4710 self_twice_nat=1, vrf_id=1)
4711 self.vapi.nat44_interface_add_del_feature(self.pg6.sw_if_index,
4714 p = (Ether(src=self.pg6.remote_mac, dst=self.pg6.local_mac) /
4715 IP(src=self.pg6.remote_ip4, dst=self.pg1.remote_ip4) /
4716 TCP(sport=12345, dport=external_port))
4717 self.pg6.add_stream(p)
4718 self.pg_enable_capture(self.pg_interfaces)
4720 capture = self.pg6.get_capture(1)
4725 self.assertEqual(ip.src, twice_nat_addr)
4726 self.assertNotEqual(tcp.sport, 12345)
4727 post_twice_nat_port = tcp.sport
4728 self.assertEqual(ip.dst, self.pg6.remote_ip4)
4729 self.assertEqual(tcp.dport, local_port)
4730 self.assert_packet_checksums_valid(p)
4732 self.logger.error(ppp("Unexpected or invalid packet:", p))
4735 p = (Ether(src=self.pg6.remote_mac, dst=self.pg6.local_mac) /
4736 IP(src=self.pg6.remote_ip4, dst=twice_nat_addr) /
4737 TCP(sport=local_port, dport=post_twice_nat_port))
4738 self.pg6.add_stream(p)
4739 self.pg_enable_capture(self.pg_interfaces)
4741 capture = self.pg6.get_capture(1)
4746 self.assertEqual(ip.src, self.pg1.remote_ip4)
4747 self.assertEqual(tcp.sport, external_port)
4748 self.assertEqual(ip.dst, self.pg6.remote_ip4)
4749 self.assertEqual(tcp.dport, 12345)
4750 self.assert_packet_checksums_valid(p)
4752 self.logger.error(ppp("Unexpected or invalid packet:", p))
4755 def twice_nat_common(self, self_twice_nat=False, same_pg=False, lb=False,
4757 twice_nat_addr = '10.0.1.3'
4765 port_in1 = port_in+1
4766 port_in2 = port_in+2
4771 server1 = self.pg0.remote_hosts[0]
4772 server2 = self.pg0.remote_hosts[1]
4784 eh_translate = ((not self_twice_nat) or (not lb and same_pg) or
4787 self.nat44_add_address(self.nat_addr)
4788 self.nat44_add_address(twice_nat_addr, twice_nat=1)
4790 self.nat44_add_static_mapping(pg0.remote_ip4, self.nat_addr,
4792 proto=IP_PROTOS.tcp,
4793 twice_nat=int(not self_twice_nat),
4794 self_twice_nat=int(self_twice_nat))
4796 locals = [{'addr': server1.ip4n,
4800 {'addr': server2.ip4n,
4804 out_addr_n = socket.inet_pton(socket.AF_INET, self.nat_addr)
4805 self.vapi.nat44_add_del_lb_static_mapping(out_addr_n,
4809 not self_twice_nat),
4812 local_num=len(locals),
4814 self.vapi.nat44_interface_add_del_feature(pg0.sw_if_index)
4815 self.vapi.nat44_interface_add_del_feature(pg1.sw_if_index,
4822 assert client_id is not None
4824 client = self.pg0.remote_hosts[0]
4825 elif client_id == 2:
4826 client = self.pg0.remote_hosts[1]
4828 client = pg1.remote_hosts[0]
4829 p = (Ether(src=pg1.remote_mac, dst=pg1.local_mac) /
4830 IP(src=client.ip4, dst=self.nat_addr) /
4831 TCP(sport=eh_port_out, dport=port_out))
4833 self.pg_enable_capture(self.pg_interfaces)
4835 capture = pg0.get_capture(1)
4841 if ip.dst == server1.ip4:
4847 self.assertEqual(ip.dst, server.ip4)
4849 self.assertIn(tcp.dport, [port_in1, port_in2])
4851 self.assertEqual(tcp.dport, port_in)
4853 self.assertEqual(ip.src, twice_nat_addr)
4854 self.assertNotEqual(tcp.sport, eh_port_out)
4856 self.assertEqual(ip.src, client.ip4)
4857 self.assertEqual(tcp.sport, eh_port_out)
4859 eh_port_in = tcp.sport
4860 saved_port_in = tcp.dport
4861 self.assert_packet_checksums_valid(p)
4863 self.logger.error(ppp("Unexpected or invalid packet:", p))
4866 p = (Ether(src=server.mac, dst=pg0.local_mac) /
4867 IP(src=server.ip4, dst=eh_addr_in) /
4868 TCP(sport=saved_port_in, dport=eh_port_in))
4870 self.pg_enable_capture(self.pg_interfaces)
4872 capture = pg1.get_capture(1)
4877 self.assertEqual(ip.dst, client.ip4)
4878 self.assertEqual(ip.src, self.nat_addr)
4879 self.assertEqual(tcp.dport, eh_port_out)
4880 self.assertEqual(tcp.sport, port_out)
4881 self.assert_packet_checksums_valid(p)
4883 self.logger.error(ppp("Unexpected or invalid packet:", p))
4887 sessions = self.vapi.nat44_user_session_dump(server.ip4n, 0)
4888 self.assertEqual(len(sessions), 1)
4889 self.assertTrue(sessions[0].ext_host_valid)
4890 self.assertTrue(sessions[0].is_twicenat)
4891 self.vapi.nat44_del_session(
4892 sessions[0].inside_ip_address,
4893 sessions[0].inside_port,
4894 sessions[0].protocol,
4895 ext_host_address=sessions[0].ext_host_nat_address,
4896 ext_host_port=sessions[0].ext_host_nat_port)
4897 sessions = self.vapi.nat44_user_session_dump(server.ip4n, 0)
4898 self.assertEqual(len(sessions), 0)
4900 def test_twice_nat(self):
4902 self.twice_nat_common()
4904 def test_self_twice_nat_positive(self):
4905 """ Self Twice NAT44 (positive test) """
4906 self.twice_nat_common(self_twice_nat=True, same_pg=True)
4908 def test_self_twice_nat_negative(self):
4909 """ Self Twice NAT44 (negative test) """
4910 self.twice_nat_common(self_twice_nat=True)
4912 def test_twice_nat_lb(self):
4913 """ Twice NAT44 local service load balancing """
4914 self.twice_nat_common(lb=True)
4916 def test_self_twice_nat_lb_positive(self):
4917 """ Self Twice NAT44 local service load balancing (positive test) """
4918 self.twice_nat_common(lb=True, self_twice_nat=True, same_pg=True,
4921 def test_self_twice_nat_lb_negative(self):
4922 """ Self Twice NAT44 local service load balancing (negative test) """
4923 self.twice_nat_common(lb=True, self_twice_nat=True, same_pg=True,
4926 def test_twice_nat_interface_addr(self):
4927 """ Acquire twice NAT44 addresses from interface """
4928 self.vapi.nat44_add_interface_addr(self.pg3.sw_if_index, twice_nat=1)
4930 # no address in NAT pool
4931 adresses = self.vapi.nat44_address_dump()
4932 self.assertEqual(0, len(adresses))
4934 # configure interface address and check NAT address pool
4935 self.pg3.config_ip4()
4936 adresses = self.vapi.nat44_address_dump()
4937 self.assertEqual(1, len(adresses))
4938 self.assertEqual(adresses[0].ip_address[0:4], self.pg3.local_ip4n)
4939 self.assertEqual(adresses[0].twice_nat, 1)
4941 # remove interface address and check NAT address pool
4942 self.pg3.unconfig_ip4()
4943 adresses = self.vapi.nat44_address_dump()
4944 self.assertEqual(0, len(adresses))
4946 def test_tcp_close(self):
4947 """ Close TCP session from inside network - output feature """
4948 self.vapi.nat44_forwarding_enable_disable(1)
4949 self.nat44_add_address(self.pg1.local_ip4)
4950 twice_nat_addr = '10.0.1.3'
4951 service_ip = '192.168.16.150'
4952 self.nat44_add_address(twice_nat_addr, twice_nat=1)
4953 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
4954 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index,
4956 self.vapi.nat44_interface_add_del_output_feature(self.pg1.sw_if_index,
4958 self.nat44_add_static_mapping(self.pg0.remote_ip4,
4962 proto=IP_PROTOS.tcp,
4965 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4n, 0)
4966 start_sessnum = len(sessions)
4968 # SYN packet out->in
4969 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
4970 IP(src=self.pg1.remote_ip4, dst=service_ip) /
4971 TCP(sport=33898, dport=80, flags="S"))
4972 self.pg1.add_stream(p)
4973 self.pg_enable_capture(self.pg_interfaces)
4975 capture = self.pg0.get_capture(1)
4977 tcp_port = p[TCP].sport
4979 # SYN + ACK packet in->out
4980 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
4981 IP(src=self.pg0.remote_ip4, dst=twice_nat_addr) /
4982 TCP(sport=80, dport=tcp_port, flags="SA"))
4983 self.pg0.add_stream(p)
4984 self.pg_enable_capture(self.pg_interfaces)
4986 self.pg1.get_capture(1)
4988 # ACK packet out->in
4989 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
4990 IP(src=self.pg1.remote_ip4, dst=service_ip) /
4991 TCP(sport=33898, dport=80, flags="A"))
4992 self.pg1.add_stream(p)
4993 self.pg_enable_capture(self.pg_interfaces)
4995 self.pg0.get_capture(1)
4997 # FIN packet in -> out
4998 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
4999 IP(src=self.pg0.remote_ip4, dst=twice_nat_addr) /
5000 TCP(sport=80, dport=tcp_port, flags="FA", seq=100, ack=300))
5001 self.pg0.add_stream(p)
5002 self.pg_enable_capture(self.pg_interfaces)
5004 self.pg1.get_capture(1)
5006 # FIN+ACK packet out -> in
5007 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
5008 IP(src=self.pg1.remote_ip4, dst=service_ip) /
5009 TCP(sport=33898, dport=80, flags="FA", seq=300, ack=101))
5010 self.pg1.add_stream(p)
5011 self.pg_enable_capture(self.pg_interfaces)
5013 self.pg0.get_capture(1)
5015 # ACK packet in -> out
5016 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5017 IP(src=self.pg0.remote_ip4, dst=twice_nat_addr) /
5018 TCP(sport=80, dport=tcp_port, flags="A", seq=101, ack=301))
5019 self.pg0.add_stream(p)
5020 self.pg_enable_capture(self.pg_interfaces)
5022 self.pg1.get_capture(1)
5024 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4n,
5026 self.assertEqual(len(sessions) - start_sessnum, 0)
5028 def test_tcp_session_close_in(self):
5029 """ Close TCP session from inside network """
5030 self.tcp_port_out = 10505
5031 self.nat44_add_address(self.nat_addr)
5032 self.nat44_add_static_mapping(self.pg0.remote_ip4,
5036 proto=IP_PROTOS.tcp,
5038 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
5039 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
5042 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4n, 0)
5043 start_sessnum = len(sessions)
5045 self.initiate_tcp_session(self.pg0, self.pg1)
5047 # FIN packet in -> out
5048 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5049 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
5050 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
5051 flags="FA", seq=100, ack=300))
5052 self.pg0.add_stream(p)
5053 self.pg_enable_capture(self.pg_interfaces)
5055 self.pg1.get_capture(1)
5059 # ACK packet out -> in
5060 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
5061 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
5062 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
5063 flags="A", seq=300, ack=101))
5066 # FIN packet out -> in
5067 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
5068 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
5069 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
5070 flags="FA", seq=300, ack=101))
5073 self.pg1.add_stream(pkts)
5074 self.pg_enable_capture(self.pg_interfaces)
5076 self.pg0.get_capture(2)
5078 # ACK packet in -> out
5079 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5080 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
5081 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
5082 flags="A", seq=101, ack=301))
5083 self.pg0.add_stream(p)
5084 self.pg_enable_capture(self.pg_interfaces)
5086 self.pg1.get_capture(1)
5088 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4n,
5090 self.assertEqual(len(sessions) - start_sessnum, 0)
5092 def test_tcp_session_close_out(self):
5093 """ Close TCP session from outside network """
5094 self.tcp_port_out = 10505
5095 self.nat44_add_address(self.nat_addr)
5096 self.nat44_add_static_mapping(self.pg0.remote_ip4,
5100 proto=IP_PROTOS.tcp,
5102 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
5103 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
5106 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4n, 0)
5107 start_sessnum = len(sessions)
5109 self.initiate_tcp_session(self.pg0, self.pg1)
5111 # FIN packet out -> in
5112 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
5113 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
5114 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
5115 flags="FA", seq=100, ack=300))
5116 self.pg1.add_stream(p)
5117 self.pg_enable_capture(self.pg_interfaces)
5119 self.pg0.get_capture(1)
5121 # FIN+ACK packet in -> out
5122 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5123 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
5124 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
5125 flags="FA", seq=300, ack=101))
5127 self.pg0.add_stream(p)
5128 self.pg_enable_capture(self.pg_interfaces)
5130 self.pg1.get_capture(1)
5132 # ACK packet out -> in
5133 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
5134 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
5135 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
5136 flags="A", seq=101, ack=301))
5137 self.pg1.add_stream(p)
5138 self.pg_enable_capture(self.pg_interfaces)
5140 self.pg0.get_capture(1)
5142 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4n,
5144 self.assertEqual(len(sessions) - start_sessnum, 0)
5146 def test_tcp_session_close_simultaneous(self):
5147 """ Close TCP session from inside network """
5148 self.tcp_port_out = 10505
5149 self.nat44_add_address(self.nat_addr)
5150 self.nat44_add_static_mapping(self.pg0.remote_ip4,
5154 proto=IP_PROTOS.tcp,
5156 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
5157 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
5160 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4n, 0)
5161 start_sessnum = len(sessions)
5163 self.initiate_tcp_session(self.pg0, self.pg1)
5165 # FIN packet in -> out
5166 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5167 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
5168 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
5169 flags="FA", seq=100, ack=300))
5170 self.pg0.add_stream(p)
5171 self.pg_enable_capture(self.pg_interfaces)
5173 self.pg1.get_capture(1)
5175 # FIN packet out -> in
5176 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
5177 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
5178 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
5179 flags="FA", seq=300, ack=100))
5180 self.pg1.add_stream(p)
5181 self.pg_enable_capture(self.pg_interfaces)
5183 self.pg0.get_capture(1)
5185 # ACK packet in -> out
5186 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5187 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
5188 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
5189 flags="A", seq=101, ack=301))
5190 self.pg0.add_stream(p)
5191 self.pg_enable_capture(self.pg_interfaces)
5193 self.pg1.get_capture(1)
5195 # ACK packet out -> in
5196 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
5197 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
5198 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
5199 flags="A", seq=301, ack=101))
5200 self.pg1.add_stream(p)
5201 self.pg_enable_capture(self.pg_interfaces)
5203 self.pg0.get_capture(1)
5205 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4n,
5207 self.assertEqual(len(sessions) - start_sessnum, 0)
5209 def test_one_armed_nat44_static(self):
5210 """ One armed NAT44 and 1:1 NAPT asymmetrical rule """
5211 remote_host = self.pg4.remote_hosts[0]
5212 local_host = self.pg4.remote_hosts[1]
5217 self.vapi.nat44_forwarding_enable_disable(1)
5218 self.nat44_add_address(self.nat_addr, twice_nat=1)
5219 self.nat44_add_static_mapping(local_host.ip4, self.nat_addr,
5220 local_port, external_port,
5221 proto=IP_PROTOS.tcp, out2in_only=1,
5223 self.vapi.nat44_interface_add_del_feature(self.pg4.sw_if_index)
5224 self.vapi.nat44_interface_add_del_feature(self.pg4.sw_if_index,
5227 # from client to service
5228 p = (Ether(src=self.pg4.remote_mac, dst=self.pg4.local_mac) /
5229 IP(src=remote_host.ip4, dst=self.nat_addr) /
5230 TCP(sport=12345, dport=external_port))
5231 self.pg4.add_stream(p)
5232 self.pg_enable_capture(self.pg_interfaces)
5234 capture = self.pg4.get_capture(1)
5239 self.assertEqual(ip.dst, local_host.ip4)
5240 self.assertEqual(ip.src, self.nat_addr)
5241 self.assertEqual(tcp.dport, local_port)
5242 self.assertNotEqual(tcp.sport, 12345)
5243 eh_port_in = tcp.sport
5244 self.assert_packet_checksums_valid(p)
5246 self.logger.error(ppp("Unexpected or invalid packet:", p))
5249 # from service back to client
5250 p = (Ether(src=self.pg4.remote_mac, dst=self.pg4.local_mac) /
5251 IP(src=local_host.ip4, dst=self.nat_addr) /
5252 TCP(sport=local_port, dport=eh_port_in))
5253 self.pg4.add_stream(p)
5254 self.pg_enable_capture(self.pg_interfaces)
5256 capture = self.pg4.get_capture(1)
5261 self.assertEqual(ip.src, self.nat_addr)
5262 self.assertEqual(ip.dst, remote_host.ip4)
5263 self.assertEqual(tcp.sport, external_port)
5264 self.assertEqual(tcp.dport, 12345)
5265 self.assert_packet_checksums_valid(p)
5267 self.logger.error(ppp("Unexpected or invalid packet:", p))
5270 def test_static_with_port_out2(self):
5271 """ 1:1 NAPT asymmetrical rule """
5276 self.vapi.nat44_forwarding_enable_disable(1)
5277 self.nat44_add_static_mapping(self.pg0.remote_ip4, self.nat_addr,
5278 local_port, external_port,
5279 proto=IP_PROTOS.tcp, out2in_only=1)
5280 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
5281 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
5284 # from client to service
5285 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
5286 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
5287 TCP(sport=12345, dport=external_port))
5288 self.pg1.add_stream(p)
5289 self.pg_enable_capture(self.pg_interfaces)
5291 capture = self.pg0.get_capture(1)
5296 self.assertEqual(ip.dst, self.pg0.remote_ip4)
5297 self.assertEqual(tcp.dport, local_port)
5298 self.assert_packet_checksums_valid(p)
5300 self.logger.error(ppp("Unexpected or invalid packet:", p))
5304 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
5305 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
5306 ICMP(type=11) / capture[0][IP])
5307 self.pg0.add_stream(p)
5308 self.pg_enable_capture(self.pg_interfaces)
5310 capture = self.pg1.get_capture(1)
5313 self.assertEqual(p[IP].src, self.nat_addr)
5315 self.assertEqual(inner.dst, self.nat_addr)
5316 self.assertEqual(inner[TCPerror].dport, external_port)
5318 self.logger.error(ppp("Unexpected or invalid packet:", p))
5321 # from service back to client
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=local_port, dport=12345))
5325 self.pg0.add_stream(p)
5326 self.pg_enable_capture(self.pg_interfaces)
5328 capture = self.pg1.get_capture(1)
5333 self.assertEqual(ip.src, self.nat_addr)
5334 self.assertEqual(tcp.sport, external_port)
5335 self.assert_packet_checksums_valid(p)
5337 self.logger.error(ppp("Unexpected or invalid packet:", p))
5341 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
5342 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
5343 ICMP(type=11) / capture[0][IP])
5344 self.pg1.add_stream(p)
5345 self.pg_enable_capture(self.pg_interfaces)
5347 capture = self.pg0.get_capture(1)
5350 self.assertEqual(p[IP].dst, self.pg0.remote_ip4)
5352 self.assertEqual(inner.src, self.pg0.remote_ip4)
5353 self.assertEqual(inner[TCPerror].sport, local_port)
5355 self.logger.error(ppp("Unexpected or invalid packet:", p))
5358 # from client to server (no translation)
5359 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
5360 IP(src=self.pg1.remote_ip4, dst=self.pg0.remote_ip4) /
5361 TCP(sport=12346, dport=local_port))
5362 self.pg1.add_stream(p)
5363 self.pg_enable_capture(self.pg_interfaces)
5365 capture = self.pg0.get_capture(1)
5370 self.assertEqual(ip.dst, self.pg0.remote_ip4)
5371 self.assertEqual(tcp.dport, local_port)
5372 self.assert_packet_checksums_valid(p)
5374 self.logger.error(ppp("Unexpected or invalid packet:", p))
5377 # from service back to client (no translation)
5378 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5379 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
5380 TCP(sport=local_port, dport=12346))
5381 self.pg0.add_stream(p)
5382 self.pg_enable_capture(self.pg_interfaces)
5384 capture = self.pg1.get_capture(1)
5389 self.assertEqual(ip.src, self.pg0.remote_ip4)
5390 self.assertEqual(tcp.sport, local_port)
5391 self.assert_packet_checksums_valid(p)
5393 self.logger.error(ppp("Unexpected or invalid packet:", p))
5396 def test_output_feature(self):
5397 """ NAT44 interface output feature (in2out postrouting) """
5398 self.vapi.nat44_forwarding_enable_disable(1)
5399 self.nat44_add_address(self.nat_addr)
5400 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index,
5402 self.vapi.nat44_interface_add_del_output_feature(self.pg1.sw_if_index,
5406 pkts = self.create_stream_in(self.pg0, self.pg1)
5407 self.pg0.add_stream(pkts)
5408 self.pg_enable_capture(self.pg_interfaces)
5410 capture = self.pg1.get_capture(len(pkts))
5411 self.verify_capture_out(capture)
5414 pkts = self.create_stream_out(self.pg1)
5415 self.pg1.add_stream(pkts)
5416 self.pg_enable_capture(self.pg_interfaces)
5418 capture = self.pg0.get_capture(len(pkts))
5419 self.verify_capture_in(capture, self.pg0)
5421 def test_multiple_vrf(self):
5422 """ Multiple VRF setup """
5423 external_addr = '1.2.3.4'
5428 self.vapi.nat44_forwarding_enable_disable(1)
5429 self.nat44_add_address(self.nat_addr)
5430 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
5431 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index,
5433 self.vapi.nat44_interface_add_del_output_feature(self.pg1.sw_if_index,
5435 self.vapi.nat44_interface_add_del_feature(self.pg5.sw_if_index)
5436 self.vapi.nat44_interface_add_del_feature(self.pg5.sw_if_index,
5438 self.vapi.nat44_interface_add_del_feature(self.pg6.sw_if_index,
5440 self.nat44_add_static_mapping(self.pg5.remote_ip4, external_addr,
5441 local_port, external_port, vrf_id=1,
5442 proto=IP_PROTOS.tcp, out2in_only=1)
5443 self.nat44_add_static_mapping(
5444 self.pg0.remote_ip4, external_sw_if_index=self.pg0.sw_if_index,
5445 local_port=local_port, vrf_id=0, external_port=external_port,
5446 proto=IP_PROTOS.tcp, out2in_only=1)
5448 # from client to service (both VRF1)
5449 p = (Ether(src=self.pg6.remote_mac, dst=self.pg6.local_mac) /
5450 IP(src=self.pg6.remote_ip4, dst=external_addr) /
5451 TCP(sport=12345, dport=external_port))
5452 self.pg6.add_stream(p)
5453 self.pg_enable_capture(self.pg_interfaces)
5455 capture = self.pg5.get_capture(1)
5460 self.assertEqual(ip.dst, self.pg5.remote_ip4)
5461 self.assertEqual(tcp.dport, local_port)
5462 self.assert_packet_checksums_valid(p)
5464 self.logger.error(ppp("Unexpected or invalid packet:", p))
5467 # from service back to client (both VRF1)
5468 p = (Ether(src=self.pg5.remote_mac, dst=self.pg5.local_mac) /
5469 IP(src=self.pg5.remote_ip4, dst=self.pg6.remote_ip4) /
5470 TCP(sport=local_port, dport=12345))
5471 self.pg5.add_stream(p)
5472 self.pg_enable_capture(self.pg_interfaces)
5474 capture = self.pg6.get_capture(1)
5479 self.assertEqual(ip.src, external_addr)
5480 self.assertEqual(tcp.sport, external_port)
5481 self.assert_packet_checksums_valid(p)
5483 self.logger.error(ppp("Unexpected or invalid packet:", p))
5486 # dynamic NAT from VRF1 to VRF0 (output-feature)
5487 p = (Ether(src=self.pg5.remote_mac, dst=self.pg5.local_mac) /
5488 IP(src=self.pg5.remote_ip4, dst=self.pg1.remote_ip4) /
5489 TCP(sport=2345, dport=22))
5490 self.pg5.add_stream(p)
5491 self.pg_enable_capture(self.pg_interfaces)
5493 capture = self.pg1.get_capture(1)
5498 self.assertEqual(ip.src, self.nat_addr)
5499 self.assertNotEqual(tcp.sport, 2345)
5500 self.assert_packet_checksums_valid(p)
5503 self.logger.error(ppp("Unexpected or invalid packet:", p))
5506 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
5507 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
5508 TCP(sport=22, dport=port))
5509 self.pg1.add_stream(p)
5510 self.pg_enable_capture(self.pg_interfaces)
5512 capture = self.pg5.get_capture(1)
5517 self.assertEqual(ip.dst, self.pg5.remote_ip4)
5518 self.assertEqual(tcp.dport, 2345)
5519 self.assert_packet_checksums_valid(p)
5521 self.logger.error(ppp("Unexpected or invalid packet:", p))
5524 # from client VRF1 to service VRF0
5525 p = (Ether(src=self.pg6.remote_mac, dst=self.pg6.local_mac) /
5526 IP(src=self.pg6.remote_ip4, dst=self.pg0.local_ip4) /
5527 TCP(sport=12346, dport=external_port))
5528 self.pg6.add_stream(p)
5529 self.pg_enable_capture(self.pg_interfaces)
5531 capture = self.pg0.get_capture(1)
5536 self.assertEqual(ip.dst, self.pg0.remote_ip4)
5537 self.assertEqual(tcp.dport, local_port)
5538 self.assert_packet_checksums_valid(p)
5540 self.logger.error(ppp("Unexpected or invalid packet:", p))
5543 # from service VRF0 back to client VRF1
5544 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5545 IP(src=self.pg0.remote_ip4, dst=self.pg6.remote_ip4) /
5546 TCP(sport=local_port, dport=12346))
5547 self.pg0.add_stream(p)
5548 self.pg_enable_capture(self.pg_interfaces)
5550 capture = self.pg6.get_capture(1)
5555 self.assertEqual(ip.src, self.pg0.local_ip4)
5556 self.assertEqual(tcp.sport, external_port)
5557 self.assert_packet_checksums_valid(p)
5559 self.logger.error(ppp("Unexpected or invalid packet:", p))
5562 # from client VRF0 to service VRF1
5563 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5564 IP(src=self.pg0.remote_ip4, dst=external_addr) /
5565 TCP(sport=12347, dport=external_port))
5566 self.pg0.add_stream(p)
5567 self.pg_enable_capture(self.pg_interfaces)
5569 capture = self.pg5.get_capture(1)
5574 self.assertEqual(ip.dst, self.pg5.remote_ip4)
5575 self.assertEqual(tcp.dport, local_port)
5576 self.assert_packet_checksums_valid(p)
5578 self.logger.error(ppp("Unexpected or invalid packet:", p))
5581 # from service VRF1 back to client VRF0
5582 p = (Ether(src=self.pg5.remote_mac, dst=self.pg5.local_mac) /
5583 IP(src=self.pg5.remote_ip4, dst=self.pg0.remote_ip4) /
5584 TCP(sport=local_port, dport=12347))
5585 self.pg5.add_stream(p)
5586 self.pg_enable_capture(self.pg_interfaces)
5588 capture = self.pg0.get_capture(1)
5593 self.assertEqual(ip.src, external_addr)
5594 self.assertEqual(tcp.sport, external_port)
5595 self.assert_packet_checksums_valid(p)
5597 self.logger.error(ppp("Unexpected or invalid packet:", p))
5600 # from client to server (both VRF1, no translation)
5601 p = (Ether(src=self.pg6.remote_mac, dst=self.pg6.local_mac) /
5602 IP(src=self.pg6.remote_ip4, dst=self.pg5.remote_ip4) /
5603 TCP(sport=12348, dport=local_port))
5604 self.pg6.add_stream(p)
5605 self.pg_enable_capture(self.pg_interfaces)
5607 capture = self.pg5.get_capture(1)
5612 self.assertEqual(ip.dst, self.pg5.remote_ip4)
5613 self.assertEqual(tcp.dport, local_port)
5614 self.assert_packet_checksums_valid(p)
5616 self.logger.error(ppp("Unexpected or invalid packet:", p))
5619 # from server back to client (both VRF1, no translation)
5620 p = (Ether(src=self.pg5.remote_mac, dst=self.pg5.local_mac) /
5621 IP(src=self.pg5.remote_ip4, dst=self.pg6.remote_ip4) /
5622 TCP(sport=local_port, dport=12348))
5623 self.pg5.add_stream(p)
5624 self.pg_enable_capture(self.pg_interfaces)
5626 capture = self.pg6.get_capture(1)
5631 self.assertEqual(ip.src, self.pg5.remote_ip4)
5632 self.assertEqual(tcp.sport, local_port)
5633 self.assert_packet_checksums_valid(p)
5635 self.logger.error(ppp("Unexpected or invalid packet:", p))
5638 # from client VRF1 to server VRF0 (no translation)
5639 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5640 IP(src=self.pg0.remote_ip4, dst=self.pg6.remote_ip4) /
5641 TCP(sport=local_port, dport=12349))
5642 self.pg0.add_stream(p)
5643 self.pg_enable_capture(self.pg_interfaces)
5645 capture = self.pg6.get_capture(1)
5650 self.assertEqual(ip.src, self.pg0.remote_ip4)
5651 self.assertEqual(tcp.sport, local_port)
5652 self.assert_packet_checksums_valid(p)
5654 self.logger.error(ppp("Unexpected or invalid packet:", p))
5657 # from server VRF0 back to client VRF1 (no translation)
5658 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5659 IP(src=self.pg0.remote_ip4, dst=self.pg6.remote_ip4) /
5660 TCP(sport=local_port, dport=12349))
5661 self.pg0.add_stream(p)
5662 self.pg_enable_capture(self.pg_interfaces)
5664 capture = self.pg6.get_capture(1)
5669 self.assertEqual(ip.src, self.pg0.remote_ip4)
5670 self.assertEqual(tcp.sport, local_port)
5671 self.assert_packet_checksums_valid(p)
5673 self.logger.error(ppp("Unexpected or invalid packet:", p))
5676 # from client VRF0 to server VRF1 (no translation)
5677 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5678 IP(src=self.pg0.remote_ip4, dst=self.pg5.remote_ip4) /
5679 TCP(sport=12344, dport=local_port))
5680 self.pg0.add_stream(p)
5681 self.pg_enable_capture(self.pg_interfaces)
5683 capture = self.pg5.get_capture(1)
5688 self.assertEqual(ip.dst, self.pg5.remote_ip4)
5689 self.assertEqual(tcp.dport, local_port)
5690 self.assert_packet_checksums_valid(p)
5692 self.logger.error(ppp("Unexpected or invalid packet:", p))
5695 # from server VRF1 back to client VRF0 (no translation)
5696 p = (Ether(src=self.pg5.remote_mac, dst=self.pg5.local_mac) /
5697 IP(src=self.pg5.remote_ip4, dst=self.pg0.remote_ip4) /
5698 TCP(sport=local_port, dport=12344))
5699 self.pg5.add_stream(p)
5700 self.pg_enable_capture(self.pg_interfaces)
5702 capture = self.pg0.get_capture(1)
5707 self.assertEqual(ip.src, self.pg5.remote_ip4)
5708 self.assertEqual(tcp.sport, local_port)
5709 self.assert_packet_checksums_valid(p)
5711 self.logger.error(ppp("Unexpected or invalid packet:", p))
5714 @unittest.skipUnless(running_extended_tests(), "part of extended tests")
5715 def test_session_timeout(self):
5716 """ NAT44 session timeouts """
5717 self.nat44_add_address(self.nat_addr)
5718 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
5719 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
5721 self.vapi.nat_set_timeouts(icmp=5)
5725 for i in range(0, max_sessions):
5726 src = "10.10.%u.%u" % ((i & 0xFF00) >> 8, i & 0xFF)
5727 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
5728 IP(src=src, dst=self.pg1.remote_ip4) /
5729 ICMP(id=1025, type='echo-request'))
5731 self.pg0.add_stream(pkts)
5732 self.pg_enable_capture(self.pg_interfaces)
5734 self.pg1.get_capture(max_sessions)
5739 for i in range(0, max_sessions):
5740 src = "10.11.%u.%u" % ((i & 0xFF00) >> 8, i & 0xFF)
5741 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
5742 IP(src=src, dst=self.pg1.remote_ip4) /
5743 ICMP(id=1026, type='echo-request'))
5745 self.pg0.add_stream(pkts)
5746 self.pg_enable_capture(self.pg_interfaces)
5748 self.pg1.get_capture(max_sessions)
5751 users = self.vapi.nat44_user_dump()
5753 nsessions = nsessions + user.nsessions
5754 self.assertLess(nsessions, 2 * max_sessions)
5756 @unittest.skipUnless(running_extended_tests(), "part of extended tests")
5757 def test_session_rst_timeout(self):
5758 """ NAT44 session RST timeouts """
5759 self.nat44_add_address(self.nat_addr)
5760 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
5761 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
5763 self.vapi.nat_set_timeouts(tcp_transitory=5)
5765 self.initiate_tcp_session(self.pg0, self.pg1)
5766 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5767 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
5768 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
5770 self.pg0.add_stream(p)
5771 self.pg_enable_capture(self.pg_interfaces)
5773 self.pg1.get_capture(1)
5777 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5778 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
5779 TCP(sport=self.tcp_port_in + 1, dport=self.tcp_external_port + 1,
5781 self.pg0.add_stream(p)
5782 self.pg_enable_capture(self.pg_interfaces)
5784 self.pg1.get_capture(1)
5787 users = self.vapi.nat44_user_dump()
5788 self.assertEqual(len(users), 1)
5789 self.assertEqual(users[0].ip_address, self.pg0.remote_ip4n)
5790 self.assertEqual(users[0].nsessions, 1)
5792 @unittest.skipUnless(running_extended_tests(), "part of extended tests")
5793 def test_session_limit_per_user(self):
5794 """ Maximum sessions per user limit """
5795 self.nat44_add_address(self.nat_addr)
5796 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
5797 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
5799 self.vapi.set_ipfix_exporter(collector_address=self.pg2.remote_ip4n,
5800 src_address=self.pg2.local_ip4n,
5802 template_interval=10)
5803 self.vapi.nat_set_timeouts(udp=5)
5805 # get maximum number of translations per user
5806 nat44_config = self.vapi.nat_show_config()
5809 for port in range(0, nat44_config.max_translations_per_user):
5810 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5811 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
5812 UDP(sport=1025 + port, dport=1025 + port))
5815 self.pg0.add_stream(pkts)
5816 self.pg_enable_capture(self.pg_interfaces)
5818 capture = self.pg1.get_capture(len(pkts))
5820 self.vapi.nat_ipfix(domain_id=self.ipfix_domain_id,
5821 src_port=self.ipfix_src_port)
5823 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5824 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
5825 UDP(sport=3001, dport=3002))
5826 self.pg0.add_stream(p)
5827 self.pg_enable_capture(self.pg_interfaces)
5829 capture = self.pg1.assert_nothing_captured()
5831 # verify IPFIX logging
5832 self.vapi.cli("ipfix flush") # FIXME this should be an API call
5834 capture = self.pg2.get_capture(10)
5835 ipfix = IPFIXDecoder()
5836 # first load template
5838 self.assertTrue(p.haslayer(IPFIX))
5839 if p.haslayer(Template):
5840 ipfix.add_template(p.getlayer(Template))
5841 # verify events in data set
5843 if p.haslayer(Data):
5844 data = ipfix.decode_data_set(p.getlayer(Set))
5845 self.verify_ipfix_max_entries_per_user(
5847 nat44_config.max_translations_per_user,
5848 self.pg0.remote_ip4n)
5851 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5852 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
5853 UDP(sport=3001, dport=3002))
5854 self.pg0.add_stream(p)
5855 self.pg_enable_capture(self.pg_interfaces)
5857 self.pg1.get_capture(1)
5859 def test_syslog_sess(self):
5860 """ Test syslog session creation and deletion """
5861 self.vapi.syslog_set_filter(SYSLOG_SEVERITY.INFO)
5862 self.vapi.syslog_set_sender(self.pg2.remote_ip4n, self.pg2.local_ip4n)
5863 self.nat44_add_address(self.nat_addr)
5864 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
5865 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
5868 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
5869 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
5870 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port))
5871 self.pg0.add_stream(p)
5872 self.pg_enable_capture(self.pg_interfaces)
5874 capture = self.pg1.get_capture(1)
5875 self.tcp_port_out = capture[0][TCP].sport
5876 capture = self.pg2.get_capture(1)
5877 self.verify_syslog_sess(capture[0][Raw].load)
5879 self.pg_enable_capture(self.pg_interfaces)
5881 self.nat44_add_address(self.nat_addr, is_add=0)
5882 capture = self.pg2.get_capture(1)
5883 self.verify_syslog_sess(capture[0][Raw].load, False)
5886 super(TestNAT44EndpointDependent, self).tearDown()
5887 if not self.vpp_dead:
5888 self.logger.info(self.vapi.cli("show nat44 addresses"))
5889 self.logger.info(self.vapi.cli("show nat44 interfaces"))
5890 self.logger.info(self.vapi.cli("show nat44 static mappings"))
5891 self.logger.info(self.vapi.cli("show nat44 interface address"))
5892 self.logger.info(self.vapi.cli("show nat44 sessions detail"))
5893 self.logger.info(self.vapi.cli("show nat44 hash tables detail"))
5894 self.logger.info(self.vapi.cli("show nat timeouts"))
5896 self.vapi.cli("clear logging")
5899 class TestNAT44Out2InDPO(MethodHolder):
5900 """ NAT44 Test Cases using out2in DPO """
5903 def setUpConstants(cls):
5904 super(TestNAT44Out2InDPO, cls).setUpConstants()
5905 cls.vpp_cmdline.extend(["nat", "{", "out2in dpo", "}"])
5908 def setUpClass(cls):
5909 super(TestNAT44Out2InDPO, cls).setUpClass()
5910 cls.vapi.cli("set log class nat level debug")
5913 cls.tcp_port_in = 6303
5914 cls.tcp_port_out = 6303
5915 cls.udp_port_in = 6304
5916 cls.udp_port_out = 6304
5917 cls.icmp_id_in = 6305
5918 cls.icmp_id_out = 6305
5919 cls.nat_addr = '10.0.0.3'
5920 cls.nat_addr_n = socket.inet_pton(socket.AF_INET, cls.nat_addr)
5921 cls.dst_ip4 = '192.168.70.1'
5923 cls.create_pg_interfaces(range(2))
5926 cls.pg0.config_ip4()
5927 cls.pg0.resolve_arp()
5930 cls.pg1.config_ip6()
5931 cls.pg1.resolve_ndp()
5933 cls.vapi.ip_add_del_route(is_ipv6=True, dst_address='\x00'*16,
5934 dst_address_length=0,
5935 next_hop_address=cls.pg1.remote_ip6n,
5936 next_hop_sw_if_index=cls.pg1.sw_if_index)
5939 super(TestNAT44Out2InDPO, cls).tearDownClass()
5942 def configure_xlat(self):
5943 self.dst_ip6_pfx = '1:2:3::'
5944 self.dst_ip6_pfx_n = socket.inet_pton(socket.AF_INET6,
5946 self.dst_ip6_pfx_len = 96
5947 self.src_ip6_pfx = '4:5:6::'
5948 self.src_ip6_pfx_n = socket.inet_pton(socket.AF_INET6,
5950 self.src_ip6_pfx_len = 96
5951 self.vapi.map_add_domain(self.dst_ip6_pfx_n, self.dst_ip6_pfx_len,
5952 self.src_ip6_pfx_n, self.src_ip6_pfx_len,
5953 '\x00\x00\x00\x00', 0, is_translation=1,
5956 @unittest.skip('Temporary disabled')
5957 def test_464xlat_ce(self):
5958 """ Test 464XLAT CE with NAT44 """
5960 nat_config = self.vapi.nat_show_config()
5961 self.assertEqual(1, nat_config.out2in_dpo)
5963 self.configure_xlat()
5965 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
5966 self.vapi.nat44_add_del_address_range(self.nat_addr_n, self.nat_addr_n)
5968 out_src_ip6 = self.compose_ip6(self.dst_ip4, self.dst_ip6_pfx,
5969 self.dst_ip6_pfx_len)
5970 out_dst_ip6 = self.compose_ip6(self.nat_addr, self.src_ip6_pfx,
5971 self.src_ip6_pfx_len)
5974 pkts = self.create_stream_in(self.pg0, self.pg1, self.dst_ip4)
5975 self.pg0.add_stream(pkts)
5976 self.pg_enable_capture(self.pg_interfaces)
5978 capture = self.pg1.get_capture(len(pkts))
5979 self.verify_capture_out_ip6(capture, nat_ip=out_dst_ip6,
5982 pkts = self.create_stream_out_ip6(self.pg1, out_src_ip6,
5984 self.pg1.add_stream(pkts)
5985 self.pg_enable_capture(self.pg_interfaces)
5987 capture = self.pg0.get_capture(len(pkts))
5988 self.verify_capture_in(capture, self.pg0)
5990 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index,
5992 self.vapi.nat44_add_del_address_range(self.nat_addr_n,
5993 self.nat_addr_n, is_add=0)
5995 @unittest.skip('Temporary disabled')
5996 def test_464xlat_ce_no_nat(self):
5997 """ Test 464XLAT CE without NAT44 """
5999 self.configure_xlat()
6001 out_src_ip6 = self.compose_ip6(self.dst_ip4, self.dst_ip6_pfx,
6002 self.dst_ip6_pfx_len)
6003 out_dst_ip6 = self.compose_ip6(self.pg0.remote_ip4, self.src_ip6_pfx,
6004 self.src_ip6_pfx_len)
6006 pkts = self.create_stream_in(self.pg0, self.pg1, self.dst_ip4)
6007 self.pg0.add_stream(pkts)
6008 self.pg_enable_capture(self.pg_interfaces)
6010 capture = self.pg1.get_capture(len(pkts))
6011 self.verify_capture_out_ip6(capture, dst_ip=out_src_ip6,
6012 nat_ip=out_dst_ip6, same_port=True)
6014 pkts = self.create_stream_out_ip6(self.pg1, out_src_ip6, out_dst_ip6)
6015 self.pg1.add_stream(pkts)
6016 self.pg_enable_capture(self.pg_interfaces)
6018 capture = self.pg0.get_capture(len(pkts))
6019 self.verify_capture_in(capture, self.pg0)
6022 class TestDeterministicNAT(MethodHolder):
6023 """ Deterministic NAT Test Cases """
6026 def setUpConstants(cls):
6027 super(TestDeterministicNAT, cls).setUpConstants()
6028 cls.vpp_cmdline.extend(["nat", "{", "deterministic", "}"])
6031 def setUpClass(cls):
6032 super(TestDeterministicNAT, cls).setUpClass()
6033 cls.vapi.cli("set log class nat level debug")
6036 cls.tcp_port_in = 6303
6037 cls.tcp_external_port = 6303
6038 cls.udp_port_in = 6304
6039 cls.udp_external_port = 6304
6040 cls.icmp_id_in = 6305
6041 cls.nat_addr = '10.0.0.3'
6043 cls.create_pg_interfaces(range(3))
6044 cls.interfaces = list(cls.pg_interfaces)
6046 for i in cls.interfaces:
6051 cls.pg0.generate_remote_hosts(2)
6052 cls.pg0.configure_ipv4_neighbors()
6055 super(TestDeterministicNAT, cls).tearDownClass()
6058 def create_stream_in(self, in_if, out_if, ttl=64):
6060 Create packet stream for inside network
6062 :param in_if: Inside interface
6063 :param out_if: Outside interface
6064 :param ttl: TTL of generated packets
6068 p = (Ether(dst=in_if.local_mac, src=in_if.remote_mac) /
6069 IP(src=in_if.remote_ip4, dst=out_if.remote_ip4, ttl=ttl) /
6070 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port))
6074 p = (Ether(dst=in_if.local_mac, src=in_if.remote_mac) /
6075 IP(src=in_if.remote_ip4, dst=out_if.remote_ip4, ttl=ttl) /
6076 UDP(sport=self.udp_port_in, dport=self.udp_external_port))
6080 p = (Ether(dst=in_if.local_mac, src=in_if.remote_mac) /
6081 IP(src=in_if.remote_ip4, dst=out_if.remote_ip4, ttl=ttl) /
6082 ICMP(id=self.icmp_id_in, type='echo-request'))
6087 def create_stream_out(self, out_if, dst_ip=None, ttl=64):
6089 Create packet stream for outside network
6091 :param out_if: Outside interface
6092 :param dst_ip: Destination IP address (Default use global NAT address)
6093 :param ttl: TTL of generated packets
6096 dst_ip = self.nat_addr
6099 p = (Ether(dst=out_if.local_mac, src=out_if.remote_mac) /
6100 IP(src=out_if.remote_ip4, dst=dst_ip, ttl=ttl) /
6101 TCP(dport=self.tcp_port_out, sport=self.tcp_external_port))
6105 p = (Ether(dst=out_if.local_mac, src=out_if.remote_mac) /
6106 IP(src=out_if.remote_ip4, dst=dst_ip, ttl=ttl) /
6107 UDP(dport=self.udp_port_out, sport=self.udp_external_port))
6111 p = (Ether(dst=out_if.local_mac, src=out_if.remote_mac) /
6112 IP(src=out_if.remote_ip4, dst=dst_ip, ttl=ttl) /
6113 ICMP(id=self.icmp_external_id, type='echo-reply'))
6118 def verify_capture_out(self, capture, nat_ip=None):
6120 Verify captured packets on outside network
6122 :param capture: Captured packets
6123 :param nat_ip: Translated IP address (Default use global NAT address)
6124 :param same_port: Sorce port number is not translated (Default False)
6127 nat_ip = self.nat_addr
6128 for packet in capture:
6130 self.assertEqual(packet[IP].src, nat_ip)
6131 if packet.haslayer(TCP):
6132 self.tcp_port_out = packet[TCP].sport
6133 elif packet.haslayer(UDP):
6134 self.udp_port_out = packet[UDP].sport
6136 self.icmp_external_id = packet[ICMP].id
6138 self.logger.error(ppp("Unexpected or invalid packet "
6139 "(outside network):", packet))
6142 def test_deterministic_mode(self):
6143 """ NAT plugin run deterministic mode """
6144 in_addr = '172.16.255.0'
6145 out_addr = '172.17.255.50'
6146 in_addr_t = '172.16.255.20'
6147 in_addr_n = socket.inet_aton(in_addr)
6148 out_addr_n = socket.inet_aton(out_addr)
6149 in_addr_t_n = socket.inet_aton(in_addr_t)
6153 nat_config = self.vapi.nat_show_config()
6154 self.assertEqual(1, nat_config.deterministic)
6156 self.vapi.nat_det_add_del_map(in_addr_n, in_plen, out_addr_n, out_plen)
6158 rep1 = self.vapi.nat_det_forward(in_addr_t_n)
6159 self.assertEqual(rep1.out_addr[:4], out_addr_n)
6160 rep2 = self.vapi.nat_det_reverse(out_addr_n, rep1.out_port_hi)
6161 self.assertEqual(rep2.in_addr[:4], in_addr_t_n)
6163 deterministic_mappings = self.vapi.nat_det_map_dump()
6164 self.assertEqual(len(deterministic_mappings), 1)
6165 dsm = deterministic_mappings[0]
6166 self.assertEqual(in_addr_n, dsm.in_addr[:4])
6167 self.assertEqual(in_plen, dsm.in_plen)
6168 self.assertEqual(out_addr_n, dsm.out_addr[:4])
6169 self.assertEqual(out_plen, dsm.out_plen)
6171 self.clear_nat_det()
6172 deterministic_mappings = self.vapi.nat_det_map_dump()
6173 self.assertEqual(len(deterministic_mappings), 0)
6175 def test_set_timeouts(self):
6176 """ Set deterministic NAT timeouts """
6177 timeouts_before = self.vapi.nat_get_timeouts()
6179 self.vapi.nat_set_timeouts(timeouts_before.udp + 10,
6180 timeouts_before.tcp_established + 10,
6181 timeouts_before.tcp_transitory + 10,
6182 timeouts_before.icmp + 10)
6184 timeouts_after = self.vapi.nat_get_timeouts()
6186 self.assertNotEqual(timeouts_before.udp, timeouts_after.udp)
6187 self.assertNotEqual(timeouts_before.icmp, timeouts_after.icmp)
6188 self.assertNotEqual(timeouts_before.tcp_established,
6189 timeouts_after.tcp_established)
6190 self.assertNotEqual(timeouts_before.tcp_transitory,
6191 timeouts_after.tcp_transitory)
6193 def test_det_in(self):
6194 """ Deterministic NAT translation test (TCP, UDP, ICMP) """
6196 nat_ip = "10.0.0.10"
6198 self.vapi.nat_det_add_del_map(self.pg0.remote_ip4n,
6200 socket.inet_aton(nat_ip),
6202 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
6203 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
6207 pkts = self.create_stream_in(self.pg0, self.pg1)
6208 self.pg0.add_stream(pkts)
6209 self.pg_enable_capture(self.pg_interfaces)
6211 capture = self.pg1.get_capture(len(pkts))
6212 self.verify_capture_out(capture, nat_ip)
6215 pkts = self.create_stream_out(self.pg1, nat_ip)
6216 self.pg1.add_stream(pkts)
6217 self.pg_enable_capture(self.pg_interfaces)
6219 capture = self.pg0.get_capture(len(pkts))
6220 self.verify_capture_in(capture, self.pg0)
6223 sessions = self.vapi.nat_det_session_dump(self.pg0.remote_ip4n)
6224 self.assertEqual(len(sessions), 3)
6228 self.assertEqual(s.ext_addr[:4], self.pg1.remote_ip4n)
6229 self.assertEqual(s.in_port, self.tcp_port_in)
6230 self.assertEqual(s.out_port, self.tcp_port_out)
6231 self.assertEqual(s.ext_port, self.tcp_external_port)
6235 self.assertEqual(s.ext_addr[:4], self.pg1.remote_ip4n)
6236 self.assertEqual(s.in_port, self.udp_port_in)
6237 self.assertEqual(s.out_port, self.udp_port_out)
6238 self.assertEqual(s.ext_port, self.udp_external_port)
6242 self.assertEqual(s.ext_addr[:4], self.pg1.remote_ip4n)
6243 self.assertEqual(s.in_port, self.icmp_id_in)
6244 self.assertEqual(s.out_port, self.icmp_external_id)
6246 def test_multiple_users(self):
6247 """ Deterministic NAT multiple users """
6249 nat_ip = "10.0.0.10"
6251 external_port = 6303
6253 host0 = self.pg0.remote_hosts[0]
6254 host1 = self.pg0.remote_hosts[1]
6256 self.vapi.nat_det_add_del_map(host0.ip4n,
6258 socket.inet_aton(nat_ip),
6260 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
6261 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
6265 p = (Ether(src=host0.mac, dst=self.pg0.local_mac) /
6266 IP(src=host0.ip4, dst=self.pg1.remote_ip4) /
6267 TCP(sport=port_in, dport=external_port))
6268 self.pg0.add_stream(p)
6269 self.pg_enable_capture(self.pg_interfaces)
6271 capture = self.pg1.get_capture(1)
6276 self.assertEqual(ip.src, nat_ip)
6277 self.assertEqual(ip.dst, self.pg1.remote_ip4)
6278 self.assertEqual(tcp.dport, external_port)
6279 port_out0 = tcp.sport
6281 self.logger.error(ppp("Unexpected or invalid packet:", p))
6285 p = (Ether(src=host1.mac, dst=self.pg0.local_mac) /
6286 IP(src=host1.ip4, dst=self.pg1.remote_ip4) /
6287 TCP(sport=port_in, dport=external_port))
6288 self.pg0.add_stream(p)
6289 self.pg_enable_capture(self.pg_interfaces)
6291 capture = self.pg1.get_capture(1)
6296 self.assertEqual(ip.src, nat_ip)
6297 self.assertEqual(ip.dst, self.pg1.remote_ip4)
6298 self.assertEqual(tcp.dport, external_port)
6299 port_out1 = tcp.sport
6301 self.logger.error(ppp("Unexpected or invalid packet:", p))
6304 dms = self.vapi.nat_det_map_dump()
6305 self.assertEqual(1, len(dms))
6306 self.assertEqual(2, dms[0].ses_num)
6309 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
6310 IP(src=self.pg1.remote_ip4, dst=nat_ip) /
6311 TCP(sport=external_port, dport=port_out0))
6312 self.pg1.add_stream(p)
6313 self.pg_enable_capture(self.pg_interfaces)
6315 capture = self.pg0.get_capture(1)
6320 self.assertEqual(ip.src, self.pg1.remote_ip4)
6321 self.assertEqual(ip.dst, host0.ip4)
6322 self.assertEqual(tcp.dport, port_in)
6323 self.assertEqual(tcp.sport, external_port)
6325 self.logger.error(ppp("Unexpected or invalid packet:", p))
6329 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
6330 IP(src=self.pg1.remote_ip4, dst=nat_ip) /
6331 TCP(sport=external_port, dport=port_out1))
6332 self.pg1.add_stream(p)
6333 self.pg_enable_capture(self.pg_interfaces)
6335 capture = self.pg0.get_capture(1)
6340 self.assertEqual(ip.src, self.pg1.remote_ip4)
6341 self.assertEqual(ip.dst, host1.ip4)
6342 self.assertEqual(tcp.dport, port_in)
6343 self.assertEqual(tcp.sport, external_port)
6345 self.logger.error(ppp("Unexpected or invalid packet", p))
6348 # session close api test
6349 self.vapi.nat_det_close_session_out(socket.inet_aton(nat_ip),
6351 self.pg1.remote_ip4n,
6353 dms = self.vapi.nat_det_map_dump()
6354 self.assertEqual(dms[0].ses_num, 1)
6356 self.vapi.nat_det_close_session_in(host0.ip4n,
6358 self.pg1.remote_ip4n,
6360 dms = self.vapi.nat_det_map_dump()
6361 self.assertEqual(dms[0].ses_num, 0)
6363 def test_tcp_session_close_detection_in(self):
6364 """ Deterministic NAT TCP session close from inside network """
6365 self.vapi.nat_det_add_del_map(self.pg0.remote_ip4n,
6367 socket.inet_aton(self.nat_addr),
6369 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
6370 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
6373 self.initiate_tcp_session(self.pg0, self.pg1)
6375 # close the session from inside
6377 # FIN packet in -> out
6378 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6379 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6380 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
6382 self.pg0.add_stream(p)
6383 self.pg_enable_capture(self.pg_interfaces)
6385 self.pg1.get_capture(1)
6389 # ACK packet out -> in
6390 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
6391 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
6392 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
6396 # FIN packet out -> in
6397 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
6398 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
6399 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
6403 self.pg1.add_stream(pkts)
6404 self.pg_enable_capture(self.pg_interfaces)
6406 self.pg0.get_capture(2)
6408 # ACK packet in -> out
6409 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6410 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6411 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
6413 self.pg0.add_stream(p)
6414 self.pg_enable_capture(self.pg_interfaces)
6416 self.pg1.get_capture(1)
6418 # Check if deterministic NAT44 closed the session
6419 dms = self.vapi.nat_det_map_dump()
6420 self.assertEqual(0, dms[0].ses_num)
6422 self.logger.error("TCP session termination failed")
6425 def test_tcp_session_close_detection_out(self):
6426 """ Deterministic NAT TCP session close from outside network """
6427 self.vapi.nat_det_add_del_map(self.pg0.remote_ip4n,
6429 socket.inet_aton(self.nat_addr),
6431 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
6432 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
6435 self.initiate_tcp_session(self.pg0, self.pg1)
6437 # close the session from outside
6439 # FIN packet out -> in
6440 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
6441 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
6442 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
6444 self.pg1.add_stream(p)
6445 self.pg_enable_capture(self.pg_interfaces)
6447 self.pg0.get_capture(1)
6451 # ACK packet in -> out
6452 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6453 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6454 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
6458 # ACK packet in -> out
6459 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6460 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6461 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
6465 self.pg0.add_stream(pkts)
6466 self.pg_enable_capture(self.pg_interfaces)
6468 self.pg1.get_capture(2)
6470 # ACK packet out -> in
6471 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
6472 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
6473 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
6475 self.pg1.add_stream(p)
6476 self.pg_enable_capture(self.pg_interfaces)
6478 self.pg0.get_capture(1)
6480 # Check if deterministic NAT44 closed the session
6481 dms = self.vapi.nat_det_map_dump()
6482 self.assertEqual(0, dms[0].ses_num)
6484 self.logger.error("TCP session termination failed")
6487 @unittest.skipUnless(running_extended_tests(), "part of extended tests")
6488 def test_session_timeout(self):
6489 """ Deterministic NAT session timeouts """
6490 self.vapi.nat_det_add_del_map(self.pg0.remote_ip4n,
6492 socket.inet_aton(self.nat_addr),
6494 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
6495 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
6498 self.initiate_tcp_session(self.pg0, self.pg1)
6499 self.vapi.nat_set_timeouts(5, 5, 5, 5)
6500 pkts = self.create_stream_in(self.pg0, self.pg1)
6501 self.pg0.add_stream(pkts)
6502 self.pg_enable_capture(self.pg_interfaces)
6504 capture = self.pg1.get_capture(len(pkts))
6507 dms = self.vapi.nat_det_map_dump()
6508 self.assertEqual(0, dms[0].ses_num)
6510 @unittest.skipUnless(running_extended_tests(), "part of extended tests")
6511 def test_session_limit_per_user(self):
6512 """ Deterministic NAT maximum sessions per user limit """
6513 self.vapi.nat_det_add_del_map(self.pg0.remote_ip4n,
6515 socket.inet_aton(self.nat_addr),
6517 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
6518 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
6520 self.vapi.set_ipfix_exporter(collector_address=self.pg2.remote_ip4n,
6521 src_address=self.pg2.local_ip4n,
6523 template_interval=10)
6524 self.vapi.nat_ipfix()
6527 for port in range(1025, 2025):
6528 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6529 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6530 UDP(sport=port, dport=port))
6533 self.pg0.add_stream(pkts)
6534 self.pg_enable_capture(self.pg_interfaces)
6536 capture = self.pg1.get_capture(len(pkts))
6538 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6539 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6540 UDP(sport=3001, dport=3002))
6541 self.pg0.add_stream(p)
6542 self.pg_enable_capture(self.pg_interfaces)
6544 capture = self.pg1.assert_nothing_captured()
6546 # verify ICMP error packet
6547 capture = self.pg0.get_capture(1)
6549 self.assertTrue(p.haslayer(ICMP))
6551 self.assertEqual(icmp.type, 3)
6552 self.assertEqual(icmp.code, 1)
6553 self.assertTrue(icmp.haslayer(IPerror))
6554 inner_ip = icmp[IPerror]
6555 self.assertEqual(inner_ip[UDPerror].sport, 3001)
6556 self.assertEqual(inner_ip[UDPerror].dport, 3002)
6558 dms = self.vapi.nat_det_map_dump()
6560 self.assertEqual(1000, dms[0].ses_num)
6562 # verify IPFIX logging
6563 self.vapi.cli("ipfix flush") # FIXME this should be an API call
6565 capture = self.pg2.get_capture(2)
6566 ipfix = IPFIXDecoder()
6567 # first load template
6569 self.assertTrue(p.haslayer(IPFIX))
6570 if p.haslayer(Template):
6571 ipfix.add_template(p.getlayer(Template))
6572 # verify events in data set
6574 if p.haslayer(Data):
6575 data = ipfix.decode_data_set(p.getlayer(Set))
6576 self.verify_ipfix_max_entries_per_user(data,
6578 self.pg0.remote_ip4n)
6580 def clear_nat_det(self):
6582 Clear deterministic NAT configuration.
6584 self.vapi.nat_ipfix(enable=0)
6585 self.vapi.nat_set_timeouts()
6586 deterministic_mappings = self.vapi.nat_det_map_dump()
6587 for dsm in deterministic_mappings:
6588 self.vapi.nat_det_add_del_map(dsm.in_addr,
6594 interfaces = self.vapi.nat44_interface_dump()
6595 for intf in interfaces:
6596 self.vapi.nat44_interface_add_del_feature(intf.sw_if_index,
6601 super(TestDeterministicNAT, self).tearDown()
6602 if not self.vpp_dead:
6603 self.logger.info(self.vapi.cli("show nat44 interfaces"))
6604 self.logger.info(self.vapi.cli("show nat timeouts"))
6606 self.vapi.cli("show nat44 deterministic mappings"))
6608 self.vapi.cli("show nat44 deterministic sessions"))
6609 self.clear_nat_det()
6612 class TestNAT64(MethodHolder):
6613 """ NAT64 Test Cases """
6616 def setUpConstants(cls):
6617 super(TestNAT64, cls).setUpConstants()
6618 cls.vpp_cmdline.extend(["nat", "{", "nat64 bib hash buckets 128",
6619 "nat64 st hash buckets 256", "}"])
6622 def setUpClass(cls):
6623 super(TestNAT64, cls).setUpClass()
6626 cls.tcp_port_in = 6303
6627 cls.tcp_port_out = 6303
6628 cls.udp_port_in = 6304
6629 cls.udp_port_out = 6304
6630 cls.icmp_id_in = 6305
6631 cls.icmp_id_out = 6305
6632 cls.tcp_external_port = 80
6633 cls.nat_addr = '10.0.0.3'
6634 cls.nat_addr_n = socket.inet_pton(socket.AF_INET, cls.nat_addr)
6636 cls.vrf1_nat_addr = '10.0.10.3'
6637 cls.vrf1_nat_addr_n = socket.inet_pton(socket.AF_INET,
6639 cls.ipfix_src_port = 4739
6640 cls.ipfix_domain_id = 1
6642 cls.create_pg_interfaces(range(6))
6643 cls.ip6_interfaces = list(cls.pg_interfaces[0:1])
6644 cls.ip6_interfaces.append(cls.pg_interfaces[2])
6645 cls.ip4_interfaces = list(cls.pg_interfaces[1:2])
6647 cls.vapi.ip_table_add_del(cls.vrf1_id, is_add=1, is_ipv6=1)
6649 cls.pg_interfaces[2].set_table_ip6(cls.vrf1_id)
6651 cls.pg0.generate_remote_hosts(2)
6653 for i in cls.ip6_interfaces:
6656 i.configure_ipv6_neighbors()
6658 for i in cls.ip4_interfaces:
6664 cls.pg3.config_ip4()
6665 cls.pg3.resolve_arp()
6666 cls.pg3.config_ip6()
6667 cls.pg3.configure_ipv6_neighbors()
6670 cls.pg5.config_ip6()
6673 super(TestNAT64, cls).tearDownClass()
6676 def test_nat64_inside_interface_handles_neighbor_advertisement(self):
6677 """ NAT64 inside interface handles Neighbor Advertisement """
6679 self.vapi.nat64_add_del_interface(self.pg5.sw_if_index)
6682 ping = (Ether(dst=self.pg5.local_mac, src=self.pg5.remote_mac) /
6683 IPv6(src=self.pg5.remote_ip6, dst=self.pg5.local_ip6) /
6684 ICMPv6EchoRequest())
6686 self.pg5.add_stream(pkts)
6687 self.pg_enable_capture(self.pg_interfaces)
6690 # Wait for Neighbor Solicitation
6691 capture = self.pg5.get_capture(len(pkts))
6694 self.assertEqual(packet[IPv6].src, self.pg5.local_ip6)
6695 self.assertEqual(packet.haslayer(ICMPv6ND_NS), 1)
6696 tgt = packet[ICMPv6ND_NS].tgt
6698 self.logger.error(ppp("Unexpected or invalid packet:", packet))
6701 # Send Neighbor Advertisement
6702 p = (Ether(dst=self.pg5.local_mac, src=self.pg5.remote_mac) /
6703 IPv6(src=self.pg5.remote_ip6, dst=self.pg5.local_ip6) /
6704 ICMPv6ND_NA(tgt=tgt) /
6705 ICMPv6NDOptDstLLAddr(lladdr=self.pg5.remote_mac))
6707 self.pg5.add_stream(pkts)
6708 self.pg_enable_capture(self.pg_interfaces)
6711 # Try to send ping again
6713 self.pg5.add_stream(pkts)
6714 self.pg_enable_capture(self.pg_interfaces)
6717 # Wait for ping reply
6718 capture = self.pg5.get_capture(len(pkts))
6721 self.assertEqual(packet[IPv6].src, self.pg5.local_ip6)
6722 self.assertEqual(packet[IPv6].dst, self.pg5.remote_ip6)
6723 self.assertEqual(packet.haslayer(ICMPv6EchoReply), 1)
6725 self.logger.error(ppp("Unexpected or invalid packet:", packet))
6728 def test_pool(self):
6729 """ Add/delete address to NAT64 pool """
6730 nat_addr = socket.inet_pton(socket.AF_INET, '1.2.3.4')
6732 self.vapi.nat64_add_del_pool_addr_range(nat_addr, nat_addr)
6734 addresses = self.vapi.nat64_pool_addr_dump()
6735 self.assertEqual(len(addresses), 1)
6736 self.assertEqual(addresses[0].address, nat_addr)
6738 self.vapi.nat64_add_del_pool_addr_range(nat_addr, nat_addr, is_add=0)
6740 addresses = self.vapi.nat64_pool_addr_dump()
6741 self.assertEqual(len(addresses), 0)
6743 def test_interface(self):
6744 """ Enable/disable NAT64 feature on the interface """
6745 self.vapi.nat64_add_del_interface(self.pg0.sw_if_index)
6746 self.vapi.nat64_add_del_interface(self.pg1.sw_if_index, is_inside=0)
6748 interfaces = self.vapi.nat64_interface_dump()
6749 self.assertEqual(len(interfaces), 2)
6752 for intf in interfaces:
6753 if intf.sw_if_index == self.pg0.sw_if_index:
6754 self.assertEqual(intf.is_inside, 1)
6756 elif intf.sw_if_index == self.pg1.sw_if_index:
6757 self.assertEqual(intf.is_inside, 0)
6759 self.assertTrue(pg0_found)
6760 self.assertTrue(pg1_found)
6762 features = self.vapi.cli("show interface features pg0")
6763 self.assertNotEqual(features.find('nat64-in2out'), -1)
6764 features = self.vapi.cli("show interface features pg1")
6765 self.assertNotEqual(features.find('nat64-out2in'), -1)
6767 self.vapi.nat64_add_del_interface(self.pg0.sw_if_index, is_add=0)
6768 self.vapi.nat64_add_del_interface(self.pg1.sw_if_index, is_add=0)
6770 interfaces = self.vapi.nat64_interface_dump()
6771 self.assertEqual(len(interfaces), 0)
6773 def test_static_bib(self):
6774 """ Add/delete static BIB entry """
6775 in_addr = socket.inet_pton(socket.AF_INET6,
6776 '2001:db8:85a3::8a2e:370:7334')
6777 out_addr = socket.inet_pton(socket.AF_INET, '10.1.1.3')
6780 proto = IP_PROTOS.tcp
6782 self.vapi.nat64_add_del_static_bib(in_addr,
6787 bib = self.vapi.nat64_bib_dump(IP_PROTOS.tcp)
6792 self.assertEqual(bibe.i_addr, in_addr)
6793 self.assertEqual(bibe.o_addr, out_addr)
6794 self.assertEqual(bibe.i_port, in_port)
6795 self.assertEqual(bibe.o_port, out_port)
6796 self.assertEqual(static_bib_num, 1)
6798 self.vapi.nat64_add_del_static_bib(in_addr,
6804 bib = self.vapi.nat64_bib_dump(IP_PROTOS.tcp)
6809 self.assertEqual(static_bib_num, 0)
6811 def test_set_timeouts(self):
6812 """ Set NAT64 timeouts """
6813 # verify default values
6814 timeouts = self.vapi.nat_get_timeouts()
6815 self.assertEqual(timeouts.udp, 300)
6816 self.assertEqual(timeouts.icmp, 60)
6817 self.assertEqual(timeouts.tcp_transitory, 240)
6818 self.assertEqual(timeouts.tcp_established, 7440)
6820 # set and verify custom values
6821 self.vapi.nat_set_timeouts(udp=200, icmp=30, tcp_transitory=250,
6822 tcp_established=7450)
6823 timeouts = self.vapi.nat_get_timeouts()
6824 self.assertEqual(timeouts.udp, 200)
6825 self.assertEqual(timeouts.icmp, 30)
6826 self.assertEqual(timeouts.tcp_transitory, 250)
6827 self.assertEqual(timeouts.tcp_established, 7450)
6829 def test_dynamic(self):
6830 """ NAT64 dynamic translation test """
6831 self.tcp_port_in = 6303
6832 self.udp_port_in = 6304
6833 self.icmp_id_in = 6305
6835 ses_num_start = self.nat64_get_ses_num()
6837 self.vapi.nat64_add_del_pool_addr_range(self.nat_addr_n,
6839 self.vapi.nat64_add_del_interface(self.pg0.sw_if_index)
6840 self.vapi.nat64_add_del_interface(self.pg1.sw_if_index, is_inside=0)
6843 pkts = self.create_stream_in_ip6(self.pg0, self.pg1)
6844 self.pg0.add_stream(pkts)
6845 self.pg_enable_capture(self.pg_interfaces)
6847 capture = self.pg1.get_capture(len(pkts))
6848 self.verify_capture_out(capture, nat_ip=self.nat_addr,
6849 dst_ip=self.pg1.remote_ip4)
6852 pkts = self.create_stream_out(self.pg1, dst_ip=self.nat_addr)
6853 self.pg1.add_stream(pkts)
6854 self.pg_enable_capture(self.pg_interfaces)
6856 capture = self.pg0.get_capture(len(pkts))
6857 ip = IPv6(src=''.join(['64:ff9b::', self.pg1.remote_ip4]))
6858 self.verify_capture_in_ip6(capture, ip[IPv6].src, self.pg0.remote_ip6)
6861 pkts = self.create_stream_in_ip6(self.pg0, self.pg1)
6862 self.pg0.add_stream(pkts)
6863 self.pg_enable_capture(self.pg_interfaces)
6865 capture = self.pg1.get_capture(len(pkts))
6866 self.verify_capture_out(capture, nat_ip=self.nat_addr,
6867 dst_ip=self.pg1.remote_ip4)
6870 pkts = self.create_stream_out(self.pg1, dst_ip=self.nat_addr)
6871 self.pg1.add_stream(pkts)
6872 self.pg_enable_capture(self.pg_interfaces)
6874 capture = self.pg0.get_capture(len(pkts))
6875 self.verify_capture_in_ip6(capture, ip[IPv6].src, self.pg0.remote_ip6)
6877 ses_num_end = self.nat64_get_ses_num()
6879 self.assertEqual(ses_num_end - ses_num_start, 3)
6881 # tenant with specific VRF
6882 self.vapi.nat64_add_del_pool_addr_range(self.vrf1_nat_addr_n,
6883 self.vrf1_nat_addr_n,
6884 vrf_id=self.vrf1_id)
6885 self.vapi.nat64_add_del_interface(self.pg2.sw_if_index)
6887 pkts = self.create_stream_in_ip6(self.pg2, self.pg1)
6888 self.pg2.add_stream(pkts)
6889 self.pg_enable_capture(self.pg_interfaces)
6891 capture = self.pg1.get_capture(len(pkts))
6892 self.verify_capture_out(capture, nat_ip=self.vrf1_nat_addr,
6893 dst_ip=self.pg1.remote_ip4)
6895 pkts = self.create_stream_out(self.pg1, dst_ip=self.vrf1_nat_addr)
6896 self.pg1.add_stream(pkts)
6897 self.pg_enable_capture(self.pg_interfaces)
6899 capture = self.pg2.get_capture(len(pkts))
6900 self.verify_capture_in_ip6(capture, ip[IPv6].src, self.pg2.remote_ip6)
6902 def test_static(self):
6903 """ NAT64 static translation test """
6904 self.tcp_port_in = 60303
6905 self.udp_port_in = 60304
6906 self.icmp_id_in = 60305
6907 self.tcp_port_out = 60303
6908 self.udp_port_out = 60304
6909 self.icmp_id_out = 60305
6911 ses_num_start = self.nat64_get_ses_num()
6913 self.vapi.nat64_add_del_pool_addr_range(self.nat_addr_n,
6915 self.vapi.nat64_add_del_interface(self.pg0.sw_if_index)
6916 self.vapi.nat64_add_del_interface(self.pg1.sw_if_index, is_inside=0)
6918 self.vapi.nat64_add_del_static_bib(self.pg0.remote_ip6n,
6923 self.vapi.nat64_add_del_static_bib(self.pg0.remote_ip6n,
6928 self.vapi.nat64_add_del_static_bib(self.pg0.remote_ip6n,
6935 pkts = self.create_stream_in_ip6(self.pg0, self.pg1)
6936 self.pg0.add_stream(pkts)
6937 self.pg_enable_capture(self.pg_interfaces)
6939 capture = self.pg1.get_capture(len(pkts))
6940 self.verify_capture_out(capture, nat_ip=self.nat_addr,
6941 dst_ip=self.pg1.remote_ip4, same_port=True)
6944 pkts = self.create_stream_out(self.pg1, dst_ip=self.nat_addr)
6945 self.pg1.add_stream(pkts)
6946 self.pg_enable_capture(self.pg_interfaces)
6948 capture = self.pg0.get_capture(len(pkts))
6949 ip = IPv6(src=''.join(['64:ff9b::', self.pg1.remote_ip4]))
6950 self.verify_capture_in_ip6(capture, ip[IPv6].src, self.pg0.remote_ip6)
6952 ses_num_end = self.nat64_get_ses_num()
6954 self.assertEqual(ses_num_end - ses_num_start, 3)
6956 @unittest.skipUnless(running_extended_tests(), "part of extended tests")
6957 def test_session_timeout(self):
6958 """ NAT64 session timeout """
6959 self.icmp_id_in = 1234
6960 self.vapi.nat64_add_del_pool_addr_range(self.nat_addr_n,
6962 self.vapi.nat64_add_del_interface(self.pg0.sw_if_index)
6963 self.vapi.nat64_add_del_interface(self.pg1.sw_if_index, is_inside=0)
6964 self.vapi.nat_set_timeouts(icmp=5, tcp_transitory=5, tcp_established=5)
6966 pkts = self.create_stream_in_ip6(self.pg0, self.pg1)
6967 self.pg0.add_stream(pkts)
6968 self.pg_enable_capture(self.pg_interfaces)
6970 capture = self.pg1.get_capture(len(pkts))
6972 ses_num_before_timeout = self.nat64_get_ses_num()
6976 # ICMP and TCP session after timeout
6977 ses_num_after_timeout = self.nat64_get_ses_num()
6978 self.assertEqual(ses_num_before_timeout - ses_num_after_timeout, 2)
6980 def test_icmp_error(self):
6981 """ NAT64 ICMP Error message translation """
6982 self.tcp_port_in = 6303
6983 self.udp_port_in = 6304
6984 self.icmp_id_in = 6305
6986 self.vapi.nat64_add_del_pool_addr_range(self.nat_addr_n,
6988 self.vapi.nat64_add_del_interface(self.pg0.sw_if_index)
6989 self.vapi.nat64_add_del_interface(self.pg1.sw_if_index, is_inside=0)
6991 # send some packets to create sessions
6992 pkts = self.create_stream_in_ip6(self.pg0, self.pg1)
6993 self.pg0.add_stream(pkts)
6994 self.pg_enable_capture(self.pg_interfaces)
6996 capture_ip4 = self.pg1.get_capture(len(pkts))
6997 self.verify_capture_out(capture_ip4,
6998 nat_ip=self.nat_addr,
6999 dst_ip=self.pg1.remote_ip4)
7001 pkts = self.create_stream_out(self.pg1, dst_ip=self.nat_addr)
7002 self.pg1.add_stream(pkts)
7003 self.pg_enable_capture(self.pg_interfaces)
7005 capture_ip6 = self.pg0.get_capture(len(pkts))
7006 ip = IPv6(src=''.join(['64:ff9b::', self.pg1.remote_ip4]))
7007 self.verify_capture_in_ip6(capture_ip6, ip[IPv6].src,
7008 self.pg0.remote_ip6)
7011 pkts = [Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
7012 IPv6(src=self.pg0.remote_ip6, dst=ip[IPv6].src) /
7013 ICMPv6DestUnreach(code=1) /
7014 packet[IPv6] for packet in capture_ip6]
7015 self.pg0.add_stream(pkts)
7016 self.pg_enable_capture(self.pg_interfaces)
7018 capture = self.pg1.get_capture(len(pkts))
7019 for packet in capture:
7021 self.assertEqual(packet[IP].src, self.nat_addr)
7022 self.assertEqual(packet[IP].dst, self.pg1.remote_ip4)
7023 self.assertEqual(packet[ICMP].type, 3)
7024 self.assertEqual(packet[ICMP].code, 13)
7025 inner = packet[IPerror]
7026 self.assertEqual(inner.src, self.pg1.remote_ip4)
7027 self.assertEqual(inner.dst, self.nat_addr)
7028 self.assert_packet_checksums_valid(packet)
7029 if inner.haslayer(TCPerror):
7030 self.assertEqual(inner[TCPerror].dport, self.tcp_port_out)
7031 elif inner.haslayer(UDPerror):
7032 self.assertEqual(inner[UDPerror].dport, self.udp_port_out)
7034 self.assertEqual(inner[ICMPerror].id, self.icmp_id_out)
7036 self.logger.error(ppp("Unexpected or invalid packet:", packet))
7040 pkts = [Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
7041 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
7042 ICMP(type=3, code=13) /
7043 packet[IP] for packet in capture_ip4]
7044 self.pg1.add_stream(pkts)
7045 self.pg_enable_capture(self.pg_interfaces)
7047 capture = self.pg0.get_capture(len(pkts))
7048 for packet in capture:
7050 self.assertEqual(packet[IPv6].src, ip.src)
7051 self.assertEqual(packet[IPv6].dst, self.pg0.remote_ip6)
7052 icmp = packet[ICMPv6DestUnreach]
7053 self.assertEqual(icmp.code, 1)
7054 inner = icmp[IPerror6]
7055 self.assertEqual(inner.src, self.pg0.remote_ip6)
7056 self.assertEqual(inner.dst, ip.src)
7057 self.assert_icmpv6_checksum_valid(packet)
7058 if inner.haslayer(TCPerror):
7059 self.assertEqual(inner[TCPerror].sport, self.tcp_port_in)
7060 elif inner.haslayer(UDPerror):
7061 self.assertEqual(inner[UDPerror].sport, self.udp_port_in)
7063 self.assertEqual(inner[ICMPv6EchoRequest].id,
7066 self.logger.error(ppp("Unexpected or invalid packet:", packet))
7069 def test_hairpinning(self):
7070 """ NAT64 hairpinning """
7072 client = self.pg0.remote_hosts[0]
7073 server = self.pg0.remote_hosts[1]
7074 server_tcp_in_port = 22
7075 server_tcp_out_port = 4022
7076 server_udp_in_port = 23
7077 server_udp_out_port = 4023
7078 client_tcp_in_port = 1234
7079 client_udp_in_port = 1235
7080 client_tcp_out_port = 0
7081 client_udp_out_port = 0
7082 ip = IPv6(src=''.join(['64:ff9b::', self.nat_addr]))
7083 nat_addr_ip6 = ip.src
7085 self.vapi.nat64_add_del_pool_addr_range(self.nat_addr_n,
7087 self.vapi.nat64_add_del_interface(self.pg0.sw_if_index)
7088 self.vapi.nat64_add_del_interface(self.pg1.sw_if_index, is_inside=0)
7090 self.vapi.nat64_add_del_static_bib(server.ip6n,
7093 server_tcp_out_port,
7095 self.vapi.nat64_add_del_static_bib(server.ip6n,
7098 server_udp_out_port,
7103 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
7104 IPv6(src=client.ip6, dst=nat_addr_ip6) /
7105 TCP(sport=client_tcp_in_port, dport=server_tcp_out_port))
7107 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
7108 IPv6(src=client.ip6, dst=nat_addr_ip6) /
7109 UDP(sport=client_udp_in_port, dport=server_udp_out_port))
7111 self.pg0.add_stream(pkts)
7112 self.pg_enable_capture(self.pg_interfaces)
7114 capture = self.pg0.get_capture(len(pkts))
7115 for packet in capture:
7117 self.assertEqual(packet[IPv6].src, nat_addr_ip6)
7118 self.assertEqual(packet[IPv6].dst, server.ip6)
7119 self.assert_packet_checksums_valid(packet)
7120 if packet.haslayer(TCP):
7121 self.assertNotEqual(packet[TCP].sport, client_tcp_in_port)
7122 self.assertEqual(packet[TCP].dport, server_tcp_in_port)
7123 client_tcp_out_port = packet[TCP].sport
7125 self.assertNotEqual(packet[UDP].sport, client_udp_in_port)
7126 self.assertEqual(packet[UDP].dport, server_udp_in_port)
7127 client_udp_out_port = packet[UDP].sport
7129 self.logger.error(ppp("Unexpected or invalid packet:", packet))
7134 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
7135 IPv6(src=server.ip6, dst=nat_addr_ip6) /
7136 TCP(sport=server_tcp_in_port, dport=client_tcp_out_port))
7138 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
7139 IPv6(src=server.ip6, dst=nat_addr_ip6) /
7140 UDP(sport=server_udp_in_port, dport=client_udp_out_port))
7142 self.pg0.add_stream(pkts)
7143 self.pg_enable_capture(self.pg_interfaces)
7145 capture = self.pg0.get_capture(len(pkts))
7146 for packet in capture:
7148 self.assertEqual(packet[IPv6].src, nat_addr_ip6)
7149 self.assertEqual(packet[IPv6].dst, client.ip6)
7150 self.assert_packet_checksums_valid(packet)
7151 if packet.haslayer(TCP):
7152 self.assertEqual(packet[TCP].sport, server_tcp_out_port)
7153 self.assertEqual(packet[TCP].dport, client_tcp_in_port)
7155 self.assertEqual(packet[UDP].sport, server_udp_out_port)
7156 self.assertEqual(packet[UDP].dport, client_udp_in_port)
7158 self.logger.error(ppp("Unexpected or invalid packet:", packet))
7163 pkts = [Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
7164 IPv6(src=client.ip6, dst=nat_addr_ip6) /
7165 ICMPv6DestUnreach(code=1) /
7166 packet[IPv6] for packet in capture]
7167 self.pg0.add_stream(pkts)
7168 self.pg_enable_capture(self.pg_interfaces)
7170 capture = self.pg0.get_capture(len(pkts))
7171 for packet in capture:
7173 self.assertEqual(packet[IPv6].src, nat_addr_ip6)
7174 self.assertEqual(packet[IPv6].dst, server.ip6)
7175 icmp = packet[ICMPv6DestUnreach]
7176 self.assertEqual(icmp.code, 1)
7177 inner = icmp[IPerror6]
7178 self.assertEqual(inner.src, server.ip6)
7179 self.assertEqual(inner.dst, nat_addr_ip6)
7180 self.assert_packet_checksums_valid(packet)
7181 if inner.haslayer(TCPerror):
7182 self.assertEqual(inner[TCPerror].sport, server_tcp_in_port)
7183 self.assertEqual(inner[TCPerror].dport,
7184 client_tcp_out_port)
7186 self.assertEqual(inner[UDPerror].sport, server_udp_in_port)
7187 self.assertEqual(inner[UDPerror].dport,
7188 client_udp_out_port)
7190 self.logger.error(ppp("Unexpected or invalid packet:", packet))
7193 def test_prefix(self):
7194 """ NAT64 Network-Specific Prefix """
7196 self.vapi.nat64_add_del_pool_addr_range(self.nat_addr_n,
7198 self.vapi.nat64_add_del_interface(self.pg0.sw_if_index)
7199 self.vapi.nat64_add_del_interface(self.pg1.sw_if_index, is_inside=0)
7200 self.vapi.nat64_add_del_pool_addr_range(self.vrf1_nat_addr_n,
7201 self.vrf1_nat_addr_n,
7202 vrf_id=self.vrf1_id)
7203 self.vapi.nat64_add_del_interface(self.pg2.sw_if_index)
7206 global_pref64 = "2001:db8::"
7207 global_pref64_n = socket.inet_pton(socket.AF_INET6, global_pref64)
7208 global_pref64_len = 32
7209 self.vapi.nat64_add_del_prefix(global_pref64_n, global_pref64_len)
7211 prefix = self.vapi.nat64_prefix_dump()
7212 self.assertEqual(len(prefix), 1)
7213 self.assertEqual(prefix[0].prefix, global_pref64_n)
7214 self.assertEqual(prefix[0].prefix_len, global_pref64_len)
7215 self.assertEqual(prefix[0].vrf_id, 0)
7217 # Add tenant specific prefix
7218 vrf1_pref64 = "2001:db8:122:300::"
7219 vrf1_pref64_n = socket.inet_pton(socket.AF_INET6, vrf1_pref64)
7220 vrf1_pref64_len = 56
7221 self.vapi.nat64_add_del_prefix(vrf1_pref64_n,
7223 vrf_id=self.vrf1_id)
7224 prefix = self.vapi.nat64_prefix_dump()
7225 self.assertEqual(len(prefix), 2)
7228 pkts = self.create_stream_in_ip6(self.pg0,
7231 plen=global_pref64_len)
7232 self.pg0.add_stream(pkts)
7233 self.pg_enable_capture(self.pg_interfaces)
7235 capture = self.pg1.get_capture(len(pkts))
7236 self.verify_capture_out(capture, nat_ip=self.nat_addr,
7237 dst_ip=self.pg1.remote_ip4)
7239 pkts = self.create_stream_out(self.pg1, dst_ip=self.nat_addr)
7240 self.pg1.add_stream(pkts)
7241 self.pg_enable_capture(self.pg_interfaces)
7243 capture = self.pg0.get_capture(len(pkts))
7244 dst_ip = self.compose_ip6(self.pg1.remote_ip4,
7247 self.verify_capture_in_ip6(capture, dst_ip, self.pg0.remote_ip6)
7249 # Tenant specific prefix
7250 pkts = self.create_stream_in_ip6(self.pg2,
7253 plen=vrf1_pref64_len)
7254 self.pg2.add_stream(pkts)
7255 self.pg_enable_capture(self.pg_interfaces)
7257 capture = self.pg1.get_capture(len(pkts))
7258 self.verify_capture_out(capture, nat_ip=self.vrf1_nat_addr,
7259 dst_ip=self.pg1.remote_ip4)
7261 pkts = self.create_stream_out(self.pg1, dst_ip=self.vrf1_nat_addr)
7262 self.pg1.add_stream(pkts)
7263 self.pg_enable_capture(self.pg_interfaces)
7265 capture = self.pg2.get_capture(len(pkts))
7266 dst_ip = self.compose_ip6(self.pg1.remote_ip4,
7269 self.verify_capture_in_ip6(capture, dst_ip, self.pg2.remote_ip6)
7271 def test_unknown_proto(self):
7272 """ NAT64 translate packet with unknown protocol """
7274 self.vapi.nat64_add_del_pool_addr_range(self.nat_addr_n,
7276 self.vapi.nat64_add_del_interface(self.pg0.sw_if_index)
7277 self.vapi.nat64_add_del_interface(self.pg1.sw_if_index, is_inside=0)
7278 remote_ip6 = self.compose_ip6(self.pg1.remote_ip4, '64:ff9b::', 96)
7281 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
7282 IPv6(src=self.pg0.remote_ip6, dst=remote_ip6) /
7283 TCP(sport=self.tcp_port_in, dport=20))
7284 self.pg0.add_stream(p)
7285 self.pg_enable_capture(self.pg_interfaces)
7287 p = self.pg1.get_capture(1)
7289 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
7290 IPv6(src=self.pg0.remote_ip6, dst=remote_ip6, nh=47) /
7292 IP(src=self.pg2.local_ip4, dst=self.pg2.remote_ip4) /
7293 TCP(sport=1234, dport=1234))
7294 self.pg0.add_stream(p)
7295 self.pg_enable_capture(self.pg_interfaces)
7297 p = self.pg1.get_capture(1)
7300 self.assertEqual(packet[IP].src, self.nat_addr)
7301 self.assertEqual(packet[IP].dst, self.pg1.remote_ip4)
7302 self.assertEqual(packet.haslayer(GRE), 1)
7303 self.assert_packet_checksums_valid(packet)
7305 self.logger.error(ppp("Unexpected or invalid packet:", packet))
7309 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
7310 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
7312 IP(src=self.pg2.remote_ip4, dst=self.pg2.local_ip4) /
7313 TCP(sport=1234, dport=1234))
7314 self.pg1.add_stream(p)
7315 self.pg_enable_capture(self.pg_interfaces)
7317 p = self.pg0.get_capture(1)
7320 self.assertEqual(packet[IPv6].src, remote_ip6)
7321 self.assertEqual(packet[IPv6].dst, self.pg0.remote_ip6)
7322 self.assertEqual(packet[IPv6].nh, 47)
7324 self.logger.error(ppp("Unexpected or invalid packet:", packet))
7327 def test_hairpinning_unknown_proto(self):
7328 """ NAT64 translate packet with unknown protocol - hairpinning """
7330 client = self.pg0.remote_hosts[0]
7331 server = self.pg0.remote_hosts[1]
7332 server_tcp_in_port = 22
7333 server_tcp_out_port = 4022
7334 client_tcp_in_port = 1234
7335 client_tcp_out_port = 1235
7336 server_nat_ip = "10.0.0.100"
7337 client_nat_ip = "10.0.0.110"
7338 server_nat_ip_n = socket.inet_pton(socket.AF_INET, server_nat_ip)
7339 client_nat_ip_n = socket.inet_pton(socket.AF_INET, client_nat_ip)
7340 server_nat_ip6 = self.compose_ip6(server_nat_ip, '64:ff9b::', 96)
7341 client_nat_ip6 = self.compose_ip6(client_nat_ip, '64:ff9b::', 96)
7343 self.vapi.nat64_add_del_pool_addr_range(server_nat_ip_n,
7345 self.vapi.nat64_add_del_interface(self.pg0.sw_if_index)
7346 self.vapi.nat64_add_del_interface(self.pg1.sw_if_index, is_inside=0)
7348 self.vapi.nat64_add_del_static_bib(server.ip6n,
7351 server_tcp_out_port,
7354 self.vapi.nat64_add_del_static_bib(server.ip6n,
7360 self.vapi.nat64_add_del_static_bib(client.ip6n,
7363 client_tcp_out_port,
7367 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
7368 IPv6(src=client.ip6, dst=server_nat_ip6) /
7369 TCP(sport=client_tcp_in_port, dport=server_tcp_out_port))
7370 self.pg0.add_stream(p)
7371 self.pg_enable_capture(self.pg_interfaces)
7373 p = self.pg0.get_capture(1)
7375 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
7376 IPv6(src=client.ip6, dst=server_nat_ip6, nh=IP_PROTOS.gre) /
7378 IP(src=self.pg2.local_ip4, dst=self.pg2.remote_ip4) /
7379 TCP(sport=1234, dport=1234))
7380 self.pg0.add_stream(p)
7381 self.pg_enable_capture(self.pg_interfaces)
7383 p = self.pg0.get_capture(1)
7386 self.assertEqual(packet[IPv6].src, client_nat_ip6)
7387 self.assertEqual(packet[IPv6].dst, server.ip6)
7388 self.assertEqual(packet[IPv6].nh, IP_PROTOS.gre)
7390 self.logger.error(ppp("Unexpected or invalid packet:", packet))
7394 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
7395 IPv6(src=server.ip6, dst=client_nat_ip6, nh=IP_PROTOS.gre) /
7397 IP(src=self.pg2.remote_ip4, dst=self.pg2.local_ip4) /
7398 TCP(sport=1234, dport=1234))
7399 self.pg0.add_stream(p)
7400 self.pg_enable_capture(self.pg_interfaces)
7402 p = self.pg0.get_capture(1)
7405 self.assertEqual(packet[IPv6].src, server_nat_ip6)
7406 self.assertEqual(packet[IPv6].dst, client.ip6)
7407 self.assertEqual(packet[IPv6].nh, IP_PROTOS.gre)
7409 self.logger.error(ppp("Unexpected or invalid packet:", packet))
7412 def test_one_armed_nat64(self):
7413 """ One armed NAT64 """
7415 remote_host_ip6 = self.compose_ip6(self.pg3.remote_ip4,
7419 self.vapi.nat64_add_del_pool_addr_range(self.nat_addr_n,
7421 self.vapi.nat64_add_del_interface(self.pg3.sw_if_index)
7422 self.vapi.nat64_add_del_interface(self.pg3.sw_if_index, is_inside=0)
7425 p = (Ether(src=self.pg3.remote_mac, dst=self.pg3.local_mac) /
7426 IPv6(src=self.pg3.remote_ip6, dst=remote_host_ip6) /
7427 TCP(sport=12345, dport=80))
7428 self.pg3.add_stream(p)
7429 self.pg_enable_capture(self.pg_interfaces)
7431 capture = self.pg3.get_capture(1)
7436 self.assertEqual(ip.src, self.nat_addr)
7437 self.assertEqual(ip.dst, self.pg3.remote_ip4)
7438 self.assertNotEqual(tcp.sport, 12345)
7439 external_port = tcp.sport
7440 self.assertEqual(tcp.dport, 80)
7441 self.assert_packet_checksums_valid(p)
7443 self.logger.error(ppp("Unexpected or invalid packet:", p))
7447 p = (Ether(src=self.pg3.remote_mac, dst=self.pg3.local_mac) /
7448 IP(src=self.pg3.remote_ip4, dst=self.nat_addr) /
7449 TCP(sport=80, dport=external_port))
7450 self.pg3.add_stream(p)
7451 self.pg_enable_capture(self.pg_interfaces)
7453 capture = self.pg3.get_capture(1)
7458 self.assertEqual(ip.src, remote_host_ip6)
7459 self.assertEqual(ip.dst, self.pg3.remote_ip6)
7460 self.assertEqual(tcp.sport, 80)
7461 self.assertEqual(tcp.dport, 12345)
7462 self.assert_packet_checksums_valid(p)
7464 self.logger.error(ppp("Unexpected or invalid packet:", p))
7467 def test_frag_in_order(self):
7468 """ NAT64 translate fragments arriving in order """
7469 self.tcp_port_in = random.randint(1025, 65535)
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)
7476 reass = self.vapi.nat_reass_dump()
7477 reass_n_start = len(reass)
7481 pkts = self.create_stream_frag_ip6(self.pg0, self.pg1.remote_ip4,
7482 self.tcp_port_in, 20, data)
7483 self.pg0.add_stream(pkts)
7484 self.pg_enable_capture(self.pg_interfaces)
7486 frags = self.pg1.get_capture(len(pkts))
7487 p = self.reass_frags_and_verify(frags,
7489 self.pg1.remote_ip4)
7490 self.assertEqual(p[TCP].dport, 20)
7491 self.assertNotEqual(p[TCP].sport, self.tcp_port_in)
7492 self.tcp_port_out = p[TCP].sport
7493 self.assertEqual(data, p[Raw].load)
7496 data = "A" * 4 + "b" * 16 + "C" * 3
7497 pkts = self.create_stream_frag(self.pg1,
7502 self.pg1.add_stream(pkts)
7503 self.pg_enable_capture(self.pg_interfaces)
7505 frags = self.pg0.get_capture(len(pkts))
7506 src = self.compose_ip6(self.pg1.remote_ip4, '64:ff9b::', 96)
7507 p = self.reass_frags_and_verify_ip6(frags, src, self.pg0.remote_ip6)
7508 self.assertEqual(p[TCP].sport, 20)
7509 self.assertEqual(p[TCP].dport, self.tcp_port_in)
7510 self.assertEqual(data, p[Raw].load)
7512 reass = self.vapi.nat_reass_dump()
7513 reass_n_end = len(reass)
7515 self.assertEqual(reass_n_end - reass_n_start, 2)
7517 def test_reass_hairpinning(self):
7518 """ NAT64 fragments hairpinning """
7520 server = self.pg0.remote_hosts[1]
7521 server_in_port = random.randint(1025, 65535)
7522 server_out_port = random.randint(1025, 65535)
7523 client_in_port = random.randint(1025, 65535)
7524 ip = IPv6(src=''.join(['64:ff9b::', self.nat_addr]))
7525 nat_addr_ip6 = ip.src
7527 self.vapi.nat64_add_del_pool_addr_range(self.nat_addr_n,
7529 self.vapi.nat64_add_del_interface(self.pg0.sw_if_index)
7530 self.vapi.nat64_add_del_interface(self.pg1.sw_if_index, is_inside=0)
7532 # add static BIB entry for server
7533 self.vapi.nat64_add_del_static_bib(server.ip6n,
7539 # send packet from host to server
7540 pkts = self.create_stream_frag_ip6(self.pg0,
7545 self.pg0.add_stream(pkts)
7546 self.pg_enable_capture(self.pg_interfaces)
7548 frags = self.pg0.get_capture(len(pkts))
7549 p = self.reass_frags_and_verify_ip6(frags, nat_addr_ip6, server.ip6)
7550 self.assertNotEqual(p[TCP].sport, client_in_port)
7551 self.assertEqual(p[TCP].dport, server_in_port)
7552 self.assertEqual(data, p[Raw].load)
7554 def test_frag_out_of_order(self):
7555 """ NAT64 translate fragments arriving out of order """
7556 self.tcp_port_in = random.randint(1025, 65535)
7558 self.vapi.nat64_add_del_pool_addr_range(self.nat_addr_n,
7560 self.vapi.nat64_add_del_interface(self.pg0.sw_if_index)
7561 self.vapi.nat64_add_del_interface(self.pg1.sw_if_index, is_inside=0)
7565 pkts = self.create_stream_frag_ip6(self.pg0, self.pg1.remote_ip4,
7566 self.tcp_port_in, 20, data)
7568 self.pg0.add_stream(pkts)
7569 self.pg_enable_capture(self.pg_interfaces)
7571 frags = self.pg1.get_capture(len(pkts))
7572 p = self.reass_frags_and_verify(frags,
7574 self.pg1.remote_ip4)
7575 self.assertEqual(p[TCP].dport, 20)
7576 self.assertNotEqual(p[TCP].sport, self.tcp_port_in)
7577 self.tcp_port_out = p[TCP].sport
7578 self.assertEqual(data, p[Raw].load)
7581 data = "A" * 4 + "B" * 16 + "C" * 3
7582 pkts = self.create_stream_frag(self.pg1,
7588 self.pg1.add_stream(pkts)
7589 self.pg_enable_capture(self.pg_interfaces)
7591 frags = self.pg0.get_capture(len(pkts))
7592 src = self.compose_ip6(self.pg1.remote_ip4, '64:ff9b::', 96)
7593 p = self.reass_frags_and_verify_ip6(frags, src, self.pg0.remote_ip6)
7594 self.assertEqual(p[TCP].sport, 20)
7595 self.assertEqual(p[TCP].dport, self.tcp_port_in)
7596 self.assertEqual(data, p[Raw].load)
7598 def test_interface_addr(self):
7599 """ Acquire NAT64 pool addresses from interface """
7600 self.vapi.nat64_add_interface_addr(self.pg4.sw_if_index)
7602 # no address in NAT64 pool
7603 adresses = self.vapi.nat44_address_dump()
7604 self.assertEqual(0, len(adresses))
7606 # configure interface address and check NAT64 address pool
7607 self.pg4.config_ip4()
7608 addresses = self.vapi.nat64_pool_addr_dump()
7609 self.assertEqual(len(addresses), 1)
7610 self.assertEqual(addresses[0].address, self.pg4.local_ip4n)
7612 # remove interface address and check NAT64 address pool
7613 self.pg4.unconfig_ip4()
7614 addresses = self.vapi.nat64_pool_addr_dump()
7615 self.assertEqual(0, len(adresses))
7617 @unittest.skipUnless(running_extended_tests(), "part of extended tests")
7618 def test_ipfix_max_bibs_sessions(self):
7619 """ IPFIX logging maximum session and BIB entries exceeded """
7622 remote_host_ip6 = self.compose_ip6(self.pg1.remote_ip4,
7626 self.vapi.nat64_add_del_pool_addr_range(self.nat_addr_n,
7628 self.vapi.nat64_add_del_interface(self.pg0.sw_if_index)
7629 self.vapi.nat64_add_del_interface(self.pg1.sw_if_index, is_inside=0)
7633 for i in range(0, max_bibs):
7634 src = "fd01:aa::%x" % (i)
7635 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
7636 IPv6(src=src, dst=remote_host_ip6) /
7637 TCP(sport=12345, dport=80))
7639 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
7640 IPv6(src=src, dst=remote_host_ip6) /
7641 TCP(sport=12345, dport=22))
7643 self.pg0.add_stream(pkts)
7644 self.pg_enable_capture(self.pg_interfaces)
7646 self.pg1.get_capture(max_sessions)
7648 self.vapi.set_ipfix_exporter(collector_address=self.pg3.remote_ip4n,
7649 src_address=self.pg3.local_ip4n,
7651 template_interval=10)
7652 self.vapi.nat_ipfix(domain_id=self.ipfix_domain_id,
7653 src_port=self.ipfix_src_port)
7655 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
7656 IPv6(src=src, dst=remote_host_ip6) /
7657 TCP(sport=12345, dport=25))
7658 self.pg0.add_stream(p)
7659 self.pg_enable_capture(self.pg_interfaces)
7661 self.pg1.assert_nothing_captured()
7663 self.vapi.cli("ipfix flush") # FIXME this should be an API call
7664 capture = self.pg3.get_capture(9)
7665 ipfix = IPFIXDecoder()
7666 # first load template
7668 self.assertTrue(p.haslayer(IPFIX))
7669 self.assertEqual(p[IP].src, self.pg3.local_ip4)
7670 self.assertEqual(p[IP].dst, self.pg3.remote_ip4)
7671 self.assertEqual(p[UDP].sport, self.ipfix_src_port)
7672 self.assertEqual(p[UDP].dport, 4739)
7673 self.assertEqual(p[IPFIX].observationDomainID,
7674 self.ipfix_domain_id)
7675 if p.haslayer(Template):
7676 ipfix.add_template(p.getlayer(Template))
7677 # verify events in data set
7679 if p.haslayer(Data):
7680 data = ipfix.decode_data_set(p.getlayer(Set))
7681 self.verify_ipfix_max_sessions(data, max_sessions)
7683 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
7684 IPv6(src=self.pg0.remote_ip6, dst=remote_host_ip6) /
7685 TCP(sport=12345, dport=80))
7686 self.pg0.add_stream(p)
7687 self.pg_enable_capture(self.pg_interfaces)
7689 self.pg1.assert_nothing_captured()
7691 self.vapi.cli("ipfix flush") # FIXME this should be an API call
7692 capture = self.pg3.get_capture(1)
7693 # verify events in data set
7695 self.assertTrue(p.haslayer(IPFIX))
7696 self.assertEqual(p[IP].src, self.pg3.local_ip4)
7697 self.assertEqual(p[IP].dst, self.pg3.remote_ip4)
7698 self.assertEqual(p[UDP].sport, self.ipfix_src_port)
7699 self.assertEqual(p[UDP].dport, 4739)
7700 self.assertEqual(p[IPFIX].observationDomainID,
7701 self.ipfix_domain_id)
7702 if p.haslayer(Data):
7703 data = ipfix.decode_data_set(p.getlayer(Set))
7704 self.verify_ipfix_max_bibs(data, max_bibs)
7706 def test_ipfix_max_frags(self):
7707 """ IPFIX logging maximum fragments pending reassembly exceeded """
7708 self.vapi.nat64_add_del_pool_addr_range(self.nat_addr_n,
7710 self.vapi.nat64_add_del_interface(self.pg0.sw_if_index)
7711 self.vapi.nat64_add_del_interface(self.pg1.sw_if_index, is_inside=0)
7712 self.vapi.nat_set_reass(max_frag=1, is_ip6=1)
7713 self.vapi.set_ipfix_exporter(collector_address=self.pg3.remote_ip4n,
7714 src_address=self.pg3.local_ip4n,
7716 template_interval=10)
7717 self.vapi.nat_ipfix(domain_id=self.ipfix_domain_id,
7718 src_port=self.ipfix_src_port)
7721 pkts = self.create_stream_frag_ip6(self.pg0, self.pg1.remote_ip4,
7722 self.tcp_port_in, 20, data)
7724 self.pg0.add_stream(pkts)
7725 self.pg_enable_capture(self.pg_interfaces)
7727 self.pg1.assert_nothing_captured()
7729 self.vapi.cli("ipfix flush") # FIXME this should be an API call
7730 capture = self.pg3.get_capture(9)
7731 ipfix = IPFIXDecoder()
7732 # first load template
7734 self.assertTrue(p.haslayer(IPFIX))
7735 self.assertEqual(p[IP].src, self.pg3.local_ip4)
7736 self.assertEqual(p[IP].dst, self.pg3.remote_ip4)
7737 self.assertEqual(p[UDP].sport, self.ipfix_src_port)
7738 self.assertEqual(p[UDP].dport, 4739)
7739 self.assertEqual(p[IPFIX].observationDomainID,
7740 self.ipfix_domain_id)
7741 if p.haslayer(Template):
7742 ipfix.add_template(p.getlayer(Template))
7743 # verify events in data set
7745 if p.haslayer(Data):
7746 data = ipfix.decode_data_set(p.getlayer(Set))
7747 self.verify_ipfix_max_fragments_ip6(data, 1,
7748 self.pg0.remote_ip6n)
7750 def test_ipfix_bib_ses(self):
7751 """ IPFIX logging NAT64 BIB/session create and delete events """
7752 self.tcp_port_in = random.randint(1025, 65535)
7753 remote_host_ip6 = self.compose_ip6(self.pg1.remote_ip4,
7757 self.vapi.nat64_add_del_pool_addr_range(self.nat_addr_n,
7759 self.vapi.nat64_add_del_interface(self.pg0.sw_if_index)
7760 self.vapi.nat64_add_del_interface(self.pg1.sw_if_index, is_inside=0)
7761 self.vapi.set_ipfix_exporter(collector_address=self.pg3.remote_ip4n,
7762 src_address=self.pg3.local_ip4n,
7764 template_interval=10)
7765 self.vapi.nat_ipfix(domain_id=self.ipfix_domain_id,
7766 src_port=self.ipfix_src_port)
7769 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
7770 IPv6(src=self.pg0.remote_ip6, dst=remote_host_ip6) /
7771 TCP(sport=self.tcp_port_in, dport=25))
7772 self.pg0.add_stream(p)
7773 self.pg_enable_capture(self.pg_interfaces)
7775 p = self.pg1.get_capture(1)
7776 self.tcp_port_out = p[0][TCP].sport
7777 self.vapi.cli("ipfix flush") # FIXME this should be an API call
7778 capture = self.pg3.get_capture(10)
7779 ipfix = IPFIXDecoder()
7780 # first load template
7782 self.assertTrue(p.haslayer(IPFIX))
7783 self.assertEqual(p[IP].src, self.pg3.local_ip4)
7784 self.assertEqual(p[IP].dst, self.pg3.remote_ip4)
7785 self.assertEqual(p[UDP].sport, self.ipfix_src_port)
7786 self.assertEqual(p[UDP].dport, 4739)
7787 self.assertEqual(p[IPFIX].observationDomainID,
7788 self.ipfix_domain_id)
7789 if p.haslayer(Template):
7790 ipfix.add_template(p.getlayer(Template))
7791 # verify events in data set
7793 if p.haslayer(Data):
7794 data = ipfix.decode_data_set(p.getlayer(Set))
7795 if ord(data[0][230]) == 10:
7796 self.verify_ipfix_bib(data, 1, self.pg0.remote_ip6n)
7797 elif ord(data[0][230]) == 6:
7798 self.verify_ipfix_nat64_ses(data,
7800 self.pg0.remote_ip6n,
7801 self.pg1.remote_ip4,
7804 self.logger.error(ppp("Unexpected or invalid packet: ", p))
7807 self.pg_enable_capture(self.pg_interfaces)
7808 self.vapi.nat64_add_del_pool_addr_range(self.nat_addr_n,
7811 self.vapi.cli("ipfix flush") # FIXME this should be an API call
7812 capture = self.pg3.get_capture(2)
7813 # verify events in data set
7815 self.assertTrue(p.haslayer(IPFIX))
7816 self.assertEqual(p[IP].src, self.pg3.local_ip4)
7817 self.assertEqual(p[IP].dst, self.pg3.remote_ip4)
7818 self.assertEqual(p[UDP].sport, self.ipfix_src_port)
7819 self.assertEqual(p[UDP].dport, 4739)
7820 self.assertEqual(p[IPFIX].observationDomainID,
7821 self.ipfix_domain_id)
7822 if p.haslayer(Data):
7823 data = ipfix.decode_data_set(p.getlayer(Set))
7824 if ord(data[0][230]) == 11:
7825 self.verify_ipfix_bib(data, 0, self.pg0.remote_ip6n)
7826 elif ord(data[0][230]) == 7:
7827 self.verify_ipfix_nat64_ses(data,
7829 self.pg0.remote_ip6n,
7830 self.pg1.remote_ip4,
7833 self.logger.error(ppp("Unexpected or invalid packet: ", p))
7835 def test_syslog_sess(self):
7836 """ Test syslog session creation and deletion """
7837 self.tcp_port_in = random.randint(1025, 65535)
7838 remote_host_ip6 = self.compose_ip6(self.pg1.remote_ip4,
7842 self.vapi.nat64_add_del_pool_addr_range(self.nat_addr_n,
7844 self.vapi.nat64_add_del_interface(self.pg0.sw_if_index)
7845 self.vapi.nat64_add_del_interface(self.pg1.sw_if_index, is_inside=0)
7846 self.vapi.syslog_set_filter(SYSLOG_SEVERITY.INFO)
7847 self.vapi.syslog_set_sender(self.pg3.remote_ip4n, self.pg3.local_ip4n)
7849 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
7850 IPv6(src=self.pg0.remote_ip6, dst=remote_host_ip6) /
7851 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port))
7852 self.pg0.add_stream(p)
7853 self.pg_enable_capture(self.pg_interfaces)
7855 p = self.pg1.get_capture(1)
7856 self.tcp_port_out = p[0][TCP].sport
7857 capture = self.pg3.get_capture(1)
7858 self.verify_syslog_sess(capture[0][Raw].load, is_ip6=True)
7860 self.pg_enable_capture(self.pg_interfaces)
7862 self.vapi.nat64_add_del_pool_addr_range(self.nat_addr_n,
7865 capture = self.pg3.get_capture(1)
7866 self.verify_syslog_sess(capture[0][Raw].load, False, True)
7868 def nat64_get_ses_num(self):
7870 Return number of active NAT64 sessions.
7872 st = self.vapi.nat64_st_dump()
7875 def clear_nat64(self):
7877 Clear NAT64 configuration.
7879 self.vapi.nat_ipfix(enable=0, src_port=self.ipfix_src_port,
7880 domain_id=self.ipfix_domain_id)
7881 self.ipfix_src_port = 4739
7882 self.ipfix_domain_id = 1
7884 self.vapi.syslog_set_filter(SYSLOG_SEVERITY.EMERG)
7886 self.vapi.nat_set_timeouts()
7888 interfaces = self.vapi.nat64_interface_dump()
7889 for intf in interfaces:
7890 if intf.is_inside > 1:
7891 self.vapi.nat64_add_del_interface(intf.sw_if_index,
7894 self.vapi.nat64_add_del_interface(intf.sw_if_index,
7898 bib = self.vapi.nat64_bib_dump(255)
7901 self.vapi.nat64_add_del_static_bib(bibe.i_addr,
7909 adresses = self.vapi.nat64_pool_addr_dump()
7910 for addr in adresses:
7911 self.vapi.nat64_add_del_pool_addr_range(addr.address,
7916 prefixes = self.vapi.nat64_prefix_dump()
7917 for prefix in prefixes:
7918 self.vapi.nat64_add_del_prefix(prefix.prefix,
7920 vrf_id=prefix.vrf_id,
7924 super(TestNAT64, self).tearDown()
7925 if not self.vpp_dead:
7926 self.logger.info(self.vapi.cli("show nat64 pool"))
7927 self.logger.info(self.vapi.cli("show nat64 interfaces"))
7928 self.logger.info(self.vapi.cli("show nat64 prefix"))
7929 self.logger.info(self.vapi.cli("show nat64 bib all"))
7930 self.logger.info(self.vapi.cli("show nat64 session table all"))
7931 self.logger.info(self.vapi.cli("show nat virtual-reassembly"))
7935 class TestDSlite(MethodHolder):
7936 """ DS-Lite Test Cases """
7939 def setUpClass(cls):
7940 super(TestDSlite, cls).setUpClass()
7943 cls.nat_addr = '10.0.0.3'
7944 cls.nat_addr_n = socket.inet_pton(socket.AF_INET, cls.nat_addr)
7946 cls.create_pg_interfaces(range(3))
7948 cls.pg0.config_ip4()
7949 cls.pg0.resolve_arp()
7951 cls.pg1.config_ip6()
7952 cls.pg1.generate_remote_hosts(2)
7953 cls.pg1.configure_ipv6_neighbors()
7955 cls.pg2.config_ip4()
7956 cls.pg2.resolve_arp()
7959 super(TestDSlite, cls).tearDownClass()
7962 def verify_syslog_apmadd(self, data, isaddr, isport, xsaddr, xsport,
7964 message = data.decode('utf-8')
7966 message = SyslogMessage.parse(message)
7967 self.assertEqual(message.severity, SyslogSeverity.info)
7968 self.assertEqual(message.appname, 'NAT')
7969 self.assertEqual(message.msgid, 'APMADD')
7970 sd_params = message.sd.get('napmap')
7971 self.assertTrue(sd_params is not None)
7972 self.assertEqual(sd_params.get('IATYP'), 'IPv4')
7973 self.assertEqual(sd_params.get('ISADDR'), isaddr)
7974 self.assertEqual(sd_params.get('ISPORT'), "%d" % isport)
7975 self.assertEqual(sd_params.get('XATYP'), 'IPv4')
7976 self.assertEqual(sd_params.get('XSADDR'), xsaddr)
7977 self.assertEqual(sd_params.get('XSPORT'), "%d" % xsport)
7978 self.assertEqual(sd_params.get('PROTO'), "%d" % proto)
7979 self.assertTrue(sd_params.get('SSUBIX') is not None)
7980 self.assertEqual(sd_params.get('SV6ENC'), sv6enc)
7981 except ParseError as e:
7982 self.logger.error(e)
7984 def test_dslite(self):
7985 """ Test DS-Lite """
7986 nat_config = self.vapi.nat_show_config()
7987 self.assertEqual(0, nat_config.dslite_ce)
7989 self.vapi.dslite_add_del_pool_addr_range(self.nat_addr_n,
7991 aftr_ip4 = '192.0.0.1'
7992 aftr_ip4_n = socket.inet_pton(socket.AF_INET, aftr_ip4)
7993 aftr_ip6 = '2001:db8:85a3::8a2e:370:1'
7994 aftr_ip6_n = socket.inet_pton(socket.AF_INET6, aftr_ip6)
7995 self.vapi.dslite_set_aftr_addr(aftr_ip6_n, aftr_ip4_n)
7996 self.vapi.syslog_set_sender(self.pg2.remote_ip4n, self.pg2.local_ip4n)
7999 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
8000 IPv6(dst=aftr_ip6, src=self.pg1.remote_hosts[0].ip6) /
8001 IP(dst=self.pg0.remote_ip4, src='192.168.1.1') /
8002 UDP(sport=20000, dport=10000))
8003 self.pg1.add_stream(p)
8004 self.pg_enable_capture(self.pg_interfaces)
8006 capture = self.pg0.get_capture(1)
8007 capture = capture[0]
8008 self.assertFalse(capture.haslayer(IPv6))
8009 self.assertEqual(capture[IP].src, self.nat_addr)
8010 self.assertEqual(capture[IP].dst, self.pg0.remote_ip4)
8011 self.assertNotEqual(capture[UDP].sport, 20000)
8012 self.assertEqual(capture[UDP].dport, 10000)
8013 self.assert_packet_checksums_valid(capture)
8014 out_port = capture[UDP].sport
8015 capture = self.pg2.get_capture(1)
8016 self.verify_syslog_apmadd(capture[0][Raw].load, '192.168.1.1',
8017 20000, self.nat_addr, out_port,
8018 self.pg1.remote_hosts[0].ip6, IP_PROTOS.udp)
8020 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
8021 IP(dst=self.nat_addr, src=self.pg0.remote_ip4) /
8022 UDP(sport=10000, dport=out_port))
8023 self.pg0.add_stream(p)
8024 self.pg_enable_capture(self.pg_interfaces)
8026 capture = self.pg1.get_capture(1)
8027 capture = capture[0]
8028 self.assertEqual(capture[IPv6].src, aftr_ip6)
8029 self.assertEqual(capture[IPv6].dst, self.pg1.remote_hosts[0].ip6)
8030 self.assertEqual(capture[IP].src, self.pg0.remote_ip4)
8031 self.assertEqual(capture[IP].dst, '192.168.1.1')
8032 self.assertEqual(capture[UDP].sport, 10000)
8033 self.assertEqual(capture[UDP].dport, 20000)
8034 self.assert_packet_checksums_valid(capture)
8037 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
8038 IPv6(dst=aftr_ip6, src=self.pg1.remote_hosts[1].ip6) /
8039 IP(dst=self.pg0.remote_ip4, src='192.168.1.1') /
8040 TCP(sport=20001, dport=10001))
8041 self.pg1.add_stream(p)
8042 self.pg_enable_capture(self.pg_interfaces)
8044 capture = self.pg0.get_capture(1)
8045 capture = capture[0]
8046 self.assertFalse(capture.haslayer(IPv6))
8047 self.assertEqual(capture[IP].src, self.nat_addr)
8048 self.assertEqual(capture[IP].dst, self.pg0.remote_ip4)
8049 self.assertNotEqual(capture[TCP].sport, 20001)
8050 self.assertEqual(capture[TCP].dport, 10001)
8051 self.assert_packet_checksums_valid(capture)
8052 out_port = capture[TCP].sport
8054 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
8055 IP(dst=self.nat_addr, src=self.pg0.remote_ip4) /
8056 TCP(sport=10001, dport=out_port))
8057 self.pg0.add_stream(p)
8058 self.pg_enable_capture(self.pg_interfaces)
8060 capture = self.pg1.get_capture(1)
8061 capture = capture[0]
8062 self.assertEqual(capture[IPv6].src, aftr_ip6)
8063 self.assertEqual(capture[IPv6].dst, self.pg1.remote_hosts[1].ip6)
8064 self.assertEqual(capture[IP].src, self.pg0.remote_ip4)
8065 self.assertEqual(capture[IP].dst, '192.168.1.1')
8066 self.assertEqual(capture[TCP].sport, 10001)
8067 self.assertEqual(capture[TCP].dport, 20001)
8068 self.assert_packet_checksums_valid(capture)
8071 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
8072 IPv6(dst=aftr_ip6, src=self.pg1.remote_hosts[1].ip6) /
8073 IP(dst=self.pg0.remote_ip4, src='192.168.1.1') /
8074 ICMP(id=4000, type='echo-request'))
8075 self.pg1.add_stream(p)
8076 self.pg_enable_capture(self.pg_interfaces)
8078 capture = self.pg0.get_capture(1)
8079 capture = capture[0]
8080 self.assertFalse(capture.haslayer(IPv6))
8081 self.assertEqual(capture[IP].src, self.nat_addr)
8082 self.assertEqual(capture[IP].dst, self.pg0.remote_ip4)
8083 self.assertNotEqual(capture[ICMP].id, 4000)
8084 self.assert_packet_checksums_valid(capture)
8085 out_id = capture[ICMP].id
8087 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
8088 IP(dst=self.nat_addr, src=self.pg0.remote_ip4) /
8089 ICMP(id=out_id, type='echo-reply'))
8090 self.pg0.add_stream(p)
8091 self.pg_enable_capture(self.pg_interfaces)
8093 capture = self.pg1.get_capture(1)
8094 capture = capture[0]
8095 self.assertEqual(capture[IPv6].src, aftr_ip6)
8096 self.assertEqual(capture[IPv6].dst, self.pg1.remote_hosts[1].ip6)
8097 self.assertEqual(capture[IP].src, self.pg0.remote_ip4)
8098 self.assertEqual(capture[IP].dst, '192.168.1.1')
8099 self.assertEqual(capture[ICMP].id, 4000)
8100 self.assert_packet_checksums_valid(capture)
8102 # ping DS-Lite AFTR tunnel endpoint address
8103 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
8104 IPv6(src=self.pg1.remote_hosts[1].ip6, dst=aftr_ip6) /
8105 ICMPv6EchoRequest())
8106 self.pg1.add_stream(p)
8107 self.pg_enable_capture(self.pg_interfaces)
8109 capture = self.pg1.get_capture(1)
8110 capture = capture[0]
8111 self.assertEqual(capture[IPv6].src, aftr_ip6)
8112 self.assertEqual(capture[IPv6].dst, self.pg1.remote_hosts[1].ip6)
8113 self.assertTrue(capture.haslayer(ICMPv6EchoReply))
8116 super(TestDSlite, self).tearDown()
8117 if not self.vpp_dead:
8118 self.logger.info(self.vapi.cli("show dslite pool"))
8120 self.vapi.cli("show dslite aftr-tunnel-endpoint-address"))
8121 self.logger.info(self.vapi.cli("show dslite sessions"))
8124 class TestDSliteCE(MethodHolder):
8125 """ DS-Lite CE Test Cases """
8128 def setUpConstants(cls):
8129 super(TestDSliteCE, cls).setUpConstants()
8130 cls.vpp_cmdline.extend(["nat", "{", "dslite ce", "}"])
8133 def setUpClass(cls):
8134 super(TestDSliteCE, cls).setUpClass()
8137 cls.create_pg_interfaces(range(2))
8139 cls.pg0.config_ip4()
8140 cls.pg0.resolve_arp()
8142 cls.pg1.config_ip6()
8143 cls.pg1.generate_remote_hosts(1)
8144 cls.pg1.configure_ipv6_neighbors()
8147 super(TestDSliteCE, cls).tearDownClass()
8150 def test_dslite_ce(self):
8151 """ Test DS-Lite CE """
8153 nat_config = self.vapi.nat_show_config()
8154 self.assertEqual(1, nat_config.dslite_ce)
8156 b4_ip4 = '192.0.0.2'
8157 b4_ip4_n = socket.inet_pton(socket.AF_INET, b4_ip4)
8158 b4_ip6 = '2001:db8:62aa::375e:f4c1:1'
8159 b4_ip6_n = socket.inet_pton(socket.AF_INET6, b4_ip6)
8160 self.vapi.dslite_set_b4_addr(b4_ip6_n, b4_ip4_n)
8162 aftr_ip4 = '192.0.0.1'
8163 aftr_ip4_n = socket.inet_pton(socket.AF_INET, aftr_ip4)
8164 aftr_ip6 = '2001:db8:85a3::8a2e:370:1'
8165 aftr_ip6_n = socket.inet_pton(socket.AF_INET6, aftr_ip6)
8166 self.vapi.dslite_set_aftr_addr(aftr_ip6_n, aftr_ip4_n)
8168 self.vapi.ip_add_del_route(dst_address=aftr_ip6_n,
8169 dst_address_length=128,
8170 next_hop_address=self.pg1.remote_ip6n,
8171 next_hop_sw_if_index=self.pg1.sw_if_index,
8175 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
8176 IP(dst=self.pg1.remote_ip4, src=self.pg0.remote_ip4) /
8177 UDP(sport=10000, dport=20000))
8178 self.pg0.add_stream(p)
8179 self.pg_enable_capture(self.pg_interfaces)
8181 capture = self.pg1.get_capture(1)
8182 capture = capture[0]
8183 self.assertEqual(capture[IPv6].src, b4_ip6)
8184 self.assertEqual(capture[IPv6].dst, aftr_ip6)
8185 self.assertEqual(capture[IP].src, self.pg0.remote_ip4)
8186 self.assertEqual(capture[IP].dst, self.pg1.remote_ip4)
8187 self.assertEqual(capture[UDP].sport, 10000)
8188 self.assertEqual(capture[UDP].dport, 20000)
8189 self.assert_packet_checksums_valid(capture)
8192 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
8193 IPv6(dst=b4_ip6, src=aftr_ip6) /
8194 IP(dst=self.pg0.remote_ip4, src=self.pg1.remote_ip4) /
8195 UDP(sport=20000, dport=10000))
8196 self.pg1.add_stream(p)
8197 self.pg_enable_capture(self.pg_interfaces)
8199 capture = self.pg0.get_capture(1)
8200 capture = capture[0]
8201 self.assertFalse(capture.haslayer(IPv6))
8202 self.assertEqual(capture[IP].src, self.pg1.remote_ip4)
8203 self.assertEqual(capture[IP].dst, self.pg0.remote_ip4)
8204 self.assertEqual(capture[UDP].sport, 20000)
8205 self.assertEqual(capture[UDP].dport, 10000)
8206 self.assert_packet_checksums_valid(capture)
8208 # ping DS-Lite B4 tunnel endpoint address
8209 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
8210 IPv6(src=self.pg1.remote_hosts[0].ip6, dst=b4_ip6) /
8211 ICMPv6EchoRequest())
8212 self.pg1.add_stream(p)
8213 self.pg_enable_capture(self.pg_interfaces)
8215 capture = self.pg1.get_capture(1)
8216 capture = capture[0]
8217 self.assertEqual(capture[IPv6].src, b4_ip6)
8218 self.assertEqual(capture[IPv6].dst, self.pg1.remote_hosts[0].ip6)
8219 self.assertTrue(capture.haslayer(ICMPv6EchoReply))
8222 super(TestDSliteCE, self).tearDown()
8223 if not self.vpp_dead:
8225 self.vapi.cli("show dslite aftr-tunnel-endpoint-address"))
8227 self.vapi.cli("show dslite b4-tunnel-endpoint-address"))
8230 class TestNAT66(MethodHolder):
8231 """ NAT66 Test Cases """
8234 def setUpClass(cls):
8235 super(TestNAT66, cls).setUpClass()
8238 cls.nat_addr = 'fd01:ff::2'
8239 cls.nat_addr_n = socket.inet_pton(socket.AF_INET6, cls.nat_addr)
8241 cls.create_pg_interfaces(range(2))
8242 cls.interfaces = list(cls.pg_interfaces)
8244 for i in cls.interfaces:
8247 i.configure_ipv6_neighbors()
8250 super(TestNAT66, cls).tearDownClass()
8253 def test_static(self):
8254 """ 1:1 NAT66 test """
8255 self.vapi.nat66_add_del_interface(self.pg0.sw_if_index)
8256 self.vapi.nat66_add_del_interface(self.pg1.sw_if_index, is_inside=0)
8257 self.vapi.nat66_add_del_static_mapping(self.pg0.remote_ip6n,
8262 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
8263 IPv6(src=self.pg0.remote_ip6, dst=self.pg1.remote_ip6) /
8266 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
8267 IPv6(src=self.pg0.remote_ip6, dst=self.pg1.remote_ip6) /
8270 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
8271 IPv6(src=self.pg0.remote_ip6, dst=self.pg1.remote_ip6) /
8272 ICMPv6EchoRequest())
8274 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
8275 IPv6(src=self.pg0.remote_ip6, dst=self.pg1.remote_ip6) /
8276 GRE() / IP() / TCP())
8278 self.pg0.add_stream(pkts)
8279 self.pg_enable_capture(self.pg_interfaces)
8281 capture = self.pg1.get_capture(len(pkts))
8282 for packet in capture:
8284 self.assertEqual(packet[IPv6].src, self.nat_addr)
8285 self.assertEqual(packet[IPv6].dst, self.pg1.remote_ip6)
8286 self.assert_packet_checksums_valid(packet)
8288 self.logger.error(ppp("Unexpected or invalid packet:", packet))
8293 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
8294 IPv6(src=self.pg1.remote_ip6, dst=self.nat_addr) /
8297 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
8298 IPv6(src=self.pg1.remote_ip6, dst=self.nat_addr) /
8301 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
8302 IPv6(src=self.pg1.remote_ip6, dst=self.nat_addr) /
8305 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
8306 IPv6(src=self.pg1.remote_ip6, dst=self.nat_addr) /
8307 GRE() / IP() / TCP())
8309 self.pg1.add_stream(pkts)
8310 self.pg_enable_capture(self.pg_interfaces)
8312 capture = self.pg0.get_capture(len(pkts))
8313 for packet in capture:
8315 self.assertEqual(packet[IPv6].src, self.pg1.remote_ip6)
8316 self.assertEqual(packet[IPv6].dst, self.pg0.remote_ip6)
8317 self.assert_packet_checksums_valid(packet)
8319 self.logger.error(ppp("Unexpected or invalid packet:", packet))
8322 sm = self.vapi.nat66_static_mapping_dump()
8323 self.assertEqual(len(sm), 1)
8324 self.assertEqual(sm[0].total_pkts, 8)
8326 def test_check_no_translate(self):
8327 """ NAT66 translate only when egress interface is outside interface """
8328 self.vapi.nat66_add_del_interface(self.pg0.sw_if_index)
8329 self.vapi.nat66_add_del_interface(self.pg1.sw_if_index)
8330 self.vapi.nat66_add_del_static_mapping(self.pg0.remote_ip6n,
8334 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
8335 IPv6(src=self.pg0.remote_ip6, dst=self.pg1.remote_ip6) /
8337 self.pg0.add_stream([p])
8338 self.pg_enable_capture(self.pg_interfaces)
8340 capture = self.pg1.get_capture(1)
8343 self.assertEqual(packet[IPv6].src, self.pg0.remote_ip6)
8344 self.assertEqual(packet[IPv6].dst, self.pg1.remote_ip6)
8346 self.logger.error(ppp("Unexpected or invalid packet:", packet))
8349 def clear_nat66(self):
8351 Clear NAT66 configuration.
8353 interfaces = self.vapi.nat66_interface_dump()
8354 for intf in interfaces:
8355 self.vapi.nat66_add_del_interface(intf.sw_if_index,
8359 static_mappings = self.vapi.nat66_static_mapping_dump()
8360 for sm in static_mappings:
8361 self.vapi.nat66_add_del_static_mapping(sm.local_ip_address,
8362 sm.external_ip_address,
8367 super(TestNAT66, self).tearDown()
8368 if not self.vpp_dead:
8369 self.logger.info(self.vapi.cli("show nat66 interfaces"))
8370 self.logger.info(self.vapi.cli("show nat66 static mappings"))
8374 if __name__ == '__main__':
8375 unittest.main(testRunner=VppTestRunner)