12 from framework import VppTestCase, VppTestRunner, running_extended_tests
13 from ipfix import IPFIX, Set, Template, Data, IPFIXDecoder
14 from scapy.all import bind_layers, Packet, ByteEnumField, ShortField, \
15 IPField, IntField, LongField, XByteField, FlagsField, FieldLenField, \
17 from scapy.data import IP_PROTOS
18 from scapy.layers.inet import IP, TCP, UDP, ICMP
19 from scapy.layers.inet import IPerror, TCPerror, UDPerror, ICMPerror
20 from scapy.layers.inet6 import ICMPv6DestUnreach, IPerror6, IPv6ExtHdrFragment
21 from scapy.layers.inet6 import IPv6, ICMPv6EchoRequest, ICMPv6EchoReply, \
22 ICMPv6ND_NS, ICMPv6ND_NA, ICMPv6NDOptDstLLAddr, fragment6
23 from scapy.layers.l2 import Ether, ARP, GRE
24 from scapy.packet import Raw
25 from syslog_rfc5424_parser import SyslogMessage, ParseError
26 from syslog_rfc5424_parser.constants import SyslogSeverity
27 from util import ip4_range
28 from util import ppc, ppp
29 from vpp_acl import AclRule, VppAcl, VppAclInterface
30 from vpp_ip_route import VppIpRoute, VppRoutePath
31 from vpp_neighbor import VppNeighbor
32 from vpp_papi import VppEnum
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: "other", 1: "udp", 2: "tcp", 3: "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 """
75 def config_flags(self):
76 return VppEnum.vl_api_nat_config_flags_t
79 def SYSLOG_SEVERITY(self):
80 return VppEnum.vl_api_syslog_severity_t
82 def clear_nat44(self):
84 Clear NAT44 configuration.
86 if hasattr(self, 'pg7') and hasattr(self, 'pg8'):
87 if self.pg7.has_ip4_config:
88 self.pg7.unconfig_ip4()
90 self.vapi.nat44_forwarding_enable_disable(enable=0)
92 interfaces = self.vapi.nat44_interface_addr_dump()
93 for intf in interfaces:
94 self.vapi.nat44_add_del_interface_addr(
96 sw_if_index=intf.sw_if_index,
99 self.vapi.nat_ipfix_enable_disable(domain_id=self.ipfix_domain_id,
100 src_port=self.ipfix_src_port,
102 self.ipfix_src_port = 4739
103 self.ipfix_domain_id = 1
105 self.vapi.syslog_set_filter(
106 self.SYSLOG_SEVERITY.SYSLOG_API_SEVERITY_EMERG)
108 self.vapi.nat_ha_set_listener(ip_address='0.0.0.0', port=0,
110 self.vapi.nat_ha_set_failover(ip_address='0.0.0.0', port=0,
111 session_refresh_interval=10)
113 interfaces = self.vapi.nat44_interface_dump()
114 for intf in interfaces:
115 if intf.flags & self.config_flags.NAT_IS_INSIDE and \
116 intf.flags & self.config_flags.NAT_IS_OUTSIDE:
117 self.vapi.nat44_interface_add_del_feature(
118 sw_if_index=intf.sw_if_index)
119 self.vapi.nat44_interface_add_del_feature(
120 sw_if_index=intf.sw_if_index,
123 interfaces = self.vapi.nat44_interface_output_feature_dump()
124 for intf in interfaces:
125 self.vapi.nat44_interface_add_del_output_feature(
128 sw_if_index=intf.sw_if_index)
129 static_mappings = self.vapi.nat44_static_mapping_dump()
130 for sm in static_mappings:
131 self.vapi.nat44_add_del_static_mapping(
133 local_ip_address=sm.local_ip_address,
134 external_ip_address=sm.external_ip_address,
135 external_sw_if_index=sm.external_sw_if_index,
136 local_port=sm.local_port,
137 external_port=sm.external_port,
139 protocol=sm.protocol,
140 flags=sm.flags, tag=sm.tag)
142 lb_static_mappings = self.vapi.nat44_lb_static_mapping_dump()
143 for lb_sm in lb_static_mappings:
144 self.vapi.nat44_add_del_lb_static_mapping(
147 external_addr=lb_sm.external_addr,
148 external_port=lb_sm.external_port,
149 protocol=lb_sm.protocol,
150 local_num=0, locals=[],
153 identity_mappings = self.vapi.nat44_identity_mapping_dump()
154 for id_m in identity_mappings:
155 self.vapi.nat44_add_del_identity_mapping(
156 ip_address=id_m.ip_address,
157 sw_if_index=id_m.sw_if_index,
161 protocol=id_m.protocol)
163 addresses = self.vapi.nat44_address_dump()
164 for addr in addresses:
165 self.vapi.nat44_add_del_address_range(
166 first_ip_address=addr.ip_address,
167 last_ip_address=addr.ip_address,
168 vrf_id=0xFFFFFFFF, flags=addr.flags)
170 self.verify_no_nat44_user()
171 self.vapi.nat_set_timeouts(udp=300, tcp_established=7440,
172 tcp_transitory=240, icmp=60)
173 self.vapi.nat_set_addr_and_port_alloc_alg()
174 self.vapi.nat_set_mss_clamping(enable=0, mss_value=1500)
176 def nat44_add_static_mapping(self, local_ip, external_ip='0.0.0.0',
177 local_port=0, external_port=0, vrf_id=0,
178 is_add=1, external_sw_if_index=0xFFFFFFFF,
179 proto=0, tag="", flags=0):
181 Add/delete NAT44 static mapping
183 :param local_ip: Local IP address
184 :param external_ip: External IP address
185 :param local_port: Local port number (Optional)
186 :param external_port: External port number (Optional)
187 :param vrf_id: VRF ID (Default 0)
188 :param is_add: 1 if add, 0 if delete (Default add)
189 :param external_sw_if_index: External interface instead of IP address
190 :param proto: IP protocol (Mandatory if port specified)
191 :param tag: Opaque string tag
192 :param flags: NAT configuration flags
195 if not (local_port and external_port):
196 flags |= self.config_flags.NAT_IS_ADDR_ONLY
198 self.vapi.nat44_add_del_static_mapping(
200 local_ip_address=local_ip,
201 external_ip_address=external_ip,
202 external_sw_if_index=external_sw_if_index,
203 local_port=local_port,
204 external_port=external_port,
205 vrf_id=vrf_id, protocol=proto,
209 def nat44_add_address(self, ip, is_add=1, vrf_id=0xFFFFFFFF, twice_nat=0):
211 Add/delete NAT44 address
213 :param ip: IP address
214 :param is_add: 1 if add, 0 if delete (Default add)
215 :param twice_nat: twice NAT address for external hosts
217 flags = self.config_flags.NAT_IS_TWICE_NAT if twice_nat else 0
218 self.vapi.nat44_add_del_address_range(first_ip_address=ip,
224 def create_stream_in(self, in_if, out_if, dst_ip=None, ttl=64):
226 Create packet stream for inside network
228 :param in_if: Inside interface
229 :param out_if: Outside interface
230 :param dst_ip: Destination address
231 :param ttl: TTL of generated packets
234 dst_ip = out_if.remote_ip4
238 p = (Ether(dst=in_if.local_mac, src=in_if.remote_mac) /
239 IP(src=in_if.remote_ip4, dst=dst_ip, ttl=ttl) /
240 TCP(sport=self.tcp_port_in, dport=20))
244 p = (Ether(dst=in_if.local_mac, src=in_if.remote_mac) /
245 IP(src=in_if.remote_ip4, dst=dst_ip, ttl=ttl) /
246 UDP(sport=self.udp_port_in, dport=20))
250 p = (Ether(dst=in_if.local_mac, src=in_if.remote_mac) /
251 IP(src=in_if.remote_ip4, dst=dst_ip, ttl=ttl) /
252 ICMP(id=self.icmp_id_in, type='echo-request'))
257 def compose_ip6(self, ip4, pref, plen):
259 Compose IPv4-embedded IPv6 addresses
261 :param ip4: IPv4 address
262 :param pref: IPv6 prefix
263 :param plen: IPv6 prefix length
264 :returns: IPv4-embedded IPv6 addresses
266 pref_n = list(socket.inet_pton(socket.AF_INET6, pref))
267 ip4_n = list(socket.inet_pton(socket.AF_INET, ip4))
282 pref_n[10] = ip4_n[3]
286 pref_n[10] = ip4_n[2]
287 pref_n[11] = ip4_n[3]
290 pref_n[10] = ip4_n[1]
291 pref_n[11] = ip4_n[2]
292 pref_n[12] = ip4_n[3]
294 pref_n[12] = ip4_n[0]
295 pref_n[13] = ip4_n[1]
296 pref_n[14] = ip4_n[2]
297 pref_n[15] = ip4_n[3]
298 packed_pref_n = b''.join([scapy.compat.chb(x) for x in pref_n])
299 return socket.inet_ntop(socket.AF_INET6, packed_pref_n)
301 def extract_ip4(self, ip6, plen):
303 Extract IPv4 address embedded in IPv6 addresses
305 :param ip6: IPv6 address
306 :param plen: IPv6 prefix length
307 :returns: extracted IPv4 address
309 ip6_n = list(socket.inet_pton(socket.AF_INET6, ip6))
341 return socket.inet_ntop(socket.AF_INET, ''.join(ip4_n))
343 def create_stream_out(self, out_if, dst_ip=None, ttl=64,
344 use_inside_ports=False):
346 Create packet stream for outside network
348 :param out_if: Outside interface
349 :param dst_ip: Destination IP address (Default use global NAT address)
350 :param ttl: TTL of generated packets
351 :param use_inside_ports: Use inside NAT ports as destination ports
352 instead of outside ports
355 dst_ip = self.nat_addr
356 if not use_inside_ports:
357 tcp_port = self.tcp_port_out
358 udp_port = self.udp_port_out
359 icmp_id = self.icmp_id_out
361 tcp_port = self.tcp_port_in
362 udp_port = self.udp_port_in
363 icmp_id = self.icmp_id_in
366 p = (Ether(dst=out_if.local_mac, src=out_if.remote_mac) /
367 IP(src=out_if.remote_ip4, dst=dst_ip, ttl=ttl) /
368 TCP(dport=tcp_port, sport=20))
372 p = (Ether(dst=out_if.local_mac, src=out_if.remote_mac) /
373 IP(src=out_if.remote_ip4, dst=dst_ip, ttl=ttl) /
374 UDP(dport=udp_port, sport=20))
378 p = (Ether(dst=out_if.local_mac, src=out_if.remote_mac) /
379 IP(src=out_if.remote_ip4, dst=dst_ip, ttl=ttl) /
380 ICMP(id=icmp_id, type='echo-reply'))
385 def create_stream_out_ip6(self, out_if, src_ip, dst_ip, hl=64):
387 Create packet stream for outside network
389 :param out_if: Outside interface
390 :param dst_ip: Destination IP address (Default use global NAT address)
391 :param hl: HL of generated packets
395 p = (Ether(dst=out_if.local_mac, src=out_if.remote_mac) /
396 IPv6(src=src_ip, dst=dst_ip, hlim=hl) /
397 TCP(dport=self.tcp_port_out, sport=20))
401 p = (Ether(dst=out_if.local_mac, src=out_if.remote_mac) /
402 IPv6(src=src_ip, dst=dst_ip, hlim=hl) /
403 UDP(dport=self.udp_port_out, sport=20))
407 p = (Ether(dst=out_if.local_mac, src=out_if.remote_mac) /
408 IPv6(src=src_ip, dst=dst_ip, hlim=hl) /
409 ICMPv6EchoReply(id=self.icmp_id_out))
414 def verify_capture_out(self, capture, nat_ip=None, same_port=False,
415 dst_ip=None, is_ip6=False, ignore_port=False):
417 Verify captured packets on outside network
419 :param capture: Captured packets
420 :param nat_ip: Translated IP address (Default use global NAT address)
421 :param same_port: Source port number is not translated (Default False)
422 :param dst_ip: Destination IP address (Default do not verify)
423 :param is_ip6: If L3 protocol is IPv6 (Default False)
427 ICMP46 = ICMPv6EchoRequest
432 nat_ip = self.nat_addr
433 for packet in capture:
436 self.assert_packet_checksums_valid(packet)
437 self.assertEqual(packet[IP46].src, nat_ip)
438 if dst_ip is not None:
439 self.assertEqual(packet[IP46].dst, dst_ip)
440 if packet.haslayer(TCP):
444 packet[TCP].sport, self.tcp_port_in)
447 packet[TCP].sport, self.tcp_port_in)
448 self.tcp_port_out = packet[TCP].sport
449 self.assert_packet_checksums_valid(packet)
450 elif packet.haslayer(UDP):
454 packet[UDP].sport, self.udp_port_in)
457 packet[UDP].sport, self.udp_port_in)
458 self.udp_port_out = packet[UDP].sport
463 packet[ICMP46].id, self.icmp_id_in)
466 packet[ICMP46].id, self.icmp_id_in)
467 self.icmp_id_out = packet[ICMP46].id
468 self.assert_packet_checksums_valid(packet)
470 self.logger.error(ppp("Unexpected or invalid packet "
471 "(outside network):", packet))
474 def verify_capture_out_ip6(self, capture, nat_ip, same_port=False,
477 Verify captured packets on outside network
479 :param capture: Captured packets
480 :param nat_ip: Translated IP address
481 :param same_port: Source port number is not translated (Default False)
482 :param dst_ip: Destination IP address (Default do not verify)
484 return self.verify_capture_out(capture, nat_ip, same_port, dst_ip,
487 def verify_capture_in(self, capture, in_if):
489 Verify captured packets on inside network
491 :param capture: Captured packets
492 :param in_if: Inside interface
494 for packet in capture:
496 self.assert_packet_checksums_valid(packet)
497 self.assertEqual(packet[IP].dst, in_if.remote_ip4)
498 if packet.haslayer(TCP):
499 self.assertEqual(packet[TCP].dport, self.tcp_port_in)
500 elif packet.haslayer(UDP):
501 self.assertEqual(packet[UDP].dport, self.udp_port_in)
503 self.assertEqual(packet[ICMP].id, self.icmp_id_in)
505 self.logger.error(ppp("Unexpected or invalid packet "
506 "(inside network):", packet))
509 def verify_capture_in_ip6(self, capture, src_ip, dst_ip):
511 Verify captured IPv6 packets on inside network
513 :param capture: Captured packets
514 :param src_ip: Source IP
515 :param dst_ip: Destination IP address
517 for packet in capture:
519 self.assertEqual(packet[IPv6].src, src_ip)
520 self.assertEqual(packet[IPv6].dst, dst_ip)
521 self.assert_packet_checksums_valid(packet)
522 if packet.haslayer(TCP):
523 self.assertEqual(packet[TCP].dport, self.tcp_port_in)
524 elif packet.haslayer(UDP):
525 self.assertEqual(packet[UDP].dport, self.udp_port_in)
527 self.assertEqual(packet[ICMPv6EchoReply].id,
530 self.logger.error(ppp("Unexpected or invalid packet "
531 "(inside network):", packet))
534 def verify_capture_no_translation(self, capture, ingress_if, egress_if):
536 Verify captured packet that don't have to be translated
538 :param capture: Captured packets
539 :param ingress_if: Ingress interface
540 :param egress_if: Egress interface
542 for packet in capture:
544 self.assertEqual(packet[IP].src, ingress_if.remote_ip4)
545 self.assertEqual(packet[IP].dst, egress_if.remote_ip4)
546 if packet.haslayer(TCP):
547 self.assertEqual(packet[TCP].sport, self.tcp_port_in)
548 elif packet.haslayer(UDP):
549 self.assertEqual(packet[UDP].sport, self.udp_port_in)
551 self.assertEqual(packet[ICMP].id, self.icmp_id_in)
553 self.logger.error(ppp("Unexpected or invalid packet "
554 "(inside network):", packet))
557 def verify_capture_out_with_icmp_errors(self, capture, src_ip=None,
560 Verify captured packets with ICMP errors on outside network
562 :param capture: Captured packets
563 :param src_ip: Translated IP address or IP address of VPP
564 (Default use global NAT address)
565 :param icmp_type: Type of error ICMP packet
566 we are expecting (Default 11)
569 src_ip = self.nat_addr
570 for packet in capture:
572 self.assertEqual(packet[IP].src, src_ip)
573 self.assertEqual(packet.haslayer(ICMP), 1)
575 self.assertEqual(icmp.type, icmp_type)
576 self.assertTrue(icmp.haslayer(IPerror))
577 inner_ip = icmp[IPerror]
578 if inner_ip.haslayer(TCPerror):
579 self.assertEqual(inner_ip[TCPerror].dport,
581 elif inner_ip.haslayer(UDPerror):
582 self.assertEqual(inner_ip[UDPerror].dport,
585 self.assertEqual(inner_ip[ICMPerror].id, self.icmp_id_out)
587 self.logger.error(ppp("Unexpected or invalid packet "
588 "(outside network):", packet))
591 def verify_capture_in_with_icmp_errors(self, capture, in_if, icmp_type=11):
593 Verify captured packets with ICMP errors on inside network
595 :param capture: Captured packets
596 :param in_if: Inside interface
597 :param icmp_type: Type of error ICMP packet
598 we are expecting (Default 11)
600 for packet in capture:
602 self.assertEqual(packet[IP].dst, in_if.remote_ip4)
603 self.assertEqual(packet.haslayer(ICMP), 1)
605 self.assertEqual(icmp.type, icmp_type)
606 self.assertTrue(icmp.haslayer(IPerror))
607 inner_ip = icmp[IPerror]
608 if inner_ip.haslayer(TCPerror):
609 self.assertEqual(inner_ip[TCPerror].sport,
611 elif inner_ip.haslayer(UDPerror):
612 self.assertEqual(inner_ip[UDPerror].sport,
615 self.assertEqual(inner_ip[ICMPerror].id, self.icmp_id_in)
617 self.logger.error(ppp("Unexpected or invalid packet "
618 "(inside network):", packet))
621 def create_stream_frag(self, src_if, dst, sport, dport, data,
622 proto=IP_PROTOS.tcp, echo_reply=False):
624 Create fragmented packet stream
626 :param src_if: Source interface
627 :param dst: Destination IPv4 address
628 :param sport: Source port
629 :param dport: Destination port
630 :param data: Payload data
631 :param proto: protocol (TCP, UDP, ICMP)
632 :param echo_reply: use echo_reply if protocol is ICMP
635 if proto == IP_PROTOS.tcp:
636 p = (IP(src=src_if.remote_ip4, dst=dst) /
637 TCP(sport=sport, dport=dport) /
639 p = p.__class__(scapy.compat.raw(p))
640 chksum = p[TCP].chksum
641 proto_header = TCP(sport=sport, dport=dport, chksum=chksum)
642 elif proto == IP_PROTOS.udp:
643 proto_header = UDP(sport=sport, dport=dport)
644 elif proto == IP_PROTOS.icmp:
646 proto_header = ICMP(id=sport, type='echo-request')
648 proto_header = ICMP(id=sport, type='echo-reply')
650 raise Exception("Unsupported protocol")
651 id = random.randint(0, 65535)
653 if proto == IP_PROTOS.tcp:
656 raw = Raw(data[0:16])
657 p = (Ether(src=src_if.remote_mac, dst=src_if.local_mac) /
658 IP(src=src_if.remote_ip4, dst=dst, flags="MF", frag=0, id=id) /
662 if proto == IP_PROTOS.tcp:
663 raw = Raw(data[4:20])
665 raw = Raw(data[16:32])
666 p = (Ether(src=src_if.remote_mac, dst=src_if.local_mac) /
667 IP(src=src_if.remote_ip4, dst=dst, flags="MF", frag=3, id=id,
671 if proto == IP_PROTOS.tcp:
675 p = (Ether(src=src_if.remote_mac, dst=src_if.local_mac) /
676 IP(src=src_if.remote_ip4, dst=dst, frag=5, proto=proto,
682 def reass_frags_and_verify(self, frags, src, dst):
684 Reassemble and verify fragmented packet
686 :param frags: Captured fragments
687 :param src: Source IPv4 address to verify
688 :param dst: Destination IPv4 address to verify
690 :returns: Reassembled IPv4 packet
694 self.assertEqual(p[IP].src, src)
695 self.assertEqual(p[IP].dst, dst)
696 self.assert_ip_checksum_valid(p)
697 buffer.seek(p[IP].frag * 8)
698 buffer.write(bytes(p[IP].payload))
699 ip = IP(src=frags[0][IP].src, dst=frags[0][IP].dst,
700 proto=frags[0][IP].proto)
701 if ip.proto == IP_PROTOS.tcp:
702 p = (ip / TCP(buffer.getvalue()))
703 self.logger.debug(ppp("Reassembled:", p))
704 self.assert_tcp_checksum_valid(p)
705 elif ip.proto == IP_PROTOS.udp:
706 p = (ip / UDP(buffer.getvalue()[:8]) /
707 Raw(buffer.getvalue()[8:]))
708 elif ip.proto == IP_PROTOS.icmp:
709 p = (ip / ICMP(buffer.getvalue()))
712 def reass_frags_and_verify_ip6(self, frags, src, dst):
714 Reassemble and verify fragmented packet
716 :param frags: Captured fragments
717 :param src: Source IPv6 address to verify
718 :param dst: Destination IPv6 address to verify
720 :returns: Reassembled IPv6 packet
724 self.assertEqual(p[IPv6].src, src)
725 self.assertEqual(p[IPv6].dst, dst)
726 buffer.seek(p[IPv6ExtHdrFragment].offset * 8)
727 buffer.write(bytes(p[IPv6ExtHdrFragment].payload))
728 ip = IPv6(src=frags[0][IPv6].src, dst=frags[0][IPv6].dst,
729 nh=frags[0][IPv6ExtHdrFragment].nh)
730 if ip.nh == IP_PROTOS.tcp:
731 p = (ip / TCP(buffer.getvalue()))
732 elif ip.nh == IP_PROTOS.udp:
733 p = (ip / UDP(buffer.getvalue()))
734 self.logger.debug(ppp("Reassembled:", p))
735 self.assert_packet_checksums_valid(p)
738 def initiate_tcp_session(self, in_if, out_if):
740 Initiates TCP session
742 :param in_if: Inside interface
743 :param out_if: Outside interface
747 p = (Ether(src=in_if.remote_mac, dst=in_if.local_mac) /
748 IP(src=in_if.remote_ip4, dst=out_if.remote_ip4) /
749 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
752 self.pg_enable_capture(self.pg_interfaces)
754 capture = out_if.get_capture(1)
756 self.tcp_port_out = p[TCP].sport
758 # SYN + ACK packet out->in
759 p = (Ether(src=out_if.remote_mac, dst=out_if.local_mac) /
760 IP(src=out_if.remote_ip4, dst=self.nat_addr) /
761 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
764 self.pg_enable_capture(self.pg_interfaces)
769 p = (Ether(src=in_if.remote_mac, dst=in_if.local_mac) /
770 IP(src=in_if.remote_ip4, dst=out_if.remote_ip4) /
771 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
774 self.pg_enable_capture(self.pg_interfaces)
776 out_if.get_capture(1)
779 self.logger.error("TCP 3 way handshake failed")
782 def verify_ipfix_nat44_ses(self, data):
784 Verify IPFIX NAT44 session create/delete event
786 :param data: Decoded IPFIX data records
788 nat44_ses_create_num = 0
789 nat44_ses_delete_num = 0
790 self.assertEqual(6, len(data))
793 self.assertIn(scapy.compat.orb(record[230]), [4, 5])
794 if scapy.compat.orb(record[230]) == 4:
795 nat44_ses_create_num += 1
797 nat44_ses_delete_num += 1
799 self.assertEqual(self.pg0.remote_ip4,
800 str(ipaddress.IPv4Address(record[8])))
801 # postNATSourceIPv4Address
802 self.assertEqual(socket.inet_pton(socket.AF_INET, self.nat_addr),
805 self.assertEqual(struct.pack("!I", 0), record[234])
806 # protocolIdentifier/sourceTransportPort
807 # /postNAPTSourceTransportPort
808 if IP_PROTOS.icmp == scapy.compat.orb(record[4]):
809 self.assertEqual(struct.pack("!H", self.icmp_id_in), record[7])
810 self.assertEqual(struct.pack("!H", self.icmp_id_out),
812 elif IP_PROTOS.tcp == scapy.compat.orb(record[4]):
813 self.assertEqual(struct.pack("!H", self.tcp_port_in),
815 self.assertEqual(struct.pack("!H", self.tcp_port_out),
817 elif IP_PROTOS.udp == scapy.compat.orb(record[4]):
818 self.assertEqual(struct.pack("!H", self.udp_port_in),
820 self.assertEqual(struct.pack("!H", self.udp_port_out),
823 self.fail("Invalid protocol")
824 self.assertEqual(3, nat44_ses_create_num)
825 self.assertEqual(3, nat44_ses_delete_num)
827 def verify_ipfix_addr_exhausted(self, data):
829 Verify IPFIX NAT addresses event
831 :param data: Decoded IPFIX data records
833 self.assertEqual(1, len(data))
836 self.assertEqual(scapy.compat.orb(record[230]), 3)
838 self.assertEqual(struct.pack("!I", 0), record[283])
840 def verify_ipfix_max_sessions(self, data, limit):
842 Verify IPFIX maximum session entries exceeded event
844 :param data: Decoded IPFIX data records
845 :param limit: Number of maximum session entries that can be created.
847 self.assertEqual(1, len(data))
850 self.assertEqual(scapy.compat.orb(record[230]), 13)
851 # natQuotaExceededEvent
852 self.assertEqual(struct.pack("I", 1), record[466])
854 self.assertEqual(struct.pack("I", limit), record[471])
856 def verify_ipfix_max_bibs(self, data, limit):
858 Verify IPFIX maximum BIB entries exceeded event
860 :param data: Decoded IPFIX data records
861 :param limit: Number of maximum BIB entries that can be created.
863 self.assertEqual(1, len(data))
866 self.assertEqual(scapy.compat.orb(record[230]), 13)
867 # natQuotaExceededEvent
868 self.assertEqual(struct.pack("I", 2), record[466])
870 self.assertEqual(struct.pack("I", limit), record[472])
872 def verify_no_nat44_user(self):
873 """ Verify that there is no NAT44 user """
874 users = self.vapi.nat44_user_dump()
875 self.assertEqual(len(users), 0)
876 users = self.statistics.get_counter('/nat44/total-users')
877 self.assertEqual(users[0][0], 0)
878 sessions = self.statistics.get_counter('/nat44/total-sessions')
879 self.assertEqual(sessions[0][0], 0)
881 def verify_ipfix_max_entries_per_user(self, data, limit, src_addr):
883 Verify IPFIX maximum entries per user exceeded event
885 :param data: Decoded IPFIX data records
886 :param limit: Number of maximum entries per user
887 :param src_addr: IPv4 source address
889 self.assertEqual(1, len(data))
892 self.assertEqual(scapy.compat.orb(record[230]), 13)
893 # natQuotaExceededEvent
894 self.assertEqual(struct.pack("I", 3), record[466])
896 self.assertEqual(struct.pack("I", limit), record[473])
898 self.assertEqual(socket.inet_pton(socket.AF_INET, src_addr), record[8])
900 def verify_syslog_apmap(self, data, is_add=True):
901 message = data.decode('utf-8')
903 message = SyslogMessage.parse(message)
904 except ParseError as e:
908 self.assertEqual(message.severity, SyslogSeverity.info)
909 self.assertEqual(message.appname, 'NAT')
910 self.assertEqual(message.msgid, 'APMADD' if is_add else 'APMDEL')
911 sd_params = message.sd.get('napmap')
912 self.assertTrue(sd_params is not None)
913 self.assertEqual(sd_params.get('IATYP'), 'IPv4')
914 self.assertEqual(sd_params.get('ISADDR'), self.pg0.remote_ip4)
915 self.assertEqual(sd_params.get('ISPORT'), "%d" % self.tcp_port_in)
916 self.assertEqual(sd_params.get('XATYP'), 'IPv4')
917 self.assertEqual(sd_params.get('XSADDR'), self.nat_addr)
918 self.assertEqual(sd_params.get('XSPORT'), "%d" % self.tcp_port_out)
919 self.assertEqual(sd_params.get('PROTO'), "%d" % IP_PROTOS.tcp)
920 self.assertTrue(sd_params.get('SSUBIX') is not None)
921 self.assertEqual(sd_params.get('SVLAN'), '0')
923 def verify_syslog_sess(self, data, is_add=True, is_ip6=False):
924 message = data.decode('utf-8')
926 message = SyslogMessage.parse(message)
927 except ParseError as e:
931 self.assertEqual(message.severity, SyslogSeverity.info)
932 self.assertEqual(message.appname, 'NAT')
933 self.assertEqual(message.msgid, 'SADD' if is_add else 'SDEL')
934 sd_params = message.sd.get('nsess')
935 self.assertTrue(sd_params is not None)
937 self.assertEqual(sd_params.get('IATYP'), 'IPv6')
938 self.assertEqual(sd_params.get('ISADDR'), self.pg0.remote_ip6)
940 self.assertEqual(sd_params.get('IATYP'), 'IPv4')
941 self.assertEqual(sd_params.get('ISADDR'), self.pg0.remote_ip4)
942 self.assertTrue(sd_params.get('SSUBIX') is not None)
943 self.assertEqual(sd_params.get('ISPORT'), "%d" % self.tcp_port_in)
944 self.assertEqual(sd_params.get('XATYP'), 'IPv4')
945 self.assertEqual(sd_params.get('XSADDR'), self.nat_addr)
946 self.assertEqual(sd_params.get('XSPORT'), "%d" % self.tcp_port_out)
947 self.assertEqual(sd_params.get('PROTO'), "%d" % IP_PROTOS.tcp)
948 self.assertEqual(sd_params.get('SVLAN'), '0')
949 self.assertEqual(sd_params.get('XDADDR'), self.pg1.remote_ip4)
950 self.assertEqual(sd_params.get('XDPORT'),
951 "%d" % self.tcp_external_port)
953 def verify_mss_value(self, pkt, mss):
960 if not pkt.haslayer(IP) or not pkt.haslayer(TCP):
961 raise TypeError("Not a TCP/IP packet")
963 for option in pkt[TCP].options:
964 if option[0] == 'MSS':
965 self.assertEqual(option[1], mss)
966 self.assert_tcp_checksum_valid(pkt)
969 def proto2layer(proto):
970 if proto == IP_PROTOS.tcp:
972 elif proto == IP_PROTOS.udp:
974 elif proto == IP_PROTOS.icmp:
977 raise Exception("Unsupported protocol")
979 def frag_in_order(self, proto=IP_PROTOS.tcp, dont_translate=False,
981 layer = self.proto2layer(proto)
983 if proto == IP_PROTOS.tcp:
984 data = b"A" * 4 + b"B" * 16 + b"C" * 3
986 data = b"A" * 16 + b"B" * 16 + b"C" * 3
987 self.port_in = random.randint(1025, 65535)
990 pkts = self.create_stream_frag(self.pg0, self.pg1.remote_ip4,
991 self.port_in, 20, data, proto)
992 self.pg0.add_stream(pkts)
993 self.pg_enable_capture(self.pg_interfaces)
995 frags = self.pg1.get_capture(len(pkts))
996 if not dont_translate:
997 p = self.reass_frags_and_verify(frags,
1001 p = self.reass_frags_and_verify(frags,
1002 self.pg0.remote_ip4,
1003 self.pg1.remote_ip4)
1004 if proto != IP_PROTOS.icmp:
1005 if not dont_translate:
1006 self.assertEqual(p[layer].dport, 20)
1008 self.assertNotEqual(p[layer].sport, self.port_in)
1010 self.assertEqual(p[layer].sport, self.port_in)
1013 if not dont_translate:
1014 self.assertNotEqual(p[layer].id, self.port_in)
1016 self.assertEqual(p[layer].id, self.port_in)
1017 self.assertEqual(data, p[Raw].load)
1020 if not dont_translate:
1021 dst_addr = self.nat_addr
1023 dst_addr = self.pg0.remote_ip4
1024 if proto != IP_PROTOS.icmp:
1026 dport = p[layer].sport
1030 pkts = self.create_stream_frag(self.pg1, dst_addr, sport, dport, data,
1031 proto, echo_reply=True)
1032 self.pg1.add_stream(pkts)
1033 self.pg_enable_capture(self.pg_interfaces)
1035 frags = self.pg0.get_capture(len(pkts))
1036 p = self.reass_frags_and_verify(frags,
1037 self.pg1.remote_ip4,
1038 self.pg0.remote_ip4)
1039 if proto != IP_PROTOS.icmp:
1040 self.assertEqual(p[layer].sport, 20)
1041 self.assertEqual(p[layer].dport, self.port_in)
1043 self.assertEqual(p[layer].id, self.port_in)
1044 self.assertEqual(data, p[Raw].load)
1046 def frag_in_order_in_plus_out(self, proto=IP_PROTOS.tcp):
1047 layer = self.proto2layer(proto)
1049 if proto == IP_PROTOS.tcp:
1050 data = b"A" * 4 + b"B" * 16 + b"C" * 3
1052 data = b"A" * 16 + b"B" * 16 + b"C" * 3
1053 self.port_in = random.randint(1025, 65535)
1057 pkts = self.create_stream_frag(self.pg0, self.server_out_addr,
1058 self.port_in, self.server_out_port,
1060 self.pg0.add_stream(pkts)
1061 self.pg_enable_capture(self.pg_interfaces)
1063 frags = self.pg1.get_capture(len(pkts))
1064 p = self.reass_frags_and_verify(frags,
1065 self.pg0.remote_ip4,
1066 self.server_in_addr)
1067 if proto != IP_PROTOS.icmp:
1068 self.assertEqual(p[layer].sport, self.port_in)
1069 self.assertEqual(p[layer].dport, self.server_in_port)
1071 self.assertEqual(p[layer].id, self.port_in)
1072 self.assertEqual(data, p[Raw].load)
1075 if proto != IP_PROTOS.icmp:
1076 pkts = self.create_stream_frag(self.pg1, self.pg0.remote_ip4,
1077 self.server_in_port,
1078 p[layer].sport, data, proto)
1080 pkts = self.create_stream_frag(self.pg1, self.pg0.remote_ip4,
1081 p[layer].id, 0, data, proto,
1083 self.pg1.add_stream(pkts)
1084 self.pg_enable_capture(self.pg_interfaces)
1086 frags = self.pg0.get_capture(len(pkts))
1087 p = self.reass_frags_and_verify(frags,
1088 self.server_out_addr,
1089 self.pg0.remote_ip4)
1090 if proto != IP_PROTOS.icmp:
1091 self.assertEqual(p[layer].sport, self.server_out_port)
1092 self.assertEqual(p[layer].dport, self.port_in)
1094 self.assertEqual(p[layer].id, self.port_in)
1095 self.assertEqual(data, p[Raw].load)
1097 def reass_hairpinning(self, proto=IP_PROTOS.tcp, ignore_port=False):
1098 layer = self.proto2layer(proto)
1100 if proto == IP_PROTOS.tcp:
1101 data = b"A" * 4 + b"B" * 16 + b"C" * 3
1103 data = b"A" * 16 + b"B" * 16 + b"C" * 3
1105 # send packet from host to server
1106 pkts = self.create_stream_frag(self.pg0,
1109 self.server_out_port,
1112 self.pg0.add_stream(pkts)
1113 self.pg_enable_capture(self.pg_interfaces)
1115 frags = self.pg0.get_capture(len(pkts))
1116 p = self.reass_frags_and_verify(frags,
1119 if proto != IP_PROTOS.icmp:
1121 self.assertNotEqual(p[layer].sport, self.host_in_port)
1122 self.assertEqual(p[layer].dport, self.server_in_port)
1125 self.assertNotEqual(p[layer].id, self.host_in_port)
1126 self.assertEqual(data, p[Raw].load)
1128 def frag_out_of_order(self, proto=IP_PROTOS.tcp, dont_translate=False,
1130 layer = self.proto2layer(proto)
1132 if proto == IP_PROTOS.tcp:
1133 data = b"A" * 4 + b"B" * 16 + b"C" * 3
1135 data = b"A" * 16 + b"B" * 16 + b"C" * 3
1136 self.port_in = random.randint(1025, 65535)
1140 pkts = self.create_stream_frag(self.pg0, self.pg1.remote_ip4,
1141 self.port_in, 20, data, proto)
1143 self.pg0.add_stream(pkts)
1144 self.pg_enable_capture(self.pg_interfaces)
1146 frags = self.pg1.get_capture(len(pkts))
1147 if not dont_translate:
1148 p = self.reass_frags_and_verify(frags,
1150 self.pg1.remote_ip4)
1152 p = self.reass_frags_and_verify(frags,
1153 self.pg0.remote_ip4,
1154 self.pg1.remote_ip4)
1155 if proto != IP_PROTOS.icmp:
1156 if not dont_translate:
1157 self.assertEqual(p[layer].dport, 20)
1159 self.assertNotEqual(p[layer].sport, self.port_in)
1161 self.assertEqual(p[layer].sport, self.port_in)
1164 if not dont_translate:
1165 self.assertNotEqual(p[layer].id, self.port_in)
1167 self.assertEqual(p[layer].id, self.port_in)
1168 self.assertEqual(data, p[Raw].load)
1171 if not dont_translate:
1172 dst_addr = self.nat_addr
1174 dst_addr = self.pg0.remote_ip4
1175 if proto != IP_PROTOS.icmp:
1177 dport = p[layer].sport
1181 pkts = self.create_stream_frag(self.pg1, dst_addr, sport, dport,
1182 data, proto, echo_reply=True)
1184 self.pg1.add_stream(pkts)
1185 self.pg_enable_capture(self.pg_interfaces)
1187 frags = self.pg0.get_capture(len(pkts))
1188 p = self.reass_frags_and_verify(frags,
1189 self.pg1.remote_ip4,
1190 self.pg0.remote_ip4)
1191 if proto != IP_PROTOS.icmp:
1192 self.assertEqual(p[layer].sport, 20)
1193 self.assertEqual(p[layer].dport, self.port_in)
1195 self.assertEqual(p[layer].id, self.port_in)
1196 self.assertEqual(data, p[Raw].load)
1198 def frag_out_of_order_in_plus_out(self, proto=IP_PROTOS.tcp):
1199 layer = self.proto2layer(proto)
1201 if proto == IP_PROTOS.tcp:
1202 data = b"A" * 4 + b"B" * 16 + b"C" * 3
1204 data = b"A" * 16 + b"B" * 16 + b"C" * 3
1205 self.port_in = random.randint(1025, 65535)
1209 pkts = self.create_stream_frag(self.pg0, self.server_out_addr,
1210 self.port_in, self.server_out_port,
1213 self.pg0.add_stream(pkts)
1214 self.pg_enable_capture(self.pg_interfaces)
1216 frags = self.pg1.get_capture(len(pkts))
1217 p = self.reass_frags_and_verify(frags,
1218 self.pg0.remote_ip4,
1219 self.server_in_addr)
1220 if proto != IP_PROTOS.icmp:
1221 self.assertEqual(p[layer].dport, self.server_in_port)
1222 self.assertEqual(p[layer].sport, self.port_in)
1223 self.assertEqual(p[layer].dport, self.server_in_port)
1225 self.assertEqual(p[layer].id, self.port_in)
1226 self.assertEqual(data, p[Raw].load)
1229 if proto != IP_PROTOS.icmp:
1230 pkts = self.create_stream_frag(self.pg1, self.pg0.remote_ip4,
1231 self.server_in_port,
1232 p[layer].sport, data, proto)
1234 pkts = self.create_stream_frag(self.pg1, self.pg0.remote_ip4,
1235 p[layer].id, 0, data, proto,
1238 self.pg1.add_stream(pkts)
1239 self.pg_enable_capture(self.pg_interfaces)
1241 frags = self.pg0.get_capture(len(pkts))
1242 p = self.reass_frags_and_verify(frags,
1243 self.server_out_addr,
1244 self.pg0.remote_ip4)
1245 if proto != IP_PROTOS.icmp:
1246 self.assertEqual(p[layer].sport, self.server_out_port)
1247 self.assertEqual(p[layer].dport, self.port_in)
1249 self.assertEqual(p[layer].id, self.port_in)
1250 self.assertEqual(data, p[Raw].load)
1253 class TestNATMisc(MethodHolder):
1254 """ NAT misc Test Cases """
1256 max_translations = 10240
1260 def setUpConstants(cls):
1261 super(TestNATMisc, cls).setUpConstants()
1262 cls.vpp_cmdline.extend([
1264 "max translations per thread %d" % cls.max_translations,
1265 "max users per thread %d" % cls.max_users,
1270 def tearDownClass(cls):
1271 super(TestNATMisc, cls).tearDownClass()
1273 def test_show_config(self):
1274 """ NAT config translation memory """
1276 nat_config = self.vapi.nat_show_config()
1277 mem = nat_config.translation_memory_size
1278 self.assertTrue(mem > 0)
1279 self.logger.info("max translation memory: %d" % mem)
1281 def test_show_config_2(self):
1282 """ NAT config2 translation memory """
1284 nat_config = self.vapi.nat_show_config_2()
1285 mem = nat_config.translation_memory_size
1286 self.assertTrue(mem > 0)
1287 self.logger.info("max translation memory: %d" % mem)
1289 def test_show_max_translations(self):
1290 """ API test - max translations per thread """
1291 nat_config = self.vapi.nat_show_config_2()
1292 self.assertEqual(self.max_translations,
1293 nat_config.max_translations_per_thread)
1296 class TestNAT44(MethodHolder):
1297 """ NAT44 Test Cases """
1299 max_translations = 10240
1303 def setUpConstants(cls):
1304 super(TestNAT44, cls).setUpConstants()
1305 cls.vpp_cmdline.extend([
1307 "max translations per thread %d" % cls.max_translations,
1308 "max users per thread %d" % cls.max_users,
1313 def setUpClass(cls):
1314 super(TestNAT44, cls).setUpClass()
1315 cls.vapi.cli("set log class nat level debug")
1317 cls.tcp_port_in = 6303
1318 cls.tcp_port_out = 6303
1319 cls.udp_port_in = 6304
1320 cls.udp_port_out = 6304
1321 cls.icmp_id_in = 6305
1322 cls.icmp_id_out = 6305
1323 cls.nat_addr = '10.0.0.3'
1324 cls.ipfix_src_port = 4739
1325 cls.ipfix_domain_id = 1
1326 cls.tcp_external_port = 80
1327 cls.udp_external_port = 69
1329 cls.create_pg_interfaces(range(10))
1330 cls.interfaces = list(cls.pg_interfaces[0:4])
1332 for i in cls.interfaces:
1337 cls.pg0.generate_remote_hosts(3)
1338 cls.pg0.configure_ipv4_neighbors()
1340 cls.pg1.generate_remote_hosts(1)
1341 cls.pg1.configure_ipv4_neighbors()
1343 cls.overlapping_interfaces = list(list(cls.pg_interfaces[4:7]))
1344 cls.vapi.ip_table_add_del(is_add=1, table={'table_id': 10})
1345 cls.vapi.ip_table_add_del(is_add=1, table={'table_id': 20})
1347 cls.pg4._local_ip4 = "172.16.255.1"
1348 cls.pg4._remote_hosts[0]._ip4 = "172.16.255.2"
1349 cls.pg4.set_table_ip4(10)
1350 cls.pg5._local_ip4 = "172.17.255.3"
1351 cls.pg5._remote_hosts[0]._ip4 = "172.17.255.4"
1352 cls.pg5.set_table_ip4(10)
1353 cls.pg6._local_ip4 = "172.16.255.1"
1354 cls.pg6._remote_hosts[0]._ip4 = "172.16.255.2"
1355 cls.pg6.set_table_ip4(20)
1356 for i in cls.overlapping_interfaces:
1364 cls.pg9.generate_remote_hosts(2)
1365 cls.pg9.config_ip4()
1366 cls.vapi.sw_interface_add_del_address(
1367 sw_if_index=cls.pg9.sw_if_index,
1368 prefix="10.0.0.1/24")
1371 cls.pg9.resolve_arp()
1372 cls.pg9._remote_hosts[1]._ip4 = cls.pg9._remote_hosts[0]._ip4
1373 cls.pg4._remote_ip4 = cls.pg9._remote_hosts[0]._ip4 = "10.0.0.2"
1374 cls.pg9.resolve_arp()
1377 def tearDownClass(cls):
1378 super(TestNAT44, cls).tearDownClass()
1380 def test_clear_sessions(self):
1381 """ NAT44 session clearing test """
1383 self.nat44_add_address(self.nat_addr)
1384 flags = self.config_flags.NAT_IS_INSIDE
1385 self.vapi.nat44_interface_add_del_feature(
1386 sw_if_index=self.pg0.sw_if_index,
1387 flags=flags, is_add=1)
1388 self.vapi.nat44_interface_add_del_feature(
1389 sw_if_index=self.pg1.sw_if_index,
1392 nat_config = self.vapi.nat_show_config()
1393 self.assertEqual(0, nat_config.endpoint_dependent)
1395 pkts = self.create_stream_in(self.pg0, self.pg1)
1396 self.pg0.add_stream(pkts)
1397 self.pg_enable_capture(self.pg_interfaces)
1399 capture = self.pg1.get_capture(len(pkts))
1400 self.verify_capture_out(capture)
1402 sessions = self.statistics.get_counter('/nat44/total-sessions')
1403 self.assertTrue(sessions[0][0] > 0)
1404 self.logger.info("sessions before clearing: %s" % sessions[0][0])
1406 self.vapi.cli("clear nat44 sessions")
1408 sessions = self.statistics.get_counter('/nat44/total-sessions')
1409 self.assertEqual(sessions[0][0], 0)
1410 self.logger.info("sessions after clearing: %s" % sessions[0][0])
1412 def test_dynamic(self):
1413 """ NAT44 dynamic translation test """
1414 self.nat44_add_address(self.nat_addr)
1415 flags = self.config_flags.NAT_IS_INSIDE
1416 self.vapi.nat44_interface_add_del_feature(
1417 sw_if_index=self.pg0.sw_if_index,
1418 flags=flags, is_add=1)
1419 self.vapi.nat44_interface_add_del_feature(
1420 sw_if_index=self.pg1.sw_if_index,
1424 tcpn = self.statistics.get_counter('/nat44/in2out/slowpath/tcp')[0]
1425 udpn = self.statistics.get_counter('/nat44/in2out/slowpath/udp')[0]
1426 icmpn = self.statistics.get_counter('/nat44/in2out/slowpath/icmp')[0]
1427 drops = self.statistics.get_counter('/nat44/in2out/slowpath/drops')[0]
1429 pkts = self.create_stream_in(self.pg0, self.pg1)
1430 self.pg0.add_stream(pkts)
1431 self.pg_enable_capture(self.pg_interfaces)
1433 capture = self.pg1.get_capture(len(pkts))
1434 self.verify_capture_out(capture)
1436 if_idx = self.pg0.sw_if_index
1437 cnt = self.statistics.get_counter('/nat44/in2out/slowpath/tcp')[0]
1438 self.assertEqual(cnt[if_idx] - tcpn[if_idx], 2)
1439 cnt = self.statistics.get_counter('/nat44/in2out/slowpath/udp')[0]
1440 self.assertEqual(cnt[if_idx] - udpn[if_idx], 1)
1441 cnt = self.statistics.get_counter('/nat44/in2out/slowpath/icmp')[0]
1442 self.assertEqual(cnt[if_idx] - icmpn[if_idx], 1)
1443 cnt = self.statistics.get_counter('/nat44/in2out/slowpath/drops')[0]
1444 self.assertEqual(cnt[if_idx] - drops[if_idx], 0)
1447 tcpn = self.statistics.get_counter('/nat44/out2in/slowpath/tcp')[0]
1448 udpn = self.statistics.get_counter('/nat44/out2in/slowpath/udp')[0]
1449 icmpn = self.statistics.get_counter('/nat44/out2in/slowpath/icmp')[0]
1450 drops = self.statistics.get_counter('/nat44/out2in/slowpath/drops')[0]
1452 pkts = self.create_stream_out(self.pg1)
1453 self.pg1.add_stream(pkts)
1454 self.pg_enable_capture(self.pg_interfaces)
1456 capture = self.pg0.get_capture(len(pkts))
1457 self.verify_capture_in(capture, self.pg0)
1459 if_idx = self.pg1.sw_if_index
1460 cnt = self.statistics.get_counter('/nat44/out2in/slowpath/tcp')[0]
1461 self.assertEqual(cnt[if_idx] - tcpn[if_idx], 2)
1462 cnt = self.statistics.get_counter('/nat44/out2in/slowpath/udp')[0]
1463 self.assertEqual(cnt[if_idx] - udpn[if_idx], 1)
1464 cnt = self.statistics.get_counter('/nat44/out2in/slowpath/icmp')[0]
1465 self.assertEqual(cnt[if_idx] - icmpn[if_idx], 1)
1466 cnt = self.statistics.get_counter('/nat44/out2in/slowpath/drops')[0]
1467 self.assertEqual(cnt[if_idx] - drops[if_idx], 0)
1469 users = self.statistics.get_counter('/nat44/total-users')
1470 self.assertEqual(users[0][0], 1)
1471 sessions = self.statistics.get_counter('/nat44/total-sessions')
1472 self.assertEqual(sessions[0][0], 3)
1474 def test_dynamic_icmp_errors_in2out_ttl_1(self):
1475 """ NAT44 handling of client packets with TTL=1 """
1477 self.nat44_add_address(self.nat_addr)
1478 flags = self.config_flags.NAT_IS_INSIDE
1479 self.vapi.nat44_interface_add_del_feature(
1480 sw_if_index=self.pg0.sw_if_index,
1481 flags=flags, is_add=1)
1482 self.vapi.nat44_interface_add_del_feature(
1483 sw_if_index=self.pg1.sw_if_index,
1486 # Client side - generate traffic
1487 pkts = self.create_stream_in(self.pg0, self.pg1, ttl=1)
1488 self.pg0.add_stream(pkts)
1489 self.pg_enable_capture(self.pg_interfaces)
1492 # Client side - verify ICMP type 11 packets
1493 capture = self.pg0.get_capture(len(pkts))
1494 self.verify_capture_in_with_icmp_errors(capture, self.pg0)
1496 def test_dynamic_icmp_errors_out2in_ttl_1(self):
1497 """ NAT44 handling of server packets with TTL=1 """
1499 self.nat44_add_address(self.nat_addr)
1500 flags = self.config_flags.NAT_IS_INSIDE
1501 self.vapi.nat44_interface_add_del_feature(
1502 sw_if_index=self.pg0.sw_if_index,
1503 flags=flags, is_add=1)
1504 self.vapi.nat44_interface_add_del_feature(
1505 sw_if_index=self.pg1.sw_if_index,
1508 # Client side - create sessions
1509 pkts = self.create_stream_in(self.pg0, self.pg1)
1510 self.pg0.add_stream(pkts)
1511 self.pg_enable_capture(self.pg_interfaces)
1514 # Server side - generate traffic
1515 capture = self.pg1.get_capture(len(pkts))
1516 self.verify_capture_out(capture)
1517 pkts = self.create_stream_out(self.pg1, ttl=1)
1518 self.pg1.add_stream(pkts)
1519 self.pg_enable_capture(self.pg_interfaces)
1522 # Server side - verify ICMP type 11 packets
1523 capture = self.pg1.get_capture(len(pkts))
1524 self.verify_capture_out_with_icmp_errors(capture,
1525 src_ip=self.pg1.local_ip4)
1527 def test_dynamic_icmp_errors_in2out_ttl_2(self):
1528 """ NAT44 handling of error responses to client packets with TTL=2 """
1530 self.nat44_add_address(self.nat_addr)
1531 flags = self.config_flags.NAT_IS_INSIDE
1532 self.vapi.nat44_interface_add_del_feature(
1533 sw_if_index=self.pg0.sw_if_index,
1534 flags=flags, is_add=1)
1535 self.vapi.nat44_interface_add_del_feature(
1536 sw_if_index=self.pg1.sw_if_index,
1539 # Client side - generate traffic
1540 pkts = self.create_stream_in(self.pg0, self.pg1, ttl=2)
1541 self.pg0.add_stream(pkts)
1542 self.pg_enable_capture(self.pg_interfaces)
1545 # Server side - simulate ICMP type 11 response
1546 capture = self.pg1.get_capture(len(pkts))
1547 pkts = [Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
1548 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
1549 ICMP(type=11) / packet[IP] for packet in capture]
1550 self.pg1.add_stream(pkts)
1551 self.pg_enable_capture(self.pg_interfaces)
1554 # Client side - verify ICMP type 11 packets
1555 capture = self.pg0.get_capture(len(pkts))
1556 self.verify_capture_in_with_icmp_errors(capture, self.pg0)
1558 def test_dynamic_icmp_errors_out2in_ttl_2(self):
1559 """ NAT44 handling of error responses to server packets with TTL=2 """
1561 self.nat44_add_address(self.nat_addr)
1562 flags = self.config_flags.NAT_IS_INSIDE
1563 self.vapi.nat44_interface_add_del_feature(
1564 sw_if_index=self.pg0.sw_if_index,
1565 flags=flags, is_add=1)
1566 self.vapi.nat44_interface_add_del_feature(
1567 sw_if_index=self.pg1.sw_if_index,
1570 # Client side - create sessions
1571 pkts = self.create_stream_in(self.pg0, self.pg1)
1572 self.pg0.add_stream(pkts)
1573 self.pg_enable_capture(self.pg_interfaces)
1576 # Server side - generate traffic
1577 capture = self.pg1.get_capture(len(pkts))
1578 self.verify_capture_out(capture)
1579 pkts = self.create_stream_out(self.pg1, ttl=2)
1580 self.pg1.add_stream(pkts)
1581 self.pg_enable_capture(self.pg_interfaces)
1584 # Client side - simulate ICMP type 11 response
1585 capture = self.pg0.get_capture(len(pkts))
1586 pkts = [Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
1587 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
1588 ICMP(type=11) / packet[IP] for packet in capture]
1589 self.pg0.add_stream(pkts)
1590 self.pg_enable_capture(self.pg_interfaces)
1593 # Server side - verify ICMP type 11 packets
1594 capture = self.pg1.get_capture(len(pkts))
1595 self.verify_capture_out_with_icmp_errors(capture)
1597 def test_ping_out_interface_from_outside(self):
1598 """ Ping NAT44 out interface from outside network """
1600 self.nat44_add_address(self.nat_addr)
1601 flags = self.config_flags.NAT_IS_INSIDE
1602 self.vapi.nat44_interface_add_del_feature(
1603 sw_if_index=self.pg0.sw_if_index,
1604 flags=flags, is_add=1)
1605 self.vapi.nat44_interface_add_del_feature(
1606 sw_if_index=self.pg1.sw_if_index,
1609 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
1610 IP(src=self.pg1.remote_ip4, dst=self.pg1.local_ip4) /
1611 ICMP(id=self.icmp_id_out, type='echo-request'))
1613 self.pg1.add_stream(pkts)
1614 self.pg_enable_capture(self.pg_interfaces)
1616 capture = self.pg1.get_capture(len(pkts))
1619 self.assertEqual(packet[IP].src, self.pg1.local_ip4)
1620 self.assertEqual(packet[IP].dst, self.pg1.remote_ip4)
1621 self.assertEqual(packet[ICMP].id, self.icmp_id_in)
1622 self.assertEqual(packet[ICMP].type, 0) # echo reply
1624 self.logger.error(ppp("Unexpected or invalid packet "
1625 "(outside network):", packet))
1628 def test_ping_internal_host_from_outside(self):
1629 """ Ping internal host from outside network """
1631 self.nat44_add_static_mapping(self.pg0.remote_ip4, self.nat_addr)
1632 flags = self.config_flags.NAT_IS_INSIDE
1633 self.vapi.nat44_interface_add_del_feature(
1634 sw_if_index=self.pg0.sw_if_index,
1635 flags=flags, is_add=1)
1636 self.vapi.nat44_interface_add_del_feature(
1637 sw_if_index=self.pg1.sw_if_index,
1641 pkt = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
1642 IP(src=self.pg1.remote_ip4, dst=self.nat_addr, ttl=64) /
1643 ICMP(id=self.icmp_id_out, type='echo-request'))
1644 self.pg1.add_stream(pkt)
1645 self.pg_enable_capture(self.pg_interfaces)
1647 capture = self.pg0.get_capture(1)
1648 self.verify_capture_in(capture, self.pg0)
1649 self.assert_equal(capture[0][IP].proto, IP_PROTOS.icmp)
1652 pkt = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
1653 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4, ttl=64) /
1654 ICMP(id=self.icmp_id_in, type='echo-reply'))
1655 self.pg0.add_stream(pkt)
1656 self.pg_enable_capture(self.pg_interfaces)
1658 capture = self.pg1.get_capture(1)
1659 self.verify_capture_out(capture, same_port=True)
1660 self.assert_equal(capture[0][IP].proto, IP_PROTOS.icmp)
1662 def test_forwarding(self):
1663 """ NAT44 forwarding test """
1665 flags = self.config_flags.NAT_IS_INSIDE
1666 self.vapi.nat44_interface_add_del_feature(
1667 sw_if_index=self.pg0.sw_if_index,
1668 flags=flags, is_add=1)
1669 self.vapi.nat44_interface_add_del_feature(
1670 sw_if_index=self.pg1.sw_if_index,
1672 self.vapi.nat44_forwarding_enable_disable(enable=1)
1674 real_ip = self.pg0.remote_ip4
1675 alias_ip = self.nat_addr
1676 flags = self.config_flags.NAT_IS_ADDR_ONLY
1677 self.vapi.nat44_add_del_static_mapping(is_add=1,
1678 local_ip_address=real_ip,
1679 external_ip_address=alias_ip,
1680 external_sw_if_index=0xFFFFFFFF,
1684 # static mapping match
1686 pkts = self.create_stream_out(self.pg1)
1687 self.pg1.add_stream(pkts)
1688 self.pg_enable_capture(self.pg_interfaces)
1690 capture = self.pg0.get_capture(len(pkts))
1691 self.verify_capture_in(capture, self.pg0)
1693 pkts = self.create_stream_in(self.pg0, self.pg1)
1694 self.pg0.add_stream(pkts)
1695 self.pg_enable_capture(self.pg_interfaces)
1697 capture = self.pg1.get_capture(len(pkts))
1698 self.verify_capture_out(capture, same_port=True)
1700 # no static mapping match
1702 host0 = self.pg0.remote_hosts[0]
1703 self.pg0.remote_hosts[0] = self.pg0.remote_hosts[1]
1705 pkts = self.create_stream_out(self.pg1,
1706 dst_ip=self.pg0.remote_ip4,
1707 use_inside_ports=True)
1708 self.pg1.add_stream(pkts)
1709 self.pg_enable_capture(self.pg_interfaces)
1711 capture = self.pg0.get_capture(len(pkts))
1712 self.verify_capture_in(capture, self.pg0)
1714 pkts = self.create_stream_in(self.pg0, self.pg1)
1715 self.pg0.add_stream(pkts)
1716 self.pg_enable_capture(self.pg_interfaces)
1718 capture = self.pg1.get_capture(len(pkts))
1719 self.verify_capture_out(capture, nat_ip=self.pg0.remote_ip4,
1722 self.pg0.remote_hosts[0] = host0
1725 self.vapi.nat44_forwarding_enable_disable(enable=0)
1726 flags = self.config_flags.NAT_IS_ADDR_ONLY
1727 self.vapi.nat44_add_del_static_mapping(
1729 local_ip_address=real_ip,
1730 external_ip_address=alias_ip,
1731 external_sw_if_index=0xFFFFFFFF,
1734 def test_static_in(self):
1735 """ 1:1 NAT initialized from inside network """
1737 nat_ip = "10.0.0.10"
1738 self.tcp_port_out = 6303
1739 self.udp_port_out = 6304
1740 self.icmp_id_out = 6305
1742 self.nat44_add_static_mapping(self.pg0.remote_ip4, nat_ip)
1743 flags = self.config_flags.NAT_IS_INSIDE
1744 self.vapi.nat44_interface_add_del_feature(
1745 sw_if_index=self.pg0.sw_if_index,
1746 flags=flags, is_add=1)
1747 self.vapi.nat44_interface_add_del_feature(
1748 sw_if_index=self.pg1.sw_if_index,
1750 sm = self.vapi.nat44_static_mapping_dump()
1751 self.assertEqual(len(sm), 1)
1752 self.assertEqual(sm[0].tag, '')
1753 self.assertEqual(sm[0].protocol, 0)
1754 self.assertEqual(sm[0].local_port, 0)
1755 self.assertEqual(sm[0].external_port, 0)
1758 pkts = self.create_stream_in(self.pg0, self.pg1)
1759 self.pg0.add_stream(pkts)
1760 self.pg_enable_capture(self.pg_interfaces)
1762 capture = self.pg1.get_capture(len(pkts))
1763 self.verify_capture_out(capture, nat_ip, True)
1766 pkts = self.create_stream_out(self.pg1, nat_ip)
1767 self.pg1.add_stream(pkts)
1768 self.pg_enable_capture(self.pg_interfaces)
1770 capture = self.pg0.get_capture(len(pkts))
1771 self.verify_capture_in(capture, self.pg0)
1773 def test_static_out(self):
1774 """ 1:1 NAT initialized from outside network """
1776 nat_ip = "10.0.0.20"
1777 self.tcp_port_out = 6303
1778 self.udp_port_out = 6304
1779 self.icmp_id_out = 6305
1782 self.nat44_add_static_mapping(self.pg0.remote_ip4, nat_ip, tag=tag)
1783 flags = self.config_flags.NAT_IS_INSIDE
1784 self.vapi.nat44_interface_add_del_feature(
1785 sw_if_index=self.pg0.sw_if_index,
1786 flags=flags, is_add=1)
1787 self.vapi.nat44_interface_add_del_feature(
1788 sw_if_index=self.pg1.sw_if_index,
1790 sm = self.vapi.nat44_static_mapping_dump()
1791 self.assertEqual(len(sm), 1)
1792 self.assertEqual(sm[0].tag, tag)
1795 pkts = self.create_stream_out(self.pg1, nat_ip)
1796 self.pg1.add_stream(pkts)
1797 self.pg_enable_capture(self.pg_interfaces)
1799 capture = self.pg0.get_capture(len(pkts))
1800 self.verify_capture_in(capture, self.pg0)
1803 pkts = self.create_stream_in(self.pg0, self.pg1)
1804 self.pg0.add_stream(pkts)
1805 self.pg_enable_capture(self.pg_interfaces)
1807 capture = self.pg1.get_capture(len(pkts))
1808 self.verify_capture_out(capture, nat_ip, True)
1810 def test_static_with_port_in(self):
1811 """ 1:1 NAPT initialized from inside network """
1813 self.tcp_port_out = 3606
1814 self.udp_port_out = 3607
1815 self.icmp_id_out = 3608
1817 self.nat44_add_address(self.nat_addr)
1818 self.nat44_add_static_mapping(self.pg0.remote_ip4, self.nat_addr,
1819 self.tcp_port_in, self.tcp_port_out,
1820 proto=IP_PROTOS.tcp)
1821 self.nat44_add_static_mapping(self.pg0.remote_ip4, self.nat_addr,
1822 self.udp_port_in, self.udp_port_out,
1823 proto=IP_PROTOS.udp)
1824 self.nat44_add_static_mapping(self.pg0.remote_ip4, self.nat_addr,
1825 self.icmp_id_in, self.icmp_id_out,
1826 proto=IP_PROTOS.icmp)
1827 flags = self.config_flags.NAT_IS_INSIDE
1828 self.vapi.nat44_interface_add_del_feature(
1829 sw_if_index=self.pg0.sw_if_index,
1830 flags=flags, is_add=1)
1831 self.vapi.nat44_interface_add_del_feature(
1832 sw_if_index=self.pg1.sw_if_index,
1836 pkts = self.create_stream_in(self.pg0, self.pg1)
1837 self.pg0.add_stream(pkts)
1838 self.pg_enable_capture(self.pg_interfaces)
1840 capture = self.pg1.get_capture(len(pkts))
1841 self.verify_capture_out(capture)
1844 pkts = self.create_stream_out(self.pg1)
1845 self.pg1.add_stream(pkts)
1846 self.pg_enable_capture(self.pg_interfaces)
1848 capture = self.pg0.get_capture(len(pkts))
1849 self.verify_capture_in(capture, self.pg0)
1851 def test_static_with_port_out(self):
1852 """ 1:1 NAPT initialized from outside network """
1854 self.tcp_port_out = 30606
1855 self.udp_port_out = 30607
1856 self.icmp_id_out = 30608
1858 self.nat44_add_address(self.nat_addr)
1859 self.nat44_add_static_mapping(self.pg0.remote_ip4, self.nat_addr,
1860 self.tcp_port_in, self.tcp_port_out,
1861 proto=IP_PROTOS.tcp)
1862 self.nat44_add_static_mapping(self.pg0.remote_ip4, self.nat_addr,
1863 self.udp_port_in, self.udp_port_out,
1864 proto=IP_PROTOS.udp)
1865 self.nat44_add_static_mapping(self.pg0.remote_ip4, self.nat_addr,
1866 self.icmp_id_in, self.icmp_id_out,
1867 proto=IP_PROTOS.icmp)
1868 flags = self.config_flags.NAT_IS_INSIDE
1869 self.vapi.nat44_interface_add_del_feature(
1870 sw_if_index=self.pg0.sw_if_index,
1871 flags=flags, is_add=1)
1872 self.vapi.nat44_interface_add_del_feature(
1873 sw_if_index=self.pg1.sw_if_index,
1877 pkts = self.create_stream_out(self.pg1)
1878 self.pg1.add_stream(pkts)
1879 self.pg_enable_capture(self.pg_interfaces)
1881 capture = self.pg0.get_capture(len(pkts))
1882 self.verify_capture_in(capture, self.pg0)
1885 pkts = self.create_stream_in(self.pg0, self.pg1)
1886 self.pg0.add_stream(pkts)
1887 self.pg_enable_capture(self.pg_interfaces)
1889 capture = self.pg1.get_capture(len(pkts))
1890 self.verify_capture_out(capture)
1892 def test_static_vrf_aware(self):
1893 """ 1:1 NAT VRF awareness """
1895 nat_ip1 = "10.0.0.30"
1896 nat_ip2 = "10.0.0.40"
1897 self.tcp_port_out = 6303
1898 self.udp_port_out = 6304
1899 self.icmp_id_out = 6305
1901 self.nat44_add_static_mapping(self.pg4.remote_ip4, nat_ip1,
1903 self.nat44_add_static_mapping(self.pg0.remote_ip4, nat_ip2,
1905 flags = self.config_flags.NAT_IS_INSIDE
1906 self.vapi.nat44_interface_add_del_feature(
1907 sw_if_index=self.pg3.sw_if_index,
1909 self.vapi.nat44_interface_add_del_feature(
1910 sw_if_index=self.pg0.sw_if_index,
1911 flags=flags, is_add=1)
1912 self.vapi.nat44_interface_add_del_feature(
1913 sw_if_index=self.pg4.sw_if_index,
1914 flags=flags, is_add=1)
1916 # inside interface VRF match NAT44 static mapping VRF
1917 pkts = self.create_stream_in(self.pg4, self.pg3)
1918 self.pg4.add_stream(pkts)
1919 self.pg_enable_capture(self.pg_interfaces)
1921 capture = self.pg3.get_capture(len(pkts))
1922 self.verify_capture_out(capture, nat_ip1, True)
1924 # inside interface VRF don't match NAT44 static mapping VRF (packets
1926 pkts = self.create_stream_in(self.pg0, self.pg3)
1927 self.pg0.add_stream(pkts)
1928 self.pg_enable_capture(self.pg_interfaces)
1930 self.pg3.assert_nothing_captured()
1932 def test_dynamic_to_static(self):
1933 """ Switch from dynamic translation to 1:1NAT """
1934 nat_ip = "10.0.0.10"
1935 self.tcp_port_out = 6303
1936 self.udp_port_out = 6304
1937 self.icmp_id_out = 6305
1939 self.nat44_add_address(self.nat_addr)
1940 flags = self.config_flags.NAT_IS_INSIDE
1941 self.vapi.nat44_interface_add_del_feature(
1942 sw_if_index=self.pg0.sw_if_index,
1943 flags=flags, is_add=1)
1944 self.vapi.nat44_interface_add_del_feature(
1945 sw_if_index=self.pg1.sw_if_index,
1949 pkts = self.create_stream_in(self.pg0, self.pg1)
1950 self.pg0.add_stream(pkts)
1951 self.pg_enable_capture(self.pg_interfaces)
1953 capture = self.pg1.get_capture(len(pkts))
1954 self.verify_capture_out(capture)
1957 self.nat44_add_static_mapping(self.pg0.remote_ip4, nat_ip)
1958 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4, 0)
1959 self.assertEqual(len(sessions), 0)
1960 pkts = self.create_stream_in(self.pg0, self.pg1)
1961 self.pg0.add_stream(pkts)
1962 self.pg_enable_capture(self.pg_interfaces)
1964 capture = self.pg1.get_capture(len(pkts))
1965 self.verify_capture_out(capture, nat_ip, True)
1967 def test_identity_nat(self):
1968 """ Identity NAT """
1969 flags = self.config_flags.NAT_IS_ADDR_ONLY
1970 self.vapi.nat44_add_del_identity_mapping(
1971 ip_address=self.pg0.remote_ip4, sw_if_index=0xFFFFFFFF,
1972 flags=flags, is_add=1)
1973 flags = self.config_flags.NAT_IS_INSIDE
1974 self.vapi.nat44_interface_add_del_feature(
1975 sw_if_index=self.pg0.sw_if_index,
1976 flags=flags, is_add=1)
1977 self.vapi.nat44_interface_add_del_feature(
1978 sw_if_index=self.pg1.sw_if_index,
1981 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
1982 IP(src=self.pg1.remote_ip4, dst=self.pg0.remote_ip4) /
1983 TCP(sport=12345, dport=56789))
1984 self.pg1.add_stream(p)
1985 self.pg_enable_capture(self.pg_interfaces)
1987 capture = self.pg0.get_capture(1)
1992 self.assertEqual(ip.dst, self.pg0.remote_ip4)
1993 self.assertEqual(ip.src, self.pg1.remote_ip4)
1994 self.assertEqual(tcp.dport, 56789)
1995 self.assertEqual(tcp.sport, 12345)
1996 self.assert_packet_checksums_valid(p)
1998 self.logger.error(ppp("Unexpected or invalid packet:", p))
2001 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4, 0)
2002 self.assertEqual(len(sessions), 0)
2003 flags = self.config_flags.NAT_IS_ADDR_ONLY
2004 self.vapi.nat44_add_del_identity_mapping(
2005 ip_address=self.pg0.remote_ip4, sw_if_index=0xFFFFFFFF,
2006 flags=flags, vrf_id=1, is_add=1)
2007 identity_mappings = self.vapi.nat44_identity_mapping_dump()
2008 self.assertEqual(len(identity_mappings), 2)
2010 def test_multiple_inside_interfaces(self):
2011 """ NAT44 multiple non-overlapping address space inside interfaces """
2013 self.nat44_add_address(self.nat_addr)
2014 flags = self.config_flags.NAT_IS_INSIDE
2015 self.vapi.nat44_interface_add_del_feature(
2016 sw_if_index=self.pg0.sw_if_index,
2017 flags=flags, is_add=1)
2018 self.vapi.nat44_interface_add_del_feature(
2019 sw_if_index=self.pg1.sw_if_index,
2020 flags=flags, is_add=1)
2021 self.vapi.nat44_interface_add_del_feature(
2022 sw_if_index=self.pg3.sw_if_index,
2025 # between two NAT44 inside interfaces (no translation)
2026 pkts = self.create_stream_in(self.pg0, self.pg1)
2027 self.pg0.add_stream(pkts)
2028 self.pg_enable_capture(self.pg_interfaces)
2030 capture = self.pg1.get_capture(len(pkts))
2031 self.verify_capture_no_translation(capture, self.pg0, self.pg1)
2033 # from NAT44 inside to interface without NAT44 feature (no translation)
2034 pkts = self.create_stream_in(self.pg0, self.pg2)
2035 self.pg0.add_stream(pkts)
2036 self.pg_enable_capture(self.pg_interfaces)
2038 capture = self.pg2.get_capture(len(pkts))
2039 self.verify_capture_no_translation(capture, self.pg0, self.pg2)
2041 # in2out 1st interface
2042 pkts = self.create_stream_in(self.pg0, self.pg3)
2043 self.pg0.add_stream(pkts)
2044 self.pg_enable_capture(self.pg_interfaces)
2046 capture = self.pg3.get_capture(len(pkts))
2047 self.verify_capture_out(capture)
2049 # out2in 1st interface
2050 pkts = self.create_stream_out(self.pg3)
2051 self.pg3.add_stream(pkts)
2052 self.pg_enable_capture(self.pg_interfaces)
2054 capture = self.pg0.get_capture(len(pkts))
2055 self.verify_capture_in(capture, self.pg0)
2057 # in2out 2nd interface
2058 pkts = self.create_stream_in(self.pg1, self.pg3)
2059 self.pg1.add_stream(pkts)
2060 self.pg_enable_capture(self.pg_interfaces)
2062 capture = self.pg3.get_capture(len(pkts))
2063 self.verify_capture_out(capture)
2065 # out2in 2nd interface
2066 pkts = self.create_stream_out(self.pg3)
2067 self.pg3.add_stream(pkts)
2068 self.pg_enable_capture(self.pg_interfaces)
2070 capture = self.pg1.get_capture(len(pkts))
2071 self.verify_capture_in(capture, self.pg1)
2073 def test_inside_overlapping_interfaces(self):
2074 """ NAT44 multiple inside interfaces with overlapping address space """
2076 static_nat_ip = "10.0.0.10"
2077 self.nat44_add_address(self.nat_addr)
2078 flags = self.config_flags.NAT_IS_INSIDE
2079 self.vapi.nat44_interface_add_del_feature(
2080 sw_if_index=self.pg3.sw_if_index,
2082 self.vapi.nat44_interface_add_del_feature(
2083 sw_if_index=self.pg4.sw_if_index,
2084 flags=flags, is_add=1)
2085 self.vapi.nat44_interface_add_del_feature(
2086 sw_if_index=self.pg5.sw_if_index,
2087 flags=flags, is_add=1)
2088 self.vapi.nat44_interface_add_del_feature(
2089 sw_if_index=self.pg6.sw_if_index,
2090 flags=flags, is_add=1)
2091 self.nat44_add_static_mapping(self.pg6.remote_ip4, static_nat_ip,
2094 # between NAT44 inside interfaces with same VRF (no translation)
2095 pkts = self.create_stream_in(self.pg4, self.pg5)
2096 self.pg4.add_stream(pkts)
2097 self.pg_enable_capture(self.pg_interfaces)
2099 capture = self.pg5.get_capture(len(pkts))
2100 self.verify_capture_no_translation(capture, self.pg4, self.pg5)
2102 # between NAT44 inside interfaces with different VRF (hairpinning)
2103 p = (Ether(src=self.pg4.remote_mac, dst=self.pg4.local_mac) /
2104 IP(src=self.pg4.remote_ip4, dst=static_nat_ip) /
2105 TCP(sport=1234, dport=5678))
2106 self.pg4.add_stream(p)
2107 self.pg_enable_capture(self.pg_interfaces)
2109 capture = self.pg6.get_capture(1)
2114 self.assertEqual(ip.src, self.nat_addr)
2115 self.assertEqual(ip.dst, self.pg6.remote_ip4)
2116 self.assertNotEqual(tcp.sport, 1234)
2117 self.assertEqual(tcp.dport, 5678)
2119 self.logger.error(ppp("Unexpected or invalid packet:", p))
2122 # in2out 1st interface
2123 pkts = self.create_stream_in(self.pg4, self.pg3)
2124 self.pg4.add_stream(pkts)
2125 self.pg_enable_capture(self.pg_interfaces)
2127 capture = self.pg3.get_capture(len(pkts))
2128 self.verify_capture_out(capture)
2130 # out2in 1st interface
2131 pkts = self.create_stream_out(self.pg3)
2132 self.pg3.add_stream(pkts)
2133 self.pg_enable_capture(self.pg_interfaces)
2135 capture = self.pg4.get_capture(len(pkts))
2136 self.verify_capture_in(capture, self.pg4)
2138 # in2out 2nd interface
2139 pkts = self.create_stream_in(self.pg5, self.pg3)
2140 self.pg5.add_stream(pkts)
2141 self.pg_enable_capture(self.pg_interfaces)
2143 capture = self.pg3.get_capture(len(pkts))
2144 self.verify_capture_out(capture)
2146 # out2in 2nd interface
2147 pkts = self.create_stream_out(self.pg3)
2148 self.pg3.add_stream(pkts)
2149 self.pg_enable_capture(self.pg_interfaces)
2151 capture = self.pg5.get_capture(len(pkts))
2152 self.verify_capture_in(capture, self.pg5)
2155 addresses = self.vapi.nat44_address_dump()
2156 self.assertEqual(len(addresses), 1)
2157 sessions = self.vapi.nat44_user_session_dump(self.pg5.remote_ip4, 10)
2158 self.assertEqual(len(sessions), 3)
2159 for session in sessions:
2160 self.assertFalse(session.flags & self.config_flags.NAT_IS_STATIC)
2161 self.assertEqual(str(session.inside_ip_address),
2162 self.pg5.remote_ip4)
2163 self.assertEqual(session.outside_ip_address,
2164 addresses[0].ip_address)
2165 self.assertEqual(sessions[0].protocol, IP_PROTOS.tcp)
2166 self.assertEqual(sessions[1].protocol, IP_PROTOS.udp)
2167 self.assertEqual(sessions[2].protocol, IP_PROTOS.icmp)
2168 self.assertEqual(sessions[0].inside_port, self.tcp_port_in)
2169 self.assertEqual(sessions[1].inside_port, self.udp_port_in)
2170 self.assertEqual(sessions[2].inside_port, self.icmp_id_in)
2171 self.assertEqual(sessions[0].outside_port, self.tcp_port_out)
2172 self.assertEqual(sessions[1].outside_port, self.udp_port_out)
2173 self.assertEqual(sessions[2].outside_port, self.icmp_id_out)
2175 # in2out 3rd interface
2176 pkts = self.create_stream_in(self.pg6, self.pg3)
2177 self.pg6.add_stream(pkts)
2178 self.pg_enable_capture(self.pg_interfaces)
2180 capture = self.pg3.get_capture(len(pkts))
2181 self.verify_capture_out(capture, static_nat_ip, True)
2183 # out2in 3rd interface
2184 pkts = self.create_stream_out(self.pg3, static_nat_ip)
2185 self.pg3.add_stream(pkts)
2186 self.pg_enable_capture(self.pg_interfaces)
2188 capture = self.pg6.get_capture(len(pkts))
2189 self.verify_capture_in(capture, self.pg6)
2191 # general user and session dump verifications
2192 users = self.vapi.nat44_user_dump()
2193 self.assertGreaterEqual(len(users), 3)
2194 addresses = self.vapi.nat44_address_dump()
2195 self.assertEqual(len(addresses), 1)
2197 sessions = self.vapi.nat44_user_session_dump(user.ip_address,
2199 for session in sessions:
2200 self.assertEqual(user.ip_address, session.inside_ip_address)
2201 self.assertTrue(session.total_bytes > session.total_pkts > 0)
2202 self.assertTrue(session.protocol in
2203 [IP_PROTOS.tcp, IP_PROTOS.udp,
2205 self.assertFalse(session.flags &
2206 self.config_flags.NAT_IS_EXT_HOST_VALID)
2209 sessions = self.vapi.nat44_user_session_dump(self.pg4.remote_ip4, 10)
2210 self.assertGreaterEqual(len(sessions), 4)
2211 for session in sessions:
2212 self.assertFalse(session.flags & self.config_flags.NAT_IS_STATIC)
2213 self.assertEqual(str(session.inside_ip_address),
2214 self.pg4.remote_ip4)
2215 self.assertEqual(session.outside_ip_address,
2216 addresses[0].ip_address)
2219 sessions = self.vapi.nat44_user_session_dump(self.pg6.remote_ip4, 20)
2220 self.assertGreaterEqual(len(sessions), 3)
2221 for session in sessions:
2222 self.assertTrue(session.flags & self.config_flags.NAT_IS_STATIC)
2223 self.assertEqual(str(session.inside_ip_address),
2224 self.pg6.remote_ip4)
2225 self.assertEqual(str(session.outside_ip_address),
2227 self.assertTrue(session.inside_port in
2228 [self.tcp_port_in, self.udp_port_in,
2231 def test_hairpinning(self):
2232 """ NAT44 hairpinning - 1:1 NAPT """
2234 host = self.pg0.remote_hosts[0]
2235 server = self.pg0.remote_hosts[1]
2238 server_in_port = 5678
2239 server_out_port = 8765
2241 self.nat44_add_address(self.nat_addr)
2242 flags = self.config_flags.NAT_IS_INSIDE
2243 self.vapi.nat44_interface_add_del_feature(
2244 sw_if_index=self.pg0.sw_if_index,
2245 flags=flags, is_add=1)
2246 self.vapi.nat44_interface_add_del_feature(
2247 sw_if_index=self.pg1.sw_if_index,
2250 # add static mapping for server
2251 self.nat44_add_static_mapping(server.ip4, self.nat_addr,
2252 server_in_port, server_out_port,
2253 proto=IP_PROTOS.tcp)
2255 cnt = self.statistics.get_counter('/nat44/hairpinning')[0]
2256 # send packet from host to server
2257 p = (Ether(src=host.mac, dst=self.pg0.local_mac) /
2258 IP(src=host.ip4, dst=self.nat_addr) /
2259 TCP(sport=host_in_port, dport=server_out_port))
2260 self.pg0.add_stream(p)
2261 self.pg_enable_capture(self.pg_interfaces)
2263 capture = self.pg0.get_capture(1)
2268 self.assertEqual(ip.src, self.nat_addr)
2269 self.assertEqual(ip.dst, server.ip4)
2270 self.assertNotEqual(tcp.sport, host_in_port)
2271 self.assertEqual(tcp.dport, server_in_port)
2272 self.assert_packet_checksums_valid(p)
2273 host_out_port = tcp.sport
2275 self.logger.error(ppp("Unexpected or invalid packet:", p))
2278 after = self.statistics.get_counter('/nat44/hairpinning')[0]
2279 if_idx = self.pg0.sw_if_index
2280 self.assertEqual(after[if_idx] - cnt[if_idx], 1)
2282 # send reply from server to host
2283 p = (Ether(src=server.mac, dst=self.pg0.local_mac) /
2284 IP(src=server.ip4, dst=self.nat_addr) /
2285 TCP(sport=server_in_port, dport=host_out_port))
2286 self.pg0.add_stream(p)
2287 self.pg_enable_capture(self.pg_interfaces)
2289 capture = self.pg0.get_capture(1)
2294 self.assertEqual(ip.src, self.nat_addr)
2295 self.assertEqual(ip.dst, host.ip4)
2296 self.assertEqual(tcp.sport, server_out_port)
2297 self.assertEqual(tcp.dport, host_in_port)
2298 self.assert_packet_checksums_valid(p)
2300 self.logger.error(ppp("Unexpected or invalid packet:", p))
2303 after = self.statistics.get_counter('/nat44/hairpinning')[0]
2304 if_idx = self.pg0.sw_if_index
2305 self.assertEqual(after[if_idx] - cnt[if_idx], 2)
2307 def test_hairpinning2(self):
2308 """ NAT44 hairpinning - 1:1 NAT"""
2310 server1_nat_ip = "10.0.0.10"
2311 server2_nat_ip = "10.0.0.11"
2312 host = self.pg0.remote_hosts[0]
2313 server1 = self.pg0.remote_hosts[1]
2314 server2 = self.pg0.remote_hosts[2]
2315 server_tcp_port = 22
2316 server_udp_port = 20
2318 self.nat44_add_address(self.nat_addr)
2319 flags = self.config_flags.NAT_IS_INSIDE
2320 self.vapi.nat44_interface_add_del_feature(
2321 sw_if_index=self.pg0.sw_if_index,
2322 flags=flags, is_add=1)
2323 self.vapi.nat44_interface_add_del_feature(
2324 sw_if_index=self.pg1.sw_if_index,
2327 # add static mapping for servers
2328 self.nat44_add_static_mapping(server1.ip4, server1_nat_ip)
2329 self.nat44_add_static_mapping(server2.ip4, server2_nat_ip)
2333 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2334 IP(src=host.ip4, dst=server1_nat_ip) /
2335 TCP(sport=self.tcp_port_in, dport=server_tcp_port))
2337 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2338 IP(src=host.ip4, dst=server1_nat_ip) /
2339 UDP(sport=self.udp_port_in, dport=server_udp_port))
2341 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2342 IP(src=host.ip4, dst=server1_nat_ip) /
2343 ICMP(id=self.icmp_id_in, type='echo-request'))
2345 self.pg0.add_stream(pkts)
2346 self.pg_enable_capture(self.pg_interfaces)
2348 capture = self.pg0.get_capture(len(pkts))
2349 for packet in capture:
2351 self.assertEqual(packet[IP].src, self.nat_addr)
2352 self.assertEqual(packet[IP].dst, server1.ip4)
2353 if packet.haslayer(TCP):
2354 self.assertNotEqual(packet[TCP].sport, self.tcp_port_in)
2355 self.assertEqual(packet[TCP].dport, server_tcp_port)
2356 self.tcp_port_out = packet[TCP].sport
2357 self.assert_packet_checksums_valid(packet)
2358 elif packet.haslayer(UDP):
2359 self.assertNotEqual(packet[UDP].sport, self.udp_port_in)
2360 self.assertEqual(packet[UDP].dport, server_udp_port)
2361 self.udp_port_out = packet[UDP].sport
2363 self.assertNotEqual(packet[ICMP].id, self.icmp_id_in)
2364 self.icmp_id_out = packet[ICMP].id
2366 self.logger.error(ppp("Unexpected or invalid packet:", packet))
2371 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2372 IP(src=server1.ip4, dst=self.nat_addr) /
2373 TCP(sport=server_tcp_port, dport=self.tcp_port_out))
2375 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2376 IP(src=server1.ip4, dst=self.nat_addr) /
2377 UDP(sport=server_udp_port, dport=self.udp_port_out))
2379 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2380 IP(src=server1.ip4, dst=self.nat_addr) /
2381 ICMP(id=self.icmp_id_out, type='echo-reply'))
2383 self.pg0.add_stream(pkts)
2384 self.pg_enable_capture(self.pg_interfaces)
2386 capture = self.pg0.get_capture(len(pkts))
2387 for packet in capture:
2389 self.assertEqual(packet[IP].src, server1_nat_ip)
2390 self.assertEqual(packet[IP].dst, host.ip4)
2391 if packet.haslayer(TCP):
2392 self.assertEqual(packet[TCP].dport, self.tcp_port_in)
2393 self.assertEqual(packet[TCP].sport, server_tcp_port)
2394 self.assert_packet_checksums_valid(packet)
2395 elif packet.haslayer(UDP):
2396 self.assertEqual(packet[UDP].dport, self.udp_port_in)
2397 self.assertEqual(packet[UDP].sport, server_udp_port)
2399 self.assertEqual(packet[ICMP].id, self.icmp_id_in)
2401 self.logger.error(ppp("Unexpected or invalid packet:", packet))
2404 # server2 to server1
2406 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2407 IP(src=server2.ip4, dst=server1_nat_ip) /
2408 TCP(sport=self.tcp_port_in, dport=server_tcp_port))
2410 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2411 IP(src=server2.ip4, dst=server1_nat_ip) /
2412 UDP(sport=self.udp_port_in, dport=server_udp_port))
2414 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2415 IP(src=server2.ip4, dst=server1_nat_ip) /
2416 ICMP(id=self.icmp_id_in, type='echo-request'))
2418 self.pg0.add_stream(pkts)
2419 self.pg_enable_capture(self.pg_interfaces)
2421 capture = self.pg0.get_capture(len(pkts))
2422 for packet in capture:
2424 self.assertEqual(packet[IP].src, server2_nat_ip)
2425 self.assertEqual(packet[IP].dst, server1.ip4)
2426 if packet.haslayer(TCP):
2427 self.assertEqual(packet[TCP].sport, self.tcp_port_in)
2428 self.assertEqual(packet[TCP].dport, server_tcp_port)
2429 self.tcp_port_out = packet[TCP].sport
2430 self.assert_packet_checksums_valid(packet)
2431 elif packet.haslayer(UDP):
2432 self.assertEqual(packet[UDP].sport, self.udp_port_in)
2433 self.assertEqual(packet[UDP].dport, server_udp_port)
2434 self.udp_port_out = packet[UDP].sport
2436 self.assertEqual(packet[ICMP].id, self.icmp_id_in)
2437 self.icmp_id_out = packet[ICMP].id
2439 self.logger.error(ppp("Unexpected or invalid packet:", packet))
2442 # server1 to server2
2444 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2445 IP(src=server1.ip4, dst=server2_nat_ip) /
2446 TCP(sport=server_tcp_port, dport=self.tcp_port_out))
2448 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2449 IP(src=server1.ip4, dst=server2_nat_ip) /
2450 UDP(sport=server_udp_port, dport=self.udp_port_out))
2452 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2453 IP(src=server1.ip4, dst=server2_nat_ip) /
2454 ICMP(id=self.icmp_id_out, type='echo-reply'))
2456 self.pg0.add_stream(pkts)
2457 self.pg_enable_capture(self.pg_interfaces)
2459 capture = self.pg0.get_capture(len(pkts))
2460 for packet in capture:
2462 self.assertEqual(packet[IP].src, server1_nat_ip)
2463 self.assertEqual(packet[IP].dst, server2.ip4)
2464 if packet.haslayer(TCP):
2465 self.assertEqual(packet[TCP].dport, self.tcp_port_in)
2466 self.assertEqual(packet[TCP].sport, server_tcp_port)
2467 self.assert_packet_checksums_valid(packet)
2468 elif packet.haslayer(UDP):
2469 self.assertEqual(packet[UDP].dport, self.udp_port_in)
2470 self.assertEqual(packet[UDP].sport, server_udp_port)
2472 self.assertEqual(packet[ICMP].id, self.icmp_id_in)
2474 self.logger.error(ppp("Unexpected or invalid packet:", packet))
2477 def test_interface_addr(self):
2478 """ Acquire NAT44 addresses from interface """
2479 self.vapi.nat44_add_del_interface_addr(
2481 sw_if_index=self.pg7.sw_if_index)
2483 # no address in NAT pool
2484 addresses = self.vapi.nat44_address_dump()
2485 self.assertEqual(0, len(addresses))
2487 # configure interface address and check NAT address pool
2488 self.pg7.config_ip4()
2489 addresses = self.vapi.nat44_address_dump()
2490 self.assertEqual(1, len(addresses))
2491 self.assertEqual(str(addresses[0].ip_address), self.pg7.local_ip4)
2493 # remove interface address and check NAT address pool
2494 self.pg7.unconfig_ip4()
2495 addresses = self.vapi.nat44_address_dump()
2496 self.assertEqual(0, len(addresses))
2498 def test_interface_addr_static_mapping(self):
2499 """ Static mapping with addresses from interface """
2502 self.vapi.nat44_add_del_interface_addr(
2504 sw_if_index=self.pg7.sw_if_index)
2505 self.nat44_add_static_mapping(
2507 external_sw_if_index=self.pg7.sw_if_index,
2510 # static mappings with external interface
2511 static_mappings = self.vapi.nat44_static_mapping_dump()
2512 self.assertEqual(1, len(static_mappings))
2513 self.assertEqual(self.pg7.sw_if_index,
2514 static_mappings[0].external_sw_if_index)
2515 self.assertEqual(static_mappings[0].tag, tag)
2517 # configure interface address and check static mappings
2518 self.pg7.config_ip4()
2519 static_mappings = self.vapi.nat44_static_mapping_dump()
2520 self.assertEqual(2, len(static_mappings))
2522 for sm in static_mappings:
2523 if sm.external_sw_if_index == 0xFFFFFFFF:
2524 self.assertEqual(str(sm.external_ip_address),
2526 self.assertEqual(sm.tag, tag)
2528 self.assertTrue(resolved)
2530 # remove interface address and check static mappings
2531 self.pg7.unconfig_ip4()
2532 static_mappings = self.vapi.nat44_static_mapping_dump()
2533 self.assertEqual(1, len(static_mappings))
2534 self.assertEqual(self.pg7.sw_if_index,
2535 static_mappings[0].external_sw_if_index)
2536 self.assertEqual(static_mappings[0].tag, tag)
2538 # configure interface address again and check static mappings
2539 self.pg7.config_ip4()
2540 static_mappings = self.vapi.nat44_static_mapping_dump()
2541 self.assertEqual(2, len(static_mappings))
2543 for sm in static_mappings:
2544 if sm.external_sw_if_index == 0xFFFFFFFF:
2545 self.assertEqual(str(sm.external_ip_address),
2547 self.assertEqual(sm.tag, tag)
2549 self.assertTrue(resolved)
2551 # remove static mapping
2552 self.nat44_add_static_mapping(
2554 external_sw_if_index=self.pg7.sw_if_index,
2557 static_mappings = self.vapi.nat44_static_mapping_dump()
2558 self.assertEqual(0, len(static_mappings))
2560 def test_interface_addr_identity_nat(self):
2561 """ Identity NAT with addresses from interface """
2564 self.vapi.nat44_add_del_interface_addr(
2566 sw_if_index=self.pg7.sw_if_index)
2567 self.vapi.nat44_add_del_identity_mapping(
2569 sw_if_index=self.pg7.sw_if_index,
2571 protocol=IP_PROTOS.tcp,
2574 # identity mappings with external interface
2575 identity_mappings = self.vapi.nat44_identity_mapping_dump()
2576 self.assertEqual(1, len(identity_mappings))
2577 self.assertEqual(self.pg7.sw_if_index,
2578 identity_mappings[0].sw_if_index)
2580 # configure interface address and check identity mappings
2581 self.pg7.config_ip4()
2582 identity_mappings = self.vapi.nat44_identity_mapping_dump()
2584 self.assertEqual(2, len(identity_mappings))
2585 for sm in identity_mappings:
2586 if sm.sw_if_index == 0xFFFFFFFF:
2587 self.assertEqual(str(identity_mappings[0].ip_address),
2589 self.assertEqual(port, identity_mappings[0].port)
2590 self.assertEqual(IP_PROTOS.tcp, identity_mappings[0].protocol)
2592 self.assertTrue(resolved)
2594 # remove interface address and check identity mappings
2595 self.pg7.unconfig_ip4()
2596 identity_mappings = self.vapi.nat44_identity_mapping_dump()
2597 self.assertEqual(1, len(identity_mappings))
2598 self.assertEqual(self.pg7.sw_if_index,
2599 identity_mappings[0].sw_if_index)
2601 def test_ipfix_nat44_sess(self):
2602 """ IPFIX logging NAT44 session created/deleted """
2603 self.ipfix_domain_id = 10
2604 self.ipfix_src_port = 20202
2605 collector_port = 30303
2606 bind_layers(UDP, IPFIX, dport=30303)
2607 self.nat44_add_address(self.nat_addr)
2608 flags = self.config_flags.NAT_IS_INSIDE
2609 self.vapi.nat44_interface_add_del_feature(
2610 sw_if_index=self.pg0.sw_if_index,
2611 flags=flags, is_add=1)
2612 self.vapi.nat44_interface_add_del_feature(
2613 sw_if_index=self.pg1.sw_if_index,
2615 self.vapi.set_ipfix_exporter(collector_address=self.pg3.remote_ip4,
2616 src_address=self.pg3.local_ip4,
2618 template_interval=10,
2619 collector_port=collector_port)
2620 self.vapi.nat_ipfix_enable_disable(domain_id=self.ipfix_domain_id,
2621 src_port=self.ipfix_src_port,
2624 pkts = self.create_stream_in(self.pg0, self.pg1)
2625 self.pg0.add_stream(pkts)
2626 self.pg_enable_capture(self.pg_interfaces)
2628 capture = self.pg1.get_capture(len(pkts))
2629 self.verify_capture_out(capture)
2630 self.nat44_add_address(self.nat_addr, is_add=0)
2631 self.vapi.ipfix_flush()
2632 capture = self.pg3.get_capture(7)
2633 ipfix = IPFIXDecoder()
2634 # first load template
2636 self.assertTrue(p.haslayer(IPFIX))
2637 self.assertEqual(p[IP].src, self.pg3.local_ip4)
2638 self.assertEqual(p[IP].dst, self.pg3.remote_ip4)
2639 self.assertEqual(p[UDP].sport, self.ipfix_src_port)
2640 self.assertEqual(p[UDP].dport, collector_port)
2641 self.assertEqual(p[IPFIX].observationDomainID,
2642 self.ipfix_domain_id)
2643 if p.haslayer(Template):
2644 ipfix.add_template(p.getlayer(Template))
2645 # verify events in data set
2647 if p.haslayer(Data):
2648 data = ipfix.decode_data_set(p.getlayer(Set))
2649 self.verify_ipfix_nat44_ses(data)
2651 def test_ipfix_addr_exhausted(self):
2652 """ IPFIX logging NAT addresses exhausted """
2653 flags = self.config_flags.NAT_IS_INSIDE
2654 self.vapi.nat44_interface_add_del_feature(
2655 sw_if_index=self.pg0.sw_if_index,
2656 flags=flags, is_add=1)
2657 self.vapi.nat44_interface_add_del_feature(
2658 sw_if_index=self.pg1.sw_if_index,
2660 self.vapi.set_ipfix_exporter(collector_address=self.pg3.remote_ip4,
2661 src_address=self.pg3.local_ip4,
2663 template_interval=10)
2664 self.vapi.nat_ipfix_enable_disable(domain_id=self.ipfix_domain_id,
2665 src_port=self.ipfix_src_port,
2668 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
2669 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
2671 self.pg0.add_stream(p)
2672 self.pg_enable_capture(self.pg_interfaces)
2674 self.pg1.assert_nothing_captured()
2676 self.vapi.ipfix_flush()
2677 capture = self.pg3.get_capture(7)
2678 ipfix = IPFIXDecoder()
2679 # first load template
2681 self.assertTrue(p.haslayer(IPFIX))
2682 self.assertEqual(p[IP].src, self.pg3.local_ip4)
2683 self.assertEqual(p[IP].dst, self.pg3.remote_ip4)
2684 self.assertEqual(p[UDP].sport, self.ipfix_src_port)
2685 self.assertEqual(p[UDP].dport, 4739)
2686 self.assertEqual(p[IPFIX].observationDomainID,
2687 self.ipfix_domain_id)
2688 if p.haslayer(Template):
2689 ipfix.add_template(p.getlayer(Template))
2690 # verify events in data set
2692 if p.haslayer(Data):
2693 data = ipfix.decode_data_set(p.getlayer(Set))
2694 self.verify_ipfix_addr_exhausted(data)
2696 @unittest.skipUnless(running_extended_tests, "part of extended tests")
2697 def test_ipfix_max_sessions(self):
2698 """ IPFIX logging maximum session entries exceeded """
2699 self.nat44_add_address(self.nat_addr)
2700 flags = self.config_flags.NAT_IS_INSIDE
2701 self.vapi.nat44_interface_add_del_feature(
2702 sw_if_index=self.pg0.sw_if_index,
2703 flags=flags, is_add=1)
2704 self.vapi.nat44_interface_add_del_feature(
2705 sw_if_index=self.pg1.sw_if_index,
2708 max_sessions = self.max_translations
2711 for i in range(0, max_sessions):
2712 src = "10.10.%u.%u" % ((i & 0xFF00) >> 8, i & 0xFF)
2713 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2714 IP(src=src, dst=self.pg1.remote_ip4) /
2717 self.pg0.add_stream(pkts)
2718 self.pg_enable_capture(self.pg_interfaces)
2721 self.pg1.get_capture(max_sessions)
2722 self.vapi.set_ipfix_exporter(collector_address=self.pg3.remote_ip4,
2723 src_address=self.pg3.local_ip4,
2725 template_interval=10)
2726 self.vapi.nat_ipfix_enable_disable(domain_id=self.ipfix_domain_id,
2727 src_port=self.ipfix_src_port,
2730 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2731 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
2733 self.pg0.add_stream(p)
2734 self.pg_enable_capture(self.pg_interfaces)
2736 self.pg1.assert_nothing_captured()
2738 self.vapi.ipfix_flush()
2739 capture = self.pg3.get_capture(7)
2740 ipfix = IPFIXDecoder()
2741 # first load template
2743 self.assertTrue(p.haslayer(IPFIX))
2744 self.assertEqual(p[IP].src, self.pg3.local_ip4)
2745 self.assertEqual(p[IP].dst, self.pg3.remote_ip4)
2746 self.assertEqual(p[UDP].sport, self.ipfix_src_port)
2747 self.assertEqual(p[UDP].dport, 4739)
2748 self.assertEqual(p[IPFIX].observationDomainID,
2749 self.ipfix_domain_id)
2750 if p.haslayer(Template):
2751 ipfix.add_template(p.getlayer(Template))
2752 # verify events in data set
2754 if p.haslayer(Data):
2755 data = ipfix.decode_data_set(p.getlayer(Set))
2756 self.verify_ipfix_max_sessions(data, max_sessions)
2758 def test_syslog_apmap(self):
2759 """ Test syslog address and port mapping creation and deletion """
2760 self.vapi.syslog_set_filter(
2761 self.SYSLOG_SEVERITY.SYSLOG_API_SEVERITY_INFO)
2762 self.vapi.syslog_set_sender(self.pg3.local_ip4, self.pg3.remote_ip4)
2763 self.nat44_add_address(self.nat_addr)
2764 flags = self.config_flags.NAT_IS_INSIDE
2765 self.vapi.nat44_interface_add_del_feature(
2766 sw_if_index=self.pg0.sw_if_index,
2767 flags=flags, is_add=1)
2768 self.vapi.nat44_interface_add_del_feature(
2769 sw_if_index=self.pg1.sw_if_index,
2772 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2773 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
2774 TCP(sport=self.tcp_port_in, dport=20))
2775 self.pg0.add_stream(p)
2776 self.pg_enable_capture(self.pg_interfaces)
2778 capture = self.pg1.get_capture(1)
2779 self.tcp_port_out = capture[0][TCP].sport
2780 capture = self.pg3.get_capture(1)
2781 self.verify_syslog_apmap(capture[0][Raw].load)
2783 self.pg_enable_capture(self.pg_interfaces)
2785 self.nat44_add_address(self.nat_addr, is_add=0)
2786 capture = self.pg3.get_capture(1)
2787 self.verify_syslog_apmap(capture[0][Raw].load, False)
2789 def test_pool_addr_fib(self):
2790 """ NAT44 add pool addresses to FIB """
2791 static_addr = '10.0.0.10'
2792 self.nat44_add_address(self.nat_addr)
2793 flags = self.config_flags.NAT_IS_INSIDE
2794 self.vapi.nat44_interface_add_del_feature(
2795 sw_if_index=self.pg0.sw_if_index,
2796 flags=flags, is_add=1)
2797 self.vapi.nat44_interface_add_del_feature(
2798 sw_if_index=self.pg1.sw_if_index,
2800 self.nat44_add_static_mapping(self.pg0.remote_ip4, static_addr)
2803 p = (Ether(src=self.pg1.remote_mac, dst='ff:ff:ff:ff:ff:ff') /
2804 ARP(op=ARP.who_has, pdst=self.nat_addr,
2805 psrc=self.pg1.remote_ip4, hwsrc=self.pg1.remote_mac))
2806 self.pg1.add_stream(p)
2807 self.pg_enable_capture(self.pg_interfaces)
2809 capture = self.pg1.get_capture(1)
2810 self.assertTrue(capture[0].haslayer(ARP))
2811 self.assertTrue(capture[0][ARP].op, ARP.is_at)
2814 p = (Ether(src=self.pg1.remote_mac, dst='ff:ff:ff:ff:ff:ff') /
2815 ARP(op=ARP.who_has, pdst=static_addr,
2816 psrc=self.pg1.remote_ip4, hwsrc=self.pg1.remote_mac))
2817 self.pg1.add_stream(p)
2818 self.pg_enable_capture(self.pg_interfaces)
2820 capture = self.pg1.get_capture(1)
2821 self.assertTrue(capture[0].haslayer(ARP))
2822 self.assertTrue(capture[0][ARP].op, ARP.is_at)
2824 # send ARP to non-NAT44 interface
2825 p = (Ether(src=self.pg2.remote_mac, dst='ff:ff:ff:ff:ff:ff') /
2826 ARP(op=ARP.who_has, pdst=self.nat_addr,
2827 psrc=self.pg2.remote_ip4, hwsrc=self.pg2.remote_mac))
2828 self.pg2.add_stream(p)
2829 self.pg_enable_capture(self.pg_interfaces)
2831 self.pg1.assert_nothing_captured()
2833 # remove addresses and verify
2834 self.nat44_add_address(self.nat_addr, is_add=0)
2835 self.nat44_add_static_mapping(self.pg0.remote_ip4, static_addr,
2838 p = (Ether(src=self.pg1.remote_mac, dst='ff:ff:ff:ff:ff:ff') /
2839 ARP(op=ARP.who_has, pdst=self.nat_addr,
2840 psrc=self.pg1.remote_ip4, hwsrc=self.pg1.remote_mac))
2841 self.pg1.add_stream(p)
2842 self.pg_enable_capture(self.pg_interfaces)
2844 self.pg1.assert_nothing_captured()
2846 p = (Ether(src=self.pg1.remote_mac, dst='ff:ff:ff:ff:ff:ff') /
2847 ARP(op=ARP.who_has, pdst=static_addr,
2848 psrc=self.pg1.remote_ip4, hwsrc=self.pg1.remote_mac))
2849 self.pg1.add_stream(p)
2850 self.pg_enable_capture(self.pg_interfaces)
2852 self.pg1.assert_nothing_captured()
2854 def test_vrf_mode(self):
2855 """ NAT44 tenant VRF aware address pool mode """
2859 nat_ip1 = "10.0.0.10"
2860 nat_ip2 = "10.0.0.11"
2862 self.pg0.unconfig_ip4()
2863 self.pg1.unconfig_ip4()
2864 self.vapi.ip_table_add_del(is_add=1, table={'table_id': vrf_id1})
2865 self.vapi.ip_table_add_del(is_add=1, table={'table_id': vrf_id2})
2866 self.pg0.set_table_ip4(vrf_id1)
2867 self.pg1.set_table_ip4(vrf_id2)
2868 self.pg0.config_ip4()
2869 self.pg1.config_ip4()
2870 self.pg0.resolve_arp()
2871 self.pg1.resolve_arp()
2873 self.nat44_add_address(nat_ip1, vrf_id=vrf_id1)
2874 self.nat44_add_address(nat_ip2, vrf_id=vrf_id2)
2875 flags = self.config_flags.NAT_IS_INSIDE
2876 self.vapi.nat44_interface_add_del_feature(
2877 sw_if_index=self.pg0.sw_if_index,
2878 flags=flags, is_add=1)
2879 self.vapi.nat44_interface_add_del_feature(
2880 sw_if_index=self.pg1.sw_if_index,
2881 flags=flags, is_add=1)
2882 self.vapi.nat44_interface_add_del_feature(
2883 sw_if_index=self.pg2.sw_if_index,
2888 pkts = self.create_stream_in(self.pg0, self.pg2)
2889 self.pg0.add_stream(pkts)
2890 self.pg_enable_capture(self.pg_interfaces)
2892 capture = self.pg2.get_capture(len(pkts))
2893 self.verify_capture_out(capture, nat_ip1)
2896 pkts = self.create_stream_in(self.pg1, self.pg2)
2897 self.pg1.add_stream(pkts)
2898 self.pg_enable_capture(self.pg_interfaces)
2900 capture = self.pg2.get_capture(len(pkts))
2901 self.verify_capture_out(capture, nat_ip2)
2904 self.pg0.unconfig_ip4()
2905 self.pg1.unconfig_ip4()
2906 self.pg0.set_table_ip4(0)
2907 self.pg1.set_table_ip4(0)
2908 self.pg0.config_ip4()
2909 self.pg1.config_ip4()
2910 self.pg0.resolve_arp()
2911 self.pg1.resolve_arp()
2912 self.vapi.ip_table_add_del(is_add=0, table={'table_id': vrf_id1})
2913 self.vapi.ip_table_add_del(is_add=0, table={'table_id': vrf_id2})
2915 def test_vrf_feature_independent(self):
2916 """ NAT44 tenant VRF independent address pool mode """
2918 nat_ip1 = "10.0.0.10"
2919 nat_ip2 = "10.0.0.11"
2921 self.nat44_add_address(nat_ip1)
2922 self.nat44_add_address(nat_ip2, vrf_id=99)
2923 flags = self.config_flags.NAT_IS_INSIDE
2924 self.vapi.nat44_interface_add_del_feature(
2925 sw_if_index=self.pg0.sw_if_index,
2926 flags=flags, is_add=1)
2927 self.vapi.nat44_interface_add_del_feature(
2928 sw_if_index=self.pg1.sw_if_index,
2929 flags=flags, is_add=1)
2930 self.vapi.nat44_interface_add_del_feature(
2931 sw_if_index=self.pg2.sw_if_index,
2935 pkts = self.create_stream_in(self.pg0, self.pg2)
2936 self.pg0.add_stream(pkts)
2937 self.pg_enable_capture(self.pg_interfaces)
2939 capture = self.pg2.get_capture(len(pkts))
2940 self.verify_capture_out(capture, nat_ip1)
2943 pkts = self.create_stream_in(self.pg1, self.pg2)
2944 self.pg1.add_stream(pkts)
2945 self.pg_enable_capture(self.pg_interfaces)
2947 capture = self.pg2.get_capture(len(pkts))
2948 self.verify_capture_out(capture, nat_ip1)
2950 def create_routes_and_neigbors(self):
2951 r1 = VppIpRoute(self, self.pg7.remote_ip4, 32,
2952 [VppRoutePath(self.pg7.remote_ip4,
2953 self.pg7.sw_if_index)])
2954 r2 = VppIpRoute(self, self.pg8.remote_ip4, 32,
2955 [VppRoutePath(self.pg8.remote_ip4,
2956 self.pg8.sw_if_index)])
2960 n1 = VppNeighbor(self,
2961 self.pg7.sw_if_index,
2962 self.pg7.remote_mac,
2963 self.pg7.remote_ip4,
2965 n2 = VppNeighbor(self,
2966 self.pg8.sw_if_index,
2967 self.pg8.remote_mac,
2968 self.pg8.remote_ip4,
2973 def test_dynamic_ipless_interfaces(self):
2974 """ NAT44 interfaces without configured IP address """
2975 self.create_routes_and_neigbors()
2976 self.nat44_add_address(self.nat_addr)
2977 flags = self.config_flags.NAT_IS_INSIDE
2978 self.vapi.nat44_interface_add_del_feature(
2979 sw_if_index=self.pg7.sw_if_index,
2980 flags=flags, is_add=1)
2981 self.vapi.nat44_interface_add_del_feature(
2982 sw_if_index=self.pg8.sw_if_index,
2986 pkts = self.create_stream_in(self.pg7, self.pg8)
2987 self.pg7.add_stream(pkts)
2988 self.pg_enable_capture(self.pg_interfaces)
2990 capture = self.pg8.get_capture(len(pkts))
2991 self.verify_capture_out(capture)
2994 pkts = self.create_stream_out(self.pg8, self.nat_addr)
2995 self.pg8.add_stream(pkts)
2996 self.pg_enable_capture(self.pg_interfaces)
2998 capture = self.pg7.get_capture(len(pkts))
2999 self.verify_capture_in(capture, self.pg7)
3001 def test_static_ipless_interfaces(self):
3002 """ NAT44 interfaces without configured IP address - 1:1 NAT """
3004 self.create_routes_and_neigbors()
3005 self.nat44_add_static_mapping(self.pg7.remote_ip4, self.nat_addr)
3006 flags = self.config_flags.NAT_IS_INSIDE
3007 self.vapi.nat44_interface_add_del_feature(
3008 sw_if_index=self.pg7.sw_if_index,
3009 flags=flags, is_add=1)
3010 self.vapi.nat44_interface_add_del_feature(
3011 sw_if_index=self.pg8.sw_if_index,
3015 pkts = self.create_stream_out(self.pg8)
3016 self.pg8.add_stream(pkts)
3017 self.pg_enable_capture(self.pg_interfaces)
3019 capture = self.pg7.get_capture(len(pkts))
3020 self.verify_capture_in(capture, self.pg7)
3023 pkts = self.create_stream_in(self.pg7, self.pg8)
3024 self.pg7.add_stream(pkts)
3025 self.pg_enable_capture(self.pg_interfaces)
3027 capture = self.pg8.get_capture(len(pkts))
3028 self.verify_capture_out(capture, self.nat_addr, True)
3030 def test_static_with_port_ipless_interfaces(self):
3031 """ NAT44 interfaces without configured IP address - 1:1 NAPT """
3033 self.tcp_port_out = 30606
3034 self.udp_port_out = 30607
3035 self.icmp_id_out = 30608
3037 self.create_routes_and_neigbors()
3038 self.nat44_add_address(self.nat_addr)
3039 self.nat44_add_static_mapping(self.pg7.remote_ip4, self.nat_addr,
3040 self.tcp_port_in, self.tcp_port_out,
3041 proto=IP_PROTOS.tcp)
3042 self.nat44_add_static_mapping(self.pg7.remote_ip4, self.nat_addr,
3043 self.udp_port_in, self.udp_port_out,
3044 proto=IP_PROTOS.udp)
3045 self.nat44_add_static_mapping(self.pg7.remote_ip4, self.nat_addr,
3046 self.icmp_id_in, self.icmp_id_out,
3047 proto=IP_PROTOS.icmp)
3048 flags = self.config_flags.NAT_IS_INSIDE
3049 self.vapi.nat44_interface_add_del_feature(
3050 sw_if_index=self.pg7.sw_if_index,
3051 flags=flags, is_add=1)
3052 self.vapi.nat44_interface_add_del_feature(
3053 sw_if_index=self.pg8.sw_if_index,
3057 pkts = self.create_stream_out(self.pg8)
3058 self.pg8.add_stream(pkts)
3059 self.pg_enable_capture(self.pg_interfaces)
3061 capture = self.pg7.get_capture(len(pkts))
3062 self.verify_capture_in(capture, self.pg7)
3065 pkts = self.create_stream_in(self.pg7, self.pg8)
3066 self.pg7.add_stream(pkts)
3067 self.pg_enable_capture(self.pg_interfaces)
3069 capture = self.pg8.get_capture(len(pkts))
3070 self.verify_capture_out(capture)
3072 def test_static_unknown_proto(self):
3073 """ 1:1 NAT translate packet with unknown protocol """
3074 nat_ip = "10.0.0.10"
3075 self.nat44_add_static_mapping(self.pg0.remote_ip4, nat_ip)
3076 flags = self.config_flags.NAT_IS_INSIDE
3077 self.vapi.nat44_interface_add_del_feature(
3078 sw_if_index=self.pg0.sw_if_index,
3079 flags=flags, is_add=1)
3080 self.vapi.nat44_interface_add_del_feature(
3081 sw_if_index=self.pg1.sw_if_index,
3085 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
3086 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
3088 IP(src=self.pg2.remote_ip4, dst=self.pg3.remote_ip4) /
3089 TCP(sport=1234, dport=1234))
3090 self.pg0.add_stream(p)
3091 self.pg_enable_capture(self.pg_interfaces)
3093 p = self.pg1.get_capture(1)
3096 self.assertEqual(packet[IP].src, nat_ip)
3097 self.assertEqual(packet[IP].dst, self.pg1.remote_ip4)
3098 self.assertEqual(packet.haslayer(GRE), 1)
3099 self.assert_packet_checksums_valid(packet)
3101 self.logger.error(ppp("Unexpected or invalid packet:", packet))
3105 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
3106 IP(src=self.pg1.remote_ip4, dst=nat_ip) /
3108 IP(src=self.pg3.remote_ip4, dst=self.pg2.remote_ip4) /
3109 TCP(sport=1234, dport=1234))
3110 self.pg1.add_stream(p)
3111 self.pg_enable_capture(self.pg_interfaces)
3113 p = self.pg0.get_capture(1)
3116 self.assertEqual(packet[IP].src, self.pg1.remote_ip4)
3117 self.assertEqual(packet[IP].dst, self.pg0.remote_ip4)
3118 self.assertEqual(packet.haslayer(GRE), 1)
3119 self.assert_packet_checksums_valid(packet)
3121 self.logger.error(ppp("Unexpected or invalid packet:", packet))
3124 def test_hairpinning_static_unknown_proto(self):
3125 """ 1:1 NAT translate packet with unknown protocol - hairpinning """
3127 host = self.pg0.remote_hosts[0]
3128 server = self.pg0.remote_hosts[1]
3130 host_nat_ip = "10.0.0.10"
3131 server_nat_ip = "10.0.0.11"
3133 self.nat44_add_static_mapping(host.ip4, host_nat_ip)
3134 self.nat44_add_static_mapping(server.ip4, server_nat_ip)
3135 flags = self.config_flags.NAT_IS_INSIDE
3136 self.vapi.nat44_interface_add_del_feature(
3137 sw_if_index=self.pg0.sw_if_index,
3138 flags=flags, is_add=1)
3139 self.vapi.nat44_interface_add_del_feature(
3140 sw_if_index=self.pg1.sw_if_index,
3144 p = (Ether(dst=self.pg0.local_mac, src=host.mac) /
3145 IP(src=host.ip4, dst=server_nat_ip) /
3147 IP(src=self.pg2.remote_ip4, dst=self.pg3.remote_ip4) /
3148 TCP(sport=1234, dport=1234))
3149 self.pg0.add_stream(p)
3150 self.pg_enable_capture(self.pg_interfaces)
3152 p = self.pg0.get_capture(1)
3155 self.assertEqual(packet[IP].src, host_nat_ip)
3156 self.assertEqual(packet[IP].dst, server.ip4)
3157 self.assertEqual(packet.haslayer(GRE), 1)
3158 self.assert_packet_checksums_valid(packet)
3160 self.logger.error(ppp("Unexpected or invalid packet:", packet))
3164 p = (Ether(dst=self.pg0.local_mac, src=server.mac) /
3165 IP(src=server.ip4, dst=host_nat_ip) /
3167 IP(src=self.pg3.remote_ip4, dst=self.pg2.remote_ip4) /
3168 TCP(sport=1234, dport=1234))
3169 self.pg0.add_stream(p)
3170 self.pg_enable_capture(self.pg_interfaces)
3172 p = self.pg0.get_capture(1)
3175 self.assertEqual(packet[IP].src, server_nat_ip)
3176 self.assertEqual(packet[IP].dst, host.ip4)
3177 self.assertEqual(packet.haslayer(GRE), 1)
3178 self.assert_packet_checksums_valid(packet)
3180 self.logger.error(ppp("Unexpected or invalid packet:", packet))
3183 def test_output_feature(self):
3184 """ NAT44 interface output feature (in2out postrouting) """
3185 self.nat44_add_address(self.nat_addr)
3186 flags = self.config_flags.NAT_IS_INSIDE
3187 self.vapi.nat44_interface_add_del_output_feature(
3188 is_add=1, flags=flags,
3189 sw_if_index=self.pg0.sw_if_index)
3190 self.vapi.nat44_interface_add_del_output_feature(
3191 is_add=1, flags=flags,
3192 sw_if_index=self.pg1.sw_if_index)
3193 self.vapi.nat44_interface_add_del_output_feature(
3195 sw_if_index=self.pg3.sw_if_index)
3198 pkts = self.create_stream_in(self.pg0, self.pg3)
3199 self.pg0.add_stream(pkts)
3200 self.pg_enable_capture(self.pg_interfaces)
3202 capture = self.pg3.get_capture(len(pkts))
3203 self.verify_capture_out(capture)
3206 pkts = self.create_stream_out(self.pg3)
3207 self.pg3.add_stream(pkts)
3208 self.pg_enable_capture(self.pg_interfaces)
3210 capture = self.pg0.get_capture(len(pkts))
3211 self.verify_capture_in(capture, self.pg0)
3213 # from non-NAT interface to NAT inside interface
3214 pkts = self.create_stream_in(self.pg2, self.pg0)
3215 self.pg2.add_stream(pkts)
3216 self.pg_enable_capture(self.pg_interfaces)
3218 capture = self.pg0.get_capture(len(pkts))
3219 self.verify_capture_no_translation(capture, self.pg2, self.pg0)
3221 def test_output_feature_vrf_aware(self):
3222 """ NAT44 interface output feature VRF aware (in2out postrouting) """
3223 nat_ip_vrf10 = "10.0.0.10"
3224 nat_ip_vrf20 = "10.0.0.20"
3226 r1 = VppIpRoute(self, self.pg3.remote_ip4, 32,
3227 [VppRoutePath(self.pg3.remote_ip4,
3228 self.pg3.sw_if_index)],
3230 r2 = VppIpRoute(self, self.pg3.remote_ip4, 32,
3231 [VppRoutePath(self.pg3.remote_ip4,
3232 self.pg3.sw_if_index)],
3237 self.nat44_add_address(nat_ip_vrf10, vrf_id=10)
3238 self.nat44_add_address(nat_ip_vrf20, vrf_id=20)
3239 flags = self.config_flags.NAT_IS_INSIDE
3240 self.vapi.nat44_interface_add_del_output_feature(
3241 is_add=1, flags=flags,
3242 sw_if_index=self.pg4.sw_if_index)
3243 self.vapi.nat44_interface_add_del_output_feature(
3244 is_add=1, flags=flags,
3245 sw_if_index=self.pg6.sw_if_index)
3246 self.vapi.nat44_interface_add_del_output_feature(
3248 sw_if_index=self.pg3.sw_if_index)
3251 pkts = self.create_stream_in(self.pg4, self.pg3)
3252 self.pg4.add_stream(pkts)
3253 self.pg_enable_capture(self.pg_interfaces)
3255 capture = self.pg3.get_capture(len(pkts))
3256 self.verify_capture_out(capture, nat_ip=nat_ip_vrf10)
3259 pkts = self.create_stream_out(self.pg3, dst_ip=nat_ip_vrf10)
3260 self.pg3.add_stream(pkts)
3261 self.pg_enable_capture(self.pg_interfaces)
3263 capture = self.pg4.get_capture(len(pkts))
3264 self.verify_capture_in(capture, self.pg4)
3267 pkts = self.create_stream_in(self.pg6, self.pg3)
3268 self.pg6.add_stream(pkts)
3269 self.pg_enable_capture(self.pg_interfaces)
3271 capture = self.pg3.get_capture(len(pkts))
3272 self.verify_capture_out(capture, nat_ip=nat_ip_vrf20)
3275 pkts = self.create_stream_out(self.pg3, dst_ip=nat_ip_vrf20)
3276 self.pg3.add_stream(pkts)
3277 self.pg_enable_capture(self.pg_interfaces)
3279 capture = self.pg6.get_capture(len(pkts))
3280 self.verify_capture_in(capture, self.pg6)
3282 def test_output_feature_hairpinning(self):
3283 """ NAT44 interface output feature hairpinning (in2out postrouting) """
3284 host = self.pg0.remote_hosts[0]
3285 server = self.pg0.remote_hosts[1]
3288 server_in_port = 5678
3289 server_out_port = 8765
3291 self.nat44_add_address(self.nat_addr)
3292 flags = self.config_flags.NAT_IS_INSIDE
3293 self.vapi.nat44_interface_add_del_output_feature(
3294 is_add=1, flags=flags,
3295 sw_if_index=self.pg0.sw_if_index)
3296 self.vapi.nat44_interface_add_del_output_feature(
3298 sw_if_index=self.pg1.sw_if_index)
3300 # add static mapping for server
3301 self.nat44_add_static_mapping(server.ip4, self.nat_addr,
3302 server_in_port, server_out_port,
3303 proto=IP_PROTOS.tcp)
3305 # send packet from host to server
3306 p = (Ether(src=host.mac, dst=self.pg0.local_mac) /
3307 IP(src=host.ip4, dst=self.nat_addr) /
3308 TCP(sport=host_in_port, dport=server_out_port))
3309 self.pg0.add_stream(p)
3310 self.pg_enable_capture(self.pg_interfaces)
3312 capture = self.pg0.get_capture(1)
3317 self.assertEqual(ip.src, self.nat_addr)
3318 self.assertEqual(ip.dst, server.ip4)
3319 self.assertNotEqual(tcp.sport, host_in_port)
3320 self.assertEqual(tcp.dport, server_in_port)
3321 self.assert_packet_checksums_valid(p)
3322 host_out_port = tcp.sport
3324 self.logger.error(ppp("Unexpected or invalid packet:", p))
3327 # send reply from server to host
3328 p = (Ether(src=server.mac, dst=self.pg0.local_mac) /
3329 IP(src=server.ip4, dst=self.nat_addr) /
3330 TCP(sport=server_in_port, dport=host_out_port))
3331 self.pg0.add_stream(p)
3332 self.pg_enable_capture(self.pg_interfaces)
3334 capture = self.pg0.get_capture(1)
3339 self.assertEqual(ip.src, self.nat_addr)
3340 self.assertEqual(ip.dst, host.ip4)
3341 self.assertEqual(tcp.sport, server_out_port)
3342 self.assertEqual(tcp.dport, host_in_port)
3343 self.assert_packet_checksums_valid(p)
3345 self.logger.error(ppp("Unexpected or invalid packet:", p))
3348 def test_one_armed_nat44(self):
3349 """ One armed NAT44 """
3350 remote_host = self.pg9.remote_hosts[0]
3351 local_host = self.pg9.remote_hosts[1]
3354 self.nat44_add_address(self.nat_addr)
3355 flags = self.config_flags.NAT_IS_INSIDE
3356 self.vapi.nat44_interface_add_del_feature(
3357 sw_if_index=self.pg9.sw_if_index,
3359 self.vapi.nat44_interface_add_del_feature(
3360 sw_if_index=self.pg9.sw_if_index,
3361 flags=flags, is_add=1)
3364 p = (Ether(src=self.pg9.remote_mac, dst=self.pg9.local_mac) /
3365 IP(src=local_host.ip4, dst=remote_host.ip4) /
3366 TCP(sport=12345, dport=80))
3367 self.pg9.add_stream(p)
3368 self.pg_enable_capture(self.pg_interfaces)
3370 capture = self.pg9.get_capture(1)
3375 self.assertEqual(ip.src, self.nat_addr)
3376 self.assertEqual(ip.dst, remote_host.ip4)
3377 self.assertNotEqual(tcp.sport, 12345)
3378 external_port = tcp.sport
3379 self.assertEqual(tcp.dport, 80)
3380 self.assert_packet_checksums_valid(p)
3382 self.logger.error(ppp("Unexpected or invalid packet:", p))
3386 p = (Ether(src=self.pg9.remote_mac, dst=self.pg9.local_mac) /
3387 IP(src=remote_host.ip4, dst=self.nat_addr) /
3388 TCP(sport=80, dport=external_port))
3389 self.pg9.add_stream(p)
3390 self.pg_enable_capture(self.pg_interfaces)
3392 capture = self.pg9.get_capture(1)
3397 self.assertEqual(ip.src, remote_host.ip4)
3398 self.assertEqual(ip.dst, local_host.ip4)
3399 self.assertEqual(tcp.sport, 80)
3400 self.assertEqual(tcp.dport, 12345)
3401 self.assert_packet_checksums_valid(p)
3403 self.logger.error(ppp("Unexpected or invalid packet:", p))
3406 err = self.statistics.get_err_counter(
3407 '/err/nat44-classify/next in2out')
3408 self.assertEqual(err, 1)
3409 err = self.statistics.get_err_counter(
3410 '/err/nat44-classify/next out2in')
3411 self.assertEqual(err, 1)
3413 def test_del_session(self):
3414 """ Delete NAT44 session """
3415 self.nat44_add_address(self.nat_addr)
3416 flags = self.config_flags.NAT_IS_INSIDE
3417 self.vapi.nat44_interface_add_del_feature(
3418 sw_if_index=self.pg0.sw_if_index,
3419 flags=flags, is_add=1)
3420 self.vapi.nat44_interface_add_del_feature(
3421 sw_if_index=self.pg1.sw_if_index,
3424 pkts = self.create_stream_in(self.pg0, self.pg1)
3425 self.pg0.add_stream(pkts)
3426 self.pg_enable_capture(self.pg_interfaces)
3428 self.pg1.get_capture(len(pkts))
3430 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4, 0)
3431 nsessions = len(sessions)
3433 self.vapi.nat44_del_session(address=sessions[0].inside_ip_address,
3434 port=sessions[0].inside_port,
3435 protocol=sessions[0].protocol,
3436 flags=self.config_flags.NAT_IS_INSIDE)
3437 self.vapi.nat44_del_session(address=sessions[1].outside_ip_address,
3438 port=sessions[1].outside_port,
3439 protocol=sessions[1].protocol)
3441 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4, 0)
3442 self.assertEqual(nsessions - len(sessions), 2)
3444 self.vapi.nat44_del_session(address=sessions[0].inside_ip_address,
3445 port=sessions[0].inside_port,
3446 protocol=sessions[0].protocol,
3447 flags=self.config_flags.NAT_IS_INSIDE)
3449 self.verify_no_nat44_user()
3451 def test_frag_in_order(self):
3452 """ NAT44 translate fragments arriving in order """
3454 self.nat44_add_address(self.nat_addr)
3455 flags = self.config_flags.NAT_IS_INSIDE
3456 self.vapi.nat44_interface_add_del_feature(
3457 sw_if_index=self.pg0.sw_if_index,
3458 flags=flags, is_add=1)
3459 self.vapi.nat44_interface_add_del_feature(
3460 sw_if_index=self.pg1.sw_if_index,
3463 self.frag_in_order(proto=IP_PROTOS.tcp)
3464 self.frag_in_order(proto=IP_PROTOS.udp)
3465 self.frag_in_order(proto=IP_PROTOS.icmp)
3467 def test_frag_forwarding(self):
3468 """ NAT44 forwarding fragment test """
3469 self.vapi.nat44_add_del_interface_addr(
3471 sw_if_index=self.pg1.sw_if_index)
3472 flags = self.config_flags.NAT_IS_INSIDE
3473 self.vapi.nat44_interface_add_del_feature(
3474 sw_if_index=self.pg0.sw_if_index,
3475 flags=flags, is_add=1)
3476 self.vapi.nat44_interface_add_del_feature(
3477 sw_if_index=self.pg1.sw_if_index,
3479 self.vapi.nat44_forwarding_enable_disable(enable=1)
3481 data = b"A" * 16 + b"B" * 16 + b"C" * 3
3482 pkts = self.create_stream_frag(self.pg1,
3483 self.pg0.remote_ip4,
3487 proto=IP_PROTOS.udp)
3488 self.pg1.add_stream(pkts)
3489 self.pg_enable_capture(self.pg_interfaces)
3491 frags = self.pg0.get_capture(len(pkts))
3492 p = self.reass_frags_and_verify(frags,
3493 self.pg1.remote_ip4,
3494 self.pg0.remote_ip4)
3495 self.assertEqual(p[UDP].sport, 4789)
3496 self.assertEqual(p[UDP].dport, 4789)
3497 self.assertEqual(data, p[Raw].load)
3499 def test_reass_hairpinning(self):
3500 """ NAT44 fragments hairpinning """
3502 self.server = self.pg0.remote_hosts[1]
3503 self.host_in_port = random.randint(1025, 65535)
3504 self.server_in_port = random.randint(1025, 65535)
3505 self.server_out_port = random.randint(1025, 65535)
3507 self.nat44_add_address(self.nat_addr)
3508 flags = self.config_flags.NAT_IS_INSIDE
3509 self.vapi.nat44_interface_add_del_feature(
3510 sw_if_index=self.pg0.sw_if_index,
3511 flags=flags, is_add=1)
3512 self.vapi.nat44_interface_add_del_feature(
3513 sw_if_index=self.pg1.sw_if_index,
3515 # add static mapping for server
3516 self.nat44_add_static_mapping(self.server.ip4, self.nat_addr,
3517 self.server_in_port,
3518 self.server_out_port,
3519 proto=IP_PROTOS.tcp)
3520 self.nat44_add_static_mapping(self.server.ip4, self.nat_addr,
3521 self.server_in_port,
3522 self.server_out_port,
3523 proto=IP_PROTOS.udp)
3524 self.nat44_add_static_mapping(self.server.ip4, self.nat_addr)
3526 self.reass_hairpinning(proto=IP_PROTOS.tcp)
3527 self.reass_hairpinning(proto=IP_PROTOS.udp)
3528 self.reass_hairpinning(proto=IP_PROTOS.icmp)
3530 def test_frag_out_of_order(self):
3531 """ NAT44 translate fragments arriving out of order """
3533 self.nat44_add_address(self.nat_addr)
3534 flags = self.config_flags.NAT_IS_INSIDE
3535 self.vapi.nat44_interface_add_del_feature(
3536 sw_if_index=self.pg0.sw_if_index,
3537 flags=flags, is_add=1)
3538 self.vapi.nat44_interface_add_del_feature(
3539 sw_if_index=self.pg1.sw_if_index,
3542 self.frag_out_of_order(proto=IP_PROTOS.tcp)
3543 self.frag_out_of_order(proto=IP_PROTOS.udp)
3544 self.frag_out_of_order(proto=IP_PROTOS.icmp)
3546 def test_port_restricted(self):
3547 """ Port restricted NAT44 (MAP-E CE) """
3548 self.nat44_add_address(self.nat_addr)
3549 flags = self.config_flags.NAT_IS_INSIDE
3550 self.vapi.nat44_interface_add_del_feature(
3551 sw_if_index=self.pg0.sw_if_index,
3552 flags=flags, is_add=1)
3553 self.vapi.nat44_interface_add_del_feature(
3554 sw_if_index=self.pg1.sw_if_index,
3556 self.vapi.nat_set_addr_and_port_alloc_alg(alg=1,
3561 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
3562 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
3563 TCP(sport=4567, dport=22))
3564 self.pg0.add_stream(p)
3565 self.pg_enable_capture(self.pg_interfaces)
3567 capture = self.pg1.get_capture(1)
3572 self.assertEqual(ip.dst, self.pg1.remote_ip4)
3573 self.assertEqual(ip.src, self.nat_addr)
3574 self.assertEqual(tcp.dport, 22)
3575 self.assertNotEqual(tcp.sport, 4567)
3576 self.assertEqual((tcp.sport >> 6) & 63, 10)
3577 self.assert_packet_checksums_valid(p)
3579 self.logger.error(ppp("Unexpected or invalid packet:", p))
3582 def test_port_range(self):
3583 """ External address port range """
3584 self.nat44_add_address(self.nat_addr)
3585 flags = self.config_flags.NAT_IS_INSIDE
3586 self.vapi.nat44_interface_add_del_feature(
3587 sw_if_index=self.pg0.sw_if_index,
3588 flags=flags, is_add=1)
3589 self.vapi.nat44_interface_add_del_feature(
3590 sw_if_index=self.pg1.sw_if_index,
3592 self.vapi.nat_set_addr_and_port_alloc_alg(alg=2,
3597 for port in range(0, 5):
3598 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
3599 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
3600 TCP(sport=1125 + port))
3602 self.pg0.add_stream(pkts)
3603 self.pg_enable_capture(self.pg_interfaces)
3605 capture = self.pg1.get_capture(3)
3608 self.assertGreaterEqual(tcp.sport, 1025)
3609 self.assertLessEqual(tcp.sport, 1027)
3611 def test_multiple_outside_vrf(self):
3612 """ Multiple outside VRF """
3616 self.pg1.unconfig_ip4()
3617 self.pg2.unconfig_ip4()
3618 self.vapi.ip_table_add_del(is_add=1, table={'table_id': vrf_id1})
3619 self.vapi.ip_table_add_del(is_add=1, table={'table_id': vrf_id2})
3620 self.pg1.set_table_ip4(vrf_id1)
3621 self.pg2.set_table_ip4(vrf_id2)
3622 self.pg1.config_ip4()
3623 self.pg2.config_ip4()
3624 self.pg1.resolve_arp()
3625 self.pg2.resolve_arp()
3627 self.nat44_add_address(self.nat_addr)
3628 flags = self.config_flags.NAT_IS_INSIDE
3629 self.vapi.nat44_interface_add_del_feature(
3630 sw_if_index=self.pg0.sw_if_index,
3631 flags=flags, is_add=1)
3632 self.vapi.nat44_interface_add_del_feature(
3633 sw_if_index=self.pg1.sw_if_index,
3635 self.vapi.nat44_interface_add_del_feature(
3636 sw_if_index=self.pg2.sw_if_index,
3641 pkts = self.create_stream_in(self.pg0, self.pg1)
3642 self.pg0.add_stream(pkts)
3643 self.pg_enable_capture(self.pg_interfaces)
3645 capture = self.pg1.get_capture(len(pkts))
3646 self.verify_capture_out(capture, self.nat_addr)
3648 pkts = self.create_stream_out(self.pg1, self.nat_addr)
3649 self.pg1.add_stream(pkts)
3650 self.pg_enable_capture(self.pg_interfaces)
3652 capture = self.pg0.get_capture(len(pkts))
3653 self.verify_capture_in(capture, self.pg0)
3655 self.tcp_port_in = 60303
3656 self.udp_port_in = 60304
3657 self.icmp_id_in = 60305
3660 pkts = self.create_stream_in(self.pg0, self.pg2)
3661 self.pg0.add_stream(pkts)
3662 self.pg_enable_capture(self.pg_interfaces)
3664 capture = self.pg2.get_capture(len(pkts))
3665 self.verify_capture_out(capture, self.nat_addr)
3667 pkts = self.create_stream_out(self.pg2, self.nat_addr)
3668 self.pg2.add_stream(pkts)
3669 self.pg_enable_capture(self.pg_interfaces)
3671 capture = self.pg0.get_capture(len(pkts))
3672 self.verify_capture_in(capture, self.pg0)
3675 self.nat44_add_address(self.nat_addr, is_add=0)
3676 self.pg1.unconfig_ip4()
3677 self.pg2.unconfig_ip4()
3678 self.pg1.set_table_ip4(0)
3679 self.pg2.set_table_ip4(0)
3680 self.pg1.config_ip4()
3681 self.pg2.config_ip4()
3682 self.pg1.resolve_arp()
3683 self.pg2.resolve_arp()
3685 @unittest.skipUnless(running_extended_tests, "part of extended tests")
3686 def test_session_timeout(self):
3687 """ NAT44 session timeouts """
3688 self.nat44_add_address(self.nat_addr)
3689 flags = self.config_flags.NAT_IS_INSIDE
3690 self.vapi.nat44_interface_add_del_feature(
3691 sw_if_index=self.pg0.sw_if_index,
3692 flags=flags, is_add=1)
3693 self.vapi.nat44_interface_add_del_feature(
3694 sw_if_index=self.pg1.sw_if_index,
3696 self.vapi.nat_set_timeouts(udp=5, tcp_established=7440,
3697 tcp_transitory=240, icmp=60)
3701 for i in range(0, max_sessions):
3702 src = "10.10.%u.%u" % ((i & 0xFF00) >> 8, i & 0xFF)
3703 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
3704 IP(src=src, dst=self.pg1.remote_ip4) /
3705 UDP(sport=1025, dport=53))
3707 self.pg0.add_stream(pkts)
3708 self.pg_enable_capture(self.pg_interfaces)
3710 self.pg1.get_capture(max_sessions)
3715 for i in range(0, max_sessions):
3716 src = "10.10.%u.%u" % ((i & 0xFF00) >> 8, i & 0xFF)
3717 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
3718 IP(src=src, dst=self.pg1.remote_ip4) /
3719 UDP(sport=1026, dport=53))
3721 self.pg0.add_stream(pkts)
3722 self.pg_enable_capture(self.pg_interfaces)
3724 self.pg1.get_capture(max_sessions)
3727 users = self.vapi.nat44_user_dump()
3729 nsessions = nsessions + user.nsessions
3730 self.assertLess(nsessions, 2 * max_sessions)
3732 def test_mss_clamping(self):
3733 """ TCP MSS clamping """
3734 self.nat44_add_address(self.nat_addr)
3735 flags = self.config_flags.NAT_IS_INSIDE
3736 self.vapi.nat44_interface_add_del_feature(
3737 sw_if_index=self.pg0.sw_if_index,
3738 flags=flags, is_add=1)
3739 self.vapi.nat44_interface_add_del_feature(
3740 sw_if_index=self.pg1.sw_if_index,
3743 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
3744 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
3745 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
3746 flags="S", options=[('MSS', 1400)]))
3748 self.vapi.nat_set_mss_clamping(enable=1, mss_value=1000)
3749 self.pg0.add_stream(p)
3750 self.pg_enable_capture(self.pg_interfaces)
3752 capture = self.pg1.get_capture(1)
3753 # Negotiated MSS value greater than configured - changed
3754 self.verify_mss_value(capture[0], 1000)
3756 self.vapi.nat_set_mss_clamping(enable=0, mss_value=1500)
3757 self.pg0.add_stream(p)
3758 self.pg_enable_capture(self.pg_interfaces)
3760 capture = self.pg1.get_capture(1)
3761 # MSS clamping disabled - negotiated MSS unchanged
3762 self.verify_mss_value(capture[0], 1400)
3764 self.vapi.nat_set_mss_clamping(enable=1, mss_value=1500)
3765 self.pg0.add_stream(p)
3766 self.pg_enable_capture(self.pg_interfaces)
3768 capture = self.pg1.get_capture(1)
3769 # Negotiated MSS value smaller than configured - unchanged
3770 self.verify_mss_value(capture[0], 1400)
3772 @unittest.skipUnless(running_extended_tests, "part of extended tests")
3773 def test_ha_send(self):
3774 """ Send HA session synchronization events (active) """
3775 self.nat44_add_address(self.nat_addr)
3776 flags = self.config_flags.NAT_IS_INSIDE
3777 self.vapi.nat44_interface_add_del_feature(
3778 sw_if_index=self.pg0.sw_if_index,
3779 flags=flags, is_add=1)
3780 self.vapi.nat44_interface_add_del_feature(
3781 sw_if_index=self.pg1.sw_if_index,
3783 self.vapi.nat_ha_set_listener(ip_address=self.pg3.local_ip4,
3786 self.vapi.nat_ha_set_failover(ip_address=self.pg3.remote_ip4,
3787 port=12346, session_refresh_interval=10)
3788 bind_layers(UDP, HANATStateSync, sport=12345)
3791 pkts = self.create_stream_in(self.pg0, self.pg1)
3792 self.pg0.add_stream(pkts)
3793 self.pg_enable_capture(self.pg_interfaces)
3795 capture = self.pg1.get_capture(len(pkts))
3796 self.verify_capture_out(capture)
3797 # active send HA events
3798 self.vapi.nat_ha_flush()
3799 stats = self.statistics.get_counter('/nat44/ha/add-event-send')
3800 self.assertEqual(stats[0][0], 3)
3801 capture = self.pg3.get_capture(1)
3803 self.assert_packet_checksums_valid(p)
3807 hanat = p[HANATStateSync]
3809 self.logger.error(ppp("Invalid packet:", p))
3812 self.assertEqual(ip.src, self.pg3.local_ip4)
3813 self.assertEqual(ip.dst, self.pg3.remote_ip4)
3814 self.assertEqual(udp.sport, 12345)
3815 self.assertEqual(udp.dport, 12346)
3816 self.assertEqual(hanat.version, 1)
3817 self.assertEqual(hanat.thread_index, 0)
3818 self.assertEqual(hanat.count, 3)
3819 seq = hanat.sequence_number
3820 for event in hanat.events:
3821 self.assertEqual(event.event_type, 1)
3822 self.assertEqual(event.in_addr, self.pg0.remote_ip4)
3823 self.assertEqual(event.out_addr, self.nat_addr)
3824 self.assertEqual(event.fib_index, 0)
3826 # ACK received events
3827 ack = (Ether(dst=self.pg3.local_mac, src=self.pg3.remote_mac) /
3828 IP(src=self.pg3.remote_ip4, dst=self.pg3.local_ip4) /
3829 UDP(sport=12346, dport=12345) /
3830 HANATStateSync(sequence_number=seq, flags='ACK'))
3831 self.pg3.add_stream(ack)
3833 stats = self.statistics.get_counter('/nat44/ha/ack-recv')
3834 self.assertEqual(stats[0][0], 1)
3836 # delete one session
3837 self.pg_enable_capture(self.pg_interfaces)
3838 self.vapi.nat44_del_session(address=self.pg0.remote_ip4,
3839 port=self.tcp_port_in,
3840 protocol=IP_PROTOS.tcp,
3841 flags=self.config_flags.NAT_IS_INSIDE)
3842 self.vapi.nat_ha_flush()
3843 stats = self.statistics.get_counter('/nat44/ha/del-event-send')
3844 self.assertEqual(stats[0][0], 1)
3845 capture = self.pg3.get_capture(1)
3848 hanat = p[HANATStateSync]
3850 self.logger.error(ppp("Invalid packet:", p))
3853 self.assertGreater(hanat.sequence_number, seq)
3855 # do not send ACK, active retry send HA event again
3856 self.pg_enable_capture(self.pg_interfaces)
3858 stats = self.statistics.get_counter('/nat44/ha/retry-count')
3859 self.assertEqual(stats[0][0], 3)
3860 stats = self.statistics.get_counter('/nat44/ha/missed-count')
3861 self.assertEqual(stats[0][0], 1)
3862 capture = self.pg3.get_capture(3)
3863 for packet in capture:
3864 self.assertEqual(packet, p)
3866 # session counters refresh
3867 pkts = self.create_stream_out(self.pg1)
3868 self.pg1.add_stream(pkts)
3869 self.pg_enable_capture(self.pg_interfaces)
3871 self.pg0.get_capture(2)
3872 self.vapi.nat_ha_flush()
3873 stats = self.statistics.get_counter('/nat44/ha/refresh-event-send')
3874 self.assertEqual(stats[0][0], 2)
3875 capture = self.pg3.get_capture(1)
3877 self.assert_packet_checksums_valid(p)
3881 hanat = p[HANATStateSync]
3883 self.logger.error(ppp("Invalid packet:", p))
3886 self.assertEqual(ip.src, self.pg3.local_ip4)
3887 self.assertEqual(ip.dst, self.pg3.remote_ip4)
3888 self.assertEqual(udp.sport, 12345)
3889 self.assertEqual(udp.dport, 12346)
3890 self.assertEqual(hanat.version, 1)
3891 self.assertEqual(hanat.count, 2)
3892 seq = hanat.sequence_number
3893 for event in hanat.events:
3894 self.assertEqual(event.event_type, 3)
3895 self.assertEqual(event.out_addr, self.nat_addr)
3896 self.assertEqual(event.fib_index, 0)
3897 self.assertEqual(event.total_pkts, 2)
3898 self.assertGreater(event.total_bytes, 0)
3900 ack = (Ether(dst=self.pg3.local_mac, src=self.pg3.remote_mac) /
3901 IP(src=self.pg3.remote_ip4, dst=self.pg3.local_ip4) /
3902 UDP(sport=12346, dport=12345) /
3903 HANATStateSync(sequence_number=seq, flags='ACK'))
3904 self.pg3.add_stream(ack)
3906 stats = self.statistics.get_counter('/nat44/ha/ack-recv')
3907 self.assertEqual(stats[0][0], 2)
3909 def test_ha_recv(self):
3910 """ Receive HA session synchronization events (passive) """
3911 self.nat44_add_address(self.nat_addr)
3912 flags = self.config_flags.NAT_IS_INSIDE
3913 self.vapi.nat44_interface_add_del_feature(
3914 sw_if_index=self.pg0.sw_if_index,
3915 flags=flags, is_add=1)
3916 self.vapi.nat44_interface_add_del_feature(
3917 sw_if_index=self.pg1.sw_if_index,
3919 self.vapi.nat_ha_set_listener(ip_address=self.pg3.local_ip4,
3922 bind_layers(UDP, HANATStateSync, sport=12345)
3924 self.tcp_port_out = random.randint(1025, 65535)
3925 self.udp_port_out = random.randint(1025, 65535)
3927 # send HA session add events to failover/passive
3928 p = (Ether(dst=self.pg3.local_mac, src=self.pg3.remote_mac) /
3929 IP(src=self.pg3.remote_ip4, dst=self.pg3.local_ip4) /
3930 UDP(sport=12346, dport=12345) /
3931 HANATStateSync(sequence_number=1, events=[
3932 Event(event_type='add', protocol='tcp',
3933 in_addr=self.pg0.remote_ip4, out_addr=self.nat_addr,
3934 in_port=self.tcp_port_in, out_port=self.tcp_port_out,
3935 eh_addr=self.pg1.remote_ip4,
3936 ehn_addr=self.pg1.remote_ip4,
3937 eh_port=self.tcp_external_port,
3938 ehn_port=self.tcp_external_port, fib_index=0),
3939 Event(event_type='add', protocol='udp',
3940 in_addr=self.pg0.remote_ip4, out_addr=self.nat_addr,
3941 in_port=self.udp_port_in, out_port=self.udp_port_out,
3942 eh_addr=self.pg1.remote_ip4,
3943 ehn_addr=self.pg1.remote_ip4,
3944 eh_port=self.udp_external_port,
3945 ehn_port=self.udp_external_port, fib_index=0)]))
3947 self.pg3.add_stream(p)
3948 self.pg_enable_capture(self.pg_interfaces)
3951 capture = self.pg3.get_capture(1)
3954 hanat = p[HANATStateSync]
3956 self.logger.error(ppp("Invalid packet:", p))
3959 self.assertEqual(hanat.sequence_number, 1)
3960 self.assertEqual(hanat.flags, 'ACK')
3961 self.assertEqual(hanat.version, 1)
3962 self.assertEqual(hanat.thread_index, 0)
3963 stats = self.statistics.get_counter('/nat44/ha/ack-send')
3964 self.assertEqual(stats[0][0], 1)
3965 stats = self.statistics.get_counter('/nat44/ha/add-event-recv')
3966 self.assertEqual(stats[0][0], 2)
3967 users = self.statistics.get_counter('/nat44/total-users')
3968 self.assertEqual(users[0][0], 1)
3969 sessions = self.statistics.get_counter('/nat44/total-sessions')
3970 self.assertEqual(sessions[0][0], 2)
3971 users = self.vapi.nat44_user_dump()
3972 self.assertEqual(len(users), 1)
3973 self.assertEqual(str(users[0].ip_address),
3974 self.pg0.remote_ip4)
3975 # there should be 2 sessions created by HA
3976 sessions = self.vapi.nat44_user_session_dump(users[0].ip_address,
3978 self.assertEqual(len(sessions), 2)
3979 for session in sessions:
3980 self.assertEqual(str(session.inside_ip_address),
3981 self.pg0.remote_ip4)
3982 self.assertEqual(str(session.outside_ip_address),
3984 self.assertIn(session.inside_port,
3985 [self.tcp_port_in, self.udp_port_in])
3986 self.assertIn(session.outside_port,
3987 [self.tcp_port_out, self.udp_port_out])
3988 self.assertIn(session.protocol, [IP_PROTOS.tcp, IP_PROTOS.udp])
3990 # send HA session delete event to failover/passive
3991 p = (Ether(dst=self.pg3.local_mac, src=self.pg3.remote_mac) /
3992 IP(src=self.pg3.remote_ip4, dst=self.pg3.local_ip4) /
3993 UDP(sport=12346, dport=12345) /
3994 HANATStateSync(sequence_number=2, events=[
3995 Event(event_type='del', protocol='udp',
3996 in_addr=self.pg0.remote_ip4, out_addr=self.nat_addr,
3997 in_port=self.udp_port_in, out_port=self.udp_port_out,
3998 eh_addr=self.pg1.remote_ip4,
3999 ehn_addr=self.pg1.remote_ip4,
4000 eh_port=self.udp_external_port,
4001 ehn_port=self.udp_external_port, fib_index=0)]))
4003 self.pg3.add_stream(p)
4004 self.pg_enable_capture(self.pg_interfaces)
4007 capture = self.pg3.get_capture(1)
4010 hanat = p[HANATStateSync]
4012 self.logger.error(ppp("Invalid packet:", p))
4015 self.assertEqual(hanat.sequence_number, 2)
4016 self.assertEqual(hanat.flags, 'ACK')
4017 self.assertEqual(hanat.version, 1)
4018 users = self.vapi.nat44_user_dump()
4019 self.assertEqual(len(users), 1)
4020 self.assertEqual(str(users[0].ip_address),
4021 self.pg0.remote_ip4)
4022 # now we should have only 1 session, 1 deleted by HA
4023 sessions = self.vapi.nat44_user_session_dump(users[0].ip_address,
4025 self.assertEqual(len(sessions), 1)
4026 stats = self.statistics.get_counter('/nat44/ha/del-event-recv')
4027 self.assertEqual(stats[0][0], 1)
4029 stats = self.statistics.get_err_counter('/err/nat-ha/pkts-processed')
4030 self.assertEqual(stats, 2)
4032 # send HA session refresh event to failover/passive
4033 p = (Ether(dst=self.pg3.local_mac, src=self.pg3.remote_mac) /
4034 IP(src=self.pg3.remote_ip4, dst=self.pg3.local_ip4) /
4035 UDP(sport=12346, dport=12345) /
4036 HANATStateSync(sequence_number=3, events=[
4037 Event(event_type='refresh', protocol='tcp',
4038 in_addr=self.pg0.remote_ip4, out_addr=self.nat_addr,
4039 in_port=self.tcp_port_in, out_port=self.tcp_port_out,
4040 eh_addr=self.pg1.remote_ip4,
4041 ehn_addr=self.pg1.remote_ip4,
4042 eh_port=self.tcp_external_port,
4043 ehn_port=self.tcp_external_port, fib_index=0,
4044 total_bytes=1024, total_pkts=2)]))
4045 self.pg3.add_stream(p)
4046 self.pg_enable_capture(self.pg_interfaces)
4049 capture = self.pg3.get_capture(1)
4052 hanat = p[HANATStateSync]
4054 self.logger.error(ppp("Invalid packet:", p))
4057 self.assertEqual(hanat.sequence_number, 3)
4058 self.assertEqual(hanat.flags, 'ACK')
4059 self.assertEqual(hanat.version, 1)
4060 users = self.vapi.nat44_user_dump()
4061 self.assertEqual(len(users), 1)
4062 self.assertEqual(str(users[0].ip_address),
4063 self.pg0.remote_ip4)
4064 sessions = self.vapi.nat44_user_session_dump(users[0].ip_address,
4066 self.assertEqual(len(sessions), 1)
4067 session = sessions[0]
4068 self.assertEqual(session.total_bytes, 1024)
4069 self.assertEqual(session.total_pkts, 2)
4070 stats = self.statistics.get_counter('/nat44/ha/refresh-event-recv')
4071 self.assertEqual(stats[0][0], 1)
4073 stats = self.statistics.get_err_counter('/err/nat-ha/pkts-processed')
4074 self.assertEqual(stats, 3)
4076 # send packet to test session created by HA
4077 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
4078 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
4079 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out))
4080 self.pg1.add_stream(p)
4081 self.pg_enable_capture(self.pg_interfaces)
4083 capture = self.pg0.get_capture(1)
4089 self.logger.error(ppp("Invalid packet:", p))
4092 self.assertEqual(ip.src, self.pg1.remote_ip4)
4093 self.assertEqual(ip.dst, self.pg0.remote_ip4)
4094 self.assertEqual(tcp.sport, self.tcp_external_port)
4095 self.assertEqual(tcp.dport, self.tcp_port_in)
4098 super(TestNAT44, self).tearDown()
4100 self.vapi.cli("clear logging")
4102 def show_commands_at_teardown(self):
4103 self.logger.info(self.vapi.cli("show nat44 addresses"))
4104 self.logger.info(self.vapi.cli("show nat44 interfaces"))
4105 self.logger.info(self.vapi.cli("show nat44 static mappings"))
4106 self.logger.info(self.vapi.cli("show nat44 interface address"))
4107 self.logger.info(self.vapi.cli("show nat44 sessions detail"))
4108 self.logger.info(self.vapi.cli("show nat44 hash tables detail"))
4109 self.logger.info(self.vapi.cli("show nat timeouts"))
4111 self.vapi.cli("show nat addr-port-assignment-alg"))
4112 self.logger.info(self.vapi.cli("show nat ha"))
4115 class TestNAT44EndpointDependent2(MethodHolder):
4116 """ Endpoint-Dependent mapping and filtering test cases """
4119 def setUpConstants(cls):
4120 super(TestNAT44EndpointDependent2, cls).setUpConstants()
4121 cls.vpp_cmdline.extend(["nat", "{", "endpoint-dependent", "}"])
4124 def tearDownClass(cls):
4125 super(TestNAT44EndpointDependent2, cls).tearDownClass()
4128 super(TestNAT44EndpointDependent2, self).tearDown()
4131 def create_and_add_ip4_table(cls, i, table_id):
4132 cls.vapi.ip_table_add_del(is_add=1, table={'table_id': table_id})
4133 i.set_table_ip4(table_id)
4136 def setUpClass(cls):
4137 super(TestNAT44EndpointDependent2, cls).setUpClass()
4139 cls.create_pg_interfaces(range(3))
4140 cls.interfaces = list(cls.pg_interfaces)
4142 cls.create_and_add_ip4_table(cls.pg1, 10)
4144 for i in cls.interfaces:
4149 i.generate_remote_hosts(1)
4150 i.configure_ipv4_neighbors()
4153 super(TestNAT44EndpointDependent2, self).setUp()
4155 nat_config = self.vapi.nat_show_config()
4156 self.assertEqual(1, nat_config.endpoint_dependent)
4158 def nat_add_inside_interface(self, i):
4159 self.vapi.nat44_interface_add_del_feature(
4160 flags=self.config_flags.NAT_IS_INSIDE,
4161 sw_if_index=i.sw_if_index, is_add=1)
4163 def nat_add_outside_interface(self, i):
4164 self.vapi.nat44_interface_add_del_feature(
4165 flags=self.config_flags.NAT_IS_OUTSIDE,
4166 sw_if_index=i.sw_if_index, is_add=1)
4168 def nat_add_interface_address(self, i):
4169 self.nat_addr = i.local_ip4
4170 self.vapi.nat44_add_del_interface_addr(
4171 sw_if_index=i.sw_if_index, is_add=1)
4173 def nat_add_address(self, address, vrf_id=0xFFFFFFFF):
4174 self.nat_addr = address
4175 self.nat44_add_address(address, vrf_id=vrf_id)
4177 def cli(self, command):
4178 result = self.vapi.cli(command)
4179 self.logger.info(result)
4182 def show_configuration(self):
4183 self.cli("show interface")
4184 self.cli("show interface address")
4185 self.cli("show nat44 addresses")
4186 self.cli("show nat44 interfaces")
4188 def create_tcp_stream(self, in_if, out_if, count):
4190 Create tcp packet stream
4192 :param in_if: Inside interface
4193 :param out_if: Outside interface
4194 :param count: count of packets to generate
4199 for i in range(count):
4200 p = (Ether(dst=in_if.local_mac, src=in_if.remote_mac) /
4201 IP(src=in_if.remote_ip4, dst=out_if.remote_ip4, ttl=64) /
4202 TCP(sport=port + i, dport=20))
4207 def test_session_limit_per_vrf(self):
4210 inside_vrf10 = self.pg1
4215 # 2 interfaces pg0, pg1 (vrf10, limit 1 tcp session)
4216 # non existing vrf_id makes process core dump
4217 self.vapi.nat44_set_session_limit(session_limit=limit, vrf_id=10)
4219 self.nat_add_inside_interface(inside)
4220 self.nat_add_inside_interface(inside_vrf10)
4221 self.nat_add_outside_interface(outside)
4224 self.nat_add_interface_address(outside)
4226 # BUG: causing core dump - when bad vrf_id is specified
4227 # self.nat44_add_address(outside.local_ip4, vrf_id=20)
4229 self.show_configuration()
4231 stream = self.create_tcp_stream(inside_vrf10, outside, limit * 2)
4232 inside_vrf10.add_stream(stream)
4234 self.pg_enable_capture(self.pg_interfaces)
4237 capture = outside.get_capture(limit)
4239 stream = self.create_tcp_stream(inside, outside, limit * 2)
4240 inside.add_stream(stream)
4242 self.pg_enable_capture(self.pg_interfaces)
4245 capture = outside.get_capture(len(stream))
4248 class TestNAT44EndpointDependent(MethodHolder):
4249 """ Endpoint-Dependent mapping and filtering test cases """
4252 def setUpConstants(cls):
4253 super(TestNAT44EndpointDependent, cls).setUpConstants()
4254 cls.vpp_cmdline.extend(["nat", "{", "endpoint-dependent", "}"])
4257 def setUpClass(cls):
4258 super(TestNAT44EndpointDependent, cls).setUpClass()
4259 cls.vapi.cli("set log class nat level debug")
4261 cls.tcp_port_in = 6303
4262 cls.tcp_port_out = 6303
4263 cls.udp_port_in = 6304
4264 cls.udp_port_out = 6304
4265 cls.icmp_id_in = 6305
4266 cls.icmp_id_out = 6305
4267 cls.nat_addr = '10.0.0.3'
4268 cls.ipfix_src_port = 4739
4269 cls.ipfix_domain_id = 1
4270 cls.tcp_external_port = 80
4272 cls.create_pg_interfaces(range(9))
4273 cls.interfaces = list(cls.pg_interfaces[0:3])
4275 for i in cls.interfaces:
4280 cls.pg0.generate_remote_hosts(3)
4281 cls.pg0.configure_ipv4_neighbors()
4285 cls.pg4.generate_remote_hosts(2)
4286 cls.pg4.config_ip4()
4287 cls.vapi.sw_interface_add_del_address(
4288 sw_if_index=cls.pg4.sw_if_index,
4289 prefix="10.0.0.1/24")
4292 cls.pg4.resolve_arp()
4293 cls.pg4._remote_hosts[1]._ip4 = cls.pg4._remote_hosts[0]._ip4
4294 cls.pg4.resolve_arp()
4296 zero_ip4 = socket.inet_pton(socket.AF_INET, "0.0.0.0")
4297 cls.vapi.ip_table_add_del(is_add=1, table={'table_id': 1})
4299 cls.pg5._local_ip4 = "10.1.1.1"
4300 cls.pg5._remote_hosts[0]._ip4 = "10.1.1.2"
4301 cls.pg5.set_table_ip4(1)
4302 cls.pg5.config_ip4()
4304 r1 = VppIpRoute(cls, cls.pg5.remote_ip4, 32,
4305 [VppRoutePath("0.0.0.0",
4306 cls.pg5.sw_if_index)],
4311 cls.pg6._local_ip4 = "10.1.2.1"
4312 cls.pg6._remote_hosts[0]._ip4 = "10.1.2.2"
4313 cls.pg6.set_table_ip4(1)
4314 cls.pg6.config_ip4()
4317 r2 = VppIpRoute(cls, cls.pg6.remote_ip4, 32,
4318 [VppRoutePath("0.0.0.0",
4319 cls.pg6.sw_if_index)],
4322 r3 = VppIpRoute(cls, cls.pg6.remote_ip4, 16,
4323 [VppRoutePath("0.0.0.0",
4328 r4 = VppIpRoute(cls, "0.0.0.0", 0,
4329 [VppRoutePath("0.0.0.0", 0xffffffff,
4333 r5 = VppIpRoute(cls, "0.0.0.0", 0,
4334 [VppRoutePath(cls.pg1.local_ip4,
4335 cls.pg1.sw_if_index)],
4342 cls.pg5.resolve_arp()
4343 cls.pg6.resolve_arp()
4346 cls.pg7.config_ip4()
4347 cls.pg7.resolve_arp()
4348 cls.pg7.generate_remote_hosts(3)
4349 cls.pg7.configure_ipv4_neighbors()
4352 cls.pg8.config_ip4()
4353 cls.pg8.resolve_arp()
4356 super(TestNAT44EndpointDependent, self).setUp()
4357 self.vapi.nat_set_timeouts(
4358 udp=300, tcp_established=7440, tcp_transitory=240, icmp=60)
4361 def tearDownClass(cls):
4362 super(TestNAT44EndpointDependent, cls).tearDownClass()
4364 def test_frag_in_order(self):
4365 """ NAT44 translate fragments arriving in order """
4366 self.nat44_add_address(self.nat_addr)
4367 flags = self.config_flags.NAT_IS_INSIDE
4368 self.vapi.nat44_interface_add_del_feature(
4369 sw_if_index=self.pg0.sw_if_index,
4370 flags=flags, is_add=1)
4371 self.vapi.nat44_interface_add_del_feature(
4372 sw_if_index=self.pg1.sw_if_index,
4374 self.frag_in_order(proto=IP_PROTOS.tcp, ignore_port=True)
4375 self.frag_in_order(proto=IP_PROTOS.udp, ignore_port=True)
4376 self.frag_in_order(proto=IP_PROTOS.icmp, ignore_port=True)
4378 def test_frag_in_order_dont_translate(self):
4379 """ NAT44 don't translate fragments arriving in order """
4380 flags = self.config_flags.NAT_IS_INSIDE
4381 self.vapi.nat44_interface_add_del_feature(
4382 sw_if_index=self.pg0.sw_if_index,
4383 flags=flags, is_add=1)
4384 self.vapi.nat44_interface_add_del_feature(
4385 sw_if_index=self.pg1.sw_if_index,
4387 self.vapi.nat44_forwarding_enable_disable(enable=True)
4388 self.frag_in_order(proto=IP_PROTOS.tcp, dont_translate=True)
4390 def test_frag_out_of_order(self):
4391 """ NAT44 translate fragments arriving out of order """
4392 self.nat44_add_address(self.nat_addr)
4393 flags = self.config_flags.NAT_IS_INSIDE
4394 self.vapi.nat44_interface_add_del_feature(
4395 sw_if_index=self.pg0.sw_if_index,
4396 flags=flags, is_add=1)
4397 self.vapi.nat44_interface_add_del_feature(
4398 sw_if_index=self.pg1.sw_if_index,
4400 self.frag_out_of_order(proto=IP_PROTOS.tcp, ignore_port=True)
4401 self.frag_out_of_order(proto=IP_PROTOS.udp, ignore_port=True)
4402 self.frag_out_of_order(proto=IP_PROTOS.icmp, ignore_port=True)
4404 def test_frag_out_of_order_dont_translate(self):
4405 """ NAT44 don't translate fragments arriving out of order """
4406 flags = self.config_flags.NAT_IS_INSIDE
4407 self.vapi.nat44_interface_add_del_feature(
4408 sw_if_index=self.pg0.sw_if_index,
4409 flags=flags, is_add=1)
4410 self.vapi.nat44_interface_add_del_feature(
4411 sw_if_index=self.pg1.sw_if_index,
4413 self.vapi.nat44_forwarding_enable_disable(enable=True)
4414 self.frag_out_of_order(proto=IP_PROTOS.tcp, dont_translate=True)
4416 def test_frag_in_order_in_plus_out(self):
4417 """ in+out interface fragments in order """
4418 flags = self.config_flags.NAT_IS_INSIDE
4419 self.vapi.nat44_interface_add_del_feature(
4420 sw_if_index=self.pg0.sw_if_index,
4422 self.vapi.nat44_interface_add_del_feature(
4423 sw_if_index=self.pg0.sw_if_index,
4424 flags=flags, is_add=1)
4425 self.vapi.nat44_interface_add_del_feature(
4426 sw_if_index=self.pg1.sw_if_index,
4428 self.vapi.nat44_interface_add_del_feature(
4429 sw_if_index=self.pg1.sw_if_index,
4430 flags=flags, is_add=1)
4432 self.server = self.pg1.remote_hosts[0]
4434 self.server_in_addr = self.server.ip4
4435 self.server_out_addr = '11.11.11.11'
4436 self.server_in_port = random.randint(1025, 65535)
4437 self.server_out_port = random.randint(1025, 65535)
4439 self.nat44_add_address(self.server_out_addr)
4441 # add static mappings for server
4442 self.nat44_add_static_mapping(self.server_in_addr,
4443 self.server_out_addr,
4444 self.server_in_port,
4445 self.server_out_port,
4446 proto=IP_PROTOS.tcp)
4447 self.nat44_add_static_mapping(self.server_in_addr,
4448 self.server_out_addr,
4449 self.server_in_port,
4450 self.server_out_port,
4451 proto=IP_PROTOS.udp)
4452 self.nat44_add_static_mapping(self.server_in_addr,
4453 self.server_out_addr,
4454 proto=IP_PROTOS.icmp)
4456 self.frag_in_order_in_plus_out(proto=IP_PROTOS.tcp)
4457 self.frag_in_order_in_plus_out(proto=IP_PROTOS.udp)
4458 self.frag_in_order_in_plus_out(proto=IP_PROTOS.icmp)
4460 def test_frag_out_of_order_in_plus_out(self):
4461 """ in+out interface fragments out of order """
4462 flags = self.config_flags.NAT_IS_INSIDE
4463 self.vapi.nat44_interface_add_del_feature(
4464 sw_if_index=self.pg0.sw_if_index,
4466 self.vapi.nat44_interface_add_del_feature(
4467 sw_if_index=self.pg0.sw_if_index,
4468 flags=flags, is_add=1)
4469 self.vapi.nat44_interface_add_del_feature(
4470 sw_if_index=self.pg1.sw_if_index,
4472 self.vapi.nat44_interface_add_del_feature(
4473 sw_if_index=self.pg1.sw_if_index,
4474 flags=flags, is_add=1)
4476 self.server = self.pg1.remote_hosts[0]
4478 self.server_in_addr = self.server.ip4
4479 self.server_out_addr = '11.11.11.11'
4480 self.server_in_port = random.randint(1025, 65535)
4481 self.server_out_port = random.randint(1025, 65535)
4483 self.nat44_add_address(self.server_out_addr)
4485 # add static mappings for server
4486 self.nat44_add_static_mapping(self.server_in_addr,
4487 self.server_out_addr,
4488 self.server_in_port,
4489 self.server_out_port,
4490 proto=IP_PROTOS.tcp)
4491 self.nat44_add_static_mapping(self.server_in_addr,
4492 self.server_out_addr,
4493 self.server_in_port,
4494 self.server_out_port,
4495 proto=IP_PROTOS.udp)
4496 self.nat44_add_static_mapping(self.server_in_addr,
4497 self.server_out_addr,
4498 proto=IP_PROTOS.icmp)
4500 self.frag_out_of_order_in_plus_out(proto=IP_PROTOS.tcp)
4501 self.frag_out_of_order_in_plus_out(proto=IP_PROTOS.udp)
4502 self.frag_out_of_order_in_plus_out(proto=IP_PROTOS.icmp)
4504 def test_reass_hairpinning(self):
4505 """ NAT44 fragments hairpinning """
4506 self.server = self.pg0.remote_hosts[1]
4507 self.host_in_port = random.randint(1025, 65535)
4508 self.server_in_port = random.randint(1025, 65535)
4509 self.server_out_port = random.randint(1025, 65535)
4511 self.nat44_add_address(self.nat_addr)
4512 flags = self.config_flags.NAT_IS_INSIDE
4513 self.vapi.nat44_interface_add_del_feature(
4514 sw_if_index=self.pg0.sw_if_index,
4515 flags=flags, is_add=1)
4516 self.vapi.nat44_interface_add_del_feature(
4517 sw_if_index=self.pg1.sw_if_index,
4519 # add static mapping for server
4520 self.nat44_add_static_mapping(self.server.ip4, self.nat_addr,
4521 self.server_in_port,
4522 self.server_out_port,
4523 proto=IP_PROTOS.tcp)
4524 self.nat44_add_static_mapping(self.server.ip4, self.nat_addr,
4525 self.server_in_port,
4526 self.server_out_port,
4527 proto=IP_PROTOS.udp)
4528 self.nat44_add_static_mapping(self.server.ip4, self.nat_addr)
4530 self.reass_hairpinning(proto=IP_PROTOS.tcp, ignore_port=True)
4531 self.reass_hairpinning(proto=IP_PROTOS.udp, ignore_port=True)
4532 self.reass_hairpinning(proto=IP_PROTOS.icmp, ignore_port=True)
4534 def test_clear_sessions(self):
4535 """ NAT44 ED session clearing test """
4537 self.nat44_add_address(self.nat_addr)
4538 flags = self.config_flags.NAT_IS_INSIDE
4539 self.vapi.nat44_interface_add_del_feature(
4540 sw_if_index=self.pg0.sw_if_index,
4541 flags=flags, is_add=1)
4542 self.vapi.nat44_interface_add_del_feature(
4543 sw_if_index=self.pg1.sw_if_index,
4546 nat_config = self.vapi.nat_show_config()
4547 self.assertEqual(1, nat_config.endpoint_dependent)
4549 pkts = self.create_stream_in(self.pg0, self.pg1)
4550 self.pg0.add_stream(pkts)
4551 self.pg_enable_capture(self.pg_interfaces)
4553 capture = self.pg1.get_capture(len(pkts))
4554 self.verify_capture_out(capture, ignore_port=True)
4556 sessions = self.statistics.get_counter('/nat44/total-sessions')
4557 self.assertTrue(sessions[0][0] > 0)
4558 self.logger.info("sessions before clearing: %s" % sessions[0][0])
4560 # just for testing purposes
4561 self.logger.info(self.vapi.cli("show nat44 summary"))
4563 self.vapi.cli("clear nat44 sessions")
4565 self.logger.info(self.vapi.cli("show nat44 summary"))
4567 sessions = self.statistics.get_counter('/nat44/total-sessions')
4568 self.assertEqual(sessions[0][0], 0)
4569 self.logger.info("sessions after clearing: %s" % sessions[0][0])
4571 def test_dynamic(self):
4572 """ NAT44 dynamic translation test """
4574 self.nat44_add_address(self.nat_addr)
4575 flags = self.config_flags.NAT_IS_INSIDE
4576 self.vapi.nat44_interface_add_del_feature(
4577 sw_if_index=self.pg0.sw_if_index,
4578 flags=flags, is_add=1)
4579 self.vapi.nat44_interface_add_del_feature(
4580 sw_if_index=self.pg1.sw_if_index,
4583 nat_config = self.vapi.nat_show_config()
4584 self.assertEqual(1, nat_config.endpoint_dependent)
4587 tcpn = self.statistics.get_counter('/nat44/ed/in2out/slowpath/tcp')[0]
4588 udpn = self.statistics.get_counter('/nat44/ed/in2out/slowpath/udp')[0]
4589 icmpn = self.statistics.get_counter(
4590 '/nat44/ed/in2out/slowpath/icmp')[0]
4591 drops = self.statistics.get_counter(
4592 '/nat44/ed/in2out/slowpath/drops')[0]
4594 pkts = self.create_stream_in(self.pg0, self.pg1)
4595 self.pg0.add_stream(pkts)
4596 self.pg_enable_capture(self.pg_interfaces)
4598 capture = self.pg1.get_capture(len(pkts))
4599 self.verify_capture_out(capture, ignore_port=True)
4601 if_idx = self.pg0.sw_if_index
4602 cnt = self.statistics.get_counter('/nat44/ed/in2out/slowpath/tcp')[0]
4603 self.assertEqual(cnt[if_idx] - tcpn[if_idx], 2)
4604 cnt = self.statistics.get_counter('/nat44/ed/in2out/slowpath/udp')[0]
4605 self.assertEqual(cnt[if_idx] - udpn[if_idx], 1)
4606 cnt = self.statistics.get_counter('/nat44/ed/in2out/slowpath/icmp')[0]
4607 self.assertEqual(cnt[if_idx] - icmpn[if_idx], 1)
4608 cnt = self.statistics.get_counter('/nat44/ed/in2out/slowpath/drops')[0]
4609 self.assertEqual(cnt[if_idx] - drops[if_idx], 0)
4612 tcpn = self.statistics.get_counter('/nat44/ed/out2in/fastpath/tcp')[0]
4613 udpn = self.statistics.get_counter('/nat44/ed/out2in/fastpath/udp')[0]
4614 icmpn = self.statistics.get_counter(
4615 '/nat44/ed/out2in/slowpath/icmp')[0]
4616 drops = self.statistics.get_counter(
4617 '/nat44/ed/out2in/fastpath/drops')[0]
4619 pkts = self.create_stream_out(self.pg1)
4620 self.pg1.add_stream(pkts)
4621 self.pg_enable_capture(self.pg_interfaces)
4623 capture = self.pg0.get_capture(len(pkts))
4624 self.verify_capture_in(capture, self.pg0)
4626 if_idx = self.pg1.sw_if_index
4627 cnt = self.statistics.get_counter('/nat44/ed/out2in/fastpath/tcp')[0]
4628 self.assertEqual(cnt[if_idx] - tcpn[if_idx], 2)
4629 cnt = self.statistics.get_counter('/nat44/ed/out2in/fastpath/udp')[0]
4630 self.assertEqual(cnt[if_idx] - udpn[if_idx], 1)
4631 cnt = self.statistics.get_counter('/nat44/ed/out2in/slowpath/icmp')[0]
4632 self.assertEqual(cnt[if_idx] - icmpn[if_idx], 1)
4633 cnt = self.statistics.get_counter('/nat44/ed/out2in/fastpath/drops')[0]
4634 self.assertEqual(cnt[if_idx] - drops[if_idx], 0)
4636 sessions = self.statistics.get_counter('/nat44/total-sessions')
4637 self.assertEqual(sessions[0][0], 3)
4639 def test_dynamic_out_of_ports(self):
4640 """ NAT44 dynamic translation test: out of ports """
4642 flags = self.config_flags.NAT_IS_INSIDE
4643 self.vapi.nat44_interface_add_del_feature(
4644 sw_if_index=self.pg0.sw_if_index,
4645 flags=flags, is_add=1)
4646 self.vapi.nat44_interface_add_del_feature(
4647 sw_if_index=self.pg1.sw_if_index,
4650 nat_config = self.vapi.nat_show_config()
4651 self.assertEqual(1, nat_config.endpoint_dependent)
4653 # in2out and no NAT addresses added
4654 err_old = self.statistics.get_err_counter(
4655 '/err/nat44-ed-in2out-slowpath/out of ports')
4657 pkts = self.create_stream_in(self.pg0, self.pg1)
4658 self.pg0.add_stream(pkts)
4659 self.pg_enable_capture(self.pg_interfaces)
4661 self.pg1.get_capture(0, timeout=1)
4663 err_new = self.statistics.get_err_counter(
4664 '/err/nat44-ed-in2out-slowpath/out of ports')
4666 self.assertEqual(err_new - err_old, len(pkts))
4668 # in2out after NAT addresses added
4669 self.nat44_add_address(self.nat_addr)
4671 err_old = self.statistics.get_err_counter(
4672 '/err/nat44-ed-in2out-slowpath/out of ports')
4674 pkts = self.create_stream_in(self.pg0, self.pg1)
4675 self.pg0.add_stream(pkts)
4676 self.pg_enable_capture(self.pg_interfaces)
4678 capture = self.pg1.get_capture(len(pkts))
4679 self.verify_capture_out(capture, ignore_port=True)
4681 err_new = self.statistics.get_err_counter(
4682 '/err/nat44-ed-in2out-slowpath/out of ports')
4684 self.assertEqual(err_new, err_old)
4686 def test_dynamic_output_feature_vrf(self):
4687 """ NAT44 dynamic translation test: output-feature, VRF"""
4689 # other then default (0)
4692 self.nat44_add_address(self.nat_addr)
4693 flags = self.config_flags.NAT_IS_INSIDE
4694 self.vapi.nat44_interface_add_del_output_feature(
4695 sw_if_index=self.pg7.sw_if_index,
4696 flags=flags, is_add=1)
4697 self.vapi.nat44_interface_add_del_output_feature(
4698 sw_if_index=self.pg8.sw_if_index,
4702 self.vapi.ip_table_add_del(is_add=1,
4703 table={'table_id': new_vrf_id})
4705 self.pg7.unconfig_ip4()
4706 self.pg7.set_table_ip4(new_vrf_id)
4707 self.pg7.config_ip4()
4708 self.pg7.resolve_arp()
4710 self.pg8.unconfig_ip4()
4711 self.pg8.set_table_ip4(new_vrf_id)
4712 self.pg8.config_ip4()
4713 self.pg8.resolve_arp()
4715 nat_config = self.vapi.nat_show_config()
4716 self.assertEqual(1, nat_config.endpoint_dependent)
4719 tcpn = self.statistics.get_counter(
4720 '/nat44/ed/in2out/slowpath/tcp')[0]
4721 udpn = self.statistics.get_counter(
4722 '/nat44/ed/in2out/slowpath/udp')[0]
4723 icmpn = self.statistics.get_counter(
4724 '/nat44/ed/in2out/slowpath/icmp')[0]
4725 drops = self.statistics.get_counter(
4726 '/nat44/ed/in2out/slowpath/drops')[0]
4728 pkts = self.create_stream_in(self.pg7, self.pg8)
4729 self.pg7.add_stream(pkts)
4730 self.pg_enable_capture(self.pg_interfaces)
4732 capture = self.pg8.get_capture(len(pkts))
4733 self.verify_capture_out(capture, ignore_port=True)
4735 if_idx = self.pg7.sw_if_index
4736 cnt = self.statistics.get_counter(
4737 '/nat44/ed/in2out/slowpath/tcp')[0]
4738 self.assertEqual(cnt[if_idx] - tcpn[if_idx], 2)
4739 cnt = self.statistics.get_counter(
4740 '/nat44/ed/in2out/slowpath/udp')[0]
4741 self.assertEqual(cnt[if_idx] - udpn[if_idx], 1)
4742 cnt = self.statistics.get_counter(
4743 '/nat44/ed/in2out/slowpath/icmp')[0]
4744 self.assertEqual(cnt[if_idx] - icmpn[if_idx], 1)
4745 cnt = self.statistics.get_counter(
4746 '/nat44/ed/in2out/slowpath/drops')[0]
4747 self.assertEqual(cnt[if_idx] - drops[if_idx], 0)
4750 tcpn = self.statistics.get_counter(
4751 '/nat44/ed/out2in/fastpath/tcp')[0]
4752 udpn = self.statistics.get_counter(
4753 '/nat44/ed/out2in/fastpath/udp')[0]
4754 icmpn = self.statistics.get_counter(
4755 '/nat44/ed/out2in/slowpath/icmp')[0]
4756 drops = self.statistics.get_counter(
4757 '/nat44/ed/out2in/fastpath/drops')[0]
4759 pkts = self.create_stream_out(self.pg8)
4760 self.pg8.add_stream(pkts)
4761 self.pg_enable_capture(self.pg_interfaces)
4763 capture = self.pg7.get_capture(len(pkts))
4764 self.verify_capture_in(capture, self.pg7)
4766 if_idx = self.pg8.sw_if_index
4767 cnt = self.statistics.get_counter(
4768 '/nat44/ed/out2in/fastpath/tcp')[0]
4769 self.assertEqual(cnt[if_idx] - tcpn[if_idx], 2)
4770 cnt = self.statistics.get_counter(
4771 '/nat44/ed/out2in/fastpath/udp')[0]
4772 self.assertEqual(cnt[if_idx] - udpn[if_idx], 1)
4773 cnt = self.statistics.get_counter(
4774 '/nat44/ed/out2in/slowpath/icmp')[0]
4775 self.assertEqual(cnt[if_idx] - icmpn[if_idx], 1)
4776 cnt = self.statistics.get_counter(
4777 '/nat44/ed/out2in/fastpath/drops')[0]
4778 self.assertEqual(cnt[if_idx] - drops[if_idx], 0)
4780 sessions = self.statistics.get_counter('/nat44/total-sessions')
4781 self.assertEqual(sessions[0][0], 3)
4784 self.pg7.unconfig_ip4()
4785 self.pg7.set_table_ip4(1)
4786 self.pg7.config_ip4()
4787 self.pg7.resolve_arp()
4789 self.pg8.unconfig_ip4()
4790 self.pg8.set_table_ip4(1)
4791 self.pg8.config_ip4()
4792 self.pg8.resolve_arp()
4794 self.vapi.ip_table_add_del(is_add=0,
4795 table={'table_id': new_vrf_id})
4797 def test_forwarding(self):
4798 """ NAT44 forwarding test """
4800 flags = self.config_flags.NAT_IS_INSIDE
4801 self.vapi.nat44_interface_add_del_feature(
4802 sw_if_index=self.pg0.sw_if_index,
4803 flags=flags, is_add=1)
4804 self.vapi.nat44_interface_add_del_feature(
4805 sw_if_index=self.pg1.sw_if_index,
4807 self.vapi.nat44_forwarding_enable_disable(enable=1)
4809 real_ip = self.pg0.remote_ip4
4810 alias_ip = self.nat_addr
4811 flags = self.config_flags.NAT_IS_ADDR_ONLY
4812 self.vapi.nat44_add_del_static_mapping(is_add=1,
4813 local_ip_address=real_ip,
4814 external_ip_address=alias_ip,
4815 external_sw_if_index=0xFFFFFFFF,
4819 # in2out - static mapping match
4821 pkts = self.create_stream_out(self.pg1)
4822 self.pg1.add_stream(pkts)
4823 self.pg_enable_capture(self.pg_interfaces)
4825 capture = self.pg0.get_capture(len(pkts))
4826 self.verify_capture_in(capture, self.pg0)
4828 pkts = self.create_stream_in(self.pg0, self.pg1)
4829 self.pg0.add_stream(pkts)
4830 self.pg_enable_capture(self.pg_interfaces)
4832 capture = self.pg1.get_capture(len(pkts))
4833 self.verify_capture_out(capture, same_port=True)
4835 # in2out - no static mapping match
4837 host0 = self.pg0.remote_hosts[0]
4838 self.pg0.remote_hosts[0] = self.pg0.remote_hosts[1]
4840 pkts = self.create_stream_out(self.pg1,
4841 dst_ip=self.pg0.remote_ip4,
4842 use_inside_ports=True)
4843 self.pg1.add_stream(pkts)
4844 self.pg_enable_capture(self.pg_interfaces)
4846 capture = self.pg0.get_capture(len(pkts))
4847 self.verify_capture_in(capture, self.pg0)
4849 pkts = self.create_stream_in(self.pg0, self.pg1)
4850 self.pg0.add_stream(pkts)
4851 self.pg_enable_capture(self.pg_interfaces)
4853 capture = self.pg1.get_capture(len(pkts))
4854 self.verify_capture_out(capture, nat_ip=self.pg0.remote_ip4,
4857 self.pg0.remote_hosts[0] = host0
4859 user = self.pg0.remote_hosts[1]
4860 sessions = self.vapi.nat44_user_session_dump(user.ip4, 0)
4861 self.assertEqual(len(sessions), 3)
4862 self.assertTrue(sessions[0].flags &
4863 self.config_flags.NAT_IS_EXT_HOST_VALID)
4864 self.vapi.nat44_del_session(
4865 address=sessions[0].inside_ip_address,
4866 port=sessions[0].inside_port,
4867 protocol=sessions[0].protocol,
4868 flags=(self.config_flags.NAT_IS_INSIDE |
4869 self.config_flags.NAT_IS_EXT_HOST_VALID),
4870 ext_host_address=sessions[0].ext_host_address,
4871 ext_host_port=sessions[0].ext_host_port)
4872 sessions = self.vapi.nat44_user_session_dump(user.ip4, 0)
4873 self.assertEqual(len(sessions), 2)
4876 self.vapi.nat44_forwarding_enable_disable(enable=0)
4877 flags = self.config_flags.NAT_IS_ADDR_ONLY
4878 self.vapi.nat44_add_del_static_mapping(
4880 local_ip_address=real_ip,
4881 external_ip_address=alias_ip,
4882 external_sw_if_index=0xFFFFFFFF,
4885 def test_static_lb(self):
4886 """ NAT44 local service load balancing """
4887 external_addr_n = self.nat_addr
4890 server1 = self.pg0.remote_hosts[0]
4891 server2 = self.pg0.remote_hosts[1]
4893 locals = [{'addr': server1.ip4,
4897 {'addr': server2.ip4,
4902 self.nat44_add_address(self.nat_addr)
4903 self.vapi.nat44_add_del_lb_static_mapping(
4905 external_addr=external_addr_n,
4906 external_port=external_port,
4907 protocol=IP_PROTOS.tcp,
4908 local_num=len(locals),
4910 flags = self.config_flags.NAT_IS_INSIDE
4911 self.vapi.nat44_interface_add_del_feature(
4912 sw_if_index=self.pg0.sw_if_index,
4913 flags=flags, is_add=1)
4914 self.vapi.nat44_interface_add_del_feature(
4915 sw_if_index=self.pg1.sw_if_index,
4918 # from client to service
4919 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
4920 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
4921 TCP(sport=12345, dport=external_port))
4922 self.pg1.add_stream(p)
4923 self.pg_enable_capture(self.pg_interfaces)
4925 capture = self.pg0.get_capture(1)
4931 self.assertIn(ip.dst, [server1.ip4, server2.ip4])
4932 if ip.dst == server1.ip4:
4936 self.assertEqual(tcp.dport, local_port)
4937 self.assert_packet_checksums_valid(p)
4939 self.logger.error(ppp("Unexpected or invalid packet:", p))
4942 # from service back to client
4943 p = (Ether(src=server.mac, dst=self.pg0.local_mac) /
4944 IP(src=server.ip4, dst=self.pg1.remote_ip4) /
4945 TCP(sport=local_port, dport=12345))
4946 self.pg0.add_stream(p)
4947 self.pg_enable_capture(self.pg_interfaces)
4949 capture = self.pg1.get_capture(1)
4954 self.assertEqual(ip.src, self.nat_addr)
4955 self.assertEqual(tcp.sport, external_port)
4956 self.assert_packet_checksums_valid(p)
4958 self.logger.error(ppp("Unexpected or invalid packet:", p))
4961 sessions = self.vapi.nat44_user_session_dump(server.ip4, 0)
4962 self.assertEqual(len(sessions), 1)
4963 self.assertTrue(sessions[0].flags &
4964 self.config_flags.NAT_IS_EXT_HOST_VALID)
4965 self.vapi.nat44_del_session(
4966 address=sessions[0].inside_ip_address,
4967 port=sessions[0].inside_port,
4968 protocol=sessions[0].protocol,
4969 flags=(self.config_flags.NAT_IS_INSIDE |
4970 self.config_flags.NAT_IS_EXT_HOST_VALID),
4971 ext_host_address=sessions[0].ext_host_address,
4972 ext_host_port=sessions[0].ext_host_port)
4973 sessions = self.vapi.nat44_user_session_dump(server.ip4, 0)
4974 self.assertEqual(len(sessions), 0)
4976 @unittest.skipUnless(running_extended_tests, "part of extended tests")
4977 def test_static_lb_multi_clients(self):
4978 """ NAT44 local service load balancing - multiple clients"""
4980 external_addr = self.nat_addr
4983 server1 = self.pg0.remote_hosts[0]
4984 server2 = self.pg0.remote_hosts[1]
4985 server3 = self.pg0.remote_hosts[2]
4987 locals = [{'addr': server1.ip4,
4991 {'addr': server2.ip4,
4996 self.nat44_add_address(self.nat_addr)
4997 self.vapi.nat44_add_del_lb_static_mapping(is_add=1,
4998 external_addr=external_addr,
4999 external_port=external_port,
5000 protocol=IP_PROTOS.tcp,
5001 local_num=len(locals),
5003 flags = self.config_flags.NAT_IS_INSIDE
5004 self.vapi.nat44_interface_add_del_feature(
5005 sw_if_index=self.pg0.sw_if_index,
5006 flags=flags, is_add=1)
5007 self.vapi.nat44_interface_add_del_feature(
5008 sw_if_index=self.pg1.sw_if_index,
5013 clients = ip4_range(self.pg1.remote_ip4, 10, 50)
5015 for client in clients:
5016 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
5017 IP(src=client, dst=self.nat_addr) /
5018 TCP(sport=12345, dport=external_port))
5020 self.pg1.add_stream(pkts)
5021 self.pg_enable_capture(self.pg_interfaces)
5023 capture = self.pg0.get_capture(len(pkts))
5025 if p[IP].dst == server1.ip4:
5029 self.assertGreater(server1_n, server2_n)
5032 'addr': server3.ip4,
5039 self.vapi.nat44_lb_static_mapping_add_del_local(
5041 external_addr=external_addr,
5042 external_port=external_port,
5044 protocol=IP_PROTOS.tcp)
5048 clients = ip4_range(self.pg1.remote_ip4, 60, 110)
5050 for client in clients:
5051 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
5052 IP(src=client, dst=self.nat_addr) /
5053 TCP(sport=12346, dport=external_port))
5055 self.assertGreater(len(pkts), 0)
5056 self.pg1.add_stream(pkts)
5057 self.pg_enable_capture(self.pg_interfaces)
5059 capture = self.pg0.get_capture(len(pkts))
5061 if p[IP].dst == server1.ip4:
5063 elif p[IP].dst == server2.ip4:
5067 self.assertGreater(server1_n, 0)
5068 self.assertGreater(server2_n, 0)
5069 self.assertGreater(server3_n, 0)
5072 'addr': server2.ip4,
5078 # remove one back-end
5079 self.vapi.nat44_lb_static_mapping_add_del_local(
5081 external_addr=external_addr,
5082 external_port=external_port,
5084 protocol=IP_PROTOS.tcp)
5088 self.pg1.add_stream(pkts)
5089 self.pg_enable_capture(self.pg_interfaces)
5091 capture = self.pg0.get_capture(len(pkts))
5093 if p[IP].dst == server1.ip4:
5095 elif p[IP].dst == server2.ip4:
5099 self.assertGreater(server1_n, 0)
5100 self.assertEqual(server2_n, 0)
5101 self.assertGreater(server3_n, 0)
5103 def test_static_lb_2(self):
5104 """ NAT44 local service load balancing (asymmetrical rule) """
5105 external_addr = self.nat_addr
5108 server1 = self.pg0.remote_hosts[0]
5109 server2 = self.pg0.remote_hosts[1]
5111 locals = [{'addr': server1.ip4,
5115 {'addr': server2.ip4,
5120 self.vapi.nat44_forwarding_enable_disable(enable=1)
5121 flags = self.config_flags.NAT_IS_OUT2IN_ONLY
5122 self.vapi.nat44_add_del_lb_static_mapping(is_add=1, flags=flags,
5123 external_addr=external_addr,
5124 external_port=external_port,
5125 protocol=IP_PROTOS.tcp,
5126 local_num=len(locals),
5128 flags = self.config_flags.NAT_IS_INSIDE
5129 self.vapi.nat44_interface_add_del_feature(
5130 sw_if_index=self.pg0.sw_if_index,
5131 flags=flags, is_add=1)
5132 self.vapi.nat44_interface_add_del_feature(
5133 sw_if_index=self.pg1.sw_if_index,
5136 # from client to service
5137 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
5138 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
5139 TCP(sport=12345, dport=external_port))
5140 self.pg1.add_stream(p)
5141 self.pg_enable_capture(self.pg_interfaces)
5143 capture = self.pg0.get_capture(1)
5149 self.assertIn(ip.dst, [server1.ip4, server2.ip4])
5150 if ip.dst == server1.ip4:
5154 self.assertEqual(tcp.dport, local_port)
5155 self.assert_packet_checksums_valid(p)
5157 self.logger.error(ppp("Unexpected or invalid packet:", p))
5160 # from service back to client
5161 p = (Ether(src=server.mac, dst=self.pg0.local_mac) /
5162 IP(src=server.ip4, dst=self.pg1.remote_ip4) /
5163 TCP(sport=local_port, dport=12345))
5164 self.pg0.add_stream(p)
5165 self.pg_enable_capture(self.pg_interfaces)
5167 capture = self.pg1.get_capture(1)
5172 self.assertEqual(ip.src, self.nat_addr)
5173 self.assertEqual(tcp.sport, external_port)
5174 self.assert_packet_checksums_valid(p)
5176 self.logger.error(ppp("Unexpected or invalid packet:", p))
5179 # from client to server (no translation)
5180 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
5181 IP(src=self.pg1.remote_ip4, dst=server1.ip4) /
5182 TCP(sport=12346, dport=local_port))
5183 self.pg1.add_stream(p)
5184 self.pg_enable_capture(self.pg_interfaces)
5186 capture = self.pg0.get_capture(1)
5192 self.assertEqual(ip.dst, server1.ip4)
5193 self.assertEqual(tcp.dport, local_port)
5194 self.assert_packet_checksums_valid(p)
5196 self.logger.error(ppp("Unexpected or invalid packet:", p))
5199 # from service back to client (no translation)
5200 p = (Ether(src=server1.mac, dst=self.pg0.local_mac) /
5201 IP(src=server1.ip4, dst=self.pg1.remote_ip4) /
5202 TCP(sport=local_port, dport=12346))
5203 self.pg0.add_stream(p)
5204 self.pg_enable_capture(self.pg_interfaces)
5206 capture = self.pg1.get_capture(1)
5211 self.assertEqual(ip.src, server1.ip4)
5212 self.assertEqual(tcp.sport, local_port)
5213 self.assert_packet_checksums_valid(p)
5215 self.logger.error(ppp("Unexpected or invalid packet:", p))
5218 def test_lb_affinity(self):
5219 """ NAT44 local service load balancing affinity """
5220 external_addr = self.nat_addr
5223 server1 = self.pg0.remote_hosts[0]
5224 server2 = self.pg0.remote_hosts[1]
5226 locals = [{'addr': server1.ip4,
5230 {'addr': server2.ip4,
5235 self.nat44_add_address(self.nat_addr)
5236 self.vapi.nat44_add_del_lb_static_mapping(is_add=1,
5237 external_addr=external_addr,
5238 external_port=external_port,
5239 protocol=IP_PROTOS.tcp,
5241 local_num=len(locals),
5243 flags = self.config_flags.NAT_IS_INSIDE
5244 self.vapi.nat44_interface_add_del_feature(
5245 sw_if_index=self.pg0.sw_if_index,
5246 flags=flags, is_add=1)
5247 self.vapi.nat44_interface_add_del_feature(
5248 sw_if_index=self.pg1.sw_if_index,
5251 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
5252 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
5253 TCP(sport=1025, dport=external_port))
5254 self.pg1.add_stream(p)
5255 self.pg_enable_capture(self.pg_interfaces)
5257 capture = self.pg0.get_capture(1)
5258 backend = capture[0][IP].dst
5260 sessions = self.vapi.nat44_user_session_dump(backend, 0)
5261 self.assertEqual(len(sessions), 1)
5262 self.assertTrue(sessions[0].flags &
5263 self.config_flags.NAT_IS_EXT_HOST_VALID)
5264 self.vapi.nat44_del_session(
5265 address=sessions[0].inside_ip_address,
5266 port=sessions[0].inside_port,
5267 protocol=sessions[0].protocol,
5268 flags=(self.config_flags.NAT_IS_INSIDE |
5269 self.config_flags.NAT_IS_EXT_HOST_VALID),
5270 ext_host_address=sessions[0].ext_host_address,
5271 ext_host_port=sessions[0].ext_host_port)
5274 for port in range(1030, 1100):
5275 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
5276 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
5277 TCP(sport=port, dport=external_port))
5279 self.pg1.add_stream(pkts)
5280 self.pg_enable_capture(self.pg_interfaces)
5282 capture = self.pg0.get_capture(len(pkts))
5284 self.assertEqual(p[IP].dst, backend)
5286 def test_unknown_proto(self):
5287 """ NAT44 translate packet with unknown protocol """
5288 self.nat44_add_address(self.nat_addr)
5289 flags = self.config_flags.NAT_IS_INSIDE
5290 self.vapi.nat44_interface_add_del_feature(
5291 sw_if_index=self.pg0.sw_if_index,
5292 flags=flags, is_add=1)
5293 self.vapi.nat44_interface_add_del_feature(
5294 sw_if_index=self.pg1.sw_if_index,
5298 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
5299 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
5300 TCP(sport=self.tcp_port_in, dport=20))
5301 self.pg0.add_stream(p)
5302 self.pg_enable_capture(self.pg_interfaces)
5304 p = self.pg1.get_capture(1)
5306 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
5307 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
5309 IP(src=self.pg2.remote_ip4, dst=self.pg2.remote_ip4) /
5310 TCP(sport=1234, dport=1234))
5311 self.pg0.add_stream(p)
5312 self.pg_enable_capture(self.pg_interfaces)
5314 p = self.pg1.get_capture(1)
5317 self.assertEqual(packet[IP].src, self.nat_addr)
5318 self.assertEqual(packet[IP].dst, self.pg1.remote_ip4)
5319 self.assertEqual(packet.haslayer(GRE), 1)
5320 self.assert_packet_checksums_valid(packet)
5322 self.logger.error(ppp("Unexpected or invalid packet:", packet))
5326 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
5327 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
5329 IP(src=self.pg2.remote_ip4, dst=self.pg2.remote_ip4) /
5330 TCP(sport=1234, dport=1234))
5331 self.pg1.add_stream(p)
5332 self.pg_enable_capture(self.pg_interfaces)
5334 p = self.pg0.get_capture(1)
5337 self.assertEqual(packet[IP].src, self.pg1.remote_ip4)
5338 self.assertEqual(packet[IP].dst, self.pg0.remote_ip4)
5339 self.assertEqual(packet.haslayer(GRE), 1)
5340 self.assert_packet_checksums_valid(packet)
5342 self.logger.error(ppp("Unexpected or invalid packet:", packet))
5345 def test_hairpinning_unknown_proto(self):
5346 """ NAT44 translate packet with unknown protocol - hairpinning """
5347 host = self.pg0.remote_hosts[0]
5348 server = self.pg0.remote_hosts[1]
5350 server_out_port = 8765
5351 server_nat_ip = "10.0.0.11"
5353 self.nat44_add_address(self.nat_addr)
5354 flags = self.config_flags.NAT_IS_INSIDE
5355 self.vapi.nat44_interface_add_del_feature(
5356 sw_if_index=self.pg0.sw_if_index,
5357 flags=flags, is_add=1)
5358 self.vapi.nat44_interface_add_del_feature(
5359 sw_if_index=self.pg1.sw_if_index,
5362 # add static mapping for server
5363 self.nat44_add_static_mapping(server.ip4, server_nat_ip)
5366 p = (Ether(src=host.mac, dst=self.pg0.local_mac) /
5367 IP(src=host.ip4, dst=server_nat_ip) /
5368 TCP(sport=host_in_port, dport=server_out_port))
5369 self.pg0.add_stream(p)
5370 self.pg_enable_capture(self.pg_interfaces)
5372 self.pg0.get_capture(1)
5374 p = (Ether(dst=self.pg0.local_mac, src=host.mac) /
5375 IP(src=host.ip4, dst=server_nat_ip) /
5377 IP(src=self.pg2.remote_ip4, dst=self.pg2.remote_ip4) /
5378 TCP(sport=1234, dport=1234))
5379 self.pg0.add_stream(p)
5380 self.pg_enable_capture(self.pg_interfaces)
5382 p = self.pg0.get_capture(1)
5385 self.assertEqual(packet[IP].src, self.nat_addr)
5386 self.assertEqual(packet[IP].dst, server.ip4)
5387 self.assertEqual(packet.haslayer(GRE), 1)
5388 self.assert_packet_checksums_valid(packet)
5390 self.logger.error(ppp("Unexpected or invalid packet:", packet))
5394 p = (Ether(dst=self.pg0.local_mac, src=server.mac) /
5395 IP(src=server.ip4, dst=self.nat_addr) /
5397 IP(src=self.pg2.remote_ip4, dst=self.pg2.remote_ip4) /
5398 TCP(sport=1234, dport=1234))
5399 self.pg0.add_stream(p)
5400 self.pg_enable_capture(self.pg_interfaces)
5402 p = self.pg0.get_capture(1)
5405 self.assertEqual(packet[IP].src, server_nat_ip)
5406 self.assertEqual(packet[IP].dst, host.ip4)
5407 self.assertEqual(packet.haslayer(GRE), 1)
5408 self.assert_packet_checksums_valid(packet)
5410 self.logger.error(ppp("Unexpected or invalid packet:", packet))
5413 def test_output_feature_and_service(self):
5414 """ NAT44 interface output feature and services """
5415 external_addr = '1.2.3.4'
5419 self.vapi.nat44_forwarding_enable_disable(enable=1)
5420 self.nat44_add_address(self.nat_addr)
5421 flags = self.config_flags.NAT_IS_ADDR_ONLY
5422 self.vapi.nat44_add_del_identity_mapping(
5423 ip_address=self.pg1.remote_ip4, sw_if_index=0xFFFFFFFF,
5424 flags=flags, is_add=1)
5425 flags = self.config_flags.NAT_IS_OUT2IN_ONLY
5426 self.nat44_add_static_mapping(self.pg0.remote_ip4, external_addr,
5427 local_port, external_port,
5428 proto=IP_PROTOS.tcp, flags=flags)
5429 flags = self.config_flags.NAT_IS_INSIDE
5430 self.vapi.nat44_interface_add_del_feature(
5431 sw_if_index=self.pg0.sw_if_index,
5433 self.vapi.nat44_interface_add_del_feature(
5434 sw_if_index=self.pg0.sw_if_index,
5435 flags=flags, is_add=1)
5436 self.vapi.nat44_interface_add_del_output_feature(
5438 sw_if_index=self.pg1.sw_if_index)
5440 # from client to service
5441 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
5442 IP(src=self.pg1.remote_ip4, dst=external_addr) /
5443 TCP(sport=12345, dport=external_port))
5444 self.pg1.add_stream(p)
5445 self.pg_enable_capture(self.pg_interfaces)
5447 capture = self.pg0.get_capture(1)
5452 self.assertEqual(ip.dst, self.pg0.remote_ip4)
5453 self.assertEqual(tcp.dport, local_port)
5454 self.assert_packet_checksums_valid(p)
5456 self.logger.error(ppp("Unexpected or invalid packet:", p))
5459 # from service back to client
5460 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5461 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
5462 TCP(sport=local_port, dport=12345))
5463 self.pg0.add_stream(p)
5464 self.pg_enable_capture(self.pg_interfaces)
5466 capture = self.pg1.get_capture(1)
5471 self.assertEqual(ip.src, external_addr)
5472 self.assertEqual(tcp.sport, external_port)
5473 self.assert_packet_checksums_valid(p)
5475 self.logger.error(ppp("Unexpected or invalid packet:", p))
5478 # from local network host to external network
5479 pkts = self.create_stream_in(self.pg0, self.pg1)
5480 self.pg0.add_stream(pkts)
5481 self.pg_enable_capture(self.pg_interfaces)
5483 capture = self.pg1.get_capture(len(pkts))
5484 self.verify_capture_out(capture, ignore_port=True)
5485 pkts = self.create_stream_in(self.pg0, self.pg1)
5486 self.pg0.add_stream(pkts)
5487 self.pg_enable_capture(self.pg_interfaces)
5489 capture = self.pg1.get_capture(len(pkts))
5490 self.verify_capture_out(capture, ignore_port=True)
5492 # from external network back to local network host
5493 pkts = self.create_stream_out(self.pg1)
5494 self.pg1.add_stream(pkts)
5495 self.pg_enable_capture(self.pg_interfaces)
5497 capture = self.pg0.get_capture(len(pkts))
5498 self.verify_capture_in(capture, self.pg0)
5500 def test_output_feature_and_service2(self):
5501 """ NAT44 interface output feature and service host direct access """
5502 self.vapi.nat44_forwarding_enable_disable(enable=1)
5503 self.nat44_add_address(self.nat_addr)
5504 self.vapi.nat44_interface_add_del_output_feature(
5506 sw_if_index=self.pg1.sw_if_index)
5508 # session initiated from service host - translate
5509 pkts = self.create_stream_in(self.pg0, self.pg1)
5510 self.pg0.add_stream(pkts)
5511 self.pg_enable_capture(self.pg_interfaces)
5513 capture = self.pg1.get_capture(len(pkts))
5514 self.verify_capture_out(capture, ignore_port=True)
5516 pkts = self.create_stream_out(self.pg1)
5517 self.pg1.add_stream(pkts)
5518 self.pg_enable_capture(self.pg_interfaces)
5520 capture = self.pg0.get_capture(len(pkts))
5521 self.verify_capture_in(capture, self.pg0)
5523 # session initiated from remote host - do not translate
5524 self.tcp_port_in = 60303
5525 self.udp_port_in = 60304
5526 self.icmp_id_in = 60305
5527 pkts = self.create_stream_out(self.pg1,
5528 self.pg0.remote_ip4,
5529 use_inside_ports=True)
5530 self.pg1.add_stream(pkts)
5531 self.pg_enable_capture(self.pg_interfaces)
5533 capture = self.pg0.get_capture(len(pkts))
5534 self.verify_capture_in(capture, self.pg0)
5536 pkts = self.create_stream_in(self.pg0, self.pg1)
5537 self.pg0.add_stream(pkts)
5538 self.pg_enable_capture(self.pg_interfaces)
5540 capture = self.pg1.get_capture(len(pkts))
5541 self.verify_capture_out(capture, nat_ip=self.pg0.remote_ip4,
5544 def test_output_feature_and_service3(self):
5545 """ NAT44 interface output feature and DST NAT """
5546 external_addr = '1.2.3.4'
5550 self.vapi.nat44_forwarding_enable_disable(enable=1)
5551 self.nat44_add_address(self.nat_addr)
5552 flags = self.config_flags.NAT_IS_OUT2IN_ONLY
5553 self.nat44_add_static_mapping(self.pg1.remote_ip4, external_addr,
5554 local_port, external_port,
5555 proto=IP_PROTOS.tcp, flags=flags)
5556 flags = self.config_flags.NAT_IS_INSIDE
5557 self.vapi.nat44_interface_add_del_feature(
5558 sw_if_index=self.pg0.sw_if_index,
5560 self.vapi.nat44_interface_add_del_feature(
5561 sw_if_index=self.pg0.sw_if_index,
5562 flags=flags, is_add=1)
5563 self.vapi.nat44_interface_add_del_output_feature(
5565 sw_if_index=self.pg1.sw_if_index)
5567 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5568 IP(src=self.pg0.remote_ip4, dst=external_addr) /
5569 TCP(sport=12345, dport=external_port))
5570 self.pg0.add_stream(p)
5571 self.pg_enable_capture(self.pg_interfaces)
5573 capture = self.pg1.get_capture(1)
5578 self.assertEqual(ip.src, self.pg0.remote_ip4)
5579 self.assertEqual(tcp.sport, 12345)
5580 self.assertEqual(ip.dst, self.pg1.remote_ip4)
5581 self.assertEqual(tcp.dport, local_port)
5582 self.assert_packet_checksums_valid(p)
5584 self.logger.error(ppp("Unexpected or invalid packet:", p))
5587 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
5588 IP(src=self.pg1.remote_ip4, dst=self.pg0.remote_ip4) /
5589 TCP(sport=local_port, dport=12345))
5590 self.pg1.add_stream(p)
5591 self.pg_enable_capture(self.pg_interfaces)
5593 capture = self.pg0.get_capture(1)
5598 self.assertEqual(ip.src, external_addr)
5599 self.assertEqual(tcp.sport, external_port)
5600 self.assertEqual(ip.dst, self.pg0.remote_ip4)
5601 self.assertEqual(tcp.dport, 12345)
5602 self.assert_packet_checksums_valid(p)
5604 self.logger.error(ppp("Unexpected or invalid packet:", p))
5607 def test_next_src_nat(self):
5608 """ On way back forward packet to nat44-in2out node. """
5609 twice_nat_addr = '10.0.1.3'
5612 post_twice_nat_port = 0
5614 self.vapi.nat44_forwarding_enable_disable(enable=1)
5615 self.nat44_add_address(twice_nat_addr, twice_nat=1)
5616 flags = (self.config_flags.NAT_IS_OUT2IN_ONLY |
5617 self.config_flags.NAT_IS_SELF_TWICE_NAT)
5618 self.nat44_add_static_mapping(self.pg6.remote_ip4, self.pg1.remote_ip4,
5619 local_port, external_port,
5620 proto=IP_PROTOS.tcp, vrf_id=1,
5622 self.vapi.nat44_interface_add_del_feature(
5623 sw_if_index=self.pg6.sw_if_index,
5626 p = (Ether(src=self.pg6.remote_mac, dst=self.pg6.local_mac) /
5627 IP(src=self.pg6.remote_ip4, dst=self.pg1.remote_ip4) /
5628 TCP(sport=12345, dport=external_port))
5629 self.pg6.add_stream(p)
5630 self.pg_enable_capture(self.pg_interfaces)
5632 capture = self.pg6.get_capture(1)
5637 self.assertEqual(ip.src, twice_nat_addr)
5638 self.assertNotEqual(tcp.sport, 12345)
5639 post_twice_nat_port = tcp.sport
5640 self.assertEqual(ip.dst, self.pg6.remote_ip4)
5641 self.assertEqual(tcp.dport, local_port)
5642 self.assert_packet_checksums_valid(p)
5644 self.logger.error(ppp("Unexpected or invalid packet:", p))
5647 p = (Ether(src=self.pg6.remote_mac, dst=self.pg6.local_mac) /
5648 IP(src=self.pg6.remote_ip4, dst=twice_nat_addr) /
5649 TCP(sport=local_port, dport=post_twice_nat_port))
5650 self.pg6.add_stream(p)
5651 self.pg_enable_capture(self.pg_interfaces)
5653 capture = self.pg6.get_capture(1)
5658 self.assertEqual(ip.src, self.pg1.remote_ip4)
5659 self.assertEqual(tcp.sport, external_port)
5660 self.assertEqual(ip.dst, self.pg6.remote_ip4)
5661 self.assertEqual(tcp.dport, 12345)
5662 self.assert_packet_checksums_valid(p)
5664 self.logger.error(ppp("Unexpected or invalid packet:", p))
5667 def twice_nat_common(self, self_twice_nat=False, same_pg=False, lb=False,
5669 twice_nat_addr = '10.0.1.3'
5677 port_in1 = port_in + 1
5678 port_in2 = port_in + 2
5683 server1 = self.pg0.remote_hosts[0]
5684 server2 = self.pg0.remote_hosts[1]
5696 eh_translate = ((not self_twice_nat) or (not lb and same_pg) or
5699 self.nat44_add_address(self.nat_addr)
5700 self.nat44_add_address(twice_nat_addr, twice_nat=1)
5704 flags |= self.config_flags.NAT_IS_SELF_TWICE_NAT
5706 flags |= self.config_flags.NAT_IS_TWICE_NAT
5709 self.nat44_add_static_mapping(pg0.remote_ip4, self.nat_addr,
5711 proto=IP_PROTOS.tcp,
5714 locals = [{'addr': server1.ip4,
5718 {'addr': server2.ip4,
5722 out_addr = self.nat_addr
5724 self.vapi.nat44_add_del_lb_static_mapping(is_add=1, flags=flags,
5725 external_addr=out_addr,
5726 external_port=port_out,
5727 protocol=IP_PROTOS.tcp,
5728 local_num=len(locals),
5730 flags = self.config_flags.NAT_IS_INSIDE
5731 self.vapi.nat44_interface_add_del_feature(
5732 sw_if_index=pg0.sw_if_index,
5733 flags=flags, is_add=1)
5734 self.vapi.nat44_interface_add_del_feature(
5735 sw_if_index=pg1.sw_if_index,
5742 assert client_id is not None
5744 client = self.pg0.remote_hosts[0]
5745 elif client_id == 2:
5746 client = self.pg0.remote_hosts[1]
5748 client = pg1.remote_hosts[0]
5749 p = (Ether(src=pg1.remote_mac, dst=pg1.local_mac) /
5750 IP(src=client.ip4, dst=self.nat_addr) /
5751 TCP(sport=eh_port_out, dport=port_out))
5753 self.pg_enable_capture(self.pg_interfaces)
5755 capture = pg0.get_capture(1)
5761 if ip.dst == server1.ip4:
5767 self.assertEqual(ip.dst, server.ip4)
5769 self.assertIn(tcp.dport, [port_in1, port_in2])
5771 self.assertEqual(tcp.dport, port_in)
5773 self.assertEqual(ip.src, twice_nat_addr)
5774 self.assertNotEqual(tcp.sport, eh_port_out)
5776 self.assertEqual(ip.src, client.ip4)
5777 self.assertEqual(tcp.sport, eh_port_out)
5779 eh_port_in = tcp.sport
5780 saved_port_in = tcp.dport
5781 self.assert_packet_checksums_valid(p)
5783 self.logger.error(ppp("Unexpected or invalid packet:", p))
5786 p = (Ether(src=server.mac, dst=pg0.local_mac) /
5787 IP(src=server.ip4, dst=eh_addr_in) /
5788 TCP(sport=saved_port_in, dport=eh_port_in))
5790 self.pg_enable_capture(self.pg_interfaces)
5792 capture = pg1.get_capture(1)
5797 self.assertEqual(ip.dst, client.ip4)
5798 self.assertEqual(ip.src, self.nat_addr)
5799 self.assertEqual(tcp.dport, eh_port_out)
5800 self.assertEqual(tcp.sport, port_out)
5801 self.assert_packet_checksums_valid(p)
5803 self.logger.error(ppp("Unexpected or invalid packet:", p))
5807 sessions = self.vapi.nat44_user_session_dump(server.ip4, 0)
5808 self.assertEqual(len(sessions), 1)
5809 self.assertTrue(sessions[0].flags &
5810 self.config_flags.NAT_IS_EXT_HOST_VALID)
5811 self.assertTrue(sessions[0].flags &
5812 self.config_flags.NAT_IS_TWICE_NAT)
5813 self.logger.info(self.vapi.cli("show nat44 sessions detail"))
5814 self.vapi.nat44_del_session(
5815 address=sessions[0].inside_ip_address,
5816 port=sessions[0].inside_port,
5817 protocol=sessions[0].protocol,
5818 flags=(self.config_flags.NAT_IS_INSIDE |
5819 self.config_flags.NAT_IS_EXT_HOST_VALID),
5820 ext_host_address=sessions[0].ext_host_nat_address,
5821 ext_host_port=sessions[0].ext_host_nat_port)
5822 sessions = self.vapi.nat44_user_session_dump(server.ip4, 0)
5823 self.assertEqual(len(sessions), 0)
5825 def test_twice_nat(self):
5827 self.twice_nat_common()
5829 def test_self_twice_nat_positive(self):
5830 """ Self Twice NAT44 (positive test) """
5831 self.twice_nat_common(self_twice_nat=True, same_pg=True)
5833 def test_self_twice_nat_negative(self):
5834 """ Self Twice NAT44 (negative test) """
5835 self.twice_nat_common(self_twice_nat=True)
5837 def test_twice_nat_lb(self):
5838 """ Twice NAT44 local service load balancing """
5839 self.twice_nat_common(lb=True)
5841 def test_self_twice_nat_lb_positive(self):
5842 """ Self Twice NAT44 local service load balancing (positive test) """
5843 self.twice_nat_common(lb=True, self_twice_nat=True, same_pg=True,
5846 def test_self_twice_nat_lb_negative(self):
5847 """ Self Twice NAT44 local service load balancing (negative test) """
5848 self.twice_nat_common(lb=True, self_twice_nat=True, same_pg=True,
5851 def test_twice_nat_interface_addr(self):
5852 """ Acquire twice NAT44 addresses from interface """
5853 flags = self.config_flags.NAT_IS_TWICE_NAT
5854 self.vapi.nat44_add_del_interface_addr(
5856 sw_if_index=self.pg3.sw_if_index,
5859 # no address in NAT pool
5860 adresses = self.vapi.nat44_address_dump()
5861 self.assertEqual(0, len(adresses))
5863 # configure interface address and check NAT address pool
5864 self.pg3.config_ip4()
5865 adresses = self.vapi.nat44_address_dump()
5866 self.assertEqual(1, len(adresses))
5867 self.assertEqual(str(adresses[0].ip_address),
5869 self.assertEqual(adresses[0].flags, flags)
5871 # remove interface address and check NAT address pool
5872 self.pg3.unconfig_ip4()
5873 adresses = self.vapi.nat44_address_dump()
5874 self.assertEqual(0, len(adresses))
5876 def test_tcp_close(self):
5877 """ Close TCP session from inside network - output feature """
5878 self.vapi.nat44_forwarding_enable_disable(enable=1)
5879 self.nat44_add_address(self.pg1.local_ip4)
5880 twice_nat_addr = '10.0.1.3'
5881 service_ip = '192.168.16.150'
5882 self.nat44_add_address(twice_nat_addr, twice_nat=1)
5883 flags = self.config_flags.NAT_IS_INSIDE
5884 self.vapi.nat44_interface_add_del_feature(
5885 sw_if_index=self.pg0.sw_if_index,
5887 self.vapi.nat44_interface_add_del_feature(
5888 sw_if_index=self.pg0.sw_if_index,
5889 flags=flags, is_add=1)
5890 self.vapi.nat44_interface_add_del_output_feature(
5892 sw_if_index=self.pg1.sw_if_index)
5893 flags = (self.config_flags.NAT_IS_OUT2IN_ONLY |
5894 self.config_flags.NAT_IS_TWICE_NAT)
5895 self.nat44_add_static_mapping(self.pg0.remote_ip4,
5899 proto=IP_PROTOS.tcp,
5901 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4, 0)
5902 start_sessnum = len(sessions)
5904 # SYN packet out->in
5905 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
5906 IP(src=self.pg1.remote_ip4, dst=service_ip) /
5907 TCP(sport=33898, dport=80, flags="S"))
5908 self.pg1.add_stream(p)
5909 self.pg_enable_capture(self.pg_interfaces)
5911 capture = self.pg0.get_capture(1)
5913 tcp_port = p[TCP].sport
5915 # SYN + ACK packet in->out
5916 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5917 IP(src=self.pg0.remote_ip4, dst=twice_nat_addr) /
5918 TCP(sport=80, dport=tcp_port, flags="SA"))
5919 self.pg0.add_stream(p)
5920 self.pg_enable_capture(self.pg_interfaces)
5922 self.pg1.get_capture(1)
5924 # ACK packet out->in
5925 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
5926 IP(src=self.pg1.remote_ip4, dst=service_ip) /
5927 TCP(sport=33898, dport=80, flags="A"))
5928 self.pg1.add_stream(p)
5929 self.pg_enable_capture(self.pg_interfaces)
5931 self.pg0.get_capture(1)
5933 # FIN packet in -> out
5934 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5935 IP(src=self.pg0.remote_ip4, dst=twice_nat_addr) /
5936 TCP(sport=80, dport=tcp_port, flags="FA", seq=100, ack=300))
5937 self.pg0.add_stream(p)
5938 self.pg_enable_capture(self.pg_interfaces)
5940 self.pg1.get_capture(1)
5942 # FIN+ACK packet out -> in
5943 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
5944 IP(src=self.pg1.remote_ip4, dst=service_ip) /
5945 TCP(sport=33898, dport=80, flags="FA", seq=300, ack=101))
5946 self.pg1.add_stream(p)
5947 self.pg_enable_capture(self.pg_interfaces)
5949 self.pg0.get_capture(1)
5951 # ACK packet in -> out
5952 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5953 IP(src=self.pg0.remote_ip4, dst=twice_nat_addr) /
5954 TCP(sport=80, dport=tcp_port, flags="A", seq=101, ack=301))
5955 self.pg0.add_stream(p)
5956 self.pg_enable_capture(self.pg_interfaces)
5958 self.pg1.get_capture(1)
5960 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4,
5962 self.assertEqual(len(sessions) - start_sessnum, 0)
5964 def test_tcp_session_close_in(self):
5965 """ Close TCP session from inside network """
5966 self.tcp_port_out = 10505
5967 self.nat44_add_address(self.nat_addr)
5968 flags = self.config_flags.NAT_IS_TWICE_NAT
5969 self.nat44_add_static_mapping(self.pg0.remote_ip4,
5973 proto=IP_PROTOS.tcp,
5975 flags = self.config_flags.NAT_IS_INSIDE
5976 self.vapi.nat44_interface_add_del_feature(
5977 sw_if_index=self.pg0.sw_if_index,
5978 flags=flags, is_add=1)
5979 self.vapi.nat44_interface_add_del_feature(
5980 sw_if_index=self.pg1.sw_if_index,
5983 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4, 0)
5984 start_sessnum = len(sessions)
5986 self.vapi.nat_set_timeouts(udp=300, tcp_established=7440,
5987 tcp_transitory=2, icmp=5)
5989 self.initiate_tcp_session(self.pg0, self.pg1)
5991 # FIN packet in -> out
5992 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5993 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
5994 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
5995 flags="FA", seq=100, ack=300))
5996 self.pg0.add_stream(p)
5997 self.pg_enable_capture(self.pg_interfaces)
5999 self.pg1.get_capture(1)
6003 # ACK packet out -> in
6004 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
6005 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
6006 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
6007 flags="A", seq=300, ack=101))
6010 # FIN packet out -> in
6011 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
6012 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
6013 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
6014 flags="FA", seq=300, ack=101))
6017 self.pg1.add_stream(pkts)
6018 self.pg_enable_capture(self.pg_interfaces)
6020 self.pg0.get_capture(2)
6022 # ACK packet in -> out
6023 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6024 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6025 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
6026 flags="A", seq=101, ack=301))
6027 self.pg0.add_stream(p)
6028 self.pg_enable_capture(self.pg_interfaces)
6030 self.pg1.get_capture(1)
6032 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4, 0)
6033 self.assertEqual(len(sessions) - start_sessnum, 1)
6035 stats = self.statistics.get_counter(
6036 '/err/nat44-ed-out2in/drops due to TCP in transitory timeout')
6037 out2in_drops = stats[0]
6038 stats = self.statistics.get_counter(
6039 '/err/nat44-ed-in2out/drops due to TCP in transitory timeout')
6040 in2out_drops = stats[0]
6042 # extra FIN packet out -> in - this should be dropped
6043 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
6044 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
6045 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
6046 flags="FA", seq=300, ack=101))
6048 self.pg1.add_stream(p)
6049 self.pg_enable_capture(self.pg_interfaces)
6051 self.pg0.assert_nothing_captured()
6053 # extra ACK packet in -> out - this should be dropped
6054 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6055 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6056 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
6057 flags="A", seq=101, ack=301))
6058 self.pg0.add_stream(p)
6059 self.pg_enable_capture(self.pg_interfaces)
6061 self.pg1.assert_nothing_captured()
6063 stats = self.statistics.get_counter(
6064 '/err/nat44-ed-out2in/drops due to TCP in transitory timeout')
6065 self.assertEqual(stats[0] - out2in_drops, 1)
6066 stats = self.statistics.get_counter(
6067 '/err/nat44-ed-in2out/drops due to TCP in transitory timeout')
6068 self.assertEqual(stats[0] - in2out_drops, 1)
6071 # extra ACK packet in -> out - this will cause session to be wiped
6072 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6073 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6074 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
6075 flags="A", seq=101, ack=301))
6076 self.pg0.add_stream(p)
6077 self.pg_enable_capture(self.pg_interfaces)
6079 self.pg1.assert_nothing_captured()
6080 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4, 0)
6081 self.assertEqual(len(sessions) - start_sessnum, 0)
6083 def test_tcp_session_close_out(self):
6084 """ Close TCP session from outside network """
6085 self.tcp_port_out = 10505
6086 self.nat44_add_address(self.nat_addr)
6087 flags = self.config_flags.NAT_IS_TWICE_NAT
6088 self.nat44_add_static_mapping(self.pg0.remote_ip4,
6092 proto=IP_PROTOS.tcp,
6094 flags = self.config_flags.NAT_IS_INSIDE
6095 self.vapi.nat44_interface_add_del_feature(
6096 sw_if_index=self.pg0.sw_if_index,
6097 flags=flags, is_add=1)
6098 self.vapi.nat44_interface_add_del_feature(
6099 sw_if_index=self.pg1.sw_if_index,
6102 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4, 0)
6103 start_sessnum = len(sessions)
6105 self.vapi.nat_set_timeouts(udp=300, tcp_established=7440,
6106 tcp_transitory=2, icmp=5)
6108 self.initiate_tcp_session(self.pg0, self.pg1)
6110 # FIN packet out -> in
6111 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
6112 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
6113 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
6114 flags="FA", seq=100, ack=300))
6115 self.pg1.add_stream(p)
6116 self.pg_enable_capture(self.pg_interfaces)
6118 self.pg0.get_capture(1)
6120 # FIN+ACK packet in -> out
6121 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6122 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6123 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
6124 flags="FA", seq=300, ack=101))
6126 self.pg0.add_stream(p)
6127 self.pg_enable_capture(self.pg_interfaces)
6129 self.pg1.get_capture(1)
6131 # ACK packet out -> in
6132 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
6133 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
6134 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
6135 flags="A", seq=101, ack=301))
6136 self.pg1.add_stream(p)
6137 self.pg_enable_capture(self.pg_interfaces)
6139 self.pg0.get_capture(1)
6141 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4, 0)
6142 self.assertEqual(len(sessions) - start_sessnum, 1)
6144 stats = self.statistics.get_counter(
6145 '/err/nat44-ed-out2in/drops due to TCP in transitory timeout')
6146 out2in_drops = stats[0]
6147 stats = self.statistics.get_counter(
6148 '/err/nat44-ed-in2out/drops due to TCP in transitory timeout')
6149 in2out_drops = stats[0]
6151 # extra FIN packet out -> in - this should be dropped
6152 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
6153 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
6154 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
6155 flags="FA", seq=300, ack=101))
6157 self.pg1.add_stream(p)
6158 self.pg_enable_capture(self.pg_interfaces)
6160 self.pg0.assert_nothing_captured()
6162 # extra ACK packet in -> out - this should be dropped
6163 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6164 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6165 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
6166 flags="A", seq=101, ack=301))
6167 self.pg0.add_stream(p)
6168 self.pg_enable_capture(self.pg_interfaces)
6170 self.pg1.assert_nothing_captured()
6172 stats = self.statistics.get_counter(
6173 '/err/nat44-ed-out2in/drops due to TCP in transitory timeout')
6174 self.assertEqual(stats[0] - out2in_drops, 1)
6175 stats = self.statistics.get_counter(
6176 '/err/nat44-ed-in2out/drops due to TCP in transitory timeout')
6177 self.assertEqual(stats[0] - in2out_drops, 1)
6180 # extra ACK packet in -> out - this will cause session to be wiped
6181 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6182 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6183 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
6184 flags="A", seq=101, ack=301))
6185 self.pg0.add_stream(p)
6186 self.pg_enable_capture(self.pg_interfaces)
6188 self.pg1.assert_nothing_captured()
6189 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4, 0)
6190 self.assertEqual(len(sessions) - start_sessnum, 0)
6192 def test_tcp_session_close_simultaneous(self):
6193 """ Close TCP session from inside network """
6194 self.tcp_port_out = 10505
6195 self.nat44_add_address(self.nat_addr)
6196 flags = self.config_flags.NAT_IS_TWICE_NAT
6197 self.nat44_add_static_mapping(self.pg0.remote_ip4,
6201 proto=IP_PROTOS.tcp,
6203 flags = self.config_flags.NAT_IS_INSIDE
6204 self.vapi.nat44_interface_add_del_feature(
6205 sw_if_index=self.pg0.sw_if_index,
6206 flags=flags, is_add=1)
6207 self.vapi.nat44_interface_add_del_feature(
6208 sw_if_index=self.pg1.sw_if_index,
6211 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4, 0)
6212 start_sessnum = len(sessions)
6214 self.vapi.nat_set_timeouts(udp=300, tcp_established=7440,
6215 tcp_transitory=2, icmp=5)
6217 self.initiate_tcp_session(self.pg0, self.pg1)
6219 # FIN packet in -> out
6220 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6221 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6222 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
6223 flags="FA", seq=100, ack=300))
6224 self.pg0.add_stream(p)
6225 self.pg_enable_capture(self.pg_interfaces)
6227 self.pg1.get_capture(1)
6229 # FIN packet out -> in
6230 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
6231 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
6232 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
6233 flags="FA", seq=300, ack=100))
6234 self.pg1.add_stream(p)
6235 self.pg_enable_capture(self.pg_interfaces)
6237 self.pg0.get_capture(1)
6239 # ACK packet in -> out
6240 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6241 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6242 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
6243 flags="A", seq=101, ack=301))
6244 self.pg0.add_stream(p)
6245 self.pg_enable_capture(self.pg_interfaces)
6247 self.pg1.get_capture(1)
6249 # ACK packet out -> in
6250 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
6251 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
6252 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
6253 flags="A", seq=301, ack=101))
6254 self.pg1.add_stream(p)
6255 self.pg_enable_capture(self.pg_interfaces)
6257 self.pg0.get_capture(1)
6259 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4, 0)
6260 self.assertEqual(len(sessions) - start_sessnum, 1)
6262 stats = self.statistics.get_counter(
6263 '/err/nat44-ed-out2in/drops due to TCP in transitory timeout')
6264 out2in_drops = stats[0]
6265 stats = self.statistics.get_counter(
6266 '/err/nat44-ed-in2out/drops due to TCP in transitory timeout')
6267 in2out_drops = stats[0]
6269 # extra FIN packet out -> in - this should be dropped
6270 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
6271 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
6272 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
6273 flags="FA", seq=300, ack=101))
6275 self.pg1.add_stream(p)
6276 self.pg_enable_capture(self.pg_interfaces)
6278 self.pg0.assert_nothing_captured()
6280 # extra ACK packet in -> out - this should be dropped
6281 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6282 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6283 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
6284 flags="A", seq=101, ack=301))
6285 self.pg0.add_stream(p)
6286 self.pg_enable_capture(self.pg_interfaces)
6288 self.pg1.assert_nothing_captured()
6290 stats = self.statistics.get_counter(
6291 '/err/nat44-ed-out2in/drops due to TCP in transitory timeout')
6292 self.assertEqual(stats[0] - out2in_drops, 1)
6293 stats = self.statistics.get_counter(
6294 '/err/nat44-ed-in2out/drops due to TCP in transitory timeout')
6295 self.assertEqual(stats[0] - in2out_drops, 1)
6298 # extra ACK packet in -> out - this will cause session to be wiped
6299 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6300 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6301 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
6302 flags="A", seq=101, ack=301))
6303 self.pg0.add_stream(p)
6304 self.pg_enable_capture(self.pg_interfaces)
6306 self.pg1.assert_nothing_captured()
6307 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4, 0)
6308 self.assertEqual(len(sessions) - start_sessnum, 0)
6310 def test_one_armed_nat44_static(self):
6311 """ One armed NAT44 and 1:1 NAPT asymmetrical rule """
6312 remote_host = self.pg4.remote_hosts[0]
6313 local_host = self.pg4.remote_hosts[1]
6318 self.vapi.nat44_forwarding_enable_disable(enable=1)
6319 self.nat44_add_address(self.nat_addr, twice_nat=1)
6320 flags = (self.config_flags.NAT_IS_OUT2IN_ONLY |
6321 self.config_flags.NAT_IS_TWICE_NAT)
6322 self.nat44_add_static_mapping(local_host.ip4, self.nat_addr,
6323 local_port, external_port,
6324 proto=IP_PROTOS.tcp, flags=flags)
6325 flags = self.config_flags.NAT_IS_INSIDE
6326 self.vapi.nat44_interface_add_del_feature(
6327 sw_if_index=self.pg4.sw_if_index,
6329 self.vapi.nat44_interface_add_del_feature(
6330 sw_if_index=self.pg4.sw_if_index,
6331 flags=flags, is_add=1)
6333 # from client to service
6334 p = (Ether(src=self.pg4.remote_mac, dst=self.pg4.local_mac) /
6335 IP(src=remote_host.ip4, dst=self.nat_addr) /
6336 TCP(sport=12345, dport=external_port))
6337 self.pg4.add_stream(p)
6338 self.pg_enable_capture(self.pg_interfaces)
6340 capture = self.pg4.get_capture(1)
6345 self.assertEqual(ip.dst, local_host.ip4)
6346 self.assertEqual(ip.src, self.nat_addr)
6347 self.assertEqual(tcp.dport, local_port)
6348 self.assertNotEqual(tcp.sport, 12345)
6349 eh_port_in = tcp.sport
6350 self.assert_packet_checksums_valid(p)
6352 self.logger.error(ppp("Unexpected or invalid packet:", p))
6355 # from service back to client
6356 p = (Ether(src=self.pg4.remote_mac, dst=self.pg4.local_mac) /
6357 IP(src=local_host.ip4, dst=self.nat_addr) /
6358 TCP(sport=local_port, dport=eh_port_in))
6359 self.pg4.add_stream(p)
6360 self.pg_enable_capture(self.pg_interfaces)
6362 capture = self.pg4.get_capture(1)
6367 self.assertEqual(ip.src, self.nat_addr)
6368 self.assertEqual(ip.dst, remote_host.ip4)
6369 self.assertEqual(tcp.sport, external_port)
6370 self.assertEqual(tcp.dport, 12345)
6371 self.assert_packet_checksums_valid(p)
6373 self.logger.error(ppp("Unexpected or invalid packet:", p))
6376 def test_static_with_port_out2(self):
6377 """ 1:1 NAPT asymmetrical rule """
6382 self.vapi.nat44_forwarding_enable_disable(enable=1)
6383 flags = self.config_flags.NAT_IS_OUT2IN_ONLY
6384 self.nat44_add_static_mapping(self.pg0.remote_ip4, self.nat_addr,
6385 local_port, external_port,
6386 proto=IP_PROTOS.tcp, flags=flags)
6387 flags = self.config_flags.NAT_IS_INSIDE
6388 self.vapi.nat44_interface_add_del_feature(
6389 sw_if_index=self.pg0.sw_if_index,
6390 flags=flags, is_add=1)
6391 self.vapi.nat44_interface_add_del_feature(
6392 sw_if_index=self.pg1.sw_if_index,
6395 # from client to service
6396 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
6397 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
6398 TCP(sport=12345, dport=external_port))
6399 self.pg1.add_stream(p)
6400 self.pg_enable_capture(self.pg_interfaces)
6402 capture = self.pg0.get_capture(1)
6407 self.assertEqual(ip.dst, self.pg0.remote_ip4)
6408 self.assertEqual(tcp.dport, local_port)
6409 self.assert_packet_checksums_valid(p)
6411 self.logger.error(ppp("Unexpected or invalid packet:", p))
6415 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
6416 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6417 ICMP(type=11) / capture[0][IP])
6418 self.pg0.add_stream(p)
6419 self.pg_enable_capture(self.pg_interfaces)
6421 capture = self.pg1.get_capture(1)
6424 self.assertEqual(p[IP].src, self.nat_addr)
6426 self.assertEqual(inner.dst, self.nat_addr)
6427 self.assertEqual(inner[TCPerror].dport, external_port)
6429 self.logger.error(ppp("Unexpected or invalid packet:", p))
6432 # from service back to client
6433 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6434 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6435 TCP(sport=local_port, dport=12345))
6436 self.pg0.add_stream(p)
6437 self.pg_enable_capture(self.pg_interfaces)
6439 capture = self.pg1.get_capture(1)
6444 self.assertEqual(ip.src, self.nat_addr)
6445 self.assertEqual(tcp.sport, external_port)
6446 self.assert_packet_checksums_valid(p)
6448 self.logger.error(ppp("Unexpected or invalid packet:", p))
6452 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
6453 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
6454 ICMP(type=11) / capture[0][IP])
6455 self.pg1.add_stream(p)
6456 self.pg_enable_capture(self.pg_interfaces)
6458 capture = self.pg0.get_capture(1)
6461 self.assertEqual(p[IP].dst, self.pg0.remote_ip4)
6463 self.assertEqual(inner.src, self.pg0.remote_ip4)
6464 self.assertEqual(inner[TCPerror].sport, local_port)
6466 self.logger.error(ppp("Unexpected or invalid packet:", p))
6469 # from client to server (no translation)
6470 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
6471 IP(src=self.pg1.remote_ip4, dst=self.pg0.remote_ip4) /
6472 TCP(sport=12346, dport=local_port))
6473 self.pg1.add_stream(p)
6474 self.pg_enable_capture(self.pg_interfaces)
6476 capture = self.pg0.get_capture(1)
6481 self.assertEqual(ip.dst, self.pg0.remote_ip4)
6482 self.assertEqual(tcp.dport, local_port)
6483 self.assert_packet_checksums_valid(p)
6485 self.logger.error(ppp("Unexpected or invalid packet:", p))
6488 # from service back to client (no translation)
6489 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6490 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6491 TCP(sport=local_port, dport=12346))
6492 self.pg0.add_stream(p)
6493 self.pg_enable_capture(self.pg_interfaces)
6495 capture = self.pg1.get_capture(1)
6500 self.assertEqual(ip.src, self.pg0.remote_ip4)
6501 self.assertEqual(tcp.sport, local_port)
6502 self.assert_packet_checksums_valid(p)
6504 self.logger.error(ppp("Unexpected or invalid packet:", p))
6507 def test_output_feature(self):
6508 """ NAT44 interface output feature (in2out postrouting) """
6509 self.vapi.nat44_forwarding_enable_disable(enable=1)
6510 self.nat44_add_address(self.nat_addr)
6511 self.vapi.nat44_interface_add_del_feature(
6512 sw_if_index=self.pg0.sw_if_index,
6514 self.vapi.nat44_interface_add_del_output_feature(
6516 sw_if_index=self.pg1.sw_if_index)
6519 pkts = self.create_stream_in(self.pg0, self.pg1)
6520 self.pg0.add_stream(pkts)
6521 self.pg_enable_capture(self.pg_interfaces)
6523 capture = self.pg1.get_capture(len(pkts))
6524 self.verify_capture_out(capture, ignore_port=True)
6527 pkts = self.create_stream_out(self.pg1)
6528 self.pg1.add_stream(pkts)
6529 self.pg_enable_capture(self.pg_interfaces)
6531 capture = self.pg0.get_capture(len(pkts))
6532 self.verify_capture_in(capture, self.pg0)
6534 def test_output_feature_stateful_acl(self):
6535 """ NAT44 endpoint-dependent output feature works with stateful ACL """
6536 self.nat44_add_address(self.nat_addr)
6537 self.vapi.nat44_interface_add_del_output_feature(
6538 sw_if_index=self.pg0.sw_if_index,
6539 flags=self.config_flags.NAT_IS_INSIDE,
6541 self.vapi.nat44_interface_add_del_output_feature(
6542 sw_if_index=self.pg1.sw_if_index,
6543 flags=self.config_flags.NAT_IS_OUTSIDE,
6546 # First ensure that the NAT is working sans ACL
6548 # send packets out2in, no sessions yet so packets should drop
6549 pkts_out2in = self.create_stream_out(self.pg1)
6550 self.send_and_assert_no_replies(self.pg1, pkts_out2in)
6552 # send packets into inside intf, ensure received via outside intf
6553 pkts_in2out = self.create_stream_in(self.pg0, self.pg1)
6554 capture = self.send_and_expect(self.pg0, pkts_in2out, self.pg1,
6556 self.verify_capture_out(capture, ignore_port=True)
6558 # send out2in again, with sessions created it should work now
6559 pkts_out2in = self.create_stream_out(self.pg1)
6560 capture = self.send_and_expect(self.pg1, pkts_out2in, self.pg0,
6562 self.verify_capture_in(capture, self.pg0)
6564 # Create an ACL blocking everything
6565 out2in_deny_rule = AclRule(is_permit=0)
6566 out2in_acl = VppAcl(self, rules=[out2in_deny_rule])
6567 out2in_acl.add_vpp_config()
6569 # create an ACL to permit/reflect everything
6570 in2out_reflect_rule = AclRule(is_permit=2)
6571 in2out_acl = VppAcl(self, rules=[in2out_reflect_rule])
6572 in2out_acl.add_vpp_config()
6574 # apply as input acl on interface and confirm it blocks everything
6575 acl_if = VppAclInterface(self, sw_if_index=self.pg1.sw_if_index,
6576 n_input=1, acls=[out2in_acl])
6577 acl_if.add_vpp_config()
6578 self.send_and_assert_no_replies(self.pg1, pkts_out2in)
6581 acl_if.acls = [out2in_acl, in2out_acl]
6582 acl_if.add_vpp_config()
6583 # send in2out to generate ACL state (NAT state was created earlier)
6584 capture = self.send_and_expect(self.pg0, pkts_in2out, self.pg1,
6586 self.verify_capture_out(capture, ignore_port=True)
6588 # send out2in again. ACL state exists so it should work now.
6589 # TCP packets with the syn flag set also need the ack flag
6590 for p in pkts_out2in:
6591 if p.haslayer(TCP) and p[TCP].flags & 0x02:
6592 p[TCP].flags |= 0x10
6593 capture = self.send_and_expect(self.pg1, pkts_out2in, self.pg0,
6595 self.verify_capture_in(capture, self.pg0)
6596 self.logger.info(self.vapi.cli("show trace"))
6598 def test_multiple_vrf(self):
6599 """ Multiple VRF setup """
6600 external_addr = '1.2.3.4'
6605 self.vapi.nat44_forwarding_enable_disable(enable=1)
6606 self.nat44_add_address(self.nat_addr)
6607 flags = self.config_flags.NAT_IS_INSIDE
6608 self.vapi.nat44_interface_add_del_feature(
6609 sw_if_index=self.pg0.sw_if_index,
6611 self.vapi.nat44_interface_add_del_feature(
6612 sw_if_index=self.pg0.sw_if_index,
6613 is_add=1, flags=flags)
6614 self.vapi.nat44_interface_add_del_output_feature(
6615 sw_if_index=self.pg1.sw_if_index,
6617 self.vapi.nat44_interface_add_del_feature(
6618 sw_if_index=self.pg5.sw_if_index,
6620 self.vapi.nat44_interface_add_del_feature(
6621 sw_if_index=self.pg5.sw_if_index,
6622 is_add=1, flags=flags)
6623 self.vapi.nat44_interface_add_del_feature(
6624 sw_if_index=self.pg6.sw_if_index,
6626 flags = self.config_flags.NAT_IS_OUT2IN_ONLY
6627 self.nat44_add_static_mapping(self.pg5.remote_ip4, external_addr,
6628 local_port, external_port, vrf_id=1,
6629 proto=IP_PROTOS.tcp, flags=flags)
6630 self.nat44_add_static_mapping(
6631 self.pg0.remote_ip4,
6632 external_sw_if_index=self.pg0.sw_if_index,
6633 local_port=local_port,
6635 external_port=external_port,
6636 proto=IP_PROTOS.tcp,
6640 # from client to service (both VRF1)
6641 p = (Ether(src=self.pg6.remote_mac, dst=self.pg6.local_mac) /
6642 IP(src=self.pg6.remote_ip4, dst=external_addr) /
6643 TCP(sport=12345, dport=external_port))
6644 self.pg6.add_stream(p)
6645 self.pg_enable_capture(self.pg_interfaces)
6647 capture = self.pg5.get_capture(1)
6652 self.assertEqual(ip.dst, self.pg5.remote_ip4)
6653 self.assertEqual(tcp.dport, local_port)
6654 self.assert_packet_checksums_valid(p)
6656 self.logger.error(ppp("Unexpected or invalid packet:", p))
6659 # from service back to client (both VRF1)
6660 p = (Ether(src=self.pg5.remote_mac, dst=self.pg5.local_mac) /
6661 IP(src=self.pg5.remote_ip4, dst=self.pg6.remote_ip4) /
6662 TCP(sport=local_port, dport=12345))
6663 self.pg5.add_stream(p)
6664 self.pg_enable_capture(self.pg_interfaces)
6666 capture = self.pg6.get_capture(1)
6671 self.assertEqual(ip.src, external_addr)
6672 self.assertEqual(tcp.sport, external_port)
6673 self.assert_packet_checksums_valid(p)
6675 self.logger.error(ppp("Unexpected or invalid packet:", p))
6678 # dynamic NAT from VRF1 to VRF0 (output-feature)
6679 p = (Ether(src=self.pg5.remote_mac, dst=self.pg5.local_mac) /
6680 IP(src=self.pg5.remote_ip4, dst=self.pg1.remote_ip4) /
6681 TCP(sport=2345, dport=22))
6682 self.pg5.add_stream(p)
6683 self.pg_enable_capture(self.pg_interfaces)
6685 capture = self.pg1.get_capture(1)
6690 self.assertEqual(ip.src, self.nat_addr)
6691 self.assert_packet_checksums_valid(p)
6694 self.logger.error(ppp("Unexpected or invalid packet:", p))
6697 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
6698 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
6699 TCP(sport=22, dport=port))
6700 self.pg1.add_stream(p)
6701 self.pg_enable_capture(self.pg_interfaces)
6703 capture = self.pg5.get_capture(1)
6708 self.assertEqual(ip.dst, self.pg5.remote_ip4)
6709 self.assertEqual(tcp.dport, 2345)
6710 self.assert_packet_checksums_valid(p)
6712 self.logger.error(ppp("Unexpected or invalid packet:", p))
6715 # from client VRF1 to service VRF0
6716 p = (Ether(src=self.pg6.remote_mac, dst=self.pg6.local_mac) /
6717 IP(src=self.pg6.remote_ip4, dst=self.pg0.local_ip4) /
6718 TCP(sport=12346, dport=external_port))
6719 self.pg6.add_stream(p)
6720 self.pg_enable_capture(self.pg_interfaces)
6722 capture = self.pg0.get_capture(1)
6727 self.assertEqual(ip.dst, self.pg0.remote_ip4)
6728 self.assertEqual(tcp.dport, local_port)
6729 self.assert_packet_checksums_valid(p)
6731 self.logger.error(ppp("Unexpected or invalid packet:", p))
6734 # from service VRF0 back to client VRF1
6735 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6736 IP(src=self.pg0.remote_ip4, dst=self.pg6.remote_ip4) /
6737 TCP(sport=local_port, dport=12346))
6738 self.pg0.add_stream(p)
6739 self.pg_enable_capture(self.pg_interfaces)
6741 capture = self.pg6.get_capture(1)
6746 self.assertEqual(ip.src, self.pg0.local_ip4)
6747 self.assertEqual(tcp.sport, external_port)
6748 self.assert_packet_checksums_valid(p)
6750 self.logger.error(ppp("Unexpected or invalid packet:", p))
6753 # from client VRF0 to service VRF1
6754 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6755 IP(src=self.pg0.remote_ip4, dst=external_addr) /
6756 TCP(sport=12347, dport=external_port))
6757 self.pg0.add_stream(p)
6758 self.pg_enable_capture(self.pg_interfaces)
6760 capture = self.pg5.get_capture(1)
6765 self.assertEqual(ip.dst, self.pg5.remote_ip4)
6766 self.assertEqual(tcp.dport, local_port)
6767 self.assert_packet_checksums_valid(p)
6769 self.logger.error(ppp("Unexpected or invalid packet:", p))
6772 # from service VRF1 back to client VRF0
6773 p = (Ether(src=self.pg5.remote_mac, dst=self.pg5.local_mac) /
6774 IP(src=self.pg5.remote_ip4, dst=self.pg0.remote_ip4) /
6775 TCP(sport=local_port, dport=12347))
6776 self.pg5.add_stream(p)
6777 self.pg_enable_capture(self.pg_interfaces)
6779 capture = self.pg0.get_capture(1)
6784 self.assertEqual(ip.src, external_addr)
6785 self.assertEqual(tcp.sport, external_port)
6786 self.assert_packet_checksums_valid(p)
6788 self.logger.error(ppp("Unexpected or invalid packet:", p))
6791 # from client to server (both VRF1, no translation)
6792 p = (Ether(src=self.pg6.remote_mac, dst=self.pg6.local_mac) /
6793 IP(src=self.pg6.remote_ip4, dst=self.pg5.remote_ip4) /
6794 TCP(sport=12348, dport=local_port))
6795 self.pg6.add_stream(p)
6796 self.pg_enable_capture(self.pg_interfaces)
6798 capture = self.pg5.get_capture(1)
6803 self.assertEqual(ip.dst, self.pg5.remote_ip4)
6804 self.assertEqual(tcp.dport, local_port)
6805 self.assert_packet_checksums_valid(p)
6807 self.logger.error(ppp("Unexpected or invalid packet:", p))
6810 # from server back to client (both VRF1, no translation)
6811 p = (Ether(src=self.pg5.remote_mac, dst=self.pg5.local_mac) /
6812 IP(src=self.pg5.remote_ip4, dst=self.pg6.remote_ip4) /
6813 TCP(sport=local_port, dport=12348))
6814 self.pg5.add_stream(p)
6815 self.pg_enable_capture(self.pg_interfaces)
6817 capture = self.pg6.get_capture(1)
6822 self.assertEqual(ip.src, self.pg5.remote_ip4)
6823 self.assertEqual(tcp.sport, local_port)
6824 self.assert_packet_checksums_valid(p)
6826 self.logger.error(ppp("Unexpected or invalid packet:", p))
6829 # from client VRF1 to server VRF0 (no translation)
6830 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6831 IP(src=self.pg0.remote_ip4, dst=self.pg6.remote_ip4) /
6832 TCP(sport=local_port, dport=12349))
6833 self.pg0.add_stream(p)
6834 self.pg_enable_capture(self.pg_interfaces)
6836 capture = self.pg6.get_capture(1)
6841 self.assertEqual(ip.src, self.pg0.remote_ip4)
6842 self.assertEqual(tcp.sport, local_port)
6843 self.assert_packet_checksums_valid(p)
6845 self.logger.error(ppp("Unexpected or invalid packet:", p))
6848 # from server VRF0 back to client VRF1 (no translation)
6849 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6850 IP(src=self.pg0.remote_ip4, dst=self.pg6.remote_ip4) /
6851 TCP(sport=local_port, dport=12349))
6852 self.pg0.add_stream(p)
6853 self.pg_enable_capture(self.pg_interfaces)
6855 capture = self.pg6.get_capture(1)
6860 self.assertEqual(ip.src, self.pg0.remote_ip4)
6861 self.assertEqual(tcp.sport, local_port)
6862 self.assert_packet_checksums_valid(p)
6864 self.logger.error(ppp("Unexpected or invalid packet:", p))
6867 # from client VRF0 to server VRF1 (no translation)
6868 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6869 IP(src=self.pg0.remote_ip4, dst=self.pg5.remote_ip4) /
6870 TCP(sport=12344, dport=local_port))
6871 self.pg0.add_stream(p)
6872 self.pg_enable_capture(self.pg_interfaces)
6874 capture = self.pg5.get_capture(1)
6879 self.assertEqual(ip.dst, self.pg5.remote_ip4)
6880 self.assertEqual(tcp.dport, local_port)
6881 self.assert_packet_checksums_valid(p)
6883 self.logger.error(ppp("Unexpected or invalid packet:", p))
6886 # from server VRF1 back to client VRF0 (no translation)
6887 p = (Ether(src=self.pg5.remote_mac, dst=self.pg5.local_mac) /
6888 IP(src=self.pg5.remote_ip4, dst=self.pg0.remote_ip4) /
6889 TCP(sport=local_port, dport=12344))
6890 self.pg5.add_stream(p)
6891 self.pg_enable_capture(self.pg_interfaces)
6893 capture = self.pg0.get_capture(1)
6898 self.assertEqual(ip.src, self.pg5.remote_ip4)
6899 self.assertEqual(tcp.sport, local_port)
6900 self.assert_packet_checksums_valid(p)
6902 self.logger.error(ppp("Unexpected or invalid packet:", p))
6905 @unittest.skipUnless(running_extended_tests, "part of extended tests")
6906 def test_session_timeout(self):
6907 """ NAT44 session timeouts """
6908 self.nat44_add_address(self.nat_addr)
6909 flags = self.config_flags.NAT_IS_INSIDE
6910 self.vapi.nat44_interface_add_del_feature(
6911 sw_if_index=self.pg0.sw_if_index,
6912 flags=flags, is_add=1)
6913 self.vapi.nat44_interface_add_del_feature(
6914 sw_if_index=self.pg1.sw_if_index,
6916 self.vapi.nat_set_timeouts(udp=300, tcp_established=7440,
6917 tcp_transitory=240, icmp=5)
6921 for i in range(0, max_sessions):
6922 src = "10.10.%u.%u" % ((i & 0xFF00) >> 8, i & 0xFF)
6923 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
6924 IP(src=src, dst=self.pg1.remote_ip4) /
6925 ICMP(id=1025, type='echo-request'))
6927 self.pg0.add_stream(pkts)
6928 self.pg_enable_capture(self.pg_interfaces)
6930 self.pg1.get_capture(max_sessions)
6935 for i in range(0, max_sessions):
6936 src = "10.11.%u.%u" % ((i & 0xFF00) >> 8, i & 0xFF)
6937 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
6938 IP(src=src, dst=self.pg1.remote_ip4) /
6939 ICMP(id=1026, type='echo-request'))
6941 self.pg0.add_stream(pkts)
6942 self.pg_enable_capture(self.pg_interfaces)
6944 self.pg1.get_capture(max_sessions)
6947 users = self.vapi.nat44_user_dump()
6949 nsessions = nsessions + user.nsessions
6950 self.assertLess(nsessions, 2 * max_sessions)
6952 @unittest.skipUnless(running_extended_tests, "part of extended tests")
6953 def test_session_rst_timeout(self):
6954 """ NAT44 session RST timeouts """
6955 self.nat44_add_address(self.nat_addr)
6956 flags = self.config_flags.NAT_IS_INSIDE
6957 self.vapi.nat44_interface_add_del_feature(
6958 sw_if_index=self.pg0.sw_if_index,
6959 flags=flags, is_add=1)
6960 self.vapi.nat44_interface_add_del_feature(
6961 sw_if_index=self.pg1.sw_if_index,
6963 self.vapi.nat_set_timeouts(udp=300, tcp_established=7440,
6964 tcp_transitory=5, icmp=60)
6966 self.initiate_tcp_session(self.pg0, self.pg1)
6967 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6968 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6969 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
6971 self.pg0.add_stream(p)
6972 self.pg_enable_capture(self.pg_interfaces)
6974 self.pg1.get_capture(1)
6978 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6979 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6980 TCP(sport=self.tcp_port_in + 1, dport=self.tcp_external_port + 1,
6982 self.pg0.add_stream(p)
6983 self.pg_enable_capture(self.pg_interfaces)
6985 self.pg1.get_capture(1)
6987 def test_syslog_sess(self):
6988 """ Test syslog session creation and deletion """
6989 self.vapi.syslog_set_filter(
6990 self.SYSLOG_SEVERITY.SYSLOG_API_SEVERITY_INFO)
6991 self.vapi.syslog_set_sender(self.pg2.local_ip4, self.pg2.remote_ip4)
6992 self.nat44_add_address(self.nat_addr)
6993 flags = self.config_flags.NAT_IS_INSIDE
6994 self.vapi.nat44_interface_add_del_feature(
6995 sw_if_index=self.pg0.sw_if_index,
6996 flags=flags, is_add=1)
6997 self.vapi.nat44_interface_add_del_feature(
6998 sw_if_index=self.pg1.sw_if_index,
7001 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
7002 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
7003 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port))
7004 self.pg0.add_stream(p)
7005 self.pg_enable_capture(self.pg_interfaces)
7007 capture = self.pg1.get_capture(1)
7008 self.tcp_port_out = capture[0][TCP].sport
7009 capture = self.pg2.get_capture(1)
7010 self.verify_syslog_sess(capture[0][Raw].load)
7012 self.pg_enable_capture(self.pg_interfaces)
7014 self.nat44_add_address(self.nat_addr, is_add=0)
7015 capture = self.pg2.get_capture(1)
7016 self.verify_syslog_sess(capture[0][Raw].load, False)
7018 def test_ed_users_dump(self):
7019 """ API test - nat44_user_dump """
7020 flags = self.config_flags.NAT_IS_INSIDE
7021 self.vapi.nat44_interface_add_del_feature(
7022 sw_if_index=self.pg0.sw_if_index,
7023 flags=flags, is_add=1)
7024 self.vapi.nat44_interface_add_del_feature(
7025 sw_if_index=self.pg1.sw_if_index,
7027 self.vapi.nat44_forwarding_enable_disable(enable=1)
7029 real_ip = self.pg0.remote_ip4
7030 alias_ip = self.nat_addr
7031 flags = self.config_flags.NAT_IS_ADDR_ONLY
7032 self.vapi.nat44_add_del_static_mapping(is_add=1,
7033 local_ip_address=real_ip,
7034 external_ip_address=alias_ip,
7035 external_sw_if_index=0xFFFFFFFF,
7038 users = self.vapi.nat44_user_dump()
7039 self.assertEqual(len(users), 0)
7041 # in2out - static mapping match
7043 pkts = self.create_stream_out(self.pg1)
7044 self.pg1.add_stream(pkts)
7045 self.pg_enable_capture(self.pg_interfaces)
7047 capture = self.pg0.get_capture(len(pkts))
7048 self.verify_capture_in(capture, self.pg0)
7050 pkts = self.create_stream_in(self.pg0, self.pg1)
7051 self.pg0.add_stream(pkts)
7052 self.pg_enable_capture(self.pg_interfaces)
7054 capture = self.pg1.get_capture(len(pkts))
7055 self.verify_capture_out(capture, same_port=True)
7057 users = self.vapi.nat44_user_dump()
7058 self.assertEqual(len(users), 1)
7059 static_user = users[0]
7060 self.assertEqual(static_user.nstaticsessions, 3)
7061 self.assertEqual(static_user.nsessions, 0)
7063 # in2out - no static mapping match
7065 host0 = self.pg0.remote_hosts[0]
7066 self.pg0.remote_hosts[0] = self.pg0.remote_hosts[1]
7068 pkts = self.create_stream_out(self.pg1,
7069 dst_ip=self.pg0.remote_ip4,
7070 use_inside_ports=True)
7071 self.pg1.add_stream(pkts)
7072 self.pg_enable_capture(self.pg_interfaces)
7074 capture = self.pg0.get_capture(len(pkts))
7075 self.verify_capture_in(capture, self.pg0)
7077 pkts = self.create_stream_in(self.pg0, self.pg1)
7078 self.pg0.add_stream(pkts)
7079 self.pg_enable_capture(self.pg_interfaces)
7081 capture = self.pg1.get_capture(len(pkts))
7082 self.verify_capture_out(capture, nat_ip=self.pg0.remote_ip4,
7085 self.pg0.remote_hosts[0] = host0
7087 users = self.vapi.nat44_user_dump()
7088 self.assertEqual(len(users), 2)
7089 if str(users[0].ip_address) == self.pg0.remote_hosts[0].ip4:
7090 non_static_user = users[1]
7091 static_user = users[0]
7093 non_static_user = users[0]
7094 static_user = users[1]
7095 self.assertEqual(static_user.nstaticsessions, 3)
7096 self.assertEqual(static_user.nsessions, 0)
7097 self.assertEqual(non_static_user.nstaticsessions, 0)
7098 self.assertEqual(non_static_user.nsessions, 3)
7100 users = self.vapi.nat44_user_dump()
7101 self.assertEqual(len(users), 2)
7102 if str(users[0].ip_address) == self.pg0.remote_hosts[0].ip4:
7103 non_static_user = users[1]
7104 static_user = users[0]
7106 non_static_user = users[0]
7107 static_user = users[1]
7108 self.assertEqual(static_user.nstaticsessions, 3)
7109 self.assertEqual(static_user.nsessions, 0)
7110 self.assertEqual(non_static_user.nstaticsessions, 0)
7111 self.assertEqual(non_static_user.nsessions, 3)
7114 self.vapi.nat44_forwarding_enable_disable(enable=0)
7115 flags = self.config_flags.NAT_IS_ADDR_ONLY
7116 self.vapi.nat44_add_del_static_mapping(
7118 local_ip_address=real_ip,
7119 external_ip_address=alias_ip,
7120 external_sw_if_index=0xFFFFFFFF,
7124 super(TestNAT44EndpointDependent, self).tearDown()
7125 if not self.vpp_dead:
7127 self.vapi.cli("clear logging")
7129 def show_commands_at_teardown(self):
7130 self.logger.info(self.vapi.cli("show errors"))
7131 self.logger.info(self.vapi.cli("show nat44 addresses"))
7132 self.logger.info(self.vapi.cli("show nat44 interfaces"))
7133 self.logger.info(self.vapi.cli("show nat44 static mappings"))
7134 self.logger.info(self.vapi.cli("show nat44 interface address"))
7135 self.logger.info(self.vapi.cli("show nat44 sessions detail"))
7136 self.logger.info(self.vapi.cli("show nat44 hash tables detail"))
7137 self.logger.info(self.vapi.cli("show nat timeouts"))
7138 self.logger.info(self.vapi.cli("debug nat44 fib registration"))
7141 class TestNAT44EndpointDependent3(MethodHolder):
7142 """ Endpoint-Dependent mapping and filtering extra test cases """
7144 max_translations = 50
7147 def setUpConstants(cls):
7148 super(TestNAT44EndpointDependent3, cls).setUpConstants()
7149 cls.vpp_cmdline.extend([
7150 "nat", "{", "endpoint-dependent",
7151 "max translations per thread %d" % cls.max_translations,
7156 def setUpClass(cls):
7157 super(TestNAT44EndpointDependent3, cls).setUpClass()
7158 cls.vapi.cli("set log class nat level debug")
7160 cls.nat_addr = '10.0.0.3'
7162 cls.create_pg_interfaces(range(2))
7164 for i in cls.pg_interfaces:
7170 super(TestNAT44EndpointDependent3, self).setUp()
7171 self.vapi.nat_set_timeouts(
7172 udp=1, tcp_established=7440, tcp_transitory=30, icmp=1)
7173 self.nat44_add_address(self.nat_addr)
7174 flags = self.config_flags.NAT_IS_INSIDE
7175 self.vapi.nat44_interface_add_del_feature(
7176 sw_if_index=self.pg0.sw_if_index, flags=flags, is_add=1)
7177 self.vapi.nat44_interface_add_del_feature(
7178 sw_if_index=self.pg1.sw_if_index, is_add=1)
7181 def tearDownClass(cls):
7182 super(TestNAT44EndpointDependent3, cls).tearDownClass()
7184 def init_tcp_session(self, in_if, out_if, sport, ext_dport):
7185 # SYN packet in->out
7186 p = (Ether(src=in_if.remote_mac, dst=in_if.local_mac) /
7187 IP(src=in_if.remote_ip4, dst=out_if.remote_ip4) /
7188 TCP(sport=sport, dport=ext_dport, flags="S"))
7190 self.pg_enable_capture(self.pg_interfaces)
7192 capture = out_if.get_capture(1)
7194 tcp_port_out = p[TCP].sport
7196 # SYN + ACK packet out->in
7197 p = (Ether(src=out_if.remote_mac, dst=out_if.local_mac) /
7198 IP(src=out_if.remote_ip4, dst=self.nat_addr) /
7199 TCP(sport=ext_dport, dport=tcp_port_out, flags="SA"))
7200 out_if.add_stream(p)
7201 self.pg_enable_capture(self.pg_interfaces)
7203 in_if.get_capture(1)
7205 # ACK packet in->out
7206 p = (Ether(src=in_if.remote_mac, dst=in_if.local_mac) /
7207 IP(src=in_if.remote_ip4, dst=out_if.remote_ip4) /
7208 TCP(sport=sport, dport=ext_dport, flags="A"))
7210 self.pg_enable_capture(self.pg_interfaces)
7212 out_if.get_capture(1)
7216 def test_lru_cleanup(self):
7217 """ LRU cleanup algorithm """
7218 tcp_port_out = self.init_tcp_session(self.pg0, self.pg1, 2000, 80)
7220 for i in range(0, self.max_translations - 1):
7221 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
7222 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4, ttl=64) /
7223 UDP(sport=7000+i, dport=80))
7226 self.pg0.add_stream(pkts)
7227 self.pg_enable_capture(self.pg_interfaces)
7229 self.pg1.get_capture(len(pkts))
7230 self.sleep(1.5, "wait for timeouts")
7233 for i in range(0, self.max_translations - 1):
7234 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
7235 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4, ttl=64) /
7236 ICMP(id=8000+i, type='echo-request'))
7239 self.pg0.add_stream(pkts)
7240 self.pg_enable_capture(self.pg_interfaces)
7242 self.pg1.get_capture(len(pkts))
7245 class TestNAT44Out2InDPO(MethodHolder):
7246 """ NAT44 Test Cases using out2in DPO """
7249 def setUpConstants(cls):
7250 super(TestNAT44Out2InDPO, cls).setUpConstants()
7251 cls.vpp_cmdline.extend(["nat", "{", "out2in dpo", "}"])
7254 def setUpClass(cls):
7255 super(TestNAT44Out2InDPO, cls).setUpClass()
7256 cls.vapi.cli("set log class nat level debug")
7258 cls.tcp_port_in = 6303
7259 cls.tcp_port_out = 6303
7260 cls.udp_port_in = 6304
7261 cls.udp_port_out = 6304
7262 cls.icmp_id_in = 6305
7263 cls.icmp_id_out = 6305
7264 cls.nat_addr = '10.0.0.3'
7265 cls.dst_ip4 = '192.168.70.1'
7267 cls.create_pg_interfaces(range(2))
7270 cls.pg0.config_ip4()
7271 cls.pg0.resolve_arp()
7274 cls.pg1.config_ip6()
7275 cls.pg1.resolve_ndp()
7277 r1 = VppIpRoute(cls, "::", 0,
7278 [VppRoutePath(cls.pg1.remote_ip6,
7279 cls.pg1.sw_if_index)],
7284 def tearDownClass(cls):
7285 super(TestNAT44Out2InDPO, cls).tearDownClass()
7287 def configure_xlat(self):
7288 self.dst_ip6_pfx = '1:2:3::'
7289 self.dst_ip6_pfx_n = socket.inet_pton(socket.AF_INET6,
7291 self.dst_ip6_pfx_len = 96
7292 self.src_ip6_pfx = '4:5:6::'
7293 self.src_ip6_pfx_n = socket.inet_pton(socket.AF_INET6,
7295 self.src_ip6_pfx_len = 96
7296 self.vapi.map_add_domain(self.dst_ip6_pfx_n, self.dst_ip6_pfx_len,
7297 self.src_ip6_pfx_n, self.src_ip6_pfx_len,
7298 '\x00\x00\x00\x00', 0)
7300 @unittest.skip('Temporary disabled')
7301 def test_464xlat_ce(self):
7302 """ Test 464XLAT CE with NAT44 """
7304 nat_config = self.vapi.nat_show_config()
7305 self.assertEqual(1, nat_config.out2in_dpo)
7307 self.configure_xlat()
7309 flags = self.config_flags.NAT_IS_INSIDE
7310 self.vapi.nat44_interface_add_del_feature(
7311 sw_if_index=self.pg0.sw_if_index,
7312 flags=flags, is_add=1)
7313 self.vapi.nat44_add_del_address_range(first_ip_address=self.nat_addr_n,
7314 last_ip_address=self.nat_addr_n,
7315 vrf_id=0xFFFFFFFF, is_add=1)
7317 out_src_ip6 = self.compose_ip6(self.dst_ip4, self.dst_ip6_pfx,
7318 self.dst_ip6_pfx_len)
7319 out_dst_ip6 = self.compose_ip6(self.nat_addr, self.src_ip6_pfx,
7320 self.src_ip6_pfx_len)
7323 pkts = self.create_stream_in(self.pg0, self.pg1, self.dst_ip4)
7324 self.pg0.add_stream(pkts)
7325 self.pg_enable_capture(self.pg_interfaces)
7327 capture = self.pg1.get_capture(len(pkts))
7328 self.verify_capture_out_ip6(capture, nat_ip=out_dst_ip6,
7331 pkts = self.create_stream_out_ip6(self.pg1, out_src_ip6,
7333 self.pg1.add_stream(pkts)
7334 self.pg_enable_capture(self.pg_interfaces)
7336 capture = self.pg0.get_capture(len(pkts))
7337 self.verify_capture_in(capture, self.pg0)
7339 self.vapi.nat44_interface_add_del_feature(
7340 sw_if_index=self.pg0.sw_if_index,
7342 self.vapi.nat44_add_del_address_range(
7343 first_ip_address=self.nat_addr_n,
7344 last_ip_address=self.nat_addr_n,
7347 @unittest.skip('Temporary disabled')
7348 def test_464xlat_ce_no_nat(self):
7349 """ Test 464XLAT CE without NAT44 """
7351 self.configure_xlat()
7353 out_src_ip6 = self.compose_ip6(self.dst_ip4, self.dst_ip6_pfx,
7354 self.dst_ip6_pfx_len)
7355 out_dst_ip6 = self.compose_ip6(self.pg0.remote_ip4, self.src_ip6_pfx,
7356 self.src_ip6_pfx_len)
7358 pkts = self.create_stream_in(self.pg0, self.pg1, self.dst_ip4)
7359 self.pg0.add_stream(pkts)
7360 self.pg_enable_capture(self.pg_interfaces)
7362 capture = self.pg1.get_capture(len(pkts))
7363 self.verify_capture_out_ip6(capture, dst_ip=out_src_ip6,
7364 nat_ip=out_dst_ip6, same_port=True)
7366 pkts = self.create_stream_out_ip6(self.pg1, out_src_ip6, out_dst_ip6)
7367 self.pg1.add_stream(pkts)
7368 self.pg_enable_capture(self.pg_interfaces)
7370 capture = self.pg0.get_capture(len(pkts))
7371 self.verify_capture_in(capture, self.pg0)
7374 if __name__ == '__main__':
7375 unittest.main(testRunner=VppTestRunner)