8 from framework import VppTestCase, VppTestRunner, running_extended_tests
11 from scapy.layers.inet import IP, TCP, UDP, ICMP
12 from scapy.layers.inet import IPerror, TCPerror, UDPerror, ICMPerror
13 from scapy.layers.inet6 import IPv6, ICMPv6EchoRequest, ICMPv6EchoReply, \
14 ICMPv6ND_NS, ICMPv6ND_NA, ICMPv6NDOptDstLLAddr, fragment6
15 from scapy.layers.inet6 import ICMPv6DestUnreach, IPerror6, IPv6ExtHdrFragment
16 from scapy.layers.l2 import Ether, ARP, GRE
17 from scapy.data import IP_PROTOS
18 from scapy.packet import bind_layers, Raw
20 from ipfix import IPFIX, Set, Template, Data, IPFIXDecoder
21 from time import sleep
22 from util import ip4_range
23 from vpp_papi import mac_pton
24 from syslog_rfc5424_parser import SyslogMessage, ParseError
25 from syslog_rfc5424_parser.constants import SyslogFacility, SyslogSeverity
26 from vpp_papi_provider import SYSLOG_SEVERITY
27 from io import BytesIO
28 from vpp_papi import VppEnum
29 from vpp_ip import VppIpAddress, VppIpPrefix
30 from scapy.all import bind_layers, Packet, ByteEnumField, ShortField, \
31 IPField, IntField, LongField, XByteField, FlagsField, FieldLenField, \
35 # NAT HA protocol event data
38 fields_desc = [ByteEnumField("event_type", None,
39 {1: "add", 2: "del", 3: "refresh"}),
40 ByteEnumField("protocol", None,
41 {0: "udp", 1: "tcp", 2: "icmp"}),
42 ShortField("flags", 0),
43 IPField("in_addr", None),
44 IPField("out_addr", None),
45 ShortField("in_port", None),
46 ShortField("out_port", None),
47 IPField("eh_addr", None),
48 IPField("ehn_addr", None),
49 ShortField("eh_port", None),
50 ShortField("ehn_port", None),
51 IntField("fib_index", None),
52 IntField("total_pkts", 0),
53 LongField("total_bytes", 0)]
55 def extract_padding(self, s):
59 # NAT HA protocol header
60 class HANATStateSync(Packet):
61 name = "HA NAT state sync"
62 fields_desc = [XByteField("version", 1),
63 FlagsField("flags", 0, 8, ['ACK']),
64 FieldLenField("count", None, count_of="events"),
65 IntField("sequence_number", 1),
66 IntField("thread_index", 0),
67 PacketListField("events", [], Event,
68 count_from=lambda pkt: pkt.count)]
71 class MethodHolder(VppTestCase):
72 """ NAT create capture and verify method holder """
74 def clear_nat44(self):
76 Clear NAT44 configuration.
78 if hasattr(self, 'pg7') and hasattr(self, 'pg8'):
79 # I found no elegant way to do this
80 self.vapi.ip_add_del_route(
81 dst_address=self.pg7.remote_ip4n,
82 dst_address_length=32,
83 next_hop_address=self.pg7.remote_ip4n,
84 next_hop_sw_if_index=self.pg7.sw_if_index,
86 self.vapi.ip_add_del_route(
87 dst_address=self.pg8.remote_ip4n,
88 dst_address_length=32,
89 next_hop_address=self.pg8.remote_ip4n,
90 next_hop_sw_if_index=self.pg8.sw_if_index,
93 for intf in [self.pg7, self.pg8]:
94 self.vapi.ip_neighbor_add_del(
98 flags=(VppEnum.vl_api_ip_neighbor_flags_t.
99 IP_API_NEIGHBOR_FLAG_STATIC),
102 if self.pg7.has_ip4_config:
103 self.pg7.unconfig_ip4()
105 self.vapi.nat44_forwarding_enable_disable(0)
107 interfaces = self.vapi.nat44_interface_addr_dump()
108 for intf in interfaces:
109 self.vapi.nat44_add_del_interface_addr(intf.sw_if_index,
110 twice_nat=intf.twice_nat,
113 self.vapi.nat_ipfix_enable_disable(enable=0,
114 src_port=self.ipfix_src_port,
115 domain_id=self.ipfix_domain_id)
116 self.ipfix_src_port = 4739
117 self.ipfix_domain_id = 1
119 self.vapi.syslog_set_filter(SYSLOG_SEVERITY.EMERG)
121 self.vapi.nat_ha_set_listener('0.0.0.0', 0)
122 self.vapi.nat_ha_set_failover('0.0.0.0', 0)
124 interfaces = self.vapi.nat44_interface_dump()
125 for intf in interfaces:
126 if intf.is_inside > 1:
127 self.vapi.nat44_interface_add_del_feature(intf.sw_if_index,
130 self.vapi.nat44_interface_add_del_feature(intf.sw_if_index,
134 interfaces = self.vapi.nat44_interface_output_feature_dump()
135 for intf in interfaces:
136 self.vapi.nat44_interface_add_del_output_feature(intf.sw_if_index,
140 static_mappings = self.vapi.nat44_static_mapping_dump()
141 for sm in static_mappings:
142 self.vapi.nat44_add_del_static_mapping(
144 sm.external_ip_address,
145 local_port=sm.local_port,
146 external_port=sm.external_port,
147 addr_only=sm.addr_only,
149 protocol=sm.protocol,
150 twice_nat=sm.twice_nat,
151 self_twice_nat=sm.self_twice_nat,
152 out2in_only=sm.out2in_only,
154 external_sw_if_index=sm.external_sw_if_index,
157 lb_static_mappings = self.vapi.nat44_lb_static_mapping_dump()
158 for lb_sm in lb_static_mappings:
159 self.vapi.nat44_add_del_lb_static_mapping(
163 twice_nat=lb_sm.twice_nat,
164 self_twice_nat=lb_sm.self_twice_nat,
165 out2in_only=lb_sm.out2in_only,
171 identity_mappings = self.vapi.nat44_identity_mapping_dump()
172 for id_m in identity_mappings:
173 self.vapi.nat44_add_del_identity_mapping(
174 addr_only=id_m.addr_only,
177 sw_if_index=id_m.sw_if_index,
179 protocol=id_m.protocol,
182 adresses = self.vapi.nat44_address_dump()
183 for addr in adresses:
184 self.vapi.nat44_add_del_address_range(addr.ip_address,
186 twice_nat=addr.twice_nat,
189 self.vapi.nat_set_reass()
190 self.vapi.nat_set_reass(is_ip6=1)
191 self.verify_no_nat44_user()
192 self.vapi.nat_set_timeouts()
193 self.vapi.nat_set_addr_and_port_alloc_alg()
194 self.vapi.nat_set_mss_clamping()
196 def nat44_add_static_mapping(self, local_ip, external_ip='0.0.0.0',
197 local_port=0, external_port=0, vrf_id=0,
198 is_add=1, external_sw_if_index=0xFFFFFFFF,
199 proto=0, twice_nat=0, self_twice_nat=0,
200 out2in_only=0, tag=""):
202 Add/delete NAT44 static mapping
204 :param local_ip: Local IP address
205 :param external_ip: External IP address
206 :param local_port: Local port number (Optional)
207 :param external_port: External port number (Optional)
208 :param vrf_id: VRF ID (Default 0)
209 :param is_add: 1 if add, 0 if delete (Default add)
210 :param external_sw_if_index: External interface instead of IP address
211 :param proto: IP protocol (Mandatory if port specified)
212 :param twice_nat: 1 if translate external host address and port
213 :param self_twice_nat: 1 if translate external host address and port
214 whenever external host address equals
215 local address of internal host
216 :param out2in_only: if 1 rule is matching only out2in direction
217 :param tag: Opaque string tag
220 if local_port and external_port:
222 l_ip = socket.inet_pton(socket.AF_INET, local_ip)
223 e_ip = socket.inet_pton(socket.AF_INET, external_ip)
224 self.vapi.nat44_add_del_static_mapping(
227 external_sw_if_index,
239 def nat44_add_address(self, ip, is_add=1, vrf_id=0xFFFFFFFF, twice_nat=0):
241 Add/delete NAT44 address
243 :param ip: IP address
244 :param is_add: 1 if add, 0 if delete (Default add)
245 :param twice_nat: twice NAT address for extenal hosts
247 nat_addr = socket.inet_pton(socket.AF_INET, ip)
248 self.vapi.nat44_add_del_address_range(nat_addr, nat_addr, is_add,
252 def create_stream_in(self, in_if, out_if, dst_ip=None, ttl=64):
254 Create packet stream for inside network
256 :param in_if: Inside interface
257 :param out_if: Outside interface
258 :param dst_ip: Destination address
259 :param ttl: TTL of generated packets
262 dst_ip = out_if.remote_ip4
266 p = (Ether(dst=in_if.local_mac, src=in_if.remote_mac) /
267 IP(src=in_if.remote_ip4, dst=dst_ip, ttl=ttl) /
268 TCP(sport=self.tcp_port_in, dport=20))
272 p = (Ether(dst=in_if.local_mac, src=in_if.remote_mac) /
273 IP(src=in_if.remote_ip4, dst=dst_ip, ttl=ttl) /
274 UDP(sport=self.udp_port_in, dport=20))
278 p = (Ether(dst=in_if.local_mac, src=in_if.remote_mac) /
279 IP(src=in_if.remote_ip4, dst=dst_ip, ttl=ttl) /
280 ICMP(id=self.icmp_id_in, type='echo-request'))
285 def compose_ip6(self, ip4, pref, plen):
287 Compose IPv4-embedded IPv6 addresses
289 :param ip4: IPv4 address
290 :param pref: IPv6 prefix
291 :param plen: IPv6 prefix length
292 :returns: IPv4-embedded IPv6 addresses
294 pref_n = list(socket.inet_pton(socket.AF_INET6, pref))
295 ip4_n = list(socket.inet_pton(socket.AF_INET, ip4))
310 pref_n[10] = ip4_n[3]
314 pref_n[10] = ip4_n[2]
315 pref_n[11] = ip4_n[3]
318 pref_n[10] = ip4_n[1]
319 pref_n[11] = ip4_n[2]
320 pref_n[12] = ip4_n[3]
322 pref_n[12] = ip4_n[0]
323 pref_n[13] = ip4_n[1]
324 pref_n[14] = ip4_n[2]
325 pref_n[15] = ip4_n[3]
326 packed_pref_n = b''.join([scapy.compat.chb(x) for x in pref_n])
327 return socket.inet_ntop(socket.AF_INET6, packed_pref_n)
329 def extract_ip4(self, ip6, plen):
331 Extract IPv4 address embedded in IPv6 addresses
333 :param ip6: IPv6 address
334 :param plen: IPv6 prefix length
335 :returns: extracted IPv4 address
337 ip6_n = list(socket.inet_pton(socket.AF_INET6, ip6))
369 return socket.inet_ntop(socket.AF_INET, ''.join(ip4_n))
371 def create_stream_in_ip6(self, in_if, out_if, hlim=64, pref=None, plen=0):
373 Create IPv6 packet stream for inside network
375 :param in_if: Inside interface
376 :param out_if: Outside interface
377 :param ttl: Hop Limit of generated packets
378 :param pref: NAT64 prefix
379 :param plen: NAT64 prefix length
383 dst = ''.join(['64:ff9b::', out_if.remote_ip4])
385 dst = self.compose_ip6(out_if.remote_ip4, pref, plen)
388 p = (Ether(dst=in_if.local_mac, src=in_if.remote_mac) /
389 IPv6(src=in_if.remote_ip6, dst=dst, hlim=hlim) /
390 TCP(sport=self.tcp_port_in, dport=20))
394 p = (Ether(dst=in_if.local_mac, src=in_if.remote_mac) /
395 IPv6(src=in_if.remote_ip6, dst=dst, hlim=hlim) /
396 UDP(sport=self.udp_port_in, dport=20))
400 p = (Ether(dst=in_if.local_mac, src=in_if.remote_mac) /
401 IPv6(src=in_if.remote_ip6, dst=dst, hlim=hlim) /
402 ICMPv6EchoRequest(id=self.icmp_id_in))
407 def create_stream_out(self, out_if, dst_ip=None, ttl=64,
408 use_inside_ports=False):
410 Create packet stream for outside network
412 :param out_if: Outside interface
413 :param dst_ip: Destination IP address (Default use global NAT address)
414 :param ttl: TTL of generated packets
415 :param use_inside_ports: Use inside NAT ports as destination ports
416 instead of outside ports
419 dst_ip = self.nat_addr
420 if not use_inside_ports:
421 tcp_port = self.tcp_port_out
422 udp_port = self.udp_port_out
423 icmp_id = self.icmp_id_out
425 tcp_port = self.tcp_port_in
426 udp_port = self.udp_port_in
427 icmp_id = self.icmp_id_in
430 p = (Ether(dst=out_if.local_mac, src=out_if.remote_mac) /
431 IP(src=out_if.remote_ip4, dst=dst_ip, ttl=ttl) /
432 TCP(dport=tcp_port, sport=20))
436 p = (Ether(dst=out_if.local_mac, src=out_if.remote_mac) /
437 IP(src=out_if.remote_ip4, dst=dst_ip, ttl=ttl) /
438 UDP(dport=udp_port, sport=20))
442 p = (Ether(dst=out_if.local_mac, src=out_if.remote_mac) /
443 IP(src=out_if.remote_ip4, dst=dst_ip, ttl=ttl) /
444 ICMP(id=icmp_id, type='echo-reply'))
449 def create_stream_out_ip6(self, out_if, src_ip, dst_ip, hl=64):
451 Create packet stream for outside network
453 :param out_if: Outside interface
454 :param dst_ip: Destination IP address (Default use global NAT address)
455 :param hl: HL of generated packets
459 p = (Ether(dst=out_if.local_mac, src=out_if.remote_mac) /
460 IPv6(src=src_ip, dst=dst_ip, hlim=hl) /
461 TCP(dport=self.tcp_port_out, sport=20))
465 p = (Ether(dst=out_if.local_mac, src=out_if.remote_mac) /
466 IPv6(src=src_ip, dst=dst_ip, hlim=hl) /
467 UDP(dport=self.udp_port_out, sport=20))
471 p = (Ether(dst=out_if.local_mac, src=out_if.remote_mac) /
472 IPv6(src=src_ip, dst=dst_ip, hlim=hl) /
473 ICMPv6EchoReply(id=self.icmp_id_out))
478 def verify_capture_out(self, capture, nat_ip=None, same_port=False,
479 dst_ip=None, is_ip6=False):
481 Verify captured packets on outside network
483 :param capture: Captured packets
484 :param nat_ip: Translated IP address (Default use global NAT address)
485 :param same_port: Sorce port number is not translated (Default False)
486 :param dst_ip: Destination IP address (Default do not verify)
487 :param is_ip6: If L3 protocol is IPv6 (Default False)
491 ICMP46 = ICMPv6EchoRequest
496 nat_ip = self.nat_addr
497 for packet in capture:
500 self.assert_packet_checksums_valid(packet)
501 self.assertEqual(packet[IP46].src, nat_ip)
502 if dst_ip is not None:
503 self.assertEqual(packet[IP46].dst, dst_ip)
504 if packet.haslayer(TCP):
506 self.assertEqual(packet[TCP].sport, self.tcp_port_in)
509 packet[TCP].sport, self.tcp_port_in)
510 self.tcp_port_out = packet[TCP].sport
511 self.assert_packet_checksums_valid(packet)
512 elif packet.haslayer(UDP):
514 self.assertEqual(packet[UDP].sport, self.udp_port_in)
517 packet[UDP].sport, self.udp_port_in)
518 self.udp_port_out = packet[UDP].sport
521 self.assertEqual(packet[ICMP46].id, self.icmp_id_in)
523 self.assertNotEqual(packet[ICMP46].id, self.icmp_id_in)
524 self.icmp_id_out = packet[ICMP46].id
525 self.assert_packet_checksums_valid(packet)
527 self.logger.error(ppp("Unexpected or invalid packet "
528 "(outside network):", packet))
531 def verify_capture_out_ip6(self, capture, nat_ip, same_port=False,
534 Verify captured packets on outside network
536 :param capture: Captured packets
537 :param nat_ip: Translated IP address
538 :param same_port: Sorce port number is not translated (Default False)
539 :param dst_ip: Destination IP address (Default do not verify)
541 return self.verify_capture_out(capture, nat_ip, same_port, dst_ip,
544 def verify_capture_in(self, capture, in_if):
546 Verify captured packets on inside network
548 :param capture: Captured packets
549 :param in_if: Inside interface
551 for packet in capture:
553 self.assert_packet_checksums_valid(packet)
554 self.assertEqual(packet[IP].dst, in_if.remote_ip4)
555 if packet.haslayer(TCP):
556 self.assertEqual(packet[TCP].dport, self.tcp_port_in)
557 elif packet.haslayer(UDP):
558 self.assertEqual(packet[UDP].dport, self.udp_port_in)
560 self.assertEqual(packet[ICMP].id, self.icmp_id_in)
562 self.logger.error(ppp("Unexpected or invalid packet "
563 "(inside network):", packet))
566 def verify_capture_in_ip6(self, capture, src_ip, dst_ip):
568 Verify captured IPv6 packets on inside network
570 :param capture: Captured packets
571 :param src_ip: Source IP
572 :param dst_ip: Destination IP address
574 for packet in capture:
576 self.assertEqual(packet[IPv6].src, src_ip)
577 self.assertEqual(packet[IPv6].dst, dst_ip)
578 self.assert_packet_checksums_valid(packet)
579 if packet.haslayer(TCP):
580 self.assertEqual(packet[TCP].dport, self.tcp_port_in)
581 elif packet.haslayer(UDP):
582 self.assertEqual(packet[UDP].dport, self.udp_port_in)
584 self.assertEqual(packet[ICMPv6EchoReply].id,
587 self.logger.error(ppp("Unexpected or invalid packet "
588 "(inside network):", packet))
591 def verify_capture_no_translation(self, capture, ingress_if, egress_if):
593 Verify captured packet that don't have to be translated
595 :param capture: Captured packets
596 :param ingress_if: Ingress interface
597 :param egress_if: Egress interface
599 for packet in capture:
601 self.assertEqual(packet[IP].src, ingress_if.remote_ip4)
602 self.assertEqual(packet[IP].dst, egress_if.remote_ip4)
603 if packet.haslayer(TCP):
604 self.assertEqual(packet[TCP].sport, self.tcp_port_in)
605 elif packet.haslayer(UDP):
606 self.assertEqual(packet[UDP].sport, self.udp_port_in)
608 self.assertEqual(packet[ICMP].id, self.icmp_id_in)
610 self.logger.error(ppp("Unexpected or invalid packet "
611 "(inside network):", packet))
614 def verify_capture_out_with_icmp_errors(self, capture, src_ip=None,
617 Verify captured packets with ICMP errors on outside network
619 :param capture: Captured packets
620 :param src_ip: Translated IP address or IP address of VPP
621 (Default use global NAT address)
622 :param icmp_type: Type of error ICMP packet
623 we are expecting (Default 11)
626 src_ip = self.nat_addr
627 for packet in capture:
629 self.assertEqual(packet[IP].src, src_ip)
630 self.assertEqual(packet.haslayer(ICMP), 1)
632 self.assertEqual(icmp.type, icmp_type)
633 self.assertTrue(icmp.haslayer(IPerror))
634 inner_ip = icmp[IPerror]
635 if inner_ip.haslayer(TCPerror):
636 self.assertEqual(inner_ip[TCPerror].dport,
638 elif inner_ip.haslayer(UDPerror):
639 self.assertEqual(inner_ip[UDPerror].dport,
642 self.assertEqual(inner_ip[ICMPerror].id, self.icmp_id_out)
644 self.logger.error(ppp("Unexpected or invalid packet "
645 "(outside network):", packet))
648 def verify_capture_in_with_icmp_errors(self, capture, in_if, icmp_type=11):
650 Verify captured packets with ICMP errors on inside network
652 :param capture: Captured packets
653 :param in_if: Inside interface
654 :param icmp_type: Type of error ICMP packet
655 we are expecting (Default 11)
657 for packet in capture:
659 self.assertEqual(packet[IP].dst, in_if.remote_ip4)
660 self.assertEqual(packet.haslayer(ICMP), 1)
662 self.assertEqual(icmp.type, icmp_type)
663 self.assertTrue(icmp.haslayer(IPerror))
664 inner_ip = icmp[IPerror]
665 if inner_ip.haslayer(TCPerror):
666 self.assertEqual(inner_ip[TCPerror].sport,
668 elif inner_ip.haslayer(UDPerror):
669 self.assertEqual(inner_ip[UDPerror].sport,
672 self.assertEqual(inner_ip[ICMPerror].id, self.icmp_id_in)
674 self.logger.error(ppp("Unexpected or invalid packet "
675 "(inside network):", packet))
678 def create_stream_frag(self, src_if, dst, sport, dport, data,
679 proto=IP_PROTOS.tcp, echo_reply=False):
681 Create fragmented packet stream
683 :param src_if: Source interface
684 :param dst: Destination IPv4 address
685 :param sport: Source port
686 :param dport: Destination port
687 :param data: Payload data
688 :param proto: protocol (TCP, UDP, ICMP)
689 :param echo_reply: use echo_reply if protocol is ICMP
692 if proto == IP_PROTOS.tcp:
693 p = (IP(src=src_if.remote_ip4, dst=dst) /
694 TCP(sport=sport, dport=dport) /
696 p = p.__class__(scapy.compat.raw(p))
697 chksum = p[TCP].chksum
698 proto_header = TCP(sport=sport, dport=dport, chksum=chksum)
699 elif proto == IP_PROTOS.udp:
700 proto_header = UDP(sport=sport, dport=dport)
701 elif proto == IP_PROTOS.icmp:
703 proto_header = ICMP(id=sport, type='echo-request')
705 proto_header = ICMP(id=sport, type='echo-reply')
707 raise Exception("Unsupported protocol")
708 id = random.randint(0, 65535)
710 if proto == IP_PROTOS.tcp:
713 raw = Raw(data[0:16])
714 p = (Ether(src=src_if.remote_mac, dst=src_if.local_mac) /
715 IP(src=src_if.remote_ip4, dst=dst, flags="MF", frag=0, id=id) /
719 if proto == IP_PROTOS.tcp:
720 raw = Raw(data[4:20])
722 raw = Raw(data[16:32])
723 p = (Ether(src=src_if.remote_mac, dst=src_if.local_mac) /
724 IP(src=src_if.remote_ip4, dst=dst, flags="MF", frag=3, id=id,
728 if proto == IP_PROTOS.tcp:
732 p = (Ether(src=src_if.remote_mac, dst=src_if.local_mac) /
733 IP(src=src_if.remote_ip4, dst=dst, frag=5, proto=proto,
739 def create_stream_frag_ip6(self, src_if, dst, sport, dport, data,
740 pref=None, plen=0, frag_size=128):
742 Create fragmented packet stream
744 :param src_if: Source interface
745 :param dst: Destination IPv4 address
746 :param sport: Source TCP port
747 :param dport: Destination TCP port
748 :param data: Payload data
749 :param pref: NAT64 prefix
750 :param plen: NAT64 prefix length
751 :param fragsize: size of fragments
755 dst_ip6 = ''.join(['64:ff9b::', dst])
757 dst_ip6 = self.compose_ip6(dst, pref, plen)
759 p = (Ether(dst=src_if.local_mac, src=src_if.remote_mac) /
760 IPv6(src=src_if.remote_ip6, dst=dst_ip6) /
761 IPv6ExtHdrFragment(id=random.randint(0, 65535)) /
762 TCP(sport=sport, dport=dport) /
765 return fragment6(p, frag_size)
767 def reass_frags_and_verify(self, frags, src, dst):
769 Reassemble and verify fragmented packet
771 :param frags: Captured fragments
772 :param src: Source IPv4 address to verify
773 :param dst: Destination IPv4 address to verify
775 :returns: Reassembled IPv4 packet
779 self.assertEqual(p[IP].src, src)
780 self.assertEqual(p[IP].dst, dst)
781 self.assert_ip_checksum_valid(p)
782 buffer.seek(p[IP].frag * 8)
783 buffer.write(bytes(p[IP].payload))
784 ip = IP(src=frags[0][IP].src, dst=frags[0][IP].dst,
785 proto=frags[0][IP].proto)
786 if ip.proto == IP_PROTOS.tcp:
787 p = (ip / TCP(buffer.getvalue()))
788 self.assert_tcp_checksum_valid(p)
789 elif ip.proto == IP_PROTOS.udp:
790 p = (ip / UDP(buffer.getvalue()[:8]) /
791 Raw(buffer.getvalue()[8:]))
792 elif ip.proto == IP_PROTOS.icmp:
793 p = (ip / ICMP(buffer.getvalue()))
796 def reass_frags_and_verify_ip6(self, frags, src, dst):
798 Reassemble and verify fragmented packet
800 :param frags: Captured fragments
801 :param src: Source IPv6 address to verify
802 :param dst: Destination IPv6 address to verify
804 :returns: Reassembled IPv6 packet
808 self.assertEqual(p[IPv6].src, src)
809 self.assertEqual(p[IPv6].dst, dst)
810 buffer.seek(p[IPv6ExtHdrFragment].offset * 8)
811 buffer.write(bytes(p[IPv6ExtHdrFragment].payload))
812 ip = IPv6(src=frags[0][IPv6].src, dst=frags[0][IPv6].dst,
813 nh=frags[0][IPv6ExtHdrFragment].nh)
814 if ip.nh == IP_PROTOS.tcp:
815 p = (ip / TCP(buffer.getvalue()))
816 elif ip.nh == IP_PROTOS.udp:
817 p = (ip / UDP(buffer.getvalue()))
818 self.assert_packet_checksums_valid(p)
821 def initiate_tcp_session(self, in_if, out_if):
823 Initiates TCP session
825 :param in_if: Inside interface
826 :param out_if: Outside interface
830 p = (Ether(src=in_if.remote_mac, dst=in_if.local_mac) /
831 IP(src=in_if.remote_ip4, dst=out_if.remote_ip4) /
832 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
835 self.pg_enable_capture(self.pg_interfaces)
837 capture = out_if.get_capture(1)
839 self.tcp_port_out = p[TCP].sport
841 # SYN + ACK packet out->in
842 p = (Ether(src=out_if.remote_mac, dst=out_if.local_mac) /
843 IP(src=out_if.remote_ip4, dst=self.nat_addr) /
844 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
847 self.pg_enable_capture(self.pg_interfaces)
852 p = (Ether(src=in_if.remote_mac, dst=in_if.local_mac) /
853 IP(src=in_if.remote_ip4, dst=out_if.remote_ip4) /
854 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
857 self.pg_enable_capture(self.pg_interfaces)
859 out_if.get_capture(1)
862 self.logger.error("TCP 3 way handshake failed")
865 def verify_ipfix_nat44_ses(self, data):
867 Verify IPFIX NAT44 session create/delete event
869 :param data: Decoded IPFIX data records
871 nat44_ses_create_num = 0
872 nat44_ses_delete_num = 0
873 self.assertEqual(6, len(data))
876 self.assertIn(scapy.compat.orb(record[230]), [4, 5])
877 if scapy.compat.orb(record[230]) == 4:
878 nat44_ses_create_num += 1
880 nat44_ses_delete_num += 1
882 self.assertEqual(self.pg0.remote_ip4n, record[8])
883 # postNATSourceIPv4Address
884 self.assertEqual(socket.inet_pton(socket.AF_INET, self.nat_addr),
887 self.assertEqual(struct.pack("!I", 0), record[234])
888 # protocolIdentifier/sourceTransportPort/postNAPTSourceTransportPort
889 if IP_PROTOS.icmp == scapy.compat.orb(record[4]):
890 self.assertEqual(struct.pack("!H", self.icmp_id_in), record[7])
891 self.assertEqual(struct.pack("!H", self.icmp_id_out),
893 elif IP_PROTOS.tcp == scapy.compat.orb(record[4]):
894 self.assertEqual(struct.pack("!H", self.tcp_port_in),
896 self.assertEqual(struct.pack("!H", self.tcp_port_out),
898 elif IP_PROTOS.udp == scapy.compat.orb(record[4]):
899 self.assertEqual(struct.pack("!H", self.udp_port_in),
901 self.assertEqual(struct.pack("!H", self.udp_port_out),
904 self.fail("Invalid protocol")
905 self.assertEqual(3, nat44_ses_create_num)
906 self.assertEqual(3, nat44_ses_delete_num)
908 def verify_ipfix_addr_exhausted(self, data):
910 Verify IPFIX NAT addresses event
912 :param data: Decoded IPFIX data records
914 self.assertEqual(1, len(data))
917 self.assertEqual(scapy.compat.orb(record[230]), 3)
919 self.assertEqual(struct.pack("!I", 0), record[283])
921 def verify_ipfix_max_sessions(self, data, limit):
923 Verify IPFIX maximum session entries exceeded event
925 :param data: Decoded IPFIX data records
926 :param limit: Number of maximum session entries that can be created.
928 self.assertEqual(1, len(data))
931 self.assertEqual(scapy.compat.orb(record[230]), 13)
932 # natQuotaExceededEvent
933 self.assertEqual(struct.pack("I", 1), record[466])
935 self.assertEqual(struct.pack("I", limit), record[471])
937 def verify_ipfix_max_bibs(self, data, limit):
939 Verify IPFIX maximum BIB entries exceeded event
941 :param data: Decoded IPFIX data records
942 :param limit: Number of maximum BIB entries that can be created.
944 self.assertEqual(1, len(data))
947 self.assertEqual(scapy.compat.orb(record[230]), 13)
948 # natQuotaExceededEvent
949 self.assertEqual(struct.pack("I", 2), record[466])
951 self.assertEqual(struct.pack("I", limit), record[472])
953 def verify_ipfix_max_fragments_ip6(self, data, limit, src_addr):
955 Verify IPFIX maximum IPv6 fragments pending reassembly exceeded event
957 :param data: Decoded IPFIX data records
958 :param limit: Number of maximum fragments pending reassembly
959 :param src_addr: IPv6 source address
961 self.assertEqual(1, len(data))
964 self.assertEqual(scapy.compat.orb(record[230]), 13)
965 # natQuotaExceededEvent
966 self.assertEqual(struct.pack("I", 5), record[466])
967 # maxFragmentsPendingReassembly
968 self.assertEqual(struct.pack("I", limit), record[475])
970 self.assertEqual(src_addr, record[27])
972 def verify_ipfix_max_fragments_ip4(self, data, limit, src_addr):
974 Verify IPFIX maximum IPv4 fragments pending reassembly exceeded event
976 :param data: Decoded IPFIX data records
977 :param limit: Number of maximum fragments pending reassembly
978 :param src_addr: IPv4 source address
980 self.assertEqual(1, len(data))
983 self.assertEqual(scapy.compat.orb(record[230]), 13)
984 # natQuotaExceededEvent
985 self.assertEqual(struct.pack("I", 5), record[466])
986 # maxFragmentsPendingReassembly
987 self.assertEqual(struct.pack("I", limit), record[475])
989 self.assertEqual(src_addr, record[8])
991 def verify_ipfix_bib(self, data, is_create, src_addr):
993 Verify IPFIX NAT64 BIB create and delete events
995 :param data: Decoded IPFIX data records
996 :param is_create: Create event if nonzero value otherwise delete event
997 :param src_addr: IPv6 source address
999 self.assertEqual(1, len(data))
1003 self.assertEqual(scapy.compat.orb(record[230]), 10)
1005 self.assertEqual(scapy.compat.orb(record[230]), 11)
1007 self.assertEqual(src_addr, record[27])
1008 # postNATSourceIPv4Address
1009 self.assertEqual(self.nat_addr_n, record[225])
1010 # protocolIdentifier
1011 self.assertEqual(IP_PROTOS.tcp, scapy.compat.orb(record[4]))
1013 self.assertEqual(struct.pack("!I", 0), record[234])
1014 # sourceTransportPort
1015 self.assertEqual(struct.pack("!H", self.tcp_port_in), record[7])
1016 # postNAPTSourceTransportPort
1017 self.assertEqual(struct.pack("!H", self.tcp_port_out), record[227])
1019 def verify_ipfix_nat64_ses(self, data, is_create, src_addr, dst_addr,
1022 Verify IPFIX NAT64 session create and delete events
1024 :param data: Decoded IPFIX data records
1025 :param is_create: Create event if nonzero value otherwise delete event
1026 :param src_addr: IPv6 source address
1027 :param dst_addr: IPv4 destination address
1028 :param dst_port: destination TCP port
1030 self.assertEqual(1, len(data))
1034 self.assertEqual(scapy.compat.orb(record[230]), 6)
1036 self.assertEqual(scapy.compat.orb(record[230]), 7)
1038 self.assertEqual(src_addr, record[27])
1039 # destinationIPv6Address
1040 self.assertEqual(socket.inet_pton(socket.AF_INET6,
1041 self.compose_ip6(dst_addr,
1045 # postNATSourceIPv4Address
1046 self.assertEqual(self.nat_addr_n, record[225])
1047 # postNATDestinationIPv4Address
1048 self.assertEqual(socket.inet_pton(socket.AF_INET, dst_addr),
1050 # protocolIdentifier
1051 self.assertEqual(IP_PROTOS.tcp, scapy.compat.orb(record[4]))
1053 self.assertEqual(struct.pack("!I", 0), record[234])
1054 # sourceTransportPort
1055 self.assertEqual(struct.pack("!H", self.tcp_port_in), record[7])
1056 # postNAPTSourceTransportPort
1057 self.assertEqual(struct.pack("!H", self.tcp_port_out), record[227])
1058 # destinationTransportPort
1059 self.assertEqual(struct.pack("!H", dst_port), record[11])
1060 # postNAPTDestinationTransportPort
1061 self.assertEqual(struct.pack("!H", dst_port), record[228])
1063 def verify_no_nat44_user(self):
1064 """ Verify that there is no NAT44 user """
1065 users = self.vapi.nat44_user_dump()
1066 self.assertEqual(len(users), 0)
1067 users = self.statistics.get_counter('/nat44/total-users')
1068 self.assertEqual(users[0][0], 0)
1069 sessions = self.statistics.get_counter('/nat44/total-sessions')
1070 self.assertEqual(sessions[0][0], 0)
1072 def verify_ipfix_max_entries_per_user(self, data, limit, src_addr):
1074 Verify IPFIX maximum entries per user exceeded event
1076 :param data: Decoded IPFIX data records
1077 :param limit: Number of maximum entries per user
1078 :param src_addr: IPv4 source address
1080 self.assertEqual(1, len(data))
1083 self.assertEqual(scapy.compat.orb(record[230]), 13)
1084 # natQuotaExceededEvent
1085 self.assertEqual(struct.pack("I", 3), record[466])
1087 self.assertEqual(struct.pack("I", limit), record[473])
1089 self.assertEqual(src_addr, record[8])
1091 def verify_syslog_apmap(self, data, is_add=True):
1092 message = data.decode('utf-8')
1094 message = SyslogMessage.parse(message)
1095 except ParseError as e:
1096 self.logger.error(e)
1099 self.assertEqual(message.severity, SyslogSeverity.info)
1100 self.assertEqual(message.appname, 'NAT')
1101 self.assertEqual(message.msgid, 'APMADD' if is_add else 'APMDEL')
1102 sd_params = message.sd.get('napmap')
1103 self.assertTrue(sd_params is not None)
1104 self.assertEqual(sd_params.get('IATYP'), 'IPv4')
1105 self.assertEqual(sd_params.get('ISADDR'), self.pg0.remote_ip4)
1106 self.assertEqual(sd_params.get('ISPORT'), "%d" % self.tcp_port_in)
1107 self.assertEqual(sd_params.get('XATYP'), 'IPv4')
1108 self.assertEqual(sd_params.get('XSADDR'), self.nat_addr)
1109 self.assertEqual(sd_params.get('XSPORT'), "%d" % self.tcp_port_out)
1110 self.assertEqual(sd_params.get('PROTO'), "%d" % IP_PROTOS.tcp)
1111 self.assertTrue(sd_params.get('SSUBIX') is not None)
1112 self.assertEqual(sd_params.get('SVLAN'), '0')
1114 def verify_syslog_sess(self, data, is_add=True, is_ip6=False):
1115 message = data.decode('utf-8')
1117 message = SyslogMessage.parse(message)
1118 except ParseError as e:
1119 self.logger.error(e)
1122 self.assertEqual(message.severity, SyslogSeverity.info)
1123 self.assertEqual(message.appname, 'NAT')
1124 self.assertEqual(message.msgid, 'SADD' if is_add else 'SDEL')
1125 sd_params = message.sd.get('nsess')
1126 self.assertTrue(sd_params is not None)
1128 self.assertEqual(sd_params.get('IATYP'), 'IPv6')
1129 self.assertEqual(sd_params.get('ISADDR'), self.pg0.remote_ip6)
1131 self.assertEqual(sd_params.get('IATYP'), 'IPv4')
1132 self.assertEqual(sd_params.get('ISADDR'), self.pg0.remote_ip4)
1133 self.assertTrue(sd_params.get('SSUBIX') is not None)
1134 self.assertEqual(sd_params.get('ISPORT'), "%d" % self.tcp_port_in)
1135 self.assertEqual(sd_params.get('XATYP'), 'IPv4')
1136 self.assertEqual(sd_params.get('XSADDR'), self.nat_addr)
1137 self.assertEqual(sd_params.get('XSPORT'), "%d" % self.tcp_port_out)
1138 self.assertEqual(sd_params.get('PROTO'), "%d" % IP_PROTOS.tcp)
1139 self.assertEqual(sd_params.get('SVLAN'), '0')
1140 self.assertEqual(sd_params.get('XDADDR'), self.pg1.remote_ip4)
1141 self.assertEqual(sd_params.get('XDPORT'),
1142 "%d" % self.tcp_external_port)
1144 def verify_mss_value(self, pkt, mss):
1146 Verify TCP MSS value
1151 if not pkt.haslayer(IP) or not pkt.haslayer(TCP):
1152 raise TypeError("Not a TCP/IP packet")
1154 for option in pkt[TCP].options:
1155 if option[0] == 'MSS':
1156 self.assertEqual(option[1], mss)
1157 self.assert_tcp_checksum_valid(pkt)
1160 def proto2layer(proto):
1161 if proto == IP_PROTOS.tcp:
1163 elif proto == IP_PROTOS.udp:
1165 elif proto == IP_PROTOS.icmp:
1168 raise Exception("Unsupported protocol")
1170 def frag_in_order(self, proto=IP_PROTOS.tcp, dont_translate=False):
1171 layer = self.proto2layer(proto)
1173 if proto == IP_PROTOS.tcp:
1174 data = b"A" * 4 + b"B" * 16 + b"C" * 3
1176 data = b"A" * 16 + b"B" * 16 + b"C" * 3
1177 self.port_in = random.randint(1025, 65535)
1179 reass = self.vapi.nat_reass_dump()
1180 reass_n_start = len(reass)
1183 pkts = self.create_stream_frag(self.pg0,
1184 self.pg1.remote_ip4,
1189 self.pg0.add_stream(pkts)
1190 self.pg_enable_capture(self.pg_interfaces)
1192 frags = self.pg1.get_capture(len(pkts))
1193 if not dont_translate:
1194 p = self.reass_frags_and_verify(frags,
1196 self.pg1.remote_ip4)
1198 p = self.reass_frags_and_verify(frags,
1199 self.pg0.remote_ip4,
1200 self.pg1.remote_ip4)
1201 if proto != IP_PROTOS.icmp:
1202 if not dont_translate:
1203 self.assertEqual(p[layer].dport, 20)
1204 self.assertNotEqual(p[layer].sport, self.port_in)
1206 self.assertEqual(p[layer].sport, self.port_in)
1208 if not dont_translate:
1209 self.assertNotEqual(p[layer].id, self.port_in)
1211 self.assertEqual(p[layer].id, self.port_in)
1212 self.assertEqual(data, p[Raw].load)
1215 if not dont_translate:
1216 dst_addr = self.nat_addr
1218 dst_addr = self.pg0.remote_ip4
1219 if proto != IP_PROTOS.icmp:
1221 dport = p[layer].sport
1225 pkts = self.create_stream_frag(self.pg1,
1232 self.pg1.add_stream(pkts)
1233 self.pg_enable_capture(self.pg_interfaces)
1235 frags = self.pg0.get_capture(len(pkts))
1236 p = self.reass_frags_and_verify(frags,
1237 self.pg1.remote_ip4,
1238 self.pg0.remote_ip4)
1239 if proto != IP_PROTOS.icmp:
1240 self.assertEqual(p[layer].sport, 20)
1241 self.assertEqual(p[layer].dport, self.port_in)
1243 self.assertEqual(p[layer].id, self.port_in)
1244 self.assertEqual(data, p[Raw].load)
1246 reass = self.vapi.nat_reass_dump()
1247 reass_n_end = len(reass)
1249 self.assertEqual(reass_n_end - reass_n_start, 2)
1251 def frag_in_order_in_plus_out(self, proto=IP_PROTOS.tcp):
1252 layer = self.proto2layer(proto)
1254 if proto == IP_PROTOS.tcp:
1255 data = b"A" * 4 + b"B" * 16 + b"C" * 3
1257 data = b"A" * 16 + b"B" * 16 + b"C" * 3
1258 self.port_in = random.randint(1025, 65535)
1261 reass = self.vapi.nat_reass_dump()
1262 reass_n_start = len(reass)
1265 pkts = self.create_stream_frag(self.pg0,
1266 self.server_out_addr,
1268 self.server_out_port,
1271 self.pg0.add_stream(pkts)
1272 self.pg_enable_capture(self.pg_interfaces)
1274 frags = self.pg1.get_capture(len(pkts))
1275 p = self.reass_frags_and_verify(frags,
1276 self.pg0.remote_ip4,
1277 self.server_in_addr)
1278 if proto != IP_PROTOS.icmp:
1279 self.assertEqual(p[layer].sport, self.port_in)
1280 self.assertEqual(p[layer].dport, self.server_in_port)
1282 self.assertEqual(p[layer].id, self.port_in)
1283 self.assertEqual(data, p[Raw].load)
1286 if proto != IP_PROTOS.icmp:
1287 pkts = self.create_stream_frag(self.pg1,
1288 self.pg0.remote_ip4,
1289 self.server_in_port,
1294 pkts = self.create_stream_frag(self.pg1,
1295 self.pg0.remote_ip4,
1301 self.pg1.add_stream(pkts)
1302 self.pg_enable_capture(self.pg_interfaces)
1304 frags = self.pg0.get_capture(len(pkts))
1305 p = self.reass_frags_and_verify(frags,
1306 self.server_out_addr,
1307 self.pg0.remote_ip4)
1308 if proto != IP_PROTOS.icmp:
1309 self.assertEqual(p[layer].sport, self.server_out_port)
1310 self.assertEqual(p[layer].dport, self.port_in)
1312 self.assertEqual(p[layer].id, self.port_in)
1313 self.assertEqual(data, p[Raw].load)
1315 reass = self.vapi.nat_reass_dump()
1316 reass_n_end = len(reass)
1318 self.assertEqual(reass_n_end - reass_n_start, 2)
1320 def reass_hairpinning(self, proto=IP_PROTOS.tcp):
1321 layer = self.proto2layer(proto)
1323 if proto == IP_PROTOS.tcp:
1324 data = b"A" * 4 + b"B" * 16 + b"C" * 3
1326 data = b"A" * 16 + b"B" * 16 + b"C" * 3
1328 # send packet from host to server
1329 pkts = self.create_stream_frag(self.pg0,
1332 self.server_out_port,
1335 self.pg0.add_stream(pkts)
1336 self.pg_enable_capture(self.pg_interfaces)
1338 frags = self.pg0.get_capture(len(pkts))
1339 p = self.reass_frags_and_verify(frags,
1342 if proto != IP_PROTOS.icmp:
1343 self.assertNotEqual(p[layer].sport, self.host_in_port)
1344 self.assertEqual(p[layer].dport, self.server_in_port)
1346 self.assertNotEqual(p[layer].id, self.host_in_port)
1347 self.assertEqual(data, p[Raw].load)
1349 def frag_out_of_order(self, proto=IP_PROTOS.tcp, dont_translate=False):
1350 layer = self.proto2layer(proto)
1352 if proto == IP_PROTOS.tcp:
1353 data = b"A" * 4 + b"B" * 16 + b"C" * 3
1355 data = b"A" * 16 + b"B" * 16 + b"C" * 3
1356 self.port_in = random.randint(1025, 65535)
1360 pkts = self.create_stream_frag(self.pg0,
1361 self.pg1.remote_ip4,
1367 self.pg0.add_stream(pkts)
1368 self.pg_enable_capture(self.pg_interfaces)
1370 frags = self.pg1.get_capture(len(pkts))
1371 if not dont_translate:
1372 p = self.reass_frags_and_verify(frags,
1374 self.pg1.remote_ip4)
1376 p = self.reass_frags_and_verify(frags,
1377 self.pg0.remote_ip4,
1378 self.pg1.remote_ip4)
1379 if proto != IP_PROTOS.icmp:
1380 if not dont_translate:
1381 self.assertEqual(p[layer].dport, 20)
1382 self.assertNotEqual(p[layer].sport, self.port_in)
1384 self.assertEqual(p[layer].sport, self.port_in)
1386 if not dont_translate:
1387 self.assertNotEqual(p[layer].id, self.port_in)
1389 self.assertEqual(p[layer].id, self.port_in)
1390 self.assertEqual(data, p[Raw].load)
1393 if not dont_translate:
1394 dst_addr = self.nat_addr
1396 dst_addr = self.pg0.remote_ip4
1397 if proto != IP_PROTOS.icmp:
1399 dport = p[layer].sport
1403 pkts = self.create_stream_frag(self.pg1,
1411 self.pg1.add_stream(pkts)
1412 self.pg_enable_capture(self.pg_interfaces)
1414 frags = self.pg0.get_capture(len(pkts))
1415 p = self.reass_frags_and_verify(frags,
1416 self.pg1.remote_ip4,
1417 self.pg0.remote_ip4)
1418 if proto != IP_PROTOS.icmp:
1419 self.assertEqual(p[layer].sport, 20)
1420 self.assertEqual(p[layer].dport, self.port_in)
1422 self.assertEqual(p[layer].id, self.port_in)
1423 self.assertEqual(data, p[Raw].load)
1425 def frag_out_of_order_in_plus_out(self, proto=IP_PROTOS.tcp):
1426 layer = self.proto2layer(proto)
1428 if proto == IP_PROTOS.tcp:
1429 data = b"A" * 4 + b"B" * 16 + b"C" * 3
1431 data = b"A" * 16 + b"B" * 16 + b"C" * 3
1432 self.port_in = random.randint(1025, 65535)
1436 pkts = self.create_stream_frag(self.pg0,
1437 self.server_out_addr,
1439 self.server_out_port,
1443 self.pg0.add_stream(pkts)
1444 self.pg_enable_capture(self.pg_interfaces)
1446 frags = self.pg1.get_capture(len(pkts))
1447 p = self.reass_frags_and_verify(frags,
1448 self.pg0.remote_ip4,
1449 self.server_in_addr)
1450 if proto != IP_PROTOS.icmp:
1451 self.assertEqual(p[layer].dport, self.server_in_port)
1452 self.assertEqual(p[layer].sport, self.port_in)
1453 self.assertEqual(p[layer].dport, self.server_in_port)
1455 self.assertEqual(p[layer].id, self.port_in)
1456 self.assertEqual(data, p[Raw].load)
1459 if proto != IP_PROTOS.icmp:
1460 pkts = self.create_stream_frag(self.pg1,
1461 self.pg0.remote_ip4,
1462 self.server_in_port,
1467 pkts = self.create_stream_frag(self.pg1,
1468 self.pg0.remote_ip4,
1475 self.pg1.add_stream(pkts)
1476 self.pg_enable_capture(self.pg_interfaces)
1478 frags = self.pg0.get_capture(len(pkts))
1479 p = self.reass_frags_and_verify(frags,
1480 self.server_out_addr,
1481 self.pg0.remote_ip4)
1482 if proto != IP_PROTOS.icmp:
1483 self.assertEqual(p[layer].sport, self.server_out_port)
1484 self.assertEqual(p[layer].dport, self.port_in)
1486 self.assertEqual(p[layer].id, self.port_in)
1487 self.assertEqual(data, p[Raw].load)
1490 class TestNAT44(MethodHolder):
1491 """ NAT44 Test Cases """
1494 def setUpClass(cls):
1495 super(TestNAT44, cls).setUpClass()
1496 cls.vapi.cli("set log class nat level debug")
1499 cls.tcp_port_in = 6303
1500 cls.tcp_port_out = 6303
1501 cls.udp_port_in = 6304
1502 cls.udp_port_out = 6304
1503 cls.icmp_id_in = 6305
1504 cls.icmp_id_out = 6305
1505 cls.nat_addr = '10.0.0.3'
1506 cls.nat_addr_n = socket.inet_pton(socket.AF_INET, cls.nat_addr)
1507 cls.ipfix_src_port = 4739
1508 cls.ipfix_domain_id = 1
1509 cls.tcp_external_port = 80
1510 cls.udp_external_port = 69
1512 cls.create_pg_interfaces(range(10))
1513 cls.interfaces = list(cls.pg_interfaces[0:4])
1515 for i in cls.interfaces:
1520 cls.pg0.generate_remote_hosts(3)
1521 cls.pg0.configure_ipv4_neighbors()
1523 cls.pg1.generate_remote_hosts(1)
1524 cls.pg1.configure_ipv4_neighbors()
1526 cls.overlapping_interfaces = list(list(cls.pg_interfaces[4:7]))
1527 cls.vapi.ip_table_add_del(is_add=1, table_id=10)
1528 cls.vapi.ip_table_add_del(is_add=1, table_id=20)
1530 cls.pg4._local_ip4 = VppIpPrefix("172.16.255.1",
1531 cls.pg4.local_ip4_prefix.len)
1532 cls.pg4._remote_hosts[0]._ip4 = "172.16.255.2"
1533 cls.pg4.set_table_ip4(10)
1534 cls.pg5._local_ip4 = VppIpPrefix("172.17.255.3",
1535 cls.pg5.local_ip4_prefix.len)
1536 cls.pg5._remote_hosts[0]._ip4 = "172.17.255.4"
1537 cls.pg5.set_table_ip4(10)
1538 cls.pg6._local_ip4 = VppIpPrefix("172.16.255.1",
1539 cls.pg6.local_ip4_prefix.len)
1540 cls.pg6._remote_hosts[0]._ip4 = "172.16.255.2"
1541 cls.pg6.set_table_ip4(20)
1542 for i in cls.overlapping_interfaces:
1550 cls.pg9.generate_remote_hosts(2)
1551 cls.pg9.config_ip4()
1552 cls.vapi.sw_interface_add_del_address(
1553 sw_if_index=cls.pg9.sw_if_index,
1554 prefix=VppIpPrefix("10.0.0.1", 24).encode())
1557 cls.pg9.resolve_arp()
1558 cls.pg9._remote_hosts[1]._ip4 = cls.pg9._remote_hosts[0]._ip4
1559 cls.pg4._remote_ip4 = cls.pg9._remote_hosts[0]._ip4 = "10.0.0.2"
1560 cls.pg9.resolve_arp()
1563 super(TestNAT44, cls).tearDownClass()
1566 def test_dynamic(self):
1567 """ NAT44 dynamic translation test """
1568 self.nat44_add_address(self.nat_addr)
1569 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
1570 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
1574 tcpn = self.statistics.get_counter(
1575 '/err/nat44-in2out-slowpath/TCP packets')
1576 udpn = self.statistics.get_counter(
1577 '/err/nat44-in2out-slowpath/UDP packets')
1578 icmpn = self.statistics.get_counter(
1579 '/err/nat44-in2out-slowpath/ICMP packets')
1580 totaln = self.statistics.get_counter(
1581 '/err/nat44-in2out-slowpath/good in2out packets processed')
1583 pkts = self.create_stream_in(self.pg0, self.pg1)
1584 self.pg0.add_stream(pkts)
1585 self.pg_enable_capture(self.pg_interfaces)
1587 capture = self.pg1.get_capture(len(pkts))
1588 self.verify_capture_out(capture)
1590 err = self.statistics.get_counter(
1591 '/err/nat44-in2out-slowpath/TCP packets')
1592 self.assertEqual(err - tcpn, 1)
1593 err = self.statistics.get_counter(
1594 '/err/nat44-in2out-slowpath/UDP packets')
1595 self.assertEqual(err - udpn, 1)
1596 err = self.statistics.get_counter(
1597 '/err/nat44-in2out-slowpath/ICMP packets')
1598 self.assertEqual(err - icmpn, 1)
1599 err = self.statistics.get_counter(
1600 '/err/nat44-in2out-slowpath/good in2out packets processed')
1601 self.assertEqual(err - totaln, 3)
1604 tcpn = self.statistics.get_counter('/err/nat44-out2in/TCP packets')
1605 udpn = self.statistics.get_counter('/err/nat44-out2in/UDP packets')
1606 icmpn = self.statistics.get_counter('/err/nat44-out2in/ICMP packets')
1607 totaln = self.statistics.get_counter(
1608 '/err/nat44-out2in/good out2in packets processed')
1610 pkts = self.create_stream_out(self.pg1)
1611 self.pg1.add_stream(pkts)
1612 self.pg_enable_capture(self.pg_interfaces)
1614 capture = self.pg0.get_capture(len(pkts))
1615 self.verify_capture_in(capture, self.pg0)
1617 err = self.statistics.get_counter('/err/nat44-out2in/TCP packets')
1618 self.assertEqual(err - tcpn, 1)
1619 err = self.statistics.get_counter('/err/nat44-out2in/UDP packets')
1620 self.assertEqual(err - udpn, 1)
1621 err = self.statistics.get_counter('/err/nat44-out2in/ICMP packets')
1622 self.assertEqual(err - icmpn, 1)
1623 err = self.statistics.get_counter(
1624 '/err/nat44-out2in/good out2in packets processed')
1625 self.assertEqual(err - totaln, 3)
1627 users = self.statistics.get_counter('/nat44/total-users')
1628 self.assertEqual(users[0][0], 1)
1629 sessions = self.statistics.get_counter('/nat44/total-sessions')
1630 self.assertEqual(sessions[0][0], 3)
1632 def test_dynamic_icmp_errors_in2out_ttl_1(self):
1633 """ NAT44 handling of client packets with TTL=1 """
1635 self.nat44_add_address(self.nat_addr)
1636 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
1637 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
1640 # Client side - generate traffic
1641 pkts = self.create_stream_in(self.pg0, self.pg1, ttl=1)
1642 self.pg0.add_stream(pkts)
1643 self.pg_enable_capture(self.pg_interfaces)
1646 # Client side - verify ICMP type 11 packets
1647 capture = self.pg0.get_capture(len(pkts))
1648 self.verify_capture_in_with_icmp_errors(capture, self.pg0)
1650 def test_dynamic_icmp_errors_out2in_ttl_1(self):
1651 """ NAT44 handling of server packets with TTL=1 """
1653 self.nat44_add_address(self.nat_addr)
1654 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
1655 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
1658 # Client side - create sessions
1659 pkts = self.create_stream_in(self.pg0, self.pg1)
1660 self.pg0.add_stream(pkts)
1661 self.pg_enable_capture(self.pg_interfaces)
1664 # Server side - generate traffic
1665 capture = self.pg1.get_capture(len(pkts))
1666 self.verify_capture_out(capture)
1667 pkts = self.create_stream_out(self.pg1, ttl=1)
1668 self.pg1.add_stream(pkts)
1669 self.pg_enable_capture(self.pg_interfaces)
1672 # Server side - verify ICMP type 11 packets
1673 capture = self.pg1.get_capture(len(pkts))
1674 self.verify_capture_out_with_icmp_errors(capture,
1675 src_ip=self.pg1.local_ip4)
1677 def test_dynamic_icmp_errors_in2out_ttl_2(self):
1678 """ NAT44 handling of error responses to client packets with TTL=2 """
1680 self.nat44_add_address(self.nat_addr)
1681 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
1682 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
1685 # Client side - generate traffic
1686 pkts = self.create_stream_in(self.pg0, self.pg1, ttl=2)
1687 self.pg0.add_stream(pkts)
1688 self.pg_enable_capture(self.pg_interfaces)
1691 # Server side - simulate ICMP type 11 response
1692 capture = self.pg1.get_capture(len(pkts))
1693 pkts = [Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
1694 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
1695 ICMP(type=11) / packet[IP] for packet in capture]
1696 self.pg1.add_stream(pkts)
1697 self.pg_enable_capture(self.pg_interfaces)
1700 # Client side - verify ICMP type 11 packets
1701 capture = self.pg0.get_capture(len(pkts))
1702 self.verify_capture_in_with_icmp_errors(capture, self.pg0)
1704 def test_dynamic_icmp_errors_out2in_ttl_2(self):
1705 """ NAT44 handling of error responses to server packets with TTL=2 """
1707 self.nat44_add_address(self.nat_addr)
1708 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
1709 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
1712 # Client side - create sessions
1713 pkts = self.create_stream_in(self.pg0, self.pg1)
1714 self.pg0.add_stream(pkts)
1715 self.pg_enable_capture(self.pg_interfaces)
1718 # Server side - generate traffic
1719 capture = self.pg1.get_capture(len(pkts))
1720 self.verify_capture_out(capture)
1721 pkts = self.create_stream_out(self.pg1, ttl=2)
1722 self.pg1.add_stream(pkts)
1723 self.pg_enable_capture(self.pg_interfaces)
1726 # Client side - simulate ICMP type 11 response
1727 capture = self.pg0.get_capture(len(pkts))
1728 pkts = [Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
1729 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
1730 ICMP(type=11) / packet[IP] for packet in capture]
1731 self.pg0.add_stream(pkts)
1732 self.pg_enable_capture(self.pg_interfaces)
1735 # Server side - verify ICMP type 11 packets
1736 capture = self.pg1.get_capture(len(pkts))
1737 self.verify_capture_out_with_icmp_errors(capture)
1739 def test_ping_out_interface_from_outside(self):
1740 """ Ping NAT44 out interface from outside network """
1742 self.nat44_add_address(self.nat_addr)
1743 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
1744 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
1747 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
1748 IP(src=self.pg1.remote_ip4, dst=self.pg1.local_ip4) /
1749 ICMP(id=self.icmp_id_out, type='echo-request'))
1751 self.pg1.add_stream(pkts)
1752 self.pg_enable_capture(self.pg_interfaces)
1754 capture = self.pg1.get_capture(len(pkts))
1757 self.assertEqual(packet[IP].src, self.pg1.local_ip4)
1758 self.assertEqual(packet[IP].dst, self.pg1.remote_ip4)
1759 self.assertEqual(packet[ICMP].id, self.icmp_id_in)
1760 self.assertEqual(packet[ICMP].type, 0) # echo reply
1762 self.logger.error(ppp("Unexpected or invalid packet "
1763 "(outside network):", packet))
1766 def test_ping_internal_host_from_outside(self):
1767 """ Ping internal host from outside network """
1769 self.nat44_add_static_mapping(self.pg0.remote_ip4, self.nat_addr)
1770 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
1771 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
1775 pkt = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
1776 IP(src=self.pg1.remote_ip4, dst=self.nat_addr, ttl=64) /
1777 ICMP(id=self.icmp_id_out, type='echo-request'))
1778 self.pg1.add_stream(pkt)
1779 self.pg_enable_capture(self.pg_interfaces)
1781 capture = self.pg0.get_capture(1)
1782 self.verify_capture_in(capture, self.pg0)
1783 self.assert_equal(capture[0][IP].proto, IP_PROTOS.icmp)
1786 pkt = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
1787 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4, ttl=64) /
1788 ICMP(id=self.icmp_id_in, type='echo-reply'))
1789 self.pg0.add_stream(pkt)
1790 self.pg_enable_capture(self.pg_interfaces)
1792 capture = self.pg1.get_capture(1)
1793 self.verify_capture_out(capture, same_port=True)
1794 self.assert_equal(capture[0][IP].proto, IP_PROTOS.icmp)
1796 def test_forwarding(self):
1797 """ NAT44 forwarding test """
1799 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
1800 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
1802 self.vapi.nat44_forwarding_enable_disable(1)
1804 real_ip = self.pg0.remote_ip4n
1805 alias_ip = self.nat_addr_n
1806 self.vapi.nat44_add_del_static_mapping(local_ip=real_ip,
1807 external_ip=alias_ip)
1810 # static mapping match
1812 pkts = self.create_stream_out(self.pg1)
1813 self.pg1.add_stream(pkts)
1814 self.pg_enable_capture(self.pg_interfaces)
1816 capture = self.pg0.get_capture(len(pkts))
1817 self.verify_capture_in(capture, self.pg0)
1819 pkts = self.create_stream_in(self.pg0, self.pg1)
1820 self.pg0.add_stream(pkts)
1821 self.pg_enable_capture(self.pg_interfaces)
1823 capture = self.pg1.get_capture(len(pkts))
1824 self.verify_capture_out(capture, same_port=True)
1826 # no static mapping match
1828 host0 = self.pg0.remote_hosts[0]
1829 self.pg0.remote_hosts[0] = self.pg0.remote_hosts[1]
1831 pkts = self.create_stream_out(self.pg1,
1832 dst_ip=self.pg0.remote_ip4,
1833 use_inside_ports=True)
1834 self.pg1.add_stream(pkts)
1835 self.pg_enable_capture(self.pg_interfaces)
1837 capture = self.pg0.get_capture(len(pkts))
1838 self.verify_capture_in(capture, self.pg0)
1840 pkts = self.create_stream_in(self.pg0, self.pg1)
1841 self.pg0.add_stream(pkts)
1842 self.pg_enable_capture(self.pg_interfaces)
1844 capture = self.pg1.get_capture(len(pkts))
1845 self.verify_capture_out(capture, nat_ip=self.pg0.remote_ip4,
1848 self.pg0.remote_hosts[0] = host0
1851 self.vapi.nat44_forwarding_enable_disable(0)
1852 self.vapi.nat44_add_del_static_mapping(local_ip=real_ip,
1853 external_ip=alias_ip,
1856 def test_static_in(self):
1857 """ 1:1 NAT initialized from inside network """
1859 nat_ip = "10.0.0.10"
1860 self.tcp_port_out = 6303
1861 self.udp_port_out = 6304
1862 self.icmp_id_out = 6305
1864 self.nat44_add_static_mapping(self.pg0.remote_ip4, nat_ip)
1865 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
1866 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
1868 sm = self.vapi.nat44_static_mapping_dump()
1869 self.assertEqual(len(sm), 1)
1870 self.assertEqual((sm[0].tag).split(b'\0', 1)[0], b'')
1871 self.assertEqual(sm[0].protocol, 0)
1872 self.assertEqual(sm[0].local_port, 0)
1873 self.assertEqual(sm[0].external_port, 0)
1876 pkts = self.create_stream_in(self.pg0, self.pg1)
1877 self.pg0.add_stream(pkts)
1878 self.pg_enable_capture(self.pg_interfaces)
1880 capture = self.pg1.get_capture(len(pkts))
1881 self.verify_capture_out(capture, nat_ip, True)
1884 pkts = self.create_stream_out(self.pg1, nat_ip)
1885 self.pg1.add_stream(pkts)
1886 self.pg_enable_capture(self.pg_interfaces)
1888 capture = self.pg0.get_capture(len(pkts))
1889 self.verify_capture_in(capture, self.pg0)
1891 def test_static_out(self):
1892 """ 1:1 NAT initialized from outside network """
1894 nat_ip = "10.0.0.20"
1895 self.tcp_port_out = 6303
1896 self.udp_port_out = 6304
1897 self.icmp_id_out = 6305
1900 self.nat44_add_static_mapping(self.pg0.remote_ip4, nat_ip, tag=tag)
1901 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
1902 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
1904 sm = self.vapi.nat44_static_mapping_dump()
1905 self.assertEqual(len(sm), 1)
1906 self.assertEqual((sm[0].tag).split(b'\0', 1)[0], tag)
1909 pkts = self.create_stream_out(self.pg1, nat_ip)
1910 self.pg1.add_stream(pkts)
1911 self.pg_enable_capture(self.pg_interfaces)
1913 capture = self.pg0.get_capture(len(pkts))
1914 self.verify_capture_in(capture, self.pg0)
1917 pkts = self.create_stream_in(self.pg0, self.pg1)
1918 self.pg0.add_stream(pkts)
1919 self.pg_enable_capture(self.pg_interfaces)
1921 capture = self.pg1.get_capture(len(pkts))
1922 self.verify_capture_out(capture, nat_ip, True)
1924 def test_static_with_port_in(self):
1925 """ 1:1 NAPT initialized from inside network """
1927 self.tcp_port_out = 3606
1928 self.udp_port_out = 3607
1929 self.icmp_id_out = 3608
1931 self.nat44_add_address(self.nat_addr)
1932 self.nat44_add_static_mapping(self.pg0.remote_ip4, self.nat_addr,
1933 self.tcp_port_in, self.tcp_port_out,
1934 proto=IP_PROTOS.tcp)
1935 self.nat44_add_static_mapping(self.pg0.remote_ip4, self.nat_addr,
1936 self.udp_port_in, self.udp_port_out,
1937 proto=IP_PROTOS.udp)
1938 self.nat44_add_static_mapping(self.pg0.remote_ip4, self.nat_addr,
1939 self.icmp_id_in, self.icmp_id_out,
1940 proto=IP_PROTOS.icmp)
1941 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
1942 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
1946 pkts = self.create_stream_in(self.pg0, self.pg1)
1947 self.pg0.add_stream(pkts)
1948 self.pg_enable_capture(self.pg_interfaces)
1950 capture = self.pg1.get_capture(len(pkts))
1951 self.verify_capture_out(capture)
1954 pkts = self.create_stream_out(self.pg1)
1955 self.pg1.add_stream(pkts)
1956 self.pg_enable_capture(self.pg_interfaces)
1958 capture = self.pg0.get_capture(len(pkts))
1959 self.verify_capture_in(capture, self.pg0)
1961 def test_static_with_port_out(self):
1962 """ 1:1 NAPT initialized from outside network """
1964 self.tcp_port_out = 30606
1965 self.udp_port_out = 30607
1966 self.icmp_id_out = 30608
1968 self.nat44_add_address(self.nat_addr)
1969 self.nat44_add_static_mapping(self.pg0.remote_ip4, self.nat_addr,
1970 self.tcp_port_in, self.tcp_port_out,
1971 proto=IP_PROTOS.tcp)
1972 self.nat44_add_static_mapping(self.pg0.remote_ip4, self.nat_addr,
1973 self.udp_port_in, self.udp_port_out,
1974 proto=IP_PROTOS.udp)
1975 self.nat44_add_static_mapping(self.pg0.remote_ip4, self.nat_addr,
1976 self.icmp_id_in, self.icmp_id_out,
1977 proto=IP_PROTOS.icmp)
1978 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
1979 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
1983 pkts = self.create_stream_out(self.pg1)
1984 self.pg1.add_stream(pkts)
1985 self.pg_enable_capture(self.pg_interfaces)
1987 capture = self.pg0.get_capture(len(pkts))
1988 self.verify_capture_in(capture, self.pg0)
1991 pkts = self.create_stream_in(self.pg0, self.pg1)
1992 self.pg0.add_stream(pkts)
1993 self.pg_enable_capture(self.pg_interfaces)
1995 capture = self.pg1.get_capture(len(pkts))
1996 self.verify_capture_out(capture)
1998 def test_static_vrf_aware(self):
1999 """ 1:1 NAT VRF awareness """
2001 nat_ip1 = "10.0.0.30"
2002 nat_ip2 = "10.0.0.40"
2003 self.tcp_port_out = 6303
2004 self.udp_port_out = 6304
2005 self.icmp_id_out = 6305
2007 self.nat44_add_static_mapping(self.pg4.remote_ip4, nat_ip1,
2009 self.nat44_add_static_mapping(self.pg0.remote_ip4, nat_ip2,
2011 self.vapi.nat44_interface_add_del_feature(self.pg3.sw_if_index,
2013 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
2014 self.vapi.nat44_interface_add_del_feature(self.pg4.sw_if_index)
2016 # inside interface VRF match NAT44 static mapping VRF
2017 pkts = self.create_stream_in(self.pg4, self.pg3)
2018 self.pg4.add_stream(pkts)
2019 self.pg_enable_capture(self.pg_interfaces)
2021 capture = self.pg3.get_capture(len(pkts))
2022 self.verify_capture_out(capture, nat_ip1, True)
2024 # inside interface VRF don't match NAT44 static mapping VRF (packets
2026 pkts = self.create_stream_in(self.pg0, self.pg3)
2027 self.pg0.add_stream(pkts)
2028 self.pg_enable_capture(self.pg_interfaces)
2030 self.pg3.assert_nothing_captured()
2032 def test_dynamic_to_static(self):
2033 """ Switch from dynamic translation to 1:1NAT """
2034 nat_ip = "10.0.0.10"
2035 self.tcp_port_out = 6303
2036 self.udp_port_out = 6304
2037 self.icmp_id_out = 6305
2039 self.nat44_add_address(self.nat_addr)
2040 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
2041 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
2045 pkts = self.create_stream_in(self.pg0, self.pg1)
2046 self.pg0.add_stream(pkts)
2047 self.pg_enable_capture(self.pg_interfaces)
2049 capture = self.pg1.get_capture(len(pkts))
2050 self.verify_capture_out(capture)
2053 self.nat44_add_static_mapping(self.pg0.remote_ip4, nat_ip)
2054 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4n, 0)
2055 self.assertEqual(len(sessions), 0)
2056 pkts = self.create_stream_in(self.pg0, self.pg1)
2057 self.pg0.add_stream(pkts)
2058 self.pg_enable_capture(self.pg_interfaces)
2060 capture = self.pg1.get_capture(len(pkts))
2061 self.verify_capture_out(capture, nat_ip, True)
2063 def test_identity_nat(self):
2064 """ Identity NAT """
2066 self.vapi.nat44_add_del_identity_mapping(ip=self.pg0.remote_ip4n)
2067 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
2068 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
2071 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
2072 IP(src=self.pg1.remote_ip4, dst=self.pg0.remote_ip4) /
2073 TCP(sport=12345, dport=56789))
2074 self.pg1.add_stream(p)
2075 self.pg_enable_capture(self.pg_interfaces)
2077 capture = self.pg0.get_capture(1)
2082 self.assertEqual(ip.dst, self.pg0.remote_ip4)
2083 self.assertEqual(ip.src, self.pg1.remote_ip4)
2084 self.assertEqual(tcp.dport, 56789)
2085 self.assertEqual(tcp.sport, 12345)
2086 self.assert_packet_checksums_valid(p)
2088 self.logger.error(ppp("Unexpected or invalid packet:", p))
2091 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4n, 0)
2092 self.assertEqual(len(sessions), 0)
2093 self.vapi.nat44_add_del_identity_mapping(ip=self.pg0.remote_ip4n,
2095 identity_mappings = self.vapi.nat44_identity_mapping_dump()
2096 self.assertEqual(len(identity_mappings), 2)
2098 def test_multiple_inside_interfaces(self):
2099 """ NAT44 multiple non-overlapping address space inside interfaces """
2101 self.nat44_add_address(self.nat_addr)
2102 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
2103 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index)
2104 self.vapi.nat44_interface_add_del_feature(self.pg3.sw_if_index,
2107 # between two NAT44 inside interfaces (no translation)
2108 pkts = self.create_stream_in(self.pg0, self.pg1)
2109 self.pg0.add_stream(pkts)
2110 self.pg_enable_capture(self.pg_interfaces)
2112 capture = self.pg1.get_capture(len(pkts))
2113 self.verify_capture_no_translation(capture, self.pg0, self.pg1)
2115 # from NAT44 inside to interface without NAT44 feature (no translation)
2116 pkts = self.create_stream_in(self.pg0, self.pg2)
2117 self.pg0.add_stream(pkts)
2118 self.pg_enable_capture(self.pg_interfaces)
2120 capture = self.pg2.get_capture(len(pkts))
2121 self.verify_capture_no_translation(capture, self.pg0, self.pg2)
2123 # in2out 1st interface
2124 pkts = self.create_stream_in(self.pg0, self.pg3)
2125 self.pg0.add_stream(pkts)
2126 self.pg_enable_capture(self.pg_interfaces)
2128 capture = self.pg3.get_capture(len(pkts))
2129 self.verify_capture_out(capture)
2131 # out2in 1st interface
2132 pkts = self.create_stream_out(self.pg3)
2133 self.pg3.add_stream(pkts)
2134 self.pg_enable_capture(self.pg_interfaces)
2136 capture = self.pg0.get_capture(len(pkts))
2137 self.verify_capture_in(capture, self.pg0)
2139 # in2out 2nd interface
2140 pkts = self.create_stream_in(self.pg1, self.pg3)
2141 self.pg1.add_stream(pkts)
2142 self.pg_enable_capture(self.pg_interfaces)
2144 capture = self.pg3.get_capture(len(pkts))
2145 self.verify_capture_out(capture)
2147 # out2in 2nd interface
2148 pkts = self.create_stream_out(self.pg3)
2149 self.pg3.add_stream(pkts)
2150 self.pg_enable_capture(self.pg_interfaces)
2152 capture = self.pg1.get_capture(len(pkts))
2153 self.verify_capture_in(capture, self.pg1)
2155 def test_inside_overlapping_interfaces(self):
2156 """ NAT44 multiple inside interfaces with overlapping address space """
2158 static_nat_ip = "10.0.0.10"
2159 self.nat44_add_address(self.nat_addr)
2160 self.vapi.nat44_interface_add_del_feature(self.pg3.sw_if_index,
2162 self.vapi.nat44_interface_add_del_feature(self.pg4.sw_if_index)
2163 self.vapi.nat44_interface_add_del_feature(self.pg5.sw_if_index)
2164 self.vapi.nat44_interface_add_del_feature(self.pg6.sw_if_index)
2165 self.nat44_add_static_mapping(self.pg6.remote_ip4, static_nat_ip,
2168 # between NAT44 inside interfaces with same VRF (no translation)
2169 pkts = self.create_stream_in(self.pg4, self.pg5)
2170 self.pg4.add_stream(pkts)
2171 self.pg_enable_capture(self.pg_interfaces)
2173 capture = self.pg5.get_capture(len(pkts))
2174 self.verify_capture_no_translation(capture, self.pg4, self.pg5)
2176 # between NAT44 inside interfaces with different VRF (hairpinning)
2177 p = (Ether(src=self.pg4.remote_mac, dst=self.pg4.local_mac) /
2178 IP(src=self.pg4.remote_ip4, dst=static_nat_ip) /
2179 TCP(sport=1234, dport=5678))
2180 self.pg4.add_stream(p)
2181 self.pg_enable_capture(self.pg_interfaces)
2183 capture = self.pg6.get_capture(1)
2188 self.assertEqual(ip.src, self.nat_addr)
2189 self.assertEqual(ip.dst, self.pg6.remote_ip4)
2190 self.assertNotEqual(tcp.sport, 1234)
2191 self.assertEqual(tcp.dport, 5678)
2193 self.logger.error(ppp("Unexpected or invalid packet:", p))
2196 # in2out 1st interface
2197 pkts = self.create_stream_in(self.pg4, self.pg3)
2198 self.pg4.add_stream(pkts)
2199 self.pg_enable_capture(self.pg_interfaces)
2201 capture = self.pg3.get_capture(len(pkts))
2202 self.verify_capture_out(capture)
2204 # out2in 1st interface
2205 pkts = self.create_stream_out(self.pg3)
2206 self.pg3.add_stream(pkts)
2207 self.pg_enable_capture(self.pg_interfaces)
2209 capture = self.pg4.get_capture(len(pkts))
2210 self.verify_capture_in(capture, self.pg4)
2212 # in2out 2nd interface
2213 pkts = self.create_stream_in(self.pg5, self.pg3)
2214 self.pg5.add_stream(pkts)
2215 self.pg_enable_capture(self.pg_interfaces)
2217 capture = self.pg3.get_capture(len(pkts))
2218 self.verify_capture_out(capture)
2220 # out2in 2nd interface
2221 pkts = self.create_stream_out(self.pg3)
2222 self.pg3.add_stream(pkts)
2223 self.pg_enable_capture(self.pg_interfaces)
2225 capture = self.pg5.get_capture(len(pkts))
2226 self.verify_capture_in(capture, self.pg5)
2229 addresses = self.vapi.nat44_address_dump()
2230 self.assertEqual(len(addresses), 1)
2231 sessions = self.vapi.nat44_user_session_dump(self.pg5.remote_ip4n, 10)
2232 self.assertEqual(len(sessions), 3)
2233 for session in sessions:
2234 self.assertFalse(session.is_static)
2235 self.assertEqual(session.inside_ip_address[0:4],
2236 self.pg5.remote_ip4n)
2237 self.assertEqual(session.outside_ip_address,
2238 addresses[0].ip_address)
2239 self.assertEqual(sessions[0].protocol, IP_PROTOS.tcp)
2240 self.assertEqual(sessions[1].protocol, IP_PROTOS.udp)
2241 self.assertEqual(sessions[2].protocol, IP_PROTOS.icmp)
2242 self.assertEqual(sessions[0].inside_port, self.tcp_port_in)
2243 self.assertEqual(sessions[1].inside_port, self.udp_port_in)
2244 self.assertEqual(sessions[2].inside_port, self.icmp_id_in)
2245 self.assertEqual(sessions[0].outside_port, self.tcp_port_out)
2246 self.assertEqual(sessions[1].outside_port, self.udp_port_out)
2247 self.assertEqual(sessions[2].outside_port, self.icmp_id_out)
2249 # in2out 3rd interface
2250 pkts = self.create_stream_in(self.pg6, self.pg3)
2251 self.pg6.add_stream(pkts)
2252 self.pg_enable_capture(self.pg_interfaces)
2254 capture = self.pg3.get_capture(len(pkts))
2255 self.verify_capture_out(capture, static_nat_ip, True)
2257 # out2in 3rd interface
2258 pkts = self.create_stream_out(self.pg3, static_nat_ip)
2259 self.pg3.add_stream(pkts)
2260 self.pg_enable_capture(self.pg_interfaces)
2262 capture = self.pg6.get_capture(len(pkts))
2263 self.verify_capture_in(capture, self.pg6)
2265 # general user and session dump verifications
2266 users = self.vapi.nat44_user_dump()
2267 self.assertGreaterEqual(len(users), 3)
2268 addresses = self.vapi.nat44_address_dump()
2269 self.assertEqual(len(addresses), 1)
2271 sessions = self.vapi.nat44_user_session_dump(user.ip_address,
2273 for session in sessions:
2274 self.assertEqual(user.ip_address, session.inside_ip_address)
2275 self.assertTrue(session.total_bytes > session.total_pkts > 0)
2276 self.assertTrue(session.protocol in
2277 [IP_PROTOS.tcp, IP_PROTOS.udp,
2279 self.assertFalse(session.ext_host_valid)
2282 sessions = self.vapi.nat44_user_session_dump(self.pg4.remote_ip4n, 10)
2283 self.assertGreaterEqual(len(sessions), 4)
2284 for session in sessions:
2285 self.assertFalse(session.is_static)
2286 self.assertEqual(session.inside_ip_address[0:4],
2287 self.pg4.remote_ip4n)
2288 self.assertEqual(session.outside_ip_address,
2289 addresses[0].ip_address)
2292 sessions = self.vapi.nat44_user_session_dump(self.pg6.remote_ip4n, 20)
2293 self.assertGreaterEqual(len(sessions), 3)
2294 for session in sessions:
2295 self.assertTrue(session.is_static)
2296 self.assertEqual(session.inside_ip_address[0:4],
2297 self.pg6.remote_ip4n)
2298 self.assertEqual(session.outside_ip_address,
2299 socket.inet_pton(socket.AF_INET, static_nat_ip))
2300 self.assertTrue(session.inside_port in
2301 [self.tcp_port_in, self.udp_port_in,
2304 def test_hairpinning(self):
2305 """ NAT44 hairpinning - 1:1 NAPT """
2307 host = self.pg0.remote_hosts[0]
2308 server = self.pg0.remote_hosts[1]
2311 server_in_port = 5678
2312 server_out_port = 8765
2314 self.nat44_add_address(self.nat_addr)
2315 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
2316 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
2318 # add static mapping for server
2319 self.nat44_add_static_mapping(server.ip4, self.nat_addr,
2320 server_in_port, server_out_port,
2321 proto=IP_PROTOS.tcp)
2323 # send packet from host to server
2324 p = (Ether(src=host.mac, dst=self.pg0.local_mac) /
2325 IP(src=host.ip4, dst=self.nat_addr) /
2326 TCP(sport=host_in_port, dport=server_out_port))
2327 self.pg0.add_stream(p)
2328 self.pg_enable_capture(self.pg_interfaces)
2330 capture = self.pg0.get_capture(1)
2335 self.assertEqual(ip.src, self.nat_addr)
2336 self.assertEqual(ip.dst, server.ip4)
2337 self.assertNotEqual(tcp.sport, host_in_port)
2338 self.assertEqual(tcp.dport, server_in_port)
2339 self.assert_packet_checksums_valid(p)
2340 host_out_port = tcp.sport
2342 self.logger.error(ppp("Unexpected or invalid packet:", p))
2345 # send reply from server to host
2346 p = (Ether(src=server.mac, dst=self.pg0.local_mac) /
2347 IP(src=server.ip4, dst=self.nat_addr) /
2348 TCP(sport=server_in_port, dport=host_out_port))
2349 self.pg0.add_stream(p)
2350 self.pg_enable_capture(self.pg_interfaces)
2352 capture = self.pg0.get_capture(1)
2357 self.assertEqual(ip.src, self.nat_addr)
2358 self.assertEqual(ip.dst, host.ip4)
2359 self.assertEqual(tcp.sport, server_out_port)
2360 self.assertEqual(tcp.dport, host_in_port)
2361 self.assert_packet_checksums_valid(p)
2363 self.logger.error(ppp("Unexpected or invalid packet:", p))
2366 def test_hairpinning2(self):
2367 """ NAT44 hairpinning - 1:1 NAT"""
2369 server1_nat_ip = "10.0.0.10"
2370 server2_nat_ip = "10.0.0.11"
2371 host = self.pg0.remote_hosts[0]
2372 server1 = self.pg0.remote_hosts[1]
2373 server2 = self.pg0.remote_hosts[2]
2374 server_tcp_port = 22
2375 server_udp_port = 20
2377 self.nat44_add_address(self.nat_addr)
2378 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
2379 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
2382 # add static mapping for servers
2383 self.nat44_add_static_mapping(server1.ip4, server1_nat_ip)
2384 self.nat44_add_static_mapping(server2.ip4, server2_nat_ip)
2388 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2389 IP(src=host.ip4, dst=server1_nat_ip) /
2390 TCP(sport=self.tcp_port_in, dport=server_tcp_port))
2392 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2393 IP(src=host.ip4, dst=server1_nat_ip) /
2394 UDP(sport=self.udp_port_in, dport=server_udp_port))
2396 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2397 IP(src=host.ip4, dst=server1_nat_ip) /
2398 ICMP(id=self.icmp_id_in, type='echo-request'))
2400 self.pg0.add_stream(pkts)
2401 self.pg_enable_capture(self.pg_interfaces)
2403 capture = self.pg0.get_capture(len(pkts))
2404 for packet in capture:
2406 self.assertEqual(packet[IP].src, self.nat_addr)
2407 self.assertEqual(packet[IP].dst, server1.ip4)
2408 if packet.haslayer(TCP):
2409 self.assertNotEqual(packet[TCP].sport, self.tcp_port_in)
2410 self.assertEqual(packet[TCP].dport, server_tcp_port)
2411 self.tcp_port_out = packet[TCP].sport
2412 self.assert_packet_checksums_valid(packet)
2413 elif packet.haslayer(UDP):
2414 self.assertNotEqual(packet[UDP].sport, self.udp_port_in)
2415 self.assertEqual(packet[UDP].dport, server_udp_port)
2416 self.udp_port_out = packet[UDP].sport
2418 self.assertNotEqual(packet[ICMP].id, self.icmp_id_in)
2419 self.icmp_id_out = packet[ICMP].id
2421 self.logger.error(ppp("Unexpected or invalid packet:", packet))
2426 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2427 IP(src=server1.ip4, dst=self.nat_addr) /
2428 TCP(sport=server_tcp_port, dport=self.tcp_port_out))
2430 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2431 IP(src=server1.ip4, dst=self.nat_addr) /
2432 UDP(sport=server_udp_port, dport=self.udp_port_out))
2434 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2435 IP(src=server1.ip4, dst=self.nat_addr) /
2436 ICMP(id=self.icmp_id_out, type='echo-reply'))
2438 self.pg0.add_stream(pkts)
2439 self.pg_enable_capture(self.pg_interfaces)
2441 capture = self.pg0.get_capture(len(pkts))
2442 for packet in capture:
2444 self.assertEqual(packet[IP].src, server1_nat_ip)
2445 self.assertEqual(packet[IP].dst, host.ip4)
2446 if packet.haslayer(TCP):
2447 self.assertEqual(packet[TCP].dport, self.tcp_port_in)
2448 self.assertEqual(packet[TCP].sport, server_tcp_port)
2449 self.assert_packet_checksums_valid(packet)
2450 elif packet.haslayer(UDP):
2451 self.assertEqual(packet[UDP].dport, self.udp_port_in)
2452 self.assertEqual(packet[UDP].sport, server_udp_port)
2454 self.assertEqual(packet[ICMP].id, self.icmp_id_in)
2456 self.logger.error(ppp("Unexpected or invalid packet:", packet))
2459 # server2 to server1
2461 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2462 IP(src=server2.ip4, dst=server1_nat_ip) /
2463 TCP(sport=self.tcp_port_in, dport=server_tcp_port))
2465 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2466 IP(src=server2.ip4, dst=server1_nat_ip) /
2467 UDP(sport=self.udp_port_in, dport=server_udp_port))
2469 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2470 IP(src=server2.ip4, dst=server1_nat_ip) /
2471 ICMP(id=self.icmp_id_in, type='echo-request'))
2473 self.pg0.add_stream(pkts)
2474 self.pg_enable_capture(self.pg_interfaces)
2476 capture = self.pg0.get_capture(len(pkts))
2477 for packet in capture:
2479 self.assertEqual(packet[IP].src, server2_nat_ip)
2480 self.assertEqual(packet[IP].dst, server1.ip4)
2481 if packet.haslayer(TCP):
2482 self.assertEqual(packet[TCP].sport, self.tcp_port_in)
2483 self.assertEqual(packet[TCP].dport, server_tcp_port)
2484 self.tcp_port_out = packet[TCP].sport
2485 self.assert_packet_checksums_valid(packet)
2486 elif packet.haslayer(UDP):
2487 self.assertEqual(packet[UDP].sport, self.udp_port_in)
2488 self.assertEqual(packet[UDP].dport, server_udp_port)
2489 self.udp_port_out = packet[UDP].sport
2491 self.assertEqual(packet[ICMP].id, self.icmp_id_in)
2492 self.icmp_id_out = packet[ICMP].id
2494 self.logger.error(ppp("Unexpected or invalid packet:", packet))
2497 # server1 to server2
2499 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2500 IP(src=server1.ip4, dst=server2_nat_ip) /
2501 TCP(sport=server_tcp_port, dport=self.tcp_port_out))
2503 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2504 IP(src=server1.ip4, dst=server2_nat_ip) /
2505 UDP(sport=server_udp_port, dport=self.udp_port_out))
2507 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2508 IP(src=server1.ip4, dst=server2_nat_ip) /
2509 ICMP(id=self.icmp_id_out, type='echo-reply'))
2511 self.pg0.add_stream(pkts)
2512 self.pg_enable_capture(self.pg_interfaces)
2514 capture = self.pg0.get_capture(len(pkts))
2515 for packet in capture:
2517 self.assertEqual(packet[IP].src, server1_nat_ip)
2518 self.assertEqual(packet[IP].dst, server2.ip4)
2519 if packet.haslayer(TCP):
2520 self.assertEqual(packet[TCP].dport, self.tcp_port_in)
2521 self.assertEqual(packet[TCP].sport, server_tcp_port)
2522 self.assert_packet_checksums_valid(packet)
2523 elif packet.haslayer(UDP):
2524 self.assertEqual(packet[UDP].dport, self.udp_port_in)
2525 self.assertEqual(packet[UDP].sport, server_udp_port)
2527 self.assertEqual(packet[ICMP].id, self.icmp_id_in)
2529 self.logger.error(ppp("Unexpected or invalid packet:", packet))
2532 def test_max_translations_per_user(self):
2533 """ MAX translations per user - recycle the least recently used """
2535 self.nat44_add_address(self.nat_addr)
2536 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
2537 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
2540 # get maximum number of translations per user
2541 nat44_config = self.vapi.nat_show_config()
2543 # send more than maximum number of translations per user packets
2544 pkts_num = nat44_config.max_translations_per_user + 5
2546 for port in range(0, pkts_num):
2547 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2548 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
2549 TCP(sport=1025 + port))
2551 self.pg0.add_stream(pkts)
2552 self.pg_enable_capture(self.pg_interfaces)
2555 # verify number of translated packet
2556 self.pg1.get_capture(pkts_num)
2558 users = self.vapi.nat44_user_dump()
2560 if user.ip_address == self.pg0.remote_ip4n:
2561 self.assertEqual(user.nsessions,
2562 nat44_config.max_translations_per_user)
2563 self.assertEqual(user.nstaticsessions, 0)
2566 self.nat44_add_static_mapping(self.pg0.remote_ip4, self.nat_addr,
2568 proto=IP_PROTOS.tcp)
2569 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2570 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
2571 TCP(sport=tcp_port))
2572 self.pg0.add_stream(p)
2573 self.pg_enable_capture(self.pg_interfaces)
2575 self.pg1.get_capture(1)
2576 users = self.vapi.nat44_user_dump()
2578 if user.ip_address == self.pg0.remote_ip4n:
2579 self.assertEqual(user.nsessions,
2580 nat44_config.max_translations_per_user - 1)
2581 self.assertEqual(user.nstaticsessions, 1)
2583 def test_interface_addr(self):
2584 """ Acquire NAT44 addresses from interface """
2585 self.vapi.nat44_add_del_interface_addr(self.pg7.sw_if_index)
2587 # no address in NAT pool
2588 adresses = self.vapi.nat44_address_dump()
2589 self.assertEqual(0, len(adresses))
2591 # configure interface address and check NAT address pool
2592 self.pg7.config_ip4()
2593 adresses = self.vapi.nat44_address_dump()
2594 self.assertEqual(1, len(adresses))
2595 self.assertEqual(adresses[0].ip_address[0:4], self.pg7.local_ip4n)
2597 # remove interface address and check NAT address pool
2598 self.pg7.unconfig_ip4()
2599 adresses = self.vapi.nat44_address_dump()
2600 self.assertEqual(0, len(adresses))
2602 def test_interface_addr_static_mapping(self):
2603 """ Static mapping with addresses from interface """
2606 self.vapi.nat44_add_del_interface_addr(self.pg7.sw_if_index)
2607 self.nat44_add_static_mapping(
2609 external_sw_if_index=self.pg7.sw_if_index,
2612 # static mappings with external interface
2613 static_mappings = self.vapi.nat44_static_mapping_dump()
2614 self.assertEqual(1, len(static_mappings))
2615 self.assertEqual(self.pg7.sw_if_index,
2616 static_mappings[0].external_sw_if_index)
2617 self.assertEqual((static_mappings[0].tag).split(b'\0', 1)[0], tag)
2619 # configure interface address and check static mappings
2620 self.pg7.config_ip4()
2621 static_mappings = self.vapi.nat44_static_mapping_dump()
2622 self.assertEqual(2, len(static_mappings))
2624 for sm in static_mappings:
2625 if sm.external_sw_if_index == 0xFFFFFFFF:
2626 self.assertEqual(sm.external_ip_address[0:4],
2627 self.pg7.local_ip4n)
2628 self.assertEqual((sm.tag).split(b'\0', 1)[0], tag)
2630 self.assertTrue(resolved)
2632 # remove interface address and check static mappings
2633 self.pg7.unconfig_ip4()
2634 static_mappings = self.vapi.nat44_static_mapping_dump()
2635 self.assertEqual(1, len(static_mappings))
2636 self.assertEqual(self.pg7.sw_if_index,
2637 static_mappings[0].external_sw_if_index)
2638 self.assertEqual((static_mappings[0].tag).split(b'\0', 1)[0], tag)
2640 # configure interface address again and check static mappings
2641 self.pg7.config_ip4()
2642 static_mappings = self.vapi.nat44_static_mapping_dump()
2643 self.assertEqual(2, len(static_mappings))
2645 for sm in static_mappings:
2646 if sm.external_sw_if_index == 0xFFFFFFFF:
2647 self.assertEqual(sm.external_ip_address[0:4],
2648 self.pg7.local_ip4n)
2649 self.assertEqual((sm.tag).split(b'\0', 1)[0], tag)
2651 self.assertTrue(resolved)
2653 # remove static mapping
2654 self.nat44_add_static_mapping(
2656 external_sw_if_index=self.pg7.sw_if_index,
2659 static_mappings = self.vapi.nat44_static_mapping_dump()
2660 self.assertEqual(0, len(static_mappings))
2662 def test_interface_addr_identity_nat(self):
2663 """ Identity NAT with addresses from interface """
2666 self.vapi.nat44_add_del_interface_addr(self.pg7.sw_if_index)
2667 self.vapi.nat44_add_del_identity_mapping(
2668 sw_if_index=self.pg7.sw_if_index,
2670 protocol=IP_PROTOS.tcp,
2673 # identity mappings with external interface
2674 identity_mappings = self.vapi.nat44_identity_mapping_dump()
2675 self.assertEqual(1, len(identity_mappings))
2676 self.assertEqual(self.pg7.sw_if_index,
2677 identity_mappings[0].sw_if_index)
2679 # configure interface address and check identity mappings
2680 self.pg7.config_ip4()
2681 identity_mappings = self.vapi.nat44_identity_mapping_dump()
2683 self.assertEqual(2, len(identity_mappings))
2684 for sm in identity_mappings:
2685 if sm.sw_if_index == 0xFFFFFFFF:
2686 self.assertEqual(identity_mappings[0].ip_address,
2687 self.pg7.local_ip4n)
2688 self.assertEqual(port, identity_mappings[0].port)
2689 self.assertEqual(IP_PROTOS.tcp, identity_mappings[0].protocol)
2691 self.assertTrue(resolved)
2693 # remove interface address and check identity mappings
2694 self.pg7.unconfig_ip4()
2695 identity_mappings = self.vapi.nat44_identity_mapping_dump()
2696 self.assertEqual(1, len(identity_mappings))
2697 self.assertEqual(self.pg7.sw_if_index,
2698 identity_mappings[0].sw_if_index)
2700 def test_ipfix_nat44_sess(self):
2701 """ IPFIX logging NAT44 session created/delted """
2702 self.ipfix_domain_id = 10
2703 self.ipfix_src_port = 20202
2704 colector_port = 30303
2705 bind_layers(UDP, IPFIX, dport=30303)
2706 self.nat44_add_address(self.nat_addr)
2707 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
2708 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
2710 self.vapi.set_ipfix_exporter(collector_address=self.pg3.remote_ip4n,
2711 src_address=self.pg3.local_ip4n,
2713 template_interval=10,
2714 collector_port=colector_port)
2715 self.vapi.nat_ipfix_enable_disable(domain_id=self.ipfix_domain_id,
2716 src_port=self.ipfix_src_port)
2718 pkts = self.create_stream_in(self.pg0, self.pg1)
2719 self.pg0.add_stream(pkts)
2720 self.pg_enable_capture(self.pg_interfaces)
2722 capture = self.pg1.get_capture(len(pkts))
2723 self.verify_capture_out(capture)
2724 self.nat44_add_address(self.nat_addr, is_add=0)
2725 self.vapi.cli("ipfix flush") # FIXME this should be an API call
2726 capture = self.pg3.get_capture(9)
2727 ipfix = IPFIXDecoder()
2728 # first load template
2730 self.assertTrue(p.haslayer(IPFIX))
2731 self.assertEqual(p[IP].src, self.pg3.local_ip4)
2732 self.assertEqual(p[IP].dst, self.pg3.remote_ip4)
2733 self.assertEqual(p[UDP].sport, self.ipfix_src_port)
2734 self.assertEqual(p[UDP].dport, colector_port)
2735 self.assertEqual(p[IPFIX].observationDomainID,
2736 self.ipfix_domain_id)
2737 if p.haslayer(Template):
2738 ipfix.add_template(p.getlayer(Template))
2739 # verify events in data set
2741 if p.haslayer(Data):
2742 data = ipfix.decode_data_set(p.getlayer(Set))
2743 self.verify_ipfix_nat44_ses(data)
2745 def test_ipfix_addr_exhausted(self):
2746 """ IPFIX logging NAT addresses exhausted """
2747 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
2748 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
2750 self.vapi.set_ipfix_exporter(collector_address=self.pg3.remote_ip4n,
2751 src_address=self.pg3.local_ip4n,
2753 template_interval=10)
2754 self.vapi.nat_ipfix_enable_disable(domain_id=self.ipfix_domain_id,
2755 src_port=self.ipfix_src_port)
2757 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
2758 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
2760 self.pg0.add_stream(p)
2761 self.pg_enable_capture(self.pg_interfaces)
2763 self.pg1.assert_nothing_captured()
2765 self.vapi.cli("ipfix flush") # FIXME this should be an API call
2766 capture = self.pg3.get_capture(9)
2767 ipfix = IPFIXDecoder()
2768 # first load template
2770 self.assertTrue(p.haslayer(IPFIX))
2771 self.assertEqual(p[IP].src, self.pg3.local_ip4)
2772 self.assertEqual(p[IP].dst, self.pg3.remote_ip4)
2773 self.assertEqual(p[UDP].sport, self.ipfix_src_port)
2774 self.assertEqual(p[UDP].dport, 4739)
2775 self.assertEqual(p[IPFIX].observationDomainID,
2776 self.ipfix_domain_id)
2777 if p.haslayer(Template):
2778 ipfix.add_template(p.getlayer(Template))
2779 # verify events in data set
2781 if p.haslayer(Data):
2782 data = ipfix.decode_data_set(p.getlayer(Set))
2783 self.verify_ipfix_addr_exhausted(data)
2785 @unittest.skipUnless(running_extended_tests, "part of extended tests")
2786 def test_ipfix_max_sessions(self):
2787 """ IPFIX logging maximum session entries exceeded """
2788 self.nat44_add_address(self.nat_addr)
2789 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
2790 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
2793 nat44_config = self.vapi.nat_show_config()
2794 max_sessions = 10 * nat44_config.translation_buckets
2797 for i in range(0, max_sessions):
2798 src = "10.10.%u.%u" % ((i & 0xFF00) >> 8, i & 0xFF)
2799 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2800 IP(src=src, dst=self.pg1.remote_ip4) /
2803 self.pg0.add_stream(pkts)
2804 self.pg_enable_capture(self.pg_interfaces)
2807 self.pg1.get_capture(max_sessions)
2808 self.vapi.set_ipfix_exporter(collector_address=self.pg3.remote_ip4n,
2809 src_address=self.pg3.local_ip4n,
2811 template_interval=10)
2812 self.vapi.nat_ipfix_enable_disable(domain_id=self.ipfix_domain_id,
2813 src_port=self.ipfix_src_port)
2815 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2816 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
2818 self.pg0.add_stream(p)
2819 self.pg_enable_capture(self.pg_interfaces)
2821 self.pg1.assert_nothing_captured()
2823 self.vapi.cli("ipfix flush") # FIXME this should be an API call
2824 capture = self.pg3.get_capture(9)
2825 ipfix = IPFIXDecoder()
2826 # first load template
2828 self.assertTrue(p.haslayer(IPFIX))
2829 self.assertEqual(p[IP].src, self.pg3.local_ip4)
2830 self.assertEqual(p[IP].dst, self.pg3.remote_ip4)
2831 self.assertEqual(p[UDP].sport, self.ipfix_src_port)
2832 self.assertEqual(p[UDP].dport, 4739)
2833 self.assertEqual(p[IPFIX].observationDomainID,
2834 self.ipfix_domain_id)
2835 if p.haslayer(Template):
2836 ipfix.add_template(p.getlayer(Template))
2837 # verify events in data set
2839 if p.haslayer(Data):
2840 data = ipfix.decode_data_set(p.getlayer(Set))
2841 self.verify_ipfix_max_sessions(data, max_sessions)
2843 def test_syslog_apmap(self):
2844 """ Test syslog address and port mapping creation and deletion """
2845 self.vapi.syslog_set_filter(SYSLOG_SEVERITY.INFO)
2846 self.vapi.syslog_set_sender(self.pg3.local_ip4n, self.pg3.remote_ip4n)
2847 self.nat44_add_address(self.nat_addr)
2848 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
2849 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
2852 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2853 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
2854 TCP(sport=self.tcp_port_in, dport=20))
2855 self.pg0.add_stream(p)
2856 self.pg_enable_capture(self.pg_interfaces)
2858 capture = self.pg1.get_capture(1)
2859 self.tcp_port_out = capture[0][TCP].sport
2860 capture = self.pg3.get_capture(1)
2861 self.verify_syslog_apmap(capture[0][Raw].load)
2863 self.pg_enable_capture(self.pg_interfaces)
2865 self.nat44_add_address(self.nat_addr, is_add=0)
2866 capture = self.pg3.get_capture(1)
2867 self.verify_syslog_apmap(capture[0][Raw].load, False)
2869 def test_pool_addr_fib(self):
2870 """ NAT44 add pool addresses to FIB """
2871 static_addr = '10.0.0.10'
2872 self.nat44_add_address(self.nat_addr)
2873 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
2874 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
2876 self.nat44_add_static_mapping(self.pg0.remote_ip4, static_addr)
2879 p = (Ether(src=self.pg1.remote_mac, dst='ff:ff:ff:ff:ff:ff') /
2880 ARP(op=ARP.who_has, pdst=self.nat_addr,
2881 psrc=self.pg1.remote_ip4, hwsrc=self.pg1.remote_mac))
2882 self.pg1.add_stream(p)
2883 self.pg_enable_capture(self.pg_interfaces)
2885 capture = self.pg1.get_capture(1)
2886 self.assertTrue(capture[0].haslayer(ARP))
2887 self.assertTrue(capture[0][ARP].op, ARP.is_at)
2890 p = (Ether(src=self.pg1.remote_mac, dst='ff:ff:ff:ff:ff:ff') /
2891 ARP(op=ARP.who_has, pdst=static_addr,
2892 psrc=self.pg1.remote_ip4, hwsrc=self.pg1.remote_mac))
2893 self.pg1.add_stream(p)
2894 self.pg_enable_capture(self.pg_interfaces)
2896 capture = self.pg1.get_capture(1)
2897 self.assertTrue(capture[0].haslayer(ARP))
2898 self.assertTrue(capture[0][ARP].op, ARP.is_at)
2900 # send ARP to non-NAT44 interface
2901 p = (Ether(src=self.pg2.remote_mac, dst='ff:ff:ff:ff:ff:ff') /
2902 ARP(op=ARP.who_has, pdst=self.nat_addr,
2903 psrc=self.pg2.remote_ip4, hwsrc=self.pg2.remote_mac))
2904 self.pg2.add_stream(p)
2905 self.pg_enable_capture(self.pg_interfaces)
2907 self.pg1.assert_nothing_captured()
2909 # remove addresses and verify
2910 self.nat44_add_address(self.nat_addr, is_add=0)
2911 self.nat44_add_static_mapping(self.pg0.remote_ip4, static_addr,
2914 p = (Ether(src=self.pg1.remote_mac, dst='ff:ff:ff:ff:ff:ff') /
2915 ARP(op=ARP.who_has, pdst=self.nat_addr,
2916 psrc=self.pg1.remote_ip4, hwsrc=self.pg1.remote_mac))
2917 self.pg1.add_stream(p)
2918 self.pg_enable_capture(self.pg_interfaces)
2920 self.pg1.assert_nothing_captured()
2922 p = (Ether(src=self.pg1.remote_mac, dst='ff:ff:ff:ff:ff:ff') /
2923 ARP(op=ARP.who_has, pdst=static_addr,
2924 psrc=self.pg1.remote_ip4, hwsrc=self.pg1.remote_mac))
2925 self.pg1.add_stream(p)
2926 self.pg_enable_capture(self.pg_interfaces)
2928 self.pg1.assert_nothing_captured()
2930 def test_vrf_mode(self):
2931 """ NAT44 tenant VRF aware address pool mode """
2935 nat_ip1 = "10.0.0.10"
2936 nat_ip2 = "10.0.0.11"
2938 self.pg0.unconfig_ip4()
2939 self.pg1.unconfig_ip4()
2940 self.vapi.ip_table_add_del(is_add=1, table_id=vrf_id1)
2941 self.vapi.ip_table_add_del(is_add=1, table_id=vrf_id2)
2942 self.pg0.set_table_ip4(vrf_id1)
2943 self.pg1.set_table_ip4(vrf_id2)
2944 self.pg0.config_ip4()
2945 self.pg1.config_ip4()
2946 self.pg0.resolve_arp()
2947 self.pg1.resolve_arp()
2949 self.nat44_add_address(nat_ip1, vrf_id=vrf_id1)
2950 self.nat44_add_address(nat_ip2, vrf_id=vrf_id2)
2951 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
2952 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index)
2953 self.vapi.nat44_interface_add_del_feature(self.pg2.sw_if_index,
2958 pkts = self.create_stream_in(self.pg0, self.pg2)
2959 self.pg0.add_stream(pkts)
2960 self.pg_enable_capture(self.pg_interfaces)
2962 capture = self.pg2.get_capture(len(pkts))
2963 self.verify_capture_out(capture, nat_ip1)
2966 pkts = self.create_stream_in(self.pg1, self.pg2)
2967 self.pg1.add_stream(pkts)
2968 self.pg_enable_capture(self.pg_interfaces)
2970 capture = self.pg2.get_capture(len(pkts))
2971 self.verify_capture_out(capture, nat_ip2)
2974 self.pg0.unconfig_ip4()
2975 self.pg1.unconfig_ip4()
2976 self.pg0.set_table_ip4(0)
2977 self.pg1.set_table_ip4(0)
2978 self.pg0.config_ip4()
2979 self.pg1.config_ip4()
2980 self.pg0.resolve_arp()
2981 self.pg1.resolve_arp()
2982 self.vapi.ip_table_add_del(is_add=0, table_id=vrf_id1)
2983 self.vapi.ip_table_add_del(is_add=0, table_id=vrf_id2)
2985 def test_vrf_feature_independent(self):
2986 """ NAT44 tenant VRF independent address pool mode """
2988 nat_ip1 = "10.0.0.10"
2989 nat_ip2 = "10.0.0.11"
2991 self.nat44_add_address(nat_ip1)
2992 self.nat44_add_address(nat_ip2, vrf_id=99)
2993 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
2994 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index)
2995 self.vapi.nat44_interface_add_del_feature(self.pg2.sw_if_index,
2999 pkts = self.create_stream_in(self.pg0, self.pg2)
3000 self.pg0.add_stream(pkts)
3001 self.pg_enable_capture(self.pg_interfaces)
3003 capture = self.pg2.get_capture(len(pkts))
3004 self.verify_capture_out(capture, nat_ip1)
3007 pkts = self.create_stream_in(self.pg1, self.pg2)
3008 self.pg1.add_stream(pkts)
3009 self.pg_enable_capture(self.pg_interfaces)
3011 capture = self.pg2.get_capture(len(pkts))
3012 self.verify_capture_out(capture, nat_ip1)
3014 def test_dynamic_ipless_interfaces(self):
3015 """ NAT44 interfaces without configured IP address """
3017 self.vapi.ip_neighbor_add_del(
3018 self.pg7.sw_if_index,
3019 self.pg7.remote_mac,
3020 self.pg7.remote_ip4,
3021 flags=(VppEnum.vl_api_ip_neighbor_flags_t.
3022 IP_API_NEIGHBOR_FLAG_STATIC))
3023 self.vapi.ip_neighbor_add_del(
3024 self.pg8.sw_if_index,
3025 self.pg8.remote_mac,
3026 self.pg8.remote_ip4,
3027 flags=(VppEnum.vl_api_ip_neighbor_flags_t.
3028 IP_API_NEIGHBOR_FLAG_STATIC))
3030 self.vapi.ip_add_del_route(dst_address=self.pg7.remote_ip4n,
3031 dst_address_length=32,
3032 next_hop_address=self.pg7.remote_ip4n,
3033 next_hop_sw_if_index=self.pg7.sw_if_index)
3034 self.vapi.ip_add_del_route(dst_address=self.pg8.remote_ip4n,
3035 dst_address_length=32,
3036 next_hop_address=self.pg8.remote_ip4n,
3037 next_hop_sw_if_index=self.pg8.sw_if_index)
3039 self.nat44_add_address(self.nat_addr)
3040 self.vapi.nat44_interface_add_del_feature(self.pg7.sw_if_index)
3041 self.vapi.nat44_interface_add_del_feature(self.pg8.sw_if_index,
3045 pkts = self.create_stream_in(self.pg7, self.pg8)
3046 self.pg7.add_stream(pkts)
3047 self.pg_enable_capture(self.pg_interfaces)
3049 capture = self.pg8.get_capture(len(pkts))
3050 self.verify_capture_out(capture)
3053 pkts = self.create_stream_out(self.pg8, self.nat_addr)
3054 self.pg8.add_stream(pkts)
3055 self.pg_enable_capture(self.pg_interfaces)
3057 capture = self.pg7.get_capture(len(pkts))
3058 self.verify_capture_in(capture, self.pg7)
3060 def test_static_ipless_interfaces(self):
3061 """ NAT44 interfaces without configured IP address - 1:1 NAT """
3063 self.vapi.ip_neighbor_add_del(
3064 self.pg7.sw_if_index,
3065 self.pg7.remote_mac,
3066 self.pg7.remote_ip4,
3067 flags=(VppEnum.vl_api_ip_neighbor_flags_t.
3068 IP_API_NEIGHBOR_FLAG_STATIC))
3069 self.vapi.ip_neighbor_add_del(
3070 self.pg8.sw_if_index,
3071 self.pg8.remote_mac,
3072 self.pg8.remote_ip4,
3073 flags=(VppEnum.vl_api_ip_neighbor_flags_t.
3074 IP_API_NEIGHBOR_FLAG_STATIC))
3076 self.vapi.ip_add_del_route(dst_address=self.pg7.remote_ip4n,
3077 dst_address_length=32,
3078 next_hop_address=self.pg7.remote_ip4n,
3079 next_hop_sw_if_index=self.pg7.sw_if_index)
3080 self.vapi.ip_add_del_route(dst_address=self.pg8.remote_ip4n,
3081 dst_address_length=32,
3082 next_hop_address=self.pg8.remote_ip4n,
3083 next_hop_sw_if_index=self.pg8.sw_if_index)
3085 self.nat44_add_static_mapping(self.pg7.remote_ip4, self.nat_addr)
3086 self.vapi.nat44_interface_add_del_feature(self.pg7.sw_if_index)
3087 self.vapi.nat44_interface_add_del_feature(self.pg8.sw_if_index,
3091 pkts = self.create_stream_out(self.pg8)
3092 self.pg8.add_stream(pkts)
3093 self.pg_enable_capture(self.pg_interfaces)
3095 capture = self.pg7.get_capture(len(pkts))
3096 self.verify_capture_in(capture, self.pg7)
3099 pkts = self.create_stream_in(self.pg7, self.pg8)
3100 self.pg7.add_stream(pkts)
3101 self.pg_enable_capture(self.pg_interfaces)
3103 capture = self.pg8.get_capture(len(pkts))
3104 self.verify_capture_out(capture, self.nat_addr, True)
3106 def test_static_with_port_ipless_interfaces(self):
3107 """ NAT44 interfaces without configured IP address - 1:1 NAPT """
3109 self.tcp_port_out = 30606
3110 self.udp_port_out = 30607
3111 self.icmp_id_out = 30608
3113 self.vapi.ip_neighbor_add_del(
3114 self.pg7.sw_if_index,
3115 self.pg7.remote_mac,
3116 self.pg7.remote_ip4,
3117 flags=(VppEnum.vl_api_ip_neighbor_flags_t.
3118 IP_API_NEIGHBOR_FLAG_STATIC))
3119 self.vapi.ip_neighbor_add_del(
3120 self.pg8.sw_if_index,
3121 self.pg8.remote_mac,
3122 self.pg8.remote_ip4,
3123 flags=(VppEnum.vl_api_ip_neighbor_flags_t.
3124 IP_API_NEIGHBOR_FLAG_STATIC))
3126 self.vapi.ip_add_del_route(dst_address=self.pg7.remote_ip4n,
3127 dst_address_length=32,
3128 next_hop_address=self.pg7.remote_ip4n,
3129 next_hop_sw_if_index=self.pg7.sw_if_index)
3130 self.vapi.ip_add_del_route(dst_address=self.pg8.remote_ip4n,
3131 dst_address_length=32,
3132 next_hop_address=self.pg8.remote_ip4n,
3133 next_hop_sw_if_index=self.pg8.sw_if_index)
3135 self.nat44_add_address(self.nat_addr)
3136 self.nat44_add_static_mapping(self.pg7.remote_ip4, self.nat_addr,
3137 self.tcp_port_in, self.tcp_port_out,
3138 proto=IP_PROTOS.tcp)
3139 self.nat44_add_static_mapping(self.pg7.remote_ip4, self.nat_addr,
3140 self.udp_port_in, self.udp_port_out,
3141 proto=IP_PROTOS.udp)
3142 self.nat44_add_static_mapping(self.pg7.remote_ip4, self.nat_addr,
3143 self.icmp_id_in, self.icmp_id_out,
3144 proto=IP_PROTOS.icmp)
3145 self.vapi.nat44_interface_add_del_feature(self.pg7.sw_if_index)
3146 self.vapi.nat44_interface_add_del_feature(self.pg8.sw_if_index,
3150 pkts = self.create_stream_out(self.pg8)
3151 self.pg8.add_stream(pkts)
3152 self.pg_enable_capture(self.pg_interfaces)
3154 capture = self.pg7.get_capture(len(pkts))
3155 self.verify_capture_in(capture, self.pg7)
3158 pkts = self.create_stream_in(self.pg7, self.pg8)
3159 self.pg7.add_stream(pkts)
3160 self.pg_enable_capture(self.pg_interfaces)
3162 capture = self.pg8.get_capture(len(pkts))
3163 self.verify_capture_out(capture)
3165 def test_static_unknown_proto(self):
3166 """ 1:1 NAT translate packet with unknown protocol """
3167 nat_ip = "10.0.0.10"
3168 self.nat44_add_static_mapping(self.pg0.remote_ip4, nat_ip)
3169 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
3170 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
3174 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
3175 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
3177 IP(src=self.pg2.remote_ip4, dst=self.pg3.remote_ip4) /
3178 TCP(sport=1234, dport=1234))
3179 self.pg0.add_stream(p)
3180 self.pg_enable_capture(self.pg_interfaces)
3182 p = self.pg1.get_capture(1)
3185 self.assertEqual(packet[IP].src, nat_ip)
3186 self.assertEqual(packet[IP].dst, self.pg1.remote_ip4)
3187 self.assertEqual(packet.haslayer(GRE), 1)
3188 self.assert_packet_checksums_valid(packet)
3190 self.logger.error(ppp("Unexpected or invalid packet:", packet))
3194 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
3195 IP(src=self.pg1.remote_ip4, dst=nat_ip) /
3197 IP(src=self.pg3.remote_ip4, dst=self.pg2.remote_ip4) /
3198 TCP(sport=1234, dport=1234))
3199 self.pg1.add_stream(p)
3200 self.pg_enable_capture(self.pg_interfaces)
3202 p = self.pg0.get_capture(1)
3205 self.assertEqual(packet[IP].src, self.pg1.remote_ip4)
3206 self.assertEqual(packet[IP].dst, self.pg0.remote_ip4)
3207 self.assertEqual(packet.haslayer(GRE), 1)
3208 self.assert_packet_checksums_valid(packet)
3210 self.logger.error(ppp("Unexpected or invalid packet:", packet))
3213 def test_hairpinning_static_unknown_proto(self):
3214 """ 1:1 NAT translate packet with unknown protocol - hairpinning """
3216 host = self.pg0.remote_hosts[0]
3217 server = self.pg0.remote_hosts[1]
3219 host_nat_ip = "10.0.0.10"
3220 server_nat_ip = "10.0.0.11"
3222 self.nat44_add_static_mapping(host.ip4, host_nat_ip)
3223 self.nat44_add_static_mapping(server.ip4, server_nat_ip)
3224 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
3225 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
3229 p = (Ether(dst=self.pg0.local_mac, src=host.mac) /
3230 IP(src=host.ip4, dst=server_nat_ip) /
3232 IP(src=self.pg2.remote_ip4, dst=self.pg3.remote_ip4) /
3233 TCP(sport=1234, dport=1234))
3234 self.pg0.add_stream(p)
3235 self.pg_enable_capture(self.pg_interfaces)
3237 p = self.pg0.get_capture(1)
3240 self.assertEqual(packet[IP].src, host_nat_ip)
3241 self.assertEqual(packet[IP].dst, server.ip4)
3242 self.assertEqual(packet.haslayer(GRE), 1)
3243 self.assert_packet_checksums_valid(packet)
3245 self.logger.error(ppp("Unexpected or invalid packet:", packet))
3249 p = (Ether(dst=self.pg0.local_mac, src=server.mac) /
3250 IP(src=server.ip4, dst=host_nat_ip) /
3252 IP(src=self.pg3.remote_ip4, dst=self.pg2.remote_ip4) /
3253 TCP(sport=1234, dport=1234))
3254 self.pg0.add_stream(p)
3255 self.pg_enable_capture(self.pg_interfaces)
3257 p = self.pg0.get_capture(1)
3260 self.assertEqual(packet[IP].src, server_nat_ip)
3261 self.assertEqual(packet[IP].dst, host.ip4)
3262 self.assertEqual(packet.haslayer(GRE), 1)
3263 self.assert_packet_checksums_valid(packet)
3265 self.logger.error(ppp("Unexpected or invalid packet:", packet))
3268 def test_output_feature(self):
3269 """ NAT44 interface output feature (in2out postrouting) """
3270 self.nat44_add_address(self.nat_addr)
3271 self.vapi.nat44_interface_add_del_output_feature(self.pg0.sw_if_index)
3272 self.vapi.nat44_interface_add_del_output_feature(self.pg1.sw_if_index)
3273 self.vapi.nat44_interface_add_del_output_feature(self.pg3.sw_if_index,
3277 pkts = self.create_stream_in(self.pg0, self.pg3)
3278 self.pg0.add_stream(pkts)
3279 self.pg_enable_capture(self.pg_interfaces)
3281 capture = self.pg3.get_capture(len(pkts))
3282 self.verify_capture_out(capture)
3285 pkts = self.create_stream_out(self.pg3)
3286 self.pg3.add_stream(pkts)
3287 self.pg_enable_capture(self.pg_interfaces)
3289 capture = self.pg0.get_capture(len(pkts))
3290 self.verify_capture_in(capture, self.pg0)
3292 # from non-NAT interface to NAT inside interface
3293 pkts = self.create_stream_in(self.pg2, self.pg0)
3294 self.pg2.add_stream(pkts)
3295 self.pg_enable_capture(self.pg_interfaces)
3297 capture = self.pg0.get_capture(len(pkts))
3298 self.verify_capture_no_translation(capture, self.pg2, self.pg0)
3300 def test_output_feature_vrf_aware(self):
3301 """ NAT44 interface output feature VRF aware (in2out postrouting) """
3302 nat_ip_vrf10 = "10.0.0.10"
3303 nat_ip_vrf20 = "10.0.0.20"
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,
3310 self.vapi.ip_add_del_route(dst_address=self.pg3.remote_ip4n,
3311 dst_address_length=32,
3312 next_hop_address=self.pg3.remote_ip4n,
3313 next_hop_sw_if_index=self.pg3.sw_if_index,
3316 self.nat44_add_address(nat_ip_vrf10, vrf_id=10)
3317 self.nat44_add_address(nat_ip_vrf20, vrf_id=20)
3318 self.vapi.nat44_interface_add_del_output_feature(self.pg4.sw_if_index)
3319 self.vapi.nat44_interface_add_del_output_feature(self.pg6.sw_if_index)
3320 self.vapi.nat44_interface_add_del_output_feature(self.pg3.sw_if_index,
3324 pkts = self.create_stream_in(self.pg4, self.pg3)
3325 self.pg4.add_stream(pkts)
3326 self.pg_enable_capture(self.pg_interfaces)
3328 capture = self.pg3.get_capture(len(pkts))
3329 self.verify_capture_out(capture, nat_ip=nat_ip_vrf10)
3332 pkts = self.create_stream_out(self.pg3, dst_ip=nat_ip_vrf10)
3333 self.pg3.add_stream(pkts)
3334 self.pg_enable_capture(self.pg_interfaces)
3336 capture = self.pg4.get_capture(len(pkts))
3337 self.verify_capture_in(capture, self.pg4)
3340 pkts = self.create_stream_in(self.pg6, self.pg3)
3341 self.pg6.add_stream(pkts)
3342 self.pg_enable_capture(self.pg_interfaces)
3344 capture = self.pg3.get_capture(len(pkts))
3345 self.verify_capture_out(capture, nat_ip=nat_ip_vrf20)
3348 pkts = self.create_stream_out(self.pg3, dst_ip=nat_ip_vrf20)
3349 self.pg3.add_stream(pkts)
3350 self.pg_enable_capture(self.pg_interfaces)
3352 capture = self.pg6.get_capture(len(pkts))
3353 self.verify_capture_in(capture, self.pg6)
3355 def test_output_feature_hairpinning(self):
3356 """ NAT44 interface output feature hairpinning (in2out postrouting) """
3357 host = self.pg0.remote_hosts[0]
3358 server = self.pg0.remote_hosts[1]
3361 server_in_port = 5678
3362 server_out_port = 8765
3364 self.nat44_add_address(self.nat_addr)
3365 self.vapi.nat44_interface_add_del_output_feature(self.pg0.sw_if_index)
3366 self.vapi.nat44_interface_add_del_output_feature(self.pg1.sw_if_index,
3369 # add static mapping for server
3370 self.nat44_add_static_mapping(server.ip4, self.nat_addr,
3371 server_in_port, server_out_port,
3372 proto=IP_PROTOS.tcp)
3374 # send packet from host to server
3375 p = (Ether(src=host.mac, dst=self.pg0.local_mac) /
3376 IP(src=host.ip4, dst=self.nat_addr) /
3377 TCP(sport=host_in_port, dport=server_out_port))
3378 self.pg0.add_stream(p)
3379 self.pg_enable_capture(self.pg_interfaces)
3381 capture = self.pg0.get_capture(1)
3386 self.assertEqual(ip.src, self.nat_addr)
3387 self.assertEqual(ip.dst, server.ip4)
3388 self.assertNotEqual(tcp.sport, host_in_port)
3389 self.assertEqual(tcp.dport, server_in_port)
3390 self.assert_packet_checksums_valid(p)
3391 host_out_port = tcp.sport
3393 self.logger.error(ppp("Unexpected or invalid packet:", p))
3396 # send reply from server to host
3397 p = (Ether(src=server.mac, dst=self.pg0.local_mac) /
3398 IP(src=server.ip4, dst=self.nat_addr) /
3399 TCP(sport=server_in_port, dport=host_out_port))
3400 self.pg0.add_stream(p)
3401 self.pg_enable_capture(self.pg_interfaces)
3403 capture = self.pg0.get_capture(1)
3408 self.assertEqual(ip.src, self.nat_addr)
3409 self.assertEqual(ip.dst, host.ip4)
3410 self.assertEqual(tcp.sport, server_out_port)
3411 self.assertEqual(tcp.dport, host_in_port)
3412 self.assert_packet_checksums_valid(p)
3414 self.logger.error(ppp("Unexpected or invalid packet:", p))
3417 def test_one_armed_nat44(self):
3418 """ One armed NAT44 """
3419 remote_host = self.pg9.remote_hosts[0]
3420 local_host = self.pg9.remote_hosts[1]
3423 self.nat44_add_address(self.nat_addr)
3424 self.vapi.nat44_interface_add_del_feature(self.pg9.sw_if_index)
3425 self.vapi.nat44_interface_add_del_feature(self.pg9.sw_if_index,
3429 p = (Ether(src=self.pg9.remote_mac, dst=self.pg9.local_mac) /
3430 IP(src=local_host.ip4, dst=remote_host.ip4) /
3431 TCP(sport=12345, dport=80))
3432 self.pg9.add_stream(p)
3433 self.pg_enable_capture(self.pg_interfaces)
3435 capture = self.pg9.get_capture(1)
3440 self.assertEqual(ip.src, self.nat_addr)
3441 self.assertEqual(ip.dst, remote_host.ip4)
3442 self.assertNotEqual(tcp.sport, 12345)
3443 external_port = tcp.sport
3444 self.assertEqual(tcp.dport, 80)
3445 self.assert_packet_checksums_valid(p)
3447 self.logger.error(ppp("Unexpected or invalid packet:", p))
3451 p = (Ether(src=self.pg9.remote_mac, dst=self.pg9.local_mac) /
3452 IP(src=remote_host.ip4, dst=self.nat_addr) /
3453 TCP(sport=80, dport=external_port))
3454 self.pg9.add_stream(p)
3455 self.pg_enable_capture(self.pg_interfaces)
3457 capture = self.pg9.get_capture(1)
3462 self.assertEqual(ip.src, remote_host.ip4)
3463 self.assertEqual(ip.dst, local_host.ip4)
3464 self.assertEqual(tcp.sport, 80)
3465 self.assertEqual(tcp.dport, 12345)
3466 self.assert_packet_checksums_valid(p)
3468 self.logger.error(ppp("Unexpected or invalid packet:", p))
3471 err = self.statistics.get_counter('/err/nat44-classify/next in2out')
3472 self.assertEqual(err, 1)
3473 err = self.statistics.get_counter('/err/nat44-classify/next out2in')
3474 self.assertEqual(err, 1)
3476 def test_del_session(self):
3477 """ Delete NAT44 session """
3478 self.nat44_add_address(self.nat_addr)
3479 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
3480 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
3483 pkts = self.create_stream_in(self.pg0, self.pg1)
3484 self.pg0.add_stream(pkts)
3485 self.pg_enable_capture(self.pg_interfaces)
3487 self.pg1.get_capture(len(pkts))
3489 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4n, 0)
3490 nsessions = len(sessions)
3492 self.vapi.nat44_del_session(sessions[0].inside_ip_address,
3493 sessions[0].inside_port,
3494 sessions[0].protocol)
3495 self.vapi.nat44_del_session(sessions[1].outside_ip_address,
3496 sessions[1].outside_port,
3497 sessions[1].protocol,
3500 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4n, 0)
3501 self.assertEqual(nsessions - len(sessions), 2)
3503 self.vapi.nat44_del_session(sessions[0].inside_ip_address,
3504 sessions[0].inside_port,
3505 sessions[0].protocol)
3507 self.verify_no_nat44_user()
3509 def test_set_get_reass(self):
3510 """ NAT44 set/get virtual fragmentation reassembly """
3511 reas_cfg1 = self.vapi.nat_get_reass()
3513 self.vapi.nat_set_reass(timeout=reas_cfg1.ip4_timeout + 5,
3514 max_reass=reas_cfg1.ip4_max_reass * 2,
3515 max_frag=reas_cfg1.ip4_max_frag * 2)
3517 reas_cfg2 = self.vapi.nat_get_reass()
3519 self.assertEqual(reas_cfg1.ip4_timeout + 5, reas_cfg2.ip4_timeout)
3520 self.assertEqual(reas_cfg1.ip4_max_reass * 2, reas_cfg2.ip4_max_reass)
3521 self.assertEqual(reas_cfg1.ip4_max_frag * 2, reas_cfg2.ip4_max_frag)
3523 self.vapi.nat_set_reass(drop_frag=1)
3524 self.assertTrue(self.vapi.nat_get_reass().ip4_drop_frag)
3526 def test_frag_in_order(self):
3527 """ NAT44 translate fragments arriving in order """
3529 self.nat44_add_address(self.nat_addr)
3530 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
3531 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
3534 self.frag_in_order(proto=IP_PROTOS.tcp)
3535 self.frag_in_order(proto=IP_PROTOS.udp)
3536 self.frag_in_order(proto=IP_PROTOS.icmp)
3538 def test_frag_forwarding(self):
3539 """ NAT44 forwarding fragment test """
3540 self.vapi.nat44_add_del_interface_addr(self.pg1.sw_if_index)
3541 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
3542 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
3544 self.vapi.nat44_forwarding_enable_disable(1)
3546 data = b"A" * 16 + b"B" * 16 + b"C" * 3
3547 pkts = self.create_stream_frag(self.pg1,
3548 self.pg0.remote_ip4,
3552 proto=IP_PROTOS.udp)
3553 self.pg1.add_stream(pkts)
3554 self.pg_enable_capture(self.pg_interfaces)
3556 frags = self.pg0.get_capture(len(pkts))
3557 p = self.reass_frags_and_verify(frags,
3558 self.pg1.remote_ip4,
3559 self.pg0.remote_ip4)
3560 self.assertEqual(p[UDP].sport, 4789)
3561 self.assertEqual(p[UDP].dport, 4789)
3562 self.assertEqual(data, p[Raw].load)
3564 def test_reass_hairpinning(self):
3565 """ NAT44 fragments hairpinning """
3567 self.server = self.pg0.remote_hosts[1]
3568 self.host_in_port = random.randint(1025, 65535)
3569 self.server_in_port = random.randint(1025, 65535)
3570 self.server_out_port = random.randint(1025, 65535)
3572 self.nat44_add_address(self.nat_addr)
3573 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
3574 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
3576 # add static mapping for server
3577 self.nat44_add_static_mapping(self.server.ip4, self.nat_addr,
3578 self.server_in_port,
3579 self.server_out_port,
3580 proto=IP_PROTOS.tcp)
3581 self.nat44_add_static_mapping(self.server.ip4, self.nat_addr,
3582 self.server_in_port,
3583 self.server_out_port,
3584 proto=IP_PROTOS.udp)
3585 self.nat44_add_static_mapping(self.server.ip4, self.nat_addr)
3587 self.reass_hairpinning(proto=IP_PROTOS.tcp)
3588 self.reass_hairpinning(proto=IP_PROTOS.udp)
3589 self.reass_hairpinning(proto=IP_PROTOS.icmp)
3591 def test_frag_out_of_order(self):
3592 """ NAT44 translate fragments arriving out of order """
3594 self.nat44_add_address(self.nat_addr)
3595 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
3596 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
3599 self.frag_out_of_order(proto=IP_PROTOS.tcp)
3600 self.frag_out_of_order(proto=IP_PROTOS.udp)
3601 self.frag_out_of_order(proto=IP_PROTOS.icmp)
3603 def test_port_restricted(self):
3604 """ Port restricted NAT44 (MAP-E CE) """
3605 self.nat44_add_address(self.nat_addr)
3606 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
3607 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
3609 self.vapi.nat_set_addr_and_port_alloc_alg(alg=1,
3614 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
3615 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
3616 TCP(sport=4567, dport=22))
3617 self.pg0.add_stream(p)
3618 self.pg_enable_capture(self.pg_interfaces)
3620 capture = self.pg1.get_capture(1)
3625 self.assertEqual(ip.dst, self.pg1.remote_ip4)
3626 self.assertEqual(ip.src, self.nat_addr)
3627 self.assertEqual(tcp.dport, 22)
3628 self.assertNotEqual(tcp.sport, 4567)
3629 self.assertEqual((tcp.sport >> 6) & 63, 10)
3630 self.assert_packet_checksums_valid(p)
3632 self.logger.error(ppp("Unexpected or invalid packet:", p))
3635 def test_port_range(self):
3636 """ External address port range """
3637 self.nat44_add_address(self.nat_addr)
3638 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
3639 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
3641 self.vapi.nat_set_addr_and_port_alloc_alg(alg=2,
3646 for port in range(0, 5):
3647 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
3648 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
3649 TCP(sport=1125 + port))
3651 self.pg0.add_stream(pkts)
3652 self.pg_enable_capture(self.pg_interfaces)
3654 capture = self.pg1.get_capture(3)
3657 self.assertGreaterEqual(tcp.sport, 1025)
3658 self.assertLessEqual(tcp.sport, 1027)
3660 def test_ipfix_max_frags(self):
3661 """ IPFIX logging maximum fragments pending reassembly exceeded """
3662 self.nat44_add_address(self.nat_addr)
3663 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
3664 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
3666 self.vapi.nat_set_reass(max_frag=1)
3667 self.vapi.set_ipfix_exporter(collector_address=self.pg3.remote_ip4n,
3668 src_address=self.pg3.local_ip4n,
3670 template_interval=10)
3671 self.vapi.nat_ipfix_enable_disable(domain_id=self.ipfix_domain_id,
3672 src_port=self.ipfix_src_port)
3674 data = b"A" * 4 + b"B" * 16 + b"C" * 3
3675 self.tcp_port_in = random.randint(1025, 65535)
3676 pkts = self.create_stream_frag(self.pg0,
3677 self.pg1.remote_ip4,
3682 self.pg0.add_stream(pkts)
3683 self.pg_enable_capture(self.pg_interfaces)
3685 self.pg1.assert_nothing_captured()
3687 self.vapi.cli("ipfix flush") # FIXME this should be an API call
3688 capture = self.pg3.get_capture(9)
3689 ipfix = IPFIXDecoder()
3690 # first load template
3692 self.assertTrue(p.haslayer(IPFIX))
3693 self.assertEqual(p[IP].src, self.pg3.local_ip4)
3694 self.assertEqual(p[IP].dst, self.pg3.remote_ip4)
3695 self.assertEqual(p[UDP].sport, self.ipfix_src_port)
3696 self.assertEqual(p[UDP].dport, 4739)
3697 self.assertEqual(p[IPFIX].observationDomainID,
3698 self.ipfix_domain_id)
3699 if p.haslayer(Template):
3700 ipfix.add_template(p.getlayer(Template))
3701 # verify events in data set
3703 if p.haslayer(Data):
3704 data = ipfix.decode_data_set(p.getlayer(Set))
3705 self.verify_ipfix_max_fragments_ip4(data, 1,
3706 self.pg0.remote_ip4n)
3708 def test_multiple_outside_vrf(self):
3709 """ Multiple outside VRF """
3713 self.pg1.unconfig_ip4()
3714 self.pg2.unconfig_ip4()
3715 self.vapi.ip_table_add_del(is_add=1, table_id=vrf_id1)
3716 self.vapi.ip_table_add_del(is_add=1, table_id=vrf_id2)
3717 self.pg1.set_table_ip4(vrf_id1)
3718 self.pg2.set_table_ip4(vrf_id2)
3719 self.pg1.config_ip4()
3720 self.pg2.config_ip4()
3721 self.pg1.resolve_arp()
3722 self.pg2.resolve_arp()
3724 self.nat44_add_address(self.nat_addr)
3725 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
3726 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
3728 self.vapi.nat44_interface_add_del_feature(self.pg2.sw_if_index,
3733 pkts = self.create_stream_in(self.pg0, self.pg1)
3734 self.pg0.add_stream(pkts)
3735 self.pg_enable_capture(self.pg_interfaces)
3737 capture = self.pg1.get_capture(len(pkts))
3738 self.verify_capture_out(capture, self.nat_addr)
3740 pkts = self.create_stream_out(self.pg1, self.nat_addr)
3741 self.pg1.add_stream(pkts)
3742 self.pg_enable_capture(self.pg_interfaces)
3744 capture = self.pg0.get_capture(len(pkts))
3745 self.verify_capture_in(capture, self.pg0)
3747 self.tcp_port_in = 60303
3748 self.udp_port_in = 60304
3749 self.icmp_id_in = 60305
3752 pkts = self.create_stream_in(self.pg0, self.pg2)
3753 self.pg0.add_stream(pkts)
3754 self.pg_enable_capture(self.pg_interfaces)
3756 capture = self.pg2.get_capture(len(pkts))
3757 self.verify_capture_out(capture, self.nat_addr)
3759 pkts = self.create_stream_out(self.pg2, self.nat_addr)
3760 self.pg2.add_stream(pkts)
3761 self.pg_enable_capture(self.pg_interfaces)
3763 capture = self.pg0.get_capture(len(pkts))
3764 self.verify_capture_in(capture, self.pg0)
3767 self.pg1.unconfig_ip4()
3768 self.pg2.unconfig_ip4()
3769 self.pg1.set_table_ip4(0)
3770 self.pg2.set_table_ip4(0)
3771 self.pg1.config_ip4()
3772 self.pg2.config_ip4()
3773 self.pg1.resolve_arp()
3774 self.pg2.resolve_arp()
3776 @unittest.skipUnless(running_extended_tests, "part of extended tests")
3777 def test_session_timeout(self):
3778 """ NAT44 session timeouts """
3779 self.nat44_add_address(self.nat_addr)
3780 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
3781 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
3783 self.vapi.nat_set_timeouts(udp=5)
3787 for i in range(0, max_sessions):
3788 src = "10.10.%u.%u" % ((i & 0xFF00) >> 8, i & 0xFF)
3789 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
3790 IP(src=src, dst=self.pg1.remote_ip4) /
3791 UDP(sport=1025, dport=53))
3793 self.pg0.add_stream(pkts)
3794 self.pg_enable_capture(self.pg_interfaces)
3796 self.pg1.get_capture(max_sessions)
3801 for i in range(0, max_sessions):
3802 src = "10.10.%u.%u" % ((i & 0xFF00) >> 8, i & 0xFF)
3803 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
3804 IP(src=src, dst=self.pg1.remote_ip4) /
3805 UDP(sport=1026, dport=53))
3807 self.pg0.add_stream(pkts)
3808 self.pg_enable_capture(self.pg_interfaces)
3810 self.pg1.get_capture(max_sessions)
3813 users = self.vapi.nat44_user_dump()
3815 nsessions = nsessions + user.nsessions
3816 self.assertLess(nsessions, 2 * max_sessions)
3818 def test_mss_clamping(self):
3819 """ TCP MSS clamping """
3820 self.nat44_add_address(self.nat_addr)
3821 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
3822 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
3825 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
3826 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
3827 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
3828 flags="S", options=[('MSS', 1400)]))
3830 self.vapi.nat_set_mss_clamping(enable=1, mss_value=1000)
3831 self.pg0.add_stream(p)
3832 self.pg_enable_capture(self.pg_interfaces)
3834 capture = self.pg1.get_capture(1)
3835 # Negotiated MSS value greater than configured - changed
3836 self.verify_mss_value(capture[0], 1000)
3838 self.vapi.nat_set_mss_clamping(enable=0)
3839 self.pg0.add_stream(p)
3840 self.pg_enable_capture(self.pg_interfaces)
3842 capture = self.pg1.get_capture(1)
3843 # MSS clamping disabled - negotiated MSS unchanged
3844 self.verify_mss_value(capture[0], 1400)
3846 self.vapi.nat_set_mss_clamping(enable=1, mss_value=1500)
3847 self.pg0.add_stream(p)
3848 self.pg_enable_capture(self.pg_interfaces)
3850 capture = self.pg1.get_capture(1)
3851 # Negotiated MSS value smaller than configured - unchanged
3852 self.verify_mss_value(capture[0], 1400)
3854 @unittest.skipUnless(running_extended_tests, "part of extended tests")
3855 def test_ha_send(self):
3856 """ Send HA session synchronization events (active) """
3857 self.nat44_add_address(self.nat_addr)
3858 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
3859 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
3861 self.vapi.nat_ha_set_listener(self.pg3.local_ip4, port=12345)
3862 self.vapi.nat_ha_set_failover(self.pg3.remote_ip4, port=12346)
3863 bind_layers(UDP, HANATStateSync, sport=12345)
3866 pkts = self.create_stream_in(self.pg0, self.pg1)
3867 self.pg0.add_stream(pkts)
3868 self.pg_enable_capture(self.pg_interfaces)
3870 capture = self.pg1.get_capture(len(pkts))
3871 self.verify_capture_out(capture)
3872 # active send HA events
3873 self.vapi.nat_ha_flush()
3874 stats = self.statistics.get_counter('/nat44/ha/add-event-send')
3875 self.assertEqual(stats[0][0], 3)
3876 capture = self.pg3.get_capture(1)
3878 self.assert_packet_checksums_valid(p)
3882 hanat = p[HANATStateSync]
3884 self.logger.error(ppp("Invalid packet:", p))
3887 self.assertEqual(ip.src, self.pg3.local_ip4)
3888 self.assertEqual(ip.dst, self.pg3.remote_ip4)
3889 self.assertEqual(udp.sport, 12345)
3890 self.assertEqual(udp.dport, 12346)
3891 self.assertEqual(hanat.version, 1)
3892 self.assertEqual(hanat.thread_index, 0)
3893 self.assertEqual(hanat.count, 3)
3894 seq = hanat.sequence_number
3895 for event in hanat.events:
3896 self.assertEqual(event.event_type, 1)
3897 self.assertEqual(event.in_addr, self.pg0.remote_ip4)
3898 self.assertEqual(event.out_addr, self.nat_addr)
3899 self.assertEqual(event.fib_index, 0)
3901 # ACK received events
3902 ack = (Ether(dst=self.pg3.local_mac, src=self.pg3.remote_mac) /
3903 IP(src=self.pg3.remote_ip4, dst=self.pg3.local_ip4) /
3904 UDP(sport=12346, dport=12345) /
3905 HANATStateSync(sequence_number=seq, flags='ACK'))
3906 self.pg3.add_stream(ack)
3908 stats = self.statistics.get_counter('/nat44/ha/ack-recv')
3909 self.assertEqual(stats[0][0], 1)
3911 # delete one session
3912 self.pg_enable_capture(self.pg_interfaces)
3913 self.vapi.nat44_del_session(self.pg0.remote_ip4n, self.tcp_port_in,
3915 self.vapi.nat_ha_flush()
3916 stats = self.statistics.get_counter('/nat44/ha/del-event-send')
3917 self.assertEqual(stats[0][0], 1)
3918 capture = self.pg3.get_capture(1)
3921 hanat = p[HANATStateSync]
3923 self.logger.error(ppp("Invalid packet:", p))
3926 self.assertGreater(hanat.sequence_number, seq)
3928 # do not send ACK, active retry send HA event again
3929 self.pg_enable_capture(self.pg_interfaces)
3931 stats = self.statistics.get_counter('/nat44/ha/retry-count')
3932 self.assertEqual(stats[0][0], 3)
3933 stats = self.statistics.get_counter('/nat44/ha/missed-count')
3934 self.assertEqual(stats[0][0], 1)
3935 capture = self.pg3.get_capture(3)
3936 for packet in capture:
3937 self.assertEqual(packet, p)
3939 # session counters refresh
3940 pkts = self.create_stream_out(self.pg1)
3941 self.pg1.add_stream(pkts)
3942 self.pg_enable_capture(self.pg_interfaces)
3944 self.pg0.get_capture(2)
3945 self.vapi.nat_ha_flush()
3946 stats = self.statistics.get_counter('/nat44/ha/refresh-event-send')
3947 self.assertEqual(stats[0][0], 2)
3948 capture = self.pg3.get_capture(1)
3950 self.assert_packet_checksums_valid(p)
3954 hanat = p[HANATStateSync]
3956 self.logger.error(ppp("Invalid packet:", p))
3959 self.assertEqual(ip.src, self.pg3.local_ip4)
3960 self.assertEqual(ip.dst, self.pg3.remote_ip4)
3961 self.assertEqual(udp.sport, 12345)
3962 self.assertEqual(udp.dport, 12346)
3963 self.assertEqual(hanat.version, 1)
3964 self.assertEqual(hanat.count, 2)
3965 seq = hanat.sequence_number
3966 for event in hanat.events:
3967 self.assertEqual(event.event_type, 3)
3968 self.assertEqual(event.out_addr, self.nat_addr)
3969 self.assertEqual(event.fib_index, 0)
3970 self.assertEqual(event.total_pkts, 2)
3971 self.assertGreater(event.total_bytes, 0)
3973 ack = (Ether(dst=self.pg3.local_mac, src=self.pg3.remote_mac) /
3974 IP(src=self.pg3.remote_ip4, dst=self.pg3.local_ip4) /
3975 UDP(sport=12346, dport=12345) /
3976 HANATStateSync(sequence_number=seq, flags='ACK'))
3977 self.pg3.add_stream(ack)
3979 stats = self.statistics.get_counter('/nat44/ha/ack-recv')
3980 self.assertEqual(stats[0][0], 2)
3982 def test_ha_recv(self):
3983 """ Receive HA session synchronization events (passive) """
3984 self.nat44_add_address(self.nat_addr)
3985 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
3986 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
3988 self.vapi.nat_ha_set_listener(self.pg3.local_ip4, port=12345)
3989 bind_layers(UDP, HANATStateSync, sport=12345)
3991 self.tcp_port_out = random.randint(1025, 65535)
3992 self.udp_port_out = random.randint(1025, 65535)
3994 # send HA session add events to failover/passive
3995 p = (Ether(dst=self.pg3.local_mac, src=self.pg3.remote_mac) /
3996 IP(src=self.pg3.remote_ip4, dst=self.pg3.local_ip4) /
3997 UDP(sport=12346, dport=12345) /
3998 HANATStateSync(sequence_number=1, events=[
3999 Event(event_type='add', protocol='tcp',
4000 in_addr=self.pg0.remote_ip4, out_addr=self.nat_addr,
4001 in_port=self.tcp_port_in, out_port=self.tcp_port_out,
4002 eh_addr=self.pg1.remote_ip4,
4003 ehn_addr=self.pg1.remote_ip4,
4004 eh_port=self.tcp_external_port,
4005 ehn_port=self.tcp_external_port, fib_index=0),
4006 Event(event_type='add', protocol='udp',
4007 in_addr=self.pg0.remote_ip4, out_addr=self.nat_addr,
4008 in_port=self.udp_port_in, out_port=self.udp_port_out,
4009 eh_addr=self.pg1.remote_ip4,
4010 ehn_addr=self.pg1.remote_ip4,
4011 eh_port=self.udp_external_port,
4012 ehn_port=self.udp_external_port, fib_index=0)]))
4014 self.pg3.add_stream(p)
4015 self.pg_enable_capture(self.pg_interfaces)
4018 capture = self.pg3.get_capture(1)
4021 hanat = p[HANATStateSync]
4023 self.logger.error(ppp("Invalid packet:", p))
4026 self.assertEqual(hanat.sequence_number, 1)
4027 self.assertEqual(hanat.flags, 'ACK')
4028 self.assertEqual(hanat.version, 1)
4029 self.assertEqual(hanat.thread_index, 0)
4030 stats = self.statistics.get_counter('/nat44/ha/ack-send')
4031 self.assertEqual(stats[0][0], 1)
4032 stats = self.statistics.get_counter('/nat44/ha/add-event-recv')
4033 self.assertEqual(stats[0][0], 2)
4034 users = self.statistics.get_counter('/nat44/total-users')
4035 self.assertEqual(users[0][0], 1)
4036 sessions = self.statistics.get_counter('/nat44/total-sessions')
4037 self.assertEqual(sessions[0][0], 2)
4038 users = self.vapi.nat44_user_dump()
4039 self.assertEqual(len(users), 1)
4040 self.assertEqual(users[0].ip_address, self.pg0.remote_ip4n)
4041 # there should be 2 sessions created by HA
4042 sessions = self.vapi.nat44_user_session_dump(users[0].ip_address,
4044 self.assertEqual(len(sessions), 2)
4045 for session in sessions:
4046 self.assertEqual(session.inside_ip_address, self.pg0.remote_ip4n)
4047 self.assertEqual(session.outside_ip_address, self.nat_addr_n)
4048 self.assertIn(session.inside_port,
4049 [self.tcp_port_in, self.udp_port_in])
4050 self.assertIn(session.outside_port,
4051 [self.tcp_port_out, self.udp_port_out])
4052 self.assertIn(session.protocol, [IP_PROTOS.tcp, IP_PROTOS.udp])
4054 # send HA session delete event to failover/passive
4055 p = (Ether(dst=self.pg3.local_mac, src=self.pg3.remote_mac) /
4056 IP(src=self.pg3.remote_ip4, dst=self.pg3.local_ip4) /
4057 UDP(sport=12346, dport=12345) /
4058 HANATStateSync(sequence_number=2, events=[
4059 Event(event_type='del', protocol='udp',
4060 in_addr=self.pg0.remote_ip4, out_addr=self.nat_addr,
4061 in_port=self.udp_port_in, out_port=self.udp_port_out,
4062 eh_addr=self.pg1.remote_ip4,
4063 ehn_addr=self.pg1.remote_ip4,
4064 eh_port=self.udp_external_port,
4065 ehn_port=self.udp_external_port, fib_index=0)]))
4067 self.pg3.add_stream(p)
4068 self.pg_enable_capture(self.pg_interfaces)
4071 capture = self.pg3.get_capture(1)
4074 hanat = p[HANATStateSync]
4076 self.logger.error(ppp("Invalid packet:", p))
4079 self.assertEqual(hanat.sequence_number, 2)
4080 self.assertEqual(hanat.flags, 'ACK')
4081 self.assertEqual(hanat.version, 1)
4082 users = self.vapi.nat44_user_dump()
4083 self.assertEqual(len(users), 1)
4084 self.assertEqual(users[0].ip_address, self.pg0.remote_ip4n)
4085 # now we should have only 1 session, 1 deleted by HA
4086 sessions = self.vapi.nat44_user_session_dump(users[0].ip_address,
4088 self.assertEqual(len(sessions), 1)
4089 stats = self.statistics.get_counter('/nat44/ha/del-event-recv')
4090 self.assertEqual(stats[0][0], 1)
4092 stats = self.statistics.get_counter('/err/nat-ha/pkts-processed')
4093 self.assertEqual(stats, 2)
4095 # send HA session refresh event to failover/passive
4096 p = (Ether(dst=self.pg3.local_mac, src=self.pg3.remote_mac) /
4097 IP(src=self.pg3.remote_ip4, dst=self.pg3.local_ip4) /
4098 UDP(sport=12346, dport=12345) /
4099 HANATStateSync(sequence_number=3, events=[
4100 Event(event_type='refresh', protocol='tcp',
4101 in_addr=self.pg0.remote_ip4, out_addr=self.nat_addr,
4102 in_port=self.tcp_port_in, out_port=self.tcp_port_out,
4103 eh_addr=self.pg1.remote_ip4,
4104 ehn_addr=self.pg1.remote_ip4,
4105 eh_port=self.tcp_external_port,
4106 ehn_port=self.tcp_external_port, fib_index=0,
4107 total_bytes=1024, total_pkts=2)]))
4108 self.pg3.add_stream(p)
4109 self.pg_enable_capture(self.pg_interfaces)
4112 capture = self.pg3.get_capture(1)
4115 hanat = p[HANATStateSync]
4117 self.logger.error(ppp("Invalid packet:", p))
4120 self.assertEqual(hanat.sequence_number, 3)
4121 self.assertEqual(hanat.flags, 'ACK')
4122 self.assertEqual(hanat.version, 1)
4123 users = self.vapi.nat44_user_dump()
4124 self.assertEqual(len(users), 1)
4125 self.assertEqual(users[0].ip_address, self.pg0.remote_ip4n)
4126 sessions = self.vapi.nat44_user_session_dump(users[0].ip_address,
4128 self.assertEqual(len(sessions), 1)
4129 session = sessions[0]
4130 self.assertEqual(session.total_bytes, 1024)
4131 self.assertEqual(session.total_pkts, 2)
4132 stats = self.statistics.get_counter('/nat44/ha/refresh-event-recv')
4133 self.assertEqual(stats[0][0], 1)
4135 stats = self.statistics.get_counter('/err/nat-ha/pkts-processed')
4136 self.assertEqual(stats, 3)
4138 # send packet to test session created by HA
4139 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
4140 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
4141 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out))
4142 self.pg1.add_stream(p)
4143 self.pg_enable_capture(self.pg_interfaces)
4145 capture = self.pg0.get_capture(1)
4151 self.logger.error(ppp("Invalid packet:", p))
4154 self.assertEqual(ip.src, self.pg1.remote_ip4)
4155 self.assertEqual(ip.dst, self.pg0.remote_ip4)
4156 self.assertEqual(tcp.sport, self.tcp_external_port)
4157 self.assertEqual(tcp.dport, self.tcp_port_in)
4160 super(TestNAT44, self).tearDown()
4161 if not self.vpp_dead:
4162 self.logger.info(self.vapi.cli("show nat44 addresses"))
4163 self.logger.info(self.vapi.cli("show nat44 interfaces"))
4164 self.logger.info(self.vapi.cli("show nat44 static mappings"))
4165 self.logger.info(self.vapi.cli("show nat44 interface address"))
4166 self.logger.info(self.vapi.cli("show nat44 sessions detail"))
4167 self.logger.info(self.vapi.cli("show nat virtual-reassembly"))
4168 self.logger.info(self.vapi.cli("show nat44 hash tables detail"))
4169 self.logger.info(self.vapi.cli("show nat timeouts"))
4171 self.vapi.cli("show nat addr-port-assignment-alg"))
4172 self.logger.info(self.vapi.cli("show nat ha"))
4174 self.vapi.cli("clear logging")
4177 class TestNAT44EndpointDependent(MethodHolder):
4178 """ Endpoint-Dependent mapping and filtering test cases """
4181 def setUpConstants(cls):
4182 super(TestNAT44EndpointDependent, cls).setUpConstants()
4183 cls.vpp_cmdline.extend(["nat", "{", "endpoint-dependent", "}"])
4186 def setUpClass(cls):
4187 super(TestNAT44EndpointDependent, cls).setUpClass()
4188 cls.vapi.cli("set log class nat level debug")
4190 cls.tcp_port_in = 6303
4191 cls.tcp_port_out = 6303
4192 cls.udp_port_in = 6304
4193 cls.udp_port_out = 6304
4194 cls.icmp_id_in = 6305
4195 cls.icmp_id_out = 6305
4196 cls.nat_addr = '10.0.0.3'
4197 cls.nat_addr_n = socket.inet_pton(socket.AF_INET, cls.nat_addr)
4198 cls.ipfix_src_port = 4739
4199 cls.ipfix_domain_id = 1
4200 cls.tcp_external_port = 80
4202 cls.create_pg_interfaces(range(7))
4203 cls.interfaces = list(cls.pg_interfaces[0:3])
4205 for i in cls.interfaces:
4210 cls.pg0.generate_remote_hosts(3)
4211 cls.pg0.configure_ipv4_neighbors()
4215 cls.pg4.generate_remote_hosts(2)
4216 cls.pg4.config_ip4()
4217 cls.vapi.sw_interface_add_del_address(
4218 sw_if_index=cls.pg4.sw_if_index,
4219 prefix=VppIpPrefix("10.0.0.1", 24).encode())
4222 cls.pg4.resolve_arp()
4223 cls.pg4._remote_hosts[1]._ip4 = cls.pg4._remote_hosts[0]._ip4
4224 cls.pg4.resolve_arp()
4226 zero_ip4n = socket.inet_pton(socket.AF_INET, "0.0.0.0")
4227 cls.vapi.ip_table_add_del(is_add=1, table_id=1)
4229 cls.pg5._local_ip4 = VppIpPrefix("10.1.1.1",
4230 cls.pg5.local_ip4_prefix.len)
4231 cls.pg5._remote_hosts[0]._ip4 = "10.1.1.2"
4232 cls.pg5._remote_hosts[0]._ip4n = socket.inet_pton(
4233 socket.AF_INET, cls.pg5.remote_ip4)
4234 cls.pg5.set_table_ip4(1)
4235 cls.pg5.config_ip4()
4237 cls.vapi.ip_add_del_route(dst_address=cls.pg5.remote_ip4n,
4238 dst_address_length=32,
4239 next_hop_address=zero_ip4n,
4240 next_hop_sw_if_index=cls.pg5.sw_if_index,
4243 cls.pg6._local_ip4 = VppIpPrefix("10.1.2.1",
4244 cls.pg6.local_ip4_prefix.len)
4245 cls.pg6._remote_hosts[0]._ip4 = "10.1.2.2"
4246 cls.pg6._remote_hosts[0]._ip4n = socket.inet_pton(
4247 socket.AF_INET, cls.pg6.remote_ip4)
4248 cls.pg6.set_table_ip4(1)
4249 cls.pg6.config_ip4()
4251 cls.vapi.ip_add_del_route(dst_address=cls.pg6.remote_ip4n,
4252 dst_address_length=32,
4253 next_hop_address=zero_ip4n,
4254 next_hop_sw_if_index=cls.pg6.sw_if_index,
4257 cls.vapi.ip_add_del_route(dst_address=cls.pg6.remote_ip4n,
4258 dst_address_length=16,
4259 next_hop_address=zero_ip4n, table_id=0,
4260 next_hop_table_id=1)
4261 cls.vapi.ip_add_del_route(dst_address=zero_ip4n,
4262 dst_address_length=0,
4263 next_hop_address=zero_ip4n, table_id=1,
4264 next_hop_table_id=0)
4265 cls.vapi.ip_add_del_route(dst_address=zero_ip4n,
4266 dst_address_length=0,
4267 next_hop_address=cls.pg1.local_ip4n,
4268 next_hop_sw_if_index=cls.pg1.sw_if_index,
4271 cls.pg5.resolve_arp()
4272 cls.pg6.resolve_arp()
4275 super(TestNAT44EndpointDependent, cls).tearDownClass()
4278 def test_frag_in_order(self):
4279 """ NAT44 translate fragments arriving in order """
4280 self.nat44_add_address(self.nat_addr)
4281 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
4282 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
4284 self.frag_in_order(proto=IP_PROTOS.tcp)
4285 self.frag_in_order(proto=IP_PROTOS.udp)
4286 self.frag_in_order(proto=IP_PROTOS.icmp)
4288 def test_frag_in_order_dont_translate(self):
4289 """ NAT44 don't translate fragments arriving in order """
4290 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
4291 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
4293 self.vapi.nat44_forwarding_enable_disable(enable=True)
4294 self.frag_in_order(proto=IP_PROTOS.tcp, dont_translate=True)
4296 def test_frag_out_of_order(self):
4297 """ NAT44 translate fragments arriving out of order """
4298 self.nat44_add_address(self.nat_addr)
4299 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
4300 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
4302 self.frag_out_of_order(proto=IP_PROTOS.tcp)
4303 self.frag_out_of_order(proto=IP_PROTOS.udp)
4304 self.frag_out_of_order(proto=IP_PROTOS.icmp)
4306 def test_frag_out_of_order_dont_translate(self):
4307 """ NAT44 don't translate fragments arriving out of order """
4308 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
4309 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
4311 self.vapi.nat44_forwarding_enable_disable(enable=True)
4312 self.frag_out_of_order(proto=IP_PROTOS.tcp, dont_translate=True)
4314 def test_frag_in_order_in_plus_out(self):
4315 """ in+out interface fragments in order """
4316 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
4317 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index,
4319 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index)
4320 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
4323 self.server = self.pg1.remote_hosts[0]
4325 self.server_in_addr = self.server.ip4
4326 self.server_out_addr = '11.11.11.11'
4327 self.server_in_port = random.randint(1025, 65535)
4328 self.server_out_port = random.randint(1025, 65535)
4330 self.nat44_add_address(self.server_out_addr)
4332 # add static mappings for server
4333 self.nat44_add_static_mapping(self.server_in_addr,
4334 self.server_out_addr,
4335 self.server_in_port,
4336 self.server_out_port,
4337 proto=IP_PROTOS.tcp)
4338 self.nat44_add_static_mapping(self.server_in_addr,
4339 self.server_out_addr,
4340 self.server_in_port,
4341 self.server_out_port,
4342 proto=IP_PROTOS.udp)
4343 self.nat44_add_static_mapping(self.server_in_addr,
4344 self.server_out_addr,
4345 proto=IP_PROTOS.icmp)
4347 self.vapi.nat_set_reass(timeout=10)
4349 self.frag_in_order_in_plus_out(proto=IP_PROTOS.tcp)
4350 self.frag_in_order_in_plus_out(proto=IP_PROTOS.udp)
4351 self.frag_in_order_in_plus_out(proto=IP_PROTOS.icmp)
4353 def test_frag_out_of_order_in_plus_out(self):
4354 """ in+out interface fragments out of order """
4355 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
4356 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index,
4358 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index)
4359 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
4362 self.server = self.pg1.remote_hosts[0]
4364 self.server_in_addr = self.server.ip4
4365 self.server_out_addr = '11.11.11.11'
4366 self.server_in_port = random.randint(1025, 65535)
4367 self.server_out_port = random.randint(1025, 65535)
4369 self.nat44_add_address(self.server_out_addr)
4371 # add static mappings for server
4372 self.nat44_add_static_mapping(self.server_in_addr,
4373 self.server_out_addr,
4374 self.server_in_port,
4375 self.server_out_port,
4376 proto=IP_PROTOS.tcp)
4377 self.nat44_add_static_mapping(self.server_in_addr,
4378 self.server_out_addr,
4379 self.server_in_port,
4380 self.server_out_port,
4381 proto=IP_PROTOS.udp)
4382 self.nat44_add_static_mapping(self.server_in_addr,
4383 self.server_out_addr,
4384 proto=IP_PROTOS.icmp)
4386 self.vapi.nat_set_reass(timeout=10)
4388 self.frag_out_of_order_in_plus_out(proto=IP_PROTOS.tcp)
4389 self.frag_out_of_order_in_plus_out(proto=IP_PROTOS.udp)
4390 self.frag_out_of_order_in_plus_out(proto=IP_PROTOS.icmp)
4392 def test_reass_hairpinning(self):
4393 """ NAT44 fragments hairpinning """
4394 self.server = self.pg0.remote_hosts[1]
4395 self.host_in_port = random.randint(1025, 65535)
4396 self.server_in_port = random.randint(1025, 65535)
4397 self.server_out_port = random.randint(1025, 65535)
4399 self.nat44_add_address(self.nat_addr)
4400 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
4401 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
4403 # add static mapping for server
4404 self.nat44_add_static_mapping(self.server.ip4, self.nat_addr,
4405 self.server_in_port,
4406 self.server_out_port,
4407 proto=IP_PROTOS.tcp)
4408 self.nat44_add_static_mapping(self.server.ip4, self.nat_addr,
4409 self.server_in_port,
4410 self.server_out_port,
4411 proto=IP_PROTOS.udp)
4412 self.nat44_add_static_mapping(self.server.ip4, self.nat_addr)
4414 self.reass_hairpinning(proto=IP_PROTOS.tcp)
4415 self.reass_hairpinning(proto=IP_PROTOS.udp)
4416 self.reass_hairpinning(proto=IP_PROTOS.icmp)
4418 def test_dynamic(self):
4419 """ NAT44 dynamic translation test """
4421 self.nat44_add_address(self.nat_addr)
4422 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
4423 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
4426 nat_config = self.vapi.nat_show_config()
4427 self.assertEqual(1, nat_config.endpoint_dependent)
4430 tcpn = self.statistics.get_counter(
4431 '/err/nat44-ed-in2out-slowpath/TCP packets')
4432 udpn = self.statistics.get_counter(
4433 '/err/nat44-ed-in2out-slowpath/UDP packets')
4434 icmpn = self.statistics.get_counter(
4435 '/err/nat44-ed-in2out-slowpath/ICMP packets')
4436 totaln = self.statistics.get_counter(
4437 '/err/nat44-ed-in2out-slowpath/good in2out packets processed')
4439 pkts = self.create_stream_in(self.pg0, self.pg1)
4440 self.pg0.add_stream(pkts)
4441 self.pg_enable_capture(self.pg_interfaces)
4443 capture = self.pg1.get_capture(len(pkts))
4444 self.verify_capture_out(capture)
4446 err = self.statistics.get_counter(
4447 '/err/nat44-ed-in2out-slowpath/TCP packets')
4448 self.assertEqual(err - tcpn, 1)
4449 err = self.statistics.get_counter(
4450 '/err/nat44-ed-in2out-slowpath/UDP packets')
4451 self.assertEqual(err - udpn, 1)
4452 err = self.statistics.get_counter(
4453 '/err/nat44-ed-in2out-slowpath/ICMP packets')
4454 self.assertEqual(err - icmpn, 1)
4455 err = self.statistics.get_counter(
4456 '/err/nat44-ed-in2out-slowpath/good in2out packets processed')
4457 self.assertEqual(err - totaln, 3)
4460 tcpn = self.statistics.get_counter('/err/nat44-ed-out2in/TCP packets')
4461 udpn = self.statistics.get_counter('/err/nat44-ed-out2in/UDP packets')
4462 icmpn = self.statistics.get_counter(
4463 '/err/nat44-ed-out2in-slowpath/ICMP packets')
4464 totaln = self.statistics.get_counter(
4465 '/err/nat44-ed-out2in/good out2in packets processed')
4467 pkts = self.create_stream_out(self.pg1)
4468 self.pg1.add_stream(pkts)
4469 self.pg_enable_capture(self.pg_interfaces)
4471 capture = self.pg0.get_capture(len(pkts))
4472 self.verify_capture_in(capture, self.pg0)
4474 err = self.statistics.get_counter('/err/nat44-ed-out2in/TCP packets')
4475 self.assertEqual(err - tcpn, 1)
4476 err = self.statistics.get_counter('/err/nat44-ed-out2in/UDP packets')
4477 self.assertEqual(err - udpn, 1)
4478 err = self.statistics.get_counter(
4479 '/err/nat44-ed-out2in-slowpath/ICMP packets')
4480 self.assertEqual(err - icmpn, 1)
4481 err = self.statistics.get_counter(
4482 '/err/nat44-ed-out2in/good out2in packets processed')
4483 self.assertEqual(err - totaln, 2)
4485 users = self.statistics.get_counter('/nat44/total-users')
4486 self.assertEqual(users[0][0], 1)
4487 sessions = self.statistics.get_counter('/nat44/total-sessions')
4488 self.assertEqual(sessions[0][0], 3)
4490 def test_forwarding(self):
4491 """ NAT44 forwarding test """
4493 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
4494 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
4496 self.vapi.nat44_forwarding_enable_disable(1)
4498 real_ip = self.pg0.remote_ip4n
4499 alias_ip = self.nat_addr_n
4500 self.vapi.nat44_add_del_static_mapping(local_ip=real_ip,
4501 external_ip=alias_ip)
4504 # in2out - static mapping match
4506 pkts = self.create_stream_out(self.pg1)
4507 self.pg1.add_stream(pkts)
4508 self.pg_enable_capture(self.pg_interfaces)
4510 capture = self.pg0.get_capture(len(pkts))
4511 self.verify_capture_in(capture, self.pg0)
4513 pkts = self.create_stream_in(self.pg0, self.pg1)
4514 self.pg0.add_stream(pkts)
4515 self.pg_enable_capture(self.pg_interfaces)
4517 capture = self.pg1.get_capture(len(pkts))
4518 self.verify_capture_out(capture, same_port=True)
4520 # in2out - no static mapping match
4522 host0 = self.pg0.remote_hosts[0]
4523 self.pg0.remote_hosts[0] = self.pg0.remote_hosts[1]
4525 pkts = self.create_stream_out(self.pg1,
4526 dst_ip=self.pg0.remote_ip4,
4527 use_inside_ports=True)
4528 self.pg1.add_stream(pkts)
4529 self.pg_enable_capture(self.pg_interfaces)
4531 capture = self.pg0.get_capture(len(pkts))
4532 self.verify_capture_in(capture, self.pg0)
4534 pkts = self.create_stream_in(self.pg0, self.pg1)
4535 self.pg0.add_stream(pkts)
4536 self.pg_enable_capture(self.pg_interfaces)
4538 capture = self.pg1.get_capture(len(pkts))
4539 self.verify_capture_out(capture, nat_ip=self.pg0.remote_ip4,
4542 self.pg0.remote_hosts[0] = host0
4544 user = self.pg0.remote_hosts[1]
4545 sessions = self.vapi.nat44_user_session_dump(user.ip4n, 0)
4546 self.assertEqual(len(sessions), 3)
4547 self.assertTrue(sessions[0].ext_host_valid)
4548 self.vapi.nat44_del_session(
4549 sessions[0].inside_ip_address,
4550 sessions[0].inside_port,
4551 sessions[0].protocol,
4552 ext_host_address=sessions[0].ext_host_address,
4553 ext_host_port=sessions[0].ext_host_port)
4554 sessions = self.vapi.nat44_user_session_dump(user.ip4n, 0)
4555 self.assertEqual(len(sessions), 2)
4558 self.vapi.nat44_forwarding_enable_disable(0)
4559 self.vapi.nat44_add_del_static_mapping(local_ip=real_ip,
4560 external_ip=alias_ip,
4563 def test_static_lb(self):
4564 """ NAT44 local service load balancing """
4565 external_addr_n = socket.inet_pton(socket.AF_INET, self.nat_addr)
4568 server1 = self.pg0.remote_hosts[0]
4569 server2 = self.pg0.remote_hosts[1]
4571 locals = [{'addr': server1.ip4n,
4575 {'addr': server2.ip4n,
4580 self.nat44_add_address(self.nat_addr)
4581 self.vapi.nat44_add_del_lb_static_mapping(external_addr_n,
4584 local_num=len(locals),
4586 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
4587 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
4590 # from client to service
4591 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
4592 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
4593 TCP(sport=12345, dport=external_port))
4594 self.pg1.add_stream(p)
4595 self.pg_enable_capture(self.pg_interfaces)
4597 capture = self.pg0.get_capture(1)
4603 self.assertIn(ip.dst, [server1.ip4, server2.ip4])
4604 if ip.dst == server1.ip4:
4608 self.assertEqual(tcp.dport, local_port)
4609 self.assert_packet_checksums_valid(p)
4611 self.logger.error(ppp("Unexpected or invalid packet:", p))
4614 # from service back to client
4615 p = (Ether(src=server.mac, dst=self.pg0.local_mac) /
4616 IP(src=server.ip4, dst=self.pg1.remote_ip4) /
4617 TCP(sport=local_port, dport=12345))
4618 self.pg0.add_stream(p)
4619 self.pg_enable_capture(self.pg_interfaces)
4621 capture = self.pg1.get_capture(1)
4626 self.assertEqual(ip.src, self.nat_addr)
4627 self.assertEqual(tcp.sport, external_port)
4628 self.assert_packet_checksums_valid(p)
4630 self.logger.error(ppp("Unexpected or invalid packet:", p))
4633 sessions = self.vapi.nat44_user_session_dump(server.ip4n, 0)
4634 self.assertEqual(len(sessions), 1)
4635 self.assertTrue(sessions[0].ext_host_valid)
4636 self.vapi.nat44_del_session(
4637 sessions[0].inside_ip_address,
4638 sessions[0].inside_port,
4639 sessions[0].protocol,
4640 ext_host_address=sessions[0].ext_host_address,
4641 ext_host_port=sessions[0].ext_host_port)
4642 sessions = self.vapi.nat44_user_session_dump(server.ip4n, 0)
4643 self.assertEqual(len(sessions), 0)
4645 @unittest.skipUnless(running_extended_tests, "part of extended tests")
4646 def test_static_lb_multi_clients(self):
4647 """ NAT44 local service load balancing - multiple clients"""
4649 external_addr_n = socket.inet_pton(socket.AF_INET, self.nat_addr)
4652 server1 = self.pg0.remote_hosts[0]
4653 server2 = self.pg0.remote_hosts[1]
4654 server3 = self.pg0.remote_hosts[2]
4656 locals = [{'addr': server1.ip4n,
4660 {'addr': server2.ip4n,
4665 self.nat44_add_address(self.nat_addr)
4666 self.vapi.nat44_add_del_lb_static_mapping(external_addr_n,
4669 local_num=len(locals),
4671 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
4672 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
4677 clients = ip4_range(self.pg1.remote_ip4, 10, 50)
4679 for client in clients:
4680 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
4681 IP(src=client, dst=self.nat_addr) /
4682 TCP(sport=12345, dport=external_port))
4684 self.pg1.add_stream(pkts)
4685 self.pg_enable_capture(self.pg_interfaces)
4687 capture = self.pg0.get_capture(len(pkts))
4689 if p[IP].dst == server1.ip4:
4693 self.assertGreater(server1_n, server2_n)
4696 self.vapi.nat44_lb_static_mapping_add_del_local(external_addr_n,
4705 clients = ip4_range(self.pg1.remote_ip4, 60, 110)
4707 for client in clients:
4708 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
4709 IP(src=client, dst=self.nat_addr) /
4710 TCP(sport=12346, dport=external_port))
4712 self.assertGreater(len(pkts), 0)
4713 self.pg1.add_stream(pkts)
4714 self.pg_enable_capture(self.pg_interfaces)
4716 capture = self.pg0.get_capture(len(pkts))
4718 if p[IP].dst == server1.ip4:
4720 elif p[IP].dst == server2.ip4:
4724 self.assertGreater(server1_n, 0)
4725 self.assertGreater(server2_n, 0)
4726 self.assertGreater(server3_n, 0)
4728 # remove one back-end
4729 self.vapi.nat44_lb_static_mapping_add_del_local(external_addr_n,
4739 self.pg1.add_stream(pkts)
4740 self.pg_enable_capture(self.pg_interfaces)
4742 capture = self.pg0.get_capture(len(pkts))
4744 if p[IP].dst == server1.ip4:
4746 elif p[IP].dst == server2.ip4:
4750 self.assertGreater(server1_n, 0)
4751 self.assertEqual(server2_n, 0)
4752 self.assertGreater(server3_n, 0)
4754 def test_static_lb_2(self):
4755 """ NAT44 local service load balancing (asymmetrical rule) """
4756 external_addr_n = socket.inet_pton(socket.AF_INET, self.nat_addr)
4759 server1 = self.pg0.remote_hosts[0]
4760 server2 = self.pg0.remote_hosts[1]
4762 locals = [{'addr': server1.ip4n,
4766 {'addr': server2.ip4n,
4771 self.vapi.nat44_forwarding_enable_disable(1)
4772 self.vapi.nat44_add_del_lb_static_mapping(external_addr_n,
4776 local_num=len(locals),
4778 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
4779 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
4782 # from client to service
4783 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
4784 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
4785 TCP(sport=12345, dport=external_port))
4786 self.pg1.add_stream(p)
4787 self.pg_enable_capture(self.pg_interfaces)
4789 capture = self.pg0.get_capture(1)
4795 self.assertIn(ip.dst, [server1.ip4, server2.ip4])
4796 if ip.dst == server1.ip4:
4800 self.assertEqual(tcp.dport, local_port)
4801 self.assert_packet_checksums_valid(p)
4803 self.logger.error(ppp("Unexpected or invalid packet:", p))
4806 # from service back to client
4807 p = (Ether(src=server.mac, dst=self.pg0.local_mac) /
4808 IP(src=server.ip4, dst=self.pg1.remote_ip4) /
4809 TCP(sport=local_port, dport=12345))
4810 self.pg0.add_stream(p)
4811 self.pg_enable_capture(self.pg_interfaces)
4813 capture = self.pg1.get_capture(1)
4818 self.assertEqual(ip.src, self.nat_addr)
4819 self.assertEqual(tcp.sport, external_port)
4820 self.assert_packet_checksums_valid(p)
4822 self.logger.error(ppp("Unexpected or invalid packet:", p))
4825 # from client to server (no translation)
4826 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
4827 IP(src=self.pg1.remote_ip4, dst=server1.ip4) /
4828 TCP(sport=12346, dport=local_port))
4829 self.pg1.add_stream(p)
4830 self.pg_enable_capture(self.pg_interfaces)
4832 capture = self.pg0.get_capture(1)
4838 self.assertEqual(ip.dst, server1.ip4)
4839 self.assertEqual(tcp.dport, local_port)
4840 self.assert_packet_checksums_valid(p)
4842 self.logger.error(ppp("Unexpected or invalid packet:", p))
4845 # from service back to client (no translation)
4846 p = (Ether(src=server1.mac, dst=self.pg0.local_mac) /
4847 IP(src=server1.ip4, dst=self.pg1.remote_ip4) /
4848 TCP(sport=local_port, dport=12346))
4849 self.pg0.add_stream(p)
4850 self.pg_enable_capture(self.pg_interfaces)
4852 capture = self.pg1.get_capture(1)
4857 self.assertEqual(ip.src, server1.ip4)
4858 self.assertEqual(tcp.sport, local_port)
4859 self.assert_packet_checksums_valid(p)
4861 self.logger.error(ppp("Unexpected or invalid packet:", p))
4864 def test_lb_affinity(self):
4865 """ NAT44 local service load balancing affinity """
4866 external_addr_n = socket.inet_pton(socket.AF_INET, self.nat_addr)
4869 server1 = self.pg0.remote_hosts[0]
4870 server2 = self.pg0.remote_hosts[1]
4872 locals = [{'addr': server1.ip4n,
4876 {'addr': server2.ip4n,
4881 self.nat44_add_address(self.nat_addr)
4882 self.vapi.nat44_add_del_lb_static_mapping(external_addr_n,
4886 local_num=len(locals),
4888 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
4889 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
4892 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
4893 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
4894 TCP(sport=1025, dport=external_port))
4895 self.pg1.add_stream(p)
4896 self.pg_enable_capture(self.pg_interfaces)
4898 capture = self.pg0.get_capture(1)
4899 backend = capture[0][IP].dst
4901 sessions = self.vapi.nat44_user_session_dump(
4902 socket.inet_pton(socket.AF_INET, backend), 0)
4903 self.assertEqual(len(sessions), 1)
4904 self.assertTrue(sessions[0].ext_host_valid)
4905 self.vapi.nat44_del_session(
4906 sessions[0].inside_ip_address,
4907 sessions[0].inside_port,
4908 sessions[0].protocol,
4909 ext_host_address=sessions[0].ext_host_address,
4910 ext_host_port=sessions[0].ext_host_port)
4913 for port in range(1030, 1100):
4914 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
4915 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
4916 TCP(sport=port, dport=external_port))
4918 self.pg1.add_stream(pkts)
4919 self.pg_enable_capture(self.pg_interfaces)
4921 capture = self.pg0.get_capture(len(pkts))
4923 self.assertEqual(p[IP].dst, backend)
4925 def test_unknown_proto(self):
4926 """ NAT44 translate packet with unknown protocol """
4927 self.nat44_add_address(self.nat_addr)
4928 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
4929 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
4933 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
4934 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
4935 TCP(sport=self.tcp_port_in, dport=20))
4936 self.pg0.add_stream(p)
4937 self.pg_enable_capture(self.pg_interfaces)
4939 p = self.pg1.get_capture(1)
4941 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
4942 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
4944 IP(src=self.pg2.remote_ip4, dst=self.pg2.remote_ip4) /
4945 TCP(sport=1234, dport=1234))
4946 self.pg0.add_stream(p)
4947 self.pg_enable_capture(self.pg_interfaces)
4949 p = self.pg1.get_capture(1)
4952 self.assertEqual(packet[IP].src, self.nat_addr)
4953 self.assertEqual(packet[IP].dst, self.pg1.remote_ip4)
4954 self.assertEqual(packet.haslayer(GRE), 1)
4955 self.assert_packet_checksums_valid(packet)
4957 self.logger.error(ppp("Unexpected or invalid packet:", packet))
4961 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
4962 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
4964 IP(src=self.pg2.remote_ip4, dst=self.pg2.remote_ip4) /
4965 TCP(sport=1234, dport=1234))
4966 self.pg1.add_stream(p)
4967 self.pg_enable_capture(self.pg_interfaces)
4969 p = self.pg0.get_capture(1)
4972 self.assertEqual(packet[IP].src, self.pg1.remote_ip4)
4973 self.assertEqual(packet[IP].dst, self.pg0.remote_ip4)
4974 self.assertEqual(packet.haslayer(GRE), 1)
4975 self.assert_packet_checksums_valid(packet)
4977 self.logger.error(ppp("Unexpected or invalid packet:", packet))
4980 def test_hairpinning_unknown_proto(self):
4981 """ NAT44 translate packet with unknown protocol - hairpinning """
4982 host = self.pg0.remote_hosts[0]
4983 server = self.pg0.remote_hosts[1]
4985 server_out_port = 8765
4986 server_nat_ip = "10.0.0.11"
4988 self.nat44_add_address(self.nat_addr)
4989 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
4990 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
4993 # add static mapping for server
4994 self.nat44_add_static_mapping(server.ip4, server_nat_ip)
4997 p = (Ether(src=host.mac, dst=self.pg0.local_mac) /
4998 IP(src=host.ip4, dst=server_nat_ip) /
4999 TCP(sport=host_in_port, dport=server_out_port))
5000 self.pg0.add_stream(p)
5001 self.pg_enable_capture(self.pg_interfaces)
5003 self.pg0.get_capture(1)
5005 p = (Ether(dst=self.pg0.local_mac, src=host.mac) /
5006 IP(src=host.ip4, dst=server_nat_ip) /
5008 IP(src=self.pg2.remote_ip4, dst=self.pg2.remote_ip4) /
5009 TCP(sport=1234, dport=1234))
5010 self.pg0.add_stream(p)
5011 self.pg_enable_capture(self.pg_interfaces)
5013 p = self.pg0.get_capture(1)
5016 self.assertEqual(packet[IP].src, self.nat_addr)
5017 self.assertEqual(packet[IP].dst, server.ip4)
5018 self.assertEqual(packet.haslayer(GRE), 1)
5019 self.assert_packet_checksums_valid(packet)
5021 self.logger.error(ppp("Unexpected or invalid packet:", packet))
5025 p = (Ether(dst=self.pg0.local_mac, src=server.mac) /
5026 IP(src=server.ip4, dst=self.nat_addr) /
5028 IP(src=self.pg2.remote_ip4, dst=self.pg2.remote_ip4) /
5029 TCP(sport=1234, dport=1234))
5030 self.pg0.add_stream(p)
5031 self.pg_enable_capture(self.pg_interfaces)
5033 p = self.pg0.get_capture(1)
5036 self.assertEqual(packet[IP].src, server_nat_ip)
5037 self.assertEqual(packet[IP].dst, host.ip4)
5038 self.assertEqual(packet.haslayer(GRE), 1)
5039 self.assert_packet_checksums_valid(packet)
5041 self.logger.error(ppp("Unexpected or invalid packet:", packet))
5044 def test_output_feature_and_service(self):
5045 """ NAT44 interface output feature and services """
5046 external_addr = '1.2.3.4'
5050 self.vapi.nat44_forwarding_enable_disable(1)
5051 self.nat44_add_address(self.nat_addr)
5052 self.vapi.nat44_add_del_identity_mapping(ip=self.pg1.remote_ip4n)
5053 self.nat44_add_static_mapping(self.pg0.remote_ip4, external_addr,
5054 local_port, external_port,
5055 proto=IP_PROTOS.tcp, out2in_only=1)
5056 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
5057 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index,
5059 self.vapi.nat44_interface_add_del_output_feature(self.pg1.sw_if_index,
5062 # from client to service
5063 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
5064 IP(src=self.pg1.remote_ip4, dst=external_addr) /
5065 TCP(sport=12345, dport=external_port))
5066 self.pg1.add_stream(p)
5067 self.pg_enable_capture(self.pg_interfaces)
5069 capture = self.pg0.get_capture(1)
5074 self.assertEqual(ip.dst, self.pg0.remote_ip4)
5075 self.assertEqual(tcp.dport, local_port)
5076 self.assert_packet_checksums_valid(p)
5078 self.logger.error(ppp("Unexpected or invalid packet:", p))
5081 # from service back to client
5082 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5083 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
5084 TCP(sport=local_port, dport=12345))
5085 self.pg0.add_stream(p)
5086 self.pg_enable_capture(self.pg_interfaces)
5088 capture = self.pg1.get_capture(1)
5093 self.assertEqual(ip.src, external_addr)
5094 self.assertEqual(tcp.sport, external_port)
5095 self.assert_packet_checksums_valid(p)
5097 self.logger.error(ppp("Unexpected or invalid packet:", p))
5100 # from local network host to external network
5101 pkts = self.create_stream_in(self.pg0, self.pg1)
5102 self.pg0.add_stream(pkts)
5103 self.pg_enable_capture(self.pg_interfaces)
5105 capture = self.pg1.get_capture(len(pkts))
5106 self.verify_capture_out(capture)
5107 pkts = self.create_stream_in(self.pg0, self.pg1)
5108 self.pg0.add_stream(pkts)
5109 self.pg_enable_capture(self.pg_interfaces)
5111 capture = self.pg1.get_capture(len(pkts))
5112 self.verify_capture_out(capture)
5114 # from external network back to local network host
5115 pkts = self.create_stream_out(self.pg1)
5116 self.pg1.add_stream(pkts)
5117 self.pg_enable_capture(self.pg_interfaces)
5119 capture = self.pg0.get_capture(len(pkts))
5120 self.verify_capture_in(capture, self.pg0)
5122 def test_output_feature_and_service2(self):
5123 """ NAT44 interface output feature and service host direct access """
5124 self.vapi.nat44_forwarding_enable_disable(1)
5125 self.nat44_add_address(self.nat_addr)
5126 self.vapi.nat44_interface_add_del_output_feature(self.pg1.sw_if_index,
5129 # session initiaded from service host - translate
5130 pkts = self.create_stream_in(self.pg0, self.pg1)
5131 self.pg0.add_stream(pkts)
5132 self.pg_enable_capture(self.pg_interfaces)
5134 capture = self.pg1.get_capture(len(pkts))
5135 self.verify_capture_out(capture)
5137 pkts = self.create_stream_out(self.pg1)
5138 self.pg1.add_stream(pkts)
5139 self.pg_enable_capture(self.pg_interfaces)
5141 capture = self.pg0.get_capture(len(pkts))
5142 self.verify_capture_in(capture, self.pg0)
5144 # session initiaded from remote host - do not translate
5145 self.tcp_port_in = 60303
5146 self.udp_port_in = 60304
5147 self.icmp_id_in = 60305
5148 pkts = self.create_stream_out(self.pg1,
5149 self.pg0.remote_ip4,
5150 use_inside_ports=True)
5151 self.pg1.add_stream(pkts)
5152 self.pg_enable_capture(self.pg_interfaces)
5154 capture = self.pg0.get_capture(len(pkts))
5155 self.verify_capture_in(capture, self.pg0)
5157 pkts = self.create_stream_in(self.pg0, self.pg1)
5158 self.pg0.add_stream(pkts)
5159 self.pg_enable_capture(self.pg_interfaces)
5161 capture = self.pg1.get_capture(len(pkts))
5162 self.verify_capture_out(capture, nat_ip=self.pg0.remote_ip4,
5165 def test_output_feature_and_service3(self):
5166 """ NAT44 interface output feature and DST NAT """
5167 external_addr = '1.2.3.4'
5171 self.vapi.nat44_forwarding_enable_disable(1)
5172 self.nat44_add_address(self.nat_addr)
5173 self.nat44_add_static_mapping(self.pg1.remote_ip4, external_addr,
5174 local_port, external_port,
5175 proto=IP_PROTOS.tcp, out2in_only=1)
5176 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
5177 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index,
5179 self.vapi.nat44_interface_add_del_output_feature(self.pg1.sw_if_index,
5182 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5183 IP(src=self.pg0.remote_ip4, dst=external_addr) /
5184 TCP(sport=12345, dport=external_port))
5185 self.pg0.add_stream(p)
5186 self.pg_enable_capture(self.pg_interfaces)
5188 capture = self.pg1.get_capture(1)
5193 self.assertEqual(ip.src, self.pg0.remote_ip4)
5194 self.assertEqual(tcp.sport, 12345)
5195 self.assertEqual(ip.dst, self.pg1.remote_ip4)
5196 self.assertEqual(tcp.dport, local_port)
5197 self.assert_packet_checksums_valid(p)
5199 self.logger.error(ppp("Unexpected or invalid packet:", p))
5202 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
5203 IP(src=self.pg1.remote_ip4, dst=self.pg0.remote_ip4) /
5204 TCP(sport=local_port, dport=12345))
5205 self.pg1.add_stream(p)
5206 self.pg_enable_capture(self.pg_interfaces)
5208 capture = self.pg0.get_capture(1)
5213 self.assertEqual(ip.src, external_addr)
5214 self.assertEqual(tcp.sport, external_port)
5215 self.assertEqual(ip.dst, self.pg0.remote_ip4)
5216 self.assertEqual(tcp.dport, 12345)
5217 self.assert_packet_checksums_valid(p)
5219 self.logger.error(ppp("Unexpected or invalid packet:", p))
5222 def test_next_src_nat(self):
5223 """ On way back forward packet to nat44-in2out node. """
5224 twice_nat_addr = '10.0.1.3'
5227 post_twice_nat_port = 0
5229 self.vapi.nat44_forwarding_enable_disable(1)
5230 self.nat44_add_address(twice_nat_addr, twice_nat=1)
5231 self.nat44_add_static_mapping(self.pg6.remote_ip4, self.pg1.remote_ip4,
5232 local_port, external_port,
5233 proto=IP_PROTOS.tcp, out2in_only=1,
5234 self_twice_nat=1, vrf_id=1)
5235 self.vapi.nat44_interface_add_del_feature(self.pg6.sw_if_index,
5238 p = (Ether(src=self.pg6.remote_mac, dst=self.pg6.local_mac) /
5239 IP(src=self.pg6.remote_ip4, dst=self.pg1.remote_ip4) /
5240 TCP(sport=12345, dport=external_port))
5241 self.pg6.add_stream(p)
5242 self.pg_enable_capture(self.pg_interfaces)
5244 capture = self.pg6.get_capture(1)
5249 self.assertEqual(ip.src, twice_nat_addr)
5250 self.assertNotEqual(tcp.sport, 12345)
5251 post_twice_nat_port = tcp.sport
5252 self.assertEqual(ip.dst, self.pg6.remote_ip4)
5253 self.assertEqual(tcp.dport, local_port)
5254 self.assert_packet_checksums_valid(p)
5256 self.logger.error(ppp("Unexpected or invalid packet:", p))
5259 p = (Ether(src=self.pg6.remote_mac, dst=self.pg6.local_mac) /
5260 IP(src=self.pg6.remote_ip4, dst=twice_nat_addr) /
5261 TCP(sport=local_port, dport=post_twice_nat_port))
5262 self.pg6.add_stream(p)
5263 self.pg_enable_capture(self.pg_interfaces)
5265 capture = self.pg6.get_capture(1)
5270 self.assertEqual(ip.src, self.pg1.remote_ip4)
5271 self.assertEqual(tcp.sport, external_port)
5272 self.assertEqual(ip.dst, self.pg6.remote_ip4)
5273 self.assertEqual(tcp.dport, 12345)
5274 self.assert_packet_checksums_valid(p)
5276 self.logger.error(ppp("Unexpected or invalid packet:", p))
5279 def twice_nat_common(self, self_twice_nat=False, same_pg=False, lb=False,
5281 twice_nat_addr = '10.0.1.3'
5289 port_in1 = port_in + 1
5290 port_in2 = port_in + 2
5295 server1 = self.pg0.remote_hosts[0]
5296 server2 = self.pg0.remote_hosts[1]
5308 eh_translate = ((not self_twice_nat) or (not lb and same_pg) or
5311 self.nat44_add_address(self.nat_addr)
5312 self.nat44_add_address(twice_nat_addr, twice_nat=1)
5314 self.nat44_add_static_mapping(pg0.remote_ip4, self.nat_addr,
5316 proto=IP_PROTOS.tcp,
5317 twice_nat=int(not self_twice_nat),
5318 self_twice_nat=int(self_twice_nat))
5320 locals = [{'addr': server1.ip4n,
5324 {'addr': server2.ip4n,
5328 out_addr_n = socket.inet_pton(socket.AF_INET, self.nat_addr)
5329 self.vapi.nat44_add_del_lb_static_mapping(out_addr_n,
5333 not self_twice_nat),
5336 local_num=len(locals),
5338 self.vapi.nat44_interface_add_del_feature(pg0.sw_if_index)
5339 self.vapi.nat44_interface_add_del_feature(pg1.sw_if_index,
5346 assert client_id is not None
5348 client = self.pg0.remote_hosts[0]
5349 elif client_id == 2:
5350 client = self.pg0.remote_hosts[1]
5352 client = pg1.remote_hosts[0]
5353 p = (Ether(src=pg1.remote_mac, dst=pg1.local_mac) /
5354 IP(src=client.ip4, dst=self.nat_addr) /
5355 TCP(sport=eh_port_out, dport=port_out))
5357 self.pg_enable_capture(self.pg_interfaces)
5359 capture = pg0.get_capture(1)
5365 if ip.dst == server1.ip4:
5371 self.assertEqual(ip.dst, server.ip4)
5373 self.assertIn(tcp.dport, [port_in1, port_in2])
5375 self.assertEqual(tcp.dport, port_in)
5377 self.assertEqual(ip.src, twice_nat_addr)
5378 self.assertNotEqual(tcp.sport, eh_port_out)
5380 self.assertEqual(ip.src, client.ip4)
5381 self.assertEqual(tcp.sport, eh_port_out)
5383 eh_port_in = tcp.sport
5384 saved_port_in = tcp.dport
5385 self.assert_packet_checksums_valid(p)
5387 self.logger.error(ppp("Unexpected or invalid packet:", p))
5390 p = (Ether(src=server.mac, dst=pg0.local_mac) /
5391 IP(src=server.ip4, dst=eh_addr_in) /
5392 TCP(sport=saved_port_in, dport=eh_port_in))
5394 self.pg_enable_capture(self.pg_interfaces)
5396 capture = pg1.get_capture(1)
5401 self.assertEqual(ip.dst, client.ip4)
5402 self.assertEqual(ip.src, self.nat_addr)
5403 self.assertEqual(tcp.dport, eh_port_out)
5404 self.assertEqual(tcp.sport, port_out)
5405 self.assert_packet_checksums_valid(p)
5407 self.logger.error(ppp("Unexpected or invalid packet:", p))
5411 sessions = self.vapi.nat44_user_session_dump(server.ip4n, 0)
5412 self.assertEqual(len(sessions), 1)
5413 self.assertTrue(sessions[0].ext_host_valid)
5414 self.assertTrue(sessions[0].is_twicenat)
5415 self.vapi.nat44_del_session(
5416 sessions[0].inside_ip_address,
5417 sessions[0].inside_port,
5418 sessions[0].protocol,
5419 ext_host_address=sessions[0].ext_host_nat_address,
5420 ext_host_port=sessions[0].ext_host_nat_port)
5421 sessions = self.vapi.nat44_user_session_dump(server.ip4n, 0)
5422 self.assertEqual(len(sessions), 0)
5424 def test_twice_nat(self):
5426 self.twice_nat_common()
5428 def test_self_twice_nat_positive(self):
5429 """ Self Twice NAT44 (positive test) """
5430 self.twice_nat_common(self_twice_nat=True, same_pg=True)
5432 def test_self_twice_nat_negative(self):
5433 """ Self Twice NAT44 (negative test) """
5434 self.twice_nat_common(self_twice_nat=True)
5436 def test_twice_nat_lb(self):
5437 """ Twice NAT44 local service load balancing """
5438 self.twice_nat_common(lb=True)
5440 def test_self_twice_nat_lb_positive(self):
5441 """ Self Twice NAT44 local service load balancing (positive test) """
5442 self.twice_nat_common(lb=True, self_twice_nat=True, same_pg=True,
5445 def test_self_twice_nat_lb_negative(self):
5446 """ Self Twice NAT44 local service load balancing (negative test) """
5447 self.twice_nat_common(lb=True, self_twice_nat=True, same_pg=True,
5450 def test_twice_nat_interface_addr(self):
5451 """ Acquire twice NAT44 addresses from interface """
5452 self.vapi.nat44_add_del_interface_addr(self.pg3.sw_if_index,
5455 # no address in NAT pool
5456 adresses = self.vapi.nat44_address_dump()
5457 self.assertEqual(0, len(adresses))
5459 # configure interface address and check NAT address pool
5460 self.pg3.config_ip4()
5461 adresses = self.vapi.nat44_address_dump()
5462 self.assertEqual(1, len(adresses))
5463 self.assertEqual(adresses[0].ip_address[0:4], self.pg3.local_ip4n)
5464 self.assertEqual(adresses[0].twice_nat, 1)
5466 # remove interface address and check NAT address pool
5467 self.pg3.unconfig_ip4()
5468 adresses = self.vapi.nat44_address_dump()
5469 self.assertEqual(0, len(adresses))
5471 def test_tcp_close(self):
5472 """ Close TCP session from inside network - output feature """
5473 self.vapi.nat44_forwarding_enable_disable(1)
5474 self.nat44_add_address(self.pg1.local_ip4)
5475 twice_nat_addr = '10.0.1.3'
5476 service_ip = '192.168.16.150'
5477 self.nat44_add_address(twice_nat_addr, twice_nat=1)
5478 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
5479 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index,
5481 self.vapi.nat44_interface_add_del_output_feature(self.pg1.sw_if_index,
5483 self.nat44_add_static_mapping(self.pg0.remote_ip4,
5487 proto=IP_PROTOS.tcp,
5490 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4n, 0)
5491 start_sessnum = len(sessions)
5493 # SYN packet out->in
5494 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
5495 IP(src=self.pg1.remote_ip4, dst=service_ip) /
5496 TCP(sport=33898, dport=80, flags="S"))
5497 self.pg1.add_stream(p)
5498 self.pg_enable_capture(self.pg_interfaces)
5500 capture = self.pg0.get_capture(1)
5502 tcp_port = p[TCP].sport
5504 # SYN + ACK packet in->out
5505 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5506 IP(src=self.pg0.remote_ip4, dst=twice_nat_addr) /
5507 TCP(sport=80, dport=tcp_port, flags="SA"))
5508 self.pg0.add_stream(p)
5509 self.pg_enable_capture(self.pg_interfaces)
5511 self.pg1.get_capture(1)
5513 # ACK packet out->in
5514 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
5515 IP(src=self.pg1.remote_ip4, dst=service_ip) /
5516 TCP(sport=33898, dport=80, flags="A"))
5517 self.pg1.add_stream(p)
5518 self.pg_enable_capture(self.pg_interfaces)
5520 self.pg0.get_capture(1)
5522 # FIN packet in -> out
5523 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5524 IP(src=self.pg0.remote_ip4, dst=twice_nat_addr) /
5525 TCP(sport=80, dport=tcp_port, flags="FA", seq=100, ack=300))
5526 self.pg0.add_stream(p)
5527 self.pg_enable_capture(self.pg_interfaces)
5529 self.pg1.get_capture(1)
5531 # FIN+ACK packet out -> in
5532 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
5533 IP(src=self.pg1.remote_ip4, dst=service_ip) /
5534 TCP(sport=33898, dport=80, flags="FA", seq=300, ack=101))
5535 self.pg1.add_stream(p)
5536 self.pg_enable_capture(self.pg_interfaces)
5538 self.pg0.get_capture(1)
5540 # ACK packet in -> out
5541 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5542 IP(src=self.pg0.remote_ip4, dst=twice_nat_addr) /
5543 TCP(sport=80, dport=tcp_port, flags="A", seq=101, ack=301))
5544 self.pg0.add_stream(p)
5545 self.pg_enable_capture(self.pg_interfaces)
5547 self.pg1.get_capture(1)
5549 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4n,
5551 self.assertEqual(len(sessions) - start_sessnum, 0)
5553 def test_tcp_session_close_in(self):
5554 """ Close TCP session from inside network """
5555 self.tcp_port_out = 10505
5556 self.nat44_add_address(self.nat_addr)
5557 self.nat44_add_static_mapping(self.pg0.remote_ip4,
5561 proto=IP_PROTOS.tcp,
5563 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
5564 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
5567 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4n, 0)
5568 start_sessnum = len(sessions)
5570 self.initiate_tcp_session(self.pg0, self.pg1)
5572 # FIN packet in -> out
5573 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5574 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
5575 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
5576 flags="FA", seq=100, ack=300))
5577 self.pg0.add_stream(p)
5578 self.pg_enable_capture(self.pg_interfaces)
5580 self.pg1.get_capture(1)
5584 # ACK packet out -> in
5585 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
5586 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
5587 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
5588 flags="A", seq=300, ack=101))
5591 # FIN packet out -> in
5592 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
5593 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
5594 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
5595 flags="FA", seq=300, ack=101))
5598 self.pg1.add_stream(pkts)
5599 self.pg_enable_capture(self.pg_interfaces)
5601 self.pg0.get_capture(2)
5603 # ACK packet in -> out
5604 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5605 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
5606 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
5607 flags="A", seq=101, ack=301))
5608 self.pg0.add_stream(p)
5609 self.pg_enable_capture(self.pg_interfaces)
5611 self.pg1.get_capture(1)
5613 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4n,
5615 self.assertEqual(len(sessions) - start_sessnum, 0)
5617 def test_tcp_session_close_out(self):
5618 """ Close TCP session from outside network """
5619 self.tcp_port_out = 10505
5620 self.nat44_add_address(self.nat_addr)
5621 self.nat44_add_static_mapping(self.pg0.remote_ip4,
5625 proto=IP_PROTOS.tcp,
5627 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
5628 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
5631 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4n, 0)
5632 start_sessnum = len(sessions)
5634 self.initiate_tcp_session(self.pg0, self.pg1)
5636 # FIN packet out -> in
5637 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
5638 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
5639 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
5640 flags="FA", seq=100, ack=300))
5641 self.pg1.add_stream(p)
5642 self.pg_enable_capture(self.pg_interfaces)
5644 self.pg0.get_capture(1)
5646 # FIN+ACK packet in -> out
5647 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5648 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
5649 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
5650 flags="FA", seq=300, ack=101))
5652 self.pg0.add_stream(p)
5653 self.pg_enable_capture(self.pg_interfaces)
5655 self.pg1.get_capture(1)
5657 # ACK packet out -> in
5658 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
5659 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
5660 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
5661 flags="A", seq=101, ack=301))
5662 self.pg1.add_stream(p)
5663 self.pg_enable_capture(self.pg_interfaces)
5665 self.pg0.get_capture(1)
5667 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4n,
5669 self.assertEqual(len(sessions) - start_sessnum, 0)
5671 def test_tcp_session_close_simultaneous(self):
5672 """ Close TCP session from inside network """
5673 self.tcp_port_out = 10505
5674 self.nat44_add_address(self.nat_addr)
5675 self.nat44_add_static_mapping(self.pg0.remote_ip4,
5679 proto=IP_PROTOS.tcp,
5681 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
5682 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
5685 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4n, 0)
5686 start_sessnum = len(sessions)
5688 self.initiate_tcp_session(self.pg0, self.pg1)
5690 # FIN packet in -> out
5691 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5692 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
5693 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
5694 flags="FA", seq=100, ack=300))
5695 self.pg0.add_stream(p)
5696 self.pg_enable_capture(self.pg_interfaces)
5698 self.pg1.get_capture(1)
5700 # FIN packet out -> in
5701 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
5702 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
5703 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
5704 flags="FA", seq=300, ack=100))
5705 self.pg1.add_stream(p)
5706 self.pg_enable_capture(self.pg_interfaces)
5708 self.pg0.get_capture(1)
5710 # ACK packet in -> out
5711 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5712 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
5713 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
5714 flags="A", seq=101, ack=301))
5715 self.pg0.add_stream(p)
5716 self.pg_enable_capture(self.pg_interfaces)
5718 self.pg1.get_capture(1)
5720 # ACK packet out -> in
5721 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
5722 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
5723 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
5724 flags="A", seq=301, ack=101))
5725 self.pg1.add_stream(p)
5726 self.pg_enable_capture(self.pg_interfaces)
5728 self.pg0.get_capture(1)
5730 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4n,
5732 self.assertEqual(len(sessions) - start_sessnum, 0)
5734 def test_one_armed_nat44_static(self):
5735 """ One armed NAT44 and 1:1 NAPT asymmetrical rule """
5736 remote_host = self.pg4.remote_hosts[0]
5737 local_host = self.pg4.remote_hosts[1]
5742 self.vapi.nat44_forwarding_enable_disable(1)
5743 self.nat44_add_address(self.nat_addr, twice_nat=1)
5744 self.nat44_add_static_mapping(local_host.ip4, self.nat_addr,
5745 local_port, external_port,
5746 proto=IP_PROTOS.tcp, out2in_only=1,
5748 self.vapi.nat44_interface_add_del_feature(self.pg4.sw_if_index)
5749 self.vapi.nat44_interface_add_del_feature(self.pg4.sw_if_index,
5752 # from client to service
5753 p = (Ether(src=self.pg4.remote_mac, dst=self.pg4.local_mac) /
5754 IP(src=remote_host.ip4, dst=self.nat_addr) /
5755 TCP(sport=12345, dport=external_port))
5756 self.pg4.add_stream(p)
5757 self.pg_enable_capture(self.pg_interfaces)
5759 capture = self.pg4.get_capture(1)
5764 self.assertEqual(ip.dst, local_host.ip4)
5765 self.assertEqual(ip.src, self.nat_addr)
5766 self.assertEqual(tcp.dport, local_port)
5767 self.assertNotEqual(tcp.sport, 12345)
5768 eh_port_in = tcp.sport
5769 self.assert_packet_checksums_valid(p)
5771 self.logger.error(ppp("Unexpected or invalid packet:", p))
5774 # from service back to client
5775 p = (Ether(src=self.pg4.remote_mac, dst=self.pg4.local_mac) /
5776 IP(src=local_host.ip4, dst=self.nat_addr) /
5777 TCP(sport=local_port, dport=eh_port_in))
5778 self.pg4.add_stream(p)
5779 self.pg_enable_capture(self.pg_interfaces)
5781 capture = self.pg4.get_capture(1)
5786 self.assertEqual(ip.src, self.nat_addr)
5787 self.assertEqual(ip.dst, remote_host.ip4)
5788 self.assertEqual(tcp.sport, external_port)
5789 self.assertEqual(tcp.dport, 12345)
5790 self.assert_packet_checksums_valid(p)
5792 self.logger.error(ppp("Unexpected or invalid packet:", p))
5795 def test_static_with_port_out2(self):
5796 """ 1:1 NAPT asymmetrical rule """
5801 self.vapi.nat44_forwarding_enable_disable(1)
5802 self.nat44_add_static_mapping(self.pg0.remote_ip4, self.nat_addr,
5803 local_port, external_port,
5804 proto=IP_PROTOS.tcp, out2in_only=1)
5805 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
5806 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
5809 # from client to service
5810 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
5811 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
5812 TCP(sport=12345, dport=external_port))
5813 self.pg1.add_stream(p)
5814 self.pg_enable_capture(self.pg_interfaces)
5816 capture = self.pg0.get_capture(1)
5821 self.assertEqual(ip.dst, self.pg0.remote_ip4)
5822 self.assertEqual(tcp.dport, local_port)
5823 self.assert_packet_checksums_valid(p)
5825 self.logger.error(ppp("Unexpected or invalid packet:", p))
5829 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
5830 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
5831 ICMP(type=11) / capture[0][IP])
5832 self.pg0.add_stream(p)
5833 self.pg_enable_capture(self.pg_interfaces)
5835 capture = self.pg1.get_capture(1)
5838 self.assertEqual(p[IP].src, self.nat_addr)
5840 self.assertEqual(inner.dst, self.nat_addr)
5841 self.assertEqual(inner[TCPerror].dport, external_port)
5843 self.logger.error(ppp("Unexpected or invalid packet:", p))
5846 # from service back to client
5847 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5848 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
5849 TCP(sport=local_port, dport=12345))
5850 self.pg0.add_stream(p)
5851 self.pg_enable_capture(self.pg_interfaces)
5853 capture = self.pg1.get_capture(1)
5858 self.assertEqual(ip.src, self.nat_addr)
5859 self.assertEqual(tcp.sport, external_port)
5860 self.assert_packet_checksums_valid(p)
5862 self.logger.error(ppp("Unexpected or invalid packet:", p))
5866 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
5867 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
5868 ICMP(type=11) / capture[0][IP])
5869 self.pg1.add_stream(p)
5870 self.pg_enable_capture(self.pg_interfaces)
5872 capture = self.pg0.get_capture(1)
5875 self.assertEqual(p[IP].dst, self.pg0.remote_ip4)
5877 self.assertEqual(inner.src, self.pg0.remote_ip4)
5878 self.assertEqual(inner[TCPerror].sport, local_port)
5880 self.logger.error(ppp("Unexpected or invalid packet:", p))
5883 # from client to server (no translation)
5884 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
5885 IP(src=self.pg1.remote_ip4, dst=self.pg0.remote_ip4) /
5886 TCP(sport=12346, dport=local_port))
5887 self.pg1.add_stream(p)
5888 self.pg_enable_capture(self.pg_interfaces)
5890 capture = self.pg0.get_capture(1)
5895 self.assertEqual(ip.dst, self.pg0.remote_ip4)
5896 self.assertEqual(tcp.dport, local_port)
5897 self.assert_packet_checksums_valid(p)
5899 self.logger.error(ppp("Unexpected or invalid packet:", p))
5902 # from service back to client (no translation)
5903 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5904 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
5905 TCP(sport=local_port, dport=12346))
5906 self.pg0.add_stream(p)
5907 self.pg_enable_capture(self.pg_interfaces)
5909 capture = self.pg1.get_capture(1)
5914 self.assertEqual(ip.src, self.pg0.remote_ip4)
5915 self.assertEqual(tcp.sport, local_port)
5916 self.assert_packet_checksums_valid(p)
5918 self.logger.error(ppp("Unexpected or invalid packet:", p))
5921 def test_output_feature(self):
5922 """ NAT44 interface output feature (in2out postrouting) """
5923 self.vapi.nat44_forwarding_enable_disable(1)
5924 self.nat44_add_address(self.nat_addr)
5925 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index,
5927 self.vapi.nat44_interface_add_del_output_feature(self.pg1.sw_if_index,
5931 pkts = self.create_stream_in(self.pg0, self.pg1)
5932 self.pg0.add_stream(pkts)
5933 self.pg_enable_capture(self.pg_interfaces)
5935 capture = self.pg1.get_capture(len(pkts))
5936 self.verify_capture_out(capture)
5939 pkts = self.create_stream_out(self.pg1)
5940 self.pg1.add_stream(pkts)
5941 self.pg_enable_capture(self.pg_interfaces)
5943 capture = self.pg0.get_capture(len(pkts))
5944 self.verify_capture_in(capture, self.pg0)
5946 def test_multiple_vrf(self):
5947 """ Multiple VRF setup """
5948 external_addr = '1.2.3.4'
5953 self.vapi.nat44_forwarding_enable_disable(1)
5954 self.nat44_add_address(self.nat_addr)
5955 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
5956 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index,
5958 self.vapi.nat44_interface_add_del_output_feature(self.pg1.sw_if_index,
5960 self.vapi.nat44_interface_add_del_feature(self.pg5.sw_if_index)
5961 self.vapi.nat44_interface_add_del_feature(self.pg5.sw_if_index,
5963 self.vapi.nat44_interface_add_del_feature(self.pg6.sw_if_index,
5965 self.nat44_add_static_mapping(self.pg5.remote_ip4, external_addr,
5966 local_port, external_port, vrf_id=1,
5967 proto=IP_PROTOS.tcp, out2in_only=1)
5968 self.nat44_add_static_mapping(
5969 self.pg0.remote_ip4, external_sw_if_index=self.pg0.sw_if_index,
5970 local_port=local_port, vrf_id=0, external_port=external_port,
5971 proto=IP_PROTOS.tcp, out2in_only=1)
5973 # from client to service (both VRF1)
5974 p = (Ether(src=self.pg6.remote_mac, dst=self.pg6.local_mac) /
5975 IP(src=self.pg6.remote_ip4, dst=external_addr) /
5976 TCP(sport=12345, dport=external_port))
5977 self.pg6.add_stream(p)
5978 self.pg_enable_capture(self.pg_interfaces)
5980 capture = self.pg5.get_capture(1)
5985 self.assertEqual(ip.dst, self.pg5.remote_ip4)
5986 self.assertEqual(tcp.dport, local_port)
5987 self.assert_packet_checksums_valid(p)
5989 self.logger.error(ppp("Unexpected or invalid packet:", p))
5992 # from service back to client (both VRF1)
5993 p = (Ether(src=self.pg5.remote_mac, dst=self.pg5.local_mac) /
5994 IP(src=self.pg5.remote_ip4, dst=self.pg6.remote_ip4) /
5995 TCP(sport=local_port, dport=12345))
5996 self.pg5.add_stream(p)
5997 self.pg_enable_capture(self.pg_interfaces)
5999 capture = self.pg6.get_capture(1)
6004 self.assertEqual(ip.src, external_addr)
6005 self.assertEqual(tcp.sport, external_port)
6006 self.assert_packet_checksums_valid(p)
6008 self.logger.error(ppp("Unexpected or invalid packet:", p))
6011 # dynamic NAT from VRF1 to VRF0 (output-feature)
6012 p = (Ether(src=self.pg5.remote_mac, dst=self.pg5.local_mac) /
6013 IP(src=self.pg5.remote_ip4, dst=self.pg1.remote_ip4) /
6014 TCP(sport=2345, dport=22))
6015 self.pg5.add_stream(p)
6016 self.pg_enable_capture(self.pg_interfaces)
6018 capture = self.pg1.get_capture(1)
6023 self.assertEqual(ip.src, self.nat_addr)
6024 self.assertNotEqual(tcp.sport, 2345)
6025 self.assert_packet_checksums_valid(p)
6028 self.logger.error(ppp("Unexpected or invalid packet:", p))
6031 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
6032 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
6033 TCP(sport=22, dport=port))
6034 self.pg1.add_stream(p)
6035 self.pg_enable_capture(self.pg_interfaces)
6037 capture = self.pg5.get_capture(1)
6042 self.assertEqual(ip.dst, self.pg5.remote_ip4)
6043 self.assertEqual(tcp.dport, 2345)
6044 self.assert_packet_checksums_valid(p)
6046 self.logger.error(ppp("Unexpected or invalid packet:", p))
6049 # from client VRF1 to service VRF0
6050 p = (Ether(src=self.pg6.remote_mac, dst=self.pg6.local_mac) /
6051 IP(src=self.pg6.remote_ip4, dst=self.pg0.local_ip4) /
6052 TCP(sport=12346, dport=external_port))
6053 self.pg6.add_stream(p)
6054 self.pg_enable_capture(self.pg_interfaces)
6056 capture = self.pg0.get_capture(1)
6061 self.assertEqual(ip.dst, self.pg0.remote_ip4)
6062 self.assertEqual(tcp.dport, local_port)
6063 self.assert_packet_checksums_valid(p)
6065 self.logger.error(ppp("Unexpected or invalid packet:", p))
6068 # from service VRF0 back to client VRF1
6069 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6070 IP(src=self.pg0.remote_ip4, dst=self.pg6.remote_ip4) /
6071 TCP(sport=local_port, dport=12346))
6072 self.pg0.add_stream(p)
6073 self.pg_enable_capture(self.pg_interfaces)
6075 capture = self.pg6.get_capture(1)
6080 self.assertEqual(ip.src, self.pg0.local_ip4)
6081 self.assertEqual(tcp.sport, external_port)
6082 self.assert_packet_checksums_valid(p)
6084 self.logger.error(ppp("Unexpected or invalid packet:", p))
6087 # from client VRF0 to service VRF1
6088 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6089 IP(src=self.pg0.remote_ip4, dst=external_addr) /
6090 TCP(sport=12347, dport=external_port))
6091 self.pg0.add_stream(p)
6092 self.pg_enable_capture(self.pg_interfaces)
6094 capture = self.pg5.get_capture(1)
6099 self.assertEqual(ip.dst, self.pg5.remote_ip4)
6100 self.assertEqual(tcp.dport, local_port)
6101 self.assert_packet_checksums_valid(p)
6103 self.logger.error(ppp("Unexpected or invalid packet:", p))
6106 # from service VRF1 back to client VRF0
6107 p = (Ether(src=self.pg5.remote_mac, dst=self.pg5.local_mac) /
6108 IP(src=self.pg5.remote_ip4, dst=self.pg0.remote_ip4) /
6109 TCP(sport=local_port, dport=12347))
6110 self.pg5.add_stream(p)
6111 self.pg_enable_capture(self.pg_interfaces)
6113 capture = self.pg0.get_capture(1)
6118 self.assertEqual(ip.src, external_addr)
6119 self.assertEqual(tcp.sport, external_port)
6120 self.assert_packet_checksums_valid(p)
6122 self.logger.error(ppp("Unexpected or invalid packet:", p))
6125 # from client to server (both VRF1, no translation)
6126 p = (Ether(src=self.pg6.remote_mac, dst=self.pg6.local_mac) /
6127 IP(src=self.pg6.remote_ip4, dst=self.pg5.remote_ip4) /
6128 TCP(sport=12348, dport=local_port))
6129 self.pg6.add_stream(p)
6130 self.pg_enable_capture(self.pg_interfaces)
6132 capture = self.pg5.get_capture(1)
6137 self.assertEqual(ip.dst, self.pg5.remote_ip4)
6138 self.assertEqual(tcp.dport, local_port)
6139 self.assert_packet_checksums_valid(p)
6141 self.logger.error(ppp("Unexpected or invalid packet:", p))
6144 # from server back to client (both VRF1, no translation)
6145 p = (Ether(src=self.pg5.remote_mac, dst=self.pg5.local_mac) /
6146 IP(src=self.pg5.remote_ip4, dst=self.pg6.remote_ip4) /
6147 TCP(sport=local_port, dport=12348))
6148 self.pg5.add_stream(p)
6149 self.pg_enable_capture(self.pg_interfaces)
6151 capture = self.pg6.get_capture(1)
6156 self.assertEqual(ip.src, self.pg5.remote_ip4)
6157 self.assertEqual(tcp.sport, local_port)
6158 self.assert_packet_checksums_valid(p)
6160 self.logger.error(ppp("Unexpected or invalid packet:", p))
6163 # from client VRF1 to server VRF0 (no translation)
6164 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6165 IP(src=self.pg0.remote_ip4, dst=self.pg6.remote_ip4) /
6166 TCP(sport=local_port, dport=12349))
6167 self.pg0.add_stream(p)
6168 self.pg_enable_capture(self.pg_interfaces)
6170 capture = self.pg6.get_capture(1)
6175 self.assertEqual(ip.src, self.pg0.remote_ip4)
6176 self.assertEqual(tcp.sport, local_port)
6177 self.assert_packet_checksums_valid(p)
6179 self.logger.error(ppp("Unexpected or invalid packet:", p))
6182 # from server VRF0 back to client VRF1 (no translation)
6183 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6184 IP(src=self.pg0.remote_ip4, dst=self.pg6.remote_ip4) /
6185 TCP(sport=local_port, dport=12349))
6186 self.pg0.add_stream(p)
6187 self.pg_enable_capture(self.pg_interfaces)
6189 capture = self.pg6.get_capture(1)
6194 self.assertEqual(ip.src, self.pg0.remote_ip4)
6195 self.assertEqual(tcp.sport, local_port)
6196 self.assert_packet_checksums_valid(p)
6198 self.logger.error(ppp("Unexpected or invalid packet:", p))
6201 # from client VRF0 to server VRF1 (no translation)
6202 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6203 IP(src=self.pg0.remote_ip4, dst=self.pg5.remote_ip4) /
6204 TCP(sport=12344, dport=local_port))
6205 self.pg0.add_stream(p)
6206 self.pg_enable_capture(self.pg_interfaces)
6208 capture = self.pg5.get_capture(1)
6213 self.assertEqual(ip.dst, self.pg5.remote_ip4)
6214 self.assertEqual(tcp.dport, local_port)
6215 self.assert_packet_checksums_valid(p)
6217 self.logger.error(ppp("Unexpected or invalid packet:", p))
6220 # from server VRF1 back to client VRF0 (no translation)
6221 p = (Ether(src=self.pg5.remote_mac, dst=self.pg5.local_mac) /
6222 IP(src=self.pg5.remote_ip4, dst=self.pg0.remote_ip4) /
6223 TCP(sport=local_port, dport=12344))
6224 self.pg5.add_stream(p)
6225 self.pg_enable_capture(self.pg_interfaces)
6227 capture = self.pg0.get_capture(1)
6232 self.assertEqual(ip.src, self.pg5.remote_ip4)
6233 self.assertEqual(tcp.sport, local_port)
6234 self.assert_packet_checksums_valid(p)
6236 self.logger.error(ppp("Unexpected or invalid packet:", p))
6239 @unittest.skipUnless(running_extended_tests, "part of extended tests")
6240 def test_session_timeout(self):
6241 """ NAT44 session timeouts """
6242 self.nat44_add_address(self.nat_addr)
6243 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
6244 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
6246 self.vapi.nat_set_timeouts(icmp=5)
6250 for i in range(0, max_sessions):
6251 src = "10.10.%u.%u" % ((i & 0xFF00) >> 8, i & 0xFF)
6252 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
6253 IP(src=src, dst=self.pg1.remote_ip4) /
6254 ICMP(id=1025, type='echo-request'))
6256 self.pg0.add_stream(pkts)
6257 self.pg_enable_capture(self.pg_interfaces)
6259 self.pg1.get_capture(max_sessions)
6264 for i in range(0, max_sessions):
6265 src = "10.11.%u.%u" % ((i & 0xFF00) >> 8, i & 0xFF)
6266 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
6267 IP(src=src, dst=self.pg1.remote_ip4) /
6268 ICMP(id=1026, type='echo-request'))
6270 self.pg0.add_stream(pkts)
6271 self.pg_enable_capture(self.pg_interfaces)
6273 self.pg1.get_capture(max_sessions)
6276 users = self.vapi.nat44_user_dump()
6278 nsessions = nsessions + user.nsessions
6279 self.assertLess(nsessions, 2 * max_sessions)
6281 @unittest.skipUnless(running_extended_tests, "part of extended tests")
6282 def test_session_rst_timeout(self):
6283 """ NAT44 session RST timeouts """
6284 self.nat44_add_address(self.nat_addr)
6285 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
6286 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
6288 self.vapi.nat_set_timeouts(tcp_transitory=5)
6290 self.initiate_tcp_session(self.pg0, self.pg1)
6291 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6292 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6293 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
6295 self.pg0.add_stream(p)
6296 self.pg_enable_capture(self.pg_interfaces)
6298 self.pg1.get_capture(1)
6302 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6303 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6304 TCP(sport=self.tcp_port_in + 1, dport=self.tcp_external_port + 1,
6306 self.pg0.add_stream(p)
6307 self.pg_enable_capture(self.pg_interfaces)
6309 self.pg1.get_capture(1)
6312 users = self.vapi.nat44_user_dump()
6313 self.assertEqual(len(users), 1)
6314 self.assertEqual(users[0].ip_address, self.pg0.remote_ip4n)
6315 self.assertEqual(users[0].nsessions, 1)
6317 @unittest.skipUnless(running_extended_tests, "part of extended tests")
6318 def test_session_limit_per_user(self):
6319 """ Maximum sessions per user limit """
6320 self.nat44_add_address(self.nat_addr)
6321 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
6322 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
6324 self.vapi.set_ipfix_exporter(collector_address=self.pg2.remote_ip4n,
6325 src_address=self.pg2.local_ip4n,
6327 template_interval=10)
6328 self.vapi.nat_set_timeouts(udp=5)
6330 # get maximum number of translations per user
6331 nat44_config = self.vapi.nat_show_config()
6334 for port in range(0, nat44_config.max_translations_per_user):
6335 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6336 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6337 UDP(sport=1025 + port, dport=1025 + port))
6340 self.pg0.add_stream(pkts)
6341 self.pg_enable_capture(self.pg_interfaces)
6343 capture = self.pg1.get_capture(len(pkts))
6345 self.vapi.nat_ipfix_enable_disable(domain_id=self.ipfix_domain_id,
6346 src_port=self.ipfix_src_port)
6348 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6349 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6350 UDP(sport=3001, dport=3002))
6351 self.pg0.add_stream(p)
6352 self.pg_enable_capture(self.pg_interfaces)
6354 capture = self.pg1.assert_nothing_captured()
6356 # verify IPFIX logging
6357 self.vapi.cli("ipfix flush") # FIXME this should be an API call
6359 capture = self.pg2.get_capture(10)
6360 ipfix = IPFIXDecoder()
6361 # first load template
6363 self.assertTrue(p.haslayer(IPFIX))
6364 if p.haslayer(Template):
6365 ipfix.add_template(p.getlayer(Template))
6366 # verify events in data set
6368 if p.haslayer(Data):
6369 data = ipfix.decode_data_set(p.getlayer(Set))
6370 self.verify_ipfix_max_entries_per_user(
6372 nat44_config.max_translations_per_user,
6373 self.pg0.remote_ip4n)
6376 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6377 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6378 UDP(sport=3001, dport=3002))
6379 self.pg0.add_stream(p)
6380 self.pg_enable_capture(self.pg_interfaces)
6382 self.pg1.get_capture(1)
6384 def test_syslog_sess(self):
6385 """ Test syslog session creation and deletion """
6386 self.vapi.syslog_set_filter(SYSLOG_SEVERITY.INFO)
6387 self.vapi.syslog_set_sender(self.pg2.local_ip4n, self.pg2.remote_ip4n)
6388 self.nat44_add_address(self.nat_addr)
6389 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
6390 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
6393 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
6394 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6395 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port))
6396 self.pg0.add_stream(p)
6397 self.pg_enable_capture(self.pg_interfaces)
6399 capture = self.pg1.get_capture(1)
6400 self.tcp_port_out = capture[0][TCP].sport
6401 capture = self.pg2.get_capture(1)
6402 self.verify_syslog_sess(capture[0][Raw].load)
6404 self.pg_enable_capture(self.pg_interfaces)
6406 self.nat44_add_address(self.nat_addr, is_add=0)
6407 capture = self.pg2.get_capture(1)
6408 self.verify_syslog_sess(capture[0][Raw].load, False)
6411 super(TestNAT44EndpointDependent, self).tearDown()
6412 if not self.vpp_dead:
6413 self.logger.info(self.vapi.cli("show nat44 addresses"))
6414 self.logger.info(self.vapi.cli("show nat44 interfaces"))
6415 self.logger.info(self.vapi.cli("show nat44 static mappings"))
6416 self.logger.info(self.vapi.cli("show nat44 interface address"))
6417 self.logger.info(self.vapi.cli("show nat44 sessions detail"))
6418 self.logger.info(self.vapi.cli("show nat44 hash tables detail"))
6419 self.logger.info(self.vapi.cli("show nat timeouts"))
6421 self.vapi.cli("clear logging")
6424 class TestNAT44Out2InDPO(MethodHolder):
6425 """ NAT44 Test Cases using out2in DPO """
6428 def setUpConstants(cls):
6429 super(TestNAT44Out2InDPO, cls).setUpConstants()
6430 cls.vpp_cmdline.extend(["nat", "{", "out2in dpo", "}"])
6433 def setUpClass(cls):
6434 super(TestNAT44Out2InDPO, cls).setUpClass()
6435 cls.vapi.cli("set log class nat level debug")
6438 cls.tcp_port_in = 6303
6439 cls.tcp_port_out = 6303
6440 cls.udp_port_in = 6304
6441 cls.udp_port_out = 6304
6442 cls.icmp_id_in = 6305
6443 cls.icmp_id_out = 6305
6444 cls.nat_addr = '10.0.0.3'
6445 cls.nat_addr_n = socket.inet_pton(socket.AF_INET, cls.nat_addr)
6446 cls.dst_ip4 = '192.168.70.1'
6448 cls.create_pg_interfaces(range(2))
6451 cls.pg0.config_ip4()
6452 cls.pg0.resolve_arp()
6455 cls.pg1.config_ip6()
6456 cls.pg1.resolve_ndp()
6458 cls.vapi.ip_add_del_route(dst_address=b'\x00' * 16,
6459 dst_address_length=0,
6460 next_hop_address=cls.pg1.remote_ip6n,
6461 next_hop_sw_if_index=cls.pg1.sw_if_index,
6465 super(TestNAT44Out2InDPO, cls).tearDownClass()
6468 def configure_xlat(self):
6469 self.dst_ip6_pfx = '1:2:3::'
6470 self.dst_ip6_pfx_n = socket.inet_pton(socket.AF_INET6,
6472 self.dst_ip6_pfx_len = 96
6473 self.src_ip6_pfx = '4:5:6::'
6474 self.src_ip6_pfx_n = socket.inet_pton(socket.AF_INET6,
6476 self.src_ip6_pfx_len = 96
6477 self.vapi.map_add_domain(self.dst_ip6_pfx_n, self.dst_ip6_pfx_len,
6478 self.src_ip6_pfx_n, self.src_ip6_pfx_len,
6479 '\x00\x00\x00\x00', 0)
6481 @unittest.skip('Temporary disabled')
6482 def test_464xlat_ce(self):
6483 """ Test 464XLAT CE with NAT44 """
6485 nat_config = self.vapi.nat_show_config()
6486 self.assertEqual(1, nat_config.out2in_dpo)
6488 self.configure_xlat()
6490 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
6491 self.vapi.nat44_add_del_address_range(self.nat_addr_n, self.nat_addr_n)
6493 out_src_ip6 = self.compose_ip6(self.dst_ip4, self.dst_ip6_pfx,
6494 self.dst_ip6_pfx_len)
6495 out_dst_ip6 = self.compose_ip6(self.nat_addr, self.src_ip6_pfx,
6496 self.src_ip6_pfx_len)
6499 pkts = self.create_stream_in(self.pg0, self.pg1, self.dst_ip4)
6500 self.pg0.add_stream(pkts)
6501 self.pg_enable_capture(self.pg_interfaces)
6503 capture = self.pg1.get_capture(len(pkts))
6504 self.verify_capture_out_ip6(capture, nat_ip=out_dst_ip6,
6507 pkts = self.create_stream_out_ip6(self.pg1, out_src_ip6,
6509 self.pg1.add_stream(pkts)
6510 self.pg_enable_capture(self.pg_interfaces)
6512 capture = self.pg0.get_capture(len(pkts))
6513 self.verify_capture_in(capture, self.pg0)
6515 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index,
6517 self.vapi.nat44_add_del_address_range(self.nat_addr_n,
6518 self.nat_addr_n, is_add=0)
6520 @unittest.skip('Temporary disabled')
6521 def test_464xlat_ce_no_nat(self):
6522 """ Test 464XLAT CE without NAT44 """
6524 self.configure_xlat()
6526 out_src_ip6 = self.compose_ip6(self.dst_ip4, self.dst_ip6_pfx,
6527 self.dst_ip6_pfx_len)
6528 out_dst_ip6 = self.compose_ip6(self.pg0.remote_ip4, self.src_ip6_pfx,
6529 self.src_ip6_pfx_len)
6531 pkts = self.create_stream_in(self.pg0, self.pg1, self.dst_ip4)
6532 self.pg0.add_stream(pkts)
6533 self.pg_enable_capture(self.pg_interfaces)
6535 capture = self.pg1.get_capture(len(pkts))
6536 self.verify_capture_out_ip6(capture, dst_ip=out_src_ip6,
6537 nat_ip=out_dst_ip6, same_port=True)
6539 pkts = self.create_stream_out_ip6(self.pg1, out_src_ip6, out_dst_ip6)
6540 self.pg1.add_stream(pkts)
6541 self.pg_enable_capture(self.pg_interfaces)
6543 capture = self.pg0.get_capture(len(pkts))
6544 self.verify_capture_in(capture, self.pg0)
6547 class TestDeterministicNAT(MethodHolder):
6548 """ Deterministic NAT Test Cases """
6551 def setUpConstants(cls):
6552 super(TestDeterministicNAT, cls).setUpConstants()
6553 cls.vpp_cmdline.extend(["nat", "{", "deterministic", "}"])
6556 def setUpClass(cls):
6557 super(TestDeterministicNAT, cls).setUpClass()
6558 cls.vapi.cli("set log class nat level debug")
6561 cls.tcp_port_in = 6303
6562 cls.tcp_external_port = 6303
6563 cls.udp_port_in = 6304
6564 cls.udp_external_port = 6304
6565 cls.icmp_id_in = 6305
6566 cls.nat_addr = '10.0.0.3'
6568 cls.create_pg_interfaces(range(3))
6569 cls.interfaces = list(cls.pg_interfaces)
6571 for i in cls.interfaces:
6576 cls.pg0.generate_remote_hosts(2)
6577 cls.pg0.configure_ipv4_neighbors()
6580 super(TestDeterministicNAT, cls).tearDownClass()
6583 def create_stream_in(self, in_if, out_if, ttl=64):
6585 Create packet stream for inside network
6587 :param in_if: Inside interface
6588 :param out_if: Outside interface
6589 :param ttl: TTL of generated packets
6593 p = (Ether(dst=in_if.local_mac, src=in_if.remote_mac) /
6594 IP(src=in_if.remote_ip4, dst=out_if.remote_ip4, ttl=ttl) /
6595 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port))
6599 p = (Ether(dst=in_if.local_mac, src=in_if.remote_mac) /
6600 IP(src=in_if.remote_ip4, dst=out_if.remote_ip4, ttl=ttl) /
6601 UDP(sport=self.udp_port_in, dport=self.udp_external_port))
6605 p = (Ether(dst=in_if.local_mac, src=in_if.remote_mac) /
6606 IP(src=in_if.remote_ip4, dst=out_if.remote_ip4, ttl=ttl) /
6607 ICMP(id=self.icmp_id_in, type='echo-request'))
6612 def create_stream_out(self, out_if, dst_ip=None, ttl=64):
6614 Create packet stream for outside network
6616 :param out_if: Outside interface
6617 :param dst_ip: Destination IP address (Default use global NAT address)
6618 :param ttl: TTL of generated packets
6621 dst_ip = self.nat_addr
6624 p = (Ether(dst=out_if.local_mac, src=out_if.remote_mac) /
6625 IP(src=out_if.remote_ip4, dst=dst_ip, ttl=ttl) /
6626 TCP(dport=self.tcp_port_out, sport=self.tcp_external_port))
6630 p = (Ether(dst=out_if.local_mac, src=out_if.remote_mac) /
6631 IP(src=out_if.remote_ip4, dst=dst_ip, ttl=ttl) /
6632 UDP(dport=self.udp_port_out, sport=self.udp_external_port))
6636 p = (Ether(dst=out_if.local_mac, src=out_if.remote_mac) /
6637 IP(src=out_if.remote_ip4, dst=dst_ip, ttl=ttl) /
6638 ICMP(id=self.icmp_external_id, type='echo-reply'))
6643 def verify_capture_out(self, capture, nat_ip=None):
6645 Verify captured packets on outside network
6647 :param capture: Captured packets
6648 :param nat_ip: Translated IP address (Default use global NAT address)
6649 :param same_port: Sorce port number is not translated (Default False)
6652 nat_ip = self.nat_addr
6653 for packet in capture:
6655 self.assertEqual(packet[IP].src, nat_ip)
6656 if packet.haslayer(TCP):
6657 self.tcp_port_out = packet[TCP].sport
6658 elif packet.haslayer(UDP):
6659 self.udp_port_out = packet[UDP].sport
6661 self.icmp_external_id = packet[ICMP].id
6663 self.logger.error(ppp("Unexpected or invalid packet "
6664 "(outside network):", packet))
6667 def test_deterministic_mode(self):
6668 """ NAT plugin run deterministic mode """
6669 in_addr = '172.16.255.0'
6670 out_addr = '172.17.255.50'
6671 in_addr_t = '172.16.255.20'
6672 in_addr_n = socket.inet_aton(in_addr)
6673 out_addr_n = socket.inet_aton(out_addr)
6674 in_addr_t_n = socket.inet_aton(in_addr_t)
6678 nat_config = self.vapi.nat_show_config()
6679 self.assertEqual(1, nat_config.deterministic)
6681 self.vapi.nat_det_add_del_map(in_addr_n, in_plen, out_addr_n, out_plen)
6683 rep1 = self.vapi.nat_det_forward(in_addr_t_n)
6684 self.assertEqual(rep1.out_addr[:4], out_addr_n)
6685 rep2 = self.vapi.nat_det_reverse(out_addr_n, rep1.out_port_hi)
6686 self.assertEqual(rep2.in_addr[:4], in_addr_t_n)
6688 deterministic_mappings = self.vapi.nat_det_map_dump()
6689 self.assertEqual(len(deterministic_mappings), 1)
6690 dsm = deterministic_mappings[0]
6691 self.assertEqual(in_addr_n, dsm.in_addr[:4])
6692 self.assertEqual(in_plen, dsm.in_plen)
6693 self.assertEqual(out_addr_n, dsm.out_addr[:4])
6694 self.assertEqual(out_plen, dsm.out_plen)
6696 self.clear_nat_det()
6697 deterministic_mappings = self.vapi.nat_det_map_dump()
6698 self.assertEqual(len(deterministic_mappings), 0)
6700 def test_set_timeouts(self):
6701 """ Set deterministic NAT timeouts """
6702 timeouts_before = self.vapi.nat_get_timeouts()
6704 self.vapi.nat_set_timeouts(timeouts_before.udp + 10,
6705 timeouts_before.tcp_established + 10,
6706 timeouts_before.tcp_transitory + 10,
6707 timeouts_before.icmp + 10)
6709 timeouts_after = self.vapi.nat_get_timeouts()
6711 self.assertNotEqual(timeouts_before.udp, timeouts_after.udp)
6712 self.assertNotEqual(timeouts_before.icmp, timeouts_after.icmp)
6713 self.assertNotEqual(timeouts_before.tcp_established,
6714 timeouts_after.tcp_established)
6715 self.assertNotEqual(timeouts_before.tcp_transitory,
6716 timeouts_after.tcp_transitory)
6718 def test_det_in(self):
6719 """ Deterministic NAT translation test (TCP, UDP, ICMP) """
6721 nat_ip = "10.0.0.10"
6723 self.vapi.nat_det_add_del_map(self.pg0.remote_ip4n,
6725 socket.inet_aton(nat_ip),
6727 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
6728 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
6732 pkts = self.create_stream_in(self.pg0, self.pg1)
6733 self.pg0.add_stream(pkts)
6734 self.pg_enable_capture(self.pg_interfaces)
6736 capture = self.pg1.get_capture(len(pkts))
6737 self.verify_capture_out(capture, nat_ip)
6740 pkts = self.create_stream_out(self.pg1, nat_ip)
6741 self.pg1.add_stream(pkts)
6742 self.pg_enable_capture(self.pg_interfaces)
6744 capture = self.pg0.get_capture(len(pkts))
6745 self.verify_capture_in(capture, self.pg0)
6748 sessions = self.vapi.nat_det_session_dump(self.pg0.remote_ip4n)
6749 self.assertEqual(len(sessions), 3)
6753 self.assertEqual(s.ext_addr[:4], self.pg1.remote_ip4n)
6754 self.assertEqual(s.in_port, self.tcp_port_in)
6755 self.assertEqual(s.out_port, self.tcp_port_out)
6756 self.assertEqual(s.ext_port, self.tcp_external_port)
6760 self.assertEqual(s.ext_addr[:4], self.pg1.remote_ip4n)
6761 self.assertEqual(s.in_port, self.udp_port_in)
6762 self.assertEqual(s.out_port, self.udp_port_out)
6763 self.assertEqual(s.ext_port, self.udp_external_port)
6767 self.assertEqual(s.ext_addr[:4], self.pg1.remote_ip4n)
6768 self.assertEqual(s.in_port, self.icmp_id_in)
6769 self.assertEqual(s.out_port, self.icmp_external_id)
6771 def test_multiple_users(self):
6772 """ Deterministic NAT multiple users """
6774 nat_ip = "10.0.0.10"
6776 external_port = 6303
6778 host0 = self.pg0.remote_hosts[0]
6779 host1 = self.pg0.remote_hosts[1]
6781 self.vapi.nat_det_add_del_map(host0.ip4n,
6783 socket.inet_aton(nat_ip),
6785 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
6786 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
6790 p = (Ether(src=host0.mac, dst=self.pg0.local_mac) /
6791 IP(src=host0.ip4, dst=self.pg1.remote_ip4) /
6792 TCP(sport=port_in, dport=external_port))
6793 self.pg0.add_stream(p)
6794 self.pg_enable_capture(self.pg_interfaces)
6796 capture = self.pg1.get_capture(1)
6801 self.assertEqual(ip.src, nat_ip)
6802 self.assertEqual(ip.dst, self.pg1.remote_ip4)
6803 self.assertEqual(tcp.dport, external_port)
6804 port_out0 = tcp.sport
6806 self.logger.error(ppp("Unexpected or invalid packet:", p))
6810 p = (Ether(src=host1.mac, dst=self.pg0.local_mac) /
6811 IP(src=host1.ip4, dst=self.pg1.remote_ip4) /
6812 TCP(sport=port_in, dport=external_port))
6813 self.pg0.add_stream(p)
6814 self.pg_enable_capture(self.pg_interfaces)
6816 capture = self.pg1.get_capture(1)
6821 self.assertEqual(ip.src, nat_ip)
6822 self.assertEqual(ip.dst, self.pg1.remote_ip4)
6823 self.assertEqual(tcp.dport, external_port)
6824 port_out1 = tcp.sport
6826 self.logger.error(ppp("Unexpected or invalid packet:", p))
6829 dms = self.vapi.nat_det_map_dump()
6830 self.assertEqual(1, len(dms))
6831 self.assertEqual(2, dms[0].ses_num)
6834 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
6835 IP(src=self.pg1.remote_ip4, dst=nat_ip) /
6836 TCP(sport=external_port, dport=port_out0))
6837 self.pg1.add_stream(p)
6838 self.pg_enable_capture(self.pg_interfaces)
6840 capture = self.pg0.get_capture(1)
6845 self.assertEqual(ip.src, self.pg1.remote_ip4)
6846 self.assertEqual(ip.dst, host0.ip4)
6847 self.assertEqual(tcp.dport, port_in)
6848 self.assertEqual(tcp.sport, external_port)
6850 self.logger.error(ppp("Unexpected or invalid packet:", p))
6854 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
6855 IP(src=self.pg1.remote_ip4, dst=nat_ip) /
6856 TCP(sport=external_port, dport=port_out1))
6857 self.pg1.add_stream(p)
6858 self.pg_enable_capture(self.pg_interfaces)
6860 capture = self.pg0.get_capture(1)
6865 self.assertEqual(ip.src, self.pg1.remote_ip4)
6866 self.assertEqual(ip.dst, host1.ip4)
6867 self.assertEqual(tcp.dport, port_in)
6868 self.assertEqual(tcp.sport, external_port)
6870 self.logger.error(ppp("Unexpected or invalid packet", p))
6873 # session close api test
6874 self.vapi.nat_det_close_session_out(socket.inet_aton(nat_ip),
6876 self.pg1.remote_ip4n,
6878 dms = self.vapi.nat_det_map_dump()
6879 self.assertEqual(dms[0].ses_num, 1)
6881 self.vapi.nat_det_close_session_in(host0.ip4n,
6883 self.pg1.remote_ip4n,
6885 dms = self.vapi.nat_det_map_dump()
6886 self.assertEqual(dms[0].ses_num, 0)
6888 def test_tcp_session_close_detection_in(self):
6889 """ Deterministic NAT TCP session close from inside network """
6890 self.vapi.nat_det_add_del_map(self.pg0.remote_ip4n,
6892 socket.inet_aton(self.nat_addr),
6894 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
6895 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
6898 self.initiate_tcp_session(self.pg0, self.pg1)
6900 # close the session from inside
6902 # FIN packet in -> out
6903 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6904 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6905 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
6907 self.pg0.add_stream(p)
6908 self.pg_enable_capture(self.pg_interfaces)
6910 self.pg1.get_capture(1)
6914 # ACK packet out -> in
6915 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
6916 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
6917 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
6921 # FIN packet out -> in
6922 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
6923 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
6924 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
6928 self.pg1.add_stream(pkts)
6929 self.pg_enable_capture(self.pg_interfaces)
6931 self.pg0.get_capture(2)
6933 # ACK packet in -> out
6934 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6935 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6936 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
6938 self.pg0.add_stream(p)
6939 self.pg_enable_capture(self.pg_interfaces)
6941 self.pg1.get_capture(1)
6943 # Check if deterministic NAT44 closed the session
6944 dms = self.vapi.nat_det_map_dump()
6945 self.assertEqual(0, dms[0].ses_num)
6947 self.logger.error("TCP session termination failed")
6950 def test_tcp_session_close_detection_out(self):
6951 """ Deterministic NAT TCP session close from outside network """
6952 self.vapi.nat_det_add_del_map(self.pg0.remote_ip4n,
6954 socket.inet_aton(self.nat_addr),
6956 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
6957 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
6960 self.initiate_tcp_session(self.pg0, self.pg1)
6962 # close the session from outside
6964 # FIN packet out -> in
6965 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
6966 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
6967 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
6969 self.pg1.add_stream(p)
6970 self.pg_enable_capture(self.pg_interfaces)
6972 self.pg0.get_capture(1)
6976 # ACK packet in -> out
6977 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6978 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6979 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
6983 # ACK packet in -> out
6984 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6985 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6986 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
6990 self.pg0.add_stream(pkts)
6991 self.pg_enable_capture(self.pg_interfaces)
6993 self.pg1.get_capture(2)
6995 # ACK packet out -> in
6996 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
6997 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
6998 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
7000 self.pg1.add_stream(p)
7001 self.pg_enable_capture(self.pg_interfaces)
7003 self.pg0.get_capture(1)
7005 # Check if deterministic NAT44 closed the session
7006 dms = self.vapi.nat_det_map_dump()
7007 self.assertEqual(0, dms[0].ses_num)
7009 self.logger.error("TCP session termination failed")
7012 @unittest.skipUnless(running_extended_tests, "part of extended tests")
7013 def test_session_timeout(self):
7014 """ Deterministic NAT session timeouts """
7015 self.vapi.nat_det_add_del_map(self.pg0.remote_ip4n,
7017 socket.inet_aton(self.nat_addr),
7019 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
7020 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
7023 self.initiate_tcp_session(self.pg0, self.pg1)
7024 self.vapi.nat_set_timeouts(5, 5, 5, 5)
7025 pkts = self.create_stream_in(self.pg0, self.pg1)
7026 self.pg0.add_stream(pkts)
7027 self.pg_enable_capture(self.pg_interfaces)
7029 capture = self.pg1.get_capture(len(pkts))
7032 dms = self.vapi.nat_det_map_dump()
7033 self.assertEqual(0, dms[0].ses_num)
7035 @unittest.skipUnless(running_extended_tests, "part of extended tests")
7036 def test_session_limit_per_user(self):
7037 """ Deterministic NAT maximum sessions per user limit """
7038 self.vapi.nat_det_add_del_map(self.pg0.remote_ip4n,
7040 socket.inet_aton(self.nat_addr),
7042 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
7043 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
7045 self.vapi.set_ipfix_exporter(collector_address=self.pg2.remote_ip4n,
7046 src_address=self.pg2.local_ip4n,
7048 template_interval=10)
7049 self.vapi.nat_ipfix_enable_disable()
7052 for port in range(1025, 2025):
7053 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
7054 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
7055 UDP(sport=port, dport=port))
7058 self.pg0.add_stream(pkts)
7059 self.pg_enable_capture(self.pg_interfaces)
7061 capture = self.pg1.get_capture(len(pkts))
7063 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
7064 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
7065 UDP(sport=3001, dport=3002))
7066 self.pg0.add_stream(p)
7067 self.pg_enable_capture(self.pg_interfaces)
7069 capture = self.pg1.assert_nothing_captured()
7071 # verify ICMP error packet
7072 capture = self.pg0.get_capture(1)
7074 self.assertTrue(p.haslayer(ICMP))
7076 self.assertEqual(icmp.type, 3)
7077 self.assertEqual(icmp.code, 1)
7078 self.assertTrue(icmp.haslayer(IPerror))
7079 inner_ip = icmp[IPerror]
7080 self.assertEqual(inner_ip[UDPerror].sport, 3001)
7081 self.assertEqual(inner_ip[UDPerror].dport, 3002)
7083 dms = self.vapi.nat_det_map_dump()
7085 self.assertEqual(1000, dms[0].ses_num)
7087 # verify IPFIX logging
7088 self.vapi.cli("ipfix flush") # FIXME this should be an API call
7090 capture = self.pg2.get_capture(2)
7091 ipfix = IPFIXDecoder()
7092 # first load template
7094 self.assertTrue(p.haslayer(IPFIX))
7095 if p.haslayer(Template):
7096 ipfix.add_template(p.getlayer(Template))
7097 # verify events in data set
7099 if p.haslayer(Data):
7100 data = ipfix.decode_data_set(p.getlayer(Set))
7101 self.verify_ipfix_max_entries_per_user(data,
7103 self.pg0.remote_ip4n)
7105 def clear_nat_det(self):
7107 Clear deterministic NAT configuration.
7109 self.vapi.nat_ipfix_enable_disable(enable=0)
7110 self.vapi.nat_set_timeouts()
7111 deterministic_mappings = self.vapi.nat_det_map_dump()
7112 for dsm in deterministic_mappings:
7113 self.vapi.nat_det_add_del_map(dsm.in_addr,
7119 interfaces = self.vapi.nat44_interface_dump()
7120 for intf in interfaces:
7121 self.vapi.nat44_interface_add_del_feature(intf.sw_if_index,
7126 super(TestDeterministicNAT, self).tearDown()
7127 if not self.vpp_dead:
7128 self.logger.info(self.vapi.cli("show nat44 interfaces"))
7129 self.logger.info(self.vapi.cli("show nat timeouts"))
7131 self.vapi.cli("show nat44 deterministic mappings"))
7133 self.vapi.cli("show nat44 deterministic sessions"))
7134 self.clear_nat_det()
7137 class TestNAT64(MethodHolder):
7138 """ NAT64 Test Cases """
7141 def setUpConstants(cls):
7142 super(TestNAT64, cls).setUpConstants()
7143 cls.vpp_cmdline.extend(["nat", "{", "nat64 bib hash buckets 128",
7144 "nat64 st hash buckets 256", "}"])
7147 def setUpClass(cls):
7148 super(TestNAT64, cls).setUpClass()
7151 cls.tcp_port_in = 6303
7152 cls.tcp_port_out = 6303
7153 cls.udp_port_in = 6304
7154 cls.udp_port_out = 6304
7155 cls.icmp_id_in = 6305
7156 cls.icmp_id_out = 6305
7157 cls.tcp_external_port = 80
7158 cls.nat_addr = '10.0.0.3'
7159 cls.nat_addr_n = socket.inet_pton(socket.AF_INET, cls.nat_addr)
7161 cls.vrf1_nat_addr = '10.0.10.3'
7162 cls.vrf1_nat_addr_n = socket.inet_pton(socket.AF_INET,
7164 cls.ipfix_src_port = 4739
7165 cls.ipfix_domain_id = 1
7167 cls.create_pg_interfaces(range(6))
7168 cls.ip6_interfaces = list(cls.pg_interfaces[0:1])
7169 cls.ip6_interfaces.append(cls.pg_interfaces[2])
7170 cls.ip4_interfaces = list(cls.pg_interfaces[1:2])
7172 cls.vapi.ip_table_add_del(is_ipv6=1, is_add=1,
7173 table_id=cls.vrf1_id)
7175 cls.pg_interfaces[2].set_table_ip6(cls.vrf1_id)
7177 cls.pg0.generate_remote_hosts(2)
7179 for i in cls.ip6_interfaces:
7182 i.configure_ipv6_neighbors()
7184 for i in cls.ip4_interfaces:
7190 cls.pg3.config_ip4()
7191 cls.pg3.resolve_arp()
7192 cls.pg3.config_ip6()
7193 cls.pg3.configure_ipv6_neighbors()
7196 cls.pg5.config_ip6()
7199 super(TestNAT64, cls).tearDownClass()
7202 def test_nat64_inside_interface_handles_neighbor_advertisement(self):
7203 """ NAT64 inside interface handles Neighbor Advertisement """
7205 self.vapi.nat64_add_del_interface(self.pg5.sw_if_index)
7208 ping = (Ether(dst=self.pg5.local_mac, src=self.pg5.remote_mac) /
7209 IPv6(src=self.pg5.remote_ip6, dst=self.pg5.local_ip6) /
7210 ICMPv6EchoRequest())
7212 self.pg5.add_stream(pkts)
7213 self.pg_enable_capture(self.pg_interfaces)
7216 # Wait for Neighbor Solicitation
7217 capture = self.pg5.get_capture(len(pkts))
7220 self.assertEqual(packet[IPv6].src, self.pg5.local_ip6)
7221 self.assertEqual(packet.haslayer(ICMPv6ND_NS), 1)
7222 tgt = packet[ICMPv6ND_NS].tgt
7224 self.logger.error(ppp("Unexpected or invalid packet:", packet))
7227 # Send Neighbor Advertisement
7228 p = (Ether(dst=self.pg5.local_mac, src=self.pg5.remote_mac) /
7229 IPv6(src=self.pg5.remote_ip6, dst=self.pg5.local_ip6) /
7230 ICMPv6ND_NA(tgt=tgt) /
7231 ICMPv6NDOptDstLLAddr(lladdr=self.pg5.remote_mac))
7233 self.pg5.add_stream(pkts)
7234 self.pg_enable_capture(self.pg_interfaces)
7237 # Try to send ping again
7239 self.pg5.add_stream(pkts)
7240 self.pg_enable_capture(self.pg_interfaces)
7243 # Wait for ping reply
7244 capture = self.pg5.get_capture(len(pkts))
7247 self.assertEqual(packet[IPv6].src, self.pg5.local_ip6)
7248 self.assertEqual(packet[IPv6].dst, self.pg5.remote_ip6)
7249 self.assertEqual(packet.haslayer(ICMPv6EchoReply), 1)
7251 self.logger.error(ppp("Unexpected or invalid packet:", packet))
7254 def test_pool(self):
7255 """ Add/delete address to NAT64 pool """
7256 nat_addr = socket.inet_pton(socket.AF_INET, '1.2.3.4')
7258 self.vapi.nat64_add_del_pool_addr_range(nat_addr, nat_addr)
7260 addresses = self.vapi.nat64_pool_addr_dump()
7261 self.assertEqual(len(addresses), 1)
7262 self.assertEqual(addresses[0].address, nat_addr)
7264 self.vapi.nat64_add_del_pool_addr_range(nat_addr, nat_addr, is_add=0)
7266 addresses = self.vapi.nat64_pool_addr_dump()
7267 self.assertEqual(len(addresses), 0)
7269 def test_interface(self):
7270 """ Enable/disable NAT64 feature on the interface """
7271 self.vapi.nat64_add_del_interface(self.pg0.sw_if_index)
7272 self.vapi.nat64_add_del_interface(self.pg1.sw_if_index, is_inside=0)
7274 interfaces = self.vapi.nat64_interface_dump()
7275 self.assertEqual(len(interfaces), 2)
7278 for intf in interfaces:
7279 if intf.sw_if_index == self.pg0.sw_if_index:
7280 self.assertEqual(intf.is_inside, 1)
7282 elif intf.sw_if_index == self.pg1.sw_if_index:
7283 self.assertEqual(intf.is_inside, 0)
7285 self.assertTrue(pg0_found)
7286 self.assertTrue(pg1_found)
7288 features = self.vapi.cli("show interface features pg0")
7289 self.assertIn('nat64-in2out', features)
7290 features = self.vapi.cli("show interface features pg1")
7291 self.assertIn('nat64-out2in', features)
7293 self.vapi.nat64_add_del_interface(self.pg0.sw_if_index, is_add=0)
7294 self.vapi.nat64_add_del_interface(self.pg1.sw_if_index, is_add=0)
7296 interfaces = self.vapi.nat64_interface_dump()
7297 self.assertEqual(len(interfaces), 0)
7299 def test_static_bib(self):
7300 """ Add/delete static BIB entry """
7301 in_addr = socket.inet_pton(socket.AF_INET6,
7302 '2001:db8:85a3::8a2e:370:7334')
7303 out_addr = socket.inet_pton(socket.AF_INET, '10.1.1.3')
7306 proto = IP_PROTOS.tcp
7308 self.vapi.nat64_add_del_static_bib(in_addr,
7313 bib = self.vapi.nat64_bib_dump(IP_PROTOS.tcp)
7318 self.assertEqual(bibe.i_addr, in_addr)
7319 self.assertEqual(bibe.o_addr, out_addr)
7320 self.assertEqual(bibe.i_port, in_port)
7321 self.assertEqual(bibe.o_port, out_port)
7322 self.assertEqual(static_bib_num, 1)
7323 bibs = self.statistics.get_counter('/nat64/total-bibs')
7324 self.assertEqual(bibs[0][0], 1)
7326 self.vapi.nat64_add_del_static_bib(in_addr,
7332 bib = self.vapi.nat64_bib_dump(IP_PROTOS.tcp)
7337 self.assertEqual(static_bib_num, 0)
7338 bibs = self.statistics.get_counter('/nat64/total-bibs')
7339 self.assertEqual(bibs[0][0], 0)
7341 def test_set_timeouts(self):
7342 """ Set NAT64 timeouts """
7343 # verify default values
7344 timeouts = self.vapi.nat_get_timeouts()
7345 self.assertEqual(timeouts.udp, 300)
7346 self.assertEqual(timeouts.icmp, 60)
7347 self.assertEqual(timeouts.tcp_transitory, 240)
7348 self.assertEqual(timeouts.tcp_established, 7440)
7350 # set and verify custom values
7351 self.vapi.nat_set_timeouts(udp=200, icmp=30, tcp_transitory=250,
7352 tcp_established=7450)
7353 timeouts = self.vapi.nat_get_timeouts()
7354 self.assertEqual(timeouts.udp, 200)
7355 self.assertEqual(timeouts.icmp, 30)
7356 self.assertEqual(timeouts.tcp_transitory, 250)
7357 self.assertEqual(timeouts.tcp_established, 7450)
7359 def test_dynamic(self):
7360 """ NAT64 dynamic translation test """
7361 self.tcp_port_in = 6303
7362 self.udp_port_in = 6304
7363 self.icmp_id_in = 6305
7365 ses_num_start = self.nat64_get_ses_num()
7367 self.vapi.nat64_add_del_pool_addr_range(self.nat_addr_n,
7369 self.vapi.nat64_add_del_interface(self.pg0.sw_if_index)
7370 self.vapi.nat64_add_del_interface(self.pg1.sw_if_index, is_inside=0)
7373 tcpn = self.statistics.get_counter('/err/nat64-in2out/TCP packets')
7374 udpn = self.statistics.get_counter('/err/nat64-in2out/UDP packets')
7375 icmpn = self.statistics.get_counter('/err/nat64-in2out/ICMP packets')
7376 totaln = self.statistics.get_counter(
7377 '/err/nat64-in2out/good in2out packets processed')
7379 pkts = self.create_stream_in_ip6(self.pg0, self.pg1)
7380 self.pg0.add_stream(pkts)
7381 self.pg_enable_capture(self.pg_interfaces)
7383 capture = self.pg1.get_capture(len(pkts))
7384 self.verify_capture_out(capture, nat_ip=self.nat_addr,
7385 dst_ip=self.pg1.remote_ip4)
7387 err = self.statistics.get_counter('/err/nat64-in2out/TCP packets')
7388 self.assertEqual(err - tcpn, 1)
7389 err = self.statistics.get_counter('/err/nat64-in2out/UDP packets')
7390 self.assertEqual(err - udpn, 1)
7391 err = self.statistics.get_counter('/err/nat64-in2out/ICMP packets')
7392 self.assertEqual(err - icmpn, 1)
7393 err = self.statistics.get_counter(
7394 '/err/nat64-in2out/good in2out packets processed')
7395 self.assertEqual(err - totaln, 3)
7398 tcpn = self.statistics.get_counter('/err/nat64-out2in/TCP packets')
7399 udpn = self.statistics.get_counter('/err/nat64-out2in/UDP packets')
7400 icmpn = self.statistics.get_counter('/err/nat64-out2in/ICMP packets')
7401 totaln = self.statistics.get_counter(
7402 '/err/nat64-out2in/good out2in packets processed')
7404 pkts = self.create_stream_out(self.pg1, dst_ip=self.nat_addr)
7405 self.pg1.add_stream(pkts)
7406 self.pg_enable_capture(self.pg_interfaces)
7408 capture = self.pg0.get_capture(len(pkts))
7409 ip = IPv6(src=''.join(['64:ff9b::', self.pg1.remote_ip4]))
7410 self.verify_capture_in_ip6(capture, ip[IPv6].src, self.pg0.remote_ip6)
7412 err = self.statistics.get_counter('/err/nat64-out2in/TCP packets')
7413 self.assertEqual(err - tcpn, 1)
7414 err = self.statistics.get_counter('/err/nat64-out2in/UDP packets')
7415 self.assertEqual(err - udpn, 1)
7416 err = self.statistics.get_counter('/err/nat64-out2in/ICMP packets')
7417 self.assertEqual(err - icmpn, 1)
7418 err = self.statistics.get_counter(
7419 '/err/nat64-out2in/good out2in packets processed')
7420 self.assertEqual(err - totaln, 3)
7422 bibs = self.statistics.get_counter('/nat64/total-bibs')
7423 self.assertEqual(bibs[0][0], 3)
7424 sessions = self.statistics.get_counter('/nat64/total-sessions')
7425 self.assertEqual(sessions[0][0], 3)
7428 pkts = self.create_stream_in_ip6(self.pg0, self.pg1)
7429 self.pg0.add_stream(pkts)
7430 self.pg_enable_capture(self.pg_interfaces)
7432 capture = self.pg1.get_capture(len(pkts))
7433 self.verify_capture_out(capture, nat_ip=self.nat_addr,
7434 dst_ip=self.pg1.remote_ip4)
7437 pkts = self.create_stream_out(self.pg1, dst_ip=self.nat_addr)
7438 self.pg1.add_stream(pkts)
7439 self.pg_enable_capture(self.pg_interfaces)
7441 capture = self.pg0.get_capture(len(pkts))
7442 self.verify_capture_in_ip6(capture, ip[IPv6].src, self.pg0.remote_ip6)
7444 ses_num_end = self.nat64_get_ses_num()
7446 self.assertEqual(ses_num_end - ses_num_start, 3)
7448 # tenant with specific VRF
7449 self.vapi.nat64_add_del_pool_addr_range(self.vrf1_nat_addr_n,
7450 self.vrf1_nat_addr_n,
7451 vrf_id=self.vrf1_id)
7452 self.vapi.nat64_add_del_interface(self.pg2.sw_if_index)
7454 pkts = self.create_stream_in_ip6(self.pg2, self.pg1)
7455 self.pg2.add_stream(pkts)
7456 self.pg_enable_capture(self.pg_interfaces)
7458 capture = self.pg1.get_capture(len(pkts))
7459 self.verify_capture_out(capture, nat_ip=self.vrf1_nat_addr,
7460 dst_ip=self.pg1.remote_ip4)
7462 pkts = self.create_stream_out(self.pg1, dst_ip=self.vrf1_nat_addr)
7463 self.pg1.add_stream(pkts)
7464 self.pg_enable_capture(self.pg_interfaces)
7466 capture = self.pg2.get_capture(len(pkts))
7467 self.verify_capture_in_ip6(capture, ip[IPv6].src, self.pg2.remote_ip6)
7469 def test_static(self):
7470 """ NAT64 static translation test """
7471 self.tcp_port_in = 60303
7472 self.udp_port_in = 60304
7473 self.icmp_id_in = 60305
7474 self.tcp_port_out = 60303
7475 self.udp_port_out = 60304
7476 self.icmp_id_out = 60305
7478 ses_num_start = self.nat64_get_ses_num()
7480 self.vapi.nat64_add_del_pool_addr_range(self.nat_addr_n,
7482 self.vapi.nat64_add_del_interface(self.pg0.sw_if_index)
7483 self.vapi.nat64_add_del_interface(self.pg1.sw_if_index, is_inside=0)
7485 self.vapi.nat64_add_del_static_bib(self.pg0.remote_ip6n,
7490 self.vapi.nat64_add_del_static_bib(self.pg0.remote_ip6n,
7495 self.vapi.nat64_add_del_static_bib(self.pg0.remote_ip6n,
7502 pkts = self.create_stream_in_ip6(self.pg0, self.pg1)
7503 self.pg0.add_stream(pkts)
7504 self.pg_enable_capture(self.pg_interfaces)
7506 capture = self.pg1.get_capture(len(pkts))
7507 self.verify_capture_out(capture, nat_ip=self.nat_addr,
7508 dst_ip=self.pg1.remote_ip4, same_port=True)
7511 pkts = self.create_stream_out(self.pg1, dst_ip=self.nat_addr)
7512 self.pg1.add_stream(pkts)
7513 self.pg_enable_capture(self.pg_interfaces)
7515 capture = self.pg0.get_capture(len(pkts))
7516 ip = IPv6(src=''.join(['64:ff9b::', self.pg1.remote_ip4]))
7517 self.verify_capture_in_ip6(capture, ip[IPv6].src, self.pg0.remote_ip6)
7519 ses_num_end = self.nat64_get_ses_num()
7521 self.assertEqual(ses_num_end - ses_num_start, 3)
7523 @unittest.skipUnless(running_extended_tests, "part of extended tests")
7524 def test_session_timeout(self):
7525 """ NAT64 session timeout """
7526 self.icmp_id_in = 1234
7527 self.vapi.nat64_add_del_pool_addr_range(self.nat_addr_n,
7529 self.vapi.nat64_add_del_interface(self.pg0.sw_if_index)
7530 self.vapi.nat64_add_del_interface(self.pg1.sw_if_index, is_inside=0)
7531 self.vapi.nat_set_timeouts(icmp=5, tcp_transitory=5, tcp_established=5)
7533 pkts = self.create_stream_in_ip6(self.pg0, self.pg1)
7534 self.pg0.add_stream(pkts)
7535 self.pg_enable_capture(self.pg_interfaces)
7537 capture = self.pg1.get_capture(len(pkts))
7539 ses_num_before_timeout = self.nat64_get_ses_num()
7543 # ICMP and TCP session after timeout
7544 ses_num_after_timeout = self.nat64_get_ses_num()
7545 self.assertEqual(ses_num_before_timeout - ses_num_after_timeout, 2)
7547 def test_icmp_error(self):
7548 """ NAT64 ICMP Error message translation """
7549 self.tcp_port_in = 6303
7550 self.udp_port_in = 6304
7551 self.icmp_id_in = 6305
7553 self.vapi.nat64_add_del_pool_addr_range(self.nat_addr_n,
7555 self.vapi.nat64_add_del_interface(self.pg0.sw_if_index)
7556 self.vapi.nat64_add_del_interface(self.pg1.sw_if_index, is_inside=0)
7558 # send some packets to create sessions
7559 pkts = self.create_stream_in_ip6(self.pg0, self.pg1)
7560 self.pg0.add_stream(pkts)
7561 self.pg_enable_capture(self.pg_interfaces)
7563 capture_ip4 = self.pg1.get_capture(len(pkts))
7564 self.verify_capture_out(capture_ip4,
7565 nat_ip=self.nat_addr,
7566 dst_ip=self.pg1.remote_ip4)
7568 pkts = self.create_stream_out(self.pg1, dst_ip=self.nat_addr)
7569 self.pg1.add_stream(pkts)
7570 self.pg_enable_capture(self.pg_interfaces)
7572 capture_ip6 = self.pg0.get_capture(len(pkts))
7573 ip = IPv6(src=''.join(['64:ff9b::', self.pg1.remote_ip4]))
7574 self.verify_capture_in_ip6(capture_ip6, ip[IPv6].src,
7575 self.pg0.remote_ip6)
7578 pkts = [Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
7579 IPv6(src=self.pg0.remote_ip6, dst=ip[IPv6].src) /
7580 ICMPv6DestUnreach(code=1) /
7581 packet[IPv6] for packet in capture_ip6]
7582 self.pg0.add_stream(pkts)
7583 self.pg_enable_capture(self.pg_interfaces)
7585 capture = self.pg1.get_capture(len(pkts))
7586 for packet in capture:
7588 self.assertEqual(packet[IP].src, self.nat_addr)
7589 self.assertEqual(packet[IP].dst, self.pg1.remote_ip4)
7590 self.assertEqual(packet[ICMP].type, 3)
7591 self.assertEqual(packet[ICMP].code, 13)
7592 inner = packet[IPerror]
7593 self.assertEqual(inner.src, self.pg1.remote_ip4)
7594 self.assertEqual(inner.dst, self.nat_addr)
7595 self.assert_packet_checksums_valid(packet)
7596 if inner.haslayer(TCPerror):
7597 self.assertEqual(inner[TCPerror].dport, self.tcp_port_out)
7598 elif inner.haslayer(UDPerror):
7599 self.assertEqual(inner[UDPerror].dport, self.udp_port_out)
7601 self.assertEqual(inner[ICMPerror].id, self.icmp_id_out)
7603 self.logger.error(ppp("Unexpected or invalid packet:", packet))
7607 pkts = [Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
7608 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
7609 ICMP(type=3, code=13) /
7610 packet[IP] for packet in capture_ip4]
7611 self.pg1.add_stream(pkts)
7612 self.pg_enable_capture(self.pg_interfaces)
7614 capture = self.pg0.get_capture(len(pkts))
7615 for packet in capture:
7617 self.assertEqual(packet[IPv6].src, ip.src)
7618 self.assertEqual(packet[IPv6].dst, self.pg0.remote_ip6)
7619 icmp = packet[ICMPv6DestUnreach]
7620 self.assertEqual(icmp.code, 1)
7621 inner = icmp[IPerror6]
7622 self.assertEqual(inner.src, self.pg0.remote_ip6)
7623 self.assertEqual(inner.dst, ip.src)
7624 self.assert_icmpv6_checksum_valid(packet)
7625 if inner.haslayer(TCPerror):
7626 self.assertEqual(inner[TCPerror].sport, self.tcp_port_in)
7627 elif inner.haslayer(UDPerror):
7628 self.assertEqual(inner[UDPerror].sport, self.udp_port_in)
7630 self.assertEqual(inner[ICMPv6EchoRequest].id,
7633 self.logger.error(ppp("Unexpected or invalid packet:", packet))
7636 def test_hairpinning(self):
7637 """ NAT64 hairpinning """
7639 client = self.pg0.remote_hosts[0]
7640 server = self.pg0.remote_hosts[1]
7641 server_tcp_in_port = 22
7642 server_tcp_out_port = 4022
7643 server_udp_in_port = 23
7644 server_udp_out_port = 4023
7645 client_tcp_in_port = 1234
7646 client_udp_in_port = 1235
7647 client_tcp_out_port = 0
7648 client_udp_out_port = 0
7649 ip = IPv6(src=''.join(['64:ff9b::', self.nat_addr]))
7650 nat_addr_ip6 = ip.src
7652 self.vapi.nat64_add_del_pool_addr_range(self.nat_addr_n,
7654 self.vapi.nat64_add_del_interface(self.pg0.sw_if_index)
7655 self.vapi.nat64_add_del_interface(self.pg1.sw_if_index, is_inside=0)
7657 self.vapi.nat64_add_del_static_bib(server.ip6n,
7660 server_tcp_out_port,
7662 self.vapi.nat64_add_del_static_bib(server.ip6n,
7665 server_udp_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 TCP(sport=client_tcp_in_port, dport=server_tcp_out_port))
7674 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
7675 IPv6(src=client.ip6, dst=nat_addr_ip6) /
7676 UDP(sport=client_udp_in_port, dport=server_udp_out_port))
7678 self.pg0.add_stream(pkts)
7679 self.pg_enable_capture(self.pg_interfaces)
7681 capture = self.pg0.get_capture(len(pkts))
7682 for packet in capture:
7684 self.assertEqual(packet[IPv6].src, nat_addr_ip6)
7685 self.assertEqual(packet[IPv6].dst, server.ip6)
7686 self.assert_packet_checksums_valid(packet)
7687 if packet.haslayer(TCP):
7688 self.assertNotEqual(packet[TCP].sport, client_tcp_in_port)
7689 self.assertEqual(packet[TCP].dport, server_tcp_in_port)
7690 client_tcp_out_port = packet[TCP].sport
7692 self.assertNotEqual(packet[UDP].sport, client_udp_in_port)
7693 self.assertEqual(packet[UDP].dport, server_udp_in_port)
7694 client_udp_out_port = packet[UDP].sport
7696 self.logger.error(ppp("Unexpected or invalid packet:", packet))
7701 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
7702 IPv6(src=server.ip6, dst=nat_addr_ip6) /
7703 TCP(sport=server_tcp_in_port, dport=client_tcp_out_port))
7705 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
7706 IPv6(src=server.ip6, dst=nat_addr_ip6) /
7707 UDP(sport=server_udp_in_port, dport=client_udp_out_port))
7709 self.pg0.add_stream(pkts)
7710 self.pg_enable_capture(self.pg_interfaces)
7712 capture = self.pg0.get_capture(len(pkts))
7713 for packet in capture:
7715 self.assertEqual(packet[IPv6].src, nat_addr_ip6)
7716 self.assertEqual(packet[IPv6].dst, client.ip6)
7717 self.assert_packet_checksums_valid(packet)
7718 if packet.haslayer(TCP):
7719 self.assertEqual(packet[TCP].sport, server_tcp_out_port)
7720 self.assertEqual(packet[TCP].dport, client_tcp_in_port)
7722 self.assertEqual(packet[UDP].sport, server_udp_out_port)
7723 self.assertEqual(packet[UDP].dport, client_udp_in_port)
7725 self.logger.error(ppp("Unexpected or invalid packet:", packet))
7730 pkts = [Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
7731 IPv6(src=client.ip6, dst=nat_addr_ip6) /
7732 ICMPv6DestUnreach(code=1) /
7733 packet[IPv6] for packet in capture]
7734 self.pg0.add_stream(pkts)
7735 self.pg_enable_capture(self.pg_interfaces)
7737 capture = self.pg0.get_capture(len(pkts))
7738 for packet in capture:
7740 self.assertEqual(packet[IPv6].src, nat_addr_ip6)
7741 self.assertEqual(packet[IPv6].dst, server.ip6)
7742 icmp = packet[ICMPv6DestUnreach]
7743 self.assertEqual(icmp.code, 1)
7744 inner = icmp[IPerror6]
7745 self.assertEqual(inner.src, server.ip6)
7746 self.assertEqual(inner.dst, nat_addr_ip6)
7747 self.assert_packet_checksums_valid(packet)
7748 if inner.haslayer(TCPerror):
7749 self.assertEqual(inner[TCPerror].sport, server_tcp_in_port)
7750 self.assertEqual(inner[TCPerror].dport,
7751 client_tcp_out_port)
7753 self.assertEqual(inner[UDPerror].sport, server_udp_in_port)
7754 self.assertEqual(inner[UDPerror].dport,
7755 client_udp_out_port)
7757 self.logger.error(ppp("Unexpected or invalid packet:", packet))
7760 def test_prefix(self):
7761 """ NAT64 Network-Specific Prefix """
7763 self.vapi.nat64_add_del_pool_addr_range(self.nat_addr_n,
7765 self.vapi.nat64_add_del_interface(self.pg0.sw_if_index)
7766 self.vapi.nat64_add_del_interface(self.pg1.sw_if_index, is_inside=0)
7767 self.vapi.nat64_add_del_pool_addr_range(self.vrf1_nat_addr_n,
7768 self.vrf1_nat_addr_n,
7769 vrf_id=self.vrf1_id)
7770 self.vapi.nat64_add_del_interface(self.pg2.sw_if_index)
7773 global_pref64 = "2001:db8::"
7774 global_pref64_n = socket.inet_pton(socket.AF_INET6, global_pref64)
7775 global_pref64_len = 32
7776 self.vapi.nat64_add_del_prefix(global_pref64_n, global_pref64_len)
7778 prefix = self.vapi.nat64_prefix_dump()
7779 self.assertEqual(len(prefix), 1)
7780 self.assertEqual(prefix[0].prefix, global_pref64_n)
7781 self.assertEqual(prefix[0].prefix_len, global_pref64_len)
7782 self.assertEqual(prefix[0].vrf_id, 0)
7784 # Add tenant specific prefix
7785 vrf1_pref64 = "2001:db8:122:300::"
7786 vrf1_pref64_n = socket.inet_pton(socket.AF_INET6, vrf1_pref64)
7787 vrf1_pref64_len = 56
7788 self.vapi.nat64_add_del_prefix(vrf1_pref64_n,
7790 vrf_id=self.vrf1_id)
7791 prefix = self.vapi.nat64_prefix_dump()
7792 self.assertEqual(len(prefix), 2)
7795 pkts = self.create_stream_in_ip6(self.pg0,
7798 plen=global_pref64_len)
7799 self.pg0.add_stream(pkts)
7800 self.pg_enable_capture(self.pg_interfaces)
7802 capture = self.pg1.get_capture(len(pkts))
7803 self.verify_capture_out(capture, nat_ip=self.nat_addr,
7804 dst_ip=self.pg1.remote_ip4)
7806 pkts = self.create_stream_out(self.pg1, dst_ip=self.nat_addr)
7807 self.pg1.add_stream(pkts)
7808 self.pg_enable_capture(self.pg_interfaces)
7810 capture = self.pg0.get_capture(len(pkts))
7811 dst_ip = self.compose_ip6(self.pg1.remote_ip4,
7814 self.verify_capture_in_ip6(capture, dst_ip, self.pg0.remote_ip6)
7816 # Tenant specific prefix
7817 pkts = self.create_stream_in_ip6(self.pg2,
7820 plen=vrf1_pref64_len)
7821 self.pg2.add_stream(pkts)
7822 self.pg_enable_capture(self.pg_interfaces)
7824 capture = self.pg1.get_capture(len(pkts))
7825 self.verify_capture_out(capture, nat_ip=self.vrf1_nat_addr,
7826 dst_ip=self.pg1.remote_ip4)
7828 pkts = self.create_stream_out(self.pg1, dst_ip=self.vrf1_nat_addr)
7829 self.pg1.add_stream(pkts)
7830 self.pg_enable_capture(self.pg_interfaces)
7832 capture = self.pg2.get_capture(len(pkts))
7833 dst_ip = self.compose_ip6(self.pg1.remote_ip4,
7836 self.verify_capture_in_ip6(capture, dst_ip, self.pg2.remote_ip6)
7838 def test_unknown_proto(self):
7839 """ NAT64 translate packet with unknown protocol """
7841 self.vapi.nat64_add_del_pool_addr_range(self.nat_addr_n,
7843 self.vapi.nat64_add_del_interface(self.pg0.sw_if_index)
7844 self.vapi.nat64_add_del_interface(self.pg1.sw_if_index, is_inside=0)
7845 remote_ip6 = self.compose_ip6(self.pg1.remote_ip4, '64:ff9b::', 96)
7848 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
7849 IPv6(src=self.pg0.remote_ip6, dst=remote_ip6) /
7850 TCP(sport=self.tcp_port_in, dport=20))
7851 self.pg0.add_stream(p)
7852 self.pg_enable_capture(self.pg_interfaces)
7854 p = self.pg1.get_capture(1)
7856 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
7857 IPv6(src=self.pg0.remote_ip6, dst=remote_ip6, nh=47) /
7859 IP(src=self.pg2.local_ip4, dst=self.pg2.remote_ip4) /
7860 TCP(sport=1234, dport=1234))
7861 self.pg0.add_stream(p)
7862 self.pg_enable_capture(self.pg_interfaces)
7864 p = self.pg1.get_capture(1)
7867 self.assertEqual(packet[IP].src, self.nat_addr)
7868 self.assertEqual(packet[IP].dst, self.pg1.remote_ip4)
7869 self.assertEqual(packet.haslayer(GRE), 1)
7870 self.assert_packet_checksums_valid(packet)
7872 self.logger.error(ppp("Unexpected or invalid packet:", packet))
7876 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
7877 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
7879 IP(src=self.pg2.remote_ip4, dst=self.pg2.local_ip4) /
7880 TCP(sport=1234, dport=1234))
7881 self.pg1.add_stream(p)
7882 self.pg_enable_capture(self.pg_interfaces)
7884 p = self.pg0.get_capture(1)
7887 self.assertEqual(packet[IPv6].src, remote_ip6)
7888 self.assertEqual(packet[IPv6].dst, self.pg0.remote_ip6)
7889 self.assertEqual(packet[IPv6].nh, 47)
7891 self.logger.error(ppp("Unexpected or invalid packet:", packet))
7894 def test_hairpinning_unknown_proto(self):
7895 """ NAT64 translate packet with unknown protocol - hairpinning """
7897 client = self.pg0.remote_hosts[0]
7898 server = self.pg0.remote_hosts[1]
7899 server_tcp_in_port = 22
7900 server_tcp_out_port = 4022
7901 client_tcp_in_port = 1234
7902 client_tcp_out_port = 1235
7903 server_nat_ip = "10.0.0.100"
7904 client_nat_ip = "10.0.0.110"
7905 server_nat_ip_n = socket.inet_pton(socket.AF_INET, server_nat_ip)
7906 client_nat_ip_n = socket.inet_pton(socket.AF_INET, client_nat_ip)
7907 server_nat_ip6 = self.compose_ip6(server_nat_ip, '64:ff9b::', 96)
7908 client_nat_ip6 = self.compose_ip6(client_nat_ip, '64:ff9b::', 96)
7910 self.vapi.nat64_add_del_pool_addr_range(server_nat_ip_n,
7912 self.vapi.nat64_add_del_interface(self.pg0.sw_if_index)
7913 self.vapi.nat64_add_del_interface(self.pg1.sw_if_index, is_inside=0)
7915 self.vapi.nat64_add_del_static_bib(server.ip6n,
7918 server_tcp_out_port,
7921 self.vapi.nat64_add_del_static_bib(server.ip6n,
7927 self.vapi.nat64_add_del_static_bib(client.ip6n,
7930 client_tcp_out_port,
7934 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
7935 IPv6(src=client.ip6, dst=server_nat_ip6) /
7936 TCP(sport=client_tcp_in_port, dport=server_tcp_out_port))
7937 self.pg0.add_stream(p)
7938 self.pg_enable_capture(self.pg_interfaces)
7940 p = self.pg0.get_capture(1)
7942 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
7943 IPv6(src=client.ip6, dst=server_nat_ip6, nh=IP_PROTOS.gre) /
7945 IP(src=self.pg2.local_ip4, dst=self.pg2.remote_ip4) /
7946 TCP(sport=1234, dport=1234))
7947 self.pg0.add_stream(p)
7948 self.pg_enable_capture(self.pg_interfaces)
7950 p = self.pg0.get_capture(1)
7953 self.assertEqual(packet[IPv6].src, client_nat_ip6)
7954 self.assertEqual(packet[IPv6].dst, server.ip6)
7955 self.assertEqual(packet[IPv6].nh, IP_PROTOS.gre)
7957 self.logger.error(ppp("Unexpected or invalid packet:", packet))
7961 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
7962 IPv6(src=server.ip6, dst=client_nat_ip6, nh=IP_PROTOS.gre) /
7964 IP(src=self.pg2.remote_ip4, dst=self.pg2.local_ip4) /
7965 TCP(sport=1234, dport=1234))
7966 self.pg0.add_stream(p)
7967 self.pg_enable_capture(self.pg_interfaces)
7969 p = self.pg0.get_capture(1)
7972 self.assertEqual(packet[IPv6].src, server_nat_ip6)
7973 self.assertEqual(packet[IPv6].dst, client.ip6)
7974 self.assertEqual(packet[IPv6].nh, IP_PROTOS.gre)
7976 self.logger.error(ppp("Unexpected or invalid packet:", packet))
7979 def test_one_armed_nat64(self):
7980 """ One armed NAT64 """
7982 remote_host_ip6 = self.compose_ip6(self.pg3.remote_ip4,
7986 self.vapi.nat64_add_del_pool_addr_range(self.nat_addr_n,
7988 self.vapi.nat64_add_del_interface(self.pg3.sw_if_index)
7989 self.vapi.nat64_add_del_interface(self.pg3.sw_if_index, is_inside=0)
7992 p = (Ether(src=self.pg3.remote_mac, dst=self.pg3.local_mac) /
7993 IPv6(src=self.pg3.remote_ip6, dst=remote_host_ip6) /
7994 TCP(sport=12345, dport=80))
7995 self.pg3.add_stream(p)
7996 self.pg_enable_capture(self.pg_interfaces)
7998 capture = self.pg3.get_capture(1)
8003 self.assertEqual(ip.src, self.nat_addr)
8004 self.assertEqual(ip.dst, self.pg3.remote_ip4)
8005 self.assertNotEqual(tcp.sport, 12345)
8006 external_port = tcp.sport
8007 self.assertEqual(tcp.dport, 80)
8008 self.assert_packet_checksums_valid(p)
8010 self.logger.error(ppp("Unexpected or invalid packet:", p))
8014 p = (Ether(src=self.pg3.remote_mac, dst=self.pg3.local_mac) /
8015 IP(src=self.pg3.remote_ip4, dst=self.nat_addr) /
8016 TCP(sport=80, dport=external_port))
8017 self.pg3.add_stream(p)
8018 self.pg_enable_capture(self.pg_interfaces)
8020 capture = self.pg3.get_capture(1)
8025 self.assertEqual(ip.src, remote_host_ip6)
8026 self.assertEqual(ip.dst, self.pg3.remote_ip6)
8027 self.assertEqual(tcp.sport, 80)
8028 self.assertEqual(tcp.dport, 12345)
8029 self.assert_packet_checksums_valid(p)
8031 self.logger.error(ppp("Unexpected or invalid packet:", p))
8034 def test_frag_in_order(self):
8035 """ NAT64 translate fragments arriving in order """
8036 self.tcp_port_in = random.randint(1025, 65535)
8038 self.vapi.nat64_add_del_pool_addr_range(self.nat_addr_n,
8040 self.vapi.nat64_add_del_interface(self.pg0.sw_if_index)
8041 self.vapi.nat64_add_del_interface(self.pg1.sw_if_index, is_inside=0)
8043 reass = self.vapi.nat_reass_dump()
8044 reass_n_start = len(reass)
8048 pkts = self.create_stream_frag_ip6(self.pg0, self.pg1.remote_ip4,
8049 self.tcp_port_in, 20, data)
8050 self.pg0.add_stream(pkts)
8051 self.pg_enable_capture(self.pg_interfaces)
8053 frags = self.pg1.get_capture(len(pkts))
8054 p = self.reass_frags_and_verify(frags,
8056 self.pg1.remote_ip4)
8057 self.assertEqual(p[TCP].dport, 20)
8058 self.assertNotEqual(p[TCP].sport, self.tcp_port_in)
8059 self.tcp_port_out = p[TCP].sport
8060 self.assertEqual(data, p[Raw].load)
8063 data = b"A" * 4 + b"b" * 16 + b"C" * 3
8064 pkts = self.create_stream_frag(self.pg1,
8069 self.pg1.add_stream(pkts)
8070 self.pg_enable_capture(self.pg_interfaces)
8072 frags = self.pg0.get_capture(len(pkts))
8073 src = self.compose_ip6(self.pg1.remote_ip4, '64:ff9b::', 96)
8074 p = self.reass_frags_and_verify_ip6(frags, src, self.pg0.remote_ip6)
8075 self.assertEqual(p[TCP].sport, 20)
8076 self.assertEqual(p[TCP].dport, self.tcp_port_in)
8077 self.assertEqual(data, p[Raw].load)
8079 reass = self.vapi.nat_reass_dump()
8080 reass_n_end = len(reass)
8082 self.assertEqual(reass_n_end - reass_n_start, 2)
8084 def test_reass_hairpinning(self):
8085 """ NAT64 fragments hairpinning """
8087 server = self.pg0.remote_hosts[1]
8088 server_in_port = random.randint(1025, 65535)
8089 server_out_port = random.randint(1025, 65535)
8090 client_in_port = random.randint(1025, 65535)
8091 ip = IPv6(src=''.join(['64:ff9b::', self.nat_addr]))
8092 nat_addr_ip6 = ip.src
8094 self.vapi.nat64_add_del_pool_addr_range(self.nat_addr_n,
8096 self.vapi.nat64_add_del_interface(self.pg0.sw_if_index)
8097 self.vapi.nat64_add_del_interface(self.pg1.sw_if_index, is_inside=0)
8099 # add static BIB entry for server
8100 self.vapi.nat64_add_del_static_bib(server.ip6n,
8106 # send packet from host to server
8107 pkts = self.create_stream_frag_ip6(self.pg0,
8112 self.pg0.add_stream(pkts)
8113 self.pg_enable_capture(self.pg_interfaces)
8115 frags = self.pg0.get_capture(len(pkts))
8116 p = self.reass_frags_and_verify_ip6(frags, nat_addr_ip6, server.ip6)
8117 self.assertNotEqual(p[TCP].sport, client_in_port)
8118 self.assertEqual(p[TCP].dport, server_in_port)
8119 self.assertEqual(data, p[Raw].load)
8121 def test_frag_out_of_order(self):
8122 """ NAT64 translate fragments arriving out of order """
8123 self.tcp_port_in = random.randint(1025, 65535)
8125 self.vapi.nat64_add_del_pool_addr_range(self.nat_addr_n,
8127 self.vapi.nat64_add_del_interface(self.pg0.sw_if_index)
8128 self.vapi.nat64_add_del_interface(self.pg1.sw_if_index, is_inside=0)
8132 pkts = self.create_stream_frag_ip6(self.pg0, self.pg1.remote_ip4,
8133 self.tcp_port_in, 20, data)
8135 self.pg0.add_stream(pkts)
8136 self.pg_enable_capture(self.pg_interfaces)
8138 frags = self.pg1.get_capture(len(pkts))
8139 p = self.reass_frags_and_verify(frags,
8141 self.pg1.remote_ip4)
8142 self.assertEqual(p[TCP].dport, 20)
8143 self.assertNotEqual(p[TCP].sport, self.tcp_port_in)
8144 self.tcp_port_out = p[TCP].sport
8145 self.assertEqual(data, p[Raw].load)
8148 data = b"A" * 4 + b"B" * 16 + b"C" * 3
8149 pkts = self.create_stream_frag(self.pg1,
8155 self.pg1.add_stream(pkts)
8156 self.pg_enable_capture(self.pg_interfaces)
8158 frags = self.pg0.get_capture(len(pkts))
8159 src = self.compose_ip6(self.pg1.remote_ip4, '64:ff9b::', 96)
8160 p = self.reass_frags_and_verify_ip6(frags, src, self.pg0.remote_ip6)
8161 self.assertEqual(p[TCP].sport, 20)
8162 self.assertEqual(p[TCP].dport, self.tcp_port_in)
8163 self.assertEqual(data, p[Raw].load)
8165 def test_interface_addr(self):
8166 """ Acquire NAT64 pool addresses from interface """
8167 self.vapi.nat64_add_del_interface_addr(self.pg4.sw_if_index)
8169 # no address in NAT64 pool
8170 adresses = self.vapi.nat44_address_dump()
8171 self.assertEqual(0, len(adresses))
8173 # configure interface address and check NAT64 address pool
8174 self.pg4.config_ip4()
8175 addresses = self.vapi.nat64_pool_addr_dump()
8176 self.assertEqual(len(addresses), 1)
8177 self.assertEqual(addresses[0].address, self.pg4.local_ip4n)
8179 # remove interface address and check NAT64 address pool
8180 self.pg4.unconfig_ip4()
8181 addresses = self.vapi.nat64_pool_addr_dump()
8182 self.assertEqual(0, len(adresses))
8184 @unittest.skipUnless(running_extended_tests, "part of extended tests")
8185 def test_ipfix_max_bibs_sessions(self):
8186 """ IPFIX logging maximum session and BIB entries exceeded """
8189 remote_host_ip6 = self.compose_ip6(self.pg1.remote_ip4,
8193 self.vapi.nat64_add_del_pool_addr_range(self.nat_addr_n,
8195 self.vapi.nat64_add_del_interface(self.pg0.sw_if_index)
8196 self.vapi.nat64_add_del_interface(self.pg1.sw_if_index, is_inside=0)
8200 for i in range(0, max_bibs):
8201 src = "fd01:aa::%x" % (i)
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=80))
8206 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
8207 IPv6(src=src, dst=remote_host_ip6) /
8208 TCP(sport=12345, dport=22))
8210 self.pg0.add_stream(pkts)
8211 self.pg_enable_capture(self.pg_interfaces)
8213 self.pg1.get_capture(max_sessions)
8215 self.vapi.set_ipfix_exporter(collector_address=self.pg3.remote_ip4n,
8216 src_address=self.pg3.local_ip4n,
8218 template_interval=10)
8219 self.vapi.nat_ipfix_enable_disable(domain_id=self.ipfix_domain_id,
8220 src_port=self.ipfix_src_port)
8222 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
8223 IPv6(src=src, dst=remote_host_ip6) /
8224 TCP(sport=12345, dport=25))
8225 self.pg0.add_stream(p)
8226 self.pg_enable_capture(self.pg_interfaces)
8228 self.pg1.assert_nothing_captured()
8230 self.vapi.cli("ipfix flush") # FIXME this should be an API call
8231 capture = self.pg3.get_capture(9)
8232 ipfix = IPFIXDecoder()
8233 # first load template
8235 self.assertTrue(p.haslayer(IPFIX))
8236 self.assertEqual(p[IP].src, self.pg3.local_ip4)
8237 self.assertEqual(p[IP].dst, self.pg3.remote_ip4)
8238 self.assertEqual(p[UDP].sport, self.ipfix_src_port)
8239 self.assertEqual(p[UDP].dport, 4739)
8240 self.assertEqual(p[IPFIX].observationDomainID,
8241 self.ipfix_domain_id)
8242 if p.haslayer(Template):
8243 ipfix.add_template(p.getlayer(Template))
8244 # verify events in data set
8246 if p.haslayer(Data):
8247 data = ipfix.decode_data_set(p.getlayer(Set))
8248 self.verify_ipfix_max_sessions(data, max_sessions)
8250 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
8251 IPv6(src=self.pg0.remote_ip6, dst=remote_host_ip6) /
8252 TCP(sport=12345, dport=80))
8253 self.pg0.add_stream(p)
8254 self.pg_enable_capture(self.pg_interfaces)
8256 self.pg1.assert_nothing_captured()
8258 self.vapi.cli("ipfix flush") # FIXME this should be an API call
8259 capture = self.pg3.get_capture(1)
8260 # verify events in data set
8262 self.assertTrue(p.haslayer(IPFIX))
8263 self.assertEqual(p[IP].src, self.pg3.local_ip4)
8264 self.assertEqual(p[IP].dst, self.pg3.remote_ip4)
8265 self.assertEqual(p[UDP].sport, self.ipfix_src_port)
8266 self.assertEqual(p[UDP].dport, 4739)
8267 self.assertEqual(p[IPFIX].observationDomainID,
8268 self.ipfix_domain_id)
8269 if p.haslayer(Data):
8270 data = ipfix.decode_data_set(p.getlayer(Set))
8271 self.verify_ipfix_max_bibs(data, max_bibs)
8273 def test_ipfix_max_frags(self):
8274 """ IPFIX logging maximum fragments pending reassembly exceeded """
8275 self.vapi.nat64_add_del_pool_addr_range(self.nat_addr_n,
8277 self.vapi.nat64_add_del_interface(self.pg0.sw_if_index)
8278 self.vapi.nat64_add_del_interface(self.pg1.sw_if_index, is_inside=0)
8279 self.vapi.nat_set_reass(max_frag=1, is_ip6=1)
8280 self.vapi.set_ipfix_exporter(collector_address=self.pg3.remote_ip4n,
8281 src_address=self.pg3.local_ip4n,
8283 template_interval=10)
8284 self.vapi.nat_ipfix_enable_disable(domain_id=self.ipfix_domain_id,
8285 src_port=self.ipfix_src_port)
8288 pkts = self.create_stream_frag_ip6(self.pg0, self.pg1.remote_ip4,
8289 self.tcp_port_in, 20, data)
8291 self.pg0.add_stream(pkts)
8292 self.pg_enable_capture(self.pg_interfaces)
8294 self.pg1.assert_nothing_captured()
8296 self.vapi.cli("ipfix flush") # FIXME this should be an API call
8297 capture = self.pg3.get_capture(9)
8298 ipfix = IPFIXDecoder()
8299 # first load template
8301 self.assertTrue(p.haslayer(IPFIX))
8302 self.assertEqual(p[IP].src, self.pg3.local_ip4)
8303 self.assertEqual(p[IP].dst, self.pg3.remote_ip4)
8304 self.assertEqual(p[UDP].sport, self.ipfix_src_port)
8305 self.assertEqual(p[UDP].dport, 4739)
8306 self.assertEqual(p[IPFIX].observationDomainID,
8307 self.ipfix_domain_id)
8308 if p.haslayer(Template):
8309 ipfix.add_template(p.getlayer(Template))
8310 # verify events in data set
8312 if p.haslayer(Data):
8313 data = ipfix.decode_data_set(p.getlayer(Set))
8314 self.verify_ipfix_max_fragments_ip6(data, 1,
8315 self.pg0.remote_ip6n)
8317 def test_ipfix_bib_ses(self):
8318 """ IPFIX logging NAT64 BIB/session create and delete events """
8319 self.tcp_port_in = random.randint(1025, 65535)
8320 remote_host_ip6 = self.compose_ip6(self.pg1.remote_ip4,
8324 self.vapi.nat64_add_del_pool_addr_range(self.nat_addr_n,
8326 self.vapi.nat64_add_del_interface(self.pg0.sw_if_index)
8327 self.vapi.nat64_add_del_interface(self.pg1.sw_if_index, is_inside=0)
8328 self.vapi.set_ipfix_exporter(collector_address=self.pg3.remote_ip4n,
8329 src_address=self.pg3.local_ip4n,
8331 template_interval=10)
8332 self.vapi.nat_ipfix_enable_disable(domain_id=self.ipfix_domain_id,
8333 src_port=self.ipfix_src_port)
8336 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
8337 IPv6(src=self.pg0.remote_ip6, dst=remote_host_ip6) /
8338 TCP(sport=self.tcp_port_in, dport=25))
8339 self.pg0.add_stream(p)
8340 self.pg_enable_capture(self.pg_interfaces)
8342 p = self.pg1.get_capture(1)
8343 self.tcp_port_out = p[0][TCP].sport
8344 self.vapi.cli("ipfix flush") # FIXME this should be an API call
8345 capture = self.pg3.get_capture(10)
8346 ipfix = IPFIXDecoder()
8347 # first load template
8349 self.assertTrue(p.haslayer(IPFIX))
8350 self.assertEqual(p[IP].src, self.pg3.local_ip4)
8351 self.assertEqual(p[IP].dst, self.pg3.remote_ip4)
8352 self.assertEqual(p[UDP].sport, self.ipfix_src_port)
8353 self.assertEqual(p[UDP].dport, 4739)
8354 self.assertEqual(p[IPFIX].observationDomainID,
8355 self.ipfix_domain_id)
8356 if p.haslayer(Template):
8357 ipfix.add_template(p.getlayer(Template))
8358 # verify events in data set
8360 if p.haslayer(Data):
8361 data = ipfix.decode_data_set(p.getlayer(Set))
8362 if scapy.compat.orb(data[0][230]) == 10:
8363 self.verify_ipfix_bib(data, 1, self.pg0.remote_ip6n)
8364 elif scapy.compat.orb(data[0][230]) == 6:
8365 self.verify_ipfix_nat64_ses(data,
8367 self.pg0.remote_ip6n,
8368 self.pg1.remote_ip4,
8371 self.logger.error(ppp("Unexpected or invalid packet: ", p))
8374 self.pg_enable_capture(self.pg_interfaces)
8375 self.vapi.nat64_add_del_pool_addr_range(self.nat_addr_n,
8378 self.vapi.cli("ipfix flush") # FIXME this should be an API call
8379 capture = self.pg3.get_capture(2)
8380 # verify events in data set
8382 self.assertTrue(p.haslayer(IPFIX))
8383 self.assertEqual(p[IP].src, self.pg3.local_ip4)
8384 self.assertEqual(p[IP].dst, self.pg3.remote_ip4)
8385 self.assertEqual(p[UDP].sport, self.ipfix_src_port)
8386 self.assertEqual(p[UDP].dport, 4739)
8387 self.assertEqual(p[IPFIX].observationDomainID,
8388 self.ipfix_domain_id)
8389 if p.haslayer(Data):
8390 data = ipfix.decode_data_set(p.getlayer(Set))
8391 if scapy.compat.orb(data[0][230]) == 11:
8392 self.verify_ipfix_bib(data, 0, self.pg0.remote_ip6n)
8393 elif scapy.compat.orb(data[0][230]) == 7:
8394 self.verify_ipfix_nat64_ses(data,
8396 self.pg0.remote_ip6n,
8397 self.pg1.remote_ip4,
8400 self.logger.error(ppp("Unexpected or invalid packet: ", p))
8402 def test_syslog_sess(self):
8403 """ Test syslog session creation and deletion """
8404 self.tcp_port_in = random.randint(1025, 65535)
8405 remote_host_ip6 = self.compose_ip6(self.pg1.remote_ip4,
8409 self.vapi.nat64_add_del_pool_addr_range(self.nat_addr_n,
8411 self.vapi.nat64_add_del_interface(self.pg0.sw_if_index)
8412 self.vapi.nat64_add_del_interface(self.pg1.sw_if_index, is_inside=0)
8413 self.vapi.syslog_set_filter(SYSLOG_SEVERITY.INFO)
8414 self.vapi.syslog_set_sender(self.pg3.local_ip4n, self.pg3.remote_ip4n)
8416 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
8417 IPv6(src=self.pg0.remote_ip6, dst=remote_host_ip6) /
8418 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port))
8419 self.pg0.add_stream(p)
8420 self.pg_enable_capture(self.pg_interfaces)
8422 p = self.pg1.get_capture(1)
8423 self.tcp_port_out = p[0][TCP].sport
8424 capture = self.pg3.get_capture(1)
8425 self.verify_syslog_sess(capture[0][Raw].load, is_ip6=True)
8427 self.pg_enable_capture(self.pg_interfaces)
8429 self.vapi.nat64_add_del_pool_addr_range(self.nat_addr_n,
8432 capture = self.pg3.get_capture(1)
8433 self.verify_syslog_sess(capture[0][Raw].load, False, True)
8435 def nat64_get_ses_num(self):
8437 Return number of active NAT64 sessions.
8439 st = self.vapi.nat64_st_dump()
8442 def clear_nat64(self):
8444 Clear NAT64 configuration.
8446 self.vapi.nat_ipfix_enable_disable(enable=0,
8447 src_port=self.ipfix_src_port,
8448 domain_id=self.ipfix_domain_id)
8449 self.ipfix_src_port = 4739
8450 self.ipfix_domain_id = 1
8452 self.vapi.syslog_set_filter(SYSLOG_SEVERITY.EMERG)
8454 self.vapi.nat_set_timeouts()
8456 interfaces = self.vapi.nat64_interface_dump()
8457 for intf in interfaces:
8458 if intf.is_inside > 1:
8459 self.vapi.nat64_add_del_interface(intf.sw_if_index,
8462 self.vapi.nat64_add_del_interface(intf.sw_if_index,
8466 bib = self.vapi.nat64_bib_dump(255)
8469 self.vapi.nat64_add_del_static_bib(bibe.i_addr,
8477 adresses = self.vapi.nat64_pool_addr_dump()
8478 for addr in adresses:
8479 self.vapi.nat64_add_del_pool_addr_range(addr.address,
8484 prefixes = self.vapi.nat64_prefix_dump()
8485 for prefix in prefixes:
8486 self.vapi.nat64_add_del_prefix(prefix.prefix,
8488 vrf_id=prefix.vrf_id,
8491 bibs = self.statistics.get_counter('/nat64/total-bibs')
8492 self.assertEqual(bibs[0][0], 0)
8493 sessions = self.statistics.get_counter('/nat64/total-sessions')
8494 self.assertEqual(sessions[0][0], 0)
8497 super(TestNAT64, self).tearDown()
8498 if not self.vpp_dead:
8499 self.logger.info(self.vapi.cli("show nat64 pool"))
8500 self.logger.info(self.vapi.cli("show nat64 interfaces"))
8501 self.logger.info(self.vapi.cli("show nat64 prefix"))
8502 self.logger.info(self.vapi.cli("show nat64 bib all"))
8503 self.logger.info(self.vapi.cli("show nat64 session table all"))
8504 self.logger.info(self.vapi.cli("show nat virtual-reassembly"))
8508 class TestDSlite(MethodHolder):
8509 """ DS-Lite Test Cases """
8512 def setUpClass(cls):
8513 super(TestDSlite, cls).setUpClass()
8516 cls.nat_addr = '10.0.0.3'
8517 cls.nat_addr_n = socket.inet_pton(socket.AF_INET, cls.nat_addr)
8519 cls.create_pg_interfaces(range(3))
8521 cls.pg0.config_ip4()
8522 cls.pg0.resolve_arp()
8524 cls.pg1.config_ip6()
8525 cls.pg1.generate_remote_hosts(2)
8526 cls.pg1.configure_ipv6_neighbors()
8528 cls.pg2.config_ip4()
8529 cls.pg2.resolve_arp()
8532 super(TestDSlite, cls).tearDownClass()
8535 def verify_syslog_apmadd(self, data, isaddr, isport, xsaddr, xsport,
8537 message = data.decode('utf-8')
8539 message = SyslogMessage.parse(message)
8540 except ParseError as e:
8541 self.logger.error(e)
8543 self.assertEqual(message.severity, SyslogSeverity.info)
8544 self.assertEqual(message.appname, 'NAT')
8545 self.assertEqual(message.msgid, 'APMADD')
8546 sd_params = message.sd.get('napmap')
8547 self.assertTrue(sd_params is not None)
8548 self.assertEqual(sd_params.get('IATYP'), 'IPv4')
8549 self.assertEqual(sd_params.get('ISADDR'), isaddr)
8550 self.assertEqual(sd_params.get('ISPORT'), "%d" % isport)
8551 self.assertEqual(sd_params.get('XATYP'), 'IPv4')
8552 self.assertEqual(sd_params.get('XSADDR'), xsaddr)
8553 self.assertEqual(sd_params.get('XSPORT'), "%d" % xsport)
8554 self.assertEqual(sd_params.get('PROTO'), "%d" % proto)
8555 self.assertTrue(sd_params.get('SSUBIX') is not None)
8556 self.assertEqual(sd_params.get('SV6ENC'), sv6enc)
8558 def test_dslite(self):
8559 """ Test DS-Lite """
8560 nat_config = self.vapi.nat_show_config()
8561 self.assertEqual(0, nat_config.dslite_ce)
8563 self.vapi.dslite_add_del_pool_addr_range(self.nat_addr_n,
8565 aftr_ip4 = '192.0.0.1'
8566 aftr_ip4_n = socket.inet_pton(socket.AF_INET, aftr_ip4)
8567 aftr_ip6 = '2001:db8:85a3::8a2e:370:1'
8568 aftr_ip6_n = socket.inet_pton(socket.AF_INET6, aftr_ip6)
8569 self.vapi.dslite_set_aftr_addr(aftr_ip6_n, aftr_ip4_n)
8570 self.vapi.syslog_set_sender(self.pg2.local_ip4n, self.pg2.remote_ip4n)
8573 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
8574 IPv6(dst=aftr_ip6, src=self.pg1.remote_hosts[0].ip6) /
8575 IP(dst=self.pg0.remote_ip4, src='192.168.1.1') /
8576 UDP(sport=20000, dport=10000))
8577 self.pg1.add_stream(p)
8578 self.pg_enable_capture(self.pg_interfaces)
8580 capture = self.pg0.get_capture(1)
8581 capture = capture[0]
8582 self.assertFalse(capture.haslayer(IPv6))
8583 self.assertEqual(capture[IP].src, self.nat_addr)
8584 self.assertEqual(capture[IP].dst, self.pg0.remote_ip4)
8585 self.assertNotEqual(capture[UDP].sport, 20000)
8586 self.assertEqual(capture[UDP].dport, 10000)
8587 self.assert_packet_checksums_valid(capture)
8588 out_port = capture[UDP].sport
8589 capture = self.pg2.get_capture(1)
8590 self.verify_syslog_apmadd(capture[0][Raw].load, '192.168.1.1',
8591 20000, self.nat_addr, out_port,
8592 self.pg1.remote_hosts[0].ip6, IP_PROTOS.udp)
8594 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
8595 IP(dst=self.nat_addr, src=self.pg0.remote_ip4) /
8596 UDP(sport=10000, dport=out_port))
8597 self.pg0.add_stream(p)
8598 self.pg_enable_capture(self.pg_interfaces)
8600 capture = self.pg1.get_capture(1)
8601 capture = capture[0]
8602 self.assertEqual(capture[IPv6].src, aftr_ip6)
8603 self.assertEqual(capture[IPv6].dst, self.pg1.remote_hosts[0].ip6)
8604 self.assertEqual(capture[IP].src, self.pg0.remote_ip4)
8605 self.assertEqual(capture[IP].dst, '192.168.1.1')
8606 self.assertEqual(capture[UDP].sport, 10000)
8607 self.assertEqual(capture[UDP].dport, 20000)
8608 self.assert_packet_checksums_valid(capture)
8611 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
8612 IPv6(dst=aftr_ip6, src=self.pg1.remote_hosts[1].ip6) /
8613 IP(dst=self.pg0.remote_ip4, src='192.168.1.1') /
8614 TCP(sport=20001, dport=10001))
8615 self.pg1.add_stream(p)
8616 self.pg_enable_capture(self.pg_interfaces)
8618 capture = self.pg0.get_capture(1)
8619 capture = capture[0]
8620 self.assertFalse(capture.haslayer(IPv6))
8621 self.assertEqual(capture[IP].src, self.nat_addr)
8622 self.assertEqual(capture[IP].dst, self.pg0.remote_ip4)
8623 self.assertNotEqual(capture[TCP].sport, 20001)
8624 self.assertEqual(capture[TCP].dport, 10001)
8625 self.assert_packet_checksums_valid(capture)
8626 out_port = capture[TCP].sport
8628 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
8629 IP(dst=self.nat_addr, src=self.pg0.remote_ip4) /
8630 TCP(sport=10001, dport=out_port))
8631 self.pg0.add_stream(p)
8632 self.pg_enable_capture(self.pg_interfaces)
8634 capture = self.pg1.get_capture(1)
8635 capture = capture[0]
8636 self.assertEqual(capture[IPv6].src, aftr_ip6)
8637 self.assertEqual(capture[IPv6].dst, self.pg1.remote_hosts[1].ip6)
8638 self.assertEqual(capture[IP].src, self.pg0.remote_ip4)
8639 self.assertEqual(capture[IP].dst, '192.168.1.1')
8640 self.assertEqual(capture[TCP].sport, 10001)
8641 self.assertEqual(capture[TCP].dport, 20001)
8642 self.assert_packet_checksums_valid(capture)
8645 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
8646 IPv6(dst=aftr_ip6, src=self.pg1.remote_hosts[1].ip6) /
8647 IP(dst=self.pg0.remote_ip4, src='192.168.1.1') /
8648 ICMP(id=4000, type='echo-request'))
8649 self.pg1.add_stream(p)
8650 self.pg_enable_capture(self.pg_interfaces)
8652 capture = self.pg0.get_capture(1)
8653 capture = capture[0]
8654 self.assertFalse(capture.haslayer(IPv6))
8655 self.assertEqual(capture[IP].src, self.nat_addr)
8656 self.assertEqual(capture[IP].dst, self.pg0.remote_ip4)
8657 self.assertNotEqual(capture[ICMP].id, 4000)
8658 self.assert_packet_checksums_valid(capture)
8659 out_id = capture[ICMP].id
8661 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
8662 IP(dst=self.nat_addr, src=self.pg0.remote_ip4) /
8663 ICMP(id=out_id, type='echo-reply'))
8664 self.pg0.add_stream(p)
8665 self.pg_enable_capture(self.pg_interfaces)
8667 capture = self.pg1.get_capture(1)
8668 capture = capture[0]
8669 self.assertEqual(capture[IPv6].src, aftr_ip6)
8670 self.assertEqual(capture[IPv6].dst, self.pg1.remote_hosts[1].ip6)
8671 self.assertEqual(capture[IP].src, self.pg0.remote_ip4)
8672 self.assertEqual(capture[IP].dst, '192.168.1.1')
8673 self.assertEqual(capture[ICMP].id, 4000)
8674 self.assert_packet_checksums_valid(capture)
8676 # ping DS-Lite AFTR tunnel endpoint address
8677 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
8678 IPv6(src=self.pg1.remote_hosts[1].ip6, dst=aftr_ip6) /
8679 ICMPv6EchoRequest())
8680 self.pg1.add_stream(p)
8681 self.pg_enable_capture(self.pg_interfaces)
8683 capture = self.pg1.get_capture(1)
8684 capture = capture[0]
8685 self.assertEqual(capture[IPv6].src, aftr_ip6)
8686 self.assertEqual(capture[IPv6].dst, self.pg1.remote_hosts[1].ip6)
8687 self.assertTrue(capture.haslayer(ICMPv6EchoReply))
8689 b4s = self.statistics.get_counter('/dslite/total-b4s')
8690 self.assertEqual(b4s[0][0], 2)
8691 sessions = self.statistics.get_counter('/dslite/total-sessions')
8692 self.assertEqual(sessions[0][0], 3)
8695 super(TestDSlite, self).tearDown()
8696 if not self.vpp_dead:
8697 self.logger.info(self.vapi.cli("show dslite pool"))
8699 self.vapi.cli("show dslite aftr-tunnel-endpoint-address"))
8700 self.logger.info(self.vapi.cli("show dslite sessions"))
8703 class TestDSliteCE(MethodHolder):
8704 """ DS-Lite CE Test Cases """
8707 def setUpConstants(cls):
8708 super(TestDSliteCE, cls).setUpConstants()
8709 cls.vpp_cmdline.extend(["nat", "{", "dslite ce", "}"])
8712 def setUpClass(cls):
8713 super(TestDSliteCE, cls).setUpClass()
8716 cls.create_pg_interfaces(range(2))
8718 cls.pg0.config_ip4()
8719 cls.pg0.resolve_arp()
8721 cls.pg1.config_ip6()
8722 cls.pg1.generate_remote_hosts(1)
8723 cls.pg1.configure_ipv6_neighbors()
8726 super(TestDSliteCE, cls).tearDownClass()
8729 def test_dslite_ce(self):
8730 """ Test DS-Lite CE """
8732 nat_config = self.vapi.nat_show_config()
8733 self.assertEqual(1, nat_config.dslite_ce)
8735 b4_ip4 = '192.0.0.2'
8736 b4_ip4_n = socket.inet_pton(socket.AF_INET, b4_ip4)
8737 b4_ip6 = '2001:db8:62aa::375e:f4c1:1'
8738 b4_ip6_n = socket.inet_pton(socket.AF_INET6, b4_ip6)
8739 self.vapi.dslite_set_b4_addr(b4_ip6_n, b4_ip4_n)
8741 aftr_ip4 = '192.0.0.1'
8742 aftr_ip4_n = socket.inet_pton(socket.AF_INET, aftr_ip4)
8743 aftr_ip6 = '2001:db8:85a3::8a2e:370:1'
8744 aftr_ip6_n = socket.inet_pton(socket.AF_INET6, aftr_ip6)
8745 self.vapi.dslite_set_aftr_addr(aftr_ip6_n, aftr_ip4_n)
8747 self.vapi.ip_add_del_route(dst_address=aftr_ip6_n,
8748 dst_address_length=128,
8749 next_hop_address=self.pg1.remote_ip6n,
8750 next_hop_sw_if_index=self.pg1.sw_if_index,
8754 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
8755 IP(dst=self.pg1.remote_ip4, src=self.pg0.remote_ip4) /
8756 UDP(sport=10000, dport=20000))
8757 self.pg0.add_stream(p)
8758 self.pg_enable_capture(self.pg_interfaces)
8760 capture = self.pg1.get_capture(1)
8761 capture = capture[0]
8762 self.assertEqual(capture[IPv6].src, b4_ip6)
8763 self.assertEqual(capture[IPv6].dst, aftr_ip6)
8764 self.assertEqual(capture[IP].src, self.pg0.remote_ip4)
8765 self.assertEqual(capture[IP].dst, self.pg1.remote_ip4)
8766 self.assertEqual(capture[UDP].sport, 10000)
8767 self.assertEqual(capture[UDP].dport, 20000)
8768 self.assert_packet_checksums_valid(capture)
8771 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
8772 IPv6(dst=b4_ip6, src=aftr_ip6) /
8773 IP(dst=self.pg0.remote_ip4, src=self.pg1.remote_ip4) /
8774 UDP(sport=20000, dport=10000))
8775 self.pg1.add_stream(p)
8776 self.pg_enable_capture(self.pg_interfaces)
8778 capture = self.pg0.get_capture(1)
8779 capture = capture[0]
8780 self.assertFalse(capture.haslayer(IPv6))
8781 self.assertEqual(capture[IP].src, self.pg1.remote_ip4)
8782 self.assertEqual(capture[IP].dst, self.pg0.remote_ip4)
8783 self.assertEqual(capture[UDP].sport, 20000)
8784 self.assertEqual(capture[UDP].dport, 10000)
8785 self.assert_packet_checksums_valid(capture)
8787 # ping DS-Lite B4 tunnel endpoint address
8788 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
8789 IPv6(src=self.pg1.remote_hosts[0].ip6, dst=b4_ip6) /
8790 ICMPv6EchoRequest())
8791 self.pg1.add_stream(p)
8792 self.pg_enable_capture(self.pg_interfaces)
8794 capture = self.pg1.get_capture(1)
8795 capture = capture[0]
8796 self.assertEqual(capture[IPv6].src, b4_ip6)
8797 self.assertEqual(capture[IPv6].dst, self.pg1.remote_hosts[0].ip6)
8798 self.assertTrue(capture.haslayer(ICMPv6EchoReply))
8801 super(TestDSliteCE, self).tearDown()
8802 if not self.vpp_dead:
8804 self.vapi.cli("show dslite aftr-tunnel-endpoint-address"))
8806 self.vapi.cli("show dslite b4-tunnel-endpoint-address"))
8809 class TestNAT66(MethodHolder):
8810 """ NAT66 Test Cases """
8813 def setUpClass(cls):
8814 super(TestNAT66, cls).setUpClass()
8817 cls.nat_addr = 'fd01:ff::2'
8818 cls.nat_addr_n = socket.inet_pton(socket.AF_INET6, cls.nat_addr)
8820 cls.create_pg_interfaces(range(2))
8821 cls.interfaces = list(cls.pg_interfaces)
8823 for i in cls.interfaces:
8826 i.configure_ipv6_neighbors()
8829 super(TestNAT66, cls).tearDownClass()
8832 def test_static(self):
8833 """ 1:1 NAT66 test """
8834 self.vapi.nat66_add_del_interface(self.pg0.sw_if_index)
8835 self.vapi.nat66_add_del_interface(self.pg1.sw_if_index, is_inside=0)
8836 self.vapi.nat66_add_del_static_mapping(self.pg0.remote_ip6n,
8841 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
8842 IPv6(src=self.pg0.remote_ip6, dst=self.pg1.remote_ip6) /
8845 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
8846 IPv6(src=self.pg0.remote_ip6, dst=self.pg1.remote_ip6) /
8849 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
8850 IPv6(src=self.pg0.remote_ip6, dst=self.pg1.remote_ip6) /
8851 ICMPv6EchoRequest())
8853 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
8854 IPv6(src=self.pg0.remote_ip6, dst=self.pg1.remote_ip6) /
8855 GRE() / IP() / TCP())
8857 self.pg0.add_stream(pkts)
8858 self.pg_enable_capture(self.pg_interfaces)
8860 capture = self.pg1.get_capture(len(pkts))
8861 for packet in capture:
8863 self.assertEqual(packet[IPv6].src, self.nat_addr)
8864 self.assertEqual(packet[IPv6].dst, self.pg1.remote_ip6)
8865 self.assert_packet_checksums_valid(packet)
8867 self.logger.error(ppp("Unexpected or invalid packet:", packet))
8872 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
8873 IPv6(src=self.pg1.remote_ip6, dst=self.nat_addr) /
8876 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
8877 IPv6(src=self.pg1.remote_ip6, dst=self.nat_addr) /
8880 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
8881 IPv6(src=self.pg1.remote_ip6, dst=self.nat_addr) /
8884 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
8885 IPv6(src=self.pg1.remote_ip6, dst=self.nat_addr) /
8886 GRE() / IP() / TCP())
8888 self.pg1.add_stream(pkts)
8889 self.pg_enable_capture(self.pg_interfaces)
8891 capture = self.pg0.get_capture(len(pkts))
8892 for packet in capture:
8894 self.assertEqual(packet[IPv6].src, self.pg1.remote_ip6)
8895 self.assertEqual(packet[IPv6].dst, self.pg0.remote_ip6)
8896 self.assert_packet_checksums_valid(packet)
8898 self.logger.error(ppp("Unexpected or invalid packet:", packet))
8901 sm = self.vapi.nat66_static_mapping_dump()
8902 self.assertEqual(len(sm), 1)
8903 self.assertEqual(sm[0].total_pkts, 8)
8905 def test_check_no_translate(self):
8906 """ NAT66 translate only when egress interface is outside interface """
8907 self.vapi.nat66_add_del_interface(self.pg0.sw_if_index)
8908 self.vapi.nat66_add_del_interface(self.pg1.sw_if_index)
8909 self.vapi.nat66_add_del_static_mapping(self.pg0.remote_ip6n,
8913 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
8914 IPv6(src=self.pg0.remote_ip6, dst=self.pg1.remote_ip6) /
8916 self.pg0.add_stream([p])
8917 self.pg_enable_capture(self.pg_interfaces)
8919 capture = self.pg1.get_capture(1)
8922 self.assertEqual(packet[IPv6].src, self.pg0.remote_ip6)
8923 self.assertEqual(packet[IPv6].dst, self.pg1.remote_ip6)
8925 self.logger.error(ppp("Unexpected or invalid packet:", packet))
8928 def clear_nat66(self):
8930 Clear NAT66 configuration.
8932 interfaces = self.vapi.nat66_interface_dump()
8933 for intf in interfaces:
8934 self.vapi.nat66_add_del_interface(intf.sw_if_index,
8938 static_mappings = self.vapi.nat66_static_mapping_dump()
8939 for sm in static_mappings:
8940 self.vapi.nat66_add_del_static_mapping(sm.local_ip_address,
8941 sm.external_ip_address,
8946 super(TestNAT66, self).tearDown()
8947 if not self.vpp_dead:
8948 self.logger.info(self.vapi.cli("show nat66 interfaces"))
8949 self.logger.info(self.vapi.cli("show nat66 static mappings"))
8953 if __name__ == '__main__':
8954 unittest.main(testRunner=VppTestRunner)