8 from framework import VppTestCase, VppTestRunner, running_extended_tests
9 from scapy.layers.inet import IP, TCP, UDP, ICMP
10 from scapy.layers.inet import IPerror, TCPerror, UDPerror, ICMPerror
11 from scapy.layers.inet6 import IPv6, ICMPv6EchoRequest, ICMPv6EchoReply, \
12 ICMPv6ND_NS, ICMPv6ND_NA, ICMPv6NDOptDstLLAddr, fragment6
13 from scapy.layers.inet6 import ICMPv6DestUnreach, IPerror6, IPv6ExtHdrFragment
14 from scapy.layers.l2 import Ether, ARP, GRE
15 from scapy.data import IP_PROTOS
16 from scapy.packet import bind_layers, Raw
18 from ipfix import IPFIX, Set, Template, Data, IPFIXDecoder
19 from time import sleep
20 from util import ip4_range
21 from vpp_papi import mac_pton
22 from syslog_rfc5424_parser import SyslogMessage, ParseError
23 from syslog_rfc5424_parser.constants import SyslogFacility, SyslogSeverity
24 from vpp_papi_provider import SYSLOG_SEVERITY
25 from io import BytesIO
26 from vpp_papi import VppEnum
27 from scapy.all import bind_layers, Packet, ByteEnumField, ShortField, \
28 IPField, IntField, LongField, XByteField, FlagsField, FieldLenField, \
32 # NAT HA protocol event data
35 fields_desc = [ByteEnumField("event_type", None,
36 {1: "add", 2: "del", 3: "refresh"}),
37 ByteEnumField("protocol", None,
38 {0: "udp", 1: "tcp", 2: "icmp"}),
39 ShortField("flags", 0),
40 IPField("in_addr", None),
41 IPField("out_addr", None),
42 ShortField("in_port", None),
43 ShortField("out_port", None),
44 IPField("eh_addr", None),
45 IPField("ehn_addr", None),
46 ShortField("eh_port", None),
47 ShortField("ehn_port", None),
48 IntField("fib_index", None),
49 IntField("total_pkts", 0),
50 LongField("total_bytes", 0)]
52 def extract_padding(self, s):
56 # NAT HA protocol header
57 class HANATStateSync(Packet):
58 name = "HA NAT state sync"
59 fields_desc = [XByteField("version", 1),
60 FlagsField("flags", 0, 8, ['ACK']),
61 FieldLenField("count", None, count_of="events"),
62 IntField("sequence_number", 1),
63 IntField("thread_index", 0),
64 PacketListField("events", [], Event,
65 count_from=lambda pkt:pkt.count)]
68 class MethodHolder(VppTestCase):
69 """ NAT create capture and verify method holder """
71 def clear_nat44(self):
73 Clear NAT44 configuration.
75 if hasattr(self, 'pg7') and hasattr(self, 'pg8'):
76 # I found no elegant way to do this
77 self.vapi.ip_add_del_route(
78 dst_address=self.pg7.remote_ip4n,
79 dst_address_length=32,
80 next_hop_address=self.pg7.remote_ip4n,
81 next_hop_sw_if_index=self.pg7.sw_if_index,
83 self.vapi.ip_add_del_route(
84 dst_address=self.pg8.remote_ip4n,
85 dst_address_length=32,
86 next_hop_address=self.pg8.remote_ip4n,
87 next_hop_sw_if_index=self.pg8.sw_if_index,
90 for intf in [self.pg7, self.pg8]:
91 self.vapi.ip_neighbor_add_del(
95 flags=(VppEnum.vl_api_ip_neighbor_flags_t.
96 IP_API_NEIGHBOR_FLAG_STATIC),
99 if self.pg7.has_ip4_config:
100 self.pg7.unconfig_ip4()
102 self.vapi.nat44_forwarding_enable_disable(0)
104 interfaces = self.vapi.nat44_interface_addr_dump()
105 for intf in interfaces:
106 self.vapi.nat44_add_interface_addr(intf.sw_if_index,
107 twice_nat=intf.twice_nat,
110 self.vapi.nat_ipfix(enable=0, src_port=self.ipfix_src_port,
111 domain_id=self.ipfix_domain_id)
112 self.ipfix_src_port = 4739
113 self.ipfix_domain_id = 1
115 self.vapi.syslog_set_filter(SYSLOG_SEVERITY.EMERG)
117 self.vapi.nat_ha_set_listener('0.0.0.0', 0)
118 self.vapi.nat_ha_set_failover('0.0.0.0', 0)
120 interfaces = self.vapi.nat44_interface_dump()
121 for intf in interfaces:
122 if intf.is_inside > 1:
123 self.vapi.nat44_interface_add_del_feature(intf.sw_if_index,
126 self.vapi.nat44_interface_add_del_feature(intf.sw_if_index,
130 interfaces = self.vapi.nat44_interface_output_feature_dump()
131 for intf in interfaces:
132 self.vapi.nat44_interface_add_del_output_feature(intf.sw_if_index,
136 static_mappings = self.vapi.nat44_static_mapping_dump()
137 for sm in static_mappings:
138 self.vapi.nat44_add_del_static_mapping(
140 sm.external_ip_address,
141 local_port=sm.local_port,
142 external_port=sm.external_port,
143 addr_only=sm.addr_only,
145 protocol=sm.protocol,
146 twice_nat=sm.twice_nat,
147 self_twice_nat=sm.self_twice_nat,
148 out2in_only=sm.out2in_only,
150 external_sw_if_index=sm.external_sw_if_index,
153 lb_static_mappings = self.vapi.nat44_lb_static_mapping_dump()
154 for lb_sm in lb_static_mappings:
155 self.vapi.nat44_add_del_lb_static_mapping(
159 twice_nat=lb_sm.twice_nat,
160 self_twice_nat=lb_sm.self_twice_nat,
161 out2in_only=lb_sm.out2in_only,
167 identity_mappings = self.vapi.nat44_identity_mapping_dump()
168 for id_m in identity_mappings:
169 self.vapi.nat44_add_del_identity_mapping(
170 addr_only=id_m.addr_only,
173 sw_if_index=id_m.sw_if_index,
175 protocol=id_m.protocol,
178 adresses = self.vapi.nat44_address_dump()
179 for addr in adresses:
180 self.vapi.nat44_add_del_address_range(addr.ip_address,
182 twice_nat=addr.twice_nat,
185 self.vapi.nat_set_reass()
186 self.vapi.nat_set_reass(is_ip6=1)
187 self.verify_no_nat44_user()
188 self.vapi.nat_set_timeouts()
189 self.vapi.nat_set_addr_and_port_alloc_alg()
190 self.vapi.nat_set_mss_clamping()
192 def nat44_add_static_mapping(self, local_ip, external_ip='0.0.0.0',
193 local_port=0, external_port=0, vrf_id=0,
194 is_add=1, external_sw_if_index=0xFFFFFFFF,
195 proto=0, twice_nat=0, self_twice_nat=0,
196 out2in_only=0, tag=""):
198 Add/delete NAT44 static mapping
200 :param local_ip: Local IP address
201 :param external_ip: External IP address
202 :param local_port: Local port number (Optional)
203 :param external_port: External port number (Optional)
204 :param vrf_id: VRF ID (Default 0)
205 :param is_add: 1 if add, 0 if delete (Default add)
206 :param external_sw_if_index: External interface instead of IP address
207 :param proto: IP protocol (Mandatory if port specified)
208 :param twice_nat: 1 if translate external host address and port
209 :param self_twice_nat: 1 if translate external host address and port
210 whenever external host address equals
211 local address of internal host
212 :param out2in_only: if 1 rule is matching only out2in direction
213 :param tag: Opaque string tag
216 if local_port and external_port:
218 l_ip = socket.inet_pton(socket.AF_INET, local_ip)
219 e_ip = socket.inet_pton(socket.AF_INET, external_ip)
220 self.vapi.nat44_add_del_static_mapping(
223 external_sw_if_index,
235 def nat44_add_address(self, ip, is_add=1, vrf_id=0xFFFFFFFF, twice_nat=0):
237 Add/delete NAT44 address
239 :param ip: IP address
240 :param is_add: 1 if add, 0 if delete (Default add)
241 :param twice_nat: twice NAT address for extenal hosts
243 nat_addr = socket.inet_pton(socket.AF_INET, ip)
244 self.vapi.nat44_add_del_address_range(nat_addr, nat_addr, is_add,
248 def create_stream_in(self, in_if, out_if, dst_ip=None, ttl=64):
250 Create packet stream for inside network
252 :param in_if: Inside interface
253 :param out_if: Outside interface
254 :param dst_ip: Destination address
255 :param ttl: TTL of generated packets
258 dst_ip = out_if.remote_ip4
262 p = (Ether(dst=in_if.local_mac, src=in_if.remote_mac) /
263 IP(src=in_if.remote_ip4, dst=dst_ip, ttl=ttl) /
264 TCP(sport=self.tcp_port_in, dport=20))
268 p = (Ether(dst=in_if.local_mac, src=in_if.remote_mac) /
269 IP(src=in_if.remote_ip4, dst=dst_ip, ttl=ttl) /
270 UDP(sport=self.udp_port_in, dport=20))
274 p = (Ether(dst=in_if.local_mac, src=in_if.remote_mac) /
275 IP(src=in_if.remote_ip4, dst=dst_ip, ttl=ttl) /
276 ICMP(id=self.icmp_id_in, type='echo-request'))
281 def compose_ip6(self, ip4, pref, plen):
283 Compose IPv4-embedded IPv6 addresses
285 :param ip4: IPv4 address
286 :param pref: IPv6 prefix
287 :param plen: IPv6 prefix length
288 :returns: IPv4-embedded IPv6 addresses
290 pref_n = list(socket.inet_pton(socket.AF_INET6, pref))
291 ip4_n = list(socket.inet_pton(socket.AF_INET, ip4))
306 pref_n[10] = ip4_n[3]
310 pref_n[10] = ip4_n[2]
311 pref_n[11] = ip4_n[3]
314 pref_n[10] = ip4_n[1]
315 pref_n[11] = ip4_n[2]
316 pref_n[12] = ip4_n[3]
318 pref_n[12] = ip4_n[0]
319 pref_n[13] = ip4_n[1]
320 pref_n[14] = ip4_n[2]
321 pref_n[15] = ip4_n[3]
322 return socket.inet_ntop(socket.AF_INET6, ''.join(pref_n))
324 def extract_ip4(self, ip6, plen):
326 Extract IPv4 address embedded in IPv6 addresses
328 :param ip6: IPv6 address
329 :param plen: IPv6 prefix length
330 :returns: extracted IPv4 address
332 ip6_n = list(socket.inet_pton(socket.AF_INET6, ip6))
364 return socket.inet_ntop(socket.AF_INET, ''.join(ip4_n))
366 def create_stream_in_ip6(self, in_if, out_if, hlim=64, pref=None, plen=0):
368 Create IPv6 packet stream for inside network
370 :param in_if: Inside interface
371 :param out_if: Outside interface
372 :param ttl: Hop Limit of generated packets
373 :param pref: NAT64 prefix
374 :param plen: NAT64 prefix length
378 dst = ''.join(['64:ff9b::', out_if.remote_ip4])
380 dst = self.compose_ip6(out_if.remote_ip4, pref, plen)
383 p = (Ether(dst=in_if.local_mac, src=in_if.remote_mac) /
384 IPv6(src=in_if.remote_ip6, dst=dst, hlim=hlim) /
385 TCP(sport=self.tcp_port_in, dport=20))
389 p = (Ether(dst=in_if.local_mac, src=in_if.remote_mac) /
390 IPv6(src=in_if.remote_ip6, dst=dst, hlim=hlim) /
391 UDP(sport=self.udp_port_in, dport=20))
395 p = (Ether(dst=in_if.local_mac, src=in_if.remote_mac) /
396 IPv6(src=in_if.remote_ip6, dst=dst, hlim=hlim) /
397 ICMPv6EchoRequest(id=self.icmp_id_in))
402 def create_stream_out(self, out_if, dst_ip=None, ttl=64,
403 use_inside_ports=False):
405 Create packet stream for outside network
407 :param out_if: Outside interface
408 :param dst_ip: Destination IP address (Default use global NAT address)
409 :param ttl: TTL of generated packets
410 :param use_inside_ports: Use inside NAT ports as destination ports
411 instead of outside ports
414 dst_ip = self.nat_addr
415 if not use_inside_ports:
416 tcp_port = self.tcp_port_out
417 udp_port = self.udp_port_out
418 icmp_id = self.icmp_id_out
420 tcp_port = self.tcp_port_in
421 udp_port = self.udp_port_in
422 icmp_id = self.icmp_id_in
425 p = (Ether(dst=out_if.local_mac, src=out_if.remote_mac) /
426 IP(src=out_if.remote_ip4, dst=dst_ip, ttl=ttl) /
427 TCP(dport=tcp_port, sport=20))
431 p = (Ether(dst=out_if.local_mac, src=out_if.remote_mac) /
432 IP(src=out_if.remote_ip4, dst=dst_ip, ttl=ttl) /
433 UDP(dport=udp_port, sport=20))
437 p = (Ether(dst=out_if.local_mac, src=out_if.remote_mac) /
438 IP(src=out_if.remote_ip4, dst=dst_ip, ttl=ttl) /
439 ICMP(id=icmp_id, type='echo-reply'))
444 def create_stream_out_ip6(self, out_if, src_ip, dst_ip, hl=64):
446 Create packet stream for outside network
448 :param out_if: Outside interface
449 :param dst_ip: Destination IP address (Default use global NAT address)
450 :param hl: HL of generated packets
454 p = (Ether(dst=out_if.local_mac, src=out_if.remote_mac) /
455 IPv6(src=src_ip, dst=dst_ip, hlim=hl) /
456 TCP(dport=self.tcp_port_out, sport=20))
460 p = (Ether(dst=out_if.local_mac, src=out_if.remote_mac) /
461 IPv6(src=src_ip, dst=dst_ip, hlim=hl) /
462 UDP(dport=self.udp_port_out, sport=20))
466 p = (Ether(dst=out_if.local_mac, src=out_if.remote_mac) /
467 IPv6(src=src_ip, dst=dst_ip, hlim=hl) /
468 ICMPv6EchoReply(id=self.icmp_id_out))
473 def verify_capture_out(self, capture, nat_ip=None, same_port=False,
474 dst_ip=None, is_ip6=False):
476 Verify captured packets on outside network
478 :param capture: Captured packets
479 :param nat_ip: Translated IP address (Default use global NAT address)
480 :param same_port: Sorce port number is not translated (Default False)
481 :param dst_ip: Destination IP address (Default do not verify)
482 :param is_ip6: If L3 protocol is IPv6 (Default False)
486 ICMP46 = ICMPv6EchoRequest
491 nat_ip = self.nat_addr
492 for packet in capture:
495 self.assert_packet_checksums_valid(packet)
496 self.assertEqual(packet[IP46].src, nat_ip)
497 if dst_ip is not None:
498 self.assertEqual(packet[IP46].dst, dst_ip)
499 if packet.haslayer(TCP):
501 self.assertEqual(packet[TCP].sport, self.tcp_port_in)
504 packet[TCP].sport, self.tcp_port_in)
505 self.tcp_port_out = packet[TCP].sport
506 self.assert_packet_checksums_valid(packet)
507 elif packet.haslayer(UDP):
509 self.assertEqual(packet[UDP].sport, self.udp_port_in)
512 packet[UDP].sport, self.udp_port_in)
513 self.udp_port_out = packet[UDP].sport
516 self.assertEqual(packet[ICMP46].id, self.icmp_id_in)
518 self.assertNotEqual(packet[ICMP46].id, self.icmp_id_in)
519 self.icmp_id_out = packet[ICMP46].id
520 self.assert_packet_checksums_valid(packet)
522 self.logger.error(ppp("Unexpected or invalid packet "
523 "(outside network):", packet))
526 def verify_capture_out_ip6(self, capture, nat_ip, same_port=False,
529 Verify captured packets on outside network
531 :param capture: Captured packets
532 :param nat_ip: Translated IP address
533 :param same_port: Sorce port number is not translated (Default False)
534 :param dst_ip: Destination IP address (Default do not verify)
536 return self.verify_capture_out(capture, nat_ip, same_port, dst_ip,
539 def verify_capture_in(self, capture, in_if):
541 Verify captured packets on inside network
543 :param capture: Captured packets
544 :param in_if: Inside interface
546 for packet in capture:
548 self.assert_packet_checksums_valid(packet)
549 self.assertEqual(packet[IP].dst, in_if.remote_ip4)
550 if packet.haslayer(TCP):
551 self.assertEqual(packet[TCP].dport, self.tcp_port_in)
552 elif packet.haslayer(UDP):
553 self.assertEqual(packet[UDP].dport, self.udp_port_in)
555 self.assertEqual(packet[ICMP].id, self.icmp_id_in)
557 self.logger.error(ppp("Unexpected or invalid packet "
558 "(inside network):", packet))
561 def verify_capture_in_ip6(self, capture, src_ip, dst_ip):
563 Verify captured IPv6 packets on inside network
565 :param capture: Captured packets
566 :param src_ip: Source IP
567 :param dst_ip: Destination IP address
569 for packet in capture:
571 self.assertEqual(packet[IPv6].src, src_ip)
572 self.assertEqual(packet[IPv6].dst, dst_ip)
573 self.assert_packet_checksums_valid(packet)
574 if packet.haslayer(TCP):
575 self.assertEqual(packet[TCP].dport, self.tcp_port_in)
576 elif packet.haslayer(UDP):
577 self.assertEqual(packet[UDP].dport, self.udp_port_in)
579 self.assertEqual(packet[ICMPv6EchoReply].id,
582 self.logger.error(ppp("Unexpected or invalid packet "
583 "(inside network):", packet))
586 def verify_capture_no_translation(self, capture, ingress_if, egress_if):
588 Verify captured packet that don't have to be translated
590 :param capture: Captured packets
591 :param ingress_if: Ingress interface
592 :param egress_if: Egress interface
594 for packet in capture:
596 self.assertEqual(packet[IP].src, ingress_if.remote_ip4)
597 self.assertEqual(packet[IP].dst, egress_if.remote_ip4)
598 if packet.haslayer(TCP):
599 self.assertEqual(packet[TCP].sport, self.tcp_port_in)
600 elif packet.haslayer(UDP):
601 self.assertEqual(packet[UDP].sport, self.udp_port_in)
603 self.assertEqual(packet[ICMP].id, self.icmp_id_in)
605 self.logger.error(ppp("Unexpected or invalid packet "
606 "(inside network):", packet))
609 def verify_capture_out_with_icmp_errors(self, capture, src_ip=None,
612 Verify captured packets with ICMP errors on outside network
614 :param capture: Captured packets
615 :param src_ip: Translated IP address or IP address of VPP
616 (Default use global NAT address)
617 :param icmp_type: Type of error ICMP packet
618 we are expecting (Default 11)
621 src_ip = self.nat_addr
622 for packet in capture:
624 self.assertEqual(packet[IP].src, src_ip)
625 self.assertEqual(packet.haslayer(ICMP), 1)
627 self.assertEqual(icmp.type, icmp_type)
628 self.assertTrue(icmp.haslayer(IPerror))
629 inner_ip = icmp[IPerror]
630 if inner_ip.haslayer(TCPerror):
631 self.assertEqual(inner_ip[TCPerror].dport,
633 elif inner_ip.haslayer(UDPerror):
634 self.assertEqual(inner_ip[UDPerror].dport,
637 self.assertEqual(inner_ip[ICMPerror].id, self.icmp_id_out)
639 self.logger.error(ppp("Unexpected or invalid packet "
640 "(outside network):", packet))
643 def verify_capture_in_with_icmp_errors(self, capture, in_if, icmp_type=11):
645 Verify captured packets with ICMP errors on inside network
647 :param capture: Captured packets
648 :param in_if: Inside interface
649 :param icmp_type: Type of error ICMP packet
650 we are expecting (Default 11)
652 for packet in capture:
654 self.assertEqual(packet[IP].dst, in_if.remote_ip4)
655 self.assertEqual(packet.haslayer(ICMP), 1)
657 self.assertEqual(icmp.type, icmp_type)
658 self.assertTrue(icmp.haslayer(IPerror))
659 inner_ip = icmp[IPerror]
660 if inner_ip.haslayer(TCPerror):
661 self.assertEqual(inner_ip[TCPerror].sport,
663 elif inner_ip.haslayer(UDPerror):
664 self.assertEqual(inner_ip[UDPerror].sport,
667 self.assertEqual(inner_ip[ICMPerror].id, self.icmp_id_in)
669 self.logger.error(ppp("Unexpected or invalid packet "
670 "(inside network):", packet))
673 def create_stream_frag(self, src_if, dst, sport, dport, data,
674 proto=IP_PROTOS.tcp, echo_reply=False):
676 Create fragmented packet stream
678 :param src_if: Source interface
679 :param dst: Destination IPv4 address
680 :param sport: Source port
681 :param dport: Destination port
682 :param data: Payload data
683 :param proto: protocol (TCP, UDP, ICMP)
684 :param echo_reply: use echo_reply if protocol is ICMP
687 if proto == IP_PROTOS.tcp:
688 p = (IP(src=src_if.remote_ip4, dst=dst) /
689 TCP(sport=sport, dport=dport) /
691 p = p.__class__(str(p))
692 chksum = p['TCP'].chksum
693 proto_header = TCP(sport=sport, dport=dport, chksum=chksum)
694 elif proto == IP_PROTOS.udp:
695 proto_header = UDP(sport=sport, dport=dport)
696 elif proto == IP_PROTOS.icmp:
698 proto_header = ICMP(id=sport, type='echo-request')
700 proto_header = ICMP(id=sport, type='echo-reply')
702 raise Exception("Unsupported protocol")
703 id = random.randint(0, 65535)
705 if proto == IP_PROTOS.tcp:
708 raw = Raw(data[0:16])
709 p = (Ether(src=src_if.remote_mac, dst=src_if.local_mac) /
710 IP(src=src_if.remote_ip4, dst=dst, flags="MF", frag=0, id=id) /
714 if proto == IP_PROTOS.tcp:
715 raw = Raw(data[4:20])
717 raw = Raw(data[16:32])
718 p = (Ether(src=src_if.remote_mac, dst=src_if.local_mac) /
719 IP(src=src_if.remote_ip4, dst=dst, flags="MF", frag=3, id=id,
723 if proto == IP_PROTOS.tcp:
727 p = (Ether(src=src_if.remote_mac, dst=src_if.local_mac) /
728 IP(src=src_if.remote_ip4, dst=dst, frag=5, proto=proto,
734 def create_stream_frag_ip6(self, src_if, dst, sport, dport, data,
735 pref=None, plen=0, frag_size=128):
737 Create fragmented packet stream
739 :param src_if: Source interface
740 :param dst: Destination IPv4 address
741 :param sport: Source TCP port
742 :param dport: Destination TCP port
743 :param data: Payload data
744 :param pref: NAT64 prefix
745 :param plen: NAT64 prefix length
746 :param fragsize: size of fragments
750 dst_ip6 = ''.join(['64:ff9b::', dst])
752 dst_ip6 = self.compose_ip6(dst, pref, plen)
754 p = (Ether(dst=src_if.local_mac, src=src_if.remote_mac) /
755 IPv6(src=src_if.remote_ip6, dst=dst_ip6) /
756 IPv6ExtHdrFragment(id=random.randint(0, 65535)) /
757 TCP(sport=sport, dport=dport) /
760 return fragment6(p, frag_size)
762 def reass_frags_and_verify(self, frags, src, dst):
764 Reassemble and verify fragmented packet
766 :param frags: Captured fragments
767 :param src: Source IPv4 address to verify
768 :param dst: Destination IPv4 address to verify
770 :returns: Reassembled IPv4 packet
774 self.assertEqual(p[IP].src, src)
775 self.assertEqual(p[IP].dst, dst)
776 self.assert_ip_checksum_valid(p)
777 buffer.seek(p[IP].frag * 8)
778 buffer.write(bytes(p[IP].payload))
779 ip = IP(src=frags[0][IP].src, dst=frags[0][IP].dst,
780 proto=frags[0][IP].proto)
781 if ip.proto == IP_PROTOS.tcp:
782 p = (ip / TCP(buffer.getvalue()))
783 self.assert_tcp_checksum_valid(p)
784 elif ip.proto == IP_PROTOS.udp:
785 p = (ip / UDP(buffer.getvalue()[:8]) /
786 Raw(buffer.getvalue()[8:]))
787 elif ip.proto == IP_PROTOS.icmp:
788 p = (ip / ICMP(buffer.getvalue()))
791 def reass_frags_and_verify_ip6(self, frags, src, dst):
793 Reassemble and verify fragmented packet
795 :param frags: Captured fragments
796 :param src: Source IPv6 address to verify
797 :param dst: Destination IPv6 address to verify
799 :returns: Reassembled IPv6 packet
803 self.assertEqual(p[IPv6].src, src)
804 self.assertEqual(p[IPv6].dst, dst)
805 buffer.seek(p[IPv6ExtHdrFragment].offset * 8)
806 buffer.write(bytes(p[IPv6ExtHdrFragment].payload))
807 ip = IPv6(src=frags[0][IPv6].src, dst=frags[0][IPv6].dst,
808 nh=frags[0][IPv6ExtHdrFragment].nh)
809 if ip.nh == IP_PROTOS.tcp:
810 p = (ip / TCP(buffer.getvalue()))
811 elif ip.nh == IP_PROTOS.udp:
812 p = (ip / UDP(buffer.getvalue()))
813 self.assert_packet_checksums_valid(p)
816 def initiate_tcp_session(self, in_if, out_if):
818 Initiates TCP session
820 :param in_if: Inside interface
821 :param out_if: Outside interface
825 p = (Ether(src=in_if.remote_mac, dst=in_if.local_mac) /
826 IP(src=in_if.remote_ip4, dst=out_if.remote_ip4) /
827 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
830 self.pg_enable_capture(self.pg_interfaces)
832 capture = out_if.get_capture(1)
834 self.tcp_port_out = p[TCP].sport
836 # SYN + ACK packet out->in
837 p = (Ether(src=out_if.remote_mac, dst=out_if.local_mac) /
838 IP(src=out_if.remote_ip4, dst=self.nat_addr) /
839 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
842 self.pg_enable_capture(self.pg_interfaces)
847 p = (Ether(src=in_if.remote_mac, dst=in_if.local_mac) /
848 IP(src=in_if.remote_ip4, dst=out_if.remote_ip4) /
849 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
852 self.pg_enable_capture(self.pg_interfaces)
854 out_if.get_capture(1)
857 self.logger.error("TCP 3 way handshake failed")
860 def verify_ipfix_nat44_ses(self, data):
862 Verify IPFIX NAT44 session create/delete event
864 :param data: Decoded IPFIX data records
866 nat44_ses_create_num = 0
867 nat44_ses_delete_num = 0
868 self.assertEqual(6, len(data))
871 self.assertIn(ord(record[230]), [4, 5])
872 if ord(record[230]) == 4:
873 nat44_ses_create_num += 1
875 nat44_ses_delete_num += 1
877 self.assertEqual(self.pg0.remote_ip4n, record[8])
878 # postNATSourceIPv4Address
879 self.assertEqual(socket.inet_pton(socket.AF_INET, self.nat_addr),
882 self.assertEqual(struct.pack("!I", 0), record[234])
883 # protocolIdentifier/sourceTransportPort/postNAPTSourceTransportPort
884 if IP_PROTOS.icmp == ord(record[4]):
885 self.assertEqual(struct.pack("!H", self.icmp_id_in), record[7])
886 self.assertEqual(struct.pack("!H", self.icmp_id_out),
888 elif IP_PROTOS.tcp == ord(record[4]):
889 self.assertEqual(struct.pack("!H", self.tcp_port_in),
891 self.assertEqual(struct.pack("!H", self.tcp_port_out),
893 elif IP_PROTOS.udp == ord(record[4]):
894 self.assertEqual(struct.pack("!H", self.udp_port_in),
896 self.assertEqual(struct.pack("!H", self.udp_port_out),
899 self.fail("Invalid protocol")
900 self.assertEqual(3, nat44_ses_create_num)
901 self.assertEqual(3, nat44_ses_delete_num)
903 def verify_ipfix_addr_exhausted(self, data):
905 Verify IPFIX NAT addresses event
907 :param data: Decoded IPFIX data records
909 self.assertEqual(1, len(data))
912 self.assertEqual(ord(record[230]), 3)
914 self.assertEqual(struct.pack("!I", 0), record[283])
916 def verify_ipfix_max_sessions(self, data, limit):
918 Verify IPFIX maximum session entries exceeded event
920 :param data: Decoded IPFIX data records
921 :param limit: Number of maximum session entries that can be created.
923 self.assertEqual(1, len(data))
926 self.assertEqual(ord(record[230]), 13)
927 # natQuotaExceededEvent
928 self.assertEqual(struct.pack("I", 1), record[466])
930 self.assertEqual(struct.pack("I", limit), record[471])
932 def verify_ipfix_max_bibs(self, data, limit):
934 Verify IPFIX maximum BIB entries exceeded event
936 :param data: Decoded IPFIX data records
937 :param limit: Number of maximum BIB entries that can be created.
939 self.assertEqual(1, len(data))
942 self.assertEqual(ord(record[230]), 13)
943 # natQuotaExceededEvent
944 self.assertEqual(struct.pack("I", 2), record[466])
946 self.assertEqual(struct.pack("I", limit), record[472])
948 def verify_ipfix_max_fragments_ip6(self, data, limit, src_addr):
950 Verify IPFIX maximum IPv6 fragments pending reassembly exceeded event
952 :param data: Decoded IPFIX data records
953 :param limit: Number of maximum fragments pending reassembly
954 :param src_addr: IPv6 source address
956 self.assertEqual(1, len(data))
959 self.assertEqual(ord(record[230]), 13)
960 # natQuotaExceededEvent
961 self.assertEqual(struct.pack("I", 5), record[466])
962 # maxFragmentsPendingReassembly
963 self.assertEqual(struct.pack("I", limit), record[475])
965 self.assertEqual(src_addr, record[27])
967 def verify_ipfix_max_fragments_ip4(self, data, limit, src_addr):
969 Verify IPFIX maximum IPv4 fragments pending reassembly exceeded event
971 :param data: Decoded IPFIX data records
972 :param limit: Number of maximum fragments pending reassembly
973 :param src_addr: IPv4 source address
975 self.assertEqual(1, len(data))
978 self.assertEqual(ord(record[230]), 13)
979 # natQuotaExceededEvent
980 self.assertEqual(struct.pack("I", 5), record[466])
981 # maxFragmentsPendingReassembly
982 self.assertEqual(struct.pack("I", limit), record[475])
984 self.assertEqual(src_addr, record[8])
986 def verify_ipfix_bib(self, data, is_create, src_addr):
988 Verify IPFIX NAT64 BIB create and delete events
990 :param data: Decoded IPFIX data records
991 :param is_create: Create event if nonzero value otherwise delete event
992 :param src_addr: IPv6 source address
994 self.assertEqual(1, len(data))
998 self.assertEqual(ord(record[230]), 10)
1000 self.assertEqual(ord(record[230]), 11)
1002 self.assertEqual(src_addr, record[27])
1003 # postNATSourceIPv4Address
1004 self.assertEqual(self.nat_addr_n, record[225])
1005 # protocolIdentifier
1006 self.assertEqual(IP_PROTOS.tcp, ord(record[4]))
1008 self.assertEqual(struct.pack("!I", 0), record[234])
1009 # sourceTransportPort
1010 self.assertEqual(struct.pack("!H", self.tcp_port_in), record[7])
1011 # postNAPTSourceTransportPort
1012 self.assertEqual(struct.pack("!H", self.tcp_port_out), record[227])
1014 def verify_ipfix_nat64_ses(self, data, is_create, src_addr, dst_addr,
1017 Verify IPFIX NAT64 session create and delete events
1019 :param data: Decoded IPFIX data records
1020 :param is_create: Create event if nonzero value otherwise delete event
1021 :param src_addr: IPv6 source address
1022 :param dst_addr: IPv4 destination address
1023 :param dst_port: destination TCP port
1025 self.assertEqual(1, len(data))
1029 self.assertEqual(ord(record[230]), 6)
1031 self.assertEqual(ord(record[230]), 7)
1033 self.assertEqual(src_addr, record[27])
1034 # destinationIPv6Address
1035 self.assertEqual(socket.inet_pton(socket.AF_INET6,
1036 self.compose_ip6(dst_addr,
1040 # postNATSourceIPv4Address
1041 self.assertEqual(self.nat_addr_n, record[225])
1042 # postNATDestinationIPv4Address
1043 self.assertEqual(socket.inet_pton(socket.AF_INET, dst_addr),
1045 # protocolIdentifier
1046 self.assertEqual(IP_PROTOS.tcp, ord(record[4]))
1048 self.assertEqual(struct.pack("!I", 0), record[234])
1049 # sourceTransportPort
1050 self.assertEqual(struct.pack("!H", self.tcp_port_in), record[7])
1051 # postNAPTSourceTransportPort
1052 self.assertEqual(struct.pack("!H", self.tcp_port_out), record[227])
1053 # destinationTransportPort
1054 self.assertEqual(struct.pack("!H", dst_port), record[11])
1055 # postNAPTDestinationTransportPort
1056 self.assertEqual(struct.pack("!H", dst_port), record[228])
1058 def verify_no_nat44_user(self):
1059 """ Verify that there is no NAT44 user """
1060 users = self.vapi.nat44_user_dump()
1061 self.assertEqual(len(users), 0)
1062 users = self.statistics.get_counter('/nat44/total-users')
1063 self.assertEqual(users[0][0], 0)
1064 sessions = self.statistics.get_counter('/nat44/total-sessions')
1065 self.assertEqual(sessions[0][0], 0)
1067 def verify_ipfix_max_entries_per_user(self, data, limit, src_addr):
1069 Verify IPFIX maximum entries per user exceeded event
1071 :param data: Decoded IPFIX data records
1072 :param limit: Number of maximum entries per user
1073 :param src_addr: IPv4 source address
1075 self.assertEqual(1, len(data))
1078 self.assertEqual(ord(record[230]), 13)
1079 # natQuotaExceededEvent
1080 self.assertEqual(struct.pack("I", 3), record[466])
1082 self.assertEqual(struct.pack("I", limit), record[473])
1084 self.assertEqual(src_addr, record[8])
1086 def verify_syslog_apmap(self, data, is_add=True):
1087 message = data.decode('utf-8')
1089 message = SyslogMessage.parse(message)
1090 except ParseError as e:
1091 self.logger.error(e)
1094 self.assertEqual(message.severity, SyslogSeverity.info)
1095 self.assertEqual(message.appname, 'NAT')
1096 self.assertEqual(message.msgid, 'APMADD' if is_add else 'APMDEL')
1097 sd_params = message.sd.get('napmap')
1098 self.assertTrue(sd_params is not None)
1099 self.assertEqual(sd_params.get('IATYP'), 'IPv4')
1100 self.assertEqual(sd_params.get('ISADDR'), self.pg0.remote_ip4)
1101 self.assertEqual(sd_params.get('ISPORT'), "%d" % self.tcp_port_in)
1102 self.assertEqual(sd_params.get('XATYP'), 'IPv4')
1103 self.assertEqual(sd_params.get('XSADDR'), self.nat_addr)
1104 self.assertEqual(sd_params.get('XSPORT'), "%d" % self.tcp_port_out)
1105 self.assertEqual(sd_params.get('PROTO'), "%d" % IP_PROTOS.tcp)
1106 self.assertTrue(sd_params.get('SSUBIX') is not None)
1107 self.assertEqual(sd_params.get('SVLAN'), '0')
1109 def verify_syslog_sess(self, data, is_add=True, is_ip6=False):
1110 message = data.decode('utf-8')
1112 message = SyslogMessage.parse(message)
1113 except ParseError as e:
1114 self.logger.error(e)
1117 self.assertEqual(message.severity, SyslogSeverity.info)
1118 self.assertEqual(message.appname, 'NAT')
1119 self.assertEqual(message.msgid, 'SADD' if is_add else 'SDEL')
1120 sd_params = message.sd.get('nsess')
1121 self.assertTrue(sd_params is not None)
1123 self.assertEqual(sd_params.get('IATYP'), 'IPv6')
1124 self.assertEqual(sd_params.get('ISADDR'), self.pg0.remote_ip6)
1126 self.assertEqual(sd_params.get('IATYP'), 'IPv4')
1127 self.assertEqual(sd_params.get('ISADDR'), self.pg0.remote_ip4)
1128 self.assertTrue(sd_params.get('SSUBIX') is not None)
1129 self.assertEqual(sd_params.get('ISPORT'), "%d" % self.tcp_port_in)
1130 self.assertEqual(sd_params.get('XATYP'), 'IPv4')
1131 self.assertEqual(sd_params.get('XSADDR'), self.nat_addr)
1132 self.assertEqual(sd_params.get('XSPORT'), "%d" % self.tcp_port_out)
1133 self.assertEqual(sd_params.get('PROTO'), "%d" % IP_PROTOS.tcp)
1134 self.assertEqual(sd_params.get('SVLAN'), '0')
1135 self.assertEqual(sd_params.get('XDADDR'), self.pg1.remote_ip4)
1136 self.assertEqual(sd_params.get('XDPORT'),
1137 "%d" % self.tcp_external_port)
1139 def verify_mss_value(self, pkt, mss):
1141 Verify TCP MSS value
1146 if not pkt.haslayer(IP) or not pkt.haslayer(TCP):
1147 raise TypeError("Not a TCP/IP packet")
1149 for option in pkt[TCP].options:
1150 if option[0] == 'MSS':
1151 self.assertEqual(option[1], mss)
1152 self.assert_tcp_checksum_valid(pkt)
1155 def proto2layer(proto):
1156 if proto == IP_PROTOS.tcp:
1158 elif proto == IP_PROTOS.udp:
1160 elif proto == IP_PROTOS.icmp:
1163 raise Exception("Unsupported protocol")
1165 def frag_in_order(self, proto=IP_PROTOS.tcp, dont_translate=False):
1166 layer = self.proto2layer(proto)
1168 if proto == IP_PROTOS.tcp:
1169 data = "A" * 4 + "B" * 16 + "C" * 3
1171 data = "A" * 16 + "B" * 16 + "C" * 3
1172 self.port_in = random.randint(1025, 65535)
1174 reass = self.vapi.nat_reass_dump()
1175 reass_n_start = len(reass)
1178 pkts = self.create_stream_frag(self.pg0,
1179 self.pg1.remote_ip4,
1184 self.pg0.add_stream(pkts)
1185 self.pg_enable_capture(self.pg_interfaces)
1187 frags = self.pg1.get_capture(len(pkts))
1188 if not dont_translate:
1189 p = self.reass_frags_and_verify(frags,
1191 self.pg1.remote_ip4)
1193 p = self.reass_frags_and_verify(frags,
1194 self.pg0.remote_ip4,
1195 self.pg1.remote_ip4)
1196 if proto != IP_PROTOS.icmp:
1197 if not dont_translate:
1198 self.assertEqual(p[layer].dport, 20)
1199 self.assertNotEqual(p[layer].sport, self.port_in)
1201 self.assertEqual(p[layer].sport, self.port_in)
1203 if not dont_translate:
1204 self.assertNotEqual(p[layer].id, self.port_in)
1206 self.assertEqual(p[layer].id, self.port_in)
1207 self.assertEqual(data, p[Raw].load)
1210 if not dont_translate:
1211 dst_addr = self.nat_addr
1213 dst_addr = self.pg0.remote_ip4
1214 if proto != IP_PROTOS.icmp:
1216 dport = p[layer].sport
1220 pkts = self.create_stream_frag(self.pg1,
1227 self.pg1.add_stream(pkts)
1228 self.pg_enable_capture(self.pg_interfaces)
1230 frags = self.pg0.get_capture(len(pkts))
1231 p = self.reass_frags_and_verify(frags,
1232 self.pg1.remote_ip4,
1233 self.pg0.remote_ip4)
1234 if proto != IP_PROTOS.icmp:
1235 self.assertEqual(p[layer].sport, 20)
1236 self.assertEqual(p[layer].dport, self.port_in)
1238 self.assertEqual(p[layer].id, self.port_in)
1239 self.assertEqual(data, p[Raw].load)
1241 reass = self.vapi.nat_reass_dump()
1242 reass_n_end = len(reass)
1244 self.assertEqual(reass_n_end - reass_n_start, 2)
1246 def frag_in_order_in_plus_out(self, proto=IP_PROTOS.tcp):
1247 layer = self.proto2layer(proto)
1249 if proto == IP_PROTOS.tcp:
1250 data = "A" * 4 + "B" * 16 + "C" * 3
1252 data = "A" * 16 + "B" * 16 + "C" * 3
1253 self.port_in = random.randint(1025, 65535)
1256 reass = self.vapi.nat_reass_dump()
1257 reass_n_start = len(reass)
1260 pkts = self.create_stream_frag(self.pg0,
1261 self.server_out_addr,
1263 self.server_out_port,
1266 self.pg0.add_stream(pkts)
1267 self.pg_enable_capture(self.pg_interfaces)
1269 frags = self.pg1.get_capture(len(pkts))
1270 p = self.reass_frags_and_verify(frags,
1271 self.pg0.remote_ip4,
1272 self.server_in_addr)
1273 if proto != IP_PROTOS.icmp:
1274 self.assertEqual(p[layer].sport, self.port_in)
1275 self.assertEqual(p[layer].dport, self.server_in_port)
1277 self.assertEqual(p[layer].id, self.port_in)
1278 self.assertEqual(data, p[Raw].load)
1281 if proto != IP_PROTOS.icmp:
1282 pkts = self.create_stream_frag(self.pg1,
1283 self.pg0.remote_ip4,
1284 self.server_in_port,
1289 pkts = self.create_stream_frag(self.pg1,
1290 self.pg0.remote_ip4,
1296 self.pg1.add_stream(pkts)
1297 self.pg_enable_capture(self.pg_interfaces)
1299 frags = self.pg0.get_capture(len(pkts))
1300 p = self.reass_frags_and_verify(frags,
1301 self.server_out_addr,
1302 self.pg0.remote_ip4)
1303 if proto != IP_PROTOS.icmp:
1304 self.assertEqual(p[layer].sport, self.server_out_port)
1305 self.assertEqual(p[layer].dport, self.port_in)
1307 self.assertEqual(p[layer].id, self.port_in)
1308 self.assertEqual(data, p[Raw].load)
1310 reass = self.vapi.nat_reass_dump()
1311 reass_n_end = len(reass)
1313 self.assertEqual(reass_n_end - reass_n_start, 2)
1315 def reass_hairpinning(self, proto=IP_PROTOS.tcp):
1316 layer = self.proto2layer(proto)
1318 if proto == IP_PROTOS.tcp:
1319 data = "A" * 4 + "B" * 16 + "C" * 3
1321 data = "A" * 16 + "B" * 16 + "C" * 3
1323 # send packet from host to server
1324 pkts = self.create_stream_frag(self.pg0,
1327 self.server_out_port,
1330 self.pg0.add_stream(pkts)
1331 self.pg_enable_capture(self.pg_interfaces)
1333 frags = self.pg0.get_capture(len(pkts))
1334 p = self.reass_frags_and_verify(frags,
1337 if proto != IP_PROTOS.icmp:
1338 self.assertNotEqual(p[layer].sport, self.host_in_port)
1339 self.assertEqual(p[layer].dport, self.server_in_port)
1341 self.assertNotEqual(p[layer].id, self.host_in_port)
1342 self.assertEqual(data, p[Raw].load)
1344 def frag_out_of_order(self, proto=IP_PROTOS.tcp, dont_translate=False):
1345 layer = self.proto2layer(proto)
1347 if proto == IP_PROTOS.tcp:
1348 data = "A" * 4 + "B" * 16 + "C" * 3
1350 data = "A" * 16 + "B" * 16 + "C" * 3
1351 self.port_in = random.randint(1025, 65535)
1355 pkts = self.create_stream_frag(self.pg0,
1356 self.pg1.remote_ip4,
1362 self.pg0.add_stream(pkts)
1363 self.pg_enable_capture(self.pg_interfaces)
1365 frags = self.pg1.get_capture(len(pkts))
1366 if not dont_translate:
1367 p = self.reass_frags_and_verify(frags,
1369 self.pg1.remote_ip4)
1371 p = self.reass_frags_and_verify(frags,
1372 self.pg0.remote_ip4,
1373 self.pg1.remote_ip4)
1374 if proto != IP_PROTOS.icmp:
1375 if not dont_translate:
1376 self.assertEqual(p[layer].dport, 20)
1377 self.assertNotEqual(p[layer].sport, self.port_in)
1379 self.assertEqual(p[layer].sport, self.port_in)
1381 if not dont_translate:
1382 self.assertNotEqual(p[layer].id, self.port_in)
1384 self.assertEqual(p[layer].id, self.port_in)
1385 self.assertEqual(data, p[Raw].load)
1388 if not dont_translate:
1389 dst_addr = self.nat_addr
1391 dst_addr = self.pg0.remote_ip4
1392 if proto != IP_PROTOS.icmp:
1394 dport = p[layer].sport
1398 pkts = self.create_stream_frag(self.pg1,
1406 self.pg1.add_stream(pkts)
1407 self.pg_enable_capture(self.pg_interfaces)
1409 frags = self.pg0.get_capture(len(pkts))
1410 p = self.reass_frags_and_verify(frags,
1411 self.pg1.remote_ip4,
1412 self.pg0.remote_ip4)
1413 if proto != IP_PROTOS.icmp:
1414 self.assertEqual(p[layer].sport, 20)
1415 self.assertEqual(p[layer].dport, self.port_in)
1417 self.assertEqual(p[layer].id, self.port_in)
1418 self.assertEqual(data, p[Raw].load)
1420 def frag_out_of_order_in_plus_out(self, proto=IP_PROTOS.tcp):
1421 layer = self.proto2layer(proto)
1423 if proto == IP_PROTOS.tcp:
1424 data = "A" * 4 + "B" * 16 + "C" * 3
1426 data = "A" * 16 + "B" * 16 + "C" * 3
1427 self.port_in = random.randint(1025, 65535)
1431 pkts = self.create_stream_frag(self.pg0,
1432 self.server_out_addr,
1434 self.server_out_port,
1438 self.pg0.add_stream(pkts)
1439 self.pg_enable_capture(self.pg_interfaces)
1441 frags = self.pg1.get_capture(len(pkts))
1442 p = self.reass_frags_and_verify(frags,
1443 self.pg0.remote_ip4,
1444 self.server_in_addr)
1445 if proto != IP_PROTOS.icmp:
1446 self.assertEqual(p[layer].dport, self.server_in_port)
1447 self.assertEqual(p[layer].sport, self.port_in)
1448 self.assertEqual(p[layer].dport, self.server_in_port)
1450 self.assertEqual(p[layer].id, self.port_in)
1451 self.assertEqual(data, p[Raw].load)
1454 if proto != IP_PROTOS.icmp:
1455 pkts = self.create_stream_frag(self.pg1,
1456 self.pg0.remote_ip4,
1457 self.server_in_port,
1462 pkts = self.create_stream_frag(self.pg1,
1463 self.pg0.remote_ip4,
1470 self.pg1.add_stream(pkts)
1471 self.pg_enable_capture(self.pg_interfaces)
1473 frags = self.pg0.get_capture(len(pkts))
1474 p = self.reass_frags_and_verify(frags,
1475 self.server_out_addr,
1476 self.pg0.remote_ip4)
1477 if proto != IP_PROTOS.icmp:
1478 self.assertEqual(p[layer].sport, self.server_out_port)
1479 self.assertEqual(p[layer].dport, self.port_in)
1481 self.assertEqual(p[layer].id, self.port_in)
1482 self.assertEqual(data, p[Raw].load)
1485 class TestNAT44(MethodHolder):
1486 """ NAT44 Test Cases """
1489 def setUpClass(cls):
1490 super(TestNAT44, cls).setUpClass()
1491 cls.vapi.cli("set log class nat level debug")
1494 cls.tcp_port_in = 6303
1495 cls.tcp_port_out = 6303
1496 cls.udp_port_in = 6304
1497 cls.udp_port_out = 6304
1498 cls.icmp_id_in = 6305
1499 cls.icmp_id_out = 6305
1500 cls.nat_addr = '10.0.0.3'
1501 cls.nat_addr_n = socket.inet_pton(socket.AF_INET, cls.nat_addr)
1502 cls.ipfix_src_port = 4739
1503 cls.ipfix_domain_id = 1
1504 cls.tcp_external_port = 80
1505 cls.udp_external_port = 69
1507 cls.create_pg_interfaces(range(10))
1508 cls.interfaces = list(cls.pg_interfaces[0:4])
1510 for i in cls.interfaces:
1515 cls.pg0.generate_remote_hosts(3)
1516 cls.pg0.configure_ipv4_neighbors()
1518 cls.pg1.generate_remote_hosts(1)
1519 cls.pg1.configure_ipv4_neighbors()
1521 cls.overlapping_interfaces = list(list(cls.pg_interfaces[4:7]))
1522 cls.vapi.ip_table_add_del(10, is_add=1)
1523 cls.vapi.ip_table_add_del(20, is_add=1)
1525 cls.pg4._local_ip4 = "172.16.255.1"
1526 cls.pg4._local_ip4n = socket.inet_pton(socket.AF_INET, i.local_ip4)
1527 cls.pg4._remote_hosts[0]._ip4 = "172.16.255.2"
1528 cls.pg4.set_table_ip4(10)
1529 cls.pg5._local_ip4 = "172.17.255.3"
1530 cls.pg5._local_ip4n = socket.inet_pton(socket.AF_INET, i.local_ip4)
1531 cls.pg5._remote_hosts[0]._ip4 = "172.17.255.4"
1532 cls.pg5.set_table_ip4(10)
1533 cls.pg6._local_ip4 = "172.16.255.1"
1534 cls.pg6._local_ip4n = socket.inet_pton(socket.AF_INET, i.local_ip4)
1535 cls.pg6._remote_hosts[0]._ip4 = "172.16.255.2"
1536 cls.pg6.set_table_ip4(20)
1537 for i in cls.overlapping_interfaces:
1545 cls.pg9.generate_remote_hosts(2)
1546 cls.pg9.config_ip4()
1547 ip_addr_n = socket.inet_pton(socket.AF_INET, "10.0.0.1")
1548 cls.vapi.sw_interface_add_del_address(cls.pg9.sw_if_index,
1552 cls.pg9.resolve_arp()
1553 cls.pg9._remote_hosts[1]._ip4 = cls.pg9._remote_hosts[0]._ip4
1554 cls.pg4._remote_ip4 = cls.pg9._remote_hosts[0]._ip4 = "10.0.0.2"
1555 cls.pg9.resolve_arp()
1558 super(TestNAT44, cls).tearDownClass()
1561 def test_dynamic(self):
1562 """ NAT44 dynamic translation test """
1563 self.nat44_add_address(self.nat_addr)
1564 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
1565 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
1569 tcpn = self.statistics.get_counter(
1570 '/err/nat44-in2out-slowpath/TCP packets')
1571 udpn = self.statistics.get_counter(
1572 '/err/nat44-in2out-slowpath/UDP packets')
1573 icmpn = self.statistics.get_counter(
1574 '/err/nat44-in2out-slowpath/ICMP packets')
1575 totaln = self.statistics.get_counter(
1576 '/err/nat44-in2out-slowpath/good in2out packets processed')
1578 pkts = self.create_stream_in(self.pg0, self.pg1)
1579 self.pg0.add_stream(pkts)
1580 self.pg_enable_capture(self.pg_interfaces)
1582 capture = self.pg1.get_capture(len(pkts))
1583 self.verify_capture_out(capture)
1585 err = self.statistics.get_counter(
1586 '/err/nat44-in2out-slowpath/TCP packets')
1587 self.assertEqual(err - tcpn, 1)
1588 err = self.statistics.get_counter(
1589 '/err/nat44-in2out-slowpath/UDP packets')
1590 self.assertEqual(err - udpn, 1)
1591 err = self.statistics.get_counter(
1592 '/err/nat44-in2out-slowpath/ICMP packets')
1593 self.assertEqual(err - icmpn, 1)
1594 err = self.statistics.get_counter(
1595 '/err/nat44-in2out-slowpath/good in2out packets processed')
1596 self.assertEqual(err - totaln, 3)
1599 tcpn = self.statistics.get_counter('/err/nat44-out2in/TCP packets')
1600 udpn = self.statistics.get_counter('/err/nat44-out2in/UDP packets')
1601 icmpn = self.statistics.get_counter('/err/nat44-out2in/ICMP packets')
1602 totaln = self.statistics.get_counter(
1603 '/err/nat44-out2in/good out2in packets processed')
1605 pkts = self.create_stream_out(self.pg1)
1606 self.pg1.add_stream(pkts)
1607 self.pg_enable_capture(self.pg_interfaces)
1609 capture = self.pg0.get_capture(len(pkts))
1610 self.verify_capture_in(capture, self.pg0)
1612 err = self.statistics.get_counter('/err/nat44-out2in/TCP packets')
1613 self.assertEqual(err - tcpn, 1)
1614 err = self.statistics.get_counter('/err/nat44-out2in/UDP packets')
1615 self.assertEqual(err - udpn, 1)
1616 err = self.statistics.get_counter('/err/nat44-out2in/ICMP packets')
1617 self.assertEqual(err - icmpn, 1)
1618 err = self.statistics.get_counter(
1619 '/err/nat44-out2in/good out2in packets processed')
1620 self.assertEqual(err - totaln, 3)
1622 users = self.statistics.get_counter('/nat44/total-users')
1623 self.assertEqual(users[0][0], 1)
1624 sessions = self.statistics.get_counter('/nat44/total-sessions')
1625 self.assertEqual(sessions[0][0], 3)
1627 def test_dynamic_icmp_errors_in2out_ttl_1(self):
1628 """ NAT44 handling of client packets with TTL=1 """
1630 self.nat44_add_address(self.nat_addr)
1631 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
1632 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
1635 # Client side - generate traffic
1636 pkts = self.create_stream_in(self.pg0, self.pg1, ttl=1)
1637 self.pg0.add_stream(pkts)
1638 self.pg_enable_capture(self.pg_interfaces)
1641 # Client side - verify ICMP type 11 packets
1642 capture = self.pg0.get_capture(len(pkts))
1643 self.verify_capture_in_with_icmp_errors(capture, self.pg0)
1645 def test_dynamic_icmp_errors_out2in_ttl_1(self):
1646 """ NAT44 handling of server packets with TTL=1 """
1648 self.nat44_add_address(self.nat_addr)
1649 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
1650 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
1653 # Client side - create sessions
1654 pkts = self.create_stream_in(self.pg0, self.pg1)
1655 self.pg0.add_stream(pkts)
1656 self.pg_enable_capture(self.pg_interfaces)
1659 # Server side - generate traffic
1660 capture = self.pg1.get_capture(len(pkts))
1661 self.verify_capture_out(capture)
1662 pkts = self.create_stream_out(self.pg1, ttl=1)
1663 self.pg1.add_stream(pkts)
1664 self.pg_enable_capture(self.pg_interfaces)
1667 # Server side - verify ICMP type 11 packets
1668 capture = self.pg1.get_capture(len(pkts))
1669 self.verify_capture_out_with_icmp_errors(capture,
1670 src_ip=self.pg1.local_ip4)
1672 def test_dynamic_icmp_errors_in2out_ttl_2(self):
1673 """ NAT44 handling of error responses to client packets with TTL=2 """
1675 self.nat44_add_address(self.nat_addr)
1676 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
1677 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
1680 # Client side - generate traffic
1681 pkts = self.create_stream_in(self.pg0, self.pg1, ttl=2)
1682 self.pg0.add_stream(pkts)
1683 self.pg_enable_capture(self.pg_interfaces)
1686 # Server side - simulate ICMP type 11 response
1687 capture = self.pg1.get_capture(len(pkts))
1688 pkts = [Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
1689 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
1690 ICMP(type=11) / packet[IP] for packet in capture]
1691 self.pg1.add_stream(pkts)
1692 self.pg_enable_capture(self.pg_interfaces)
1695 # Client side - verify ICMP type 11 packets
1696 capture = self.pg0.get_capture(len(pkts))
1697 self.verify_capture_in_with_icmp_errors(capture, self.pg0)
1699 def test_dynamic_icmp_errors_out2in_ttl_2(self):
1700 """ NAT44 handling of error responses to server packets with TTL=2 """
1702 self.nat44_add_address(self.nat_addr)
1703 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
1704 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
1707 # Client side - create sessions
1708 pkts = self.create_stream_in(self.pg0, self.pg1)
1709 self.pg0.add_stream(pkts)
1710 self.pg_enable_capture(self.pg_interfaces)
1713 # Server side - generate traffic
1714 capture = self.pg1.get_capture(len(pkts))
1715 self.verify_capture_out(capture)
1716 pkts = self.create_stream_out(self.pg1, ttl=2)
1717 self.pg1.add_stream(pkts)
1718 self.pg_enable_capture(self.pg_interfaces)
1721 # Client side - simulate ICMP type 11 response
1722 capture = self.pg0.get_capture(len(pkts))
1723 pkts = [Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
1724 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
1725 ICMP(type=11) / packet[IP] for packet in capture]
1726 self.pg0.add_stream(pkts)
1727 self.pg_enable_capture(self.pg_interfaces)
1730 # Server side - verify ICMP type 11 packets
1731 capture = self.pg1.get_capture(len(pkts))
1732 self.verify_capture_out_with_icmp_errors(capture)
1734 def test_ping_out_interface_from_outside(self):
1735 """ Ping NAT44 out interface from outside network """
1737 self.nat44_add_address(self.nat_addr)
1738 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
1739 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
1742 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
1743 IP(src=self.pg1.remote_ip4, dst=self.pg1.local_ip4) /
1744 ICMP(id=self.icmp_id_out, type='echo-request'))
1746 self.pg1.add_stream(pkts)
1747 self.pg_enable_capture(self.pg_interfaces)
1749 capture = self.pg1.get_capture(len(pkts))
1752 self.assertEqual(packet[IP].src, self.pg1.local_ip4)
1753 self.assertEqual(packet[IP].dst, self.pg1.remote_ip4)
1754 self.assertEqual(packet[ICMP].id, self.icmp_id_in)
1755 self.assertEqual(packet[ICMP].type, 0) # echo reply
1757 self.logger.error(ppp("Unexpected or invalid packet "
1758 "(outside network):", packet))
1761 def test_ping_internal_host_from_outside(self):
1762 """ Ping internal host from outside network """
1764 self.nat44_add_static_mapping(self.pg0.remote_ip4, self.nat_addr)
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,
1770 pkt = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
1771 IP(src=self.pg1.remote_ip4, dst=self.nat_addr, ttl=64) /
1772 ICMP(id=self.icmp_id_out, type='echo-request'))
1773 self.pg1.add_stream(pkt)
1774 self.pg_enable_capture(self.pg_interfaces)
1776 capture = self.pg0.get_capture(1)
1777 self.verify_capture_in(capture, self.pg0)
1778 self.assert_equal(capture[0][IP].proto, IP_PROTOS.icmp)
1781 pkt = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
1782 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4, ttl=64) /
1783 ICMP(id=self.icmp_id_in, type='echo-reply'))
1784 self.pg0.add_stream(pkt)
1785 self.pg_enable_capture(self.pg_interfaces)
1787 capture = self.pg1.get_capture(1)
1788 self.verify_capture_out(capture, same_port=True)
1789 self.assert_equal(capture[0][IP].proto, IP_PROTOS.icmp)
1791 def test_forwarding(self):
1792 """ NAT44 forwarding test """
1794 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
1795 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
1797 self.vapi.nat44_forwarding_enable_disable(1)
1799 real_ip = self.pg0.remote_ip4n
1800 alias_ip = self.nat_addr_n
1801 self.vapi.nat44_add_del_static_mapping(local_ip=real_ip,
1802 external_ip=alias_ip)
1805 # static mapping match
1807 pkts = self.create_stream_out(self.pg1)
1808 self.pg1.add_stream(pkts)
1809 self.pg_enable_capture(self.pg_interfaces)
1811 capture = self.pg0.get_capture(len(pkts))
1812 self.verify_capture_in(capture, self.pg0)
1814 pkts = self.create_stream_in(self.pg0, self.pg1)
1815 self.pg0.add_stream(pkts)
1816 self.pg_enable_capture(self.pg_interfaces)
1818 capture = self.pg1.get_capture(len(pkts))
1819 self.verify_capture_out(capture, same_port=True)
1821 # no static mapping match
1823 host0 = self.pg0.remote_hosts[0]
1824 self.pg0.remote_hosts[0] = self.pg0.remote_hosts[1]
1826 pkts = self.create_stream_out(self.pg1,
1827 dst_ip=self.pg0.remote_ip4,
1828 use_inside_ports=True)
1829 self.pg1.add_stream(pkts)
1830 self.pg_enable_capture(self.pg_interfaces)
1832 capture = self.pg0.get_capture(len(pkts))
1833 self.verify_capture_in(capture, self.pg0)
1835 pkts = self.create_stream_in(self.pg0, self.pg1)
1836 self.pg0.add_stream(pkts)
1837 self.pg_enable_capture(self.pg_interfaces)
1839 capture = self.pg1.get_capture(len(pkts))
1840 self.verify_capture_out(capture, nat_ip=self.pg0.remote_ip4,
1843 self.pg0.remote_hosts[0] = host0
1846 self.vapi.nat44_forwarding_enable_disable(0)
1847 self.vapi.nat44_add_del_static_mapping(local_ip=real_ip,
1848 external_ip=alias_ip,
1851 def test_static_in(self):
1852 """ 1:1 NAT initialized from inside network """
1854 nat_ip = "10.0.0.10"
1855 self.tcp_port_out = 6303
1856 self.udp_port_out = 6304
1857 self.icmp_id_out = 6305
1859 self.nat44_add_static_mapping(self.pg0.remote_ip4, nat_ip)
1860 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
1861 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
1863 sm = self.vapi.nat44_static_mapping_dump()
1864 self.assertEqual(len(sm), 1)
1865 self.assertEqual((sm[0].tag).split('\0', 1)[0], '')
1866 self.assertEqual(sm[0].protocol, 0)
1867 self.assertEqual(sm[0].local_port, 0)
1868 self.assertEqual(sm[0].external_port, 0)
1871 pkts = self.create_stream_in(self.pg0, self.pg1)
1872 self.pg0.add_stream(pkts)
1873 self.pg_enable_capture(self.pg_interfaces)
1875 capture = self.pg1.get_capture(len(pkts))
1876 self.verify_capture_out(capture, nat_ip, True)
1879 pkts = self.create_stream_out(self.pg1, nat_ip)
1880 self.pg1.add_stream(pkts)
1881 self.pg_enable_capture(self.pg_interfaces)
1883 capture = self.pg0.get_capture(len(pkts))
1884 self.verify_capture_in(capture, self.pg0)
1886 def test_static_out(self):
1887 """ 1:1 NAT initialized from outside network """
1889 nat_ip = "10.0.0.20"
1890 self.tcp_port_out = 6303
1891 self.udp_port_out = 6304
1892 self.icmp_id_out = 6305
1895 self.nat44_add_static_mapping(self.pg0.remote_ip4, nat_ip, tag=tag)
1896 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
1897 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
1899 sm = self.vapi.nat44_static_mapping_dump()
1900 self.assertEqual(len(sm), 1)
1901 self.assertEqual((sm[0].tag).split('\0', 1)[0], tag)
1904 pkts = self.create_stream_out(self.pg1, nat_ip)
1905 self.pg1.add_stream(pkts)
1906 self.pg_enable_capture(self.pg_interfaces)
1908 capture = self.pg0.get_capture(len(pkts))
1909 self.verify_capture_in(capture, self.pg0)
1912 pkts = self.create_stream_in(self.pg0, self.pg1)
1913 self.pg0.add_stream(pkts)
1914 self.pg_enable_capture(self.pg_interfaces)
1916 capture = self.pg1.get_capture(len(pkts))
1917 self.verify_capture_out(capture, nat_ip, True)
1919 def test_static_with_port_in(self):
1920 """ 1:1 NAPT initialized from inside network """
1922 self.tcp_port_out = 3606
1923 self.udp_port_out = 3607
1924 self.icmp_id_out = 3608
1926 self.nat44_add_address(self.nat_addr)
1927 self.nat44_add_static_mapping(self.pg0.remote_ip4, self.nat_addr,
1928 self.tcp_port_in, self.tcp_port_out,
1929 proto=IP_PROTOS.tcp)
1930 self.nat44_add_static_mapping(self.pg0.remote_ip4, self.nat_addr,
1931 self.udp_port_in, self.udp_port_out,
1932 proto=IP_PROTOS.udp)
1933 self.nat44_add_static_mapping(self.pg0.remote_ip4, self.nat_addr,
1934 self.icmp_id_in, self.icmp_id_out,
1935 proto=IP_PROTOS.icmp)
1936 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
1937 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
1941 pkts = self.create_stream_in(self.pg0, self.pg1)
1942 self.pg0.add_stream(pkts)
1943 self.pg_enable_capture(self.pg_interfaces)
1945 capture = self.pg1.get_capture(len(pkts))
1946 self.verify_capture_out(capture)
1949 pkts = self.create_stream_out(self.pg1)
1950 self.pg1.add_stream(pkts)
1951 self.pg_enable_capture(self.pg_interfaces)
1953 capture = self.pg0.get_capture(len(pkts))
1954 self.verify_capture_in(capture, self.pg0)
1956 def test_static_with_port_out(self):
1957 """ 1:1 NAPT initialized from outside network """
1959 self.tcp_port_out = 30606
1960 self.udp_port_out = 30607
1961 self.icmp_id_out = 30608
1963 self.nat44_add_address(self.nat_addr)
1964 self.nat44_add_static_mapping(self.pg0.remote_ip4, self.nat_addr,
1965 self.tcp_port_in, self.tcp_port_out,
1966 proto=IP_PROTOS.tcp)
1967 self.nat44_add_static_mapping(self.pg0.remote_ip4, self.nat_addr,
1968 self.udp_port_in, self.udp_port_out,
1969 proto=IP_PROTOS.udp)
1970 self.nat44_add_static_mapping(self.pg0.remote_ip4, self.nat_addr,
1971 self.icmp_id_in, self.icmp_id_out,
1972 proto=IP_PROTOS.icmp)
1973 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
1974 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
1978 pkts = self.create_stream_out(self.pg1)
1979 self.pg1.add_stream(pkts)
1980 self.pg_enable_capture(self.pg_interfaces)
1982 capture = self.pg0.get_capture(len(pkts))
1983 self.verify_capture_in(capture, self.pg0)
1986 pkts = self.create_stream_in(self.pg0, self.pg1)
1987 self.pg0.add_stream(pkts)
1988 self.pg_enable_capture(self.pg_interfaces)
1990 capture = self.pg1.get_capture(len(pkts))
1991 self.verify_capture_out(capture)
1993 def test_static_vrf_aware(self):
1994 """ 1:1 NAT VRF awareness """
1996 nat_ip1 = "10.0.0.30"
1997 nat_ip2 = "10.0.0.40"
1998 self.tcp_port_out = 6303
1999 self.udp_port_out = 6304
2000 self.icmp_id_out = 6305
2002 self.nat44_add_static_mapping(self.pg4.remote_ip4, nat_ip1,
2004 self.nat44_add_static_mapping(self.pg0.remote_ip4, nat_ip2,
2006 self.vapi.nat44_interface_add_del_feature(self.pg3.sw_if_index,
2008 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
2009 self.vapi.nat44_interface_add_del_feature(self.pg4.sw_if_index)
2011 # inside interface VRF match NAT44 static mapping VRF
2012 pkts = self.create_stream_in(self.pg4, self.pg3)
2013 self.pg4.add_stream(pkts)
2014 self.pg_enable_capture(self.pg_interfaces)
2016 capture = self.pg3.get_capture(len(pkts))
2017 self.verify_capture_out(capture, nat_ip1, True)
2019 # inside interface VRF don't match NAT44 static mapping VRF (packets
2021 pkts = self.create_stream_in(self.pg0, self.pg3)
2022 self.pg0.add_stream(pkts)
2023 self.pg_enable_capture(self.pg_interfaces)
2025 self.pg3.assert_nothing_captured()
2027 def test_dynamic_to_static(self):
2028 """ Switch from dynamic translation to 1:1NAT """
2029 nat_ip = "10.0.0.10"
2030 self.tcp_port_out = 6303
2031 self.udp_port_out = 6304
2032 self.icmp_id_out = 6305
2034 self.nat44_add_address(self.nat_addr)
2035 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
2036 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
2040 pkts = self.create_stream_in(self.pg0, self.pg1)
2041 self.pg0.add_stream(pkts)
2042 self.pg_enable_capture(self.pg_interfaces)
2044 capture = self.pg1.get_capture(len(pkts))
2045 self.verify_capture_out(capture)
2048 self.nat44_add_static_mapping(self.pg0.remote_ip4, nat_ip)
2049 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4n, 0)
2050 self.assertEqual(len(sessions), 0)
2051 pkts = self.create_stream_in(self.pg0, self.pg1)
2052 self.pg0.add_stream(pkts)
2053 self.pg_enable_capture(self.pg_interfaces)
2055 capture = self.pg1.get_capture(len(pkts))
2056 self.verify_capture_out(capture, nat_ip, True)
2058 def test_identity_nat(self):
2059 """ Identity NAT """
2061 self.vapi.nat44_add_del_identity_mapping(ip=self.pg0.remote_ip4n)
2062 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
2063 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
2066 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
2067 IP(src=self.pg1.remote_ip4, dst=self.pg0.remote_ip4) /
2068 TCP(sport=12345, dport=56789))
2069 self.pg1.add_stream(p)
2070 self.pg_enable_capture(self.pg_interfaces)
2072 capture = self.pg0.get_capture(1)
2077 self.assertEqual(ip.dst, self.pg0.remote_ip4)
2078 self.assertEqual(ip.src, self.pg1.remote_ip4)
2079 self.assertEqual(tcp.dport, 56789)
2080 self.assertEqual(tcp.sport, 12345)
2081 self.assert_packet_checksums_valid(p)
2083 self.logger.error(ppp("Unexpected or invalid packet:", p))
2086 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4n, 0)
2087 self.assertEqual(len(sessions), 0)
2088 self.vapi.nat44_add_del_identity_mapping(ip=self.pg0.remote_ip4n,
2090 identity_mappings = self.vapi.nat44_identity_mapping_dump()
2091 self.assertEqual(len(identity_mappings), 2)
2093 def test_multiple_inside_interfaces(self):
2094 """ NAT44 multiple non-overlapping address space inside interfaces """
2096 self.nat44_add_address(self.nat_addr)
2097 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
2098 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index)
2099 self.vapi.nat44_interface_add_del_feature(self.pg3.sw_if_index,
2102 # between two NAT44 inside interfaces (no translation)
2103 pkts = self.create_stream_in(self.pg0, self.pg1)
2104 self.pg0.add_stream(pkts)
2105 self.pg_enable_capture(self.pg_interfaces)
2107 capture = self.pg1.get_capture(len(pkts))
2108 self.verify_capture_no_translation(capture, self.pg0, self.pg1)
2110 # from NAT44 inside to interface without NAT44 feature (no translation)
2111 pkts = self.create_stream_in(self.pg0, self.pg2)
2112 self.pg0.add_stream(pkts)
2113 self.pg_enable_capture(self.pg_interfaces)
2115 capture = self.pg2.get_capture(len(pkts))
2116 self.verify_capture_no_translation(capture, self.pg0, self.pg2)
2118 # in2out 1st interface
2119 pkts = self.create_stream_in(self.pg0, self.pg3)
2120 self.pg0.add_stream(pkts)
2121 self.pg_enable_capture(self.pg_interfaces)
2123 capture = self.pg3.get_capture(len(pkts))
2124 self.verify_capture_out(capture)
2126 # out2in 1st interface
2127 pkts = self.create_stream_out(self.pg3)
2128 self.pg3.add_stream(pkts)
2129 self.pg_enable_capture(self.pg_interfaces)
2131 capture = self.pg0.get_capture(len(pkts))
2132 self.verify_capture_in(capture, self.pg0)
2134 # in2out 2nd interface
2135 pkts = self.create_stream_in(self.pg1, self.pg3)
2136 self.pg1.add_stream(pkts)
2137 self.pg_enable_capture(self.pg_interfaces)
2139 capture = self.pg3.get_capture(len(pkts))
2140 self.verify_capture_out(capture)
2142 # out2in 2nd interface
2143 pkts = self.create_stream_out(self.pg3)
2144 self.pg3.add_stream(pkts)
2145 self.pg_enable_capture(self.pg_interfaces)
2147 capture = self.pg1.get_capture(len(pkts))
2148 self.verify_capture_in(capture, self.pg1)
2150 def test_inside_overlapping_interfaces(self):
2151 """ NAT44 multiple inside interfaces with overlapping address space """
2153 static_nat_ip = "10.0.0.10"
2154 self.nat44_add_address(self.nat_addr)
2155 self.vapi.nat44_interface_add_del_feature(self.pg3.sw_if_index,
2157 self.vapi.nat44_interface_add_del_feature(self.pg4.sw_if_index)
2158 self.vapi.nat44_interface_add_del_feature(self.pg5.sw_if_index)
2159 self.vapi.nat44_interface_add_del_feature(self.pg6.sw_if_index)
2160 self.nat44_add_static_mapping(self.pg6.remote_ip4, static_nat_ip,
2163 # between NAT44 inside interfaces with same VRF (no translation)
2164 pkts = self.create_stream_in(self.pg4, self.pg5)
2165 self.pg4.add_stream(pkts)
2166 self.pg_enable_capture(self.pg_interfaces)
2168 capture = self.pg5.get_capture(len(pkts))
2169 self.verify_capture_no_translation(capture, self.pg4, self.pg5)
2171 # between NAT44 inside interfaces with different VRF (hairpinning)
2172 p = (Ether(src=self.pg4.remote_mac, dst=self.pg4.local_mac) /
2173 IP(src=self.pg4.remote_ip4, dst=static_nat_ip) /
2174 TCP(sport=1234, dport=5678))
2175 self.pg4.add_stream(p)
2176 self.pg_enable_capture(self.pg_interfaces)
2178 capture = self.pg6.get_capture(1)
2183 self.assertEqual(ip.src, self.nat_addr)
2184 self.assertEqual(ip.dst, self.pg6.remote_ip4)
2185 self.assertNotEqual(tcp.sport, 1234)
2186 self.assertEqual(tcp.dport, 5678)
2188 self.logger.error(ppp("Unexpected or invalid packet:", p))
2191 # in2out 1st interface
2192 pkts = self.create_stream_in(self.pg4, self.pg3)
2193 self.pg4.add_stream(pkts)
2194 self.pg_enable_capture(self.pg_interfaces)
2196 capture = self.pg3.get_capture(len(pkts))
2197 self.verify_capture_out(capture)
2199 # out2in 1st interface
2200 pkts = self.create_stream_out(self.pg3)
2201 self.pg3.add_stream(pkts)
2202 self.pg_enable_capture(self.pg_interfaces)
2204 capture = self.pg4.get_capture(len(pkts))
2205 self.verify_capture_in(capture, self.pg4)
2207 # in2out 2nd interface
2208 pkts = self.create_stream_in(self.pg5, self.pg3)
2209 self.pg5.add_stream(pkts)
2210 self.pg_enable_capture(self.pg_interfaces)
2212 capture = self.pg3.get_capture(len(pkts))
2213 self.verify_capture_out(capture)
2215 # out2in 2nd interface
2216 pkts = self.create_stream_out(self.pg3)
2217 self.pg3.add_stream(pkts)
2218 self.pg_enable_capture(self.pg_interfaces)
2220 capture = self.pg5.get_capture(len(pkts))
2221 self.verify_capture_in(capture, self.pg5)
2224 addresses = self.vapi.nat44_address_dump()
2225 self.assertEqual(len(addresses), 1)
2226 sessions = self.vapi.nat44_user_session_dump(self.pg5.remote_ip4n, 10)
2227 self.assertEqual(len(sessions), 3)
2228 for session in sessions:
2229 self.assertFalse(session.is_static)
2230 self.assertEqual(session.inside_ip_address[0:4],
2231 self.pg5.remote_ip4n)
2232 self.assertEqual(session.outside_ip_address,
2233 addresses[0].ip_address)
2234 self.assertEqual(sessions[0].protocol, IP_PROTOS.tcp)
2235 self.assertEqual(sessions[1].protocol, IP_PROTOS.udp)
2236 self.assertEqual(sessions[2].protocol, IP_PROTOS.icmp)
2237 self.assertEqual(sessions[0].inside_port, self.tcp_port_in)
2238 self.assertEqual(sessions[1].inside_port, self.udp_port_in)
2239 self.assertEqual(sessions[2].inside_port, self.icmp_id_in)
2240 self.assertEqual(sessions[0].outside_port, self.tcp_port_out)
2241 self.assertEqual(sessions[1].outside_port, self.udp_port_out)
2242 self.assertEqual(sessions[2].outside_port, self.icmp_id_out)
2244 # in2out 3rd interface
2245 pkts = self.create_stream_in(self.pg6, self.pg3)
2246 self.pg6.add_stream(pkts)
2247 self.pg_enable_capture(self.pg_interfaces)
2249 capture = self.pg3.get_capture(len(pkts))
2250 self.verify_capture_out(capture, static_nat_ip, True)
2252 # out2in 3rd interface
2253 pkts = self.create_stream_out(self.pg3, static_nat_ip)
2254 self.pg3.add_stream(pkts)
2255 self.pg_enable_capture(self.pg_interfaces)
2257 capture = self.pg6.get_capture(len(pkts))
2258 self.verify_capture_in(capture, self.pg6)
2260 # general user and session dump verifications
2261 users = self.vapi.nat44_user_dump()
2262 self.assertGreaterEqual(len(users), 3)
2263 addresses = self.vapi.nat44_address_dump()
2264 self.assertEqual(len(addresses), 1)
2266 sessions = self.vapi.nat44_user_session_dump(user.ip_address,
2268 for session in sessions:
2269 self.assertEqual(user.ip_address, session.inside_ip_address)
2270 self.assertTrue(session.total_bytes > session.total_pkts > 0)
2271 self.assertTrue(session.protocol in
2272 [IP_PROTOS.tcp, IP_PROTOS.udp,
2274 self.assertFalse(session.ext_host_valid)
2277 sessions = self.vapi.nat44_user_session_dump(self.pg4.remote_ip4n, 10)
2278 self.assertGreaterEqual(len(sessions), 4)
2279 for session in sessions:
2280 self.assertFalse(session.is_static)
2281 self.assertEqual(session.inside_ip_address[0:4],
2282 self.pg4.remote_ip4n)
2283 self.assertEqual(session.outside_ip_address,
2284 addresses[0].ip_address)
2287 sessions = self.vapi.nat44_user_session_dump(self.pg6.remote_ip4n, 20)
2288 self.assertGreaterEqual(len(sessions), 3)
2289 for session in sessions:
2290 self.assertTrue(session.is_static)
2291 self.assertEqual(session.inside_ip_address[0:4],
2292 self.pg6.remote_ip4n)
2293 self.assertEqual(session.outside_ip_address,
2294 socket.inet_pton(socket.AF_INET, static_nat_ip))
2295 self.assertTrue(session.inside_port in
2296 [self.tcp_port_in, self.udp_port_in,
2299 def test_hairpinning(self):
2300 """ NAT44 hairpinning - 1:1 NAPT """
2302 host = self.pg0.remote_hosts[0]
2303 server = self.pg0.remote_hosts[1]
2306 server_in_port = 5678
2307 server_out_port = 8765
2309 self.nat44_add_address(self.nat_addr)
2310 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
2311 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
2313 # add static mapping for server
2314 self.nat44_add_static_mapping(server.ip4, self.nat_addr,
2315 server_in_port, server_out_port,
2316 proto=IP_PROTOS.tcp)
2318 # send packet from host to server
2319 p = (Ether(src=host.mac, dst=self.pg0.local_mac) /
2320 IP(src=host.ip4, dst=self.nat_addr) /
2321 TCP(sport=host_in_port, dport=server_out_port))
2322 self.pg0.add_stream(p)
2323 self.pg_enable_capture(self.pg_interfaces)
2325 capture = self.pg0.get_capture(1)
2330 self.assertEqual(ip.src, self.nat_addr)
2331 self.assertEqual(ip.dst, server.ip4)
2332 self.assertNotEqual(tcp.sport, host_in_port)
2333 self.assertEqual(tcp.dport, server_in_port)
2334 self.assert_packet_checksums_valid(p)
2335 host_out_port = tcp.sport
2337 self.logger.error(ppp("Unexpected or invalid packet:", p))
2340 # send reply from server to host
2341 p = (Ether(src=server.mac, dst=self.pg0.local_mac) /
2342 IP(src=server.ip4, dst=self.nat_addr) /
2343 TCP(sport=server_in_port, dport=host_out_port))
2344 self.pg0.add_stream(p)
2345 self.pg_enable_capture(self.pg_interfaces)
2347 capture = self.pg0.get_capture(1)
2352 self.assertEqual(ip.src, self.nat_addr)
2353 self.assertEqual(ip.dst, host.ip4)
2354 self.assertEqual(tcp.sport, server_out_port)
2355 self.assertEqual(tcp.dport, host_in_port)
2356 self.assert_packet_checksums_valid(p)
2358 self.logger.error(ppp("Unexpected or invalid packet:", p))
2361 def test_hairpinning2(self):
2362 """ NAT44 hairpinning - 1:1 NAT"""
2364 server1_nat_ip = "10.0.0.10"
2365 server2_nat_ip = "10.0.0.11"
2366 host = self.pg0.remote_hosts[0]
2367 server1 = self.pg0.remote_hosts[1]
2368 server2 = self.pg0.remote_hosts[2]
2369 server_tcp_port = 22
2370 server_udp_port = 20
2372 self.nat44_add_address(self.nat_addr)
2373 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
2374 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
2377 # add static mapping for servers
2378 self.nat44_add_static_mapping(server1.ip4, server1_nat_ip)
2379 self.nat44_add_static_mapping(server2.ip4, server2_nat_ip)
2383 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2384 IP(src=host.ip4, dst=server1_nat_ip) /
2385 TCP(sport=self.tcp_port_in, dport=server_tcp_port))
2387 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2388 IP(src=host.ip4, dst=server1_nat_ip) /
2389 UDP(sport=self.udp_port_in, dport=server_udp_port))
2391 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2392 IP(src=host.ip4, dst=server1_nat_ip) /
2393 ICMP(id=self.icmp_id_in, type='echo-request'))
2395 self.pg0.add_stream(pkts)
2396 self.pg_enable_capture(self.pg_interfaces)
2398 capture = self.pg0.get_capture(len(pkts))
2399 for packet in capture:
2401 self.assertEqual(packet[IP].src, self.nat_addr)
2402 self.assertEqual(packet[IP].dst, server1.ip4)
2403 if packet.haslayer(TCP):
2404 self.assertNotEqual(packet[TCP].sport, self.tcp_port_in)
2405 self.assertEqual(packet[TCP].dport, server_tcp_port)
2406 self.tcp_port_out = packet[TCP].sport
2407 self.assert_packet_checksums_valid(packet)
2408 elif packet.haslayer(UDP):
2409 self.assertNotEqual(packet[UDP].sport, self.udp_port_in)
2410 self.assertEqual(packet[UDP].dport, server_udp_port)
2411 self.udp_port_out = packet[UDP].sport
2413 self.assertNotEqual(packet[ICMP].id, self.icmp_id_in)
2414 self.icmp_id_out = packet[ICMP].id
2416 self.logger.error(ppp("Unexpected or invalid packet:", packet))
2421 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2422 IP(src=server1.ip4, dst=self.nat_addr) /
2423 TCP(sport=server_tcp_port, dport=self.tcp_port_out))
2425 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2426 IP(src=server1.ip4, dst=self.nat_addr) /
2427 UDP(sport=server_udp_port, dport=self.udp_port_out))
2429 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2430 IP(src=server1.ip4, dst=self.nat_addr) /
2431 ICMP(id=self.icmp_id_out, type='echo-reply'))
2433 self.pg0.add_stream(pkts)
2434 self.pg_enable_capture(self.pg_interfaces)
2436 capture = self.pg0.get_capture(len(pkts))
2437 for packet in capture:
2439 self.assertEqual(packet[IP].src, server1_nat_ip)
2440 self.assertEqual(packet[IP].dst, host.ip4)
2441 if packet.haslayer(TCP):
2442 self.assertEqual(packet[TCP].dport, self.tcp_port_in)
2443 self.assertEqual(packet[TCP].sport, server_tcp_port)
2444 self.assert_packet_checksums_valid(packet)
2445 elif packet.haslayer(UDP):
2446 self.assertEqual(packet[UDP].dport, self.udp_port_in)
2447 self.assertEqual(packet[UDP].sport, server_udp_port)
2449 self.assertEqual(packet[ICMP].id, self.icmp_id_in)
2451 self.logger.error(ppp("Unexpected or invalid packet:", packet))
2454 # server2 to server1
2456 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2457 IP(src=server2.ip4, dst=server1_nat_ip) /
2458 TCP(sport=self.tcp_port_in, dport=server_tcp_port))
2460 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2461 IP(src=server2.ip4, dst=server1_nat_ip) /
2462 UDP(sport=self.udp_port_in, dport=server_udp_port))
2464 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2465 IP(src=server2.ip4, dst=server1_nat_ip) /
2466 ICMP(id=self.icmp_id_in, type='echo-request'))
2468 self.pg0.add_stream(pkts)
2469 self.pg_enable_capture(self.pg_interfaces)
2471 capture = self.pg0.get_capture(len(pkts))
2472 for packet in capture:
2474 self.assertEqual(packet[IP].src, server2_nat_ip)
2475 self.assertEqual(packet[IP].dst, server1.ip4)
2476 if packet.haslayer(TCP):
2477 self.assertEqual(packet[TCP].sport, self.tcp_port_in)
2478 self.assertEqual(packet[TCP].dport, server_tcp_port)
2479 self.tcp_port_out = packet[TCP].sport
2480 self.assert_packet_checksums_valid(packet)
2481 elif packet.haslayer(UDP):
2482 self.assertEqual(packet[UDP].sport, self.udp_port_in)
2483 self.assertEqual(packet[UDP].dport, server_udp_port)
2484 self.udp_port_out = packet[UDP].sport
2486 self.assertEqual(packet[ICMP].id, self.icmp_id_in)
2487 self.icmp_id_out = packet[ICMP].id
2489 self.logger.error(ppp("Unexpected or invalid packet:", packet))
2492 # server1 to server2
2494 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2495 IP(src=server1.ip4, dst=server2_nat_ip) /
2496 TCP(sport=server_tcp_port, dport=self.tcp_port_out))
2498 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2499 IP(src=server1.ip4, dst=server2_nat_ip) /
2500 UDP(sport=server_udp_port, dport=self.udp_port_out))
2502 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2503 IP(src=server1.ip4, dst=server2_nat_ip) /
2504 ICMP(id=self.icmp_id_out, type='echo-reply'))
2506 self.pg0.add_stream(pkts)
2507 self.pg_enable_capture(self.pg_interfaces)
2509 capture = self.pg0.get_capture(len(pkts))
2510 for packet in capture:
2512 self.assertEqual(packet[IP].src, server1_nat_ip)
2513 self.assertEqual(packet[IP].dst, server2.ip4)
2514 if packet.haslayer(TCP):
2515 self.assertEqual(packet[TCP].dport, self.tcp_port_in)
2516 self.assertEqual(packet[TCP].sport, server_tcp_port)
2517 self.assert_packet_checksums_valid(packet)
2518 elif packet.haslayer(UDP):
2519 self.assertEqual(packet[UDP].dport, self.udp_port_in)
2520 self.assertEqual(packet[UDP].sport, server_udp_port)
2522 self.assertEqual(packet[ICMP].id, self.icmp_id_in)
2524 self.logger.error(ppp("Unexpected or invalid packet:", packet))
2527 def test_max_translations_per_user(self):
2528 """ MAX translations per user - recycle the least recently used """
2530 self.nat44_add_address(self.nat_addr)
2531 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
2532 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
2535 # get maximum number of translations per user
2536 nat44_config = self.vapi.nat_show_config()
2538 # send more than maximum number of translations per user packets
2539 pkts_num = nat44_config.max_translations_per_user + 5
2541 for port in range(0, pkts_num):
2542 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2543 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
2544 TCP(sport=1025 + port))
2546 self.pg0.add_stream(pkts)
2547 self.pg_enable_capture(self.pg_interfaces)
2550 # verify number of translated packet
2551 self.pg1.get_capture(pkts_num)
2553 users = self.vapi.nat44_user_dump()
2555 if user.ip_address == self.pg0.remote_ip4n:
2556 self.assertEqual(user.nsessions,
2557 nat44_config.max_translations_per_user)
2558 self.assertEqual(user.nstaticsessions, 0)
2561 self.nat44_add_static_mapping(self.pg0.remote_ip4, self.nat_addr,
2563 proto=IP_PROTOS.tcp)
2564 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2565 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
2566 TCP(sport=tcp_port))
2567 self.pg0.add_stream(p)
2568 self.pg_enable_capture(self.pg_interfaces)
2570 self.pg1.get_capture(1)
2571 users = self.vapi.nat44_user_dump()
2573 if user.ip_address == self.pg0.remote_ip4n:
2574 self.assertEqual(user.nsessions,
2575 nat44_config.max_translations_per_user - 1)
2576 self.assertEqual(user.nstaticsessions, 1)
2578 def test_interface_addr(self):
2579 """ Acquire NAT44 addresses from interface """
2580 self.vapi.nat44_add_interface_addr(self.pg7.sw_if_index)
2582 # no address in NAT pool
2583 adresses = self.vapi.nat44_address_dump()
2584 self.assertEqual(0, len(adresses))
2586 # configure interface address and check NAT address pool
2587 self.pg7.config_ip4()
2588 adresses = self.vapi.nat44_address_dump()
2589 self.assertEqual(1, len(adresses))
2590 self.assertEqual(adresses[0].ip_address[0:4], self.pg7.local_ip4n)
2592 # remove interface address and check NAT address pool
2593 self.pg7.unconfig_ip4()
2594 adresses = self.vapi.nat44_address_dump()
2595 self.assertEqual(0, len(adresses))
2597 def test_interface_addr_static_mapping(self):
2598 """ Static mapping with addresses from interface """
2601 self.vapi.nat44_add_interface_addr(self.pg7.sw_if_index)
2602 self.nat44_add_static_mapping(
2604 external_sw_if_index=self.pg7.sw_if_index,
2607 # static mappings with external interface
2608 static_mappings = self.vapi.nat44_static_mapping_dump()
2609 self.assertEqual(1, len(static_mappings))
2610 self.assertEqual(self.pg7.sw_if_index,
2611 static_mappings[0].external_sw_if_index)
2612 self.assertEqual((static_mappings[0].tag).split('\0', 1)[0], tag)
2614 # configure interface address and check static mappings
2615 self.pg7.config_ip4()
2616 static_mappings = self.vapi.nat44_static_mapping_dump()
2617 self.assertEqual(2, len(static_mappings))
2619 for sm in static_mappings:
2620 if sm.external_sw_if_index == 0xFFFFFFFF:
2621 self.assertEqual(sm.external_ip_address[0:4],
2622 self.pg7.local_ip4n)
2623 self.assertEqual((sm.tag).split('\0', 1)[0], tag)
2625 self.assertTrue(resolved)
2627 # remove interface address and check static mappings
2628 self.pg7.unconfig_ip4()
2629 static_mappings = self.vapi.nat44_static_mapping_dump()
2630 self.assertEqual(1, len(static_mappings))
2631 self.assertEqual(self.pg7.sw_if_index,
2632 static_mappings[0].external_sw_if_index)
2633 self.assertEqual((static_mappings[0].tag).split('\0', 1)[0], tag)
2635 # configure interface address again and check static mappings
2636 self.pg7.config_ip4()
2637 static_mappings = self.vapi.nat44_static_mapping_dump()
2638 self.assertEqual(2, len(static_mappings))
2640 for sm in static_mappings:
2641 if sm.external_sw_if_index == 0xFFFFFFFF:
2642 self.assertEqual(sm.external_ip_address[0:4],
2643 self.pg7.local_ip4n)
2644 self.assertEqual((sm.tag).split('\0', 1)[0], tag)
2646 self.assertTrue(resolved)
2648 # remove static mapping
2649 self.nat44_add_static_mapping(
2651 external_sw_if_index=self.pg7.sw_if_index,
2654 static_mappings = self.vapi.nat44_static_mapping_dump()
2655 self.assertEqual(0, len(static_mappings))
2657 def test_interface_addr_identity_nat(self):
2658 """ Identity NAT with addresses from interface """
2661 self.vapi.nat44_add_interface_addr(self.pg7.sw_if_index)
2662 self.vapi.nat44_add_del_identity_mapping(
2663 sw_if_index=self.pg7.sw_if_index,
2665 protocol=IP_PROTOS.tcp,
2668 # identity mappings with external interface
2669 identity_mappings = self.vapi.nat44_identity_mapping_dump()
2670 self.assertEqual(1, len(identity_mappings))
2671 self.assertEqual(self.pg7.sw_if_index,
2672 identity_mappings[0].sw_if_index)
2674 # configure interface address and check identity mappings
2675 self.pg7.config_ip4()
2676 identity_mappings = self.vapi.nat44_identity_mapping_dump()
2678 self.assertEqual(2, len(identity_mappings))
2679 for sm in identity_mappings:
2680 if sm.sw_if_index == 0xFFFFFFFF:
2681 self.assertEqual(identity_mappings[0].ip_address,
2682 self.pg7.local_ip4n)
2683 self.assertEqual(port, identity_mappings[0].port)
2684 self.assertEqual(IP_PROTOS.tcp, identity_mappings[0].protocol)
2686 self.assertTrue(resolved)
2688 # remove interface address and check identity mappings
2689 self.pg7.unconfig_ip4()
2690 identity_mappings = self.vapi.nat44_identity_mapping_dump()
2691 self.assertEqual(1, len(identity_mappings))
2692 self.assertEqual(self.pg7.sw_if_index,
2693 identity_mappings[0].sw_if_index)
2695 def test_ipfix_nat44_sess(self):
2696 """ IPFIX logging NAT44 session created/delted """
2697 self.ipfix_domain_id = 10
2698 self.ipfix_src_port = 20202
2699 colector_port = 30303
2700 bind_layers(UDP, IPFIX, dport=30303)
2701 self.nat44_add_address(self.nat_addr)
2702 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
2703 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
2705 self.vapi.set_ipfix_exporter(collector_address=self.pg3.remote_ip4n,
2706 src_address=self.pg3.local_ip4n,
2708 template_interval=10,
2709 collector_port=colector_port)
2710 self.vapi.nat_ipfix(domain_id=self.ipfix_domain_id,
2711 src_port=self.ipfix_src_port)
2713 pkts = self.create_stream_in(self.pg0, self.pg1)
2714 self.pg0.add_stream(pkts)
2715 self.pg_enable_capture(self.pg_interfaces)
2717 capture = self.pg1.get_capture(len(pkts))
2718 self.verify_capture_out(capture)
2719 self.nat44_add_address(self.nat_addr, is_add=0)
2720 self.vapi.cli("ipfix flush") # FIXME this should be an API call
2721 capture = self.pg3.get_capture(9)
2722 ipfix = IPFIXDecoder()
2723 # first load template
2725 self.assertTrue(p.haslayer(IPFIX))
2726 self.assertEqual(p[IP].src, self.pg3.local_ip4)
2727 self.assertEqual(p[IP].dst, self.pg3.remote_ip4)
2728 self.assertEqual(p[UDP].sport, self.ipfix_src_port)
2729 self.assertEqual(p[UDP].dport, colector_port)
2730 self.assertEqual(p[IPFIX].observationDomainID,
2731 self.ipfix_domain_id)
2732 if p.haslayer(Template):
2733 ipfix.add_template(p.getlayer(Template))
2734 # verify events in data set
2736 if p.haslayer(Data):
2737 data = ipfix.decode_data_set(p.getlayer(Set))
2738 self.verify_ipfix_nat44_ses(data)
2740 def test_ipfix_addr_exhausted(self):
2741 """ IPFIX logging NAT addresses exhausted """
2742 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
2743 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
2745 self.vapi.set_ipfix_exporter(collector_address=self.pg3.remote_ip4n,
2746 src_address=self.pg3.local_ip4n,
2748 template_interval=10)
2749 self.vapi.nat_ipfix(domain_id=self.ipfix_domain_id,
2750 src_port=self.ipfix_src_port)
2752 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
2753 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
2755 self.pg0.add_stream(p)
2756 self.pg_enable_capture(self.pg_interfaces)
2758 self.pg1.assert_nothing_captured()
2760 self.vapi.cli("ipfix flush") # FIXME this should be an API call
2761 capture = self.pg3.get_capture(9)
2762 ipfix = IPFIXDecoder()
2763 # first load template
2765 self.assertTrue(p.haslayer(IPFIX))
2766 self.assertEqual(p[IP].src, self.pg3.local_ip4)
2767 self.assertEqual(p[IP].dst, self.pg3.remote_ip4)
2768 self.assertEqual(p[UDP].sport, self.ipfix_src_port)
2769 self.assertEqual(p[UDP].dport, 4739)
2770 self.assertEqual(p[IPFIX].observationDomainID,
2771 self.ipfix_domain_id)
2772 if p.haslayer(Template):
2773 ipfix.add_template(p.getlayer(Template))
2774 # verify events in data set
2776 if p.haslayer(Data):
2777 data = ipfix.decode_data_set(p.getlayer(Set))
2778 self.verify_ipfix_addr_exhausted(data)
2780 @unittest.skipUnless(running_extended_tests, "part of extended tests")
2781 def test_ipfix_max_sessions(self):
2782 """ IPFIX logging maximum session entries exceeded """
2783 self.nat44_add_address(self.nat_addr)
2784 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
2785 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
2788 nat44_config = self.vapi.nat_show_config()
2789 max_sessions = 10 * nat44_config.translation_buckets
2792 for i in range(0, max_sessions):
2793 src = "10.10.%u.%u" % ((i & 0xFF00) >> 8, i & 0xFF)
2794 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2795 IP(src=src, dst=self.pg1.remote_ip4) /
2798 self.pg0.add_stream(pkts)
2799 self.pg_enable_capture(self.pg_interfaces)
2802 self.pg1.get_capture(max_sessions)
2803 self.vapi.set_ipfix_exporter(collector_address=self.pg3.remote_ip4n,
2804 src_address=self.pg3.local_ip4n,
2806 template_interval=10)
2807 self.vapi.nat_ipfix(domain_id=self.ipfix_domain_id,
2808 src_port=self.ipfix_src_port)
2810 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2811 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
2813 self.pg0.add_stream(p)
2814 self.pg_enable_capture(self.pg_interfaces)
2816 self.pg1.assert_nothing_captured()
2818 self.vapi.cli("ipfix flush") # FIXME this should be an API call
2819 capture = self.pg3.get_capture(9)
2820 ipfix = IPFIXDecoder()
2821 # first load template
2823 self.assertTrue(p.haslayer(IPFIX))
2824 self.assertEqual(p[IP].src, self.pg3.local_ip4)
2825 self.assertEqual(p[IP].dst, self.pg3.remote_ip4)
2826 self.assertEqual(p[UDP].sport, self.ipfix_src_port)
2827 self.assertEqual(p[UDP].dport, 4739)
2828 self.assertEqual(p[IPFIX].observationDomainID,
2829 self.ipfix_domain_id)
2830 if p.haslayer(Template):
2831 ipfix.add_template(p.getlayer(Template))
2832 # verify events in data set
2834 if p.haslayer(Data):
2835 data = ipfix.decode_data_set(p.getlayer(Set))
2836 self.verify_ipfix_max_sessions(data, max_sessions)
2838 def test_syslog_apmap(self):
2839 """ Test syslog address and port mapping creation and deletion """
2840 self.vapi.syslog_set_filter(SYSLOG_SEVERITY.INFO)
2841 self.vapi.syslog_set_sender(self.pg3.remote_ip4n, self.pg3.local_ip4n)
2842 self.nat44_add_address(self.nat_addr)
2843 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
2844 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
2847 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2848 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
2849 TCP(sport=self.tcp_port_in, dport=20))
2850 self.pg0.add_stream(p)
2851 self.pg_enable_capture(self.pg_interfaces)
2853 capture = self.pg1.get_capture(1)
2854 self.tcp_port_out = capture[0][TCP].sport
2855 capture = self.pg3.get_capture(1)
2856 self.verify_syslog_apmap(capture[0][Raw].load)
2858 self.pg_enable_capture(self.pg_interfaces)
2860 self.nat44_add_address(self.nat_addr, is_add=0)
2861 capture = self.pg3.get_capture(1)
2862 self.verify_syslog_apmap(capture[0][Raw].load, False)
2864 def test_pool_addr_fib(self):
2865 """ NAT44 add pool addresses to FIB """
2866 static_addr = '10.0.0.10'
2867 self.nat44_add_address(self.nat_addr)
2868 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
2869 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
2871 self.nat44_add_static_mapping(self.pg0.remote_ip4, static_addr)
2874 p = (Ether(src=self.pg1.remote_mac, dst='ff:ff:ff:ff:ff:ff') /
2875 ARP(op=ARP.who_has, pdst=self.nat_addr,
2876 psrc=self.pg1.remote_ip4, hwsrc=self.pg1.remote_mac))
2877 self.pg1.add_stream(p)
2878 self.pg_enable_capture(self.pg_interfaces)
2880 capture = self.pg1.get_capture(1)
2881 self.assertTrue(capture[0].haslayer(ARP))
2882 self.assertTrue(capture[0][ARP].op, ARP.is_at)
2885 p = (Ether(src=self.pg1.remote_mac, dst='ff:ff:ff:ff:ff:ff') /
2886 ARP(op=ARP.who_has, pdst=static_addr,
2887 psrc=self.pg1.remote_ip4, hwsrc=self.pg1.remote_mac))
2888 self.pg1.add_stream(p)
2889 self.pg_enable_capture(self.pg_interfaces)
2891 capture = self.pg1.get_capture(1)
2892 self.assertTrue(capture[0].haslayer(ARP))
2893 self.assertTrue(capture[0][ARP].op, ARP.is_at)
2895 # send ARP to non-NAT44 interface
2896 p = (Ether(src=self.pg2.remote_mac, dst='ff:ff:ff:ff:ff:ff') /
2897 ARP(op=ARP.who_has, pdst=self.nat_addr,
2898 psrc=self.pg2.remote_ip4, hwsrc=self.pg2.remote_mac))
2899 self.pg2.add_stream(p)
2900 self.pg_enable_capture(self.pg_interfaces)
2902 self.pg1.assert_nothing_captured()
2904 # remove addresses and verify
2905 self.nat44_add_address(self.nat_addr, is_add=0)
2906 self.nat44_add_static_mapping(self.pg0.remote_ip4, static_addr,
2909 p = (Ether(src=self.pg1.remote_mac, dst='ff:ff:ff:ff:ff:ff') /
2910 ARP(op=ARP.who_has, pdst=self.nat_addr,
2911 psrc=self.pg1.remote_ip4, hwsrc=self.pg1.remote_mac))
2912 self.pg1.add_stream(p)
2913 self.pg_enable_capture(self.pg_interfaces)
2915 self.pg1.assert_nothing_captured()
2917 p = (Ether(src=self.pg1.remote_mac, dst='ff:ff:ff:ff:ff:ff') /
2918 ARP(op=ARP.who_has, pdst=static_addr,
2919 psrc=self.pg1.remote_ip4, hwsrc=self.pg1.remote_mac))
2920 self.pg1.add_stream(p)
2921 self.pg_enable_capture(self.pg_interfaces)
2923 self.pg1.assert_nothing_captured()
2925 def test_vrf_mode(self):
2926 """ NAT44 tenant VRF aware address pool mode """
2930 nat_ip1 = "10.0.0.10"
2931 nat_ip2 = "10.0.0.11"
2933 self.pg0.unconfig_ip4()
2934 self.pg1.unconfig_ip4()
2935 self.vapi.ip_table_add_del(vrf_id1, is_add=1)
2936 self.vapi.ip_table_add_del(vrf_id2, is_add=1)
2937 self.pg0.set_table_ip4(vrf_id1)
2938 self.pg1.set_table_ip4(vrf_id2)
2939 self.pg0.config_ip4()
2940 self.pg1.config_ip4()
2941 self.pg0.resolve_arp()
2942 self.pg1.resolve_arp()
2944 self.nat44_add_address(nat_ip1, vrf_id=vrf_id1)
2945 self.nat44_add_address(nat_ip2, vrf_id=vrf_id2)
2946 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
2947 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index)
2948 self.vapi.nat44_interface_add_del_feature(self.pg2.sw_if_index,
2953 pkts = self.create_stream_in(self.pg0, self.pg2)
2954 self.pg0.add_stream(pkts)
2955 self.pg_enable_capture(self.pg_interfaces)
2957 capture = self.pg2.get_capture(len(pkts))
2958 self.verify_capture_out(capture, nat_ip1)
2961 pkts = self.create_stream_in(self.pg1, self.pg2)
2962 self.pg1.add_stream(pkts)
2963 self.pg_enable_capture(self.pg_interfaces)
2965 capture = self.pg2.get_capture(len(pkts))
2966 self.verify_capture_out(capture, nat_ip2)
2969 self.pg0.unconfig_ip4()
2970 self.pg1.unconfig_ip4()
2971 self.pg0.set_table_ip4(0)
2972 self.pg1.set_table_ip4(0)
2973 self.pg0.config_ip4()
2974 self.pg1.config_ip4()
2975 self.pg0.resolve_arp()
2976 self.pg1.resolve_arp()
2977 self.vapi.ip_table_add_del(vrf_id1, is_add=0)
2978 self.vapi.ip_table_add_del(vrf_id2, is_add=0)
2980 def test_vrf_feature_independent(self):
2981 """ NAT44 tenant VRF independent address pool mode """
2983 nat_ip1 = "10.0.0.10"
2984 nat_ip2 = "10.0.0.11"
2986 self.nat44_add_address(nat_ip1)
2987 self.nat44_add_address(nat_ip2, vrf_id=99)
2988 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
2989 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index)
2990 self.vapi.nat44_interface_add_del_feature(self.pg2.sw_if_index,
2994 pkts = self.create_stream_in(self.pg0, self.pg2)
2995 self.pg0.add_stream(pkts)
2996 self.pg_enable_capture(self.pg_interfaces)
2998 capture = self.pg2.get_capture(len(pkts))
2999 self.verify_capture_out(capture, nat_ip1)
3002 pkts = self.create_stream_in(self.pg1, self.pg2)
3003 self.pg1.add_stream(pkts)
3004 self.pg_enable_capture(self.pg_interfaces)
3006 capture = self.pg2.get_capture(len(pkts))
3007 self.verify_capture_out(capture, nat_ip1)
3009 def test_dynamic_ipless_interfaces(self):
3010 """ NAT44 interfaces without configured IP address """
3012 self.vapi.ip_neighbor_add_del(
3013 self.pg7.sw_if_index,
3014 self.pg7.remote_mac,
3015 self.pg7.remote_ip4,
3016 flags=(VppEnum.vl_api_ip_neighbor_flags_t.
3017 IP_API_NEIGHBOR_FLAG_STATIC))
3018 self.vapi.ip_neighbor_add_del(
3019 self.pg8.sw_if_index,
3020 self.pg8.remote_mac,
3021 self.pg8.remote_ip4,
3022 flags=(VppEnum.vl_api_ip_neighbor_flags_t.
3023 IP_API_NEIGHBOR_FLAG_STATIC))
3025 self.vapi.ip_add_del_route(dst_address=self.pg7.remote_ip4n,
3026 dst_address_length=32,
3027 next_hop_address=self.pg7.remote_ip4n,
3028 next_hop_sw_if_index=self.pg7.sw_if_index)
3029 self.vapi.ip_add_del_route(dst_address=self.pg8.remote_ip4n,
3030 dst_address_length=32,
3031 next_hop_address=self.pg8.remote_ip4n,
3032 next_hop_sw_if_index=self.pg8.sw_if_index)
3034 self.nat44_add_address(self.nat_addr)
3035 self.vapi.nat44_interface_add_del_feature(self.pg7.sw_if_index)
3036 self.vapi.nat44_interface_add_del_feature(self.pg8.sw_if_index,
3040 pkts = self.create_stream_in(self.pg7, self.pg8)
3041 self.pg7.add_stream(pkts)
3042 self.pg_enable_capture(self.pg_interfaces)
3044 capture = self.pg8.get_capture(len(pkts))
3045 self.verify_capture_out(capture)
3048 pkts = self.create_stream_out(self.pg8, self.nat_addr)
3049 self.pg8.add_stream(pkts)
3050 self.pg_enable_capture(self.pg_interfaces)
3052 capture = self.pg7.get_capture(len(pkts))
3053 self.verify_capture_in(capture, self.pg7)
3055 def test_static_ipless_interfaces(self):
3056 """ NAT44 interfaces without configured IP address - 1:1 NAT """
3058 self.vapi.ip_neighbor_add_del(
3059 self.pg7.sw_if_index,
3060 self.pg7.remote_mac,
3061 self.pg7.remote_ip4,
3062 flags=(VppEnum.vl_api_ip_neighbor_flags_t.
3063 IP_API_NEIGHBOR_FLAG_STATIC))
3064 self.vapi.ip_neighbor_add_del(
3065 self.pg8.sw_if_index,
3066 self.pg8.remote_mac,
3067 self.pg8.remote_ip4,
3068 flags=(VppEnum.vl_api_ip_neighbor_flags_t.
3069 IP_API_NEIGHBOR_FLAG_STATIC))
3071 self.vapi.ip_add_del_route(dst_address=self.pg7.remote_ip4n,
3072 dst_address_length=32,
3073 next_hop_address=self.pg7.remote_ip4n,
3074 next_hop_sw_if_index=self.pg7.sw_if_index)
3075 self.vapi.ip_add_del_route(dst_address=self.pg8.remote_ip4n,
3076 dst_address_length=32,
3077 next_hop_address=self.pg8.remote_ip4n,
3078 next_hop_sw_if_index=self.pg8.sw_if_index)
3080 self.nat44_add_static_mapping(self.pg7.remote_ip4, self.nat_addr)
3081 self.vapi.nat44_interface_add_del_feature(self.pg7.sw_if_index)
3082 self.vapi.nat44_interface_add_del_feature(self.pg8.sw_if_index,
3086 pkts = self.create_stream_out(self.pg8)
3087 self.pg8.add_stream(pkts)
3088 self.pg_enable_capture(self.pg_interfaces)
3090 capture = self.pg7.get_capture(len(pkts))
3091 self.verify_capture_in(capture, self.pg7)
3094 pkts = self.create_stream_in(self.pg7, self.pg8)
3095 self.pg7.add_stream(pkts)
3096 self.pg_enable_capture(self.pg_interfaces)
3098 capture = self.pg8.get_capture(len(pkts))
3099 self.verify_capture_out(capture, self.nat_addr, True)
3101 def test_static_with_port_ipless_interfaces(self):
3102 """ NAT44 interfaces without configured IP address - 1:1 NAPT """
3104 self.tcp_port_out = 30606
3105 self.udp_port_out = 30607
3106 self.icmp_id_out = 30608
3108 self.vapi.ip_neighbor_add_del(
3109 self.pg7.sw_if_index,
3110 self.pg7.remote_mac,
3111 self.pg7.remote_ip4,
3112 flags=(VppEnum.vl_api_ip_neighbor_flags_t.
3113 IP_API_NEIGHBOR_FLAG_STATIC))
3114 self.vapi.ip_neighbor_add_del(
3115 self.pg8.sw_if_index,
3116 self.pg8.remote_mac,
3117 self.pg8.remote_ip4,
3118 flags=(VppEnum.vl_api_ip_neighbor_flags_t.
3119 IP_API_NEIGHBOR_FLAG_STATIC))
3121 self.vapi.ip_add_del_route(dst_address=self.pg7.remote_ip4n,
3122 dst_address_length=32,
3123 next_hop_address=self.pg7.remote_ip4n,
3124 next_hop_sw_if_index=self.pg7.sw_if_index)
3125 self.vapi.ip_add_del_route(dst_address=self.pg8.remote_ip4n,
3126 dst_address_length=32,
3127 next_hop_address=self.pg8.remote_ip4n,
3128 next_hop_sw_if_index=self.pg8.sw_if_index)
3130 self.nat44_add_address(self.nat_addr)
3131 self.nat44_add_static_mapping(self.pg7.remote_ip4, self.nat_addr,
3132 self.tcp_port_in, self.tcp_port_out,
3133 proto=IP_PROTOS.tcp)
3134 self.nat44_add_static_mapping(self.pg7.remote_ip4, self.nat_addr,
3135 self.udp_port_in, self.udp_port_out,
3136 proto=IP_PROTOS.udp)
3137 self.nat44_add_static_mapping(self.pg7.remote_ip4, self.nat_addr,
3138 self.icmp_id_in, self.icmp_id_out,
3139 proto=IP_PROTOS.icmp)
3140 self.vapi.nat44_interface_add_del_feature(self.pg7.sw_if_index)
3141 self.vapi.nat44_interface_add_del_feature(self.pg8.sw_if_index,
3145 pkts = self.create_stream_out(self.pg8)
3146 self.pg8.add_stream(pkts)
3147 self.pg_enable_capture(self.pg_interfaces)
3149 capture = self.pg7.get_capture(len(pkts))
3150 self.verify_capture_in(capture, self.pg7)
3153 pkts = self.create_stream_in(self.pg7, self.pg8)
3154 self.pg7.add_stream(pkts)
3155 self.pg_enable_capture(self.pg_interfaces)
3157 capture = self.pg8.get_capture(len(pkts))
3158 self.verify_capture_out(capture)
3160 def test_static_unknown_proto(self):
3161 """ 1:1 NAT translate packet with unknown protocol """
3162 nat_ip = "10.0.0.10"
3163 self.nat44_add_static_mapping(self.pg0.remote_ip4, nat_ip)
3164 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
3165 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
3169 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
3170 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
3172 IP(src=self.pg2.remote_ip4, dst=self.pg3.remote_ip4) /
3173 TCP(sport=1234, dport=1234))
3174 self.pg0.add_stream(p)
3175 self.pg_enable_capture(self.pg_interfaces)
3177 p = self.pg1.get_capture(1)
3180 self.assertEqual(packet[IP].src, nat_ip)
3181 self.assertEqual(packet[IP].dst, self.pg1.remote_ip4)
3182 self.assertEqual(packet.haslayer(GRE), 1)
3183 self.assert_packet_checksums_valid(packet)
3185 self.logger.error(ppp("Unexpected or invalid packet:", packet))
3189 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
3190 IP(src=self.pg1.remote_ip4, dst=nat_ip) /
3192 IP(src=self.pg3.remote_ip4, dst=self.pg2.remote_ip4) /
3193 TCP(sport=1234, dport=1234))
3194 self.pg1.add_stream(p)
3195 self.pg_enable_capture(self.pg_interfaces)
3197 p = self.pg0.get_capture(1)
3200 self.assertEqual(packet[IP].src, self.pg1.remote_ip4)
3201 self.assertEqual(packet[IP].dst, self.pg0.remote_ip4)
3202 self.assertEqual(packet.haslayer(GRE), 1)
3203 self.assert_packet_checksums_valid(packet)
3205 self.logger.error(ppp("Unexpected or invalid packet:", packet))
3208 def test_hairpinning_static_unknown_proto(self):
3209 """ 1:1 NAT translate packet with unknown protocol - hairpinning """
3211 host = self.pg0.remote_hosts[0]
3212 server = self.pg0.remote_hosts[1]
3214 host_nat_ip = "10.0.0.10"
3215 server_nat_ip = "10.0.0.11"
3217 self.nat44_add_static_mapping(host.ip4, host_nat_ip)
3218 self.nat44_add_static_mapping(server.ip4, server_nat_ip)
3219 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
3220 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
3224 p = (Ether(dst=self.pg0.local_mac, src=host.mac) /
3225 IP(src=host.ip4, dst=server_nat_ip) /
3227 IP(src=self.pg2.remote_ip4, dst=self.pg3.remote_ip4) /
3228 TCP(sport=1234, dport=1234))
3229 self.pg0.add_stream(p)
3230 self.pg_enable_capture(self.pg_interfaces)
3232 p = self.pg0.get_capture(1)
3235 self.assertEqual(packet[IP].src, host_nat_ip)
3236 self.assertEqual(packet[IP].dst, server.ip4)
3237 self.assertEqual(packet.haslayer(GRE), 1)
3238 self.assert_packet_checksums_valid(packet)
3240 self.logger.error(ppp("Unexpected or invalid packet:", packet))
3244 p = (Ether(dst=self.pg0.local_mac, src=server.mac) /
3245 IP(src=server.ip4, dst=host_nat_ip) /
3247 IP(src=self.pg3.remote_ip4, dst=self.pg2.remote_ip4) /
3248 TCP(sport=1234, dport=1234))
3249 self.pg0.add_stream(p)
3250 self.pg_enable_capture(self.pg_interfaces)
3252 p = self.pg0.get_capture(1)
3255 self.assertEqual(packet[IP].src, server_nat_ip)
3256 self.assertEqual(packet[IP].dst, host.ip4)
3257 self.assertEqual(packet.haslayer(GRE), 1)
3258 self.assert_packet_checksums_valid(packet)
3260 self.logger.error(ppp("Unexpected or invalid packet:", packet))
3263 def test_output_feature(self):
3264 """ NAT44 interface output feature (in2out postrouting) """
3265 self.nat44_add_address(self.nat_addr)
3266 self.vapi.nat44_interface_add_del_output_feature(self.pg0.sw_if_index)
3267 self.vapi.nat44_interface_add_del_output_feature(self.pg1.sw_if_index)
3268 self.vapi.nat44_interface_add_del_output_feature(self.pg3.sw_if_index,
3272 pkts = self.create_stream_in(self.pg0, self.pg3)
3273 self.pg0.add_stream(pkts)
3274 self.pg_enable_capture(self.pg_interfaces)
3276 capture = self.pg3.get_capture(len(pkts))
3277 self.verify_capture_out(capture)
3280 pkts = self.create_stream_out(self.pg3)
3281 self.pg3.add_stream(pkts)
3282 self.pg_enable_capture(self.pg_interfaces)
3284 capture = self.pg0.get_capture(len(pkts))
3285 self.verify_capture_in(capture, self.pg0)
3287 # from non-NAT interface to NAT inside interface
3288 pkts = self.create_stream_in(self.pg2, self.pg0)
3289 self.pg2.add_stream(pkts)
3290 self.pg_enable_capture(self.pg_interfaces)
3292 capture = self.pg0.get_capture(len(pkts))
3293 self.verify_capture_no_translation(capture, self.pg2, self.pg0)
3295 def test_output_feature_vrf_aware(self):
3296 """ NAT44 interface output feature VRF aware (in2out postrouting) """
3297 nat_ip_vrf10 = "10.0.0.10"
3298 nat_ip_vrf20 = "10.0.0.20"
3300 self.vapi.ip_add_del_route(dst_address=self.pg3.remote_ip4n,
3301 dst_address_length=32,
3302 next_hop_address=self.pg3.remote_ip4n,
3303 next_hop_sw_if_index=self.pg3.sw_if_index,
3305 self.vapi.ip_add_del_route(dst_address=self.pg3.remote_ip4n,
3306 dst_address_length=32,
3307 next_hop_address=self.pg3.remote_ip4n,
3308 next_hop_sw_if_index=self.pg3.sw_if_index,
3311 self.nat44_add_address(nat_ip_vrf10, vrf_id=10)
3312 self.nat44_add_address(nat_ip_vrf20, vrf_id=20)
3313 self.vapi.nat44_interface_add_del_output_feature(self.pg4.sw_if_index)
3314 self.vapi.nat44_interface_add_del_output_feature(self.pg6.sw_if_index)
3315 self.vapi.nat44_interface_add_del_output_feature(self.pg3.sw_if_index,
3319 pkts = self.create_stream_in(self.pg4, self.pg3)
3320 self.pg4.add_stream(pkts)
3321 self.pg_enable_capture(self.pg_interfaces)
3323 capture = self.pg3.get_capture(len(pkts))
3324 self.verify_capture_out(capture, nat_ip=nat_ip_vrf10)
3327 pkts = self.create_stream_out(self.pg3, dst_ip=nat_ip_vrf10)
3328 self.pg3.add_stream(pkts)
3329 self.pg_enable_capture(self.pg_interfaces)
3331 capture = self.pg4.get_capture(len(pkts))
3332 self.verify_capture_in(capture, self.pg4)
3335 pkts = self.create_stream_in(self.pg6, self.pg3)
3336 self.pg6.add_stream(pkts)
3337 self.pg_enable_capture(self.pg_interfaces)
3339 capture = self.pg3.get_capture(len(pkts))
3340 self.verify_capture_out(capture, nat_ip=nat_ip_vrf20)
3343 pkts = self.create_stream_out(self.pg3, dst_ip=nat_ip_vrf20)
3344 self.pg3.add_stream(pkts)
3345 self.pg_enable_capture(self.pg_interfaces)
3347 capture = self.pg6.get_capture(len(pkts))
3348 self.verify_capture_in(capture, self.pg6)
3350 def test_output_feature_hairpinning(self):
3351 """ NAT44 interface output feature hairpinning (in2out postrouting) """
3352 host = self.pg0.remote_hosts[0]
3353 server = self.pg0.remote_hosts[1]
3356 server_in_port = 5678
3357 server_out_port = 8765
3359 self.nat44_add_address(self.nat_addr)
3360 self.vapi.nat44_interface_add_del_output_feature(self.pg0.sw_if_index)
3361 self.vapi.nat44_interface_add_del_output_feature(self.pg1.sw_if_index,
3364 # add static mapping for server
3365 self.nat44_add_static_mapping(server.ip4, self.nat_addr,
3366 server_in_port, server_out_port,
3367 proto=IP_PROTOS.tcp)
3369 # send packet from host to server
3370 p = (Ether(src=host.mac, dst=self.pg0.local_mac) /
3371 IP(src=host.ip4, dst=self.nat_addr) /
3372 TCP(sport=host_in_port, dport=server_out_port))
3373 self.pg0.add_stream(p)
3374 self.pg_enable_capture(self.pg_interfaces)
3376 capture = self.pg0.get_capture(1)
3381 self.assertEqual(ip.src, self.nat_addr)
3382 self.assertEqual(ip.dst, server.ip4)
3383 self.assertNotEqual(tcp.sport, host_in_port)
3384 self.assertEqual(tcp.dport, server_in_port)
3385 self.assert_packet_checksums_valid(p)
3386 host_out_port = tcp.sport
3388 self.logger.error(ppp("Unexpected or invalid packet:", p))
3391 # send reply from server to host
3392 p = (Ether(src=server.mac, dst=self.pg0.local_mac) /
3393 IP(src=server.ip4, dst=self.nat_addr) /
3394 TCP(sport=server_in_port, dport=host_out_port))
3395 self.pg0.add_stream(p)
3396 self.pg_enable_capture(self.pg_interfaces)
3398 capture = self.pg0.get_capture(1)
3403 self.assertEqual(ip.src, self.nat_addr)
3404 self.assertEqual(ip.dst, host.ip4)
3405 self.assertEqual(tcp.sport, server_out_port)
3406 self.assertEqual(tcp.dport, host_in_port)
3407 self.assert_packet_checksums_valid(p)
3409 self.logger.error(ppp("Unexpected or invalid packet:", p))
3412 def test_one_armed_nat44(self):
3413 """ One armed NAT44 """
3414 remote_host = self.pg9.remote_hosts[0]
3415 local_host = self.pg9.remote_hosts[1]
3418 self.nat44_add_address(self.nat_addr)
3419 self.vapi.nat44_interface_add_del_feature(self.pg9.sw_if_index)
3420 self.vapi.nat44_interface_add_del_feature(self.pg9.sw_if_index,
3424 p = (Ether(src=self.pg9.remote_mac, dst=self.pg9.local_mac) /
3425 IP(src=local_host.ip4, dst=remote_host.ip4) /
3426 TCP(sport=12345, dport=80))
3427 self.pg9.add_stream(p)
3428 self.pg_enable_capture(self.pg_interfaces)
3430 capture = self.pg9.get_capture(1)
3435 self.assertEqual(ip.src, self.nat_addr)
3436 self.assertEqual(ip.dst, remote_host.ip4)
3437 self.assertNotEqual(tcp.sport, 12345)
3438 external_port = tcp.sport
3439 self.assertEqual(tcp.dport, 80)
3440 self.assert_packet_checksums_valid(p)
3442 self.logger.error(ppp("Unexpected or invalid packet:", p))
3446 p = (Ether(src=self.pg9.remote_mac, dst=self.pg9.local_mac) /
3447 IP(src=remote_host.ip4, dst=self.nat_addr) /
3448 TCP(sport=80, dport=external_port))
3449 self.pg9.add_stream(p)
3450 self.pg_enable_capture(self.pg_interfaces)
3452 capture = self.pg9.get_capture(1)
3457 self.assertEqual(ip.src, remote_host.ip4)
3458 self.assertEqual(ip.dst, local_host.ip4)
3459 self.assertEqual(tcp.sport, 80)
3460 self.assertEqual(tcp.dport, 12345)
3461 self.assert_packet_checksums_valid(p)
3463 self.logger.error(ppp("Unexpected or invalid packet:", p))
3466 err = self.statistics.get_counter('/err/nat44-classify/next in2out')
3467 self.assertEqual(err, 1)
3468 err = self.statistics.get_counter('/err/nat44-classify/next out2in')
3469 self.assertEqual(err, 1)
3471 def test_del_session(self):
3472 """ Delete NAT44 session """
3473 self.nat44_add_address(self.nat_addr)
3474 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
3475 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
3478 pkts = self.create_stream_in(self.pg0, self.pg1)
3479 self.pg0.add_stream(pkts)
3480 self.pg_enable_capture(self.pg_interfaces)
3482 self.pg1.get_capture(len(pkts))
3484 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4n, 0)
3485 nsessions = len(sessions)
3487 self.vapi.nat44_del_session(sessions[0].inside_ip_address,
3488 sessions[0].inside_port,
3489 sessions[0].protocol)
3490 self.vapi.nat44_del_session(sessions[1].outside_ip_address,
3491 sessions[1].outside_port,
3492 sessions[1].protocol,
3495 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4n, 0)
3496 self.assertEqual(nsessions - len(sessions), 2)
3498 self.vapi.nat44_del_session(sessions[0].inside_ip_address,
3499 sessions[0].inside_port,
3500 sessions[0].protocol)
3502 self.verify_no_nat44_user()
3504 def test_set_get_reass(self):
3505 """ NAT44 set/get virtual fragmentation reassembly """
3506 reas_cfg1 = self.vapi.nat_get_reass()
3508 self.vapi.nat_set_reass(timeout=reas_cfg1.ip4_timeout + 5,
3509 max_reass=reas_cfg1.ip4_max_reass * 2,
3510 max_frag=reas_cfg1.ip4_max_frag * 2)
3512 reas_cfg2 = self.vapi.nat_get_reass()
3514 self.assertEqual(reas_cfg1.ip4_timeout + 5, reas_cfg2.ip4_timeout)
3515 self.assertEqual(reas_cfg1.ip4_max_reass * 2, reas_cfg2.ip4_max_reass)
3516 self.assertEqual(reas_cfg1.ip4_max_frag * 2, reas_cfg2.ip4_max_frag)
3518 self.vapi.nat_set_reass(drop_frag=1)
3519 self.assertTrue(self.vapi.nat_get_reass().ip4_drop_frag)
3521 def test_frag_in_order(self):
3522 """ NAT44 translate fragments arriving in order """
3524 self.nat44_add_address(self.nat_addr)
3525 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
3526 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
3529 self.frag_in_order(proto=IP_PROTOS.tcp)
3530 self.frag_in_order(proto=IP_PROTOS.udp)
3531 self.frag_in_order(proto=IP_PROTOS.icmp)
3533 def test_frag_forwarding(self):
3534 """ NAT44 forwarding fragment test """
3535 self.vapi.nat44_add_interface_addr(self.pg1.sw_if_index)
3536 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
3537 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
3539 self.vapi.nat44_forwarding_enable_disable(1)
3541 data = "A" * 16 + "B" * 16 + "C" * 3
3542 pkts = self.create_stream_frag(self.pg1,
3543 self.pg0.remote_ip4,
3547 proto=IP_PROTOS.udp)
3548 self.pg1.add_stream(pkts)
3549 self.pg_enable_capture(self.pg_interfaces)
3551 frags = self.pg0.get_capture(len(pkts))
3552 p = self.reass_frags_and_verify(frags,
3553 self.pg1.remote_ip4,
3554 self.pg0.remote_ip4)
3555 self.assertEqual(p[UDP].sport, 4789)
3556 self.assertEqual(p[UDP].dport, 4789)
3557 self.assertEqual(data, p[Raw].load)
3559 def test_reass_hairpinning(self):
3560 """ NAT44 fragments hairpinning """
3562 self.server = self.pg0.remote_hosts[1]
3563 self.host_in_port = random.randint(1025, 65535)
3564 self.server_in_port = random.randint(1025, 65535)
3565 self.server_out_port = random.randint(1025, 65535)
3567 self.nat44_add_address(self.nat_addr)
3568 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
3569 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
3571 # add static mapping for server
3572 self.nat44_add_static_mapping(self.server.ip4, self.nat_addr,
3573 self.server_in_port,
3574 self.server_out_port,
3575 proto=IP_PROTOS.tcp)
3576 self.nat44_add_static_mapping(self.server.ip4, self.nat_addr,
3577 self.server_in_port,
3578 self.server_out_port,
3579 proto=IP_PROTOS.udp)
3580 self.nat44_add_static_mapping(self.server.ip4, self.nat_addr)
3582 self.reass_hairpinning(proto=IP_PROTOS.tcp)
3583 self.reass_hairpinning(proto=IP_PROTOS.udp)
3584 self.reass_hairpinning(proto=IP_PROTOS.icmp)
3586 def test_frag_out_of_order(self):
3587 """ NAT44 translate fragments arriving out of order """
3589 self.nat44_add_address(self.nat_addr)
3590 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
3591 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
3594 self.frag_out_of_order(proto=IP_PROTOS.tcp)
3595 self.frag_out_of_order(proto=IP_PROTOS.udp)
3596 self.frag_out_of_order(proto=IP_PROTOS.icmp)
3598 def test_port_restricted(self):
3599 """ Port restricted NAT44 (MAP-E CE) """
3600 self.nat44_add_address(self.nat_addr)
3601 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
3602 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
3604 self.vapi.nat_set_addr_and_port_alloc_alg(alg=1,
3609 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
3610 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
3611 TCP(sport=4567, dport=22))
3612 self.pg0.add_stream(p)
3613 self.pg_enable_capture(self.pg_interfaces)
3615 capture = self.pg1.get_capture(1)
3620 self.assertEqual(ip.dst, self.pg1.remote_ip4)
3621 self.assertEqual(ip.src, self.nat_addr)
3622 self.assertEqual(tcp.dport, 22)
3623 self.assertNotEqual(tcp.sport, 4567)
3624 self.assertEqual((tcp.sport >> 6) & 63, 10)
3625 self.assert_packet_checksums_valid(p)
3627 self.logger.error(ppp("Unexpected or invalid packet:", p))
3630 def test_port_range(self):
3631 """ External address port range """
3632 self.nat44_add_address(self.nat_addr)
3633 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
3634 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
3636 self.vapi.nat_set_addr_and_port_alloc_alg(alg=2,
3641 for port in range(0, 5):
3642 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
3643 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
3644 TCP(sport=1125 + port))
3646 self.pg0.add_stream(pkts)
3647 self.pg_enable_capture(self.pg_interfaces)
3649 capture = self.pg1.get_capture(3)
3652 self.assertGreaterEqual(tcp.sport, 1025)
3653 self.assertLessEqual(tcp.sport, 1027)
3655 def test_ipfix_max_frags(self):
3656 """ IPFIX logging maximum fragments pending reassembly exceeded """
3657 self.nat44_add_address(self.nat_addr)
3658 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
3659 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
3661 self.vapi.nat_set_reass(max_frag=1)
3662 self.vapi.set_ipfix_exporter(collector_address=self.pg3.remote_ip4n,
3663 src_address=self.pg3.local_ip4n,
3665 template_interval=10)
3666 self.vapi.nat_ipfix(domain_id=self.ipfix_domain_id,
3667 src_port=self.ipfix_src_port)
3669 data = "A" * 4 + "B" * 16 + "C" * 3
3670 self.tcp_port_in = random.randint(1025, 65535)
3671 pkts = self.create_stream_frag(self.pg0,
3672 self.pg1.remote_ip4,
3677 self.pg0.add_stream(pkts)
3678 self.pg_enable_capture(self.pg_interfaces)
3680 self.pg1.assert_nothing_captured()
3682 self.vapi.cli("ipfix flush") # FIXME this should be an API call
3683 capture = self.pg3.get_capture(9)
3684 ipfix = IPFIXDecoder()
3685 # first load template
3687 self.assertTrue(p.haslayer(IPFIX))
3688 self.assertEqual(p[IP].src, self.pg3.local_ip4)
3689 self.assertEqual(p[IP].dst, self.pg3.remote_ip4)
3690 self.assertEqual(p[UDP].sport, self.ipfix_src_port)
3691 self.assertEqual(p[UDP].dport, 4739)
3692 self.assertEqual(p[IPFIX].observationDomainID,
3693 self.ipfix_domain_id)
3694 if p.haslayer(Template):
3695 ipfix.add_template(p.getlayer(Template))
3696 # verify events in data set
3698 if p.haslayer(Data):
3699 data = ipfix.decode_data_set(p.getlayer(Set))
3700 self.verify_ipfix_max_fragments_ip4(data, 1,
3701 self.pg0.remote_ip4n)
3703 def test_multiple_outside_vrf(self):
3704 """ Multiple outside VRF """
3708 self.pg1.unconfig_ip4()
3709 self.pg2.unconfig_ip4()
3710 self.vapi.ip_table_add_del(vrf_id1, is_add=1)
3711 self.vapi.ip_table_add_del(vrf_id2, is_add=1)
3712 self.pg1.set_table_ip4(vrf_id1)
3713 self.pg2.set_table_ip4(vrf_id2)
3714 self.pg1.config_ip4()
3715 self.pg2.config_ip4()
3716 self.pg1.resolve_arp()
3717 self.pg2.resolve_arp()
3719 self.nat44_add_address(self.nat_addr)
3720 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
3721 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
3723 self.vapi.nat44_interface_add_del_feature(self.pg2.sw_if_index,
3728 pkts = self.create_stream_in(self.pg0, self.pg1)
3729 self.pg0.add_stream(pkts)
3730 self.pg_enable_capture(self.pg_interfaces)
3732 capture = self.pg1.get_capture(len(pkts))
3733 self.verify_capture_out(capture, self.nat_addr)
3735 pkts = self.create_stream_out(self.pg1, self.nat_addr)
3736 self.pg1.add_stream(pkts)
3737 self.pg_enable_capture(self.pg_interfaces)
3739 capture = self.pg0.get_capture(len(pkts))
3740 self.verify_capture_in(capture, self.pg0)
3742 self.tcp_port_in = 60303
3743 self.udp_port_in = 60304
3744 self.icmp_id_in = 60305
3747 pkts = self.create_stream_in(self.pg0, self.pg2)
3748 self.pg0.add_stream(pkts)
3749 self.pg_enable_capture(self.pg_interfaces)
3751 capture = self.pg2.get_capture(len(pkts))
3752 self.verify_capture_out(capture, self.nat_addr)
3754 pkts = self.create_stream_out(self.pg2, self.nat_addr)
3755 self.pg2.add_stream(pkts)
3756 self.pg_enable_capture(self.pg_interfaces)
3758 capture = self.pg0.get_capture(len(pkts))
3759 self.verify_capture_in(capture, self.pg0)
3762 self.pg1.unconfig_ip4()
3763 self.pg2.unconfig_ip4()
3764 self.pg1.set_table_ip4(0)
3765 self.pg2.set_table_ip4(0)
3766 self.pg1.config_ip4()
3767 self.pg2.config_ip4()
3768 self.pg1.resolve_arp()
3769 self.pg2.resolve_arp()
3771 @unittest.skipUnless(running_extended_tests, "part of extended tests")
3772 def test_session_timeout(self):
3773 """ NAT44 session timeouts """
3774 self.nat44_add_address(self.nat_addr)
3775 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
3776 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
3778 self.vapi.nat_set_timeouts(udp=5)
3782 for i in range(0, max_sessions):
3783 src = "10.10.%u.%u" % ((i & 0xFF00) >> 8, i & 0xFF)
3784 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
3785 IP(src=src, dst=self.pg1.remote_ip4) /
3786 UDP(sport=1025, dport=53))
3788 self.pg0.add_stream(pkts)
3789 self.pg_enable_capture(self.pg_interfaces)
3791 self.pg1.get_capture(max_sessions)
3796 for i in range(0, max_sessions):
3797 src = "10.10.%u.%u" % ((i & 0xFF00) >> 8, i & 0xFF)
3798 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
3799 IP(src=src, dst=self.pg1.remote_ip4) /
3800 UDP(sport=1026, dport=53))
3802 self.pg0.add_stream(pkts)
3803 self.pg_enable_capture(self.pg_interfaces)
3805 self.pg1.get_capture(max_sessions)
3808 users = self.vapi.nat44_user_dump()
3810 nsessions = nsessions + user.nsessions
3811 self.assertLess(nsessions, 2 * max_sessions)
3813 def test_mss_clamping(self):
3814 """ TCP MSS clamping """
3815 self.nat44_add_address(self.nat_addr)
3816 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
3817 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
3820 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
3821 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
3822 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
3823 flags="S", options=[('MSS', 1400)]))
3825 self.vapi.nat_set_mss_clamping(enable=1, mss_value=1000)
3826 self.pg0.add_stream(p)
3827 self.pg_enable_capture(self.pg_interfaces)
3829 capture = self.pg1.get_capture(1)
3830 # Negotiated MSS value greater than configured - changed
3831 self.verify_mss_value(capture[0], 1000)
3833 self.vapi.nat_set_mss_clamping(enable=0)
3834 self.pg0.add_stream(p)
3835 self.pg_enable_capture(self.pg_interfaces)
3837 capture = self.pg1.get_capture(1)
3838 # MSS clamping disabled - negotiated MSS unchanged
3839 self.verify_mss_value(capture[0], 1400)
3841 self.vapi.nat_set_mss_clamping(enable=1, mss_value=1500)
3842 self.pg0.add_stream(p)
3843 self.pg_enable_capture(self.pg_interfaces)
3845 capture = self.pg1.get_capture(1)
3846 # Negotiated MSS value smaller than configured - unchanged
3847 self.verify_mss_value(capture[0], 1400)
3849 @unittest.skipUnless(running_extended_tests, "part of extended tests")
3850 def test_ha_send(self):
3851 """ Send HA session synchronization events (active) """
3852 self.nat44_add_address(self.nat_addr)
3853 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
3854 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
3856 self.vapi.nat_ha_set_listener(self.pg3.local_ip4, port=12345)
3857 self.vapi.nat_ha_set_failover(self.pg3.remote_ip4, port=12346)
3858 bind_layers(UDP, HANATStateSync, sport=12345)
3861 pkts = self.create_stream_in(self.pg0, self.pg1)
3862 self.pg0.add_stream(pkts)
3863 self.pg_enable_capture(self.pg_interfaces)
3865 capture = self.pg1.get_capture(len(pkts))
3866 self.verify_capture_out(capture)
3867 # active send HA events
3868 self.vapi.nat_ha_flush()
3869 stats = self.statistics.get_counter('/nat44/ha/add-event-send')
3870 self.assertEqual(stats[0][0], 3)
3871 capture = self.pg3.get_capture(1)
3873 self.assert_packet_checksums_valid(p)
3877 hanat = p[HANATStateSync]
3879 self.logger.error(ppp("Invalid packet:", p))
3882 self.assertEqual(ip.src, self.pg3.local_ip4)
3883 self.assertEqual(ip.dst, self.pg3.remote_ip4)
3884 self.assertEqual(udp.sport, 12345)
3885 self.assertEqual(udp.dport, 12346)
3886 self.assertEqual(hanat.version, 1)
3887 self.assertEqual(hanat.thread_index, 0)
3888 self.assertEqual(hanat.count, 3)
3889 seq = hanat.sequence_number
3890 for event in hanat.events:
3891 self.assertEqual(event.event_type, 1)
3892 self.assertEqual(event.in_addr, self.pg0.remote_ip4)
3893 self.assertEqual(event.out_addr, self.nat_addr)
3894 self.assertEqual(event.fib_index, 0)
3896 # ACK received events
3897 ack = (Ether(dst=self.pg3.local_mac, src=self.pg3.remote_mac) /
3898 IP(src=self.pg3.remote_ip4, dst=self.pg3.local_ip4) /
3899 UDP(sport=12346, dport=12345) /
3900 HANATStateSync(sequence_number=seq, flags='ACK'))
3901 self.pg3.add_stream(ack)
3903 stats = self.statistics.get_counter('/nat44/ha/ack-recv')
3904 self.assertEqual(stats[0][0], 1)
3906 # delete one session
3907 self.pg_enable_capture(self.pg_interfaces)
3908 self.vapi.nat44_del_session(self.pg0.remote_ip4n, self.tcp_port_in,
3910 self.vapi.nat_ha_flush()
3911 stats = self.statistics.get_counter('/nat44/ha/del-event-send')
3912 self.assertEqual(stats[0][0], 1)
3913 capture = self.pg3.get_capture(1)
3916 hanat = p[HANATStateSync]
3918 self.logger.error(ppp("Invalid packet:", p))
3921 self.assertGreater(hanat.sequence_number, seq)
3923 # do not send ACK, active retry send HA event again
3924 self.pg_enable_capture(self.pg_interfaces)
3926 stats = self.statistics.get_counter('/nat44/ha/retry-count')
3927 self.assertEqual(stats[0][0], 3)
3928 stats = self.statistics.get_counter('/nat44/ha/missed-count')
3929 self.assertEqual(stats[0][0], 1)
3930 capture = self.pg3.get_capture(3)
3931 for packet in capture:
3932 self.assertEqual(packet, p)
3934 # session counters refresh
3935 pkts = self.create_stream_out(self.pg1)
3936 self.pg1.add_stream(pkts)
3937 self.pg_enable_capture(self.pg_interfaces)
3939 self.pg0.get_capture(2)
3940 self.vapi.nat_ha_flush()
3941 stats = self.statistics.get_counter('/nat44/ha/refresh-event-send')
3942 self.assertEqual(stats[0][0], 2)
3943 capture = self.pg3.get_capture(1)
3945 self.assert_packet_checksums_valid(p)
3949 hanat = p[HANATStateSync]
3951 self.logger.error(ppp("Invalid packet:", p))
3954 self.assertEqual(ip.src, self.pg3.local_ip4)
3955 self.assertEqual(ip.dst, self.pg3.remote_ip4)
3956 self.assertEqual(udp.sport, 12345)
3957 self.assertEqual(udp.dport, 12346)
3958 self.assertEqual(hanat.version, 1)
3959 self.assertEqual(hanat.count, 2)
3960 seq = hanat.sequence_number
3961 for event in hanat.events:
3962 self.assertEqual(event.event_type, 3)
3963 self.assertEqual(event.out_addr, self.nat_addr)
3964 self.assertEqual(event.fib_index, 0)
3965 self.assertEqual(event.total_pkts, 2)
3966 self.assertGreater(event.total_bytes, 0)
3968 ack = (Ether(dst=self.pg3.local_mac, src=self.pg3.remote_mac) /
3969 IP(src=self.pg3.remote_ip4, dst=self.pg3.local_ip4) /
3970 UDP(sport=12346, dport=12345) /
3971 HANATStateSync(sequence_number=seq, flags='ACK'))
3972 self.pg3.add_stream(ack)
3974 stats = self.statistics.get_counter('/nat44/ha/ack-recv')
3975 self.assertEqual(stats[0][0], 2)
3977 def test_ha_recv(self):
3978 """ Receive HA session synchronization events (passive) """
3979 self.nat44_add_address(self.nat_addr)
3980 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
3981 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
3983 self.vapi.nat_ha_set_listener(self.pg3.local_ip4, port=12345)
3984 bind_layers(UDP, HANATStateSync, sport=12345)
3986 self.tcp_port_out = random.randint(1025, 65535)
3987 self.udp_port_out = random.randint(1025, 65535)
3989 # send HA session add events to failover/passive
3990 p = (Ether(dst=self.pg3.local_mac, src=self.pg3.remote_mac) /
3991 IP(src=self.pg3.remote_ip4, dst=self.pg3.local_ip4) /
3992 UDP(sport=12346, dport=12345) /
3993 HANATStateSync(sequence_number=1, events=[
3994 Event(event_type='add', protocol='tcp',
3995 in_addr=self.pg0.remote_ip4, out_addr=self.nat_addr,
3996 in_port=self.tcp_port_in, out_port=self.tcp_port_out,
3997 eh_addr=self.pg1.remote_ip4,
3998 ehn_addr=self.pg1.remote_ip4,
3999 eh_port=self.tcp_external_port,
4000 ehn_port=self.tcp_external_port, fib_index=0),
4001 Event(event_type='add', protocol='udp',
4002 in_addr=self.pg0.remote_ip4, out_addr=self.nat_addr,
4003 in_port=self.udp_port_in, out_port=self.udp_port_out,
4004 eh_addr=self.pg1.remote_ip4,
4005 ehn_addr=self.pg1.remote_ip4,
4006 eh_port=self.udp_external_port,
4007 ehn_port=self.udp_external_port, fib_index=0)]))
4009 self.pg3.add_stream(p)
4010 self.pg_enable_capture(self.pg_interfaces)
4013 capture = self.pg3.get_capture(1)
4016 hanat = p[HANATStateSync]
4018 self.logger.error(ppp("Invalid packet:", p))
4021 self.assertEqual(hanat.sequence_number, 1)
4022 self.assertEqual(hanat.flags, 'ACK')
4023 self.assertEqual(hanat.version, 1)
4024 self.assertEqual(hanat.thread_index, 0)
4025 stats = self.statistics.get_counter('/nat44/ha/ack-send')
4026 self.assertEqual(stats[0][0], 1)
4027 stats = self.statistics.get_counter('/nat44/ha/add-event-recv')
4028 self.assertEqual(stats[0][0], 2)
4029 users = self.statistics.get_counter('/nat44/total-users')
4030 self.assertEqual(users[0][0], 1)
4031 sessions = self.statistics.get_counter('/nat44/total-sessions')
4032 self.assertEqual(sessions[0][0], 2)
4033 users = self.vapi.nat44_user_dump()
4034 self.assertEqual(len(users), 1)
4035 self.assertEqual(users[0].ip_address, self.pg0.remote_ip4n)
4036 # there should be 2 sessions created by HA
4037 sessions = self.vapi.nat44_user_session_dump(users[0].ip_address,
4039 self.assertEqual(len(sessions), 2)
4040 for session in sessions:
4041 self.assertEqual(session.inside_ip_address, self.pg0.remote_ip4n)
4042 self.assertEqual(session.outside_ip_address, self.nat_addr_n)
4043 self.assertIn(session.inside_port,
4044 [self.tcp_port_in, self.udp_port_in])
4045 self.assertIn(session.outside_port,
4046 [self.tcp_port_out, self.udp_port_out])
4047 self.assertIn(session.protocol, [IP_PROTOS.tcp, IP_PROTOS.udp])
4049 # send HA session delete event to failover/passive
4050 p = (Ether(dst=self.pg3.local_mac, src=self.pg3.remote_mac) /
4051 IP(src=self.pg3.remote_ip4, dst=self.pg3.local_ip4) /
4052 UDP(sport=12346, dport=12345) /
4053 HANATStateSync(sequence_number=2, events=[
4054 Event(event_type='del', protocol='udp',
4055 in_addr=self.pg0.remote_ip4, out_addr=self.nat_addr,
4056 in_port=self.udp_port_in, out_port=self.udp_port_out,
4057 eh_addr=self.pg1.remote_ip4,
4058 ehn_addr=self.pg1.remote_ip4,
4059 eh_port=self.udp_external_port,
4060 ehn_port=self.udp_external_port, fib_index=0)]))
4062 self.pg3.add_stream(p)
4063 self.pg_enable_capture(self.pg_interfaces)
4066 capture = self.pg3.get_capture(1)
4069 hanat = p[HANATStateSync]
4071 self.logger.error(ppp("Invalid packet:", p))
4074 self.assertEqual(hanat.sequence_number, 2)
4075 self.assertEqual(hanat.flags, 'ACK')
4076 self.assertEqual(hanat.version, 1)
4077 users = self.vapi.nat44_user_dump()
4078 self.assertEqual(len(users), 1)
4079 self.assertEqual(users[0].ip_address, self.pg0.remote_ip4n)
4080 # now we should have only 1 session, 1 deleted by HA
4081 sessions = self.vapi.nat44_user_session_dump(users[0].ip_address,
4083 self.assertEqual(len(sessions), 1)
4084 stats = self.statistics.get_counter('/nat44/ha/del-event-recv')
4085 self.assertEqual(stats[0][0], 1)
4087 stats = self.statistics.get_counter('/err/nat-ha/pkts-processed')
4088 self.assertEqual(stats, 2)
4090 # send HA session refresh event to failover/passive
4091 p = (Ether(dst=self.pg3.local_mac, src=self.pg3.remote_mac) /
4092 IP(src=self.pg3.remote_ip4, dst=self.pg3.local_ip4) /
4093 UDP(sport=12346, dport=12345) /
4094 HANATStateSync(sequence_number=3, events=[
4095 Event(event_type='refresh', protocol='tcp',
4096 in_addr=self.pg0.remote_ip4, out_addr=self.nat_addr,
4097 in_port=self.tcp_port_in, out_port=self.tcp_port_out,
4098 eh_addr=self.pg1.remote_ip4,
4099 ehn_addr=self.pg1.remote_ip4,
4100 eh_port=self.tcp_external_port,
4101 ehn_port=self.tcp_external_port, fib_index=0,
4102 total_bytes=1024, total_pkts=2)]))
4103 self.pg3.add_stream(p)
4104 self.pg_enable_capture(self.pg_interfaces)
4107 capture = self.pg3.get_capture(1)
4110 hanat = p[HANATStateSync]
4112 self.logger.error(ppp("Invalid packet:", p))
4115 self.assertEqual(hanat.sequence_number, 3)
4116 self.assertEqual(hanat.flags, 'ACK')
4117 self.assertEqual(hanat.version, 1)
4118 users = self.vapi.nat44_user_dump()
4119 self.assertEqual(len(users), 1)
4120 self.assertEqual(users[0].ip_address, self.pg0.remote_ip4n)
4121 sessions = self.vapi.nat44_user_session_dump(users[0].ip_address,
4123 self.assertEqual(len(sessions), 1)
4124 session = sessions[0]
4125 self.assertEqual(session.total_bytes, 1024)
4126 self.assertEqual(session.total_pkts, 2)
4127 stats = self.statistics.get_counter('/nat44/ha/refresh-event-recv')
4128 self.assertEqual(stats[0][0], 1)
4130 stats = self.statistics.get_counter('/err/nat-ha/pkts-processed')
4131 self.assertEqual(stats, 3)
4133 # send packet to test session created by HA
4134 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
4135 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
4136 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out))
4137 self.pg1.add_stream(p)
4138 self.pg_enable_capture(self.pg_interfaces)
4140 capture = self.pg0.get_capture(1)
4146 self.logger.error(ppp("Invalid packet:", p))
4149 self.assertEqual(ip.src, self.pg1.remote_ip4)
4150 self.assertEqual(ip.dst, self.pg0.remote_ip4)
4151 self.assertEqual(tcp.sport, self.tcp_external_port)
4152 self.assertEqual(tcp.dport, self.tcp_port_in)
4155 super(TestNAT44, self).tearDown()
4156 if not self.vpp_dead:
4157 self.logger.info(self.vapi.cli("show nat44 addresses"))
4158 self.logger.info(self.vapi.cli("show nat44 interfaces"))
4159 self.logger.info(self.vapi.cli("show nat44 static mappings"))
4160 self.logger.info(self.vapi.cli("show nat44 interface address"))
4161 self.logger.info(self.vapi.cli("show nat44 sessions detail"))
4162 self.logger.info(self.vapi.cli("show nat virtual-reassembly"))
4163 self.logger.info(self.vapi.cli("show nat44 hash tables detail"))
4164 self.logger.info(self.vapi.cli("show nat timeouts"))
4166 self.vapi.cli("show nat addr-port-assignment-alg"))
4167 self.logger.info(self.vapi.cli("show nat ha"))
4169 self.vapi.cli("clear logging")
4172 class TestNAT44EndpointDependent(MethodHolder):
4173 """ Endpoint-Dependent mapping and filtering test cases """
4176 def setUpConstants(cls):
4177 super(TestNAT44EndpointDependent, cls).setUpConstants()
4178 cls.vpp_cmdline.extend(["nat", "{", "endpoint-dependent", "}"])
4181 def setUpClass(cls):
4182 super(TestNAT44EndpointDependent, cls).setUpClass()
4183 cls.vapi.cli("set log class nat level debug")
4185 cls.tcp_port_in = 6303
4186 cls.tcp_port_out = 6303
4187 cls.udp_port_in = 6304
4188 cls.udp_port_out = 6304
4189 cls.icmp_id_in = 6305
4190 cls.icmp_id_out = 6305
4191 cls.nat_addr = '10.0.0.3'
4192 cls.nat_addr_n = socket.inet_pton(socket.AF_INET, cls.nat_addr)
4193 cls.ipfix_src_port = 4739
4194 cls.ipfix_domain_id = 1
4195 cls.tcp_external_port = 80
4197 cls.create_pg_interfaces(range(7))
4198 cls.interfaces = list(cls.pg_interfaces[0:3])
4200 for i in cls.interfaces:
4205 cls.pg0.generate_remote_hosts(3)
4206 cls.pg0.configure_ipv4_neighbors()
4210 cls.pg4.generate_remote_hosts(2)
4211 cls.pg4.config_ip4()
4212 ip_addr_n = socket.inet_pton(socket.AF_INET, "10.0.0.1")
4213 cls.vapi.sw_interface_add_del_address(cls.pg4.sw_if_index,
4217 cls.pg4.resolve_arp()
4218 cls.pg4._remote_hosts[1]._ip4 = cls.pg4._remote_hosts[0]._ip4
4219 cls.pg4.resolve_arp()
4221 zero_ip4n = socket.inet_pton(socket.AF_INET, "0.0.0.0")
4222 cls.vapi.ip_table_add_del(1, is_add=1)
4224 cls.pg5._local_ip4 = "10.1.1.1"
4225 cls.pg5._local_ip4n = socket.inet_pton(socket.AF_INET,
4227 cls.pg5._remote_hosts[0]._ip4 = "10.1.1.2"
4228 cls.pg5._remote_hosts[0]._ip4n = socket.inet_pton(
4229 socket.AF_INET, cls.pg5.remote_ip4)
4230 cls.pg5.set_table_ip4(1)
4231 cls.pg5.config_ip4()
4233 cls.vapi.ip_add_del_route(dst_address=cls.pg5.remote_ip4n,
4234 dst_address_length=32,
4236 next_hop_sw_if_index=cls.pg5.sw_if_index,
4237 next_hop_address=zero_ip4n)
4239 cls.pg6._local_ip4 = "10.1.2.1"
4240 cls.pg6._local_ip4n = socket.inet_pton(socket.AF_INET,
4242 cls.pg6._remote_hosts[0]._ip4 = "10.1.2.2"
4243 cls.pg6._remote_hosts[0]._ip4n = socket.inet_pton(
4244 socket.AF_INET, cls.pg6.remote_ip4)
4245 cls.pg6.set_table_ip4(1)
4246 cls.pg6.config_ip4()
4248 cls.vapi.ip_add_del_route(dst_address=cls.pg6.remote_ip4n,
4249 dst_address_length=32,
4251 next_hop_sw_if_index=cls.pg6.sw_if_index,
4252 next_hop_address=zero_ip4n)
4254 cls.vapi.ip_add_del_route(dst_address=cls.pg6.remote_ip4n,
4255 dst_address_length=16,
4256 next_hop_address=zero_ip4n,
4258 next_hop_table_id=1)
4259 cls.vapi.ip_add_del_route(dst_address=zero_ip4n,
4260 dst_address_length=0,
4261 next_hop_address=zero_ip4n,
4263 next_hop_table_id=0)
4264 cls.vapi.ip_add_del_route(dst_address=zero_ip4n,
4265 dst_address_length=0,
4267 next_hop_sw_if_index=cls.pg1.sw_if_index,
4268 next_hop_address=cls.pg1.local_ip4n)
4270 cls.pg5.resolve_arp()
4271 cls.pg6.resolve_arp()
4274 super(TestNAT44EndpointDependent, cls).tearDownClass()
4277 def test_frag_in_order(self):
4278 """ NAT44 translate fragments arriving in order """
4279 self.nat44_add_address(self.nat_addr)
4280 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
4281 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
4283 self.frag_in_order(proto=IP_PROTOS.tcp)
4284 self.frag_in_order(proto=IP_PROTOS.udp)
4285 self.frag_in_order(proto=IP_PROTOS.icmp)
4287 def test_frag_in_order_dont_translate(self):
4288 """ NAT44 don't translate fragments arriving in order """
4289 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
4290 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
4292 self.vapi.nat44_forwarding_enable_disable(enable=True)
4293 self.frag_in_order(proto=IP_PROTOS.tcp, dont_translate=True)
4295 def test_frag_out_of_order(self):
4296 """ NAT44 translate fragments arriving out of order """
4297 self.nat44_add_address(self.nat_addr)
4298 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
4299 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
4301 self.frag_out_of_order(proto=IP_PROTOS.tcp)
4302 self.frag_out_of_order(proto=IP_PROTOS.udp)
4303 self.frag_out_of_order(proto=IP_PROTOS.icmp)
4305 def test_frag_out_of_order_dont_translate(self):
4306 """ NAT44 don't translate fragments arriving out of order """
4307 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
4308 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
4310 self.vapi.nat44_forwarding_enable_disable(enable=True)
4311 self.frag_out_of_order(proto=IP_PROTOS.tcp, dont_translate=True)
4313 def test_frag_in_order_in_plus_out(self):
4314 """ in+out interface fragments in order """
4315 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
4316 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index,
4318 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index)
4319 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
4322 self.server = self.pg1.remote_hosts[0]
4324 self.server_in_addr = self.server.ip4
4325 self.server_out_addr = '11.11.11.11'
4326 self.server_in_port = random.randint(1025, 65535)
4327 self.server_out_port = random.randint(1025, 65535)
4329 self.nat44_add_address(self.server_out_addr)
4331 # add static mappings for server
4332 self.nat44_add_static_mapping(self.server_in_addr,
4333 self.server_out_addr,
4334 self.server_in_port,
4335 self.server_out_port,
4336 proto=IP_PROTOS.tcp)
4337 self.nat44_add_static_mapping(self.server_in_addr,
4338 self.server_out_addr,
4339 self.server_in_port,
4340 self.server_out_port,
4341 proto=IP_PROTOS.udp)
4342 self.nat44_add_static_mapping(self.server_in_addr,
4343 self.server_out_addr,
4344 proto=IP_PROTOS.icmp)
4346 self.vapi.nat_set_reass(timeout=10)
4348 self.frag_in_order_in_plus_out(proto=IP_PROTOS.tcp)
4349 self.frag_in_order_in_plus_out(proto=IP_PROTOS.udp)
4350 self.frag_in_order_in_plus_out(proto=IP_PROTOS.icmp)
4352 def test_frag_out_of_order_in_plus_out(self):
4353 """ in+out interface fragments out of order """
4354 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
4355 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index,
4357 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index)
4358 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
4361 self.server = self.pg1.remote_hosts[0]
4363 self.server_in_addr = self.server.ip4
4364 self.server_out_addr = '11.11.11.11'
4365 self.server_in_port = random.randint(1025, 65535)
4366 self.server_out_port = random.randint(1025, 65535)
4368 self.nat44_add_address(self.server_out_addr)
4370 # add static mappings for server
4371 self.nat44_add_static_mapping(self.server_in_addr,
4372 self.server_out_addr,
4373 self.server_in_port,
4374 self.server_out_port,
4375 proto=IP_PROTOS.tcp)
4376 self.nat44_add_static_mapping(self.server_in_addr,
4377 self.server_out_addr,
4378 self.server_in_port,
4379 self.server_out_port,
4380 proto=IP_PROTOS.udp)
4381 self.nat44_add_static_mapping(self.server_in_addr,
4382 self.server_out_addr,
4383 proto=IP_PROTOS.icmp)
4385 self.vapi.nat_set_reass(timeout=10)
4387 self.frag_out_of_order_in_plus_out(proto=IP_PROTOS.tcp)
4388 self.frag_out_of_order_in_plus_out(proto=IP_PROTOS.udp)
4389 self.frag_out_of_order_in_plus_out(proto=IP_PROTOS.icmp)
4391 def test_reass_hairpinning(self):
4392 """ NAT44 fragments hairpinning """
4393 self.server = self.pg0.remote_hosts[1]
4394 self.host_in_port = random.randint(1025, 65535)
4395 self.server_in_port = random.randint(1025, 65535)
4396 self.server_out_port = random.randint(1025, 65535)
4398 self.nat44_add_address(self.nat_addr)
4399 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
4400 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
4402 # add static mapping for server
4403 self.nat44_add_static_mapping(self.server.ip4, self.nat_addr,
4404 self.server_in_port,
4405 self.server_out_port,
4406 proto=IP_PROTOS.tcp)
4407 self.nat44_add_static_mapping(self.server.ip4, self.nat_addr,
4408 self.server_in_port,
4409 self.server_out_port,
4410 proto=IP_PROTOS.udp)
4411 self.nat44_add_static_mapping(self.server.ip4, self.nat_addr)
4413 self.reass_hairpinning(proto=IP_PROTOS.tcp)
4414 self.reass_hairpinning(proto=IP_PROTOS.udp)
4415 self.reass_hairpinning(proto=IP_PROTOS.icmp)
4417 def test_dynamic(self):
4418 """ NAT44 dynamic translation test """
4420 self.nat44_add_address(self.nat_addr)
4421 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
4422 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
4425 nat_config = self.vapi.nat_show_config()
4426 self.assertEqual(1, nat_config.endpoint_dependent)
4429 tcpn = self.statistics.get_counter(
4430 '/err/nat44-ed-in2out-slowpath/TCP packets')
4431 udpn = self.statistics.get_counter(
4432 '/err/nat44-ed-in2out-slowpath/UDP packets')
4433 icmpn = self.statistics.get_counter(
4434 '/err/nat44-ed-in2out-slowpath/ICMP packets')
4435 totaln = self.statistics.get_counter(
4436 '/err/nat44-ed-in2out-slowpath/good in2out packets processed')
4438 pkts = self.create_stream_in(self.pg0, self.pg1)
4439 self.pg0.add_stream(pkts)
4440 self.pg_enable_capture(self.pg_interfaces)
4442 capture = self.pg1.get_capture(len(pkts))
4443 self.verify_capture_out(capture)
4445 err = self.statistics.get_counter(
4446 '/err/nat44-ed-in2out-slowpath/TCP packets')
4447 self.assertEqual(err - tcpn, 1)
4448 err = self.statistics.get_counter(
4449 '/err/nat44-ed-in2out-slowpath/UDP packets')
4450 self.assertEqual(err - udpn, 1)
4451 err = self.statistics.get_counter(
4452 '/err/nat44-ed-in2out-slowpath/ICMP packets')
4453 self.assertEqual(err - icmpn, 1)
4454 err = self.statistics.get_counter(
4455 '/err/nat44-ed-in2out-slowpath/good in2out packets processed')
4456 self.assertEqual(err - totaln, 3)
4459 tcpn = self.statistics.get_counter('/err/nat44-ed-out2in/TCP packets')
4460 udpn = self.statistics.get_counter('/err/nat44-ed-out2in/UDP packets')
4461 icmpn = self.statistics.get_counter(
4462 '/err/nat44-ed-out2in-slowpath/ICMP packets')
4463 totaln = self.statistics.get_counter(
4464 '/err/nat44-ed-out2in/good out2in packets processed')
4466 pkts = self.create_stream_out(self.pg1)
4467 self.pg1.add_stream(pkts)
4468 self.pg_enable_capture(self.pg_interfaces)
4470 capture = self.pg0.get_capture(len(pkts))
4471 self.verify_capture_in(capture, self.pg0)
4473 err = self.statistics.get_counter('/err/nat44-ed-out2in/TCP packets')
4474 self.assertEqual(err - tcpn, 1)
4475 err = self.statistics.get_counter('/err/nat44-ed-out2in/UDP packets')
4476 self.assertEqual(err - udpn, 1)
4477 err = self.statistics.get_counter(
4478 '/err/nat44-ed-out2in-slowpath/ICMP packets')
4479 self.assertEqual(err - icmpn, 1)
4480 err = self.statistics.get_counter(
4481 '/err/nat44-ed-out2in/good out2in packets processed')
4482 self.assertEqual(err - totaln, 2)
4484 users = self.statistics.get_counter('/nat44/total-users')
4485 self.assertEqual(users[0][0], 1)
4486 sessions = self.statistics.get_counter('/nat44/total-sessions')
4487 self.assertEqual(sessions[0][0], 3)
4489 def test_forwarding(self):
4490 """ NAT44 forwarding test """
4492 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
4493 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
4495 self.vapi.nat44_forwarding_enable_disable(1)
4497 real_ip = self.pg0.remote_ip4n
4498 alias_ip = self.nat_addr_n
4499 self.vapi.nat44_add_del_static_mapping(local_ip=real_ip,
4500 external_ip=alias_ip)
4503 # in2out - static mapping match
4505 pkts = self.create_stream_out(self.pg1)
4506 self.pg1.add_stream(pkts)
4507 self.pg_enable_capture(self.pg_interfaces)
4509 capture = self.pg0.get_capture(len(pkts))
4510 self.verify_capture_in(capture, self.pg0)
4512 pkts = self.create_stream_in(self.pg0, self.pg1)
4513 self.pg0.add_stream(pkts)
4514 self.pg_enable_capture(self.pg_interfaces)
4516 capture = self.pg1.get_capture(len(pkts))
4517 self.verify_capture_out(capture, same_port=True)
4519 # in2out - no static mapping match
4521 host0 = self.pg0.remote_hosts[0]
4522 self.pg0.remote_hosts[0] = self.pg0.remote_hosts[1]
4524 pkts = self.create_stream_out(self.pg1,
4525 dst_ip=self.pg0.remote_ip4,
4526 use_inside_ports=True)
4527 self.pg1.add_stream(pkts)
4528 self.pg_enable_capture(self.pg_interfaces)
4530 capture = self.pg0.get_capture(len(pkts))
4531 self.verify_capture_in(capture, self.pg0)
4533 pkts = self.create_stream_in(self.pg0, self.pg1)
4534 self.pg0.add_stream(pkts)
4535 self.pg_enable_capture(self.pg_interfaces)
4537 capture = self.pg1.get_capture(len(pkts))
4538 self.verify_capture_out(capture, nat_ip=self.pg0.remote_ip4,
4541 self.pg0.remote_hosts[0] = host0
4543 user = self.pg0.remote_hosts[1]
4544 sessions = self.vapi.nat44_user_session_dump(user.ip4n, 0)
4545 self.assertEqual(len(sessions), 3)
4546 self.assertTrue(sessions[0].ext_host_valid)
4547 self.vapi.nat44_del_session(
4548 sessions[0].inside_ip_address,
4549 sessions[0].inside_port,
4550 sessions[0].protocol,
4551 ext_host_address=sessions[0].ext_host_address,
4552 ext_host_port=sessions[0].ext_host_port)
4553 sessions = self.vapi.nat44_user_session_dump(user.ip4n, 0)
4554 self.assertEqual(len(sessions), 2)
4557 self.vapi.nat44_forwarding_enable_disable(0)
4558 self.vapi.nat44_add_del_static_mapping(local_ip=real_ip,
4559 external_ip=alias_ip,
4562 def test_static_lb(self):
4563 """ NAT44 local service load balancing """
4564 external_addr_n = socket.inet_pton(socket.AF_INET, self.nat_addr)
4567 server1 = self.pg0.remote_hosts[0]
4568 server2 = self.pg0.remote_hosts[1]
4570 locals = [{'addr': server1.ip4n,
4574 {'addr': server2.ip4n,
4579 self.nat44_add_address(self.nat_addr)
4580 self.vapi.nat44_add_del_lb_static_mapping(external_addr_n,
4583 local_num=len(locals),
4585 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
4586 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
4589 # from client to service
4590 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
4591 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
4592 TCP(sport=12345, dport=external_port))
4593 self.pg1.add_stream(p)
4594 self.pg_enable_capture(self.pg_interfaces)
4596 capture = self.pg0.get_capture(1)
4602 self.assertIn(ip.dst, [server1.ip4, server2.ip4])
4603 if ip.dst == server1.ip4:
4607 self.assertEqual(tcp.dport, local_port)
4608 self.assert_packet_checksums_valid(p)
4610 self.logger.error(ppp("Unexpected or invalid packet:", p))
4613 # from service back to client
4614 p = (Ether(src=server.mac, dst=self.pg0.local_mac) /
4615 IP(src=server.ip4, dst=self.pg1.remote_ip4) /
4616 TCP(sport=local_port, dport=12345))
4617 self.pg0.add_stream(p)
4618 self.pg_enable_capture(self.pg_interfaces)
4620 capture = self.pg1.get_capture(1)
4625 self.assertEqual(ip.src, self.nat_addr)
4626 self.assertEqual(tcp.sport, external_port)
4627 self.assert_packet_checksums_valid(p)
4629 self.logger.error(ppp("Unexpected or invalid packet:", p))
4632 sessions = self.vapi.nat44_user_session_dump(server.ip4n, 0)
4633 self.assertEqual(len(sessions), 1)
4634 self.assertTrue(sessions[0].ext_host_valid)
4635 self.vapi.nat44_del_session(
4636 sessions[0].inside_ip_address,
4637 sessions[0].inside_port,
4638 sessions[0].protocol,
4639 ext_host_address=sessions[0].ext_host_address,
4640 ext_host_port=sessions[0].ext_host_port)
4641 sessions = self.vapi.nat44_user_session_dump(server.ip4n, 0)
4642 self.assertEqual(len(sessions), 0)
4644 @unittest.skipUnless(running_extended_tests, "part of extended tests")
4645 def test_static_lb_multi_clients(self):
4646 """ NAT44 local service load balancing - multiple clients"""
4648 external_addr_n = socket.inet_pton(socket.AF_INET, self.nat_addr)
4651 server1 = self.pg0.remote_hosts[0]
4652 server2 = self.pg0.remote_hosts[1]
4653 server3 = self.pg0.remote_hosts[2]
4655 locals = [{'addr': server1.ip4n,
4659 {'addr': server2.ip4n,
4664 self.nat44_add_address(self.nat_addr)
4665 self.vapi.nat44_add_del_lb_static_mapping(external_addr_n,
4668 local_num=len(locals),
4670 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
4671 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
4676 clients = ip4_range(self.pg1.remote_ip4, 10, 50)
4678 for client in clients:
4679 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
4680 IP(src=client, dst=self.nat_addr) /
4681 TCP(sport=12345, dport=external_port))
4683 self.pg1.add_stream(pkts)
4684 self.pg_enable_capture(self.pg_interfaces)
4686 capture = self.pg0.get_capture(len(pkts))
4688 if p[IP].dst == server1.ip4:
4692 self.assertGreater(server1_n, server2_n)
4695 self.vapi.nat44_lb_static_mapping_add_del_local(external_addr_n,
4704 clients = ip4_range(self.pg1.remote_ip4, 60, 110)
4706 for client in clients:
4707 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
4708 IP(src=client, dst=self.nat_addr) /
4709 TCP(sport=12346, dport=external_port))
4711 self.assertGreater(len(pkts), 0)
4712 self.pg1.add_stream(pkts)
4713 self.pg_enable_capture(self.pg_interfaces)
4715 capture = self.pg0.get_capture(len(pkts))
4717 if p[IP].dst == server1.ip4:
4719 elif p[IP].dst == server2.ip4:
4723 self.assertGreater(server1_n, 0)
4724 self.assertGreater(server2_n, 0)
4725 self.assertGreater(server3_n, 0)
4727 # remove one back-end
4728 self.vapi.nat44_lb_static_mapping_add_del_local(external_addr_n,
4738 self.pg1.add_stream(pkts)
4739 self.pg_enable_capture(self.pg_interfaces)
4741 capture = self.pg0.get_capture(len(pkts))
4743 if p[IP].dst == server1.ip4:
4745 elif p[IP].dst == server2.ip4:
4749 self.assertGreater(server1_n, 0)
4750 self.assertEqual(server2_n, 0)
4751 self.assertGreater(server3_n, 0)
4753 def test_static_lb_2(self):
4754 """ NAT44 local service load balancing (asymmetrical rule) """
4755 external_addr_n = socket.inet_pton(socket.AF_INET, self.nat_addr)
4758 server1 = self.pg0.remote_hosts[0]
4759 server2 = self.pg0.remote_hosts[1]
4761 locals = [{'addr': server1.ip4n,
4765 {'addr': server2.ip4n,
4770 self.vapi.nat44_forwarding_enable_disable(1)
4771 self.vapi.nat44_add_del_lb_static_mapping(external_addr_n,
4775 local_num=len(locals),
4777 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
4778 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
4781 # from client to service
4782 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
4783 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
4784 TCP(sport=12345, dport=external_port))
4785 self.pg1.add_stream(p)
4786 self.pg_enable_capture(self.pg_interfaces)
4788 capture = self.pg0.get_capture(1)
4794 self.assertIn(ip.dst, [server1.ip4, server2.ip4])
4795 if ip.dst == server1.ip4:
4799 self.assertEqual(tcp.dport, local_port)
4800 self.assert_packet_checksums_valid(p)
4802 self.logger.error(ppp("Unexpected or invalid packet:", p))
4805 # from service back to client
4806 p = (Ether(src=server.mac, dst=self.pg0.local_mac) /
4807 IP(src=server.ip4, dst=self.pg1.remote_ip4) /
4808 TCP(sport=local_port, dport=12345))
4809 self.pg0.add_stream(p)
4810 self.pg_enable_capture(self.pg_interfaces)
4812 capture = self.pg1.get_capture(1)
4817 self.assertEqual(ip.src, self.nat_addr)
4818 self.assertEqual(tcp.sport, external_port)
4819 self.assert_packet_checksums_valid(p)
4821 self.logger.error(ppp("Unexpected or invalid packet:", p))
4824 # from client to server (no translation)
4825 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
4826 IP(src=self.pg1.remote_ip4, dst=server1.ip4) /
4827 TCP(sport=12346, dport=local_port))
4828 self.pg1.add_stream(p)
4829 self.pg_enable_capture(self.pg_interfaces)
4831 capture = self.pg0.get_capture(1)
4837 self.assertEqual(ip.dst, server1.ip4)
4838 self.assertEqual(tcp.dport, local_port)
4839 self.assert_packet_checksums_valid(p)
4841 self.logger.error(ppp("Unexpected or invalid packet:", p))
4844 # from service back to client (no translation)
4845 p = (Ether(src=server1.mac, dst=self.pg0.local_mac) /
4846 IP(src=server1.ip4, dst=self.pg1.remote_ip4) /
4847 TCP(sport=local_port, dport=12346))
4848 self.pg0.add_stream(p)
4849 self.pg_enable_capture(self.pg_interfaces)
4851 capture = self.pg1.get_capture(1)
4856 self.assertEqual(ip.src, server1.ip4)
4857 self.assertEqual(tcp.sport, local_port)
4858 self.assert_packet_checksums_valid(p)
4860 self.logger.error(ppp("Unexpected or invalid packet:", p))
4863 def test_lb_affinity(self):
4864 """ NAT44 local service load balancing affinity """
4865 external_addr_n = socket.inet_pton(socket.AF_INET, self.nat_addr)
4868 server1 = self.pg0.remote_hosts[0]
4869 server2 = self.pg0.remote_hosts[1]
4871 locals = [{'addr': server1.ip4n,
4875 {'addr': server2.ip4n,
4880 self.nat44_add_address(self.nat_addr)
4881 self.vapi.nat44_add_del_lb_static_mapping(external_addr_n,
4885 local_num=len(locals),
4887 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
4888 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
4891 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
4892 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
4893 TCP(sport=1025, dport=external_port))
4894 self.pg1.add_stream(p)
4895 self.pg_enable_capture(self.pg_interfaces)
4897 capture = self.pg0.get_capture(1)
4898 backend = capture[0][IP].dst
4900 sessions = self.vapi.nat44_user_session_dump(
4901 socket.inet_pton(socket.AF_INET, backend), 0)
4902 self.assertEqual(len(sessions), 1)
4903 self.assertTrue(sessions[0].ext_host_valid)
4904 self.vapi.nat44_del_session(
4905 sessions[0].inside_ip_address,
4906 sessions[0].inside_port,
4907 sessions[0].protocol,
4908 ext_host_address=sessions[0].ext_host_address,
4909 ext_host_port=sessions[0].ext_host_port)
4912 for port in range(1030, 1100):
4913 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
4914 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
4915 TCP(sport=port, dport=external_port))
4917 self.pg1.add_stream(pkts)
4918 self.pg_enable_capture(self.pg_interfaces)
4920 capture = self.pg0.get_capture(len(pkts))
4922 self.assertEqual(p[IP].dst, backend)
4924 def test_unknown_proto(self):
4925 """ NAT44 translate packet with unknown protocol """
4926 self.nat44_add_address(self.nat_addr)
4927 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
4928 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
4932 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
4933 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
4934 TCP(sport=self.tcp_port_in, dport=20))
4935 self.pg0.add_stream(p)
4936 self.pg_enable_capture(self.pg_interfaces)
4938 p = self.pg1.get_capture(1)
4940 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
4941 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
4943 IP(src=self.pg2.remote_ip4, dst=self.pg2.remote_ip4) /
4944 TCP(sport=1234, dport=1234))
4945 self.pg0.add_stream(p)
4946 self.pg_enable_capture(self.pg_interfaces)
4948 p = self.pg1.get_capture(1)
4951 self.assertEqual(packet[IP].src, self.nat_addr)
4952 self.assertEqual(packet[IP].dst, self.pg1.remote_ip4)
4953 self.assertEqual(packet.haslayer(GRE), 1)
4954 self.assert_packet_checksums_valid(packet)
4956 self.logger.error(ppp("Unexpected or invalid packet:", packet))
4960 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
4961 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
4963 IP(src=self.pg2.remote_ip4, dst=self.pg2.remote_ip4) /
4964 TCP(sport=1234, dport=1234))
4965 self.pg1.add_stream(p)
4966 self.pg_enable_capture(self.pg_interfaces)
4968 p = self.pg0.get_capture(1)
4971 self.assertEqual(packet[IP].src, self.pg1.remote_ip4)
4972 self.assertEqual(packet[IP].dst, self.pg0.remote_ip4)
4973 self.assertEqual(packet.haslayer(GRE), 1)
4974 self.assert_packet_checksums_valid(packet)
4976 self.logger.error(ppp("Unexpected or invalid packet:", packet))
4979 def test_hairpinning_unknown_proto(self):
4980 """ NAT44 translate packet with unknown protocol - hairpinning """
4981 host = self.pg0.remote_hosts[0]
4982 server = self.pg0.remote_hosts[1]
4984 server_out_port = 8765
4985 server_nat_ip = "10.0.0.11"
4987 self.nat44_add_address(self.nat_addr)
4988 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
4989 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
4992 # add static mapping for server
4993 self.nat44_add_static_mapping(server.ip4, server_nat_ip)
4996 p = (Ether(src=host.mac, dst=self.pg0.local_mac) /
4997 IP(src=host.ip4, dst=server_nat_ip) /
4998 TCP(sport=host_in_port, dport=server_out_port))
4999 self.pg0.add_stream(p)
5000 self.pg_enable_capture(self.pg_interfaces)
5002 self.pg0.get_capture(1)
5004 p = (Ether(dst=self.pg0.local_mac, src=host.mac) /
5005 IP(src=host.ip4, dst=server_nat_ip) /
5007 IP(src=self.pg2.remote_ip4, dst=self.pg2.remote_ip4) /
5008 TCP(sport=1234, dport=1234))
5009 self.pg0.add_stream(p)
5010 self.pg_enable_capture(self.pg_interfaces)
5012 p = self.pg0.get_capture(1)
5015 self.assertEqual(packet[IP].src, self.nat_addr)
5016 self.assertEqual(packet[IP].dst, server.ip4)
5017 self.assertEqual(packet.haslayer(GRE), 1)
5018 self.assert_packet_checksums_valid(packet)
5020 self.logger.error(ppp("Unexpected or invalid packet:", packet))
5024 p = (Ether(dst=self.pg0.local_mac, src=server.mac) /
5025 IP(src=server.ip4, dst=self.nat_addr) /
5027 IP(src=self.pg2.remote_ip4, dst=self.pg2.remote_ip4) /
5028 TCP(sport=1234, dport=1234))
5029 self.pg0.add_stream(p)
5030 self.pg_enable_capture(self.pg_interfaces)
5032 p = self.pg0.get_capture(1)
5035 self.assertEqual(packet[IP].src, server_nat_ip)
5036 self.assertEqual(packet[IP].dst, host.ip4)
5037 self.assertEqual(packet.haslayer(GRE), 1)
5038 self.assert_packet_checksums_valid(packet)
5040 self.logger.error(ppp("Unexpected or invalid packet:", packet))
5043 def test_output_feature_and_service(self):
5044 """ NAT44 interface output feature and services """
5045 external_addr = '1.2.3.4'
5049 self.vapi.nat44_forwarding_enable_disable(1)
5050 self.nat44_add_address(self.nat_addr)
5051 self.vapi.nat44_add_del_identity_mapping(ip=self.pg1.remote_ip4n)
5052 self.nat44_add_static_mapping(self.pg0.remote_ip4, external_addr,
5053 local_port, external_port,
5054 proto=IP_PROTOS.tcp, out2in_only=1)
5055 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
5056 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index,
5058 self.vapi.nat44_interface_add_del_output_feature(self.pg1.sw_if_index,
5061 # from client to service
5062 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
5063 IP(src=self.pg1.remote_ip4, dst=external_addr) /
5064 TCP(sport=12345, dport=external_port))
5065 self.pg1.add_stream(p)
5066 self.pg_enable_capture(self.pg_interfaces)
5068 capture = self.pg0.get_capture(1)
5073 self.assertEqual(ip.dst, self.pg0.remote_ip4)
5074 self.assertEqual(tcp.dport, local_port)
5075 self.assert_packet_checksums_valid(p)
5077 self.logger.error(ppp("Unexpected or invalid packet:", p))
5080 # from service back to client
5081 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5082 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
5083 TCP(sport=local_port, dport=12345))
5084 self.pg0.add_stream(p)
5085 self.pg_enable_capture(self.pg_interfaces)
5087 capture = self.pg1.get_capture(1)
5092 self.assertEqual(ip.src, external_addr)
5093 self.assertEqual(tcp.sport, external_port)
5094 self.assert_packet_checksums_valid(p)
5096 self.logger.error(ppp("Unexpected or invalid packet:", p))
5099 # from local network host to external network
5100 pkts = self.create_stream_in(self.pg0, self.pg1)
5101 self.pg0.add_stream(pkts)
5102 self.pg_enable_capture(self.pg_interfaces)
5104 capture = self.pg1.get_capture(len(pkts))
5105 self.verify_capture_out(capture)
5106 pkts = self.create_stream_in(self.pg0, self.pg1)
5107 self.pg0.add_stream(pkts)
5108 self.pg_enable_capture(self.pg_interfaces)
5110 capture = self.pg1.get_capture(len(pkts))
5111 self.verify_capture_out(capture)
5113 # from external network back to local network host
5114 pkts = self.create_stream_out(self.pg1)
5115 self.pg1.add_stream(pkts)
5116 self.pg_enable_capture(self.pg_interfaces)
5118 capture = self.pg0.get_capture(len(pkts))
5119 self.verify_capture_in(capture, self.pg0)
5121 def test_output_feature_and_service2(self):
5122 """ NAT44 interface output feature and service host direct access """
5123 self.vapi.nat44_forwarding_enable_disable(1)
5124 self.nat44_add_address(self.nat_addr)
5125 self.vapi.nat44_interface_add_del_output_feature(self.pg1.sw_if_index,
5128 # session initiaded from service host - translate
5129 pkts = self.create_stream_in(self.pg0, self.pg1)
5130 self.pg0.add_stream(pkts)
5131 self.pg_enable_capture(self.pg_interfaces)
5133 capture = self.pg1.get_capture(len(pkts))
5134 self.verify_capture_out(capture)
5136 pkts = self.create_stream_out(self.pg1)
5137 self.pg1.add_stream(pkts)
5138 self.pg_enable_capture(self.pg_interfaces)
5140 capture = self.pg0.get_capture(len(pkts))
5141 self.verify_capture_in(capture, self.pg0)
5143 # session initiaded from remote host - do not translate
5144 self.tcp_port_in = 60303
5145 self.udp_port_in = 60304
5146 self.icmp_id_in = 60305
5147 pkts = self.create_stream_out(self.pg1,
5148 self.pg0.remote_ip4,
5149 use_inside_ports=True)
5150 self.pg1.add_stream(pkts)
5151 self.pg_enable_capture(self.pg_interfaces)
5153 capture = self.pg0.get_capture(len(pkts))
5154 self.verify_capture_in(capture, self.pg0)
5156 pkts = self.create_stream_in(self.pg0, self.pg1)
5157 self.pg0.add_stream(pkts)
5158 self.pg_enable_capture(self.pg_interfaces)
5160 capture = self.pg1.get_capture(len(pkts))
5161 self.verify_capture_out(capture, nat_ip=self.pg0.remote_ip4,
5164 def test_output_feature_and_service3(self):
5165 """ NAT44 interface output feature and DST NAT """
5166 external_addr = '1.2.3.4'
5170 self.vapi.nat44_forwarding_enable_disable(1)
5171 self.nat44_add_address(self.nat_addr)
5172 self.nat44_add_static_mapping(self.pg1.remote_ip4, external_addr,
5173 local_port, external_port,
5174 proto=IP_PROTOS.tcp, out2in_only=1)
5175 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
5176 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index,
5178 self.vapi.nat44_interface_add_del_output_feature(self.pg1.sw_if_index,
5181 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5182 IP(src=self.pg0.remote_ip4, dst=external_addr) /
5183 TCP(sport=12345, dport=external_port))
5184 self.pg0.add_stream(p)
5185 self.pg_enable_capture(self.pg_interfaces)
5187 capture = self.pg1.get_capture(1)
5192 self.assertEqual(ip.src, self.pg0.remote_ip4)
5193 self.assertEqual(tcp.sport, 12345)
5194 self.assertEqual(ip.dst, self.pg1.remote_ip4)
5195 self.assertEqual(tcp.dport, local_port)
5196 self.assert_packet_checksums_valid(p)
5198 self.logger.error(ppp("Unexpected or invalid packet:", p))
5201 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
5202 IP(src=self.pg1.remote_ip4, dst=self.pg0.remote_ip4) /
5203 TCP(sport=local_port, dport=12345))
5204 self.pg1.add_stream(p)
5205 self.pg_enable_capture(self.pg_interfaces)
5207 capture = self.pg0.get_capture(1)
5212 self.assertEqual(ip.src, external_addr)
5213 self.assertEqual(tcp.sport, external_port)
5214 self.assertEqual(ip.dst, self.pg0.remote_ip4)
5215 self.assertEqual(tcp.dport, 12345)
5216 self.assert_packet_checksums_valid(p)
5218 self.logger.error(ppp("Unexpected or invalid packet:", p))
5221 def test_next_src_nat(self):
5222 """ On way back forward packet to nat44-in2out node. """
5223 twice_nat_addr = '10.0.1.3'
5226 post_twice_nat_port = 0
5228 self.vapi.nat44_forwarding_enable_disable(1)
5229 self.nat44_add_address(twice_nat_addr, twice_nat=1)
5230 self.nat44_add_static_mapping(self.pg6.remote_ip4, self.pg1.remote_ip4,
5231 local_port, external_port,
5232 proto=IP_PROTOS.tcp, out2in_only=1,
5233 self_twice_nat=1, vrf_id=1)
5234 self.vapi.nat44_interface_add_del_feature(self.pg6.sw_if_index,
5237 p = (Ether(src=self.pg6.remote_mac, dst=self.pg6.local_mac) /
5238 IP(src=self.pg6.remote_ip4, dst=self.pg1.remote_ip4) /
5239 TCP(sport=12345, dport=external_port))
5240 self.pg6.add_stream(p)
5241 self.pg_enable_capture(self.pg_interfaces)
5243 capture = self.pg6.get_capture(1)
5248 self.assertEqual(ip.src, twice_nat_addr)
5249 self.assertNotEqual(tcp.sport, 12345)
5250 post_twice_nat_port = tcp.sport
5251 self.assertEqual(ip.dst, self.pg6.remote_ip4)
5252 self.assertEqual(tcp.dport, local_port)
5253 self.assert_packet_checksums_valid(p)
5255 self.logger.error(ppp("Unexpected or invalid packet:", p))
5258 p = (Ether(src=self.pg6.remote_mac, dst=self.pg6.local_mac) /
5259 IP(src=self.pg6.remote_ip4, dst=twice_nat_addr) /
5260 TCP(sport=local_port, dport=post_twice_nat_port))
5261 self.pg6.add_stream(p)
5262 self.pg_enable_capture(self.pg_interfaces)
5264 capture = self.pg6.get_capture(1)
5269 self.assertEqual(ip.src, self.pg1.remote_ip4)
5270 self.assertEqual(tcp.sport, external_port)
5271 self.assertEqual(ip.dst, self.pg6.remote_ip4)
5272 self.assertEqual(tcp.dport, 12345)
5273 self.assert_packet_checksums_valid(p)
5275 self.logger.error(ppp("Unexpected or invalid packet:", p))
5278 def twice_nat_common(self, self_twice_nat=False, same_pg=False, lb=False,
5280 twice_nat_addr = '10.0.1.3'
5288 port_in1 = port_in+1
5289 port_in2 = port_in+2
5294 server1 = self.pg0.remote_hosts[0]
5295 server2 = self.pg0.remote_hosts[1]
5307 eh_translate = ((not self_twice_nat) or (not lb and same_pg) or
5310 self.nat44_add_address(self.nat_addr)
5311 self.nat44_add_address(twice_nat_addr, twice_nat=1)
5313 self.nat44_add_static_mapping(pg0.remote_ip4, self.nat_addr,
5315 proto=IP_PROTOS.tcp,
5316 twice_nat=int(not self_twice_nat),
5317 self_twice_nat=int(self_twice_nat))
5319 locals = [{'addr': server1.ip4n,
5323 {'addr': server2.ip4n,
5327 out_addr_n = socket.inet_pton(socket.AF_INET, self.nat_addr)
5328 self.vapi.nat44_add_del_lb_static_mapping(out_addr_n,
5332 not self_twice_nat),
5335 local_num=len(locals),
5337 self.vapi.nat44_interface_add_del_feature(pg0.sw_if_index)
5338 self.vapi.nat44_interface_add_del_feature(pg1.sw_if_index,
5345 assert client_id is not None
5347 client = self.pg0.remote_hosts[0]
5348 elif client_id == 2:
5349 client = self.pg0.remote_hosts[1]
5351 client = pg1.remote_hosts[0]
5352 p = (Ether(src=pg1.remote_mac, dst=pg1.local_mac) /
5353 IP(src=client.ip4, dst=self.nat_addr) /
5354 TCP(sport=eh_port_out, dport=port_out))
5356 self.pg_enable_capture(self.pg_interfaces)
5358 capture = pg0.get_capture(1)
5364 if ip.dst == server1.ip4:
5370 self.assertEqual(ip.dst, server.ip4)
5372 self.assertIn(tcp.dport, [port_in1, port_in2])
5374 self.assertEqual(tcp.dport, port_in)
5376 self.assertEqual(ip.src, twice_nat_addr)
5377 self.assertNotEqual(tcp.sport, eh_port_out)
5379 self.assertEqual(ip.src, client.ip4)
5380 self.assertEqual(tcp.sport, eh_port_out)
5382 eh_port_in = tcp.sport
5383 saved_port_in = tcp.dport
5384 self.assert_packet_checksums_valid(p)
5386 self.logger.error(ppp("Unexpected or invalid packet:", p))
5389 p = (Ether(src=server.mac, dst=pg0.local_mac) /
5390 IP(src=server.ip4, dst=eh_addr_in) /
5391 TCP(sport=saved_port_in, dport=eh_port_in))
5393 self.pg_enable_capture(self.pg_interfaces)
5395 capture = pg1.get_capture(1)
5400 self.assertEqual(ip.dst, client.ip4)
5401 self.assertEqual(ip.src, self.nat_addr)
5402 self.assertEqual(tcp.dport, eh_port_out)
5403 self.assertEqual(tcp.sport, port_out)
5404 self.assert_packet_checksums_valid(p)
5406 self.logger.error(ppp("Unexpected or invalid packet:", p))
5410 sessions = self.vapi.nat44_user_session_dump(server.ip4n, 0)
5411 self.assertEqual(len(sessions), 1)
5412 self.assertTrue(sessions[0].ext_host_valid)
5413 self.assertTrue(sessions[0].is_twicenat)
5414 self.vapi.nat44_del_session(
5415 sessions[0].inside_ip_address,
5416 sessions[0].inside_port,
5417 sessions[0].protocol,
5418 ext_host_address=sessions[0].ext_host_nat_address,
5419 ext_host_port=sessions[0].ext_host_nat_port)
5420 sessions = self.vapi.nat44_user_session_dump(server.ip4n, 0)
5421 self.assertEqual(len(sessions), 0)
5423 def test_twice_nat(self):
5425 self.twice_nat_common()
5427 def test_self_twice_nat_positive(self):
5428 """ Self Twice NAT44 (positive test) """
5429 self.twice_nat_common(self_twice_nat=True, same_pg=True)
5431 def test_self_twice_nat_negative(self):
5432 """ Self Twice NAT44 (negative test) """
5433 self.twice_nat_common(self_twice_nat=True)
5435 def test_twice_nat_lb(self):
5436 """ Twice NAT44 local service load balancing """
5437 self.twice_nat_common(lb=True)
5439 def test_self_twice_nat_lb_positive(self):
5440 """ Self Twice NAT44 local service load balancing (positive test) """
5441 self.twice_nat_common(lb=True, self_twice_nat=True, same_pg=True,
5444 def test_self_twice_nat_lb_negative(self):
5445 """ Self Twice NAT44 local service load balancing (negative test) """
5446 self.twice_nat_common(lb=True, self_twice_nat=True, same_pg=True,
5449 def test_twice_nat_interface_addr(self):
5450 """ Acquire twice NAT44 addresses from interface """
5451 self.vapi.nat44_add_interface_addr(self.pg3.sw_if_index, twice_nat=1)
5453 # no address in NAT pool
5454 adresses = self.vapi.nat44_address_dump()
5455 self.assertEqual(0, len(adresses))
5457 # configure interface address and check NAT address pool
5458 self.pg3.config_ip4()
5459 adresses = self.vapi.nat44_address_dump()
5460 self.assertEqual(1, len(adresses))
5461 self.assertEqual(adresses[0].ip_address[0:4], self.pg3.local_ip4n)
5462 self.assertEqual(adresses[0].twice_nat, 1)
5464 # remove interface address and check NAT address pool
5465 self.pg3.unconfig_ip4()
5466 adresses = self.vapi.nat44_address_dump()
5467 self.assertEqual(0, len(adresses))
5469 def test_tcp_close(self):
5470 """ Close TCP session from inside network - output feature """
5471 self.vapi.nat44_forwarding_enable_disable(1)
5472 self.nat44_add_address(self.pg1.local_ip4)
5473 twice_nat_addr = '10.0.1.3'
5474 service_ip = '192.168.16.150'
5475 self.nat44_add_address(twice_nat_addr, twice_nat=1)
5476 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
5477 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index,
5479 self.vapi.nat44_interface_add_del_output_feature(self.pg1.sw_if_index,
5481 self.nat44_add_static_mapping(self.pg0.remote_ip4,
5485 proto=IP_PROTOS.tcp,
5488 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4n, 0)
5489 start_sessnum = len(sessions)
5491 # SYN packet out->in
5492 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
5493 IP(src=self.pg1.remote_ip4, dst=service_ip) /
5494 TCP(sport=33898, dport=80, flags="S"))
5495 self.pg1.add_stream(p)
5496 self.pg_enable_capture(self.pg_interfaces)
5498 capture = self.pg0.get_capture(1)
5500 tcp_port = p[TCP].sport
5502 # SYN + ACK packet in->out
5503 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5504 IP(src=self.pg0.remote_ip4, dst=twice_nat_addr) /
5505 TCP(sport=80, dport=tcp_port, flags="SA"))
5506 self.pg0.add_stream(p)
5507 self.pg_enable_capture(self.pg_interfaces)
5509 self.pg1.get_capture(1)
5511 # ACK packet out->in
5512 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
5513 IP(src=self.pg1.remote_ip4, dst=service_ip) /
5514 TCP(sport=33898, dport=80, flags="A"))
5515 self.pg1.add_stream(p)
5516 self.pg_enable_capture(self.pg_interfaces)
5518 self.pg0.get_capture(1)
5520 # FIN packet in -> out
5521 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5522 IP(src=self.pg0.remote_ip4, dst=twice_nat_addr) /
5523 TCP(sport=80, dport=tcp_port, flags="FA", seq=100, ack=300))
5524 self.pg0.add_stream(p)
5525 self.pg_enable_capture(self.pg_interfaces)
5527 self.pg1.get_capture(1)
5529 # FIN+ACK packet out -> in
5530 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
5531 IP(src=self.pg1.remote_ip4, dst=service_ip) /
5532 TCP(sport=33898, dport=80, flags="FA", seq=300, ack=101))
5533 self.pg1.add_stream(p)
5534 self.pg_enable_capture(self.pg_interfaces)
5536 self.pg0.get_capture(1)
5538 # ACK packet in -> out
5539 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5540 IP(src=self.pg0.remote_ip4, dst=twice_nat_addr) /
5541 TCP(sport=80, dport=tcp_port, flags="A", seq=101, ack=301))
5542 self.pg0.add_stream(p)
5543 self.pg_enable_capture(self.pg_interfaces)
5545 self.pg1.get_capture(1)
5547 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4n,
5549 self.assertEqual(len(sessions) - start_sessnum, 0)
5551 def test_tcp_session_close_in(self):
5552 """ Close TCP session from inside network """
5553 self.tcp_port_out = 10505
5554 self.nat44_add_address(self.nat_addr)
5555 self.nat44_add_static_mapping(self.pg0.remote_ip4,
5559 proto=IP_PROTOS.tcp,
5561 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
5562 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
5565 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4n, 0)
5566 start_sessnum = len(sessions)
5568 self.initiate_tcp_session(self.pg0, self.pg1)
5570 # FIN packet in -> out
5571 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5572 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
5573 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
5574 flags="FA", seq=100, ack=300))
5575 self.pg0.add_stream(p)
5576 self.pg_enable_capture(self.pg_interfaces)
5578 self.pg1.get_capture(1)
5582 # ACK packet out -> in
5583 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
5584 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
5585 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
5586 flags="A", seq=300, ack=101))
5589 # FIN packet out -> in
5590 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
5591 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
5592 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
5593 flags="FA", seq=300, ack=101))
5596 self.pg1.add_stream(pkts)
5597 self.pg_enable_capture(self.pg_interfaces)
5599 self.pg0.get_capture(2)
5601 # ACK packet in -> out
5602 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5603 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
5604 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
5605 flags="A", seq=101, ack=301))
5606 self.pg0.add_stream(p)
5607 self.pg_enable_capture(self.pg_interfaces)
5609 self.pg1.get_capture(1)
5611 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4n,
5613 self.assertEqual(len(sessions) - start_sessnum, 0)
5615 def test_tcp_session_close_out(self):
5616 """ Close TCP session from outside network """
5617 self.tcp_port_out = 10505
5618 self.nat44_add_address(self.nat_addr)
5619 self.nat44_add_static_mapping(self.pg0.remote_ip4,
5623 proto=IP_PROTOS.tcp,
5625 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
5626 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
5629 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4n, 0)
5630 start_sessnum = len(sessions)
5632 self.initiate_tcp_session(self.pg0, self.pg1)
5634 # FIN packet out -> in
5635 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
5636 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
5637 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
5638 flags="FA", seq=100, ack=300))
5639 self.pg1.add_stream(p)
5640 self.pg_enable_capture(self.pg_interfaces)
5642 self.pg0.get_capture(1)
5644 # FIN+ACK packet in -> out
5645 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5646 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
5647 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
5648 flags="FA", seq=300, ack=101))
5650 self.pg0.add_stream(p)
5651 self.pg_enable_capture(self.pg_interfaces)
5653 self.pg1.get_capture(1)
5655 # ACK packet out -> in
5656 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
5657 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
5658 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
5659 flags="A", seq=101, ack=301))
5660 self.pg1.add_stream(p)
5661 self.pg_enable_capture(self.pg_interfaces)
5663 self.pg0.get_capture(1)
5665 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4n,
5667 self.assertEqual(len(sessions) - start_sessnum, 0)
5669 def test_tcp_session_close_simultaneous(self):
5670 """ Close TCP session from inside network """
5671 self.tcp_port_out = 10505
5672 self.nat44_add_address(self.nat_addr)
5673 self.nat44_add_static_mapping(self.pg0.remote_ip4,
5677 proto=IP_PROTOS.tcp,
5679 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
5680 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
5683 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4n, 0)
5684 start_sessnum = len(sessions)
5686 self.initiate_tcp_session(self.pg0, self.pg1)
5688 # FIN packet in -> out
5689 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5690 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
5691 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
5692 flags="FA", seq=100, ack=300))
5693 self.pg0.add_stream(p)
5694 self.pg_enable_capture(self.pg_interfaces)
5696 self.pg1.get_capture(1)
5698 # FIN packet out -> in
5699 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
5700 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
5701 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
5702 flags="FA", seq=300, ack=100))
5703 self.pg1.add_stream(p)
5704 self.pg_enable_capture(self.pg_interfaces)
5706 self.pg0.get_capture(1)
5708 # ACK packet in -> out
5709 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5710 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
5711 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
5712 flags="A", seq=101, ack=301))
5713 self.pg0.add_stream(p)
5714 self.pg_enable_capture(self.pg_interfaces)
5716 self.pg1.get_capture(1)
5718 # ACK packet out -> in
5719 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
5720 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
5721 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
5722 flags="A", seq=301, ack=101))
5723 self.pg1.add_stream(p)
5724 self.pg_enable_capture(self.pg_interfaces)
5726 self.pg0.get_capture(1)
5728 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4n,
5730 self.assertEqual(len(sessions) - start_sessnum, 0)
5732 def test_one_armed_nat44_static(self):
5733 """ One armed NAT44 and 1:1 NAPT asymmetrical rule """
5734 remote_host = self.pg4.remote_hosts[0]
5735 local_host = self.pg4.remote_hosts[1]
5740 self.vapi.nat44_forwarding_enable_disable(1)
5741 self.nat44_add_address(self.nat_addr, twice_nat=1)
5742 self.nat44_add_static_mapping(local_host.ip4, self.nat_addr,
5743 local_port, external_port,
5744 proto=IP_PROTOS.tcp, out2in_only=1,
5746 self.vapi.nat44_interface_add_del_feature(self.pg4.sw_if_index)
5747 self.vapi.nat44_interface_add_del_feature(self.pg4.sw_if_index,
5750 # from client to service
5751 p = (Ether(src=self.pg4.remote_mac, dst=self.pg4.local_mac) /
5752 IP(src=remote_host.ip4, dst=self.nat_addr) /
5753 TCP(sport=12345, dport=external_port))
5754 self.pg4.add_stream(p)
5755 self.pg_enable_capture(self.pg_interfaces)
5757 capture = self.pg4.get_capture(1)
5762 self.assertEqual(ip.dst, local_host.ip4)
5763 self.assertEqual(ip.src, self.nat_addr)
5764 self.assertEqual(tcp.dport, local_port)
5765 self.assertNotEqual(tcp.sport, 12345)
5766 eh_port_in = tcp.sport
5767 self.assert_packet_checksums_valid(p)
5769 self.logger.error(ppp("Unexpected or invalid packet:", p))
5772 # from service back to client
5773 p = (Ether(src=self.pg4.remote_mac, dst=self.pg4.local_mac) /
5774 IP(src=local_host.ip4, dst=self.nat_addr) /
5775 TCP(sport=local_port, dport=eh_port_in))
5776 self.pg4.add_stream(p)
5777 self.pg_enable_capture(self.pg_interfaces)
5779 capture = self.pg4.get_capture(1)
5784 self.assertEqual(ip.src, self.nat_addr)
5785 self.assertEqual(ip.dst, remote_host.ip4)
5786 self.assertEqual(tcp.sport, external_port)
5787 self.assertEqual(tcp.dport, 12345)
5788 self.assert_packet_checksums_valid(p)
5790 self.logger.error(ppp("Unexpected or invalid packet:", p))
5793 def test_static_with_port_out2(self):
5794 """ 1:1 NAPT asymmetrical rule """
5799 self.vapi.nat44_forwarding_enable_disable(1)
5800 self.nat44_add_static_mapping(self.pg0.remote_ip4, self.nat_addr,
5801 local_port, external_port,
5802 proto=IP_PROTOS.tcp, out2in_only=1)
5803 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
5804 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
5807 # from client to service
5808 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
5809 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
5810 TCP(sport=12345, dport=external_port))
5811 self.pg1.add_stream(p)
5812 self.pg_enable_capture(self.pg_interfaces)
5814 capture = self.pg0.get_capture(1)
5819 self.assertEqual(ip.dst, self.pg0.remote_ip4)
5820 self.assertEqual(tcp.dport, local_port)
5821 self.assert_packet_checksums_valid(p)
5823 self.logger.error(ppp("Unexpected or invalid packet:", p))
5827 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
5828 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
5829 ICMP(type=11) / capture[0][IP])
5830 self.pg0.add_stream(p)
5831 self.pg_enable_capture(self.pg_interfaces)
5833 capture = self.pg1.get_capture(1)
5836 self.assertEqual(p[IP].src, self.nat_addr)
5838 self.assertEqual(inner.dst, self.nat_addr)
5839 self.assertEqual(inner[TCPerror].dport, external_port)
5841 self.logger.error(ppp("Unexpected or invalid packet:", p))
5844 # from service back to client
5845 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5846 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
5847 TCP(sport=local_port, dport=12345))
5848 self.pg0.add_stream(p)
5849 self.pg_enable_capture(self.pg_interfaces)
5851 capture = self.pg1.get_capture(1)
5856 self.assertEqual(ip.src, self.nat_addr)
5857 self.assertEqual(tcp.sport, external_port)
5858 self.assert_packet_checksums_valid(p)
5860 self.logger.error(ppp("Unexpected or invalid packet:", p))
5864 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
5865 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
5866 ICMP(type=11) / capture[0][IP])
5867 self.pg1.add_stream(p)
5868 self.pg_enable_capture(self.pg_interfaces)
5870 capture = self.pg0.get_capture(1)
5873 self.assertEqual(p[IP].dst, self.pg0.remote_ip4)
5875 self.assertEqual(inner.src, self.pg0.remote_ip4)
5876 self.assertEqual(inner[TCPerror].sport, local_port)
5878 self.logger.error(ppp("Unexpected or invalid packet:", p))
5881 # from client to server (no translation)
5882 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
5883 IP(src=self.pg1.remote_ip4, dst=self.pg0.remote_ip4) /
5884 TCP(sport=12346, dport=local_port))
5885 self.pg1.add_stream(p)
5886 self.pg_enable_capture(self.pg_interfaces)
5888 capture = self.pg0.get_capture(1)
5893 self.assertEqual(ip.dst, self.pg0.remote_ip4)
5894 self.assertEqual(tcp.dport, local_port)
5895 self.assert_packet_checksums_valid(p)
5897 self.logger.error(ppp("Unexpected or invalid packet:", p))
5900 # from service back to client (no translation)
5901 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5902 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
5903 TCP(sport=local_port, dport=12346))
5904 self.pg0.add_stream(p)
5905 self.pg_enable_capture(self.pg_interfaces)
5907 capture = self.pg1.get_capture(1)
5912 self.assertEqual(ip.src, self.pg0.remote_ip4)
5913 self.assertEqual(tcp.sport, local_port)
5914 self.assert_packet_checksums_valid(p)
5916 self.logger.error(ppp("Unexpected or invalid packet:", p))
5919 def test_output_feature(self):
5920 """ NAT44 interface output feature (in2out postrouting) """
5921 self.vapi.nat44_forwarding_enable_disable(1)
5922 self.nat44_add_address(self.nat_addr)
5923 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index,
5925 self.vapi.nat44_interface_add_del_output_feature(self.pg1.sw_if_index,
5929 pkts = self.create_stream_in(self.pg0, self.pg1)
5930 self.pg0.add_stream(pkts)
5931 self.pg_enable_capture(self.pg_interfaces)
5933 capture = self.pg1.get_capture(len(pkts))
5934 self.verify_capture_out(capture)
5937 pkts = self.create_stream_out(self.pg1)
5938 self.pg1.add_stream(pkts)
5939 self.pg_enable_capture(self.pg_interfaces)
5941 capture = self.pg0.get_capture(len(pkts))
5942 self.verify_capture_in(capture, self.pg0)
5944 def test_multiple_vrf(self):
5945 """ Multiple VRF setup """
5946 external_addr = '1.2.3.4'
5951 self.vapi.nat44_forwarding_enable_disable(1)
5952 self.nat44_add_address(self.nat_addr)
5953 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
5954 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index,
5956 self.vapi.nat44_interface_add_del_output_feature(self.pg1.sw_if_index,
5958 self.vapi.nat44_interface_add_del_feature(self.pg5.sw_if_index)
5959 self.vapi.nat44_interface_add_del_feature(self.pg5.sw_if_index,
5961 self.vapi.nat44_interface_add_del_feature(self.pg6.sw_if_index,
5963 self.nat44_add_static_mapping(self.pg5.remote_ip4, external_addr,
5964 local_port, external_port, vrf_id=1,
5965 proto=IP_PROTOS.tcp, out2in_only=1)
5966 self.nat44_add_static_mapping(
5967 self.pg0.remote_ip4, external_sw_if_index=self.pg0.sw_if_index,
5968 local_port=local_port, vrf_id=0, external_port=external_port,
5969 proto=IP_PROTOS.tcp, out2in_only=1)
5971 # from client to service (both VRF1)
5972 p = (Ether(src=self.pg6.remote_mac, dst=self.pg6.local_mac) /
5973 IP(src=self.pg6.remote_ip4, dst=external_addr) /
5974 TCP(sport=12345, dport=external_port))
5975 self.pg6.add_stream(p)
5976 self.pg_enable_capture(self.pg_interfaces)
5978 capture = self.pg5.get_capture(1)
5983 self.assertEqual(ip.dst, self.pg5.remote_ip4)
5984 self.assertEqual(tcp.dport, local_port)
5985 self.assert_packet_checksums_valid(p)
5987 self.logger.error(ppp("Unexpected or invalid packet:", p))
5990 # from service back to client (both VRF1)
5991 p = (Ether(src=self.pg5.remote_mac, dst=self.pg5.local_mac) /
5992 IP(src=self.pg5.remote_ip4, dst=self.pg6.remote_ip4) /
5993 TCP(sport=local_port, dport=12345))
5994 self.pg5.add_stream(p)
5995 self.pg_enable_capture(self.pg_interfaces)
5997 capture = self.pg6.get_capture(1)
6002 self.assertEqual(ip.src, external_addr)
6003 self.assertEqual(tcp.sport, external_port)
6004 self.assert_packet_checksums_valid(p)
6006 self.logger.error(ppp("Unexpected or invalid packet:", p))
6009 # dynamic NAT from VRF1 to VRF0 (output-feature)
6010 p = (Ether(src=self.pg5.remote_mac, dst=self.pg5.local_mac) /
6011 IP(src=self.pg5.remote_ip4, dst=self.pg1.remote_ip4) /
6012 TCP(sport=2345, dport=22))
6013 self.pg5.add_stream(p)
6014 self.pg_enable_capture(self.pg_interfaces)
6016 capture = self.pg1.get_capture(1)
6021 self.assertEqual(ip.src, self.nat_addr)
6022 self.assertNotEqual(tcp.sport, 2345)
6023 self.assert_packet_checksums_valid(p)
6026 self.logger.error(ppp("Unexpected or invalid packet:", p))
6029 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
6030 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
6031 TCP(sport=22, dport=port))
6032 self.pg1.add_stream(p)
6033 self.pg_enable_capture(self.pg_interfaces)
6035 capture = self.pg5.get_capture(1)
6040 self.assertEqual(ip.dst, self.pg5.remote_ip4)
6041 self.assertEqual(tcp.dport, 2345)
6042 self.assert_packet_checksums_valid(p)
6044 self.logger.error(ppp("Unexpected or invalid packet:", p))
6047 # from client VRF1 to service VRF0
6048 p = (Ether(src=self.pg6.remote_mac, dst=self.pg6.local_mac) /
6049 IP(src=self.pg6.remote_ip4, dst=self.pg0.local_ip4) /
6050 TCP(sport=12346, dport=external_port))
6051 self.pg6.add_stream(p)
6052 self.pg_enable_capture(self.pg_interfaces)
6054 capture = self.pg0.get_capture(1)
6059 self.assertEqual(ip.dst, self.pg0.remote_ip4)
6060 self.assertEqual(tcp.dport, local_port)
6061 self.assert_packet_checksums_valid(p)
6063 self.logger.error(ppp("Unexpected or invalid packet:", p))
6066 # from service VRF0 back to client VRF1
6067 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6068 IP(src=self.pg0.remote_ip4, dst=self.pg6.remote_ip4) /
6069 TCP(sport=local_port, dport=12346))
6070 self.pg0.add_stream(p)
6071 self.pg_enable_capture(self.pg_interfaces)
6073 capture = self.pg6.get_capture(1)
6078 self.assertEqual(ip.src, self.pg0.local_ip4)
6079 self.assertEqual(tcp.sport, external_port)
6080 self.assert_packet_checksums_valid(p)
6082 self.logger.error(ppp("Unexpected or invalid packet:", p))
6085 # from client VRF0 to service VRF1
6086 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6087 IP(src=self.pg0.remote_ip4, dst=external_addr) /
6088 TCP(sport=12347, dport=external_port))
6089 self.pg0.add_stream(p)
6090 self.pg_enable_capture(self.pg_interfaces)
6092 capture = self.pg5.get_capture(1)
6097 self.assertEqual(ip.dst, self.pg5.remote_ip4)
6098 self.assertEqual(tcp.dport, local_port)
6099 self.assert_packet_checksums_valid(p)
6101 self.logger.error(ppp("Unexpected or invalid packet:", p))
6104 # from service VRF1 back to client VRF0
6105 p = (Ether(src=self.pg5.remote_mac, dst=self.pg5.local_mac) /
6106 IP(src=self.pg5.remote_ip4, dst=self.pg0.remote_ip4) /
6107 TCP(sport=local_port, dport=12347))
6108 self.pg5.add_stream(p)
6109 self.pg_enable_capture(self.pg_interfaces)
6111 capture = self.pg0.get_capture(1)
6116 self.assertEqual(ip.src, external_addr)
6117 self.assertEqual(tcp.sport, external_port)
6118 self.assert_packet_checksums_valid(p)
6120 self.logger.error(ppp("Unexpected or invalid packet:", p))
6123 # from client to server (both VRF1, no translation)
6124 p = (Ether(src=self.pg6.remote_mac, dst=self.pg6.local_mac) /
6125 IP(src=self.pg6.remote_ip4, dst=self.pg5.remote_ip4) /
6126 TCP(sport=12348, dport=local_port))
6127 self.pg6.add_stream(p)
6128 self.pg_enable_capture(self.pg_interfaces)
6130 capture = self.pg5.get_capture(1)
6135 self.assertEqual(ip.dst, self.pg5.remote_ip4)
6136 self.assertEqual(tcp.dport, local_port)
6137 self.assert_packet_checksums_valid(p)
6139 self.logger.error(ppp("Unexpected or invalid packet:", p))
6142 # from server back to client (both VRF1, no translation)
6143 p = (Ether(src=self.pg5.remote_mac, dst=self.pg5.local_mac) /
6144 IP(src=self.pg5.remote_ip4, dst=self.pg6.remote_ip4) /
6145 TCP(sport=local_port, dport=12348))
6146 self.pg5.add_stream(p)
6147 self.pg_enable_capture(self.pg_interfaces)
6149 capture = self.pg6.get_capture(1)
6154 self.assertEqual(ip.src, self.pg5.remote_ip4)
6155 self.assertEqual(tcp.sport, local_port)
6156 self.assert_packet_checksums_valid(p)
6158 self.logger.error(ppp("Unexpected or invalid packet:", p))
6161 # from client VRF1 to server VRF0 (no translation)
6162 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6163 IP(src=self.pg0.remote_ip4, dst=self.pg6.remote_ip4) /
6164 TCP(sport=local_port, dport=12349))
6165 self.pg0.add_stream(p)
6166 self.pg_enable_capture(self.pg_interfaces)
6168 capture = self.pg6.get_capture(1)
6173 self.assertEqual(ip.src, self.pg0.remote_ip4)
6174 self.assertEqual(tcp.sport, local_port)
6175 self.assert_packet_checksums_valid(p)
6177 self.logger.error(ppp("Unexpected or invalid packet:", p))
6180 # from server VRF0 back to client VRF1 (no translation)
6181 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6182 IP(src=self.pg0.remote_ip4, dst=self.pg6.remote_ip4) /
6183 TCP(sport=local_port, dport=12349))
6184 self.pg0.add_stream(p)
6185 self.pg_enable_capture(self.pg_interfaces)
6187 capture = self.pg6.get_capture(1)
6192 self.assertEqual(ip.src, self.pg0.remote_ip4)
6193 self.assertEqual(tcp.sport, local_port)
6194 self.assert_packet_checksums_valid(p)
6196 self.logger.error(ppp("Unexpected or invalid packet:", p))
6199 # from client VRF0 to server VRF1 (no translation)
6200 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6201 IP(src=self.pg0.remote_ip4, dst=self.pg5.remote_ip4) /
6202 TCP(sport=12344, dport=local_port))
6203 self.pg0.add_stream(p)
6204 self.pg_enable_capture(self.pg_interfaces)
6206 capture = self.pg5.get_capture(1)
6211 self.assertEqual(ip.dst, self.pg5.remote_ip4)
6212 self.assertEqual(tcp.dport, local_port)
6213 self.assert_packet_checksums_valid(p)
6215 self.logger.error(ppp("Unexpected or invalid packet:", p))
6218 # from server VRF1 back to client VRF0 (no translation)
6219 p = (Ether(src=self.pg5.remote_mac, dst=self.pg5.local_mac) /
6220 IP(src=self.pg5.remote_ip4, dst=self.pg0.remote_ip4) /
6221 TCP(sport=local_port, dport=12344))
6222 self.pg5.add_stream(p)
6223 self.pg_enable_capture(self.pg_interfaces)
6225 capture = self.pg0.get_capture(1)
6230 self.assertEqual(ip.src, self.pg5.remote_ip4)
6231 self.assertEqual(tcp.sport, local_port)
6232 self.assert_packet_checksums_valid(p)
6234 self.logger.error(ppp("Unexpected or invalid packet:", p))
6237 @unittest.skipUnless(running_extended_tests, "part of extended tests")
6238 def test_session_timeout(self):
6239 """ NAT44 session timeouts """
6240 self.nat44_add_address(self.nat_addr)
6241 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
6242 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
6244 self.vapi.nat_set_timeouts(icmp=5)
6248 for i in range(0, max_sessions):
6249 src = "10.10.%u.%u" % ((i & 0xFF00) >> 8, i & 0xFF)
6250 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
6251 IP(src=src, dst=self.pg1.remote_ip4) /
6252 ICMP(id=1025, type='echo-request'))
6254 self.pg0.add_stream(pkts)
6255 self.pg_enable_capture(self.pg_interfaces)
6257 self.pg1.get_capture(max_sessions)
6262 for i in range(0, max_sessions):
6263 src = "10.11.%u.%u" % ((i & 0xFF00) >> 8, i & 0xFF)
6264 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
6265 IP(src=src, dst=self.pg1.remote_ip4) /
6266 ICMP(id=1026, type='echo-request'))
6268 self.pg0.add_stream(pkts)
6269 self.pg_enable_capture(self.pg_interfaces)
6271 self.pg1.get_capture(max_sessions)
6274 users = self.vapi.nat44_user_dump()
6276 nsessions = nsessions + user.nsessions
6277 self.assertLess(nsessions, 2 * max_sessions)
6279 @unittest.skipUnless(running_extended_tests, "part of extended tests")
6280 def test_session_rst_timeout(self):
6281 """ NAT44 session RST timeouts """
6282 self.nat44_add_address(self.nat_addr)
6283 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
6284 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
6286 self.vapi.nat_set_timeouts(tcp_transitory=5)
6288 self.initiate_tcp_session(self.pg0, self.pg1)
6289 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6290 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6291 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
6293 self.pg0.add_stream(p)
6294 self.pg_enable_capture(self.pg_interfaces)
6296 self.pg1.get_capture(1)
6300 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6301 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6302 TCP(sport=self.tcp_port_in + 1, dport=self.tcp_external_port + 1,
6304 self.pg0.add_stream(p)
6305 self.pg_enable_capture(self.pg_interfaces)
6307 self.pg1.get_capture(1)
6310 users = self.vapi.nat44_user_dump()
6311 self.assertEqual(len(users), 1)
6312 self.assertEqual(users[0].ip_address, self.pg0.remote_ip4n)
6313 self.assertEqual(users[0].nsessions, 1)
6315 @unittest.skipUnless(running_extended_tests, "part of extended tests")
6316 def test_session_limit_per_user(self):
6317 """ Maximum sessions per user limit """
6318 self.nat44_add_address(self.nat_addr)
6319 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
6320 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
6322 self.vapi.set_ipfix_exporter(collector_address=self.pg2.remote_ip4n,
6323 src_address=self.pg2.local_ip4n,
6325 template_interval=10)
6326 self.vapi.nat_set_timeouts(udp=5)
6328 # get maximum number of translations per user
6329 nat44_config = self.vapi.nat_show_config()
6332 for port in range(0, nat44_config.max_translations_per_user):
6333 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6334 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6335 UDP(sport=1025 + port, dport=1025 + port))
6338 self.pg0.add_stream(pkts)
6339 self.pg_enable_capture(self.pg_interfaces)
6341 capture = self.pg1.get_capture(len(pkts))
6343 self.vapi.nat_ipfix(domain_id=self.ipfix_domain_id,
6344 src_port=self.ipfix_src_port)
6346 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6347 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6348 UDP(sport=3001, dport=3002))
6349 self.pg0.add_stream(p)
6350 self.pg_enable_capture(self.pg_interfaces)
6352 capture = self.pg1.assert_nothing_captured()
6354 # verify IPFIX logging
6355 self.vapi.cli("ipfix flush") # FIXME this should be an API call
6357 capture = self.pg2.get_capture(10)
6358 ipfix = IPFIXDecoder()
6359 # first load template
6361 self.assertTrue(p.haslayer(IPFIX))
6362 if p.haslayer(Template):
6363 ipfix.add_template(p.getlayer(Template))
6364 # verify events in data set
6366 if p.haslayer(Data):
6367 data = ipfix.decode_data_set(p.getlayer(Set))
6368 self.verify_ipfix_max_entries_per_user(
6370 nat44_config.max_translations_per_user,
6371 self.pg0.remote_ip4n)
6374 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6375 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6376 UDP(sport=3001, dport=3002))
6377 self.pg0.add_stream(p)
6378 self.pg_enable_capture(self.pg_interfaces)
6380 self.pg1.get_capture(1)
6382 def test_syslog_sess(self):
6383 """ Test syslog session creation and deletion """
6384 self.vapi.syslog_set_filter(SYSLOG_SEVERITY.INFO)
6385 self.vapi.syslog_set_sender(self.pg2.remote_ip4n, self.pg2.local_ip4n)
6386 self.nat44_add_address(self.nat_addr)
6387 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
6388 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
6391 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
6392 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6393 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port))
6394 self.pg0.add_stream(p)
6395 self.pg_enable_capture(self.pg_interfaces)
6397 capture = self.pg1.get_capture(1)
6398 self.tcp_port_out = capture[0][TCP].sport
6399 capture = self.pg2.get_capture(1)
6400 self.verify_syslog_sess(capture[0][Raw].load)
6402 self.pg_enable_capture(self.pg_interfaces)
6404 self.nat44_add_address(self.nat_addr, is_add=0)
6405 capture = self.pg2.get_capture(1)
6406 self.verify_syslog_sess(capture[0][Raw].load, False)
6409 super(TestNAT44EndpointDependent, self).tearDown()
6410 if not self.vpp_dead:
6411 self.logger.info(self.vapi.cli("show nat44 addresses"))
6412 self.logger.info(self.vapi.cli("show nat44 interfaces"))
6413 self.logger.info(self.vapi.cli("show nat44 static mappings"))
6414 self.logger.info(self.vapi.cli("show nat44 interface address"))
6415 self.logger.info(self.vapi.cli("show nat44 sessions detail"))
6416 self.logger.info(self.vapi.cli("show nat44 hash tables detail"))
6417 self.logger.info(self.vapi.cli("show nat timeouts"))
6419 self.vapi.cli("clear logging")
6422 class TestNAT44Out2InDPO(MethodHolder):
6423 """ NAT44 Test Cases using out2in DPO """
6426 def setUpConstants(cls):
6427 super(TestNAT44Out2InDPO, cls).setUpConstants()
6428 cls.vpp_cmdline.extend(["nat", "{", "out2in dpo", "}"])
6431 def setUpClass(cls):
6432 super(TestNAT44Out2InDPO, cls).setUpClass()
6433 cls.vapi.cli("set log class nat level debug")
6436 cls.tcp_port_in = 6303
6437 cls.tcp_port_out = 6303
6438 cls.udp_port_in = 6304
6439 cls.udp_port_out = 6304
6440 cls.icmp_id_in = 6305
6441 cls.icmp_id_out = 6305
6442 cls.nat_addr = '10.0.0.3'
6443 cls.nat_addr_n = socket.inet_pton(socket.AF_INET, cls.nat_addr)
6444 cls.dst_ip4 = '192.168.70.1'
6446 cls.create_pg_interfaces(range(2))
6449 cls.pg0.config_ip4()
6450 cls.pg0.resolve_arp()
6453 cls.pg1.config_ip6()
6454 cls.pg1.resolve_ndp()
6456 cls.vapi.ip_add_del_route(is_ipv6=True, dst_address='\x00'*16,
6457 dst_address_length=0,
6458 next_hop_address=cls.pg1.remote_ip6n,
6459 next_hop_sw_if_index=cls.pg1.sw_if_index)
6462 super(TestNAT44Out2InDPO, cls).tearDownClass()
6465 def configure_xlat(self):
6466 self.dst_ip6_pfx = '1:2:3::'
6467 self.dst_ip6_pfx_n = socket.inet_pton(socket.AF_INET6,
6469 self.dst_ip6_pfx_len = 96
6470 self.src_ip6_pfx = '4:5:6::'
6471 self.src_ip6_pfx_n = socket.inet_pton(socket.AF_INET6,
6473 self.src_ip6_pfx_len = 96
6474 self.vapi.map_add_domain(self.dst_ip6_pfx_n, self.dst_ip6_pfx_len,
6475 self.src_ip6_pfx_n, self.src_ip6_pfx_len,
6476 '\x00\x00\x00\x00', 0)
6478 @unittest.skip('Temporary disabled')
6479 def test_464xlat_ce(self):
6480 """ Test 464XLAT CE with NAT44 """
6482 nat_config = self.vapi.nat_show_config()
6483 self.assertEqual(1, nat_config.out2in_dpo)
6485 self.configure_xlat()
6487 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
6488 self.vapi.nat44_add_del_address_range(self.nat_addr_n, self.nat_addr_n)
6490 out_src_ip6 = self.compose_ip6(self.dst_ip4, self.dst_ip6_pfx,
6491 self.dst_ip6_pfx_len)
6492 out_dst_ip6 = self.compose_ip6(self.nat_addr, self.src_ip6_pfx,
6493 self.src_ip6_pfx_len)
6496 pkts = self.create_stream_in(self.pg0, self.pg1, self.dst_ip4)
6497 self.pg0.add_stream(pkts)
6498 self.pg_enable_capture(self.pg_interfaces)
6500 capture = self.pg1.get_capture(len(pkts))
6501 self.verify_capture_out_ip6(capture, nat_ip=out_dst_ip6,
6504 pkts = self.create_stream_out_ip6(self.pg1, out_src_ip6,
6506 self.pg1.add_stream(pkts)
6507 self.pg_enable_capture(self.pg_interfaces)
6509 capture = self.pg0.get_capture(len(pkts))
6510 self.verify_capture_in(capture, self.pg0)
6512 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index,
6514 self.vapi.nat44_add_del_address_range(self.nat_addr_n,
6515 self.nat_addr_n, is_add=0)
6517 @unittest.skip('Temporary disabled')
6518 def test_464xlat_ce_no_nat(self):
6519 """ Test 464XLAT CE without NAT44 """
6521 self.configure_xlat()
6523 out_src_ip6 = self.compose_ip6(self.dst_ip4, self.dst_ip6_pfx,
6524 self.dst_ip6_pfx_len)
6525 out_dst_ip6 = self.compose_ip6(self.pg0.remote_ip4, self.src_ip6_pfx,
6526 self.src_ip6_pfx_len)
6528 pkts = self.create_stream_in(self.pg0, self.pg1, self.dst_ip4)
6529 self.pg0.add_stream(pkts)
6530 self.pg_enable_capture(self.pg_interfaces)
6532 capture = self.pg1.get_capture(len(pkts))
6533 self.verify_capture_out_ip6(capture, dst_ip=out_src_ip6,
6534 nat_ip=out_dst_ip6, same_port=True)
6536 pkts = self.create_stream_out_ip6(self.pg1, out_src_ip6, out_dst_ip6)
6537 self.pg1.add_stream(pkts)
6538 self.pg_enable_capture(self.pg_interfaces)
6540 capture = self.pg0.get_capture(len(pkts))
6541 self.verify_capture_in(capture, self.pg0)
6544 class TestDeterministicNAT(MethodHolder):
6545 """ Deterministic NAT Test Cases """
6548 def setUpConstants(cls):
6549 super(TestDeterministicNAT, cls).setUpConstants()
6550 cls.vpp_cmdline.extend(["nat", "{", "deterministic", "}"])
6553 def setUpClass(cls):
6554 super(TestDeterministicNAT, cls).setUpClass()
6555 cls.vapi.cli("set log class nat level debug")
6558 cls.tcp_port_in = 6303
6559 cls.tcp_external_port = 6303
6560 cls.udp_port_in = 6304
6561 cls.udp_external_port = 6304
6562 cls.icmp_id_in = 6305
6563 cls.nat_addr = '10.0.0.3'
6565 cls.create_pg_interfaces(range(3))
6566 cls.interfaces = list(cls.pg_interfaces)
6568 for i in cls.interfaces:
6573 cls.pg0.generate_remote_hosts(2)
6574 cls.pg0.configure_ipv4_neighbors()
6577 super(TestDeterministicNAT, cls).tearDownClass()
6580 def create_stream_in(self, in_if, out_if, ttl=64):
6582 Create packet stream for inside network
6584 :param in_if: Inside interface
6585 :param out_if: Outside interface
6586 :param ttl: TTL of generated packets
6590 p = (Ether(dst=in_if.local_mac, src=in_if.remote_mac) /
6591 IP(src=in_if.remote_ip4, dst=out_if.remote_ip4, ttl=ttl) /
6592 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port))
6596 p = (Ether(dst=in_if.local_mac, src=in_if.remote_mac) /
6597 IP(src=in_if.remote_ip4, dst=out_if.remote_ip4, ttl=ttl) /
6598 UDP(sport=self.udp_port_in, dport=self.udp_external_port))
6602 p = (Ether(dst=in_if.local_mac, src=in_if.remote_mac) /
6603 IP(src=in_if.remote_ip4, dst=out_if.remote_ip4, ttl=ttl) /
6604 ICMP(id=self.icmp_id_in, type='echo-request'))
6609 def create_stream_out(self, out_if, dst_ip=None, ttl=64):
6611 Create packet stream for outside network
6613 :param out_if: Outside interface
6614 :param dst_ip: Destination IP address (Default use global NAT address)
6615 :param ttl: TTL of generated packets
6618 dst_ip = self.nat_addr
6621 p = (Ether(dst=out_if.local_mac, src=out_if.remote_mac) /
6622 IP(src=out_if.remote_ip4, dst=dst_ip, ttl=ttl) /
6623 TCP(dport=self.tcp_port_out, sport=self.tcp_external_port))
6627 p = (Ether(dst=out_if.local_mac, src=out_if.remote_mac) /
6628 IP(src=out_if.remote_ip4, dst=dst_ip, ttl=ttl) /
6629 UDP(dport=self.udp_port_out, sport=self.udp_external_port))
6633 p = (Ether(dst=out_if.local_mac, src=out_if.remote_mac) /
6634 IP(src=out_if.remote_ip4, dst=dst_ip, ttl=ttl) /
6635 ICMP(id=self.icmp_external_id, type='echo-reply'))
6640 def verify_capture_out(self, capture, nat_ip=None):
6642 Verify captured packets on outside network
6644 :param capture: Captured packets
6645 :param nat_ip: Translated IP address (Default use global NAT address)
6646 :param same_port: Sorce port number is not translated (Default False)
6649 nat_ip = self.nat_addr
6650 for packet in capture:
6652 self.assertEqual(packet[IP].src, nat_ip)
6653 if packet.haslayer(TCP):
6654 self.tcp_port_out = packet[TCP].sport
6655 elif packet.haslayer(UDP):
6656 self.udp_port_out = packet[UDP].sport
6658 self.icmp_external_id = packet[ICMP].id
6660 self.logger.error(ppp("Unexpected or invalid packet "
6661 "(outside network):", packet))
6664 def test_deterministic_mode(self):
6665 """ NAT plugin run deterministic mode """
6666 in_addr = '172.16.255.0'
6667 out_addr = '172.17.255.50'
6668 in_addr_t = '172.16.255.20'
6669 in_addr_n = socket.inet_aton(in_addr)
6670 out_addr_n = socket.inet_aton(out_addr)
6671 in_addr_t_n = socket.inet_aton(in_addr_t)
6675 nat_config = self.vapi.nat_show_config()
6676 self.assertEqual(1, nat_config.deterministic)
6678 self.vapi.nat_det_add_del_map(in_addr_n, in_plen, out_addr_n, out_plen)
6680 rep1 = self.vapi.nat_det_forward(in_addr_t_n)
6681 self.assertEqual(rep1.out_addr[:4], out_addr_n)
6682 rep2 = self.vapi.nat_det_reverse(out_addr_n, rep1.out_port_hi)
6683 self.assertEqual(rep2.in_addr[:4], in_addr_t_n)
6685 deterministic_mappings = self.vapi.nat_det_map_dump()
6686 self.assertEqual(len(deterministic_mappings), 1)
6687 dsm = deterministic_mappings[0]
6688 self.assertEqual(in_addr_n, dsm.in_addr[:4])
6689 self.assertEqual(in_plen, dsm.in_plen)
6690 self.assertEqual(out_addr_n, dsm.out_addr[:4])
6691 self.assertEqual(out_plen, dsm.out_plen)
6693 self.clear_nat_det()
6694 deterministic_mappings = self.vapi.nat_det_map_dump()
6695 self.assertEqual(len(deterministic_mappings), 0)
6697 def test_set_timeouts(self):
6698 """ Set deterministic NAT timeouts """
6699 timeouts_before = self.vapi.nat_get_timeouts()
6701 self.vapi.nat_set_timeouts(timeouts_before.udp + 10,
6702 timeouts_before.tcp_established + 10,
6703 timeouts_before.tcp_transitory + 10,
6704 timeouts_before.icmp + 10)
6706 timeouts_after = self.vapi.nat_get_timeouts()
6708 self.assertNotEqual(timeouts_before.udp, timeouts_after.udp)
6709 self.assertNotEqual(timeouts_before.icmp, timeouts_after.icmp)
6710 self.assertNotEqual(timeouts_before.tcp_established,
6711 timeouts_after.tcp_established)
6712 self.assertNotEqual(timeouts_before.tcp_transitory,
6713 timeouts_after.tcp_transitory)
6715 def test_det_in(self):
6716 """ Deterministic NAT translation test (TCP, UDP, ICMP) """
6718 nat_ip = "10.0.0.10"
6720 self.vapi.nat_det_add_del_map(self.pg0.remote_ip4n,
6722 socket.inet_aton(nat_ip),
6724 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
6725 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
6729 pkts = self.create_stream_in(self.pg0, self.pg1)
6730 self.pg0.add_stream(pkts)
6731 self.pg_enable_capture(self.pg_interfaces)
6733 capture = self.pg1.get_capture(len(pkts))
6734 self.verify_capture_out(capture, nat_ip)
6737 pkts = self.create_stream_out(self.pg1, nat_ip)
6738 self.pg1.add_stream(pkts)
6739 self.pg_enable_capture(self.pg_interfaces)
6741 capture = self.pg0.get_capture(len(pkts))
6742 self.verify_capture_in(capture, self.pg0)
6745 sessions = self.vapi.nat_det_session_dump(self.pg0.remote_ip4n)
6746 self.assertEqual(len(sessions), 3)
6750 self.assertEqual(s.ext_addr[:4], self.pg1.remote_ip4n)
6751 self.assertEqual(s.in_port, self.tcp_port_in)
6752 self.assertEqual(s.out_port, self.tcp_port_out)
6753 self.assertEqual(s.ext_port, self.tcp_external_port)
6757 self.assertEqual(s.ext_addr[:4], self.pg1.remote_ip4n)
6758 self.assertEqual(s.in_port, self.udp_port_in)
6759 self.assertEqual(s.out_port, self.udp_port_out)
6760 self.assertEqual(s.ext_port, self.udp_external_port)
6764 self.assertEqual(s.ext_addr[:4], self.pg1.remote_ip4n)
6765 self.assertEqual(s.in_port, self.icmp_id_in)
6766 self.assertEqual(s.out_port, self.icmp_external_id)
6768 def test_multiple_users(self):
6769 """ Deterministic NAT multiple users """
6771 nat_ip = "10.0.0.10"
6773 external_port = 6303
6775 host0 = self.pg0.remote_hosts[0]
6776 host1 = self.pg0.remote_hosts[1]
6778 self.vapi.nat_det_add_del_map(host0.ip4n,
6780 socket.inet_aton(nat_ip),
6782 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
6783 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
6787 p = (Ether(src=host0.mac, dst=self.pg0.local_mac) /
6788 IP(src=host0.ip4, dst=self.pg1.remote_ip4) /
6789 TCP(sport=port_in, dport=external_port))
6790 self.pg0.add_stream(p)
6791 self.pg_enable_capture(self.pg_interfaces)
6793 capture = self.pg1.get_capture(1)
6798 self.assertEqual(ip.src, nat_ip)
6799 self.assertEqual(ip.dst, self.pg1.remote_ip4)
6800 self.assertEqual(tcp.dport, external_port)
6801 port_out0 = tcp.sport
6803 self.logger.error(ppp("Unexpected or invalid packet:", p))
6807 p = (Ether(src=host1.mac, dst=self.pg0.local_mac) /
6808 IP(src=host1.ip4, dst=self.pg1.remote_ip4) /
6809 TCP(sport=port_in, dport=external_port))
6810 self.pg0.add_stream(p)
6811 self.pg_enable_capture(self.pg_interfaces)
6813 capture = self.pg1.get_capture(1)
6818 self.assertEqual(ip.src, nat_ip)
6819 self.assertEqual(ip.dst, self.pg1.remote_ip4)
6820 self.assertEqual(tcp.dport, external_port)
6821 port_out1 = tcp.sport
6823 self.logger.error(ppp("Unexpected or invalid packet:", p))
6826 dms = self.vapi.nat_det_map_dump()
6827 self.assertEqual(1, len(dms))
6828 self.assertEqual(2, dms[0].ses_num)
6831 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
6832 IP(src=self.pg1.remote_ip4, dst=nat_ip) /
6833 TCP(sport=external_port, dport=port_out0))
6834 self.pg1.add_stream(p)
6835 self.pg_enable_capture(self.pg_interfaces)
6837 capture = self.pg0.get_capture(1)
6842 self.assertEqual(ip.src, self.pg1.remote_ip4)
6843 self.assertEqual(ip.dst, host0.ip4)
6844 self.assertEqual(tcp.dport, port_in)
6845 self.assertEqual(tcp.sport, external_port)
6847 self.logger.error(ppp("Unexpected or invalid packet:", p))
6851 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
6852 IP(src=self.pg1.remote_ip4, dst=nat_ip) /
6853 TCP(sport=external_port, dport=port_out1))
6854 self.pg1.add_stream(p)
6855 self.pg_enable_capture(self.pg_interfaces)
6857 capture = self.pg0.get_capture(1)
6862 self.assertEqual(ip.src, self.pg1.remote_ip4)
6863 self.assertEqual(ip.dst, host1.ip4)
6864 self.assertEqual(tcp.dport, port_in)
6865 self.assertEqual(tcp.sport, external_port)
6867 self.logger.error(ppp("Unexpected or invalid packet", p))
6870 # session close api test
6871 self.vapi.nat_det_close_session_out(socket.inet_aton(nat_ip),
6873 self.pg1.remote_ip4n,
6875 dms = self.vapi.nat_det_map_dump()
6876 self.assertEqual(dms[0].ses_num, 1)
6878 self.vapi.nat_det_close_session_in(host0.ip4n,
6880 self.pg1.remote_ip4n,
6882 dms = self.vapi.nat_det_map_dump()
6883 self.assertEqual(dms[0].ses_num, 0)
6885 def test_tcp_session_close_detection_in(self):
6886 """ Deterministic NAT TCP session close from inside network """
6887 self.vapi.nat_det_add_del_map(self.pg0.remote_ip4n,
6889 socket.inet_aton(self.nat_addr),
6891 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
6892 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
6895 self.initiate_tcp_session(self.pg0, self.pg1)
6897 # close the session from inside
6899 # FIN packet in -> out
6900 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6901 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6902 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
6904 self.pg0.add_stream(p)
6905 self.pg_enable_capture(self.pg_interfaces)
6907 self.pg1.get_capture(1)
6911 # ACK packet out -> in
6912 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
6913 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
6914 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
6918 # FIN packet out -> in
6919 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
6920 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
6921 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
6925 self.pg1.add_stream(pkts)
6926 self.pg_enable_capture(self.pg_interfaces)
6928 self.pg0.get_capture(2)
6930 # ACK packet in -> out
6931 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6932 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6933 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
6935 self.pg0.add_stream(p)
6936 self.pg_enable_capture(self.pg_interfaces)
6938 self.pg1.get_capture(1)
6940 # Check if deterministic NAT44 closed the session
6941 dms = self.vapi.nat_det_map_dump()
6942 self.assertEqual(0, dms[0].ses_num)
6944 self.logger.error("TCP session termination failed")
6947 def test_tcp_session_close_detection_out(self):
6948 """ Deterministic NAT TCP session close from outside network """
6949 self.vapi.nat_det_add_del_map(self.pg0.remote_ip4n,
6951 socket.inet_aton(self.nat_addr),
6953 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
6954 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
6957 self.initiate_tcp_session(self.pg0, self.pg1)
6959 # close the session from outside
6961 # FIN packet out -> in
6962 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
6963 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
6964 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
6966 self.pg1.add_stream(p)
6967 self.pg_enable_capture(self.pg_interfaces)
6969 self.pg0.get_capture(1)
6973 # ACK packet in -> out
6974 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6975 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6976 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
6980 # ACK packet in -> out
6981 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6982 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6983 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
6987 self.pg0.add_stream(pkts)
6988 self.pg_enable_capture(self.pg_interfaces)
6990 self.pg1.get_capture(2)
6992 # ACK packet out -> in
6993 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
6994 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
6995 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
6997 self.pg1.add_stream(p)
6998 self.pg_enable_capture(self.pg_interfaces)
7000 self.pg0.get_capture(1)
7002 # Check if deterministic NAT44 closed the session
7003 dms = self.vapi.nat_det_map_dump()
7004 self.assertEqual(0, dms[0].ses_num)
7006 self.logger.error("TCP session termination failed")
7009 @unittest.skipUnless(running_extended_tests, "part of extended tests")
7010 def test_session_timeout(self):
7011 """ Deterministic NAT session timeouts """
7012 self.vapi.nat_det_add_del_map(self.pg0.remote_ip4n,
7014 socket.inet_aton(self.nat_addr),
7016 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
7017 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
7020 self.initiate_tcp_session(self.pg0, self.pg1)
7021 self.vapi.nat_set_timeouts(5, 5, 5, 5)
7022 pkts = self.create_stream_in(self.pg0, self.pg1)
7023 self.pg0.add_stream(pkts)
7024 self.pg_enable_capture(self.pg_interfaces)
7026 capture = self.pg1.get_capture(len(pkts))
7029 dms = self.vapi.nat_det_map_dump()
7030 self.assertEqual(0, dms[0].ses_num)
7032 @unittest.skipUnless(running_extended_tests, "part of extended tests")
7033 def test_session_limit_per_user(self):
7034 """ Deterministic NAT maximum sessions per user limit """
7035 self.vapi.nat_det_add_del_map(self.pg0.remote_ip4n,
7037 socket.inet_aton(self.nat_addr),
7039 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
7040 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
7042 self.vapi.set_ipfix_exporter(collector_address=self.pg2.remote_ip4n,
7043 src_address=self.pg2.local_ip4n,
7045 template_interval=10)
7046 self.vapi.nat_ipfix()
7049 for port in range(1025, 2025):
7050 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
7051 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
7052 UDP(sport=port, dport=port))
7055 self.pg0.add_stream(pkts)
7056 self.pg_enable_capture(self.pg_interfaces)
7058 capture = self.pg1.get_capture(len(pkts))
7060 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
7061 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
7062 UDP(sport=3001, dport=3002))
7063 self.pg0.add_stream(p)
7064 self.pg_enable_capture(self.pg_interfaces)
7066 capture = self.pg1.assert_nothing_captured()
7068 # verify ICMP error packet
7069 capture = self.pg0.get_capture(1)
7071 self.assertTrue(p.haslayer(ICMP))
7073 self.assertEqual(icmp.type, 3)
7074 self.assertEqual(icmp.code, 1)
7075 self.assertTrue(icmp.haslayer(IPerror))
7076 inner_ip = icmp[IPerror]
7077 self.assertEqual(inner_ip[UDPerror].sport, 3001)
7078 self.assertEqual(inner_ip[UDPerror].dport, 3002)
7080 dms = self.vapi.nat_det_map_dump()
7082 self.assertEqual(1000, dms[0].ses_num)
7084 # verify IPFIX logging
7085 self.vapi.cli("ipfix flush") # FIXME this should be an API call
7087 capture = self.pg2.get_capture(2)
7088 ipfix = IPFIXDecoder()
7089 # first load template
7091 self.assertTrue(p.haslayer(IPFIX))
7092 if p.haslayer(Template):
7093 ipfix.add_template(p.getlayer(Template))
7094 # verify events in data set
7096 if p.haslayer(Data):
7097 data = ipfix.decode_data_set(p.getlayer(Set))
7098 self.verify_ipfix_max_entries_per_user(data,
7100 self.pg0.remote_ip4n)
7102 def clear_nat_det(self):
7104 Clear deterministic NAT configuration.
7106 self.vapi.nat_ipfix(enable=0)
7107 self.vapi.nat_set_timeouts()
7108 deterministic_mappings = self.vapi.nat_det_map_dump()
7109 for dsm in deterministic_mappings:
7110 self.vapi.nat_det_add_del_map(dsm.in_addr,
7116 interfaces = self.vapi.nat44_interface_dump()
7117 for intf in interfaces:
7118 self.vapi.nat44_interface_add_del_feature(intf.sw_if_index,
7123 super(TestDeterministicNAT, self).tearDown()
7124 if not self.vpp_dead:
7125 self.logger.info(self.vapi.cli("show nat44 interfaces"))
7126 self.logger.info(self.vapi.cli("show nat timeouts"))
7128 self.vapi.cli("show nat44 deterministic mappings"))
7130 self.vapi.cli("show nat44 deterministic sessions"))
7131 self.clear_nat_det()
7134 class TestNAT64(MethodHolder):
7135 """ NAT64 Test Cases """
7138 def setUpConstants(cls):
7139 super(TestNAT64, cls).setUpConstants()
7140 cls.vpp_cmdline.extend(["nat", "{", "nat64 bib hash buckets 128",
7141 "nat64 st hash buckets 256", "}"])
7144 def setUpClass(cls):
7145 super(TestNAT64, cls).setUpClass()
7148 cls.tcp_port_in = 6303
7149 cls.tcp_port_out = 6303
7150 cls.udp_port_in = 6304
7151 cls.udp_port_out = 6304
7152 cls.icmp_id_in = 6305
7153 cls.icmp_id_out = 6305
7154 cls.tcp_external_port = 80
7155 cls.nat_addr = '10.0.0.3'
7156 cls.nat_addr_n = socket.inet_pton(socket.AF_INET, cls.nat_addr)
7158 cls.vrf1_nat_addr = '10.0.10.3'
7159 cls.vrf1_nat_addr_n = socket.inet_pton(socket.AF_INET,
7161 cls.ipfix_src_port = 4739
7162 cls.ipfix_domain_id = 1
7164 cls.create_pg_interfaces(range(6))
7165 cls.ip6_interfaces = list(cls.pg_interfaces[0:1])
7166 cls.ip6_interfaces.append(cls.pg_interfaces[2])
7167 cls.ip4_interfaces = list(cls.pg_interfaces[1:2])
7169 cls.vapi.ip_table_add_del(cls.vrf1_id, is_add=1, is_ipv6=1)
7171 cls.pg_interfaces[2].set_table_ip6(cls.vrf1_id)
7173 cls.pg0.generate_remote_hosts(2)
7175 for i in cls.ip6_interfaces:
7178 i.configure_ipv6_neighbors()
7180 for i in cls.ip4_interfaces:
7186 cls.pg3.config_ip4()
7187 cls.pg3.resolve_arp()
7188 cls.pg3.config_ip6()
7189 cls.pg3.configure_ipv6_neighbors()
7192 cls.pg5.config_ip6()
7195 super(TestNAT64, cls).tearDownClass()
7198 def test_nat64_inside_interface_handles_neighbor_advertisement(self):
7199 """ NAT64 inside interface handles Neighbor Advertisement """
7201 self.vapi.nat64_add_del_interface(self.pg5.sw_if_index)
7204 ping = (Ether(dst=self.pg5.local_mac, src=self.pg5.remote_mac) /
7205 IPv6(src=self.pg5.remote_ip6, dst=self.pg5.local_ip6) /
7206 ICMPv6EchoRequest())
7208 self.pg5.add_stream(pkts)
7209 self.pg_enable_capture(self.pg_interfaces)
7212 # Wait for Neighbor Solicitation
7213 capture = self.pg5.get_capture(len(pkts))
7216 self.assertEqual(packet[IPv6].src, self.pg5.local_ip6)
7217 self.assertEqual(packet.haslayer(ICMPv6ND_NS), 1)
7218 tgt = packet[ICMPv6ND_NS].tgt
7220 self.logger.error(ppp("Unexpected or invalid packet:", packet))
7223 # Send Neighbor Advertisement
7224 p = (Ether(dst=self.pg5.local_mac, src=self.pg5.remote_mac) /
7225 IPv6(src=self.pg5.remote_ip6, dst=self.pg5.local_ip6) /
7226 ICMPv6ND_NA(tgt=tgt) /
7227 ICMPv6NDOptDstLLAddr(lladdr=self.pg5.remote_mac))
7229 self.pg5.add_stream(pkts)
7230 self.pg_enable_capture(self.pg_interfaces)
7233 # Try to send ping again
7235 self.pg5.add_stream(pkts)
7236 self.pg_enable_capture(self.pg_interfaces)
7239 # Wait for ping reply
7240 capture = self.pg5.get_capture(len(pkts))
7243 self.assertEqual(packet[IPv6].src, self.pg5.local_ip6)
7244 self.assertEqual(packet[IPv6].dst, self.pg5.remote_ip6)
7245 self.assertEqual(packet.haslayer(ICMPv6EchoReply), 1)
7247 self.logger.error(ppp("Unexpected or invalid packet:", packet))
7250 def test_pool(self):
7251 """ Add/delete address to NAT64 pool """
7252 nat_addr = socket.inet_pton(socket.AF_INET, '1.2.3.4')
7254 self.vapi.nat64_add_del_pool_addr_range(nat_addr, nat_addr)
7256 addresses = self.vapi.nat64_pool_addr_dump()
7257 self.assertEqual(len(addresses), 1)
7258 self.assertEqual(addresses[0].address, nat_addr)
7260 self.vapi.nat64_add_del_pool_addr_range(nat_addr, nat_addr, is_add=0)
7262 addresses = self.vapi.nat64_pool_addr_dump()
7263 self.assertEqual(len(addresses), 0)
7265 def test_interface(self):
7266 """ Enable/disable NAT64 feature on the interface """
7267 self.vapi.nat64_add_del_interface(self.pg0.sw_if_index)
7268 self.vapi.nat64_add_del_interface(self.pg1.sw_if_index, is_inside=0)
7270 interfaces = self.vapi.nat64_interface_dump()
7271 self.assertEqual(len(interfaces), 2)
7274 for intf in interfaces:
7275 if intf.sw_if_index == self.pg0.sw_if_index:
7276 self.assertEqual(intf.is_inside, 1)
7278 elif intf.sw_if_index == self.pg1.sw_if_index:
7279 self.assertEqual(intf.is_inside, 0)
7281 self.assertTrue(pg0_found)
7282 self.assertTrue(pg1_found)
7284 features = self.vapi.cli("show interface features pg0")
7285 self.assertNotEqual(features.find('nat64-in2out'), -1)
7286 features = self.vapi.cli("show interface features pg1")
7287 self.assertNotEqual(features.find('nat64-out2in'), -1)
7289 self.vapi.nat64_add_del_interface(self.pg0.sw_if_index, is_add=0)
7290 self.vapi.nat64_add_del_interface(self.pg1.sw_if_index, is_add=0)
7292 interfaces = self.vapi.nat64_interface_dump()
7293 self.assertEqual(len(interfaces), 0)
7295 def test_static_bib(self):
7296 """ Add/delete static BIB entry """
7297 in_addr = socket.inet_pton(socket.AF_INET6,
7298 '2001:db8:85a3::8a2e:370:7334')
7299 out_addr = socket.inet_pton(socket.AF_INET, '10.1.1.3')
7302 proto = IP_PROTOS.tcp
7304 self.vapi.nat64_add_del_static_bib(in_addr,
7309 bib = self.vapi.nat64_bib_dump(IP_PROTOS.tcp)
7314 self.assertEqual(bibe.i_addr, in_addr)
7315 self.assertEqual(bibe.o_addr, out_addr)
7316 self.assertEqual(bibe.i_port, in_port)
7317 self.assertEqual(bibe.o_port, out_port)
7318 self.assertEqual(static_bib_num, 1)
7319 bibs = self.statistics.get_counter('/nat64/total-bibs')
7320 self.assertEqual(bibs[0][0], 1)
7322 self.vapi.nat64_add_del_static_bib(in_addr,
7328 bib = self.vapi.nat64_bib_dump(IP_PROTOS.tcp)
7333 self.assertEqual(static_bib_num, 0)
7334 bibs = self.statistics.get_counter('/nat64/total-bibs')
7335 self.assertEqual(bibs[0][0], 0)
7337 def test_set_timeouts(self):
7338 """ Set NAT64 timeouts """
7339 # verify default values
7340 timeouts = self.vapi.nat_get_timeouts()
7341 self.assertEqual(timeouts.udp, 300)
7342 self.assertEqual(timeouts.icmp, 60)
7343 self.assertEqual(timeouts.tcp_transitory, 240)
7344 self.assertEqual(timeouts.tcp_established, 7440)
7346 # set and verify custom values
7347 self.vapi.nat_set_timeouts(udp=200, icmp=30, tcp_transitory=250,
7348 tcp_established=7450)
7349 timeouts = self.vapi.nat_get_timeouts()
7350 self.assertEqual(timeouts.udp, 200)
7351 self.assertEqual(timeouts.icmp, 30)
7352 self.assertEqual(timeouts.tcp_transitory, 250)
7353 self.assertEqual(timeouts.tcp_established, 7450)
7355 def test_dynamic(self):
7356 """ NAT64 dynamic translation test """
7357 self.tcp_port_in = 6303
7358 self.udp_port_in = 6304
7359 self.icmp_id_in = 6305
7361 ses_num_start = self.nat64_get_ses_num()
7363 self.vapi.nat64_add_del_pool_addr_range(self.nat_addr_n,
7365 self.vapi.nat64_add_del_interface(self.pg0.sw_if_index)
7366 self.vapi.nat64_add_del_interface(self.pg1.sw_if_index, is_inside=0)
7369 tcpn = self.statistics.get_counter('/err/nat64-in2out/TCP packets')
7370 udpn = self.statistics.get_counter('/err/nat64-in2out/UDP packets')
7371 icmpn = self.statistics.get_counter('/err/nat64-in2out/ICMP packets')
7372 totaln = self.statistics.get_counter(
7373 '/err/nat64-in2out/good in2out packets processed')
7375 pkts = self.create_stream_in_ip6(self.pg0, self.pg1)
7376 self.pg0.add_stream(pkts)
7377 self.pg_enable_capture(self.pg_interfaces)
7379 capture = self.pg1.get_capture(len(pkts))
7380 self.verify_capture_out(capture, nat_ip=self.nat_addr,
7381 dst_ip=self.pg1.remote_ip4)
7383 err = self.statistics.get_counter('/err/nat64-in2out/TCP packets')
7384 self.assertEqual(err - tcpn, 1)
7385 err = self.statistics.get_counter('/err/nat64-in2out/UDP packets')
7386 self.assertEqual(err - udpn, 1)
7387 err = self.statistics.get_counter('/err/nat64-in2out/ICMP packets')
7388 self.assertEqual(err - icmpn, 1)
7389 err = self.statistics.get_counter(
7390 '/err/nat64-in2out/good in2out packets processed')
7391 self.assertEqual(err - totaln, 3)
7394 tcpn = self.statistics.get_counter('/err/nat64-out2in/TCP packets')
7395 udpn = self.statistics.get_counter('/err/nat64-out2in/UDP packets')
7396 icmpn = self.statistics.get_counter('/err/nat64-out2in/ICMP packets')
7397 totaln = self.statistics.get_counter(
7398 '/err/nat64-out2in/good out2in packets processed')
7400 pkts = self.create_stream_out(self.pg1, dst_ip=self.nat_addr)
7401 self.pg1.add_stream(pkts)
7402 self.pg_enable_capture(self.pg_interfaces)
7404 capture = self.pg0.get_capture(len(pkts))
7405 ip = IPv6(src=''.join(['64:ff9b::', self.pg1.remote_ip4]))
7406 self.verify_capture_in_ip6(capture, ip[IPv6].src, self.pg0.remote_ip6)
7408 err = self.statistics.get_counter('/err/nat64-out2in/TCP packets')
7409 self.assertEqual(err - tcpn, 1)
7410 err = self.statistics.get_counter('/err/nat64-out2in/UDP packets')
7411 self.assertEqual(err - udpn, 1)
7412 err = self.statistics.get_counter('/err/nat64-out2in/ICMP packets')
7413 self.assertEqual(err - icmpn, 1)
7414 err = self.statistics.get_counter(
7415 '/err/nat64-out2in/good out2in packets processed')
7416 self.assertEqual(err - totaln, 3)
7418 bibs = self.statistics.get_counter('/nat64/total-bibs')
7419 self.assertEqual(bibs[0][0], 3)
7420 sessions = self.statistics.get_counter('/nat64/total-sessions')
7421 self.assertEqual(sessions[0][0], 3)
7424 pkts = self.create_stream_in_ip6(self.pg0, self.pg1)
7425 self.pg0.add_stream(pkts)
7426 self.pg_enable_capture(self.pg_interfaces)
7428 capture = self.pg1.get_capture(len(pkts))
7429 self.verify_capture_out(capture, nat_ip=self.nat_addr,
7430 dst_ip=self.pg1.remote_ip4)
7433 pkts = self.create_stream_out(self.pg1, dst_ip=self.nat_addr)
7434 self.pg1.add_stream(pkts)
7435 self.pg_enable_capture(self.pg_interfaces)
7437 capture = self.pg0.get_capture(len(pkts))
7438 self.verify_capture_in_ip6(capture, ip[IPv6].src, self.pg0.remote_ip6)
7440 ses_num_end = self.nat64_get_ses_num()
7442 self.assertEqual(ses_num_end - ses_num_start, 3)
7444 # tenant with specific VRF
7445 self.vapi.nat64_add_del_pool_addr_range(self.vrf1_nat_addr_n,
7446 self.vrf1_nat_addr_n,
7447 vrf_id=self.vrf1_id)
7448 self.vapi.nat64_add_del_interface(self.pg2.sw_if_index)
7450 pkts = self.create_stream_in_ip6(self.pg2, self.pg1)
7451 self.pg2.add_stream(pkts)
7452 self.pg_enable_capture(self.pg_interfaces)
7454 capture = self.pg1.get_capture(len(pkts))
7455 self.verify_capture_out(capture, nat_ip=self.vrf1_nat_addr,
7456 dst_ip=self.pg1.remote_ip4)
7458 pkts = self.create_stream_out(self.pg1, dst_ip=self.vrf1_nat_addr)
7459 self.pg1.add_stream(pkts)
7460 self.pg_enable_capture(self.pg_interfaces)
7462 capture = self.pg2.get_capture(len(pkts))
7463 self.verify_capture_in_ip6(capture, ip[IPv6].src, self.pg2.remote_ip6)
7465 def test_static(self):
7466 """ NAT64 static translation test """
7467 self.tcp_port_in = 60303
7468 self.udp_port_in = 60304
7469 self.icmp_id_in = 60305
7470 self.tcp_port_out = 60303
7471 self.udp_port_out = 60304
7472 self.icmp_id_out = 60305
7474 ses_num_start = self.nat64_get_ses_num()
7476 self.vapi.nat64_add_del_pool_addr_range(self.nat_addr_n,
7478 self.vapi.nat64_add_del_interface(self.pg0.sw_if_index)
7479 self.vapi.nat64_add_del_interface(self.pg1.sw_if_index, is_inside=0)
7481 self.vapi.nat64_add_del_static_bib(self.pg0.remote_ip6n,
7486 self.vapi.nat64_add_del_static_bib(self.pg0.remote_ip6n,
7491 self.vapi.nat64_add_del_static_bib(self.pg0.remote_ip6n,
7498 pkts = self.create_stream_in_ip6(self.pg0, self.pg1)
7499 self.pg0.add_stream(pkts)
7500 self.pg_enable_capture(self.pg_interfaces)
7502 capture = self.pg1.get_capture(len(pkts))
7503 self.verify_capture_out(capture, nat_ip=self.nat_addr,
7504 dst_ip=self.pg1.remote_ip4, same_port=True)
7507 pkts = self.create_stream_out(self.pg1, dst_ip=self.nat_addr)
7508 self.pg1.add_stream(pkts)
7509 self.pg_enable_capture(self.pg_interfaces)
7511 capture = self.pg0.get_capture(len(pkts))
7512 ip = IPv6(src=''.join(['64:ff9b::', self.pg1.remote_ip4]))
7513 self.verify_capture_in_ip6(capture, ip[IPv6].src, self.pg0.remote_ip6)
7515 ses_num_end = self.nat64_get_ses_num()
7517 self.assertEqual(ses_num_end - ses_num_start, 3)
7519 @unittest.skipUnless(running_extended_tests, "part of extended tests")
7520 def test_session_timeout(self):
7521 """ NAT64 session timeout """
7522 self.icmp_id_in = 1234
7523 self.vapi.nat64_add_del_pool_addr_range(self.nat_addr_n,
7525 self.vapi.nat64_add_del_interface(self.pg0.sw_if_index)
7526 self.vapi.nat64_add_del_interface(self.pg1.sw_if_index, is_inside=0)
7527 self.vapi.nat_set_timeouts(icmp=5, tcp_transitory=5, tcp_established=5)
7529 pkts = self.create_stream_in_ip6(self.pg0, self.pg1)
7530 self.pg0.add_stream(pkts)
7531 self.pg_enable_capture(self.pg_interfaces)
7533 capture = self.pg1.get_capture(len(pkts))
7535 ses_num_before_timeout = self.nat64_get_ses_num()
7539 # ICMP and TCP session after timeout
7540 ses_num_after_timeout = self.nat64_get_ses_num()
7541 self.assertEqual(ses_num_before_timeout - ses_num_after_timeout, 2)
7543 def test_icmp_error(self):
7544 """ NAT64 ICMP Error message translation """
7545 self.tcp_port_in = 6303
7546 self.udp_port_in = 6304
7547 self.icmp_id_in = 6305
7549 self.vapi.nat64_add_del_pool_addr_range(self.nat_addr_n,
7551 self.vapi.nat64_add_del_interface(self.pg0.sw_if_index)
7552 self.vapi.nat64_add_del_interface(self.pg1.sw_if_index, is_inside=0)
7554 # send some packets to create sessions
7555 pkts = self.create_stream_in_ip6(self.pg0, self.pg1)
7556 self.pg0.add_stream(pkts)
7557 self.pg_enable_capture(self.pg_interfaces)
7559 capture_ip4 = self.pg1.get_capture(len(pkts))
7560 self.verify_capture_out(capture_ip4,
7561 nat_ip=self.nat_addr,
7562 dst_ip=self.pg1.remote_ip4)
7564 pkts = self.create_stream_out(self.pg1, dst_ip=self.nat_addr)
7565 self.pg1.add_stream(pkts)
7566 self.pg_enable_capture(self.pg_interfaces)
7568 capture_ip6 = self.pg0.get_capture(len(pkts))
7569 ip = IPv6(src=''.join(['64:ff9b::', self.pg1.remote_ip4]))
7570 self.verify_capture_in_ip6(capture_ip6, ip[IPv6].src,
7571 self.pg0.remote_ip6)
7574 pkts = [Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
7575 IPv6(src=self.pg0.remote_ip6, dst=ip[IPv6].src) /
7576 ICMPv6DestUnreach(code=1) /
7577 packet[IPv6] for packet in capture_ip6]
7578 self.pg0.add_stream(pkts)
7579 self.pg_enable_capture(self.pg_interfaces)
7581 capture = self.pg1.get_capture(len(pkts))
7582 for packet in capture:
7584 self.assertEqual(packet[IP].src, self.nat_addr)
7585 self.assertEqual(packet[IP].dst, self.pg1.remote_ip4)
7586 self.assertEqual(packet[ICMP].type, 3)
7587 self.assertEqual(packet[ICMP].code, 13)
7588 inner = packet[IPerror]
7589 self.assertEqual(inner.src, self.pg1.remote_ip4)
7590 self.assertEqual(inner.dst, self.nat_addr)
7591 self.assert_packet_checksums_valid(packet)
7592 if inner.haslayer(TCPerror):
7593 self.assertEqual(inner[TCPerror].dport, self.tcp_port_out)
7594 elif inner.haslayer(UDPerror):
7595 self.assertEqual(inner[UDPerror].dport, self.udp_port_out)
7597 self.assertEqual(inner[ICMPerror].id, self.icmp_id_out)
7599 self.logger.error(ppp("Unexpected or invalid packet:", packet))
7603 pkts = [Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
7604 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
7605 ICMP(type=3, code=13) /
7606 packet[IP] for packet in capture_ip4]
7607 self.pg1.add_stream(pkts)
7608 self.pg_enable_capture(self.pg_interfaces)
7610 capture = self.pg0.get_capture(len(pkts))
7611 for packet in capture:
7613 self.assertEqual(packet[IPv6].src, ip.src)
7614 self.assertEqual(packet[IPv6].dst, self.pg0.remote_ip6)
7615 icmp = packet[ICMPv6DestUnreach]
7616 self.assertEqual(icmp.code, 1)
7617 inner = icmp[IPerror6]
7618 self.assertEqual(inner.src, self.pg0.remote_ip6)
7619 self.assertEqual(inner.dst, ip.src)
7620 self.assert_icmpv6_checksum_valid(packet)
7621 if inner.haslayer(TCPerror):
7622 self.assertEqual(inner[TCPerror].sport, self.tcp_port_in)
7623 elif inner.haslayer(UDPerror):
7624 self.assertEqual(inner[UDPerror].sport, self.udp_port_in)
7626 self.assertEqual(inner[ICMPv6EchoRequest].id,
7629 self.logger.error(ppp("Unexpected or invalid packet:", packet))
7632 def test_hairpinning(self):
7633 """ NAT64 hairpinning """
7635 client = self.pg0.remote_hosts[0]
7636 server = self.pg0.remote_hosts[1]
7637 server_tcp_in_port = 22
7638 server_tcp_out_port = 4022
7639 server_udp_in_port = 23
7640 server_udp_out_port = 4023
7641 client_tcp_in_port = 1234
7642 client_udp_in_port = 1235
7643 client_tcp_out_port = 0
7644 client_udp_out_port = 0
7645 ip = IPv6(src=''.join(['64:ff9b::', self.nat_addr]))
7646 nat_addr_ip6 = ip.src
7648 self.vapi.nat64_add_del_pool_addr_range(self.nat_addr_n,
7650 self.vapi.nat64_add_del_interface(self.pg0.sw_if_index)
7651 self.vapi.nat64_add_del_interface(self.pg1.sw_if_index, is_inside=0)
7653 self.vapi.nat64_add_del_static_bib(server.ip6n,
7656 server_tcp_out_port,
7658 self.vapi.nat64_add_del_static_bib(server.ip6n,
7661 server_udp_out_port,
7666 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
7667 IPv6(src=client.ip6, dst=nat_addr_ip6) /
7668 TCP(sport=client_tcp_in_port, dport=server_tcp_out_port))
7670 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
7671 IPv6(src=client.ip6, dst=nat_addr_ip6) /
7672 UDP(sport=client_udp_in_port, dport=server_udp_out_port))
7674 self.pg0.add_stream(pkts)
7675 self.pg_enable_capture(self.pg_interfaces)
7677 capture = self.pg0.get_capture(len(pkts))
7678 for packet in capture:
7680 self.assertEqual(packet[IPv6].src, nat_addr_ip6)
7681 self.assertEqual(packet[IPv6].dst, server.ip6)
7682 self.assert_packet_checksums_valid(packet)
7683 if packet.haslayer(TCP):
7684 self.assertNotEqual(packet[TCP].sport, client_tcp_in_port)
7685 self.assertEqual(packet[TCP].dport, server_tcp_in_port)
7686 client_tcp_out_port = packet[TCP].sport
7688 self.assertNotEqual(packet[UDP].sport, client_udp_in_port)
7689 self.assertEqual(packet[UDP].dport, server_udp_in_port)
7690 client_udp_out_port = packet[UDP].sport
7692 self.logger.error(ppp("Unexpected or invalid packet:", packet))
7697 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
7698 IPv6(src=server.ip6, dst=nat_addr_ip6) /
7699 TCP(sport=server_tcp_in_port, dport=client_tcp_out_port))
7701 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
7702 IPv6(src=server.ip6, dst=nat_addr_ip6) /
7703 UDP(sport=server_udp_in_port, dport=client_udp_out_port))
7705 self.pg0.add_stream(pkts)
7706 self.pg_enable_capture(self.pg_interfaces)
7708 capture = self.pg0.get_capture(len(pkts))
7709 for packet in capture:
7711 self.assertEqual(packet[IPv6].src, nat_addr_ip6)
7712 self.assertEqual(packet[IPv6].dst, client.ip6)
7713 self.assert_packet_checksums_valid(packet)
7714 if packet.haslayer(TCP):
7715 self.assertEqual(packet[TCP].sport, server_tcp_out_port)
7716 self.assertEqual(packet[TCP].dport, client_tcp_in_port)
7718 self.assertEqual(packet[UDP].sport, server_udp_out_port)
7719 self.assertEqual(packet[UDP].dport, client_udp_in_port)
7721 self.logger.error(ppp("Unexpected or invalid packet:", packet))
7726 pkts = [Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
7727 IPv6(src=client.ip6, dst=nat_addr_ip6) /
7728 ICMPv6DestUnreach(code=1) /
7729 packet[IPv6] for packet in capture]
7730 self.pg0.add_stream(pkts)
7731 self.pg_enable_capture(self.pg_interfaces)
7733 capture = self.pg0.get_capture(len(pkts))
7734 for packet in capture:
7736 self.assertEqual(packet[IPv6].src, nat_addr_ip6)
7737 self.assertEqual(packet[IPv6].dst, server.ip6)
7738 icmp = packet[ICMPv6DestUnreach]
7739 self.assertEqual(icmp.code, 1)
7740 inner = icmp[IPerror6]
7741 self.assertEqual(inner.src, server.ip6)
7742 self.assertEqual(inner.dst, nat_addr_ip6)
7743 self.assert_packet_checksums_valid(packet)
7744 if inner.haslayer(TCPerror):
7745 self.assertEqual(inner[TCPerror].sport, server_tcp_in_port)
7746 self.assertEqual(inner[TCPerror].dport,
7747 client_tcp_out_port)
7749 self.assertEqual(inner[UDPerror].sport, server_udp_in_port)
7750 self.assertEqual(inner[UDPerror].dport,
7751 client_udp_out_port)
7753 self.logger.error(ppp("Unexpected or invalid packet:", packet))
7756 def test_prefix(self):
7757 """ NAT64 Network-Specific Prefix """
7759 self.vapi.nat64_add_del_pool_addr_range(self.nat_addr_n,
7761 self.vapi.nat64_add_del_interface(self.pg0.sw_if_index)
7762 self.vapi.nat64_add_del_interface(self.pg1.sw_if_index, is_inside=0)
7763 self.vapi.nat64_add_del_pool_addr_range(self.vrf1_nat_addr_n,
7764 self.vrf1_nat_addr_n,
7765 vrf_id=self.vrf1_id)
7766 self.vapi.nat64_add_del_interface(self.pg2.sw_if_index)
7769 global_pref64 = "2001:db8::"
7770 global_pref64_n = socket.inet_pton(socket.AF_INET6, global_pref64)
7771 global_pref64_len = 32
7772 self.vapi.nat64_add_del_prefix(global_pref64_n, global_pref64_len)
7774 prefix = self.vapi.nat64_prefix_dump()
7775 self.assertEqual(len(prefix), 1)
7776 self.assertEqual(prefix[0].prefix, global_pref64_n)
7777 self.assertEqual(prefix[0].prefix_len, global_pref64_len)
7778 self.assertEqual(prefix[0].vrf_id, 0)
7780 # Add tenant specific prefix
7781 vrf1_pref64 = "2001:db8:122:300::"
7782 vrf1_pref64_n = socket.inet_pton(socket.AF_INET6, vrf1_pref64)
7783 vrf1_pref64_len = 56
7784 self.vapi.nat64_add_del_prefix(vrf1_pref64_n,
7786 vrf_id=self.vrf1_id)
7787 prefix = self.vapi.nat64_prefix_dump()
7788 self.assertEqual(len(prefix), 2)
7791 pkts = self.create_stream_in_ip6(self.pg0,
7794 plen=global_pref64_len)
7795 self.pg0.add_stream(pkts)
7796 self.pg_enable_capture(self.pg_interfaces)
7798 capture = self.pg1.get_capture(len(pkts))
7799 self.verify_capture_out(capture, nat_ip=self.nat_addr,
7800 dst_ip=self.pg1.remote_ip4)
7802 pkts = self.create_stream_out(self.pg1, dst_ip=self.nat_addr)
7803 self.pg1.add_stream(pkts)
7804 self.pg_enable_capture(self.pg_interfaces)
7806 capture = self.pg0.get_capture(len(pkts))
7807 dst_ip = self.compose_ip6(self.pg1.remote_ip4,
7810 self.verify_capture_in_ip6(capture, dst_ip, self.pg0.remote_ip6)
7812 # Tenant specific prefix
7813 pkts = self.create_stream_in_ip6(self.pg2,
7816 plen=vrf1_pref64_len)
7817 self.pg2.add_stream(pkts)
7818 self.pg_enable_capture(self.pg_interfaces)
7820 capture = self.pg1.get_capture(len(pkts))
7821 self.verify_capture_out(capture, nat_ip=self.vrf1_nat_addr,
7822 dst_ip=self.pg1.remote_ip4)
7824 pkts = self.create_stream_out(self.pg1, dst_ip=self.vrf1_nat_addr)
7825 self.pg1.add_stream(pkts)
7826 self.pg_enable_capture(self.pg_interfaces)
7828 capture = self.pg2.get_capture(len(pkts))
7829 dst_ip = self.compose_ip6(self.pg1.remote_ip4,
7832 self.verify_capture_in_ip6(capture, dst_ip, self.pg2.remote_ip6)
7834 def test_unknown_proto(self):
7835 """ NAT64 translate packet with unknown protocol """
7837 self.vapi.nat64_add_del_pool_addr_range(self.nat_addr_n,
7839 self.vapi.nat64_add_del_interface(self.pg0.sw_if_index)
7840 self.vapi.nat64_add_del_interface(self.pg1.sw_if_index, is_inside=0)
7841 remote_ip6 = self.compose_ip6(self.pg1.remote_ip4, '64:ff9b::', 96)
7844 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
7845 IPv6(src=self.pg0.remote_ip6, dst=remote_ip6) /
7846 TCP(sport=self.tcp_port_in, dport=20))
7847 self.pg0.add_stream(p)
7848 self.pg_enable_capture(self.pg_interfaces)
7850 p = self.pg1.get_capture(1)
7852 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
7853 IPv6(src=self.pg0.remote_ip6, dst=remote_ip6, nh=47) /
7855 IP(src=self.pg2.local_ip4, dst=self.pg2.remote_ip4) /
7856 TCP(sport=1234, dport=1234))
7857 self.pg0.add_stream(p)
7858 self.pg_enable_capture(self.pg_interfaces)
7860 p = self.pg1.get_capture(1)
7863 self.assertEqual(packet[IP].src, self.nat_addr)
7864 self.assertEqual(packet[IP].dst, self.pg1.remote_ip4)
7865 self.assertEqual(packet.haslayer(GRE), 1)
7866 self.assert_packet_checksums_valid(packet)
7868 self.logger.error(ppp("Unexpected or invalid packet:", packet))
7872 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
7873 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
7875 IP(src=self.pg2.remote_ip4, dst=self.pg2.local_ip4) /
7876 TCP(sport=1234, dport=1234))
7877 self.pg1.add_stream(p)
7878 self.pg_enable_capture(self.pg_interfaces)
7880 p = self.pg0.get_capture(1)
7883 self.assertEqual(packet[IPv6].src, remote_ip6)
7884 self.assertEqual(packet[IPv6].dst, self.pg0.remote_ip6)
7885 self.assertEqual(packet[IPv6].nh, 47)
7887 self.logger.error(ppp("Unexpected or invalid packet:", packet))
7890 def test_hairpinning_unknown_proto(self):
7891 """ NAT64 translate packet with unknown protocol - hairpinning """
7893 client = self.pg0.remote_hosts[0]
7894 server = self.pg0.remote_hosts[1]
7895 server_tcp_in_port = 22
7896 server_tcp_out_port = 4022
7897 client_tcp_in_port = 1234
7898 client_tcp_out_port = 1235
7899 server_nat_ip = "10.0.0.100"
7900 client_nat_ip = "10.0.0.110"
7901 server_nat_ip_n = socket.inet_pton(socket.AF_INET, server_nat_ip)
7902 client_nat_ip_n = socket.inet_pton(socket.AF_INET, client_nat_ip)
7903 server_nat_ip6 = self.compose_ip6(server_nat_ip, '64:ff9b::', 96)
7904 client_nat_ip6 = self.compose_ip6(client_nat_ip, '64:ff9b::', 96)
7906 self.vapi.nat64_add_del_pool_addr_range(server_nat_ip_n,
7908 self.vapi.nat64_add_del_interface(self.pg0.sw_if_index)
7909 self.vapi.nat64_add_del_interface(self.pg1.sw_if_index, is_inside=0)
7911 self.vapi.nat64_add_del_static_bib(server.ip6n,
7914 server_tcp_out_port,
7917 self.vapi.nat64_add_del_static_bib(server.ip6n,
7923 self.vapi.nat64_add_del_static_bib(client.ip6n,
7926 client_tcp_out_port,
7930 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
7931 IPv6(src=client.ip6, dst=server_nat_ip6) /
7932 TCP(sport=client_tcp_in_port, dport=server_tcp_out_port))
7933 self.pg0.add_stream(p)
7934 self.pg_enable_capture(self.pg_interfaces)
7936 p = self.pg0.get_capture(1)
7938 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
7939 IPv6(src=client.ip6, dst=server_nat_ip6, nh=IP_PROTOS.gre) /
7941 IP(src=self.pg2.local_ip4, dst=self.pg2.remote_ip4) /
7942 TCP(sport=1234, dport=1234))
7943 self.pg0.add_stream(p)
7944 self.pg_enable_capture(self.pg_interfaces)
7946 p = self.pg0.get_capture(1)
7949 self.assertEqual(packet[IPv6].src, client_nat_ip6)
7950 self.assertEqual(packet[IPv6].dst, server.ip6)
7951 self.assertEqual(packet[IPv6].nh, IP_PROTOS.gre)
7953 self.logger.error(ppp("Unexpected or invalid packet:", packet))
7957 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
7958 IPv6(src=server.ip6, dst=client_nat_ip6, nh=IP_PROTOS.gre) /
7960 IP(src=self.pg2.remote_ip4, dst=self.pg2.local_ip4) /
7961 TCP(sport=1234, dport=1234))
7962 self.pg0.add_stream(p)
7963 self.pg_enable_capture(self.pg_interfaces)
7965 p = self.pg0.get_capture(1)
7968 self.assertEqual(packet[IPv6].src, server_nat_ip6)
7969 self.assertEqual(packet[IPv6].dst, client.ip6)
7970 self.assertEqual(packet[IPv6].nh, IP_PROTOS.gre)
7972 self.logger.error(ppp("Unexpected or invalid packet:", packet))
7975 def test_one_armed_nat64(self):
7976 """ One armed NAT64 """
7978 remote_host_ip6 = self.compose_ip6(self.pg3.remote_ip4,
7982 self.vapi.nat64_add_del_pool_addr_range(self.nat_addr_n,
7984 self.vapi.nat64_add_del_interface(self.pg3.sw_if_index)
7985 self.vapi.nat64_add_del_interface(self.pg3.sw_if_index, is_inside=0)
7988 p = (Ether(src=self.pg3.remote_mac, dst=self.pg3.local_mac) /
7989 IPv6(src=self.pg3.remote_ip6, dst=remote_host_ip6) /
7990 TCP(sport=12345, dport=80))
7991 self.pg3.add_stream(p)
7992 self.pg_enable_capture(self.pg_interfaces)
7994 capture = self.pg3.get_capture(1)
7999 self.assertEqual(ip.src, self.nat_addr)
8000 self.assertEqual(ip.dst, self.pg3.remote_ip4)
8001 self.assertNotEqual(tcp.sport, 12345)
8002 external_port = tcp.sport
8003 self.assertEqual(tcp.dport, 80)
8004 self.assert_packet_checksums_valid(p)
8006 self.logger.error(ppp("Unexpected or invalid packet:", p))
8010 p = (Ether(src=self.pg3.remote_mac, dst=self.pg3.local_mac) /
8011 IP(src=self.pg3.remote_ip4, dst=self.nat_addr) /
8012 TCP(sport=80, dport=external_port))
8013 self.pg3.add_stream(p)
8014 self.pg_enable_capture(self.pg_interfaces)
8016 capture = self.pg3.get_capture(1)
8021 self.assertEqual(ip.src, remote_host_ip6)
8022 self.assertEqual(ip.dst, self.pg3.remote_ip6)
8023 self.assertEqual(tcp.sport, 80)
8024 self.assertEqual(tcp.dport, 12345)
8025 self.assert_packet_checksums_valid(p)
8027 self.logger.error(ppp("Unexpected or invalid packet:", p))
8030 def test_frag_in_order(self):
8031 """ NAT64 translate fragments arriving in order """
8032 self.tcp_port_in = random.randint(1025, 65535)
8034 self.vapi.nat64_add_del_pool_addr_range(self.nat_addr_n,
8036 self.vapi.nat64_add_del_interface(self.pg0.sw_if_index)
8037 self.vapi.nat64_add_del_interface(self.pg1.sw_if_index, is_inside=0)
8039 reass = self.vapi.nat_reass_dump()
8040 reass_n_start = len(reass)
8044 pkts = self.create_stream_frag_ip6(self.pg0, self.pg1.remote_ip4,
8045 self.tcp_port_in, 20, data)
8046 self.pg0.add_stream(pkts)
8047 self.pg_enable_capture(self.pg_interfaces)
8049 frags = self.pg1.get_capture(len(pkts))
8050 p = self.reass_frags_and_verify(frags,
8052 self.pg1.remote_ip4)
8053 self.assertEqual(p[TCP].dport, 20)
8054 self.assertNotEqual(p[TCP].sport, self.tcp_port_in)
8055 self.tcp_port_out = p[TCP].sport
8056 self.assertEqual(data, p[Raw].load)
8059 data = "A" * 4 + "b" * 16 + "C" * 3
8060 pkts = self.create_stream_frag(self.pg1,
8065 self.pg1.add_stream(pkts)
8066 self.pg_enable_capture(self.pg_interfaces)
8068 frags = self.pg0.get_capture(len(pkts))
8069 src = self.compose_ip6(self.pg1.remote_ip4, '64:ff9b::', 96)
8070 p = self.reass_frags_and_verify_ip6(frags, src, self.pg0.remote_ip6)
8071 self.assertEqual(p[TCP].sport, 20)
8072 self.assertEqual(p[TCP].dport, self.tcp_port_in)
8073 self.assertEqual(data, p[Raw].load)
8075 reass = self.vapi.nat_reass_dump()
8076 reass_n_end = len(reass)
8078 self.assertEqual(reass_n_end - reass_n_start, 2)
8080 def test_reass_hairpinning(self):
8081 """ NAT64 fragments hairpinning """
8083 server = self.pg0.remote_hosts[1]
8084 server_in_port = random.randint(1025, 65535)
8085 server_out_port = random.randint(1025, 65535)
8086 client_in_port = random.randint(1025, 65535)
8087 ip = IPv6(src=''.join(['64:ff9b::', self.nat_addr]))
8088 nat_addr_ip6 = ip.src
8090 self.vapi.nat64_add_del_pool_addr_range(self.nat_addr_n,
8092 self.vapi.nat64_add_del_interface(self.pg0.sw_if_index)
8093 self.vapi.nat64_add_del_interface(self.pg1.sw_if_index, is_inside=0)
8095 # add static BIB entry for server
8096 self.vapi.nat64_add_del_static_bib(server.ip6n,
8102 # send packet from host to server
8103 pkts = self.create_stream_frag_ip6(self.pg0,
8108 self.pg0.add_stream(pkts)
8109 self.pg_enable_capture(self.pg_interfaces)
8111 frags = self.pg0.get_capture(len(pkts))
8112 p = self.reass_frags_and_verify_ip6(frags, nat_addr_ip6, server.ip6)
8113 self.assertNotEqual(p[TCP].sport, client_in_port)
8114 self.assertEqual(p[TCP].dport, server_in_port)
8115 self.assertEqual(data, p[Raw].load)
8117 def test_frag_out_of_order(self):
8118 """ NAT64 translate fragments arriving out of order """
8119 self.tcp_port_in = random.randint(1025, 65535)
8121 self.vapi.nat64_add_del_pool_addr_range(self.nat_addr_n,
8123 self.vapi.nat64_add_del_interface(self.pg0.sw_if_index)
8124 self.vapi.nat64_add_del_interface(self.pg1.sw_if_index, is_inside=0)
8128 pkts = self.create_stream_frag_ip6(self.pg0, self.pg1.remote_ip4,
8129 self.tcp_port_in, 20, data)
8131 self.pg0.add_stream(pkts)
8132 self.pg_enable_capture(self.pg_interfaces)
8134 frags = self.pg1.get_capture(len(pkts))
8135 p = self.reass_frags_and_verify(frags,
8137 self.pg1.remote_ip4)
8138 self.assertEqual(p[TCP].dport, 20)
8139 self.assertNotEqual(p[TCP].sport, self.tcp_port_in)
8140 self.tcp_port_out = p[TCP].sport
8141 self.assertEqual(data, p[Raw].load)
8144 data = "A" * 4 + "B" * 16 + "C" * 3
8145 pkts = self.create_stream_frag(self.pg1,
8151 self.pg1.add_stream(pkts)
8152 self.pg_enable_capture(self.pg_interfaces)
8154 frags = self.pg0.get_capture(len(pkts))
8155 src = self.compose_ip6(self.pg1.remote_ip4, '64:ff9b::', 96)
8156 p = self.reass_frags_and_verify_ip6(frags, src, self.pg0.remote_ip6)
8157 self.assertEqual(p[TCP].sport, 20)
8158 self.assertEqual(p[TCP].dport, self.tcp_port_in)
8159 self.assertEqual(data, p[Raw].load)
8161 def test_interface_addr(self):
8162 """ Acquire NAT64 pool addresses from interface """
8163 self.vapi.nat64_add_interface_addr(self.pg4.sw_if_index)
8165 # no address in NAT64 pool
8166 adresses = self.vapi.nat44_address_dump()
8167 self.assertEqual(0, len(adresses))
8169 # configure interface address and check NAT64 address pool
8170 self.pg4.config_ip4()
8171 addresses = self.vapi.nat64_pool_addr_dump()
8172 self.assertEqual(len(addresses), 1)
8173 self.assertEqual(addresses[0].address, self.pg4.local_ip4n)
8175 # remove interface address and check NAT64 address pool
8176 self.pg4.unconfig_ip4()
8177 addresses = self.vapi.nat64_pool_addr_dump()
8178 self.assertEqual(0, len(adresses))
8180 @unittest.skipUnless(running_extended_tests, "part of extended tests")
8181 def test_ipfix_max_bibs_sessions(self):
8182 """ IPFIX logging maximum session and BIB entries exceeded """
8185 remote_host_ip6 = self.compose_ip6(self.pg1.remote_ip4,
8189 self.vapi.nat64_add_del_pool_addr_range(self.nat_addr_n,
8191 self.vapi.nat64_add_del_interface(self.pg0.sw_if_index)
8192 self.vapi.nat64_add_del_interface(self.pg1.sw_if_index, is_inside=0)
8196 for i in range(0, max_bibs):
8197 src = "fd01:aa::%x" % (i)
8198 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
8199 IPv6(src=src, dst=remote_host_ip6) /
8200 TCP(sport=12345, dport=80))
8202 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
8203 IPv6(src=src, dst=remote_host_ip6) /
8204 TCP(sport=12345, dport=22))
8206 self.pg0.add_stream(pkts)
8207 self.pg_enable_capture(self.pg_interfaces)
8209 self.pg1.get_capture(max_sessions)
8211 self.vapi.set_ipfix_exporter(collector_address=self.pg3.remote_ip4n,
8212 src_address=self.pg3.local_ip4n,
8214 template_interval=10)
8215 self.vapi.nat_ipfix(domain_id=self.ipfix_domain_id,
8216 src_port=self.ipfix_src_port)
8218 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
8219 IPv6(src=src, dst=remote_host_ip6) /
8220 TCP(sport=12345, dport=25))
8221 self.pg0.add_stream(p)
8222 self.pg_enable_capture(self.pg_interfaces)
8224 self.pg1.assert_nothing_captured()
8226 self.vapi.cli("ipfix flush") # FIXME this should be an API call
8227 capture = self.pg3.get_capture(9)
8228 ipfix = IPFIXDecoder()
8229 # first load template
8231 self.assertTrue(p.haslayer(IPFIX))
8232 self.assertEqual(p[IP].src, self.pg3.local_ip4)
8233 self.assertEqual(p[IP].dst, self.pg3.remote_ip4)
8234 self.assertEqual(p[UDP].sport, self.ipfix_src_port)
8235 self.assertEqual(p[UDP].dport, 4739)
8236 self.assertEqual(p[IPFIX].observationDomainID,
8237 self.ipfix_domain_id)
8238 if p.haslayer(Template):
8239 ipfix.add_template(p.getlayer(Template))
8240 # verify events in data set
8242 if p.haslayer(Data):
8243 data = ipfix.decode_data_set(p.getlayer(Set))
8244 self.verify_ipfix_max_sessions(data, max_sessions)
8246 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
8247 IPv6(src=self.pg0.remote_ip6, dst=remote_host_ip6) /
8248 TCP(sport=12345, dport=80))
8249 self.pg0.add_stream(p)
8250 self.pg_enable_capture(self.pg_interfaces)
8252 self.pg1.assert_nothing_captured()
8254 self.vapi.cli("ipfix flush") # FIXME this should be an API call
8255 capture = self.pg3.get_capture(1)
8256 # verify events in data set
8258 self.assertTrue(p.haslayer(IPFIX))
8259 self.assertEqual(p[IP].src, self.pg3.local_ip4)
8260 self.assertEqual(p[IP].dst, self.pg3.remote_ip4)
8261 self.assertEqual(p[UDP].sport, self.ipfix_src_port)
8262 self.assertEqual(p[UDP].dport, 4739)
8263 self.assertEqual(p[IPFIX].observationDomainID,
8264 self.ipfix_domain_id)
8265 if p.haslayer(Data):
8266 data = ipfix.decode_data_set(p.getlayer(Set))
8267 self.verify_ipfix_max_bibs(data, max_bibs)
8269 def test_ipfix_max_frags(self):
8270 """ IPFIX logging maximum fragments pending reassembly exceeded """
8271 self.vapi.nat64_add_del_pool_addr_range(self.nat_addr_n,
8273 self.vapi.nat64_add_del_interface(self.pg0.sw_if_index)
8274 self.vapi.nat64_add_del_interface(self.pg1.sw_if_index, is_inside=0)
8275 self.vapi.nat_set_reass(max_frag=1, is_ip6=1)
8276 self.vapi.set_ipfix_exporter(collector_address=self.pg3.remote_ip4n,
8277 src_address=self.pg3.local_ip4n,
8279 template_interval=10)
8280 self.vapi.nat_ipfix(domain_id=self.ipfix_domain_id,
8281 src_port=self.ipfix_src_port)
8284 pkts = self.create_stream_frag_ip6(self.pg0, self.pg1.remote_ip4,
8285 self.tcp_port_in, 20, data)
8287 self.pg0.add_stream(pkts)
8288 self.pg_enable_capture(self.pg_interfaces)
8290 self.pg1.assert_nothing_captured()
8292 self.vapi.cli("ipfix flush") # FIXME this should be an API call
8293 capture = self.pg3.get_capture(9)
8294 ipfix = IPFIXDecoder()
8295 # first load template
8297 self.assertTrue(p.haslayer(IPFIX))
8298 self.assertEqual(p[IP].src, self.pg3.local_ip4)
8299 self.assertEqual(p[IP].dst, self.pg3.remote_ip4)
8300 self.assertEqual(p[UDP].sport, self.ipfix_src_port)
8301 self.assertEqual(p[UDP].dport, 4739)
8302 self.assertEqual(p[IPFIX].observationDomainID,
8303 self.ipfix_domain_id)
8304 if p.haslayer(Template):
8305 ipfix.add_template(p.getlayer(Template))
8306 # verify events in data set
8308 if p.haslayer(Data):
8309 data = ipfix.decode_data_set(p.getlayer(Set))
8310 self.verify_ipfix_max_fragments_ip6(data, 1,
8311 self.pg0.remote_ip6n)
8313 def test_ipfix_bib_ses(self):
8314 """ IPFIX logging NAT64 BIB/session create and delete events """
8315 self.tcp_port_in = random.randint(1025, 65535)
8316 remote_host_ip6 = self.compose_ip6(self.pg1.remote_ip4,
8320 self.vapi.nat64_add_del_pool_addr_range(self.nat_addr_n,
8322 self.vapi.nat64_add_del_interface(self.pg0.sw_if_index)
8323 self.vapi.nat64_add_del_interface(self.pg1.sw_if_index, is_inside=0)
8324 self.vapi.set_ipfix_exporter(collector_address=self.pg3.remote_ip4n,
8325 src_address=self.pg3.local_ip4n,
8327 template_interval=10)
8328 self.vapi.nat_ipfix(domain_id=self.ipfix_domain_id,
8329 src_port=self.ipfix_src_port)
8332 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
8333 IPv6(src=self.pg0.remote_ip6, dst=remote_host_ip6) /
8334 TCP(sport=self.tcp_port_in, dport=25))
8335 self.pg0.add_stream(p)
8336 self.pg_enable_capture(self.pg_interfaces)
8338 p = self.pg1.get_capture(1)
8339 self.tcp_port_out = p[0][TCP].sport
8340 self.vapi.cli("ipfix flush") # FIXME this should be an API call
8341 capture = self.pg3.get_capture(10)
8342 ipfix = IPFIXDecoder()
8343 # first load template
8345 self.assertTrue(p.haslayer(IPFIX))
8346 self.assertEqual(p[IP].src, self.pg3.local_ip4)
8347 self.assertEqual(p[IP].dst, self.pg3.remote_ip4)
8348 self.assertEqual(p[UDP].sport, self.ipfix_src_port)
8349 self.assertEqual(p[UDP].dport, 4739)
8350 self.assertEqual(p[IPFIX].observationDomainID,
8351 self.ipfix_domain_id)
8352 if p.haslayer(Template):
8353 ipfix.add_template(p.getlayer(Template))
8354 # verify events in data set
8356 if p.haslayer(Data):
8357 data = ipfix.decode_data_set(p.getlayer(Set))
8358 if ord(data[0][230]) == 10:
8359 self.verify_ipfix_bib(data, 1, self.pg0.remote_ip6n)
8360 elif ord(data[0][230]) == 6:
8361 self.verify_ipfix_nat64_ses(data,
8363 self.pg0.remote_ip6n,
8364 self.pg1.remote_ip4,
8367 self.logger.error(ppp("Unexpected or invalid packet: ", p))
8370 self.pg_enable_capture(self.pg_interfaces)
8371 self.vapi.nat64_add_del_pool_addr_range(self.nat_addr_n,
8374 self.vapi.cli("ipfix flush") # FIXME this should be an API call
8375 capture = self.pg3.get_capture(2)
8376 # verify events in data set
8378 self.assertTrue(p.haslayer(IPFIX))
8379 self.assertEqual(p[IP].src, self.pg3.local_ip4)
8380 self.assertEqual(p[IP].dst, self.pg3.remote_ip4)
8381 self.assertEqual(p[UDP].sport, self.ipfix_src_port)
8382 self.assertEqual(p[UDP].dport, 4739)
8383 self.assertEqual(p[IPFIX].observationDomainID,
8384 self.ipfix_domain_id)
8385 if p.haslayer(Data):
8386 data = ipfix.decode_data_set(p.getlayer(Set))
8387 if ord(data[0][230]) == 11:
8388 self.verify_ipfix_bib(data, 0, self.pg0.remote_ip6n)
8389 elif ord(data[0][230]) == 7:
8390 self.verify_ipfix_nat64_ses(data,
8392 self.pg0.remote_ip6n,
8393 self.pg1.remote_ip4,
8396 self.logger.error(ppp("Unexpected or invalid packet: ", p))
8398 def test_syslog_sess(self):
8399 """ Test syslog session creation and deletion """
8400 self.tcp_port_in = random.randint(1025, 65535)
8401 remote_host_ip6 = self.compose_ip6(self.pg1.remote_ip4,
8405 self.vapi.nat64_add_del_pool_addr_range(self.nat_addr_n,
8407 self.vapi.nat64_add_del_interface(self.pg0.sw_if_index)
8408 self.vapi.nat64_add_del_interface(self.pg1.sw_if_index, is_inside=0)
8409 self.vapi.syslog_set_filter(SYSLOG_SEVERITY.INFO)
8410 self.vapi.syslog_set_sender(self.pg3.remote_ip4n, self.pg3.local_ip4n)
8412 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
8413 IPv6(src=self.pg0.remote_ip6, dst=remote_host_ip6) /
8414 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port))
8415 self.pg0.add_stream(p)
8416 self.pg_enable_capture(self.pg_interfaces)
8418 p = self.pg1.get_capture(1)
8419 self.tcp_port_out = p[0][TCP].sport
8420 capture = self.pg3.get_capture(1)
8421 self.verify_syslog_sess(capture[0][Raw].load, is_ip6=True)
8423 self.pg_enable_capture(self.pg_interfaces)
8425 self.vapi.nat64_add_del_pool_addr_range(self.nat_addr_n,
8428 capture = self.pg3.get_capture(1)
8429 self.verify_syslog_sess(capture[0][Raw].load, False, True)
8431 def nat64_get_ses_num(self):
8433 Return number of active NAT64 sessions.
8435 st = self.vapi.nat64_st_dump()
8438 def clear_nat64(self):
8440 Clear NAT64 configuration.
8442 self.vapi.nat_ipfix(enable=0, src_port=self.ipfix_src_port,
8443 domain_id=self.ipfix_domain_id)
8444 self.ipfix_src_port = 4739
8445 self.ipfix_domain_id = 1
8447 self.vapi.syslog_set_filter(SYSLOG_SEVERITY.EMERG)
8449 self.vapi.nat_set_timeouts()
8451 interfaces = self.vapi.nat64_interface_dump()
8452 for intf in interfaces:
8453 if intf.is_inside > 1:
8454 self.vapi.nat64_add_del_interface(intf.sw_if_index,
8457 self.vapi.nat64_add_del_interface(intf.sw_if_index,
8461 bib = self.vapi.nat64_bib_dump(255)
8464 self.vapi.nat64_add_del_static_bib(bibe.i_addr,
8472 adresses = self.vapi.nat64_pool_addr_dump()
8473 for addr in adresses:
8474 self.vapi.nat64_add_del_pool_addr_range(addr.address,
8479 prefixes = self.vapi.nat64_prefix_dump()
8480 for prefix in prefixes:
8481 self.vapi.nat64_add_del_prefix(prefix.prefix,
8483 vrf_id=prefix.vrf_id,
8486 bibs = self.statistics.get_counter('/nat64/total-bibs')
8487 self.assertEqual(bibs[0][0], 0)
8488 sessions = self.statistics.get_counter('/nat64/total-sessions')
8489 self.assertEqual(sessions[0][0], 0)
8492 super(TestNAT64, self).tearDown()
8493 if not self.vpp_dead:
8494 self.logger.info(self.vapi.cli("show nat64 pool"))
8495 self.logger.info(self.vapi.cli("show nat64 interfaces"))
8496 self.logger.info(self.vapi.cli("show nat64 prefix"))
8497 self.logger.info(self.vapi.cli("show nat64 bib all"))
8498 self.logger.info(self.vapi.cli("show nat64 session table all"))
8499 self.logger.info(self.vapi.cli("show nat virtual-reassembly"))
8503 class TestDSlite(MethodHolder):
8504 """ DS-Lite Test Cases """
8507 def setUpClass(cls):
8508 super(TestDSlite, cls).setUpClass()
8511 cls.nat_addr = '10.0.0.3'
8512 cls.nat_addr_n = socket.inet_pton(socket.AF_INET, cls.nat_addr)
8514 cls.create_pg_interfaces(range(3))
8516 cls.pg0.config_ip4()
8517 cls.pg0.resolve_arp()
8519 cls.pg1.config_ip6()
8520 cls.pg1.generate_remote_hosts(2)
8521 cls.pg1.configure_ipv6_neighbors()
8523 cls.pg2.config_ip4()
8524 cls.pg2.resolve_arp()
8527 super(TestDSlite, cls).tearDownClass()
8530 def verify_syslog_apmadd(self, data, isaddr, isport, xsaddr, xsport,
8532 message = data.decode('utf-8')
8534 message = SyslogMessage.parse(message)
8535 except ParseError as e:
8536 self.logger.error(e)
8538 self.assertEqual(message.severity, SyslogSeverity.info)
8539 self.assertEqual(message.appname, 'NAT')
8540 self.assertEqual(message.msgid, 'APMADD')
8541 sd_params = message.sd.get('napmap')
8542 self.assertTrue(sd_params is not None)
8543 self.assertEqual(sd_params.get('IATYP'), 'IPv4')
8544 self.assertEqual(sd_params.get('ISADDR'), isaddr)
8545 self.assertEqual(sd_params.get('ISPORT'), "%d" % isport)
8546 self.assertEqual(sd_params.get('XATYP'), 'IPv4')
8547 self.assertEqual(sd_params.get('XSADDR'), xsaddr)
8548 self.assertEqual(sd_params.get('XSPORT'), "%d" % xsport)
8549 self.assertEqual(sd_params.get('PROTO'), "%d" % proto)
8550 self.assertTrue(sd_params.get('SSUBIX') is not None)
8551 self.assertEqual(sd_params.get('SV6ENC'), sv6enc)
8553 def test_dslite(self):
8554 """ Test DS-Lite """
8555 nat_config = self.vapi.nat_show_config()
8556 self.assertEqual(0, nat_config.dslite_ce)
8558 self.vapi.dslite_add_del_pool_addr_range(self.nat_addr_n,
8560 aftr_ip4 = '192.0.0.1'
8561 aftr_ip4_n = socket.inet_pton(socket.AF_INET, aftr_ip4)
8562 aftr_ip6 = '2001:db8:85a3::8a2e:370:1'
8563 aftr_ip6_n = socket.inet_pton(socket.AF_INET6, aftr_ip6)
8564 self.vapi.dslite_set_aftr_addr(aftr_ip6_n, aftr_ip4_n)
8565 self.vapi.syslog_set_sender(self.pg2.remote_ip4n, self.pg2.local_ip4n)
8568 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
8569 IPv6(dst=aftr_ip6, src=self.pg1.remote_hosts[0].ip6) /
8570 IP(dst=self.pg0.remote_ip4, src='192.168.1.1') /
8571 UDP(sport=20000, dport=10000))
8572 self.pg1.add_stream(p)
8573 self.pg_enable_capture(self.pg_interfaces)
8575 capture = self.pg0.get_capture(1)
8576 capture = capture[0]
8577 self.assertFalse(capture.haslayer(IPv6))
8578 self.assertEqual(capture[IP].src, self.nat_addr)
8579 self.assertEqual(capture[IP].dst, self.pg0.remote_ip4)
8580 self.assertNotEqual(capture[UDP].sport, 20000)
8581 self.assertEqual(capture[UDP].dport, 10000)
8582 self.assert_packet_checksums_valid(capture)
8583 out_port = capture[UDP].sport
8584 capture = self.pg2.get_capture(1)
8585 self.verify_syslog_apmadd(capture[0][Raw].load, '192.168.1.1',
8586 20000, self.nat_addr, out_port,
8587 self.pg1.remote_hosts[0].ip6, IP_PROTOS.udp)
8589 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
8590 IP(dst=self.nat_addr, src=self.pg0.remote_ip4) /
8591 UDP(sport=10000, dport=out_port))
8592 self.pg0.add_stream(p)
8593 self.pg_enable_capture(self.pg_interfaces)
8595 capture = self.pg1.get_capture(1)
8596 capture = capture[0]
8597 self.assertEqual(capture[IPv6].src, aftr_ip6)
8598 self.assertEqual(capture[IPv6].dst, self.pg1.remote_hosts[0].ip6)
8599 self.assertEqual(capture[IP].src, self.pg0.remote_ip4)
8600 self.assertEqual(capture[IP].dst, '192.168.1.1')
8601 self.assertEqual(capture[UDP].sport, 10000)
8602 self.assertEqual(capture[UDP].dport, 20000)
8603 self.assert_packet_checksums_valid(capture)
8606 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
8607 IPv6(dst=aftr_ip6, src=self.pg1.remote_hosts[1].ip6) /
8608 IP(dst=self.pg0.remote_ip4, src='192.168.1.1') /
8609 TCP(sport=20001, dport=10001))
8610 self.pg1.add_stream(p)
8611 self.pg_enable_capture(self.pg_interfaces)
8613 capture = self.pg0.get_capture(1)
8614 capture = capture[0]
8615 self.assertFalse(capture.haslayer(IPv6))
8616 self.assertEqual(capture[IP].src, self.nat_addr)
8617 self.assertEqual(capture[IP].dst, self.pg0.remote_ip4)
8618 self.assertNotEqual(capture[TCP].sport, 20001)
8619 self.assertEqual(capture[TCP].dport, 10001)
8620 self.assert_packet_checksums_valid(capture)
8621 out_port = capture[TCP].sport
8623 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
8624 IP(dst=self.nat_addr, src=self.pg0.remote_ip4) /
8625 TCP(sport=10001, dport=out_port))
8626 self.pg0.add_stream(p)
8627 self.pg_enable_capture(self.pg_interfaces)
8629 capture = self.pg1.get_capture(1)
8630 capture = capture[0]
8631 self.assertEqual(capture[IPv6].src, aftr_ip6)
8632 self.assertEqual(capture[IPv6].dst, self.pg1.remote_hosts[1].ip6)
8633 self.assertEqual(capture[IP].src, self.pg0.remote_ip4)
8634 self.assertEqual(capture[IP].dst, '192.168.1.1')
8635 self.assertEqual(capture[TCP].sport, 10001)
8636 self.assertEqual(capture[TCP].dport, 20001)
8637 self.assert_packet_checksums_valid(capture)
8640 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
8641 IPv6(dst=aftr_ip6, src=self.pg1.remote_hosts[1].ip6) /
8642 IP(dst=self.pg0.remote_ip4, src='192.168.1.1') /
8643 ICMP(id=4000, type='echo-request'))
8644 self.pg1.add_stream(p)
8645 self.pg_enable_capture(self.pg_interfaces)
8647 capture = self.pg0.get_capture(1)
8648 capture = capture[0]
8649 self.assertFalse(capture.haslayer(IPv6))
8650 self.assertEqual(capture[IP].src, self.nat_addr)
8651 self.assertEqual(capture[IP].dst, self.pg0.remote_ip4)
8652 self.assertNotEqual(capture[ICMP].id, 4000)
8653 self.assert_packet_checksums_valid(capture)
8654 out_id = capture[ICMP].id
8656 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
8657 IP(dst=self.nat_addr, src=self.pg0.remote_ip4) /
8658 ICMP(id=out_id, type='echo-reply'))
8659 self.pg0.add_stream(p)
8660 self.pg_enable_capture(self.pg_interfaces)
8662 capture = self.pg1.get_capture(1)
8663 capture = capture[0]
8664 self.assertEqual(capture[IPv6].src, aftr_ip6)
8665 self.assertEqual(capture[IPv6].dst, self.pg1.remote_hosts[1].ip6)
8666 self.assertEqual(capture[IP].src, self.pg0.remote_ip4)
8667 self.assertEqual(capture[IP].dst, '192.168.1.1')
8668 self.assertEqual(capture[ICMP].id, 4000)
8669 self.assert_packet_checksums_valid(capture)
8671 # ping DS-Lite AFTR tunnel endpoint address
8672 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
8673 IPv6(src=self.pg1.remote_hosts[1].ip6, dst=aftr_ip6) /
8674 ICMPv6EchoRequest())
8675 self.pg1.add_stream(p)
8676 self.pg_enable_capture(self.pg_interfaces)
8678 capture = self.pg1.get_capture(1)
8679 capture = capture[0]
8680 self.assertEqual(capture[IPv6].src, aftr_ip6)
8681 self.assertEqual(capture[IPv6].dst, self.pg1.remote_hosts[1].ip6)
8682 self.assertTrue(capture.haslayer(ICMPv6EchoReply))
8684 b4s = self.statistics.get_counter('/dslite/total-b4s')
8685 self.assertEqual(b4s[0][0], 2)
8686 sessions = self.statistics.get_counter('/dslite/total-sessions')
8687 self.assertEqual(sessions[0][0], 3)
8690 super(TestDSlite, self).tearDown()
8691 if not self.vpp_dead:
8692 self.logger.info(self.vapi.cli("show dslite pool"))
8694 self.vapi.cli("show dslite aftr-tunnel-endpoint-address"))
8695 self.logger.info(self.vapi.cli("show dslite sessions"))
8698 class TestDSliteCE(MethodHolder):
8699 """ DS-Lite CE Test Cases """
8702 def setUpConstants(cls):
8703 super(TestDSliteCE, cls).setUpConstants()
8704 cls.vpp_cmdline.extend(["nat", "{", "dslite ce", "}"])
8707 def setUpClass(cls):
8708 super(TestDSliteCE, cls).setUpClass()
8711 cls.create_pg_interfaces(range(2))
8713 cls.pg0.config_ip4()
8714 cls.pg0.resolve_arp()
8716 cls.pg1.config_ip6()
8717 cls.pg1.generate_remote_hosts(1)
8718 cls.pg1.configure_ipv6_neighbors()
8721 super(TestDSliteCE, cls).tearDownClass()
8724 def test_dslite_ce(self):
8725 """ Test DS-Lite CE """
8727 nat_config = self.vapi.nat_show_config()
8728 self.assertEqual(1, nat_config.dslite_ce)
8730 b4_ip4 = '192.0.0.2'
8731 b4_ip4_n = socket.inet_pton(socket.AF_INET, b4_ip4)
8732 b4_ip6 = '2001:db8:62aa::375e:f4c1:1'
8733 b4_ip6_n = socket.inet_pton(socket.AF_INET6, b4_ip6)
8734 self.vapi.dslite_set_b4_addr(b4_ip6_n, b4_ip4_n)
8736 aftr_ip4 = '192.0.0.1'
8737 aftr_ip4_n = socket.inet_pton(socket.AF_INET, aftr_ip4)
8738 aftr_ip6 = '2001:db8:85a3::8a2e:370:1'
8739 aftr_ip6_n = socket.inet_pton(socket.AF_INET6, aftr_ip6)
8740 self.vapi.dslite_set_aftr_addr(aftr_ip6_n, aftr_ip4_n)
8742 self.vapi.ip_add_del_route(dst_address=aftr_ip6_n,
8743 dst_address_length=128,
8744 next_hop_address=self.pg1.remote_ip6n,
8745 next_hop_sw_if_index=self.pg1.sw_if_index,
8749 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
8750 IP(dst=self.pg1.remote_ip4, src=self.pg0.remote_ip4) /
8751 UDP(sport=10000, dport=20000))
8752 self.pg0.add_stream(p)
8753 self.pg_enable_capture(self.pg_interfaces)
8755 capture = self.pg1.get_capture(1)
8756 capture = capture[0]
8757 self.assertEqual(capture[IPv6].src, b4_ip6)
8758 self.assertEqual(capture[IPv6].dst, aftr_ip6)
8759 self.assertEqual(capture[IP].src, self.pg0.remote_ip4)
8760 self.assertEqual(capture[IP].dst, self.pg1.remote_ip4)
8761 self.assertEqual(capture[UDP].sport, 10000)
8762 self.assertEqual(capture[UDP].dport, 20000)
8763 self.assert_packet_checksums_valid(capture)
8766 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
8767 IPv6(dst=b4_ip6, src=aftr_ip6) /
8768 IP(dst=self.pg0.remote_ip4, src=self.pg1.remote_ip4) /
8769 UDP(sport=20000, dport=10000))
8770 self.pg1.add_stream(p)
8771 self.pg_enable_capture(self.pg_interfaces)
8773 capture = self.pg0.get_capture(1)
8774 capture = capture[0]
8775 self.assertFalse(capture.haslayer(IPv6))
8776 self.assertEqual(capture[IP].src, self.pg1.remote_ip4)
8777 self.assertEqual(capture[IP].dst, self.pg0.remote_ip4)
8778 self.assertEqual(capture[UDP].sport, 20000)
8779 self.assertEqual(capture[UDP].dport, 10000)
8780 self.assert_packet_checksums_valid(capture)
8782 # ping DS-Lite B4 tunnel endpoint address
8783 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
8784 IPv6(src=self.pg1.remote_hosts[0].ip6, dst=b4_ip6) /
8785 ICMPv6EchoRequest())
8786 self.pg1.add_stream(p)
8787 self.pg_enable_capture(self.pg_interfaces)
8789 capture = self.pg1.get_capture(1)
8790 capture = capture[0]
8791 self.assertEqual(capture[IPv6].src, b4_ip6)
8792 self.assertEqual(capture[IPv6].dst, self.pg1.remote_hosts[0].ip6)
8793 self.assertTrue(capture.haslayer(ICMPv6EchoReply))
8796 super(TestDSliteCE, self).tearDown()
8797 if not self.vpp_dead:
8799 self.vapi.cli("show dslite aftr-tunnel-endpoint-address"))
8801 self.vapi.cli("show dslite b4-tunnel-endpoint-address"))
8804 class TestNAT66(MethodHolder):
8805 """ NAT66 Test Cases """
8808 def setUpClass(cls):
8809 super(TestNAT66, cls).setUpClass()
8812 cls.nat_addr = 'fd01:ff::2'
8813 cls.nat_addr_n = socket.inet_pton(socket.AF_INET6, cls.nat_addr)
8815 cls.create_pg_interfaces(range(2))
8816 cls.interfaces = list(cls.pg_interfaces)
8818 for i in cls.interfaces:
8821 i.configure_ipv6_neighbors()
8824 super(TestNAT66, cls).tearDownClass()
8827 def test_static(self):
8828 """ 1:1 NAT66 test """
8829 self.vapi.nat66_add_del_interface(self.pg0.sw_if_index)
8830 self.vapi.nat66_add_del_interface(self.pg1.sw_if_index, is_inside=0)
8831 self.vapi.nat66_add_del_static_mapping(self.pg0.remote_ip6n,
8836 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
8837 IPv6(src=self.pg0.remote_ip6, dst=self.pg1.remote_ip6) /
8840 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
8841 IPv6(src=self.pg0.remote_ip6, dst=self.pg1.remote_ip6) /
8844 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
8845 IPv6(src=self.pg0.remote_ip6, dst=self.pg1.remote_ip6) /
8846 ICMPv6EchoRequest())
8848 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
8849 IPv6(src=self.pg0.remote_ip6, dst=self.pg1.remote_ip6) /
8850 GRE() / IP() / TCP())
8852 self.pg0.add_stream(pkts)
8853 self.pg_enable_capture(self.pg_interfaces)
8855 capture = self.pg1.get_capture(len(pkts))
8856 for packet in capture:
8858 self.assertEqual(packet[IPv6].src, self.nat_addr)
8859 self.assertEqual(packet[IPv6].dst, self.pg1.remote_ip6)
8860 self.assert_packet_checksums_valid(packet)
8862 self.logger.error(ppp("Unexpected or invalid packet:", packet))
8867 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
8868 IPv6(src=self.pg1.remote_ip6, dst=self.nat_addr) /
8871 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
8872 IPv6(src=self.pg1.remote_ip6, dst=self.nat_addr) /
8875 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
8876 IPv6(src=self.pg1.remote_ip6, dst=self.nat_addr) /
8879 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
8880 IPv6(src=self.pg1.remote_ip6, dst=self.nat_addr) /
8881 GRE() / IP() / TCP())
8883 self.pg1.add_stream(pkts)
8884 self.pg_enable_capture(self.pg_interfaces)
8886 capture = self.pg0.get_capture(len(pkts))
8887 for packet in capture:
8889 self.assertEqual(packet[IPv6].src, self.pg1.remote_ip6)
8890 self.assertEqual(packet[IPv6].dst, self.pg0.remote_ip6)
8891 self.assert_packet_checksums_valid(packet)
8893 self.logger.error(ppp("Unexpected or invalid packet:", packet))
8896 sm = self.vapi.nat66_static_mapping_dump()
8897 self.assertEqual(len(sm), 1)
8898 self.assertEqual(sm[0].total_pkts, 8)
8900 def test_check_no_translate(self):
8901 """ NAT66 translate only when egress interface is outside interface """
8902 self.vapi.nat66_add_del_interface(self.pg0.sw_if_index)
8903 self.vapi.nat66_add_del_interface(self.pg1.sw_if_index)
8904 self.vapi.nat66_add_del_static_mapping(self.pg0.remote_ip6n,
8908 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
8909 IPv6(src=self.pg0.remote_ip6, dst=self.pg1.remote_ip6) /
8911 self.pg0.add_stream([p])
8912 self.pg_enable_capture(self.pg_interfaces)
8914 capture = self.pg1.get_capture(1)
8917 self.assertEqual(packet[IPv6].src, self.pg0.remote_ip6)
8918 self.assertEqual(packet[IPv6].dst, self.pg1.remote_ip6)
8920 self.logger.error(ppp("Unexpected or invalid packet:", packet))
8923 def clear_nat66(self):
8925 Clear NAT66 configuration.
8927 interfaces = self.vapi.nat66_interface_dump()
8928 for intf in interfaces:
8929 self.vapi.nat66_add_del_interface(intf.sw_if_index,
8933 static_mappings = self.vapi.nat66_static_mapping_dump()
8934 for sm in static_mappings:
8935 self.vapi.nat66_add_del_static_mapping(sm.local_ip_address,
8936 sm.external_ip_address,
8941 super(TestNAT66, self).tearDown()
8942 if not self.vpp_dead:
8943 self.logger.info(self.vapi.cli("show nat66 interfaces"))
8944 self.logger.info(self.vapi.cli("show nat66 static mappings"))
8948 if __name__ == '__main__':
8949 unittest.main(testRunner=VppTestRunner)