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 nat44_config_flags(self):
80 return VppEnum.vl_api_nat44_config_flags_t
83 def SYSLOG_SEVERITY(self):
84 return VppEnum.vl_api_syslog_severity_t
86 def nat44_add_static_mapping(self, local_ip, external_ip='0.0.0.0',
87 local_port=0, external_port=0, vrf_id=0,
88 is_add=1, external_sw_if_index=0xFFFFFFFF,
89 proto=0, tag="", flags=0):
91 Add/delete NAT44 static mapping
93 :param local_ip: Local IP address
94 :param external_ip: External IP address
95 :param local_port: Local port number (Optional)
96 :param external_port: External port number (Optional)
97 :param vrf_id: VRF ID (Default 0)
98 :param is_add: 1 if add, 0 if delete (Default add)
99 :param external_sw_if_index: External interface instead of IP address
100 :param proto: IP protocol (Mandatory if port specified)
101 :param tag: Opaque string tag
102 :param flags: NAT configuration flags
105 if not (local_port and external_port):
106 flags |= self.config_flags.NAT_IS_ADDR_ONLY
108 self.vapi.nat44_add_del_static_mapping(
110 local_ip_address=local_ip,
111 external_ip_address=external_ip,
112 external_sw_if_index=external_sw_if_index,
113 local_port=local_port,
114 external_port=external_port,
115 vrf_id=vrf_id, protocol=proto,
119 def nat44_add_address(self, ip, is_add=1, vrf_id=0xFFFFFFFF, twice_nat=0):
121 Add/delete NAT44 address
123 :param ip: IP address
124 :param is_add: 1 if add, 0 if delete (Default add)
125 :param twice_nat: twice NAT address for external hosts
127 flags = self.config_flags.NAT_IS_TWICE_NAT if twice_nat else 0
128 self.vapi.nat44_add_del_address_range(first_ip_address=ip,
134 def create_stream_in(self, in_if, out_if, dst_ip=None, ttl=64):
136 Create packet stream for inside network
138 :param in_if: Inside interface
139 :param out_if: Outside interface
140 :param dst_ip: Destination address
141 :param ttl: TTL of generated packets
144 dst_ip = out_if.remote_ip4
148 p = (Ether(dst=in_if.local_mac, src=in_if.remote_mac) /
149 IP(src=in_if.remote_ip4, dst=dst_ip, ttl=ttl) /
150 TCP(sport=self.tcp_port_in, dport=20))
154 p = (Ether(dst=in_if.local_mac, src=in_if.remote_mac) /
155 IP(src=in_if.remote_ip4, dst=dst_ip, ttl=ttl) /
156 UDP(sport=self.udp_port_in, dport=20))
160 p = (Ether(dst=in_if.local_mac, src=in_if.remote_mac) /
161 IP(src=in_if.remote_ip4, dst=dst_ip, ttl=ttl) /
162 ICMP(id=self.icmp_id_in, type='echo-request'))
167 def compose_ip6(self, ip4, pref, plen):
169 Compose IPv4-embedded IPv6 addresses
171 :param ip4: IPv4 address
172 :param pref: IPv6 prefix
173 :param plen: IPv6 prefix length
174 :returns: IPv4-embedded IPv6 addresses
176 pref_n = list(socket.inet_pton(socket.AF_INET6, pref))
177 ip4_n = list(socket.inet_pton(socket.AF_INET, ip4))
192 pref_n[10] = ip4_n[3]
196 pref_n[10] = ip4_n[2]
197 pref_n[11] = ip4_n[3]
200 pref_n[10] = ip4_n[1]
201 pref_n[11] = ip4_n[2]
202 pref_n[12] = ip4_n[3]
204 pref_n[12] = ip4_n[0]
205 pref_n[13] = ip4_n[1]
206 pref_n[14] = ip4_n[2]
207 pref_n[15] = ip4_n[3]
208 packed_pref_n = b''.join([scapy.compat.chb(x) for x in pref_n])
209 return socket.inet_ntop(socket.AF_INET6, packed_pref_n)
211 def extract_ip4(self, ip6, plen):
213 Extract IPv4 address embedded in IPv6 addresses
215 :param ip6: IPv6 address
216 :param plen: IPv6 prefix length
217 :returns: extracted IPv4 address
219 ip6_n = list(socket.inet_pton(socket.AF_INET6, ip6))
251 return socket.inet_ntop(socket.AF_INET, ''.join(ip4_n))
253 def create_stream_out(self, out_if, dst_ip=None, ttl=64,
254 use_inside_ports=False):
256 Create packet stream for outside network
258 :param out_if: Outside interface
259 :param dst_ip: Destination IP address (Default use global NAT address)
260 :param ttl: TTL of generated packets
261 :param use_inside_ports: Use inside NAT ports as destination ports
262 instead of outside ports
265 dst_ip = self.nat_addr
266 if not use_inside_ports:
267 tcp_port = self.tcp_port_out
268 udp_port = self.udp_port_out
269 icmp_id = self.icmp_id_out
271 tcp_port = self.tcp_port_in
272 udp_port = self.udp_port_in
273 icmp_id = self.icmp_id_in
276 p = (Ether(dst=out_if.local_mac, src=out_if.remote_mac) /
277 IP(src=out_if.remote_ip4, dst=dst_ip, ttl=ttl) /
278 TCP(dport=tcp_port, sport=20))
282 p = (Ether(dst=out_if.local_mac, src=out_if.remote_mac) /
283 IP(src=out_if.remote_ip4, dst=dst_ip, ttl=ttl) /
284 UDP(dport=udp_port, sport=20))
288 p = (Ether(dst=out_if.local_mac, src=out_if.remote_mac) /
289 IP(src=out_if.remote_ip4, dst=dst_ip, ttl=ttl) /
290 ICMP(id=icmp_id, type='echo-reply'))
295 def create_stream_out_ip6(self, out_if, src_ip, dst_ip, hl=64):
297 Create packet stream for outside network
299 :param out_if: Outside interface
300 :param dst_ip: Destination IP address (Default use global NAT address)
301 :param hl: HL of generated packets
305 p = (Ether(dst=out_if.local_mac, src=out_if.remote_mac) /
306 IPv6(src=src_ip, dst=dst_ip, hlim=hl) /
307 TCP(dport=self.tcp_port_out, sport=20))
311 p = (Ether(dst=out_if.local_mac, src=out_if.remote_mac) /
312 IPv6(src=src_ip, dst=dst_ip, hlim=hl) /
313 UDP(dport=self.udp_port_out, sport=20))
317 p = (Ether(dst=out_if.local_mac, src=out_if.remote_mac) /
318 IPv6(src=src_ip, dst=dst_ip, hlim=hl) /
319 ICMPv6EchoReply(id=self.icmp_id_out))
324 def verify_capture_out(self, capture, nat_ip=None, same_port=False,
325 dst_ip=None, is_ip6=False, ignore_port=False):
327 Verify captured packets on outside network
329 :param capture: Captured packets
330 :param nat_ip: Translated IP address (Default use global NAT address)
331 :param same_port: Source port number is not translated (Default False)
332 :param dst_ip: Destination IP address (Default do not verify)
333 :param is_ip6: If L3 protocol is IPv6 (Default False)
337 ICMP46 = ICMPv6EchoRequest
342 nat_ip = self.nat_addr
343 for packet in capture:
346 self.assert_packet_checksums_valid(packet)
347 self.assertEqual(packet[IP46].src, nat_ip)
348 if dst_ip is not None:
349 self.assertEqual(packet[IP46].dst, dst_ip)
350 if packet.haslayer(TCP):
354 packet[TCP].sport, self.tcp_port_in)
357 packet[TCP].sport, self.tcp_port_in)
358 self.tcp_port_out = packet[TCP].sport
359 self.assert_packet_checksums_valid(packet)
360 elif packet.haslayer(UDP):
364 packet[UDP].sport, self.udp_port_in)
367 packet[UDP].sport, self.udp_port_in)
368 self.udp_port_out = packet[UDP].sport
373 packet[ICMP46].id, self.icmp_id_in)
376 packet[ICMP46].id, self.icmp_id_in)
377 self.icmp_id_out = packet[ICMP46].id
378 self.assert_packet_checksums_valid(packet)
380 self.logger.error(ppp("Unexpected or invalid packet "
381 "(outside network):", packet))
384 def verify_capture_out_ip6(self, capture, nat_ip, same_port=False,
387 Verify captured packets on outside network
389 :param capture: Captured packets
390 :param nat_ip: Translated IP address
391 :param same_port: Source port number is not translated (Default False)
392 :param dst_ip: Destination IP address (Default do not verify)
394 return self.verify_capture_out(capture, nat_ip, same_port, dst_ip,
397 def verify_capture_in(self, capture, in_if):
399 Verify captured packets on inside network
401 :param capture: Captured packets
402 :param in_if: Inside interface
404 for packet in capture:
406 self.assert_packet_checksums_valid(packet)
407 self.assertEqual(packet[IP].dst, in_if.remote_ip4)
408 if packet.haslayer(TCP):
409 self.assertEqual(packet[TCP].dport, self.tcp_port_in)
410 elif packet.haslayer(UDP):
411 self.assertEqual(packet[UDP].dport, self.udp_port_in)
413 self.assertEqual(packet[ICMP].id, self.icmp_id_in)
415 self.logger.error(ppp("Unexpected or invalid packet "
416 "(inside network):", packet))
419 def verify_capture_in_ip6(self, capture, src_ip, dst_ip):
421 Verify captured IPv6 packets on inside network
423 :param capture: Captured packets
424 :param src_ip: Source IP
425 :param dst_ip: Destination IP address
427 for packet in capture:
429 self.assertEqual(packet[IPv6].src, src_ip)
430 self.assertEqual(packet[IPv6].dst, dst_ip)
431 self.assert_packet_checksums_valid(packet)
432 if packet.haslayer(TCP):
433 self.assertEqual(packet[TCP].dport, self.tcp_port_in)
434 elif packet.haslayer(UDP):
435 self.assertEqual(packet[UDP].dport, self.udp_port_in)
437 self.assertEqual(packet[ICMPv6EchoReply].id,
440 self.logger.error(ppp("Unexpected or invalid packet "
441 "(inside network):", packet))
444 def verify_capture_no_translation(self, capture, ingress_if, egress_if):
446 Verify captured packet that don't have to be translated
448 :param capture: Captured packets
449 :param ingress_if: Ingress interface
450 :param egress_if: Egress interface
452 for packet in capture:
454 self.assertEqual(packet[IP].src, ingress_if.remote_ip4)
455 self.assertEqual(packet[IP].dst, egress_if.remote_ip4)
456 if packet.haslayer(TCP):
457 self.assertEqual(packet[TCP].sport, self.tcp_port_in)
458 elif packet.haslayer(UDP):
459 self.assertEqual(packet[UDP].sport, self.udp_port_in)
461 self.assertEqual(packet[ICMP].id, self.icmp_id_in)
463 self.logger.error(ppp("Unexpected or invalid packet "
464 "(inside network):", packet))
467 def verify_capture_out_with_icmp_errors(self, capture, src_ip=None,
470 Verify captured packets with ICMP errors on outside network
472 :param capture: Captured packets
473 :param src_ip: Translated IP address or IP address of VPP
474 (Default use global NAT address)
475 :param icmp_type: Type of error ICMP packet
476 we are expecting (Default 11)
479 src_ip = self.nat_addr
480 for packet in capture:
482 self.assertEqual(packet[IP].src, src_ip)
483 self.assertEqual(packet.haslayer(ICMP), 1)
485 self.assertEqual(icmp.type, icmp_type)
486 self.assertTrue(icmp.haslayer(IPerror))
487 inner_ip = icmp[IPerror]
488 if inner_ip.haslayer(TCPerror):
489 self.assertEqual(inner_ip[TCPerror].dport,
491 elif inner_ip.haslayer(UDPerror):
492 self.assertEqual(inner_ip[UDPerror].dport,
495 self.assertEqual(inner_ip[ICMPerror].id, self.icmp_id_out)
497 self.logger.error(ppp("Unexpected or invalid packet "
498 "(outside network):", packet))
501 def verify_capture_in_with_icmp_errors(self, capture, in_if, icmp_type=11):
503 Verify captured packets with ICMP errors on inside network
505 :param capture: Captured packets
506 :param in_if: Inside interface
507 :param icmp_type: Type of error ICMP packet
508 we are expecting (Default 11)
510 for packet in capture:
512 self.assertEqual(packet[IP].dst, in_if.remote_ip4)
513 self.assertEqual(packet.haslayer(ICMP), 1)
515 self.assertEqual(icmp.type, icmp_type)
516 self.assertTrue(icmp.haslayer(IPerror))
517 inner_ip = icmp[IPerror]
518 if inner_ip.haslayer(TCPerror):
519 self.assertEqual(inner_ip[TCPerror].sport,
521 elif inner_ip.haslayer(UDPerror):
522 self.assertEqual(inner_ip[UDPerror].sport,
525 self.assertEqual(inner_ip[ICMPerror].id, self.icmp_id_in)
527 self.logger.error(ppp("Unexpected or invalid packet "
528 "(inside network):", packet))
531 def create_stream_frag(self, src_if, dst, sport, dport, data,
532 proto=IP_PROTOS.tcp, echo_reply=False):
534 Create fragmented packet stream
536 :param src_if: Source interface
537 :param dst: Destination IPv4 address
538 :param sport: Source port
539 :param dport: Destination port
540 :param data: Payload data
541 :param proto: protocol (TCP, UDP, ICMP)
542 :param echo_reply: use echo_reply if protocol is ICMP
545 if proto == IP_PROTOS.tcp:
546 p = (IP(src=src_if.remote_ip4, dst=dst) /
547 TCP(sport=sport, dport=dport) /
549 p = p.__class__(scapy.compat.raw(p))
550 chksum = p[TCP].chksum
551 proto_header = TCP(sport=sport, dport=dport, chksum=chksum)
552 elif proto == IP_PROTOS.udp:
553 proto_header = UDP(sport=sport, dport=dport)
554 elif proto == IP_PROTOS.icmp:
556 proto_header = ICMP(id=sport, type='echo-request')
558 proto_header = ICMP(id=sport, type='echo-reply')
560 raise Exception("Unsupported protocol")
561 id = random.randint(0, 65535)
563 if proto == IP_PROTOS.tcp:
566 raw = Raw(data[0:16])
567 p = (Ether(src=src_if.remote_mac, dst=src_if.local_mac) /
568 IP(src=src_if.remote_ip4, dst=dst, flags="MF", frag=0, id=id) /
572 if proto == IP_PROTOS.tcp:
573 raw = Raw(data[4:20])
575 raw = Raw(data[16:32])
576 p = (Ether(src=src_if.remote_mac, dst=src_if.local_mac) /
577 IP(src=src_if.remote_ip4, dst=dst, flags="MF", frag=3, id=id,
581 if proto == IP_PROTOS.tcp:
585 p = (Ether(src=src_if.remote_mac, dst=src_if.local_mac) /
586 IP(src=src_if.remote_ip4, dst=dst, frag=5, proto=proto,
592 def reass_frags_and_verify(self, frags, src, dst):
594 Reassemble and verify fragmented packet
596 :param frags: Captured fragments
597 :param src: Source IPv4 address to verify
598 :param dst: Destination IPv4 address to verify
600 :returns: Reassembled IPv4 packet
604 self.assertEqual(p[IP].src, src)
605 self.assertEqual(p[IP].dst, dst)
606 self.assert_ip_checksum_valid(p)
607 buffer.seek(p[IP].frag * 8)
608 buffer.write(bytes(p[IP].payload))
609 ip = IP(src=frags[0][IP].src, dst=frags[0][IP].dst,
610 proto=frags[0][IP].proto)
611 if ip.proto == IP_PROTOS.tcp:
612 p = (ip / TCP(buffer.getvalue()))
613 self.logger.debug(ppp("Reassembled:", p))
614 self.assert_tcp_checksum_valid(p)
615 elif ip.proto == IP_PROTOS.udp:
616 p = (ip / UDP(buffer.getvalue()[:8]) /
617 Raw(buffer.getvalue()[8:]))
618 elif ip.proto == IP_PROTOS.icmp:
619 p = (ip / ICMP(buffer.getvalue()))
622 def reass_frags_and_verify_ip6(self, frags, src, dst):
624 Reassemble and verify fragmented packet
626 :param frags: Captured fragments
627 :param src: Source IPv6 address to verify
628 :param dst: Destination IPv6 address to verify
630 :returns: Reassembled IPv6 packet
634 self.assertEqual(p[IPv6].src, src)
635 self.assertEqual(p[IPv6].dst, dst)
636 buffer.seek(p[IPv6ExtHdrFragment].offset * 8)
637 buffer.write(bytes(p[IPv6ExtHdrFragment].payload))
638 ip = IPv6(src=frags[0][IPv6].src, dst=frags[0][IPv6].dst,
639 nh=frags[0][IPv6ExtHdrFragment].nh)
640 if ip.nh == IP_PROTOS.tcp:
641 p = (ip / TCP(buffer.getvalue()))
642 elif ip.nh == IP_PROTOS.udp:
643 p = (ip / UDP(buffer.getvalue()))
644 self.logger.debug(ppp("Reassembled:", p))
645 self.assert_packet_checksums_valid(p)
648 def initiate_tcp_session(self, in_if, out_if):
650 Initiates TCP session
652 :param in_if: Inside interface
653 :param out_if: Outside interface
657 p = (Ether(src=in_if.remote_mac, dst=in_if.local_mac) /
658 IP(src=in_if.remote_ip4, dst=out_if.remote_ip4) /
659 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
662 self.pg_enable_capture(self.pg_interfaces)
664 capture = out_if.get_capture(1)
666 self.tcp_port_out = p[TCP].sport
668 # SYN + ACK packet out->in
669 p = (Ether(src=out_if.remote_mac, dst=out_if.local_mac) /
670 IP(src=out_if.remote_ip4, dst=self.nat_addr) /
671 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
674 self.pg_enable_capture(self.pg_interfaces)
679 p = (Ether(src=in_if.remote_mac, dst=in_if.local_mac) /
680 IP(src=in_if.remote_ip4, dst=out_if.remote_ip4) /
681 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
684 self.pg_enable_capture(self.pg_interfaces)
686 out_if.get_capture(1)
689 self.logger.error("TCP 3 way handshake failed")
692 def verify_ipfix_nat44_ses(self, data):
694 Verify IPFIX NAT44 session create/delete event
696 :param data: Decoded IPFIX data records
698 nat44_ses_create_num = 0
699 nat44_ses_delete_num = 0
700 self.assertEqual(6, len(data))
703 self.assertIn(scapy.compat.orb(record[230]), [4, 5])
704 if scapy.compat.orb(record[230]) == 4:
705 nat44_ses_create_num += 1
707 nat44_ses_delete_num += 1
709 self.assertEqual(self.pg0.remote_ip4,
710 str(ipaddress.IPv4Address(record[8])))
711 # postNATSourceIPv4Address
712 self.assertEqual(socket.inet_pton(socket.AF_INET, self.nat_addr),
715 self.assertEqual(struct.pack("!I", 0), record[234])
716 # protocolIdentifier/sourceTransportPort
717 # /postNAPTSourceTransportPort
718 if IP_PROTOS.icmp == scapy.compat.orb(record[4]):
719 self.assertEqual(struct.pack("!H", self.icmp_id_in), record[7])
720 self.assertEqual(struct.pack("!H", self.icmp_id_out),
722 elif IP_PROTOS.tcp == scapy.compat.orb(record[4]):
723 self.assertEqual(struct.pack("!H", self.tcp_port_in),
725 self.assertEqual(struct.pack("!H", self.tcp_port_out),
727 elif IP_PROTOS.udp == scapy.compat.orb(record[4]):
728 self.assertEqual(struct.pack("!H", self.udp_port_in),
730 self.assertEqual(struct.pack("!H", self.udp_port_out),
733 self.fail("Invalid protocol")
734 self.assertEqual(3, nat44_ses_create_num)
735 self.assertEqual(3, nat44_ses_delete_num)
737 def verify_ipfix_addr_exhausted(self, data):
739 Verify IPFIX NAT addresses event
741 :param data: Decoded IPFIX data records
743 self.assertEqual(1, len(data))
746 self.assertEqual(scapy.compat.orb(record[230]), 3)
748 self.assertEqual(struct.pack("!I", 0), record[283])
750 def verify_ipfix_max_sessions(self, data, limit):
752 Verify IPFIX maximum session entries exceeded event
754 :param data: Decoded IPFIX data records
755 :param limit: Number of maximum session entries that can be created.
757 self.assertEqual(1, len(data))
760 self.assertEqual(scapy.compat.orb(record[230]), 13)
761 # natQuotaExceededEvent
762 self.assertEqual(struct.pack("I", 1), record[466])
764 self.assertEqual(struct.pack("I", limit), record[471])
766 def verify_ipfix_max_bibs(self, data, limit):
768 Verify IPFIX maximum BIB entries exceeded event
770 :param data: Decoded IPFIX data records
771 :param limit: Number of maximum BIB entries that can be created.
773 self.assertEqual(1, len(data))
776 self.assertEqual(scapy.compat.orb(record[230]), 13)
777 # natQuotaExceededEvent
778 self.assertEqual(struct.pack("I", 2), record[466])
780 self.assertEqual(struct.pack("I", limit), record[472])
782 def verify_no_nat44_user(self):
783 """ Verify that there is no NAT44 user """
784 users = self.vapi.nat44_user_dump()
785 self.assertEqual(len(users), 0)
786 users = self.statistics.get_counter('/nat44/total-users')
787 self.assertEqual(users[0][0], 0)
788 sessions = self.statistics.get_counter('/nat44/total-sessions')
789 self.assertEqual(sessions[0][0], 0)
791 def verify_ipfix_max_entries_per_user(self, data, limit, src_addr):
793 Verify IPFIX maximum entries per user exceeded event
795 :param data: Decoded IPFIX data records
796 :param limit: Number of maximum entries per user
797 :param src_addr: IPv4 source address
799 self.assertEqual(1, len(data))
802 self.assertEqual(scapy.compat.orb(record[230]), 13)
803 # natQuotaExceededEvent
804 self.assertEqual(struct.pack("I", 3), record[466])
806 self.assertEqual(struct.pack("I", limit), record[473])
808 self.assertEqual(socket.inet_pton(socket.AF_INET, src_addr), record[8])
810 def verify_syslog_apmap(self, data, is_add=True):
811 message = data.decode('utf-8')
813 message = SyslogMessage.parse(message)
814 except ParseError as e:
818 self.assertEqual(message.severity, SyslogSeverity.info)
819 self.assertEqual(message.appname, 'NAT')
820 self.assertEqual(message.msgid, 'APMADD' if is_add else 'APMDEL')
821 sd_params = message.sd.get('napmap')
822 self.assertTrue(sd_params is not None)
823 self.assertEqual(sd_params.get('IATYP'), 'IPv4')
824 self.assertEqual(sd_params.get('ISADDR'), self.pg0.remote_ip4)
825 self.assertEqual(sd_params.get('ISPORT'), "%d" % self.tcp_port_in)
826 self.assertEqual(sd_params.get('XATYP'), 'IPv4')
827 self.assertEqual(sd_params.get('XSADDR'), self.nat_addr)
828 self.assertEqual(sd_params.get('XSPORT'), "%d" % self.tcp_port_out)
829 self.assertEqual(sd_params.get('PROTO'), "%d" % IP_PROTOS.tcp)
830 self.assertTrue(sd_params.get('SSUBIX') is not None)
831 self.assertEqual(sd_params.get('SVLAN'), '0')
833 def verify_syslog_sess(self, data, is_add=True, is_ip6=False):
834 message = data.decode('utf-8')
836 message = SyslogMessage.parse(message)
837 except ParseError as e:
841 self.assertEqual(message.severity, SyslogSeverity.info)
842 self.assertEqual(message.appname, 'NAT')
843 self.assertEqual(message.msgid, 'SADD' if is_add else 'SDEL')
844 sd_params = message.sd.get('nsess')
845 self.assertTrue(sd_params is not None)
847 self.assertEqual(sd_params.get('IATYP'), 'IPv6')
848 self.assertEqual(sd_params.get('ISADDR'), self.pg0.remote_ip6)
850 self.assertEqual(sd_params.get('IATYP'), 'IPv4')
851 self.assertEqual(sd_params.get('ISADDR'), self.pg0.remote_ip4)
852 self.assertTrue(sd_params.get('SSUBIX') is not None)
853 self.assertEqual(sd_params.get('ISPORT'), "%d" % self.tcp_port_in)
854 self.assertEqual(sd_params.get('XATYP'), 'IPv4')
855 self.assertEqual(sd_params.get('XSADDR'), self.nat_addr)
856 self.assertEqual(sd_params.get('XSPORT'), "%d" % self.tcp_port_out)
857 self.assertEqual(sd_params.get('PROTO'), "%d" % IP_PROTOS.tcp)
858 self.assertEqual(sd_params.get('SVLAN'), '0')
859 self.assertEqual(sd_params.get('XDADDR'), self.pg1.remote_ip4)
860 self.assertEqual(sd_params.get('XDPORT'),
861 "%d" % self.tcp_external_port)
863 def verify_mss_value(self, pkt, mss):
870 if not pkt.haslayer(IP) or not pkt.haslayer(TCP):
871 raise TypeError("Not a TCP/IP packet")
873 for option in pkt[TCP].options:
874 if option[0] == 'MSS':
875 self.assertEqual(option[1], mss)
876 self.assert_tcp_checksum_valid(pkt)
879 def proto2layer(proto):
880 if proto == IP_PROTOS.tcp:
882 elif proto == IP_PROTOS.udp:
884 elif proto == IP_PROTOS.icmp:
887 raise Exception("Unsupported protocol")
889 def frag_in_order(self, proto=IP_PROTOS.tcp, dont_translate=False,
891 layer = self.proto2layer(proto)
893 if proto == IP_PROTOS.tcp:
894 data = b"A" * 4 + b"B" * 16 + b"C" * 3
896 data = b"A" * 16 + b"B" * 16 + b"C" * 3
897 self.port_in = random.randint(1025, 65535)
900 pkts = self.create_stream_frag(self.pg0, self.pg1.remote_ip4,
901 self.port_in, 20, data, proto)
902 self.pg0.add_stream(pkts)
903 self.pg_enable_capture(self.pg_interfaces)
905 frags = self.pg1.get_capture(len(pkts))
906 if not dont_translate:
907 p = self.reass_frags_and_verify(frags,
911 p = self.reass_frags_and_verify(frags,
914 if proto != IP_PROTOS.icmp:
915 if not dont_translate:
916 self.assertEqual(p[layer].dport, 20)
918 self.assertNotEqual(p[layer].sport, self.port_in)
920 self.assertEqual(p[layer].sport, self.port_in)
923 if not dont_translate:
924 self.assertNotEqual(p[layer].id, self.port_in)
926 self.assertEqual(p[layer].id, self.port_in)
927 self.assertEqual(data, p[Raw].load)
930 if not dont_translate:
931 dst_addr = self.nat_addr
933 dst_addr = self.pg0.remote_ip4
934 if proto != IP_PROTOS.icmp:
936 dport = p[layer].sport
940 pkts = self.create_stream_frag(self.pg1, dst_addr, sport, dport, data,
941 proto, echo_reply=True)
942 self.pg1.add_stream(pkts)
943 self.pg_enable_capture(self.pg_interfaces)
945 frags = self.pg0.get_capture(len(pkts))
946 p = self.reass_frags_and_verify(frags,
949 if proto != IP_PROTOS.icmp:
950 self.assertEqual(p[layer].sport, 20)
951 self.assertEqual(p[layer].dport, self.port_in)
953 self.assertEqual(p[layer].id, self.port_in)
954 self.assertEqual(data, p[Raw].load)
956 def frag_in_order_in_plus_out(self, proto=IP_PROTOS.tcp):
957 layer = self.proto2layer(proto)
959 if proto == IP_PROTOS.tcp:
960 data = b"A" * 4 + b"B" * 16 + b"C" * 3
962 data = b"A" * 16 + b"B" * 16 + b"C" * 3
963 self.port_in = random.randint(1025, 65535)
967 pkts = self.create_stream_frag(self.pg0, self.server_out_addr,
968 self.port_in, self.server_out_port,
970 self.pg0.add_stream(pkts)
971 self.pg_enable_capture(self.pg_interfaces)
973 frags = self.pg1.get_capture(len(pkts))
974 p = self.reass_frags_and_verify(frags,
977 if proto != IP_PROTOS.icmp:
978 self.assertEqual(p[layer].sport, self.port_in)
979 self.assertEqual(p[layer].dport, self.server_in_port)
981 self.assertEqual(p[layer].id, self.port_in)
982 self.assertEqual(data, p[Raw].load)
985 if proto != IP_PROTOS.icmp:
986 pkts = self.create_stream_frag(self.pg1, self.pg0.remote_ip4,
988 p[layer].sport, data, proto)
990 pkts = self.create_stream_frag(self.pg1, self.pg0.remote_ip4,
991 p[layer].id, 0, data, proto,
993 self.pg1.add_stream(pkts)
994 self.pg_enable_capture(self.pg_interfaces)
996 frags = self.pg0.get_capture(len(pkts))
997 p = self.reass_frags_and_verify(frags,
998 self.server_out_addr,
1000 if proto != IP_PROTOS.icmp:
1001 self.assertEqual(p[layer].sport, self.server_out_port)
1002 self.assertEqual(p[layer].dport, self.port_in)
1004 self.assertEqual(p[layer].id, self.port_in)
1005 self.assertEqual(data, p[Raw].load)
1007 def reass_hairpinning(self, proto=IP_PROTOS.tcp, ignore_port=False):
1008 layer = self.proto2layer(proto)
1010 if proto == IP_PROTOS.tcp:
1011 data = b"A" * 4 + b"B" * 16 + b"C" * 3
1013 data = b"A" * 16 + b"B" * 16 + b"C" * 3
1015 # send packet from host to server
1016 pkts = self.create_stream_frag(self.pg0,
1019 self.server_out_port,
1022 self.pg0.add_stream(pkts)
1023 self.pg_enable_capture(self.pg_interfaces)
1025 frags = self.pg0.get_capture(len(pkts))
1026 p = self.reass_frags_and_verify(frags,
1029 if proto != IP_PROTOS.icmp:
1031 self.assertNotEqual(p[layer].sport, self.host_in_port)
1032 self.assertEqual(p[layer].dport, self.server_in_port)
1035 self.assertNotEqual(p[layer].id, self.host_in_port)
1036 self.assertEqual(data, p[Raw].load)
1038 def frag_out_of_order(self, proto=IP_PROTOS.tcp, dont_translate=False,
1040 layer = self.proto2layer(proto)
1042 if proto == IP_PROTOS.tcp:
1043 data = b"A" * 4 + b"B" * 16 + b"C" * 3
1045 data = b"A" * 16 + b"B" * 16 + b"C" * 3
1046 self.port_in = random.randint(1025, 65535)
1050 pkts = self.create_stream_frag(self.pg0, self.pg1.remote_ip4,
1051 self.port_in, 20, data, proto)
1053 self.pg0.add_stream(pkts)
1054 self.pg_enable_capture(self.pg_interfaces)
1056 frags = self.pg1.get_capture(len(pkts))
1057 if not dont_translate:
1058 p = self.reass_frags_and_verify(frags,
1060 self.pg1.remote_ip4)
1062 p = self.reass_frags_and_verify(frags,
1063 self.pg0.remote_ip4,
1064 self.pg1.remote_ip4)
1065 if proto != IP_PROTOS.icmp:
1066 if not dont_translate:
1067 self.assertEqual(p[layer].dport, 20)
1069 self.assertNotEqual(p[layer].sport, self.port_in)
1071 self.assertEqual(p[layer].sport, self.port_in)
1074 if not dont_translate:
1075 self.assertNotEqual(p[layer].id, self.port_in)
1077 self.assertEqual(p[layer].id, self.port_in)
1078 self.assertEqual(data, p[Raw].load)
1081 if not dont_translate:
1082 dst_addr = self.nat_addr
1084 dst_addr = self.pg0.remote_ip4
1085 if proto != IP_PROTOS.icmp:
1087 dport = p[layer].sport
1091 pkts = self.create_stream_frag(self.pg1, dst_addr, sport, dport,
1092 data, proto, echo_reply=True)
1094 self.pg1.add_stream(pkts)
1095 self.pg_enable_capture(self.pg_interfaces)
1097 frags = self.pg0.get_capture(len(pkts))
1098 p = self.reass_frags_and_verify(frags,
1099 self.pg1.remote_ip4,
1100 self.pg0.remote_ip4)
1101 if proto != IP_PROTOS.icmp:
1102 self.assertEqual(p[layer].sport, 20)
1103 self.assertEqual(p[layer].dport, self.port_in)
1105 self.assertEqual(p[layer].id, self.port_in)
1106 self.assertEqual(data, p[Raw].load)
1108 def frag_out_of_order_in_plus_out(self, proto=IP_PROTOS.tcp):
1109 layer = self.proto2layer(proto)
1111 if proto == IP_PROTOS.tcp:
1112 data = b"A" * 4 + b"B" * 16 + b"C" * 3
1114 data = b"A" * 16 + b"B" * 16 + b"C" * 3
1115 self.port_in = random.randint(1025, 65535)
1119 pkts = self.create_stream_frag(self.pg0, self.server_out_addr,
1120 self.port_in, self.server_out_port,
1123 self.pg0.add_stream(pkts)
1124 self.pg_enable_capture(self.pg_interfaces)
1126 frags = self.pg1.get_capture(len(pkts))
1127 p = self.reass_frags_and_verify(frags,
1128 self.pg0.remote_ip4,
1129 self.server_in_addr)
1130 if proto != IP_PROTOS.icmp:
1131 self.assertEqual(p[layer].dport, self.server_in_port)
1132 self.assertEqual(p[layer].sport, self.port_in)
1133 self.assertEqual(p[layer].dport, self.server_in_port)
1135 self.assertEqual(p[layer].id, self.port_in)
1136 self.assertEqual(data, p[Raw].load)
1139 if proto != IP_PROTOS.icmp:
1140 pkts = self.create_stream_frag(self.pg1, self.pg0.remote_ip4,
1141 self.server_in_port,
1142 p[layer].sport, data, proto)
1144 pkts = self.create_stream_frag(self.pg1, self.pg0.remote_ip4,
1145 p[layer].id, 0, data, proto,
1148 self.pg1.add_stream(pkts)
1149 self.pg_enable_capture(self.pg_interfaces)
1151 frags = self.pg0.get_capture(len(pkts))
1152 p = self.reass_frags_and_verify(frags,
1153 self.server_out_addr,
1154 self.pg0.remote_ip4)
1155 if proto != IP_PROTOS.icmp:
1156 self.assertEqual(p[layer].sport, self.server_out_port)
1157 self.assertEqual(p[layer].dport, self.port_in)
1159 self.assertEqual(p[layer].id, self.port_in)
1160 self.assertEqual(data, p[Raw].load)
1163 class TestNATMisc(MethodHolder):
1164 """ NAT misc Test Cases """
1166 max_translations = 10240
1170 super(TestNATMisc, self).setUp()
1171 self.vapi.nat44_plugin_enable_disable(
1172 sessions=self.max_translations,
1173 users=self.max_users, enable=1)
1176 super(TestNATMisc, self).tearDown()
1177 if not self.vpp_dead:
1178 self.vapi.nat44_plugin_enable_disable(enable=0)
1179 self.vapi.cli("clear logging")
1181 def test_show_max_translations(self):
1182 """ API test - max translations per thread """
1183 nat_config = self.vapi.nat_show_config_2()
1184 self.assertEqual(self.max_translations,
1185 nat_config.max_translations_per_thread)
1188 class TestNAT44(MethodHolder):
1189 """ NAT44 Test Cases """
1191 max_translations = 10240
1195 def setUpClass(cls):
1196 super(TestNAT44, cls).setUpClass()
1197 cls.vapi.cli("set log class nat level debug")
1199 cls.tcp_port_in = 6303
1200 cls.tcp_port_out = 6303
1201 cls.udp_port_in = 6304
1202 cls.udp_port_out = 6304
1203 cls.icmp_id_in = 6305
1204 cls.icmp_id_out = 6305
1205 cls.nat_addr = '10.0.0.3'
1206 cls.ipfix_src_port = 4739
1207 cls.ipfix_domain_id = 1
1208 cls.tcp_external_port = 80
1209 cls.udp_external_port = 69
1211 cls.create_pg_interfaces(range(10))
1212 cls.interfaces = list(cls.pg_interfaces[0:4])
1214 for i in cls.interfaces:
1219 cls.pg0.generate_remote_hosts(3)
1220 cls.pg0.configure_ipv4_neighbors()
1222 cls.pg1.generate_remote_hosts(1)
1223 cls.pg1.configure_ipv4_neighbors()
1225 cls.overlapping_interfaces = list(list(cls.pg_interfaces[4:7]))
1226 cls.vapi.ip_table_add_del(is_add=1, table={'table_id': 10})
1227 cls.vapi.ip_table_add_del(is_add=1, table={'table_id': 20})
1229 cls.pg4._local_ip4 = "172.16.255.1"
1230 cls.pg4._remote_hosts[0]._ip4 = "172.16.255.2"
1231 cls.pg4.set_table_ip4(10)
1232 cls.pg5._local_ip4 = "172.17.255.3"
1233 cls.pg5._remote_hosts[0]._ip4 = "172.17.255.4"
1234 cls.pg5.set_table_ip4(10)
1235 cls.pg6._local_ip4 = "172.16.255.1"
1236 cls.pg6._remote_hosts[0]._ip4 = "172.16.255.2"
1237 cls.pg6.set_table_ip4(20)
1238 for i in cls.overlapping_interfaces:
1246 cls.pg9.generate_remote_hosts(2)
1247 cls.pg9.config_ip4()
1248 cls.vapi.sw_interface_add_del_address(
1249 sw_if_index=cls.pg9.sw_if_index,
1250 prefix="10.0.0.1/24")
1253 cls.pg9.resolve_arp()
1254 cls.pg9._remote_hosts[1]._ip4 = cls.pg9._remote_hosts[0]._ip4
1255 cls.pg4._remote_ip4 = cls.pg9._remote_hosts[0]._ip4 = "10.0.0.2"
1256 cls.pg9.resolve_arp()
1259 super(TestNAT44, self).setUp()
1260 self.vapi.nat44_plugin_enable_disable(
1261 sessions=self.max_translations,
1262 users=self.max_users, enable=1)
1265 def tearDownClass(cls):
1266 super(TestNAT44, cls).tearDownClass()
1269 super(TestNAT44, self).tearDown()
1270 if not self.vpp_dead:
1271 self.vapi.nat_ipfix_enable_disable(domain_id=self.ipfix_domain_id,
1272 src_port=self.ipfix_src_port,
1274 self.ipfix_src_port = 4739
1275 self.ipfix_domain_id = 1
1277 self.vapi.nat44_plugin_enable_disable(enable=0)
1278 self.vapi.cli("clear logging")
1280 def test_clear_sessions(self):
1281 """ NAT44 session clearing test """
1283 self.nat44_add_address(self.nat_addr)
1284 flags = self.config_flags.NAT_IS_INSIDE
1285 self.vapi.nat44_interface_add_del_feature(
1286 sw_if_index=self.pg0.sw_if_index,
1287 flags=flags, is_add=1)
1288 self.vapi.nat44_interface_add_del_feature(
1289 sw_if_index=self.pg1.sw_if_index,
1292 nat_config = self.vapi.nat_show_config()
1293 self.assertEqual(0, nat_config.endpoint_dependent)
1295 pkts = self.create_stream_in(self.pg0, self.pg1)
1296 self.pg0.add_stream(pkts)
1297 self.pg_enable_capture(self.pg_interfaces)
1299 capture = self.pg1.get_capture(len(pkts))
1300 self.verify_capture_out(capture)
1302 sessions = self.statistics.get_counter('/nat44/total-sessions')
1303 self.assertTrue(sessions[0][0] > 0)
1304 self.logger.info("sessions before clearing: %s" % sessions[0][0])
1306 self.vapi.cli("clear nat44 sessions")
1308 sessions = self.statistics.get_counter('/nat44/total-sessions')
1309 self.assertEqual(sessions[0][0], 0)
1310 self.logger.info("sessions after clearing: %s" % sessions[0][0])
1312 def test_dynamic(self):
1313 """ NAT44 dynamic translation test """
1314 self.nat44_add_address(self.nat_addr)
1315 flags = self.config_flags.NAT_IS_INSIDE
1316 self.vapi.nat44_interface_add_del_feature(
1317 sw_if_index=self.pg0.sw_if_index,
1318 flags=flags, is_add=1)
1319 self.vapi.nat44_interface_add_del_feature(
1320 sw_if_index=self.pg1.sw_if_index,
1324 tcpn = self.statistics.get_counter('/nat44/in2out/slowpath/tcp')[0]
1325 udpn = self.statistics.get_counter('/nat44/in2out/slowpath/udp')[0]
1326 icmpn = self.statistics.get_counter('/nat44/in2out/slowpath/icmp')[0]
1327 drops = self.statistics.get_counter('/nat44/in2out/slowpath/drops')[0]
1329 pkts = self.create_stream_in(self.pg0, self.pg1)
1330 self.pg0.add_stream(pkts)
1331 self.pg_enable_capture(self.pg_interfaces)
1333 capture = self.pg1.get_capture(len(pkts))
1334 self.verify_capture_out(capture)
1336 if_idx = self.pg0.sw_if_index
1337 cnt = self.statistics.get_counter('/nat44/in2out/slowpath/tcp')[0]
1338 self.assertEqual(cnt[if_idx] - tcpn[if_idx], 2)
1339 cnt = self.statistics.get_counter('/nat44/in2out/slowpath/udp')[0]
1340 self.assertEqual(cnt[if_idx] - udpn[if_idx], 1)
1341 cnt = self.statistics.get_counter('/nat44/in2out/slowpath/icmp')[0]
1342 self.assertEqual(cnt[if_idx] - icmpn[if_idx], 1)
1343 cnt = self.statistics.get_counter('/nat44/in2out/slowpath/drops')[0]
1344 self.assertEqual(cnt[if_idx] - drops[if_idx], 0)
1347 tcpn = self.statistics.get_counter('/nat44/out2in/slowpath/tcp')[0]
1348 udpn = self.statistics.get_counter('/nat44/out2in/slowpath/udp')[0]
1349 icmpn = self.statistics.get_counter('/nat44/out2in/slowpath/icmp')[0]
1350 drops = self.statistics.get_counter('/nat44/out2in/slowpath/drops')[0]
1352 pkts = self.create_stream_out(self.pg1)
1353 self.pg1.add_stream(pkts)
1354 self.pg_enable_capture(self.pg_interfaces)
1356 capture = self.pg0.get_capture(len(pkts))
1357 self.verify_capture_in(capture, self.pg0)
1359 if_idx = self.pg1.sw_if_index
1360 cnt = self.statistics.get_counter('/nat44/out2in/slowpath/tcp')[0]
1361 self.assertEqual(cnt[if_idx] - tcpn[if_idx], 2)
1362 cnt = self.statistics.get_counter('/nat44/out2in/slowpath/udp')[0]
1363 self.assertEqual(cnt[if_idx] - udpn[if_idx], 1)
1364 cnt = self.statistics.get_counter('/nat44/out2in/slowpath/icmp')[0]
1365 self.assertEqual(cnt[if_idx] - icmpn[if_idx], 1)
1366 cnt = self.statistics.get_counter('/nat44/out2in/slowpath/drops')[0]
1367 self.assertEqual(cnt[if_idx] - drops[if_idx], 0)
1369 users = self.statistics.get_counter('/nat44/total-users')
1370 self.assertEqual(users[0][0], 1)
1371 sessions = self.statistics.get_counter('/nat44/total-sessions')
1372 self.assertEqual(sessions[0][0], 3)
1374 def test_dynamic_icmp_errors_in2out_ttl_1(self):
1375 """ NAT44 handling of client packets with TTL=1 """
1377 self.nat44_add_address(self.nat_addr)
1378 flags = self.config_flags.NAT_IS_INSIDE
1379 self.vapi.nat44_interface_add_del_feature(
1380 sw_if_index=self.pg0.sw_if_index,
1381 flags=flags, is_add=1)
1382 self.vapi.nat44_interface_add_del_feature(
1383 sw_if_index=self.pg1.sw_if_index,
1386 # Client side - generate traffic
1387 pkts = self.create_stream_in(self.pg0, self.pg1, ttl=1)
1388 self.pg0.add_stream(pkts)
1389 self.pg_enable_capture(self.pg_interfaces)
1392 # Client side - verify ICMP type 11 packets
1393 capture = self.pg0.get_capture(len(pkts))
1394 self.verify_capture_in_with_icmp_errors(capture, self.pg0)
1396 def test_dynamic_icmp_errors_out2in_ttl_1(self):
1397 """ NAT44 handling of server packets with TTL=1 """
1399 self.nat44_add_address(self.nat_addr)
1400 flags = self.config_flags.NAT_IS_INSIDE
1401 self.vapi.nat44_interface_add_del_feature(
1402 sw_if_index=self.pg0.sw_if_index,
1403 flags=flags, is_add=1)
1404 self.vapi.nat44_interface_add_del_feature(
1405 sw_if_index=self.pg1.sw_if_index,
1408 # Client side - create sessions
1409 pkts = self.create_stream_in(self.pg0, self.pg1)
1410 self.pg0.add_stream(pkts)
1411 self.pg_enable_capture(self.pg_interfaces)
1414 # Server side - generate traffic
1415 capture = self.pg1.get_capture(len(pkts))
1416 self.verify_capture_out(capture)
1417 pkts = self.create_stream_out(self.pg1, ttl=1)
1418 self.pg1.add_stream(pkts)
1419 self.pg_enable_capture(self.pg_interfaces)
1422 # Server side - verify ICMP type 11 packets
1423 capture = self.pg1.get_capture(len(pkts))
1424 self.verify_capture_out_with_icmp_errors(capture,
1425 src_ip=self.pg1.local_ip4)
1427 def test_dynamic_icmp_errors_in2out_ttl_2(self):
1428 """ NAT44 handling of error responses to client packets with TTL=2 """
1430 self.nat44_add_address(self.nat_addr)
1431 flags = self.config_flags.NAT_IS_INSIDE
1432 self.vapi.nat44_interface_add_del_feature(
1433 sw_if_index=self.pg0.sw_if_index,
1434 flags=flags, is_add=1)
1435 self.vapi.nat44_interface_add_del_feature(
1436 sw_if_index=self.pg1.sw_if_index,
1439 # Client side - generate traffic
1440 pkts = self.create_stream_in(self.pg0, self.pg1, ttl=2)
1441 self.pg0.add_stream(pkts)
1442 self.pg_enable_capture(self.pg_interfaces)
1445 # Server side - simulate ICMP type 11 response
1446 capture = self.pg1.get_capture(len(pkts))
1447 pkts = [Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
1448 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
1449 ICMP(type=11) / packet[IP] for packet in capture]
1450 self.pg1.add_stream(pkts)
1451 self.pg_enable_capture(self.pg_interfaces)
1454 # Client side - verify ICMP type 11 packets
1455 capture = self.pg0.get_capture(len(pkts))
1456 self.verify_capture_in_with_icmp_errors(capture, self.pg0)
1458 def test_dynamic_icmp_errors_out2in_ttl_2(self):
1459 """ NAT44 handling of error responses to server packets with TTL=2 """
1461 self.nat44_add_address(self.nat_addr)
1462 flags = self.config_flags.NAT_IS_INSIDE
1463 self.vapi.nat44_interface_add_del_feature(
1464 sw_if_index=self.pg0.sw_if_index,
1465 flags=flags, is_add=1)
1466 self.vapi.nat44_interface_add_del_feature(
1467 sw_if_index=self.pg1.sw_if_index,
1470 # Client side - create sessions
1471 pkts = self.create_stream_in(self.pg0, self.pg1)
1472 self.pg0.add_stream(pkts)
1473 self.pg_enable_capture(self.pg_interfaces)
1476 # Server side - generate traffic
1477 capture = self.pg1.get_capture(len(pkts))
1478 self.verify_capture_out(capture)
1479 pkts = self.create_stream_out(self.pg1, ttl=2)
1480 self.pg1.add_stream(pkts)
1481 self.pg_enable_capture(self.pg_interfaces)
1484 # Client side - simulate ICMP type 11 response
1485 capture = self.pg0.get_capture(len(pkts))
1486 pkts = [Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
1487 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
1488 ICMP(type=11) / packet[IP] for packet in capture]
1489 self.pg0.add_stream(pkts)
1490 self.pg_enable_capture(self.pg_interfaces)
1493 # Server side - verify ICMP type 11 packets
1494 capture = self.pg1.get_capture(len(pkts))
1495 self.verify_capture_out_with_icmp_errors(capture)
1497 def test_ping_out_interface_from_outside(self):
1498 """ Ping NAT44 out interface from outside network """
1500 self.nat44_add_address(self.nat_addr)
1501 flags = self.config_flags.NAT_IS_INSIDE
1502 self.vapi.nat44_interface_add_del_feature(
1503 sw_if_index=self.pg0.sw_if_index,
1504 flags=flags, is_add=1)
1505 self.vapi.nat44_interface_add_del_feature(
1506 sw_if_index=self.pg1.sw_if_index,
1509 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
1510 IP(src=self.pg1.remote_ip4, dst=self.pg1.local_ip4) /
1511 ICMP(id=self.icmp_id_out, type='echo-request'))
1513 self.pg1.add_stream(pkts)
1514 self.pg_enable_capture(self.pg_interfaces)
1516 capture = self.pg1.get_capture(len(pkts))
1519 self.assertEqual(packet[IP].src, self.pg1.local_ip4)
1520 self.assertEqual(packet[IP].dst, self.pg1.remote_ip4)
1521 self.assertEqual(packet[ICMP].id, self.icmp_id_in)
1522 self.assertEqual(packet[ICMP].type, 0) # echo reply
1524 self.logger.error(ppp("Unexpected or invalid packet "
1525 "(outside network):", packet))
1528 def test_ping_internal_host_from_outside(self):
1529 """ Ping internal host from outside network """
1531 self.nat44_add_static_mapping(self.pg0.remote_ip4, self.nat_addr)
1532 flags = self.config_flags.NAT_IS_INSIDE
1533 self.vapi.nat44_interface_add_del_feature(
1534 sw_if_index=self.pg0.sw_if_index,
1535 flags=flags, is_add=1)
1536 self.vapi.nat44_interface_add_del_feature(
1537 sw_if_index=self.pg1.sw_if_index,
1541 pkt = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
1542 IP(src=self.pg1.remote_ip4, dst=self.nat_addr, ttl=64) /
1543 ICMP(id=self.icmp_id_out, type='echo-request'))
1544 self.pg1.add_stream(pkt)
1545 self.pg_enable_capture(self.pg_interfaces)
1547 capture = self.pg0.get_capture(1)
1548 self.verify_capture_in(capture, self.pg0)
1549 self.assert_equal(capture[0][IP].proto, IP_PROTOS.icmp)
1552 pkt = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
1553 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4, ttl=64) /
1554 ICMP(id=self.icmp_id_in, type='echo-reply'))
1555 self.pg0.add_stream(pkt)
1556 self.pg_enable_capture(self.pg_interfaces)
1558 capture = self.pg1.get_capture(1)
1559 self.verify_capture_out(capture, same_port=True)
1560 self.assert_equal(capture[0][IP].proto, IP_PROTOS.icmp)
1562 def test_forwarding(self):
1563 """ NAT44 forwarding test """
1565 flags = self.config_flags.NAT_IS_INSIDE
1566 self.vapi.nat44_interface_add_del_feature(
1567 sw_if_index=self.pg0.sw_if_index,
1568 flags=flags, is_add=1)
1569 self.vapi.nat44_interface_add_del_feature(
1570 sw_if_index=self.pg1.sw_if_index,
1572 self.vapi.nat44_forwarding_enable_disable(enable=1)
1574 real_ip = self.pg0.remote_ip4
1575 alias_ip = self.nat_addr
1576 flags = self.config_flags.NAT_IS_ADDR_ONLY
1577 self.vapi.nat44_add_del_static_mapping(is_add=1,
1578 local_ip_address=real_ip,
1579 external_ip_address=alias_ip,
1580 external_sw_if_index=0xFFFFFFFF,
1584 # static mapping match
1586 pkts = self.create_stream_out(self.pg1)
1587 self.pg1.add_stream(pkts)
1588 self.pg_enable_capture(self.pg_interfaces)
1590 capture = self.pg0.get_capture(len(pkts))
1591 self.verify_capture_in(capture, self.pg0)
1593 pkts = self.create_stream_in(self.pg0, self.pg1)
1594 self.pg0.add_stream(pkts)
1595 self.pg_enable_capture(self.pg_interfaces)
1597 capture = self.pg1.get_capture(len(pkts))
1598 self.verify_capture_out(capture, same_port=True)
1600 # no static mapping match
1602 host0 = self.pg0.remote_hosts[0]
1603 self.pg0.remote_hosts[0] = self.pg0.remote_hosts[1]
1605 pkts = self.create_stream_out(self.pg1,
1606 dst_ip=self.pg0.remote_ip4,
1607 use_inside_ports=True)
1608 self.pg1.add_stream(pkts)
1609 self.pg_enable_capture(self.pg_interfaces)
1611 capture = self.pg0.get_capture(len(pkts))
1612 self.verify_capture_in(capture, self.pg0)
1614 pkts = self.create_stream_in(self.pg0, self.pg1)
1615 self.pg0.add_stream(pkts)
1616 self.pg_enable_capture(self.pg_interfaces)
1618 capture = self.pg1.get_capture(len(pkts))
1619 self.verify_capture_out(capture, nat_ip=self.pg0.remote_ip4,
1622 self.pg0.remote_hosts[0] = host0
1625 self.vapi.nat44_forwarding_enable_disable(enable=0)
1626 flags = self.config_flags.NAT_IS_ADDR_ONLY
1627 self.vapi.nat44_add_del_static_mapping(
1629 local_ip_address=real_ip,
1630 external_ip_address=alias_ip,
1631 external_sw_if_index=0xFFFFFFFF,
1634 def test_static_in(self):
1635 """ 1:1 NAT initialized from inside network """
1637 nat_ip = "10.0.0.10"
1638 self.tcp_port_out = 6303
1639 self.udp_port_out = 6304
1640 self.icmp_id_out = 6305
1642 self.nat44_add_static_mapping(self.pg0.remote_ip4, nat_ip)
1643 flags = self.config_flags.NAT_IS_INSIDE
1644 self.vapi.nat44_interface_add_del_feature(
1645 sw_if_index=self.pg0.sw_if_index,
1646 flags=flags, is_add=1)
1647 self.vapi.nat44_interface_add_del_feature(
1648 sw_if_index=self.pg1.sw_if_index,
1650 sm = self.vapi.nat44_static_mapping_dump()
1651 self.assertEqual(len(sm), 1)
1652 self.assertEqual(sm[0].tag, '')
1653 self.assertEqual(sm[0].protocol, 0)
1654 self.assertEqual(sm[0].local_port, 0)
1655 self.assertEqual(sm[0].external_port, 0)
1658 pkts = self.create_stream_in(self.pg0, self.pg1)
1659 self.pg0.add_stream(pkts)
1660 self.pg_enable_capture(self.pg_interfaces)
1662 capture = self.pg1.get_capture(len(pkts))
1663 self.verify_capture_out(capture, nat_ip, True)
1666 pkts = self.create_stream_out(self.pg1, nat_ip)
1667 self.pg1.add_stream(pkts)
1668 self.pg_enable_capture(self.pg_interfaces)
1670 capture = self.pg0.get_capture(len(pkts))
1671 self.verify_capture_in(capture, self.pg0)
1673 def test_static_out(self):
1674 """ 1:1 NAT initialized from outside network """
1676 nat_ip = "10.0.0.20"
1677 self.tcp_port_out = 6303
1678 self.udp_port_out = 6304
1679 self.icmp_id_out = 6305
1682 self.nat44_add_static_mapping(self.pg0.remote_ip4, nat_ip, tag=tag)
1683 flags = self.config_flags.NAT_IS_INSIDE
1684 self.vapi.nat44_interface_add_del_feature(
1685 sw_if_index=self.pg0.sw_if_index,
1686 flags=flags, is_add=1)
1687 self.vapi.nat44_interface_add_del_feature(
1688 sw_if_index=self.pg1.sw_if_index,
1690 sm = self.vapi.nat44_static_mapping_dump()
1691 self.assertEqual(len(sm), 1)
1692 self.assertEqual(sm[0].tag, tag)
1695 pkts = self.create_stream_out(self.pg1, nat_ip)
1696 self.pg1.add_stream(pkts)
1697 self.pg_enable_capture(self.pg_interfaces)
1699 capture = self.pg0.get_capture(len(pkts))
1700 self.verify_capture_in(capture, self.pg0)
1703 pkts = self.create_stream_in(self.pg0, self.pg1)
1704 self.pg0.add_stream(pkts)
1705 self.pg_enable_capture(self.pg_interfaces)
1707 capture = self.pg1.get_capture(len(pkts))
1708 self.verify_capture_out(capture, nat_ip, True)
1710 def test_static_with_port_in(self):
1711 """ 1:1 NAPT initialized from inside network """
1713 self.tcp_port_out = 3606
1714 self.udp_port_out = 3607
1715 self.icmp_id_out = 3608
1717 self.nat44_add_address(self.nat_addr)
1718 self.nat44_add_static_mapping(self.pg0.remote_ip4, self.nat_addr,
1719 self.tcp_port_in, self.tcp_port_out,
1720 proto=IP_PROTOS.tcp)
1721 self.nat44_add_static_mapping(self.pg0.remote_ip4, self.nat_addr,
1722 self.udp_port_in, self.udp_port_out,
1723 proto=IP_PROTOS.udp)
1724 self.nat44_add_static_mapping(self.pg0.remote_ip4, self.nat_addr,
1725 self.icmp_id_in, self.icmp_id_out,
1726 proto=IP_PROTOS.icmp)
1727 flags = self.config_flags.NAT_IS_INSIDE
1728 self.vapi.nat44_interface_add_del_feature(
1729 sw_if_index=self.pg0.sw_if_index,
1730 flags=flags, is_add=1)
1731 self.vapi.nat44_interface_add_del_feature(
1732 sw_if_index=self.pg1.sw_if_index,
1736 pkts = self.create_stream_in(self.pg0, self.pg1)
1737 self.pg0.add_stream(pkts)
1738 self.pg_enable_capture(self.pg_interfaces)
1740 capture = self.pg1.get_capture(len(pkts))
1741 self.verify_capture_out(capture)
1744 pkts = self.create_stream_out(self.pg1)
1745 self.pg1.add_stream(pkts)
1746 self.pg_enable_capture(self.pg_interfaces)
1748 capture = self.pg0.get_capture(len(pkts))
1749 self.verify_capture_in(capture, self.pg0)
1751 def test_static_with_port_out(self):
1752 """ 1:1 NAPT initialized from outside network """
1754 self.tcp_port_out = 30606
1755 self.udp_port_out = 30607
1756 self.icmp_id_out = 30608
1758 self.nat44_add_address(self.nat_addr)
1759 self.nat44_add_static_mapping(self.pg0.remote_ip4, self.nat_addr,
1760 self.tcp_port_in, self.tcp_port_out,
1761 proto=IP_PROTOS.tcp)
1762 self.nat44_add_static_mapping(self.pg0.remote_ip4, self.nat_addr,
1763 self.udp_port_in, self.udp_port_out,
1764 proto=IP_PROTOS.udp)
1765 self.nat44_add_static_mapping(self.pg0.remote_ip4, self.nat_addr,
1766 self.icmp_id_in, self.icmp_id_out,
1767 proto=IP_PROTOS.icmp)
1768 flags = self.config_flags.NAT_IS_INSIDE
1769 self.vapi.nat44_interface_add_del_feature(
1770 sw_if_index=self.pg0.sw_if_index,
1771 flags=flags, is_add=1)
1772 self.vapi.nat44_interface_add_del_feature(
1773 sw_if_index=self.pg1.sw_if_index,
1777 pkts = self.create_stream_out(self.pg1)
1778 self.pg1.add_stream(pkts)
1779 self.pg_enable_capture(self.pg_interfaces)
1781 capture = self.pg0.get_capture(len(pkts))
1782 self.verify_capture_in(capture, self.pg0)
1785 pkts = self.create_stream_in(self.pg0, self.pg1)
1786 self.pg0.add_stream(pkts)
1787 self.pg_enable_capture(self.pg_interfaces)
1789 capture = self.pg1.get_capture(len(pkts))
1790 self.verify_capture_out(capture)
1792 def test_static_vrf_aware(self):
1793 """ 1:1 NAT VRF awareness """
1795 nat_ip1 = "10.0.0.30"
1796 nat_ip2 = "10.0.0.40"
1797 self.tcp_port_out = 6303
1798 self.udp_port_out = 6304
1799 self.icmp_id_out = 6305
1801 self.nat44_add_static_mapping(self.pg4.remote_ip4, nat_ip1,
1803 self.nat44_add_static_mapping(self.pg0.remote_ip4, nat_ip2,
1805 flags = self.config_flags.NAT_IS_INSIDE
1806 self.vapi.nat44_interface_add_del_feature(
1807 sw_if_index=self.pg3.sw_if_index,
1809 self.vapi.nat44_interface_add_del_feature(
1810 sw_if_index=self.pg0.sw_if_index,
1811 flags=flags, is_add=1)
1812 self.vapi.nat44_interface_add_del_feature(
1813 sw_if_index=self.pg4.sw_if_index,
1814 flags=flags, is_add=1)
1816 # inside interface VRF match NAT44 static mapping VRF
1817 pkts = self.create_stream_in(self.pg4, self.pg3)
1818 self.pg4.add_stream(pkts)
1819 self.pg_enable_capture(self.pg_interfaces)
1821 capture = self.pg3.get_capture(len(pkts))
1822 self.verify_capture_out(capture, nat_ip1, True)
1824 # inside interface VRF don't match NAT44 static mapping VRF (packets
1826 pkts = self.create_stream_in(self.pg0, self.pg3)
1827 self.pg0.add_stream(pkts)
1828 self.pg_enable_capture(self.pg_interfaces)
1830 self.pg3.assert_nothing_captured()
1832 def test_dynamic_to_static(self):
1833 """ Switch from dynamic translation to 1:1NAT """
1834 nat_ip = "10.0.0.10"
1835 self.tcp_port_out = 6303
1836 self.udp_port_out = 6304
1837 self.icmp_id_out = 6305
1839 self.nat44_add_address(self.nat_addr)
1840 flags = self.config_flags.NAT_IS_INSIDE
1841 self.vapi.nat44_interface_add_del_feature(
1842 sw_if_index=self.pg0.sw_if_index,
1843 flags=flags, is_add=1)
1844 self.vapi.nat44_interface_add_del_feature(
1845 sw_if_index=self.pg1.sw_if_index,
1849 pkts = self.create_stream_in(self.pg0, self.pg1)
1850 self.pg0.add_stream(pkts)
1851 self.pg_enable_capture(self.pg_interfaces)
1853 capture = self.pg1.get_capture(len(pkts))
1854 self.verify_capture_out(capture)
1857 self.nat44_add_static_mapping(self.pg0.remote_ip4, nat_ip)
1858 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4, 0)
1859 self.assertEqual(len(sessions), 0)
1860 pkts = self.create_stream_in(self.pg0, self.pg1)
1861 self.pg0.add_stream(pkts)
1862 self.pg_enable_capture(self.pg_interfaces)
1864 capture = self.pg1.get_capture(len(pkts))
1865 self.verify_capture_out(capture, nat_ip, True)
1867 def test_identity_nat(self):
1868 """ Identity NAT """
1869 flags = self.config_flags.NAT_IS_ADDR_ONLY
1870 self.vapi.nat44_add_del_identity_mapping(
1871 ip_address=self.pg0.remote_ip4, sw_if_index=0xFFFFFFFF,
1872 flags=flags, is_add=1)
1873 flags = self.config_flags.NAT_IS_INSIDE
1874 self.vapi.nat44_interface_add_del_feature(
1875 sw_if_index=self.pg0.sw_if_index,
1876 flags=flags, is_add=1)
1877 self.vapi.nat44_interface_add_del_feature(
1878 sw_if_index=self.pg1.sw_if_index,
1881 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
1882 IP(src=self.pg1.remote_ip4, dst=self.pg0.remote_ip4) /
1883 TCP(sport=12345, dport=56789))
1884 self.pg1.add_stream(p)
1885 self.pg_enable_capture(self.pg_interfaces)
1887 capture = self.pg0.get_capture(1)
1892 self.assertEqual(ip.dst, self.pg0.remote_ip4)
1893 self.assertEqual(ip.src, self.pg1.remote_ip4)
1894 self.assertEqual(tcp.dport, 56789)
1895 self.assertEqual(tcp.sport, 12345)
1896 self.assert_packet_checksums_valid(p)
1898 self.logger.error(ppp("Unexpected or invalid packet:", p))
1901 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4, 0)
1902 self.assertEqual(len(sessions), 0)
1903 flags = self.config_flags.NAT_IS_ADDR_ONLY
1904 self.vapi.nat44_add_del_identity_mapping(
1905 ip_address=self.pg0.remote_ip4, sw_if_index=0xFFFFFFFF,
1906 flags=flags, vrf_id=1, is_add=1)
1907 identity_mappings = self.vapi.nat44_identity_mapping_dump()
1908 self.assertEqual(len(identity_mappings), 2)
1910 def test_multiple_inside_interfaces(self):
1911 """ NAT44 multiple non-overlapping address space inside interfaces """
1913 self.nat44_add_address(self.nat_addr)
1914 flags = self.config_flags.NAT_IS_INSIDE
1915 self.vapi.nat44_interface_add_del_feature(
1916 sw_if_index=self.pg0.sw_if_index,
1917 flags=flags, is_add=1)
1918 self.vapi.nat44_interface_add_del_feature(
1919 sw_if_index=self.pg1.sw_if_index,
1920 flags=flags, is_add=1)
1921 self.vapi.nat44_interface_add_del_feature(
1922 sw_if_index=self.pg3.sw_if_index,
1925 # between two NAT44 inside interfaces (no translation)
1926 pkts = self.create_stream_in(self.pg0, self.pg1)
1927 self.pg0.add_stream(pkts)
1928 self.pg_enable_capture(self.pg_interfaces)
1930 capture = self.pg1.get_capture(len(pkts))
1931 self.verify_capture_no_translation(capture, self.pg0, self.pg1)
1933 # from NAT44 inside to interface without NAT44 feature (no translation)
1934 pkts = self.create_stream_in(self.pg0, self.pg2)
1935 self.pg0.add_stream(pkts)
1936 self.pg_enable_capture(self.pg_interfaces)
1938 capture = self.pg2.get_capture(len(pkts))
1939 self.verify_capture_no_translation(capture, self.pg0, self.pg2)
1941 # in2out 1st interface
1942 pkts = self.create_stream_in(self.pg0, self.pg3)
1943 self.pg0.add_stream(pkts)
1944 self.pg_enable_capture(self.pg_interfaces)
1946 capture = self.pg3.get_capture(len(pkts))
1947 self.verify_capture_out(capture)
1949 # out2in 1st interface
1950 pkts = self.create_stream_out(self.pg3)
1951 self.pg3.add_stream(pkts)
1952 self.pg_enable_capture(self.pg_interfaces)
1954 capture = self.pg0.get_capture(len(pkts))
1955 self.verify_capture_in(capture, self.pg0)
1957 # in2out 2nd interface
1958 pkts = self.create_stream_in(self.pg1, self.pg3)
1959 self.pg1.add_stream(pkts)
1960 self.pg_enable_capture(self.pg_interfaces)
1962 capture = self.pg3.get_capture(len(pkts))
1963 self.verify_capture_out(capture)
1965 # out2in 2nd interface
1966 pkts = self.create_stream_out(self.pg3)
1967 self.pg3.add_stream(pkts)
1968 self.pg_enable_capture(self.pg_interfaces)
1970 capture = self.pg1.get_capture(len(pkts))
1971 self.verify_capture_in(capture, self.pg1)
1973 def test_inside_overlapping_interfaces(self):
1974 """ NAT44 multiple inside interfaces with overlapping address space """
1976 static_nat_ip = "10.0.0.10"
1977 self.nat44_add_address(self.nat_addr)
1978 flags = self.config_flags.NAT_IS_INSIDE
1979 self.vapi.nat44_interface_add_del_feature(
1980 sw_if_index=self.pg3.sw_if_index,
1982 self.vapi.nat44_interface_add_del_feature(
1983 sw_if_index=self.pg4.sw_if_index,
1984 flags=flags, is_add=1)
1985 self.vapi.nat44_interface_add_del_feature(
1986 sw_if_index=self.pg5.sw_if_index,
1987 flags=flags, is_add=1)
1988 self.vapi.nat44_interface_add_del_feature(
1989 sw_if_index=self.pg6.sw_if_index,
1990 flags=flags, is_add=1)
1991 self.nat44_add_static_mapping(self.pg6.remote_ip4, static_nat_ip,
1994 # between NAT44 inside interfaces with same VRF (no translation)
1995 pkts = self.create_stream_in(self.pg4, self.pg5)
1996 self.pg4.add_stream(pkts)
1997 self.pg_enable_capture(self.pg_interfaces)
1999 capture = self.pg5.get_capture(len(pkts))
2000 self.verify_capture_no_translation(capture, self.pg4, self.pg5)
2002 # between NAT44 inside interfaces with different VRF (hairpinning)
2003 p = (Ether(src=self.pg4.remote_mac, dst=self.pg4.local_mac) /
2004 IP(src=self.pg4.remote_ip4, dst=static_nat_ip) /
2005 TCP(sport=1234, dport=5678))
2006 self.pg4.add_stream(p)
2007 self.pg_enable_capture(self.pg_interfaces)
2009 capture = self.pg6.get_capture(1)
2014 self.assertEqual(ip.src, self.nat_addr)
2015 self.assertEqual(ip.dst, self.pg6.remote_ip4)
2016 self.assertNotEqual(tcp.sport, 1234)
2017 self.assertEqual(tcp.dport, 5678)
2019 self.logger.error(ppp("Unexpected or invalid packet:", p))
2022 # in2out 1st interface
2023 pkts = self.create_stream_in(self.pg4, self.pg3)
2024 self.pg4.add_stream(pkts)
2025 self.pg_enable_capture(self.pg_interfaces)
2027 capture = self.pg3.get_capture(len(pkts))
2028 self.verify_capture_out(capture)
2030 # out2in 1st interface
2031 pkts = self.create_stream_out(self.pg3)
2032 self.pg3.add_stream(pkts)
2033 self.pg_enable_capture(self.pg_interfaces)
2035 capture = self.pg4.get_capture(len(pkts))
2036 self.verify_capture_in(capture, self.pg4)
2038 # in2out 2nd interface
2039 pkts = self.create_stream_in(self.pg5, self.pg3)
2040 self.pg5.add_stream(pkts)
2041 self.pg_enable_capture(self.pg_interfaces)
2043 capture = self.pg3.get_capture(len(pkts))
2044 self.verify_capture_out(capture)
2046 # out2in 2nd interface
2047 pkts = self.create_stream_out(self.pg3)
2048 self.pg3.add_stream(pkts)
2049 self.pg_enable_capture(self.pg_interfaces)
2051 capture = self.pg5.get_capture(len(pkts))
2052 self.verify_capture_in(capture, self.pg5)
2055 addresses = self.vapi.nat44_address_dump()
2056 self.assertEqual(len(addresses), 1)
2057 sessions = self.vapi.nat44_user_session_dump(self.pg5.remote_ip4, 10)
2058 self.assertEqual(len(sessions), 3)
2059 for session in sessions:
2060 self.assertFalse(session.flags & self.config_flags.NAT_IS_STATIC)
2061 self.assertEqual(str(session.inside_ip_address),
2062 self.pg5.remote_ip4)
2063 self.assertEqual(session.outside_ip_address,
2064 addresses[0].ip_address)
2065 self.assertEqual(sessions[0].protocol, IP_PROTOS.tcp)
2066 self.assertEqual(sessions[1].protocol, IP_PROTOS.udp)
2067 self.assertEqual(sessions[2].protocol, IP_PROTOS.icmp)
2068 self.assertEqual(sessions[0].inside_port, self.tcp_port_in)
2069 self.assertEqual(sessions[1].inside_port, self.udp_port_in)
2070 self.assertEqual(sessions[2].inside_port, self.icmp_id_in)
2071 self.assertEqual(sessions[0].outside_port, self.tcp_port_out)
2072 self.assertEqual(sessions[1].outside_port, self.udp_port_out)
2073 self.assertEqual(sessions[2].outside_port, self.icmp_id_out)
2075 # in2out 3rd interface
2076 pkts = self.create_stream_in(self.pg6, self.pg3)
2077 self.pg6.add_stream(pkts)
2078 self.pg_enable_capture(self.pg_interfaces)
2080 capture = self.pg3.get_capture(len(pkts))
2081 self.verify_capture_out(capture, static_nat_ip, True)
2083 # out2in 3rd interface
2084 pkts = self.create_stream_out(self.pg3, static_nat_ip)
2085 self.pg3.add_stream(pkts)
2086 self.pg_enable_capture(self.pg_interfaces)
2088 capture = self.pg6.get_capture(len(pkts))
2089 self.verify_capture_in(capture, self.pg6)
2091 # general user and session dump verifications
2092 users = self.vapi.nat44_user_dump()
2093 self.assertGreaterEqual(len(users), 3)
2094 addresses = self.vapi.nat44_address_dump()
2095 self.assertEqual(len(addresses), 1)
2097 sessions = self.vapi.nat44_user_session_dump(user.ip_address,
2099 for session in sessions:
2100 self.assertEqual(user.ip_address, session.inside_ip_address)
2101 self.assertTrue(session.total_bytes > session.total_pkts > 0)
2102 self.assertTrue(session.protocol in
2103 [IP_PROTOS.tcp, IP_PROTOS.udp,
2105 self.assertFalse(session.flags &
2106 self.config_flags.NAT_IS_EXT_HOST_VALID)
2109 sessions = self.vapi.nat44_user_session_dump(self.pg4.remote_ip4, 10)
2110 self.assertGreaterEqual(len(sessions), 4)
2111 for session in sessions:
2112 self.assertFalse(session.flags & self.config_flags.NAT_IS_STATIC)
2113 self.assertEqual(str(session.inside_ip_address),
2114 self.pg4.remote_ip4)
2115 self.assertEqual(session.outside_ip_address,
2116 addresses[0].ip_address)
2119 sessions = self.vapi.nat44_user_session_dump(self.pg6.remote_ip4, 20)
2120 self.assertGreaterEqual(len(sessions), 3)
2121 for session in sessions:
2122 self.assertTrue(session.flags & self.config_flags.NAT_IS_STATIC)
2123 self.assertEqual(str(session.inside_ip_address),
2124 self.pg6.remote_ip4)
2125 self.assertEqual(str(session.outside_ip_address),
2127 self.assertTrue(session.inside_port in
2128 [self.tcp_port_in, self.udp_port_in,
2131 def test_hairpinning(self):
2132 """ NAT44 hairpinning - 1:1 NAPT """
2134 host = self.pg0.remote_hosts[0]
2135 server = self.pg0.remote_hosts[1]
2138 server_in_port = 5678
2139 server_out_port = 8765
2141 self.nat44_add_address(self.nat_addr)
2142 flags = self.config_flags.NAT_IS_INSIDE
2143 self.vapi.nat44_interface_add_del_feature(
2144 sw_if_index=self.pg0.sw_if_index,
2145 flags=flags, is_add=1)
2146 self.vapi.nat44_interface_add_del_feature(
2147 sw_if_index=self.pg1.sw_if_index,
2150 # add static mapping for server
2151 self.nat44_add_static_mapping(server.ip4, self.nat_addr,
2152 server_in_port, server_out_port,
2153 proto=IP_PROTOS.tcp)
2155 cnt = self.statistics.get_counter('/nat44/hairpinning')[0]
2156 # send packet from host to server
2157 p = (Ether(src=host.mac, dst=self.pg0.local_mac) /
2158 IP(src=host.ip4, dst=self.nat_addr) /
2159 TCP(sport=host_in_port, dport=server_out_port))
2160 self.pg0.add_stream(p)
2161 self.pg_enable_capture(self.pg_interfaces)
2163 capture = self.pg0.get_capture(1)
2168 self.assertEqual(ip.src, self.nat_addr)
2169 self.assertEqual(ip.dst, server.ip4)
2170 self.assertNotEqual(tcp.sport, host_in_port)
2171 self.assertEqual(tcp.dport, server_in_port)
2172 self.assert_packet_checksums_valid(p)
2173 host_out_port = tcp.sport
2175 self.logger.error(ppp("Unexpected or invalid packet:", p))
2178 after = self.statistics.get_counter('/nat44/hairpinning')[0]
2179 if_idx = self.pg0.sw_if_index
2180 self.assertEqual(after[if_idx] - cnt[if_idx], 1)
2182 # send reply from server to host
2183 p = (Ether(src=server.mac, dst=self.pg0.local_mac) /
2184 IP(src=server.ip4, dst=self.nat_addr) /
2185 TCP(sport=server_in_port, dport=host_out_port))
2186 self.pg0.add_stream(p)
2187 self.pg_enable_capture(self.pg_interfaces)
2189 capture = self.pg0.get_capture(1)
2194 self.assertEqual(ip.src, self.nat_addr)
2195 self.assertEqual(ip.dst, host.ip4)
2196 self.assertEqual(tcp.sport, server_out_port)
2197 self.assertEqual(tcp.dport, host_in_port)
2198 self.assert_packet_checksums_valid(p)
2200 self.logger.error(ppp("Unexpected or invalid packet:", p))
2203 after = self.statistics.get_counter('/nat44/hairpinning')[0]
2204 if_idx = self.pg0.sw_if_index
2205 self.assertEqual(after[if_idx] - cnt[if_idx], 2)
2207 def test_hairpinning2(self):
2208 """ NAT44 hairpinning - 1:1 NAT"""
2210 server1_nat_ip = "10.0.0.10"
2211 server2_nat_ip = "10.0.0.11"
2212 host = self.pg0.remote_hosts[0]
2213 server1 = self.pg0.remote_hosts[1]
2214 server2 = self.pg0.remote_hosts[2]
2215 server_tcp_port = 22
2216 server_udp_port = 20
2218 self.nat44_add_address(self.nat_addr)
2219 flags = self.config_flags.NAT_IS_INSIDE
2220 self.vapi.nat44_interface_add_del_feature(
2221 sw_if_index=self.pg0.sw_if_index,
2222 flags=flags, is_add=1)
2223 self.vapi.nat44_interface_add_del_feature(
2224 sw_if_index=self.pg1.sw_if_index,
2227 # add static mapping for servers
2228 self.nat44_add_static_mapping(server1.ip4, server1_nat_ip)
2229 self.nat44_add_static_mapping(server2.ip4, server2_nat_ip)
2233 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2234 IP(src=host.ip4, dst=server1_nat_ip) /
2235 TCP(sport=self.tcp_port_in, dport=server_tcp_port))
2237 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2238 IP(src=host.ip4, dst=server1_nat_ip) /
2239 UDP(sport=self.udp_port_in, dport=server_udp_port))
2241 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2242 IP(src=host.ip4, dst=server1_nat_ip) /
2243 ICMP(id=self.icmp_id_in, type='echo-request'))
2245 self.pg0.add_stream(pkts)
2246 self.pg_enable_capture(self.pg_interfaces)
2248 capture = self.pg0.get_capture(len(pkts))
2249 for packet in capture:
2251 self.assertEqual(packet[IP].src, self.nat_addr)
2252 self.assertEqual(packet[IP].dst, server1.ip4)
2253 if packet.haslayer(TCP):
2254 self.assertNotEqual(packet[TCP].sport, self.tcp_port_in)
2255 self.assertEqual(packet[TCP].dport, server_tcp_port)
2256 self.tcp_port_out = packet[TCP].sport
2257 self.assert_packet_checksums_valid(packet)
2258 elif packet.haslayer(UDP):
2259 self.assertNotEqual(packet[UDP].sport, self.udp_port_in)
2260 self.assertEqual(packet[UDP].dport, server_udp_port)
2261 self.udp_port_out = packet[UDP].sport
2263 self.assertNotEqual(packet[ICMP].id, self.icmp_id_in)
2264 self.icmp_id_out = packet[ICMP].id
2266 self.logger.error(ppp("Unexpected or invalid packet:", packet))
2271 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2272 IP(src=server1.ip4, dst=self.nat_addr) /
2273 TCP(sport=server_tcp_port, dport=self.tcp_port_out))
2275 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2276 IP(src=server1.ip4, dst=self.nat_addr) /
2277 UDP(sport=server_udp_port, dport=self.udp_port_out))
2279 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2280 IP(src=server1.ip4, dst=self.nat_addr) /
2281 ICMP(id=self.icmp_id_out, type='echo-reply'))
2283 self.pg0.add_stream(pkts)
2284 self.pg_enable_capture(self.pg_interfaces)
2286 capture = self.pg0.get_capture(len(pkts))
2287 for packet in capture:
2289 self.assertEqual(packet[IP].src, server1_nat_ip)
2290 self.assertEqual(packet[IP].dst, host.ip4)
2291 if packet.haslayer(TCP):
2292 self.assertEqual(packet[TCP].dport, self.tcp_port_in)
2293 self.assertEqual(packet[TCP].sport, server_tcp_port)
2294 self.assert_packet_checksums_valid(packet)
2295 elif packet.haslayer(UDP):
2296 self.assertEqual(packet[UDP].dport, self.udp_port_in)
2297 self.assertEqual(packet[UDP].sport, server_udp_port)
2299 self.assertEqual(packet[ICMP].id, self.icmp_id_in)
2301 self.logger.error(ppp("Unexpected or invalid packet:", packet))
2304 # server2 to server1
2306 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2307 IP(src=server2.ip4, dst=server1_nat_ip) /
2308 TCP(sport=self.tcp_port_in, dport=server_tcp_port))
2310 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2311 IP(src=server2.ip4, dst=server1_nat_ip) /
2312 UDP(sport=self.udp_port_in, dport=server_udp_port))
2314 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2315 IP(src=server2.ip4, dst=server1_nat_ip) /
2316 ICMP(id=self.icmp_id_in, type='echo-request'))
2318 self.pg0.add_stream(pkts)
2319 self.pg_enable_capture(self.pg_interfaces)
2321 capture = self.pg0.get_capture(len(pkts))
2322 for packet in capture:
2324 self.assertEqual(packet[IP].src, server2_nat_ip)
2325 self.assertEqual(packet[IP].dst, server1.ip4)
2326 if packet.haslayer(TCP):
2327 self.assertEqual(packet[TCP].sport, self.tcp_port_in)
2328 self.assertEqual(packet[TCP].dport, server_tcp_port)
2329 self.tcp_port_out = packet[TCP].sport
2330 self.assert_packet_checksums_valid(packet)
2331 elif packet.haslayer(UDP):
2332 self.assertEqual(packet[UDP].sport, self.udp_port_in)
2333 self.assertEqual(packet[UDP].dport, server_udp_port)
2334 self.udp_port_out = packet[UDP].sport
2336 self.assertEqual(packet[ICMP].id, self.icmp_id_in)
2337 self.icmp_id_out = packet[ICMP].id
2339 self.logger.error(ppp("Unexpected or invalid packet:", packet))
2342 # server1 to server2
2344 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2345 IP(src=server1.ip4, dst=server2_nat_ip) /
2346 TCP(sport=server_tcp_port, dport=self.tcp_port_out))
2348 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2349 IP(src=server1.ip4, dst=server2_nat_ip) /
2350 UDP(sport=server_udp_port, dport=self.udp_port_out))
2352 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2353 IP(src=server1.ip4, dst=server2_nat_ip) /
2354 ICMP(id=self.icmp_id_out, type='echo-reply'))
2356 self.pg0.add_stream(pkts)
2357 self.pg_enable_capture(self.pg_interfaces)
2359 capture = self.pg0.get_capture(len(pkts))
2360 for packet in capture:
2362 self.assertEqual(packet[IP].src, server1_nat_ip)
2363 self.assertEqual(packet[IP].dst, server2.ip4)
2364 if packet.haslayer(TCP):
2365 self.assertEqual(packet[TCP].dport, self.tcp_port_in)
2366 self.assertEqual(packet[TCP].sport, server_tcp_port)
2367 self.assert_packet_checksums_valid(packet)
2368 elif packet.haslayer(UDP):
2369 self.assertEqual(packet[UDP].dport, self.udp_port_in)
2370 self.assertEqual(packet[UDP].sport, server_udp_port)
2372 self.assertEqual(packet[ICMP].id, self.icmp_id_in)
2374 self.logger.error(ppp("Unexpected or invalid packet:", packet))
2377 def test_interface_addr(self):
2378 """ Acquire NAT44 addresses from interface """
2379 self.vapi.nat44_add_del_interface_addr(
2381 sw_if_index=self.pg7.sw_if_index)
2383 # no address in NAT pool
2384 addresses = self.vapi.nat44_address_dump()
2385 self.assertEqual(0, len(addresses))
2387 # configure interface address and check NAT address pool
2388 self.pg7.config_ip4()
2389 addresses = self.vapi.nat44_address_dump()
2390 self.assertEqual(1, len(addresses))
2391 self.assertEqual(str(addresses[0].ip_address), self.pg7.local_ip4)
2393 # remove interface address and check NAT address pool
2394 self.pg7.unconfig_ip4()
2395 addresses = self.vapi.nat44_address_dump()
2396 self.assertEqual(0, len(addresses))
2398 def test_interface_addr_static_mapping(self):
2399 """ Static mapping with addresses from interface """
2402 self.vapi.nat44_add_del_interface_addr(
2404 sw_if_index=self.pg7.sw_if_index)
2405 self.nat44_add_static_mapping(
2407 external_sw_if_index=self.pg7.sw_if_index,
2410 # static mappings with external interface
2411 static_mappings = self.vapi.nat44_static_mapping_dump()
2412 self.assertEqual(1, len(static_mappings))
2413 self.assertEqual(self.pg7.sw_if_index,
2414 static_mappings[0].external_sw_if_index)
2415 self.assertEqual(static_mappings[0].tag, tag)
2417 # configure interface address and check static mappings
2418 self.pg7.config_ip4()
2419 static_mappings = self.vapi.nat44_static_mapping_dump()
2420 self.assertEqual(2, len(static_mappings))
2422 for sm in static_mappings:
2423 if sm.external_sw_if_index == 0xFFFFFFFF:
2424 self.assertEqual(str(sm.external_ip_address),
2426 self.assertEqual(sm.tag, tag)
2428 self.assertTrue(resolved)
2430 # remove interface address and check static mappings
2431 self.pg7.unconfig_ip4()
2432 static_mappings = self.vapi.nat44_static_mapping_dump()
2433 self.assertEqual(1, len(static_mappings))
2434 self.assertEqual(self.pg7.sw_if_index,
2435 static_mappings[0].external_sw_if_index)
2436 self.assertEqual(static_mappings[0].tag, tag)
2438 # configure interface address again and check static mappings
2439 self.pg7.config_ip4()
2440 static_mappings = self.vapi.nat44_static_mapping_dump()
2441 self.assertEqual(2, len(static_mappings))
2443 for sm in static_mappings:
2444 if sm.external_sw_if_index == 0xFFFFFFFF:
2445 self.assertEqual(str(sm.external_ip_address),
2447 self.assertEqual(sm.tag, tag)
2449 self.assertTrue(resolved)
2451 # remove static mapping
2452 self.nat44_add_static_mapping(
2454 external_sw_if_index=self.pg7.sw_if_index,
2457 static_mappings = self.vapi.nat44_static_mapping_dump()
2458 self.assertEqual(0, len(static_mappings))
2460 def test_interface_addr_identity_nat(self):
2461 """ Identity NAT with addresses from interface """
2464 self.vapi.nat44_add_del_interface_addr(
2466 sw_if_index=self.pg7.sw_if_index)
2467 self.vapi.nat44_add_del_identity_mapping(
2469 sw_if_index=self.pg7.sw_if_index,
2471 protocol=IP_PROTOS.tcp,
2474 # identity mappings with external interface
2475 identity_mappings = self.vapi.nat44_identity_mapping_dump()
2476 self.assertEqual(1, len(identity_mappings))
2477 self.assertEqual(self.pg7.sw_if_index,
2478 identity_mappings[0].sw_if_index)
2480 # configure interface address and check identity mappings
2481 self.pg7.config_ip4()
2482 identity_mappings = self.vapi.nat44_identity_mapping_dump()
2484 self.assertEqual(2, len(identity_mappings))
2485 for sm in identity_mappings:
2486 if sm.sw_if_index == 0xFFFFFFFF:
2487 self.assertEqual(str(identity_mappings[0].ip_address),
2489 self.assertEqual(port, identity_mappings[0].port)
2490 self.assertEqual(IP_PROTOS.tcp, identity_mappings[0].protocol)
2492 self.assertTrue(resolved)
2494 # remove interface address and check identity mappings
2495 self.pg7.unconfig_ip4()
2496 identity_mappings = self.vapi.nat44_identity_mapping_dump()
2497 self.assertEqual(1, len(identity_mappings))
2498 self.assertEqual(self.pg7.sw_if_index,
2499 identity_mappings[0].sw_if_index)
2501 def test_ipfix_nat44_sess(self):
2502 """ IPFIX logging NAT44 session created/deleted """
2503 self.ipfix_domain_id = 10
2504 self.ipfix_src_port = 20202
2505 collector_port = 30303
2506 bind_layers(UDP, IPFIX, dport=30303)
2507 self.nat44_add_address(self.nat_addr)
2508 flags = self.config_flags.NAT_IS_INSIDE
2509 self.vapi.nat44_interface_add_del_feature(
2510 sw_if_index=self.pg0.sw_if_index,
2511 flags=flags, is_add=1)
2512 self.vapi.nat44_interface_add_del_feature(
2513 sw_if_index=self.pg1.sw_if_index,
2515 self.vapi.set_ipfix_exporter(collector_address=self.pg3.remote_ip4,
2516 src_address=self.pg3.local_ip4,
2518 template_interval=10,
2519 collector_port=collector_port)
2520 self.vapi.nat_ipfix_enable_disable(domain_id=self.ipfix_domain_id,
2521 src_port=self.ipfix_src_port,
2524 pkts = self.create_stream_in(self.pg0, self.pg1)
2525 self.pg0.add_stream(pkts)
2526 self.pg_enable_capture(self.pg_interfaces)
2528 capture = self.pg1.get_capture(len(pkts))
2529 self.verify_capture_out(capture)
2530 self.nat44_add_address(self.nat_addr, is_add=0)
2531 self.vapi.ipfix_flush()
2532 capture = self.pg3.get_capture(7)
2533 ipfix = IPFIXDecoder()
2534 # first load template
2536 self.assertTrue(p.haslayer(IPFIX))
2537 self.assertEqual(p[IP].src, self.pg3.local_ip4)
2538 self.assertEqual(p[IP].dst, self.pg3.remote_ip4)
2539 self.assertEqual(p[UDP].sport, self.ipfix_src_port)
2540 self.assertEqual(p[UDP].dport, collector_port)
2541 self.assertEqual(p[IPFIX].observationDomainID,
2542 self.ipfix_domain_id)
2543 if p.haslayer(Template):
2544 ipfix.add_template(p.getlayer(Template))
2545 # verify events in data set
2547 if p.haslayer(Data):
2548 data = ipfix.decode_data_set(p.getlayer(Set))
2549 self.verify_ipfix_nat44_ses(data)
2551 def test_ipfix_addr_exhausted(self):
2552 """ IPFIX logging NAT addresses exhausted """
2553 flags = self.config_flags.NAT_IS_INSIDE
2554 self.vapi.nat44_interface_add_del_feature(
2555 sw_if_index=self.pg0.sw_if_index,
2556 flags=flags, is_add=1)
2557 self.vapi.nat44_interface_add_del_feature(
2558 sw_if_index=self.pg1.sw_if_index,
2560 self.vapi.set_ipfix_exporter(collector_address=self.pg3.remote_ip4,
2561 src_address=self.pg3.local_ip4,
2563 template_interval=10)
2564 self.vapi.nat_ipfix_enable_disable(domain_id=self.ipfix_domain_id,
2565 src_port=self.ipfix_src_port,
2568 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
2569 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
2571 self.pg0.add_stream(p)
2572 self.pg_enable_capture(self.pg_interfaces)
2574 self.pg1.assert_nothing_captured()
2576 self.vapi.ipfix_flush()
2577 capture = self.pg3.get_capture(7)
2578 ipfix = IPFIXDecoder()
2579 # first load template
2581 self.assertTrue(p.haslayer(IPFIX))
2582 self.assertEqual(p[IP].src, self.pg3.local_ip4)
2583 self.assertEqual(p[IP].dst, self.pg3.remote_ip4)
2584 self.assertEqual(p[UDP].sport, self.ipfix_src_port)
2585 self.assertEqual(p[UDP].dport, 4739)
2586 self.assertEqual(p[IPFIX].observationDomainID,
2587 self.ipfix_domain_id)
2588 if p.haslayer(Template):
2589 ipfix.add_template(p.getlayer(Template))
2590 # verify events in data set
2592 if p.haslayer(Data):
2593 data = ipfix.decode_data_set(p.getlayer(Set))
2594 self.verify_ipfix_addr_exhausted(data)
2596 @unittest.skipUnless(running_extended_tests, "part of extended tests")
2597 def test_ipfix_max_sessions(self):
2598 """ IPFIX logging maximum session entries exceeded """
2599 self.nat44_add_address(self.nat_addr)
2600 flags = self.config_flags.NAT_IS_INSIDE
2601 self.vapi.nat44_interface_add_del_feature(
2602 sw_if_index=self.pg0.sw_if_index,
2603 flags=flags, is_add=1)
2604 self.vapi.nat44_interface_add_del_feature(
2605 sw_if_index=self.pg1.sw_if_index,
2608 max_sessions = self.max_translations
2611 for i in range(0, max_sessions):
2612 src = "10.10.%u.%u" % ((i & 0xFF00) >> 8, i & 0xFF)
2613 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2614 IP(src=src, dst=self.pg1.remote_ip4) /
2617 self.pg0.add_stream(pkts)
2618 self.pg_enable_capture(self.pg_interfaces)
2621 self.pg1.get_capture(max_sessions)
2622 self.vapi.set_ipfix_exporter(collector_address=self.pg3.remote_ip4,
2623 src_address=self.pg3.local_ip4,
2625 template_interval=10)
2626 self.vapi.nat_ipfix_enable_disable(domain_id=self.ipfix_domain_id,
2627 src_port=self.ipfix_src_port,
2630 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2631 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
2633 self.pg0.add_stream(p)
2634 self.pg_enable_capture(self.pg_interfaces)
2636 self.pg1.assert_nothing_captured()
2638 self.vapi.ipfix_flush()
2639 capture = self.pg3.get_capture(7)
2640 ipfix = IPFIXDecoder()
2641 # first load template
2643 self.assertTrue(p.haslayer(IPFIX))
2644 self.assertEqual(p[IP].src, self.pg3.local_ip4)
2645 self.assertEqual(p[IP].dst, self.pg3.remote_ip4)
2646 self.assertEqual(p[UDP].sport, self.ipfix_src_port)
2647 self.assertEqual(p[UDP].dport, 4739)
2648 self.assertEqual(p[IPFIX].observationDomainID,
2649 self.ipfix_domain_id)
2650 if p.haslayer(Template):
2651 ipfix.add_template(p.getlayer(Template))
2652 # verify events in data set
2654 if p.haslayer(Data):
2655 data = ipfix.decode_data_set(p.getlayer(Set))
2656 self.verify_ipfix_max_sessions(data, max_sessions)
2658 def test_syslog_apmap(self):
2659 """ Test syslog address and port mapping creation and deletion """
2660 self.vapi.syslog_set_filter(
2661 self.SYSLOG_SEVERITY.SYSLOG_API_SEVERITY_INFO)
2662 self.vapi.syslog_set_sender(self.pg3.local_ip4, self.pg3.remote_ip4)
2663 self.nat44_add_address(self.nat_addr)
2664 flags = self.config_flags.NAT_IS_INSIDE
2665 self.vapi.nat44_interface_add_del_feature(
2666 sw_if_index=self.pg0.sw_if_index,
2667 flags=flags, is_add=1)
2668 self.vapi.nat44_interface_add_del_feature(
2669 sw_if_index=self.pg1.sw_if_index,
2672 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2673 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
2674 TCP(sport=self.tcp_port_in, dport=20))
2675 self.pg0.add_stream(p)
2676 self.pg_enable_capture(self.pg_interfaces)
2678 capture = self.pg1.get_capture(1)
2679 self.tcp_port_out = capture[0][TCP].sport
2680 capture = self.pg3.get_capture(1)
2681 self.verify_syslog_apmap(capture[0][Raw].load)
2683 self.pg_enable_capture(self.pg_interfaces)
2685 self.nat44_add_address(self.nat_addr, is_add=0)
2686 capture = self.pg3.get_capture(1)
2687 self.verify_syslog_apmap(capture[0][Raw].load, False)
2689 def test_pool_addr_fib(self):
2690 """ NAT44 add pool addresses to FIB """
2691 static_addr = '10.0.0.10'
2692 self.nat44_add_address(self.nat_addr)
2693 flags = self.config_flags.NAT_IS_INSIDE
2694 self.vapi.nat44_interface_add_del_feature(
2695 sw_if_index=self.pg0.sw_if_index,
2696 flags=flags, is_add=1)
2697 self.vapi.nat44_interface_add_del_feature(
2698 sw_if_index=self.pg1.sw_if_index,
2700 self.nat44_add_static_mapping(self.pg0.remote_ip4, static_addr)
2703 p = (Ether(src=self.pg1.remote_mac, dst='ff:ff:ff:ff:ff:ff') /
2704 ARP(op=ARP.who_has, pdst=self.nat_addr,
2705 psrc=self.pg1.remote_ip4, hwsrc=self.pg1.remote_mac))
2706 self.pg1.add_stream(p)
2707 self.pg_enable_capture(self.pg_interfaces)
2709 capture = self.pg1.get_capture(1)
2710 self.assertTrue(capture[0].haslayer(ARP))
2711 self.assertTrue(capture[0][ARP].op, ARP.is_at)
2714 p = (Ether(src=self.pg1.remote_mac, dst='ff:ff:ff:ff:ff:ff') /
2715 ARP(op=ARP.who_has, pdst=static_addr,
2716 psrc=self.pg1.remote_ip4, hwsrc=self.pg1.remote_mac))
2717 self.pg1.add_stream(p)
2718 self.pg_enable_capture(self.pg_interfaces)
2720 capture = self.pg1.get_capture(1)
2721 self.assertTrue(capture[0].haslayer(ARP))
2722 self.assertTrue(capture[0][ARP].op, ARP.is_at)
2724 # send ARP to non-NAT44 interface
2725 p = (Ether(src=self.pg2.remote_mac, dst='ff:ff:ff:ff:ff:ff') /
2726 ARP(op=ARP.who_has, pdst=self.nat_addr,
2727 psrc=self.pg2.remote_ip4, hwsrc=self.pg2.remote_mac))
2728 self.pg2.add_stream(p)
2729 self.pg_enable_capture(self.pg_interfaces)
2731 self.pg1.assert_nothing_captured()
2733 # remove addresses and verify
2734 self.nat44_add_address(self.nat_addr, is_add=0)
2735 self.nat44_add_static_mapping(self.pg0.remote_ip4, static_addr,
2738 p = (Ether(src=self.pg1.remote_mac, dst='ff:ff:ff:ff:ff:ff') /
2739 ARP(op=ARP.who_has, pdst=self.nat_addr,
2740 psrc=self.pg1.remote_ip4, hwsrc=self.pg1.remote_mac))
2741 self.pg1.add_stream(p)
2742 self.pg_enable_capture(self.pg_interfaces)
2744 self.pg1.assert_nothing_captured()
2746 p = (Ether(src=self.pg1.remote_mac, dst='ff:ff:ff:ff:ff:ff') /
2747 ARP(op=ARP.who_has, pdst=static_addr,
2748 psrc=self.pg1.remote_ip4, hwsrc=self.pg1.remote_mac))
2749 self.pg1.add_stream(p)
2750 self.pg_enable_capture(self.pg_interfaces)
2752 self.pg1.assert_nothing_captured()
2754 def test_vrf_mode(self):
2755 """ NAT44 tenant VRF aware address pool mode """
2759 nat_ip1 = "10.0.0.10"
2760 nat_ip2 = "10.0.0.11"
2762 self.pg0.unconfig_ip4()
2763 self.pg1.unconfig_ip4()
2764 self.vapi.ip_table_add_del(is_add=1, table={'table_id': vrf_id1})
2765 self.vapi.ip_table_add_del(is_add=1, table={'table_id': vrf_id2})
2766 self.pg0.set_table_ip4(vrf_id1)
2767 self.pg1.set_table_ip4(vrf_id2)
2768 self.pg0.config_ip4()
2769 self.pg1.config_ip4()
2770 self.pg0.resolve_arp()
2771 self.pg1.resolve_arp()
2773 self.nat44_add_address(nat_ip1, vrf_id=vrf_id1)
2774 self.nat44_add_address(nat_ip2, vrf_id=vrf_id2)
2775 flags = self.config_flags.NAT_IS_INSIDE
2776 self.vapi.nat44_interface_add_del_feature(
2777 sw_if_index=self.pg0.sw_if_index,
2778 flags=flags, is_add=1)
2779 self.vapi.nat44_interface_add_del_feature(
2780 sw_if_index=self.pg1.sw_if_index,
2781 flags=flags, is_add=1)
2782 self.vapi.nat44_interface_add_del_feature(
2783 sw_if_index=self.pg2.sw_if_index,
2788 pkts = self.create_stream_in(self.pg0, self.pg2)
2789 self.pg0.add_stream(pkts)
2790 self.pg_enable_capture(self.pg_interfaces)
2792 capture = self.pg2.get_capture(len(pkts))
2793 self.verify_capture_out(capture, nat_ip1)
2796 pkts = self.create_stream_in(self.pg1, self.pg2)
2797 self.pg1.add_stream(pkts)
2798 self.pg_enable_capture(self.pg_interfaces)
2800 capture = self.pg2.get_capture(len(pkts))
2801 self.verify_capture_out(capture, nat_ip2)
2804 self.pg0.unconfig_ip4()
2805 self.pg1.unconfig_ip4()
2806 self.pg0.set_table_ip4(0)
2807 self.pg1.set_table_ip4(0)
2808 self.pg0.config_ip4()
2809 self.pg1.config_ip4()
2810 self.pg0.resolve_arp()
2811 self.pg1.resolve_arp()
2812 self.vapi.ip_table_add_del(is_add=0, table={'table_id': vrf_id1})
2813 self.vapi.ip_table_add_del(is_add=0, table={'table_id': vrf_id2})
2815 def test_vrf_feature_independent(self):
2816 """ NAT44 tenant VRF independent address pool mode """
2818 nat_ip1 = "10.0.0.10"
2819 nat_ip2 = "10.0.0.11"
2821 self.nat44_add_address(nat_ip1)
2822 self.nat44_add_address(nat_ip2, vrf_id=99)
2823 flags = self.config_flags.NAT_IS_INSIDE
2824 self.vapi.nat44_interface_add_del_feature(
2825 sw_if_index=self.pg0.sw_if_index,
2826 flags=flags, is_add=1)
2827 self.vapi.nat44_interface_add_del_feature(
2828 sw_if_index=self.pg1.sw_if_index,
2829 flags=flags, is_add=1)
2830 self.vapi.nat44_interface_add_del_feature(
2831 sw_if_index=self.pg2.sw_if_index,
2835 pkts = self.create_stream_in(self.pg0, self.pg2)
2836 self.pg0.add_stream(pkts)
2837 self.pg_enable_capture(self.pg_interfaces)
2839 capture = self.pg2.get_capture(len(pkts))
2840 self.verify_capture_out(capture, nat_ip1)
2843 pkts = self.create_stream_in(self.pg1, self.pg2)
2844 self.pg1.add_stream(pkts)
2845 self.pg_enable_capture(self.pg_interfaces)
2847 capture = self.pg2.get_capture(len(pkts))
2848 self.verify_capture_out(capture, nat_ip1)
2850 def create_routes_and_neigbors(self):
2851 r1 = VppIpRoute(self, self.pg7.remote_ip4, 32,
2852 [VppRoutePath(self.pg7.remote_ip4,
2853 self.pg7.sw_if_index)])
2854 r2 = VppIpRoute(self, self.pg8.remote_ip4, 32,
2855 [VppRoutePath(self.pg8.remote_ip4,
2856 self.pg8.sw_if_index)])
2860 n1 = VppNeighbor(self,
2861 self.pg7.sw_if_index,
2862 self.pg7.remote_mac,
2863 self.pg7.remote_ip4,
2865 n2 = VppNeighbor(self,
2866 self.pg8.sw_if_index,
2867 self.pg8.remote_mac,
2868 self.pg8.remote_ip4,
2873 def test_dynamic_ipless_interfaces(self):
2874 """ NAT44 interfaces without configured IP address """
2875 self.create_routes_and_neigbors()
2876 self.nat44_add_address(self.nat_addr)
2877 flags = self.config_flags.NAT_IS_INSIDE
2878 self.vapi.nat44_interface_add_del_feature(
2879 sw_if_index=self.pg7.sw_if_index,
2880 flags=flags, is_add=1)
2881 self.vapi.nat44_interface_add_del_feature(
2882 sw_if_index=self.pg8.sw_if_index,
2886 pkts = self.create_stream_in(self.pg7, self.pg8)
2887 self.pg7.add_stream(pkts)
2888 self.pg_enable_capture(self.pg_interfaces)
2890 capture = self.pg8.get_capture(len(pkts))
2891 self.verify_capture_out(capture)
2894 pkts = self.create_stream_out(self.pg8, self.nat_addr)
2895 self.pg8.add_stream(pkts)
2896 self.pg_enable_capture(self.pg_interfaces)
2898 capture = self.pg7.get_capture(len(pkts))
2899 self.verify_capture_in(capture, self.pg7)
2901 def test_static_ipless_interfaces(self):
2902 """ NAT44 interfaces without configured IP address - 1:1 NAT """
2904 self.create_routes_and_neigbors()
2905 self.nat44_add_static_mapping(self.pg7.remote_ip4, self.nat_addr)
2906 flags = self.config_flags.NAT_IS_INSIDE
2907 self.vapi.nat44_interface_add_del_feature(
2908 sw_if_index=self.pg7.sw_if_index,
2909 flags=flags, is_add=1)
2910 self.vapi.nat44_interface_add_del_feature(
2911 sw_if_index=self.pg8.sw_if_index,
2915 pkts = self.create_stream_out(self.pg8)
2916 self.pg8.add_stream(pkts)
2917 self.pg_enable_capture(self.pg_interfaces)
2919 capture = self.pg7.get_capture(len(pkts))
2920 self.verify_capture_in(capture, self.pg7)
2923 pkts = self.create_stream_in(self.pg7, self.pg8)
2924 self.pg7.add_stream(pkts)
2925 self.pg_enable_capture(self.pg_interfaces)
2927 capture = self.pg8.get_capture(len(pkts))
2928 self.verify_capture_out(capture, self.nat_addr, True)
2930 def test_static_with_port_ipless_interfaces(self):
2931 """ NAT44 interfaces without configured IP address - 1:1 NAPT """
2933 self.tcp_port_out = 30606
2934 self.udp_port_out = 30607
2935 self.icmp_id_out = 30608
2937 self.create_routes_and_neigbors()
2938 self.nat44_add_address(self.nat_addr)
2939 self.nat44_add_static_mapping(self.pg7.remote_ip4, self.nat_addr,
2940 self.tcp_port_in, self.tcp_port_out,
2941 proto=IP_PROTOS.tcp)
2942 self.nat44_add_static_mapping(self.pg7.remote_ip4, self.nat_addr,
2943 self.udp_port_in, self.udp_port_out,
2944 proto=IP_PROTOS.udp)
2945 self.nat44_add_static_mapping(self.pg7.remote_ip4, self.nat_addr,
2946 self.icmp_id_in, self.icmp_id_out,
2947 proto=IP_PROTOS.icmp)
2948 flags = self.config_flags.NAT_IS_INSIDE
2949 self.vapi.nat44_interface_add_del_feature(
2950 sw_if_index=self.pg7.sw_if_index,
2951 flags=flags, is_add=1)
2952 self.vapi.nat44_interface_add_del_feature(
2953 sw_if_index=self.pg8.sw_if_index,
2957 pkts = self.create_stream_out(self.pg8)
2958 self.pg8.add_stream(pkts)
2959 self.pg_enable_capture(self.pg_interfaces)
2961 capture = self.pg7.get_capture(len(pkts))
2962 self.verify_capture_in(capture, self.pg7)
2965 pkts = self.create_stream_in(self.pg7, self.pg8)
2966 self.pg7.add_stream(pkts)
2967 self.pg_enable_capture(self.pg_interfaces)
2969 capture = self.pg8.get_capture(len(pkts))
2970 self.verify_capture_out(capture)
2972 def test_static_unknown_proto(self):
2973 """ 1:1 NAT translate packet with unknown protocol """
2974 nat_ip = "10.0.0.10"
2975 self.nat44_add_static_mapping(self.pg0.remote_ip4, nat_ip)
2976 flags = self.config_flags.NAT_IS_INSIDE
2977 self.vapi.nat44_interface_add_del_feature(
2978 sw_if_index=self.pg0.sw_if_index,
2979 flags=flags, is_add=1)
2980 self.vapi.nat44_interface_add_del_feature(
2981 sw_if_index=self.pg1.sw_if_index,
2985 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2986 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
2988 IP(src=self.pg2.remote_ip4, dst=self.pg3.remote_ip4) /
2989 TCP(sport=1234, dport=1234))
2990 self.pg0.add_stream(p)
2991 self.pg_enable_capture(self.pg_interfaces)
2993 p = self.pg1.get_capture(1)
2996 self.assertEqual(packet[IP].src, nat_ip)
2997 self.assertEqual(packet[IP].dst, self.pg1.remote_ip4)
2998 self.assertEqual(packet.haslayer(GRE), 1)
2999 self.assert_packet_checksums_valid(packet)
3001 self.logger.error(ppp("Unexpected or invalid packet:", packet))
3005 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
3006 IP(src=self.pg1.remote_ip4, dst=nat_ip) /
3008 IP(src=self.pg3.remote_ip4, dst=self.pg2.remote_ip4) /
3009 TCP(sport=1234, dport=1234))
3010 self.pg1.add_stream(p)
3011 self.pg_enable_capture(self.pg_interfaces)
3013 p = self.pg0.get_capture(1)
3016 self.assertEqual(packet[IP].src, self.pg1.remote_ip4)
3017 self.assertEqual(packet[IP].dst, self.pg0.remote_ip4)
3018 self.assertEqual(packet.haslayer(GRE), 1)
3019 self.assert_packet_checksums_valid(packet)
3021 self.logger.error(ppp("Unexpected or invalid packet:", packet))
3024 def test_hairpinning_static_unknown_proto(self):
3025 """ 1:1 NAT translate packet with unknown protocol - hairpinning """
3027 host = self.pg0.remote_hosts[0]
3028 server = self.pg0.remote_hosts[1]
3030 host_nat_ip = "10.0.0.10"
3031 server_nat_ip = "10.0.0.11"
3033 self.nat44_add_static_mapping(host.ip4, host_nat_ip)
3034 self.nat44_add_static_mapping(server.ip4, server_nat_ip)
3035 flags = self.config_flags.NAT_IS_INSIDE
3036 self.vapi.nat44_interface_add_del_feature(
3037 sw_if_index=self.pg0.sw_if_index,
3038 flags=flags, is_add=1)
3039 self.vapi.nat44_interface_add_del_feature(
3040 sw_if_index=self.pg1.sw_if_index,
3044 p = (Ether(dst=self.pg0.local_mac, src=host.mac) /
3045 IP(src=host.ip4, dst=server_nat_ip) /
3047 IP(src=self.pg2.remote_ip4, dst=self.pg3.remote_ip4) /
3048 TCP(sport=1234, dport=1234))
3049 self.pg0.add_stream(p)
3050 self.pg_enable_capture(self.pg_interfaces)
3052 p = self.pg0.get_capture(1)
3055 self.assertEqual(packet[IP].src, host_nat_ip)
3056 self.assertEqual(packet[IP].dst, server.ip4)
3057 self.assertEqual(packet.haslayer(GRE), 1)
3058 self.assert_packet_checksums_valid(packet)
3060 self.logger.error(ppp("Unexpected or invalid packet:", packet))
3064 p = (Ether(dst=self.pg0.local_mac, src=server.mac) /
3065 IP(src=server.ip4, dst=host_nat_ip) /
3067 IP(src=self.pg3.remote_ip4, dst=self.pg2.remote_ip4) /
3068 TCP(sport=1234, dport=1234))
3069 self.pg0.add_stream(p)
3070 self.pg_enable_capture(self.pg_interfaces)
3072 p = self.pg0.get_capture(1)
3075 self.assertEqual(packet[IP].src, server_nat_ip)
3076 self.assertEqual(packet[IP].dst, host.ip4)
3077 self.assertEqual(packet.haslayer(GRE), 1)
3078 self.assert_packet_checksums_valid(packet)
3080 self.logger.error(ppp("Unexpected or invalid packet:", packet))
3083 def test_output_feature(self):
3084 """ NAT44 interface output feature (in2out postrouting) """
3085 self.nat44_add_address(self.nat_addr)
3086 flags = self.config_flags.NAT_IS_INSIDE
3087 self.vapi.nat44_interface_add_del_output_feature(
3088 is_add=1, flags=flags,
3089 sw_if_index=self.pg0.sw_if_index)
3090 self.vapi.nat44_interface_add_del_output_feature(
3091 is_add=1, flags=flags,
3092 sw_if_index=self.pg1.sw_if_index)
3093 self.vapi.nat44_interface_add_del_output_feature(
3095 sw_if_index=self.pg3.sw_if_index)
3098 pkts = self.create_stream_in(self.pg0, self.pg3)
3099 self.pg0.add_stream(pkts)
3100 self.pg_enable_capture(self.pg_interfaces)
3102 capture = self.pg3.get_capture(len(pkts))
3103 self.verify_capture_out(capture)
3106 pkts = self.create_stream_out(self.pg3)
3107 self.pg3.add_stream(pkts)
3108 self.pg_enable_capture(self.pg_interfaces)
3110 capture = self.pg0.get_capture(len(pkts))
3111 self.verify_capture_in(capture, self.pg0)
3113 # from non-NAT interface to NAT inside interface
3114 pkts = self.create_stream_in(self.pg2, self.pg0)
3115 self.pg2.add_stream(pkts)
3116 self.pg_enable_capture(self.pg_interfaces)
3118 capture = self.pg0.get_capture(len(pkts))
3119 self.verify_capture_no_translation(capture, self.pg2, self.pg0)
3121 def test_output_feature_vrf_aware(self):
3122 """ NAT44 interface output feature VRF aware (in2out postrouting) """
3123 nat_ip_vrf10 = "10.0.0.10"
3124 nat_ip_vrf20 = "10.0.0.20"
3126 r1 = VppIpRoute(self, self.pg3.remote_ip4, 32,
3127 [VppRoutePath(self.pg3.remote_ip4,
3128 self.pg3.sw_if_index)],
3130 r2 = VppIpRoute(self, self.pg3.remote_ip4, 32,
3131 [VppRoutePath(self.pg3.remote_ip4,
3132 self.pg3.sw_if_index)],
3137 self.nat44_add_address(nat_ip_vrf10, vrf_id=10)
3138 self.nat44_add_address(nat_ip_vrf20, vrf_id=20)
3139 flags = self.config_flags.NAT_IS_INSIDE
3140 self.vapi.nat44_interface_add_del_output_feature(
3141 is_add=1, flags=flags,
3142 sw_if_index=self.pg4.sw_if_index)
3143 self.vapi.nat44_interface_add_del_output_feature(
3144 is_add=1, flags=flags,
3145 sw_if_index=self.pg6.sw_if_index)
3146 self.vapi.nat44_interface_add_del_output_feature(
3148 sw_if_index=self.pg3.sw_if_index)
3151 pkts = self.create_stream_in(self.pg4, self.pg3)
3152 self.pg4.add_stream(pkts)
3153 self.pg_enable_capture(self.pg_interfaces)
3155 capture = self.pg3.get_capture(len(pkts))
3156 self.verify_capture_out(capture, nat_ip=nat_ip_vrf10)
3159 pkts = self.create_stream_out(self.pg3, dst_ip=nat_ip_vrf10)
3160 self.pg3.add_stream(pkts)
3161 self.pg_enable_capture(self.pg_interfaces)
3163 capture = self.pg4.get_capture(len(pkts))
3164 self.verify_capture_in(capture, self.pg4)
3167 pkts = self.create_stream_in(self.pg6, self.pg3)
3168 self.pg6.add_stream(pkts)
3169 self.pg_enable_capture(self.pg_interfaces)
3171 capture = self.pg3.get_capture(len(pkts))
3172 self.verify_capture_out(capture, nat_ip=nat_ip_vrf20)
3175 pkts = self.create_stream_out(self.pg3, dst_ip=nat_ip_vrf20)
3176 self.pg3.add_stream(pkts)
3177 self.pg_enable_capture(self.pg_interfaces)
3179 capture = self.pg6.get_capture(len(pkts))
3180 self.verify_capture_in(capture, self.pg6)
3182 def test_output_feature_hairpinning(self):
3183 """ NAT44 interface output feature hairpinning (in2out postrouting) """
3184 host = self.pg0.remote_hosts[0]
3185 server = self.pg0.remote_hosts[1]
3188 server_in_port = 5678
3189 server_out_port = 8765
3191 self.nat44_add_address(self.nat_addr)
3192 flags = self.config_flags.NAT_IS_INSIDE
3193 self.vapi.nat44_interface_add_del_output_feature(
3194 is_add=1, flags=flags,
3195 sw_if_index=self.pg0.sw_if_index)
3196 self.vapi.nat44_interface_add_del_output_feature(
3198 sw_if_index=self.pg1.sw_if_index)
3200 # add static mapping for server
3201 self.nat44_add_static_mapping(server.ip4, self.nat_addr,
3202 server_in_port, server_out_port,
3203 proto=IP_PROTOS.tcp)
3205 # send packet from host to server
3206 p = (Ether(src=host.mac, dst=self.pg0.local_mac) /
3207 IP(src=host.ip4, dst=self.nat_addr) /
3208 TCP(sport=host_in_port, dport=server_out_port))
3209 self.pg0.add_stream(p)
3210 self.pg_enable_capture(self.pg_interfaces)
3212 capture = self.pg0.get_capture(1)
3217 self.assertEqual(ip.src, self.nat_addr)
3218 self.assertEqual(ip.dst, server.ip4)
3219 self.assertNotEqual(tcp.sport, host_in_port)
3220 self.assertEqual(tcp.dport, server_in_port)
3221 self.assert_packet_checksums_valid(p)
3222 host_out_port = tcp.sport
3224 self.logger.error(ppp("Unexpected or invalid packet:", p))
3227 # send reply from server to host
3228 p = (Ether(src=server.mac, dst=self.pg0.local_mac) /
3229 IP(src=server.ip4, dst=self.nat_addr) /
3230 TCP(sport=server_in_port, dport=host_out_port))
3231 self.pg0.add_stream(p)
3232 self.pg_enable_capture(self.pg_interfaces)
3234 capture = self.pg0.get_capture(1)
3239 self.assertEqual(ip.src, self.nat_addr)
3240 self.assertEqual(ip.dst, host.ip4)
3241 self.assertEqual(tcp.sport, server_out_port)
3242 self.assertEqual(tcp.dport, host_in_port)
3243 self.assert_packet_checksums_valid(p)
3245 self.logger.error(ppp("Unexpected or invalid packet:", p))
3248 def test_one_armed_nat44(self):
3249 """ One armed NAT44 """
3250 remote_host = self.pg9.remote_hosts[0]
3251 local_host = self.pg9.remote_hosts[1]
3254 self.nat44_add_address(self.nat_addr)
3255 flags = self.config_flags.NAT_IS_INSIDE
3256 self.vapi.nat44_interface_add_del_feature(
3257 sw_if_index=self.pg9.sw_if_index,
3259 self.vapi.nat44_interface_add_del_feature(
3260 sw_if_index=self.pg9.sw_if_index,
3261 flags=flags, is_add=1)
3264 p = (Ether(src=self.pg9.remote_mac, dst=self.pg9.local_mac) /
3265 IP(src=local_host.ip4, dst=remote_host.ip4) /
3266 TCP(sport=12345, dport=80))
3267 self.pg9.add_stream(p)
3268 self.pg_enable_capture(self.pg_interfaces)
3270 capture = self.pg9.get_capture(1)
3275 self.assertEqual(ip.src, self.nat_addr)
3276 self.assertEqual(ip.dst, remote_host.ip4)
3277 self.assertNotEqual(tcp.sport, 12345)
3278 external_port = tcp.sport
3279 self.assertEqual(tcp.dport, 80)
3280 self.assert_packet_checksums_valid(p)
3282 self.logger.error(ppp("Unexpected or invalid packet:", p))
3286 p = (Ether(src=self.pg9.remote_mac, dst=self.pg9.local_mac) /
3287 IP(src=remote_host.ip4, dst=self.nat_addr) /
3288 TCP(sport=80, dport=external_port))
3289 self.pg9.add_stream(p)
3290 self.pg_enable_capture(self.pg_interfaces)
3292 capture = self.pg9.get_capture(1)
3297 self.assertEqual(ip.src, remote_host.ip4)
3298 self.assertEqual(ip.dst, local_host.ip4)
3299 self.assertEqual(tcp.sport, 80)
3300 self.assertEqual(tcp.dport, 12345)
3301 self.assert_packet_checksums_valid(p)
3303 self.logger.error(ppp("Unexpected or invalid packet:", p))
3306 err = self.statistics.get_err_counter(
3307 '/err/nat44-classify/next in2out')
3308 self.assertEqual(err, 1)
3309 err = self.statistics.get_err_counter(
3310 '/err/nat44-classify/next out2in')
3311 self.assertEqual(err, 1)
3313 def test_del_session(self):
3314 """ Delete NAT44 session """
3315 self.nat44_add_address(self.nat_addr)
3316 flags = self.config_flags.NAT_IS_INSIDE
3317 self.vapi.nat44_interface_add_del_feature(
3318 sw_if_index=self.pg0.sw_if_index,
3319 flags=flags, is_add=1)
3320 self.vapi.nat44_interface_add_del_feature(
3321 sw_if_index=self.pg1.sw_if_index,
3324 pkts = self.create_stream_in(self.pg0, self.pg1)
3325 self.pg0.add_stream(pkts)
3326 self.pg_enable_capture(self.pg_interfaces)
3328 self.pg1.get_capture(len(pkts))
3330 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4, 0)
3331 nsessions = len(sessions)
3333 self.vapi.nat44_del_session(address=sessions[0].inside_ip_address,
3334 port=sessions[0].inside_port,
3335 protocol=sessions[0].protocol,
3336 flags=self.config_flags.NAT_IS_INSIDE)
3337 self.vapi.nat44_del_session(address=sessions[1].outside_ip_address,
3338 port=sessions[1].outside_port,
3339 protocol=sessions[1].protocol)
3341 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4, 0)
3342 self.assertEqual(nsessions - len(sessions), 2)
3344 self.vapi.nat44_del_session(address=sessions[0].inside_ip_address,
3345 port=sessions[0].inside_port,
3346 protocol=sessions[0].protocol,
3347 flags=self.config_flags.NAT_IS_INSIDE)
3349 self.verify_no_nat44_user()
3351 def test_frag_in_order(self):
3352 """ NAT44 translate fragments arriving in order """
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.pg0.sw_if_index,
3358 flags=flags, is_add=1)
3359 self.vapi.nat44_interface_add_del_feature(
3360 sw_if_index=self.pg1.sw_if_index,
3363 self.frag_in_order(proto=IP_PROTOS.tcp)
3364 self.frag_in_order(proto=IP_PROTOS.udp)
3365 self.frag_in_order(proto=IP_PROTOS.icmp)
3367 def test_frag_forwarding(self):
3368 """ NAT44 forwarding fragment test """
3369 self.vapi.nat44_add_del_interface_addr(
3371 sw_if_index=self.pg1.sw_if_index)
3372 flags = self.config_flags.NAT_IS_INSIDE
3373 self.vapi.nat44_interface_add_del_feature(
3374 sw_if_index=self.pg0.sw_if_index,
3375 flags=flags, is_add=1)
3376 self.vapi.nat44_interface_add_del_feature(
3377 sw_if_index=self.pg1.sw_if_index,
3379 self.vapi.nat44_forwarding_enable_disable(enable=1)
3381 data = b"A" * 16 + b"B" * 16 + b"C" * 3
3382 pkts = self.create_stream_frag(self.pg1,
3383 self.pg0.remote_ip4,
3387 proto=IP_PROTOS.udp)
3388 self.pg1.add_stream(pkts)
3389 self.pg_enable_capture(self.pg_interfaces)
3391 frags = self.pg0.get_capture(len(pkts))
3392 p = self.reass_frags_and_verify(frags,
3393 self.pg1.remote_ip4,
3394 self.pg0.remote_ip4)
3395 self.assertEqual(p[UDP].sport, 4789)
3396 self.assertEqual(p[UDP].dport, 4789)
3397 self.assertEqual(data, p[Raw].load)
3399 def test_reass_hairpinning(self):
3400 """ NAT44 fragments hairpinning """
3402 self.server = self.pg0.remote_hosts[1]
3403 self.host_in_port = random.randint(1025, 65535)
3404 self.server_in_port = random.randint(1025, 65535)
3405 self.server_out_port = random.randint(1025, 65535)
3407 self.nat44_add_address(self.nat_addr)
3408 flags = self.config_flags.NAT_IS_INSIDE
3409 self.vapi.nat44_interface_add_del_feature(
3410 sw_if_index=self.pg0.sw_if_index,
3411 flags=flags, is_add=1)
3412 self.vapi.nat44_interface_add_del_feature(
3413 sw_if_index=self.pg1.sw_if_index,
3415 # add static mapping for server
3416 self.nat44_add_static_mapping(self.server.ip4, self.nat_addr,
3417 self.server_in_port,
3418 self.server_out_port,
3419 proto=IP_PROTOS.tcp)
3420 self.nat44_add_static_mapping(self.server.ip4, self.nat_addr,
3421 self.server_in_port,
3422 self.server_out_port,
3423 proto=IP_PROTOS.udp)
3424 self.nat44_add_static_mapping(self.server.ip4, self.nat_addr)
3426 self.reass_hairpinning(proto=IP_PROTOS.tcp)
3427 self.reass_hairpinning(proto=IP_PROTOS.udp)
3428 self.reass_hairpinning(proto=IP_PROTOS.icmp)
3430 def test_frag_out_of_order(self):
3431 """ NAT44 translate fragments arriving out of order """
3433 self.nat44_add_address(self.nat_addr)
3434 flags = self.config_flags.NAT_IS_INSIDE
3435 self.vapi.nat44_interface_add_del_feature(
3436 sw_if_index=self.pg0.sw_if_index,
3437 flags=flags, is_add=1)
3438 self.vapi.nat44_interface_add_del_feature(
3439 sw_if_index=self.pg1.sw_if_index,
3442 self.frag_out_of_order(proto=IP_PROTOS.tcp)
3443 self.frag_out_of_order(proto=IP_PROTOS.udp)
3444 self.frag_out_of_order(proto=IP_PROTOS.icmp)
3446 def test_port_restricted(self):
3447 """ Port restricted NAT44 (MAP-E CE) """
3448 self.nat44_add_address(self.nat_addr)
3449 flags = self.config_flags.NAT_IS_INSIDE
3450 self.vapi.nat44_interface_add_del_feature(
3451 sw_if_index=self.pg0.sw_if_index,
3452 flags=flags, is_add=1)
3453 self.vapi.nat44_interface_add_del_feature(
3454 sw_if_index=self.pg1.sw_if_index,
3456 self.vapi.nat_set_addr_and_port_alloc_alg(alg=1,
3461 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
3462 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
3463 TCP(sport=4567, dport=22))
3464 self.pg0.add_stream(p)
3465 self.pg_enable_capture(self.pg_interfaces)
3467 capture = self.pg1.get_capture(1)
3472 self.assertEqual(ip.dst, self.pg1.remote_ip4)
3473 self.assertEqual(ip.src, self.nat_addr)
3474 self.assertEqual(tcp.dport, 22)
3475 self.assertNotEqual(tcp.sport, 4567)
3476 self.assertEqual((tcp.sport >> 6) & 63, 10)
3477 self.assert_packet_checksums_valid(p)
3479 self.logger.error(ppp("Unexpected or invalid packet:", p))
3482 def test_port_range(self):
3483 """ External address port range """
3484 self.nat44_add_address(self.nat_addr)
3485 flags = self.config_flags.NAT_IS_INSIDE
3486 self.vapi.nat44_interface_add_del_feature(
3487 sw_if_index=self.pg0.sw_if_index,
3488 flags=flags, is_add=1)
3489 self.vapi.nat44_interface_add_del_feature(
3490 sw_if_index=self.pg1.sw_if_index,
3492 self.vapi.nat_set_addr_and_port_alloc_alg(alg=2,
3497 for port in range(0, 5):
3498 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
3499 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
3500 TCP(sport=1125 + port))
3502 self.pg0.add_stream(pkts)
3503 self.pg_enable_capture(self.pg_interfaces)
3505 capture = self.pg1.get_capture(3)
3508 self.assertGreaterEqual(tcp.sport, 1025)
3509 self.assertLessEqual(tcp.sport, 1027)
3511 def test_multiple_outside_vrf(self):
3512 """ Multiple outside VRF """
3516 self.pg1.unconfig_ip4()
3517 self.pg2.unconfig_ip4()
3518 self.vapi.ip_table_add_del(is_add=1, table={'table_id': vrf_id1})
3519 self.vapi.ip_table_add_del(is_add=1, table={'table_id': vrf_id2})
3520 self.pg1.set_table_ip4(vrf_id1)
3521 self.pg2.set_table_ip4(vrf_id2)
3522 self.pg1.config_ip4()
3523 self.pg2.config_ip4()
3524 self.pg1.resolve_arp()
3525 self.pg2.resolve_arp()
3527 self.nat44_add_address(self.nat_addr)
3528 flags = self.config_flags.NAT_IS_INSIDE
3529 self.vapi.nat44_interface_add_del_feature(
3530 sw_if_index=self.pg0.sw_if_index,
3531 flags=flags, is_add=1)
3532 self.vapi.nat44_interface_add_del_feature(
3533 sw_if_index=self.pg1.sw_if_index,
3535 self.vapi.nat44_interface_add_del_feature(
3536 sw_if_index=self.pg2.sw_if_index,
3541 pkts = self.create_stream_in(self.pg0, self.pg1)
3542 self.pg0.add_stream(pkts)
3543 self.pg_enable_capture(self.pg_interfaces)
3545 capture = self.pg1.get_capture(len(pkts))
3546 self.verify_capture_out(capture, self.nat_addr)
3548 pkts = self.create_stream_out(self.pg1, self.nat_addr)
3549 self.pg1.add_stream(pkts)
3550 self.pg_enable_capture(self.pg_interfaces)
3552 capture = self.pg0.get_capture(len(pkts))
3553 self.verify_capture_in(capture, self.pg0)
3555 self.tcp_port_in = 60303
3556 self.udp_port_in = 60304
3557 self.icmp_id_in = 60305
3560 pkts = self.create_stream_in(self.pg0, self.pg2)
3561 self.pg0.add_stream(pkts)
3562 self.pg_enable_capture(self.pg_interfaces)
3564 capture = self.pg2.get_capture(len(pkts))
3565 self.verify_capture_out(capture, self.nat_addr)
3567 pkts = self.create_stream_out(self.pg2, self.nat_addr)
3568 self.pg2.add_stream(pkts)
3569 self.pg_enable_capture(self.pg_interfaces)
3571 capture = self.pg0.get_capture(len(pkts))
3572 self.verify_capture_in(capture, self.pg0)
3575 self.nat44_add_address(self.nat_addr, is_add=0)
3576 self.pg1.unconfig_ip4()
3577 self.pg2.unconfig_ip4()
3578 self.pg1.set_table_ip4(0)
3579 self.pg2.set_table_ip4(0)
3580 self.pg1.config_ip4()
3581 self.pg2.config_ip4()
3582 self.pg1.resolve_arp()
3583 self.pg2.resolve_arp()
3585 @unittest.skipUnless(running_extended_tests, "part of extended tests")
3586 def test_session_timeout(self):
3587 """ NAT44 session timeouts """
3588 self.nat44_add_address(self.nat_addr)
3589 flags = self.config_flags.NAT_IS_INSIDE
3590 self.vapi.nat44_interface_add_del_feature(
3591 sw_if_index=self.pg0.sw_if_index,
3592 flags=flags, is_add=1)
3593 self.vapi.nat44_interface_add_del_feature(
3594 sw_if_index=self.pg1.sw_if_index,
3596 self.vapi.nat_set_timeouts(udp=5, tcp_established=7440,
3597 tcp_transitory=240, icmp=60)
3601 for i in range(0, max_sessions):
3602 src = "10.10.%u.%u" % ((i & 0xFF00) >> 8, i & 0xFF)
3603 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
3604 IP(src=src, dst=self.pg1.remote_ip4) /
3605 UDP(sport=1025, dport=53))
3607 self.pg0.add_stream(pkts)
3608 self.pg_enable_capture(self.pg_interfaces)
3610 self.pg1.get_capture(max_sessions)
3615 for i in range(0, max_sessions):
3616 src = "10.10.%u.%u" % ((i & 0xFF00) >> 8, i & 0xFF)
3617 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
3618 IP(src=src, dst=self.pg1.remote_ip4) /
3619 UDP(sport=1026, dport=53))
3621 self.pg0.add_stream(pkts)
3622 self.pg_enable_capture(self.pg_interfaces)
3624 self.pg1.get_capture(max_sessions)
3627 users = self.vapi.nat44_user_dump()
3629 nsessions = nsessions + user.nsessions
3630 self.assertLess(nsessions, 2 * max_sessions)
3632 def test_mss_clamping(self):
3633 """ TCP MSS clamping """
3634 self.nat44_add_address(self.nat_addr)
3635 flags = self.config_flags.NAT_IS_INSIDE
3636 self.vapi.nat44_interface_add_del_feature(
3637 sw_if_index=self.pg0.sw_if_index,
3638 flags=flags, is_add=1)
3639 self.vapi.nat44_interface_add_del_feature(
3640 sw_if_index=self.pg1.sw_if_index,
3643 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
3644 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
3645 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
3646 flags="S", options=[('MSS', 1400)]))
3648 self.vapi.nat_set_mss_clamping(enable=1, mss_value=1000)
3649 self.pg0.add_stream(p)
3650 self.pg_enable_capture(self.pg_interfaces)
3652 capture = self.pg1.get_capture(1)
3653 # Negotiated MSS value greater than configured - changed
3654 self.verify_mss_value(capture[0], 1000)
3656 self.vapi.nat_set_mss_clamping(enable=0, mss_value=1500)
3657 self.pg0.add_stream(p)
3658 self.pg_enable_capture(self.pg_interfaces)
3660 capture = self.pg1.get_capture(1)
3661 # MSS clamping disabled - negotiated MSS unchanged
3662 self.verify_mss_value(capture[0], 1400)
3664 self.vapi.nat_set_mss_clamping(enable=1, mss_value=1500)
3665 self.pg0.add_stream(p)
3666 self.pg_enable_capture(self.pg_interfaces)
3668 capture = self.pg1.get_capture(1)
3669 # Negotiated MSS value smaller than configured - unchanged
3670 self.verify_mss_value(capture[0], 1400)
3672 @unittest.skipUnless(running_extended_tests, "part of extended tests")
3673 def test_ha_send(self):
3674 """ Send HA session synchronization events (active) """
3675 self.nat44_add_address(self.nat_addr)
3676 flags = self.config_flags.NAT_IS_INSIDE
3677 self.vapi.nat44_interface_add_del_feature(
3678 sw_if_index=self.pg0.sw_if_index,
3679 flags=flags, is_add=1)
3680 self.vapi.nat44_interface_add_del_feature(
3681 sw_if_index=self.pg1.sw_if_index,
3683 self.vapi.nat_ha_set_listener(ip_address=self.pg3.local_ip4,
3686 self.vapi.nat_ha_set_failover(ip_address=self.pg3.remote_ip4,
3687 port=12346, session_refresh_interval=10)
3688 bind_layers(UDP, HANATStateSync, sport=12345)
3691 pkts = self.create_stream_in(self.pg0, self.pg1)
3692 self.pg0.add_stream(pkts)
3693 self.pg_enable_capture(self.pg_interfaces)
3695 capture = self.pg1.get_capture(len(pkts))
3696 self.verify_capture_out(capture)
3697 # active send HA events
3698 self.vapi.nat_ha_flush()
3699 stats = self.statistics.get_counter('/nat44/ha/add-event-send')
3700 self.assertEqual(stats[0][0], 3)
3701 capture = self.pg3.get_capture(1)
3703 self.assert_packet_checksums_valid(p)
3707 hanat = p[HANATStateSync]
3709 self.logger.error(ppp("Invalid packet:", p))
3712 self.assertEqual(ip.src, self.pg3.local_ip4)
3713 self.assertEqual(ip.dst, self.pg3.remote_ip4)
3714 self.assertEqual(udp.sport, 12345)
3715 self.assertEqual(udp.dport, 12346)
3716 self.assertEqual(hanat.version, 1)
3717 self.assertEqual(hanat.thread_index, 0)
3718 self.assertEqual(hanat.count, 3)
3719 seq = hanat.sequence_number
3720 for event in hanat.events:
3721 self.assertEqual(event.event_type, 1)
3722 self.assertEqual(event.in_addr, self.pg0.remote_ip4)
3723 self.assertEqual(event.out_addr, self.nat_addr)
3724 self.assertEqual(event.fib_index, 0)
3726 # ACK received events
3727 ack = (Ether(dst=self.pg3.local_mac, src=self.pg3.remote_mac) /
3728 IP(src=self.pg3.remote_ip4, dst=self.pg3.local_ip4) /
3729 UDP(sport=12346, dport=12345) /
3730 HANATStateSync(sequence_number=seq, flags='ACK'))
3731 self.pg3.add_stream(ack)
3733 stats = self.statistics.get_counter('/nat44/ha/ack-recv')
3734 self.assertEqual(stats[0][0], 1)
3736 # delete one session
3737 self.pg_enable_capture(self.pg_interfaces)
3738 self.vapi.nat44_del_session(address=self.pg0.remote_ip4,
3739 port=self.tcp_port_in,
3740 protocol=IP_PROTOS.tcp,
3741 flags=self.config_flags.NAT_IS_INSIDE)
3742 self.vapi.nat_ha_flush()
3743 stats = self.statistics.get_counter('/nat44/ha/del-event-send')
3744 self.assertEqual(stats[0][0], 1)
3745 capture = self.pg3.get_capture(1)
3748 hanat = p[HANATStateSync]
3750 self.logger.error(ppp("Invalid packet:", p))
3753 self.assertGreater(hanat.sequence_number, seq)
3755 # do not send ACK, active retry send HA event again
3756 self.pg_enable_capture(self.pg_interfaces)
3758 stats = self.statistics.get_counter('/nat44/ha/retry-count')
3759 self.assertEqual(stats[0][0], 3)
3760 stats = self.statistics.get_counter('/nat44/ha/missed-count')
3761 self.assertEqual(stats[0][0], 1)
3762 capture = self.pg3.get_capture(3)
3763 for packet in capture:
3764 self.assertEqual(packet, p)
3766 # session counters refresh
3767 pkts = self.create_stream_out(self.pg1)
3768 self.pg1.add_stream(pkts)
3769 self.pg_enable_capture(self.pg_interfaces)
3771 self.pg0.get_capture(2)
3772 self.vapi.nat_ha_flush()
3773 stats = self.statistics.get_counter('/nat44/ha/refresh-event-send')
3774 self.assertEqual(stats[0][0], 2)
3775 capture = self.pg3.get_capture(1)
3777 self.assert_packet_checksums_valid(p)
3781 hanat = p[HANATStateSync]
3783 self.logger.error(ppp("Invalid packet:", p))
3786 self.assertEqual(ip.src, self.pg3.local_ip4)
3787 self.assertEqual(ip.dst, self.pg3.remote_ip4)
3788 self.assertEqual(udp.sport, 12345)
3789 self.assertEqual(udp.dport, 12346)
3790 self.assertEqual(hanat.version, 1)
3791 self.assertEqual(hanat.count, 2)
3792 seq = hanat.sequence_number
3793 for event in hanat.events:
3794 self.assertEqual(event.event_type, 3)
3795 self.assertEqual(event.out_addr, self.nat_addr)
3796 self.assertEqual(event.fib_index, 0)
3797 self.assertEqual(event.total_pkts, 2)
3798 self.assertGreater(event.total_bytes, 0)
3800 ack = (Ether(dst=self.pg3.local_mac, src=self.pg3.remote_mac) /
3801 IP(src=self.pg3.remote_ip4, dst=self.pg3.local_ip4) /
3802 UDP(sport=12346, dport=12345) /
3803 HANATStateSync(sequence_number=seq, flags='ACK'))
3804 self.pg3.add_stream(ack)
3806 stats = self.statistics.get_counter('/nat44/ha/ack-recv')
3807 self.assertEqual(stats[0][0], 2)
3809 def test_ha_recv(self):
3810 """ Receive HA session synchronization events (passive) """
3811 self.nat44_add_address(self.nat_addr)
3812 flags = self.config_flags.NAT_IS_INSIDE
3813 self.vapi.nat44_interface_add_del_feature(
3814 sw_if_index=self.pg0.sw_if_index,
3815 flags=flags, is_add=1)
3816 self.vapi.nat44_interface_add_del_feature(
3817 sw_if_index=self.pg1.sw_if_index,
3819 self.vapi.nat_ha_set_listener(ip_address=self.pg3.local_ip4,
3822 bind_layers(UDP, HANATStateSync, sport=12345)
3824 self.tcp_port_out = random.randint(1025, 65535)
3825 self.udp_port_out = random.randint(1025, 65535)
3827 # send HA session add events to failover/passive
3828 p = (Ether(dst=self.pg3.local_mac, src=self.pg3.remote_mac) /
3829 IP(src=self.pg3.remote_ip4, dst=self.pg3.local_ip4) /
3830 UDP(sport=12346, dport=12345) /
3831 HANATStateSync(sequence_number=1, events=[
3832 Event(event_type='add', protocol='tcp',
3833 in_addr=self.pg0.remote_ip4, out_addr=self.nat_addr,
3834 in_port=self.tcp_port_in, out_port=self.tcp_port_out,
3835 eh_addr=self.pg1.remote_ip4,
3836 ehn_addr=self.pg1.remote_ip4,
3837 eh_port=self.tcp_external_port,
3838 ehn_port=self.tcp_external_port, fib_index=0),
3839 Event(event_type='add', protocol='udp',
3840 in_addr=self.pg0.remote_ip4, out_addr=self.nat_addr,
3841 in_port=self.udp_port_in, out_port=self.udp_port_out,
3842 eh_addr=self.pg1.remote_ip4,
3843 ehn_addr=self.pg1.remote_ip4,
3844 eh_port=self.udp_external_port,
3845 ehn_port=self.udp_external_port, fib_index=0)]))
3847 self.pg3.add_stream(p)
3848 self.pg_enable_capture(self.pg_interfaces)
3851 capture = self.pg3.get_capture(1)
3854 hanat = p[HANATStateSync]
3856 self.logger.error(ppp("Invalid packet:", p))
3859 self.assertEqual(hanat.sequence_number, 1)
3860 self.assertEqual(hanat.flags, 'ACK')
3861 self.assertEqual(hanat.version, 1)
3862 self.assertEqual(hanat.thread_index, 0)
3863 stats = self.statistics.get_counter('/nat44/ha/ack-send')
3864 self.assertEqual(stats[0][0], 1)
3865 stats = self.statistics.get_counter('/nat44/ha/add-event-recv')
3866 self.assertEqual(stats[0][0], 2)
3867 users = self.statistics.get_counter('/nat44/total-users')
3868 self.assertEqual(users[0][0], 1)
3869 sessions = self.statistics.get_counter('/nat44/total-sessions')
3870 self.assertEqual(sessions[0][0], 2)
3871 users = self.vapi.nat44_user_dump()
3872 self.assertEqual(len(users), 1)
3873 self.assertEqual(str(users[0].ip_address),
3874 self.pg0.remote_ip4)
3875 # there should be 2 sessions created by HA
3876 sessions = self.vapi.nat44_user_session_dump(users[0].ip_address,
3878 self.assertEqual(len(sessions), 2)
3879 for session in sessions:
3880 self.assertEqual(str(session.inside_ip_address),
3881 self.pg0.remote_ip4)
3882 self.assertEqual(str(session.outside_ip_address),
3884 self.assertIn(session.inside_port,
3885 [self.tcp_port_in, self.udp_port_in])
3886 self.assertIn(session.outside_port,
3887 [self.tcp_port_out, self.udp_port_out])
3888 self.assertIn(session.protocol, [IP_PROTOS.tcp, IP_PROTOS.udp])
3890 # send HA session delete event to failover/passive
3891 p = (Ether(dst=self.pg3.local_mac, src=self.pg3.remote_mac) /
3892 IP(src=self.pg3.remote_ip4, dst=self.pg3.local_ip4) /
3893 UDP(sport=12346, dport=12345) /
3894 HANATStateSync(sequence_number=2, events=[
3895 Event(event_type='del', protocol='udp',
3896 in_addr=self.pg0.remote_ip4, out_addr=self.nat_addr,
3897 in_port=self.udp_port_in, out_port=self.udp_port_out,
3898 eh_addr=self.pg1.remote_ip4,
3899 ehn_addr=self.pg1.remote_ip4,
3900 eh_port=self.udp_external_port,
3901 ehn_port=self.udp_external_port, fib_index=0)]))
3903 self.pg3.add_stream(p)
3904 self.pg_enable_capture(self.pg_interfaces)
3907 capture = self.pg3.get_capture(1)
3910 hanat = p[HANATStateSync]
3912 self.logger.error(ppp("Invalid packet:", p))
3915 self.assertEqual(hanat.sequence_number, 2)
3916 self.assertEqual(hanat.flags, 'ACK')
3917 self.assertEqual(hanat.version, 1)
3918 users = self.vapi.nat44_user_dump()
3919 self.assertEqual(len(users), 1)
3920 self.assertEqual(str(users[0].ip_address),
3921 self.pg0.remote_ip4)
3922 # now we should have only 1 session, 1 deleted by HA
3923 sessions = self.vapi.nat44_user_session_dump(users[0].ip_address,
3925 self.assertEqual(len(sessions), 1)
3926 stats = self.statistics.get_counter('/nat44/ha/del-event-recv')
3927 self.assertEqual(stats[0][0], 1)
3929 stats = self.statistics.get_err_counter('/err/nat-ha/pkts-processed')
3930 self.assertEqual(stats, 2)
3932 # send HA session refresh event to failover/passive
3933 p = (Ether(dst=self.pg3.local_mac, src=self.pg3.remote_mac) /
3934 IP(src=self.pg3.remote_ip4, dst=self.pg3.local_ip4) /
3935 UDP(sport=12346, dport=12345) /
3936 HANATStateSync(sequence_number=3, events=[
3937 Event(event_type='refresh', protocol='tcp',
3938 in_addr=self.pg0.remote_ip4, out_addr=self.nat_addr,
3939 in_port=self.tcp_port_in, out_port=self.tcp_port_out,
3940 eh_addr=self.pg1.remote_ip4,
3941 ehn_addr=self.pg1.remote_ip4,
3942 eh_port=self.tcp_external_port,
3943 ehn_port=self.tcp_external_port, fib_index=0,
3944 total_bytes=1024, total_pkts=2)]))
3945 self.pg3.add_stream(p)
3946 self.pg_enable_capture(self.pg_interfaces)
3949 capture = self.pg3.get_capture(1)
3952 hanat = p[HANATStateSync]
3954 self.logger.error(ppp("Invalid packet:", p))
3957 self.assertEqual(hanat.sequence_number, 3)
3958 self.assertEqual(hanat.flags, 'ACK')
3959 self.assertEqual(hanat.version, 1)
3960 users = self.vapi.nat44_user_dump()
3961 self.assertEqual(len(users), 1)
3962 self.assertEqual(str(users[0].ip_address),
3963 self.pg0.remote_ip4)
3964 sessions = self.vapi.nat44_user_session_dump(users[0].ip_address,
3966 self.assertEqual(len(sessions), 1)
3967 session = sessions[0]
3968 self.assertEqual(session.total_bytes, 1024)
3969 self.assertEqual(session.total_pkts, 2)
3970 stats = self.statistics.get_counter('/nat44/ha/refresh-event-recv')
3971 self.assertEqual(stats[0][0], 1)
3973 stats = self.statistics.get_err_counter('/err/nat-ha/pkts-processed')
3974 self.assertEqual(stats, 3)
3976 # send packet to test session created by HA
3977 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
3978 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
3979 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out))
3980 self.pg1.add_stream(p)
3981 self.pg_enable_capture(self.pg_interfaces)
3983 capture = self.pg0.get_capture(1)
3989 self.logger.error(ppp("Invalid packet:", p))
3992 self.assertEqual(ip.src, self.pg1.remote_ip4)
3993 self.assertEqual(ip.dst, self.pg0.remote_ip4)
3994 self.assertEqual(tcp.sport, self.tcp_external_port)
3995 self.assertEqual(tcp.dport, self.tcp_port_in)
3997 def show_commands_at_teardown(self):
3998 self.logger.info(self.vapi.cli("show nat44 addresses"))
3999 self.logger.info(self.vapi.cli("show nat44 interfaces"))
4000 self.logger.info(self.vapi.cli("show nat44 static mappings"))
4001 self.logger.info(self.vapi.cli("show nat44 interface address"))
4002 self.logger.info(self.vapi.cli("show nat44 sessions detail"))
4003 self.logger.info(self.vapi.cli("show nat44 hash tables detail"))
4004 self.logger.info(self.vapi.cli("show nat timeouts"))
4006 self.vapi.cli("show nat addr-port-assignment-alg"))
4007 self.logger.info(self.vapi.cli("show nat ha"))
4010 class TestNAT44EndpointDependent2(MethodHolder):
4011 """ Endpoint-Dependent mapping and filtering test cases """
4014 def tearDownClass(cls):
4015 super(TestNAT44EndpointDependent2, cls).tearDownClass()
4018 super(TestNAT44EndpointDependent2, self).tearDown()
4021 def create_and_add_ip4_table(cls, i, table_id):
4022 cls.vapi.ip_table_add_del(is_add=1, table={'table_id': table_id})
4023 i.set_table_ip4(table_id)
4026 def setUpClass(cls):
4027 super(TestNAT44EndpointDependent2, cls).setUpClass()
4029 cls.create_pg_interfaces(range(3))
4030 cls.interfaces = list(cls.pg_interfaces)
4032 cls.create_and_add_ip4_table(cls.pg1, 10)
4034 for i in cls.interfaces:
4039 i.generate_remote_hosts(1)
4040 i.configure_ipv4_neighbors()
4043 super(TestNAT44EndpointDependent2, self).setUp()
4044 flags = self.nat44_config_flags.NAT44_IS_ENDPOINT_DEPENDENT
4045 self.vapi.nat44_plugin_enable_disable(enable=1, flags=flags)
4048 super(TestNAT44EndpointDependent2, self).tearDown()
4049 if not self.vpp_dead:
4050 self.vapi.nat44_plugin_enable_disable(enable=0)
4051 self.vapi.cli("clear logging")
4053 def nat_add_inside_interface(self, i):
4054 self.vapi.nat44_interface_add_del_feature(
4055 flags=self.config_flags.NAT_IS_INSIDE,
4056 sw_if_index=i.sw_if_index, is_add=1)
4058 def nat_add_outside_interface(self, i):
4059 self.vapi.nat44_interface_add_del_feature(
4060 flags=self.config_flags.NAT_IS_OUTSIDE,
4061 sw_if_index=i.sw_if_index, is_add=1)
4063 def nat_add_interface_address(self, i):
4064 self.nat_addr = i.local_ip4
4065 self.vapi.nat44_add_del_interface_addr(
4066 sw_if_index=i.sw_if_index, is_add=1)
4068 def nat_add_address(self, address, vrf_id=0xFFFFFFFF):
4069 self.nat_addr = address
4070 self.nat44_add_address(address, vrf_id=vrf_id)
4072 def cli(self, command):
4073 result = self.vapi.cli(command)
4074 self.logger.info(result)
4077 def show_configuration(self):
4078 self.cli("show interface")
4079 self.cli("show interface address")
4080 self.cli("show nat44 addresses")
4081 self.cli("show nat44 interfaces")
4083 def create_tcp_stream(self, in_if, out_if, count):
4085 Create tcp packet stream
4087 :param in_if: Inside interface
4088 :param out_if: Outside interface
4089 :param count: count of packets to generate
4094 for i in range(count):
4095 p = (Ether(dst=in_if.local_mac, src=in_if.remote_mac) /
4096 IP(src=in_if.remote_ip4, dst=out_if.remote_ip4, ttl=64) /
4097 TCP(sport=port + i, dport=20))
4102 def test_session_limit_per_vrf(self):
4105 inside_vrf10 = self.pg1
4110 # 2 interfaces pg0, pg1 (vrf10, limit 1 tcp session)
4111 # non existing vrf_id makes process core dump
4112 self.vapi.nat44_set_session_limit(session_limit=limit, vrf_id=10)
4114 self.nat_add_inside_interface(inside)
4115 self.nat_add_inside_interface(inside_vrf10)
4116 self.nat_add_outside_interface(outside)
4119 self.nat_add_interface_address(outside)
4121 # BUG: causing core dump - when bad vrf_id is specified
4122 # self.nat44_add_address(outside.local_ip4, vrf_id=20)
4124 self.show_configuration()
4126 stream = self.create_tcp_stream(inside_vrf10, outside, limit * 2)
4127 inside_vrf10.add_stream(stream)
4129 self.pg_enable_capture(self.pg_interfaces)
4132 capture = outside.get_capture(limit)
4134 stream = self.create_tcp_stream(inside, outside, limit * 2)
4135 inside.add_stream(stream)
4137 self.pg_enable_capture(self.pg_interfaces)
4140 capture = outside.get_capture(len(stream))
4143 class TestNAT44EndpointDependent(MethodHolder):
4144 """ Endpoint-Dependent mapping and filtering test cases """
4147 def setUpClass(cls):
4148 super(TestNAT44EndpointDependent, cls).setUpClass()
4149 cls.vapi.cli("set log class nat level debug")
4151 cls.tcp_port_in = 6303
4152 cls.tcp_port_out = 6303
4153 cls.udp_port_in = 6304
4154 cls.udp_port_out = 6304
4155 cls.icmp_id_in = 6305
4156 cls.icmp_id_out = 6305
4157 cls.nat_addr = '10.0.0.3'
4158 cls.ipfix_src_port = 4739
4159 cls.ipfix_domain_id = 1
4160 cls.tcp_external_port = 80
4162 cls.create_pg_interfaces(range(9))
4163 cls.interfaces = list(cls.pg_interfaces[0:3])
4165 for i in cls.interfaces:
4170 cls.pg0.generate_remote_hosts(3)
4171 cls.pg0.configure_ipv4_neighbors()
4175 cls.pg4.generate_remote_hosts(2)
4176 cls.pg4.config_ip4()
4177 cls.vapi.sw_interface_add_del_address(
4178 sw_if_index=cls.pg4.sw_if_index,
4179 prefix="10.0.0.1/24")
4182 cls.pg4.resolve_arp()
4183 cls.pg4._remote_hosts[1]._ip4 = cls.pg4._remote_hosts[0]._ip4
4184 cls.pg4.resolve_arp()
4186 zero_ip4 = socket.inet_pton(socket.AF_INET, "0.0.0.0")
4187 cls.vapi.ip_table_add_del(is_add=1, table={'table_id': 1})
4189 cls.pg5._local_ip4 = "10.1.1.1"
4190 cls.pg5._remote_hosts[0]._ip4 = "10.1.1.2"
4191 cls.pg5.set_table_ip4(1)
4192 cls.pg5.config_ip4()
4194 r1 = VppIpRoute(cls, cls.pg5.remote_ip4, 32,
4195 [VppRoutePath("0.0.0.0",
4196 cls.pg5.sw_if_index)],
4201 cls.pg6._local_ip4 = "10.1.2.1"
4202 cls.pg6._remote_hosts[0]._ip4 = "10.1.2.2"
4203 cls.pg6.set_table_ip4(1)
4204 cls.pg6.config_ip4()
4207 r2 = VppIpRoute(cls, cls.pg6.remote_ip4, 32,
4208 [VppRoutePath("0.0.0.0",
4209 cls.pg6.sw_if_index)],
4212 r3 = VppIpRoute(cls, cls.pg6.remote_ip4, 16,
4213 [VppRoutePath("0.0.0.0",
4218 r4 = VppIpRoute(cls, "0.0.0.0", 0,
4219 [VppRoutePath("0.0.0.0", 0xffffffff,
4223 r5 = VppIpRoute(cls, "0.0.0.0", 0,
4224 [VppRoutePath(cls.pg1.local_ip4,
4225 cls.pg1.sw_if_index)],
4232 cls.pg5.resolve_arp()
4233 cls.pg6.resolve_arp()
4236 cls.pg7.config_ip4()
4237 cls.pg7.resolve_arp()
4238 cls.pg7.generate_remote_hosts(3)
4239 cls.pg7.configure_ipv4_neighbors()
4242 cls.pg8.config_ip4()
4243 cls.pg8.resolve_arp()
4246 def tearDownClass(cls):
4247 super(TestNAT44EndpointDependent, cls).tearDownClass()
4250 super(TestNAT44EndpointDependent, self).setUp()
4251 flags = self.nat44_config_flags.NAT44_IS_ENDPOINT_DEPENDENT
4252 self.vapi.nat44_plugin_enable_disable(enable=1, flags=flags)
4253 self.vapi.nat_set_timeouts(
4254 udp=300, tcp_established=7440,
4255 tcp_transitory=240, icmp=60)
4258 super(TestNAT44EndpointDependent, self).tearDown()
4259 if not self.vpp_dead:
4260 self.vapi.nat44_plugin_enable_disable(enable=0)
4261 self.vapi.cli("clear logging")
4263 def test_frag_in_order(self):
4264 """ NAT44 translate fragments arriving in order """
4265 self.nat44_add_address(self.nat_addr)
4266 flags = self.config_flags.NAT_IS_INSIDE
4267 self.vapi.nat44_interface_add_del_feature(
4268 sw_if_index=self.pg0.sw_if_index,
4269 flags=flags, is_add=1)
4270 self.vapi.nat44_interface_add_del_feature(
4271 sw_if_index=self.pg1.sw_if_index,
4273 self.frag_in_order(proto=IP_PROTOS.tcp, ignore_port=True)
4274 self.frag_in_order(proto=IP_PROTOS.udp, ignore_port=True)
4275 self.frag_in_order(proto=IP_PROTOS.icmp, ignore_port=True)
4277 def test_frag_in_order_dont_translate(self):
4278 """ NAT44 don't translate fragments arriving in order """
4279 flags = self.config_flags.NAT_IS_INSIDE
4280 self.vapi.nat44_interface_add_del_feature(
4281 sw_if_index=self.pg0.sw_if_index,
4282 flags=flags, is_add=1)
4283 self.vapi.nat44_interface_add_del_feature(
4284 sw_if_index=self.pg1.sw_if_index,
4286 self.vapi.nat44_forwarding_enable_disable(enable=True)
4287 self.frag_in_order(proto=IP_PROTOS.tcp, dont_translate=True)
4289 def test_frag_out_of_order(self):
4290 """ NAT44 translate fragments arriving out of order """
4291 self.nat44_add_address(self.nat_addr)
4292 flags = self.config_flags.NAT_IS_INSIDE
4293 self.vapi.nat44_interface_add_del_feature(
4294 sw_if_index=self.pg0.sw_if_index,
4295 flags=flags, is_add=1)
4296 self.vapi.nat44_interface_add_del_feature(
4297 sw_if_index=self.pg1.sw_if_index,
4299 self.frag_out_of_order(proto=IP_PROTOS.tcp, ignore_port=True)
4300 self.frag_out_of_order(proto=IP_PROTOS.udp, ignore_port=True)
4301 self.frag_out_of_order(proto=IP_PROTOS.icmp, ignore_port=True)
4303 def test_frag_out_of_order_dont_translate(self):
4304 """ NAT44 don't translate fragments arriving out of order """
4305 flags = self.config_flags.NAT_IS_INSIDE
4306 self.vapi.nat44_interface_add_del_feature(
4307 sw_if_index=self.pg0.sw_if_index,
4308 flags=flags, is_add=1)
4309 self.vapi.nat44_interface_add_del_feature(
4310 sw_if_index=self.pg1.sw_if_index,
4312 self.vapi.nat44_forwarding_enable_disable(enable=True)
4313 self.frag_out_of_order(proto=IP_PROTOS.tcp, dont_translate=True)
4315 def test_frag_in_order_in_plus_out(self):
4316 """ in+out interface fragments in order """
4317 flags = self.config_flags.NAT_IS_INSIDE
4318 self.vapi.nat44_interface_add_del_feature(
4319 sw_if_index=self.pg0.sw_if_index,
4321 self.vapi.nat44_interface_add_del_feature(
4322 sw_if_index=self.pg0.sw_if_index,
4323 flags=flags, is_add=1)
4324 self.vapi.nat44_interface_add_del_feature(
4325 sw_if_index=self.pg1.sw_if_index,
4327 self.vapi.nat44_interface_add_del_feature(
4328 sw_if_index=self.pg1.sw_if_index,
4329 flags=flags, is_add=1)
4331 self.server = self.pg1.remote_hosts[0]
4333 self.server_in_addr = self.server.ip4
4334 self.server_out_addr = '11.11.11.11'
4335 self.server_in_port = random.randint(1025, 65535)
4336 self.server_out_port = random.randint(1025, 65535)
4338 self.nat44_add_address(self.server_out_addr)
4340 # add static mappings for server
4341 self.nat44_add_static_mapping(self.server_in_addr,
4342 self.server_out_addr,
4343 self.server_in_port,
4344 self.server_out_port,
4345 proto=IP_PROTOS.tcp)
4346 self.nat44_add_static_mapping(self.server_in_addr,
4347 self.server_out_addr,
4348 self.server_in_port,
4349 self.server_out_port,
4350 proto=IP_PROTOS.udp)
4351 self.nat44_add_static_mapping(self.server_in_addr,
4352 self.server_out_addr,
4353 proto=IP_PROTOS.icmp)
4355 self.frag_in_order_in_plus_out(proto=IP_PROTOS.tcp)
4356 self.frag_in_order_in_plus_out(proto=IP_PROTOS.udp)
4357 self.frag_in_order_in_plus_out(proto=IP_PROTOS.icmp)
4359 def test_frag_out_of_order_in_plus_out(self):
4360 """ in+out interface fragments out of order """
4361 flags = self.config_flags.NAT_IS_INSIDE
4362 self.vapi.nat44_interface_add_del_feature(
4363 sw_if_index=self.pg0.sw_if_index,
4365 self.vapi.nat44_interface_add_del_feature(
4366 sw_if_index=self.pg0.sw_if_index,
4367 flags=flags, is_add=1)
4368 self.vapi.nat44_interface_add_del_feature(
4369 sw_if_index=self.pg1.sw_if_index,
4371 self.vapi.nat44_interface_add_del_feature(
4372 sw_if_index=self.pg1.sw_if_index,
4373 flags=flags, is_add=1)
4375 self.server = self.pg1.remote_hosts[0]
4377 self.server_in_addr = self.server.ip4
4378 self.server_out_addr = '11.11.11.11'
4379 self.server_in_port = random.randint(1025, 65535)
4380 self.server_out_port = random.randint(1025, 65535)
4382 self.nat44_add_address(self.server_out_addr)
4384 # add static mappings for server
4385 self.nat44_add_static_mapping(self.server_in_addr,
4386 self.server_out_addr,
4387 self.server_in_port,
4388 self.server_out_port,
4389 proto=IP_PROTOS.tcp)
4390 self.nat44_add_static_mapping(self.server_in_addr,
4391 self.server_out_addr,
4392 self.server_in_port,
4393 self.server_out_port,
4394 proto=IP_PROTOS.udp)
4395 self.nat44_add_static_mapping(self.server_in_addr,
4396 self.server_out_addr,
4397 proto=IP_PROTOS.icmp)
4399 self.frag_out_of_order_in_plus_out(proto=IP_PROTOS.tcp)
4400 self.frag_out_of_order_in_plus_out(proto=IP_PROTOS.udp)
4401 self.frag_out_of_order_in_plus_out(proto=IP_PROTOS.icmp)
4403 def test_reass_hairpinning(self):
4404 """ NAT44 fragments hairpinning """
4405 self.server = self.pg0.remote_hosts[1]
4406 self.host_in_port = random.randint(1025, 65535)
4407 self.server_in_port = random.randint(1025, 65535)
4408 self.server_out_port = random.randint(1025, 65535)
4410 self.nat44_add_address(self.nat_addr)
4411 flags = self.config_flags.NAT_IS_INSIDE
4412 self.vapi.nat44_interface_add_del_feature(
4413 sw_if_index=self.pg0.sw_if_index,
4414 flags=flags, is_add=1)
4415 self.vapi.nat44_interface_add_del_feature(
4416 sw_if_index=self.pg1.sw_if_index,
4418 # add static mapping for server
4419 self.nat44_add_static_mapping(self.server.ip4, self.nat_addr,
4420 self.server_in_port,
4421 self.server_out_port,
4422 proto=IP_PROTOS.tcp)
4423 self.nat44_add_static_mapping(self.server.ip4, self.nat_addr,
4424 self.server_in_port,
4425 self.server_out_port,
4426 proto=IP_PROTOS.udp)
4427 self.nat44_add_static_mapping(self.server.ip4, self.nat_addr)
4429 self.reass_hairpinning(proto=IP_PROTOS.tcp, ignore_port=True)
4430 self.reass_hairpinning(proto=IP_PROTOS.udp, ignore_port=True)
4431 self.reass_hairpinning(proto=IP_PROTOS.icmp, ignore_port=True)
4433 def test_clear_sessions(self):
4434 """ NAT44 ED session clearing test """
4436 self.nat44_add_address(self.nat_addr)
4437 flags = self.config_flags.NAT_IS_INSIDE
4438 self.vapi.nat44_interface_add_del_feature(
4439 sw_if_index=self.pg0.sw_if_index,
4440 flags=flags, is_add=1)
4441 self.vapi.nat44_interface_add_del_feature(
4442 sw_if_index=self.pg1.sw_if_index,
4445 nat_config = self.vapi.nat_show_config()
4446 self.assertEqual(1, nat_config.endpoint_dependent)
4448 pkts = self.create_stream_in(self.pg0, self.pg1)
4449 self.pg0.add_stream(pkts)
4450 self.pg_enable_capture(self.pg_interfaces)
4452 capture = self.pg1.get_capture(len(pkts))
4453 self.verify_capture_out(capture, ignore_port=True)
4455 sessions = self.statistics.get_counter('/nat44/total-sessions')
4456 self.assertTrue(sessions[0][0] > 0)
4457 self.logger.info("sessions before clearing: %s" % sessions[0][0])
4459 # just for testing purposes
4460 self.logger.info(self.vapi.cli("show nat44 summary"))
4462 self.vapi.cli("clear nat44 sessions")
4464 self.logger.info(self.vapi.cli("show nat44 summary"))
4466 sessions = self.statistics.get_counter('/nat44/total-sessions')
4467 self.assertEqual(sessions[0][0], 0)
4468 self.logger.info("sessions after clearing: %s" % sessions[0][0])
4470 def test_dynamic(self):
4471 """ NAT44 dynamic translation test """
4473 self.nat44_add_address(self.nat_addr)
4474 flags = self.config_flags.NAT_IS_INSIDE
4475 self.vapi.nat44_interface_add_del_feature(
4476 sw_if_index=self.pg0.sw_if_index,
4477 flags=flags, is_add=1)
4478 self.vapi.nat44_interface_add_del_feature(
4479 sw_if_index=self.pg1.sw_if_index,
4482 nat_config = self.vapi.nat_show_config()
4483 self.assertEqual(1, nat_config.endpoint_dependent)
4486 tcpn = self.statistics.get_counter('/nat44/ed/in2out/slowpath/tcp')[0]
4487 udpn = self.statistics.get_counter('/nat44/ed/in2out/slowpath/udp')[0]
4488 icmpn = self.statistics.get_counter(
4489 '/nat44/ed/in2out/slowpath/icmp')[0]
4490 drops = self.statistics.get_counter(
4491 '/nat44/ed/in2out/slowpath/drops')[0]
4493 pkts = self.create_stream_in(self.pg0, self.pg1)
4494 self.pg0.add_stream(pkts)
4495 self.pg_enable_capture(self.pg_interfaces)
4497 capture = self.pg1.get_capture(len(pkts))
4498 self.verify_capture_out(capture, ignore_port=True)
4500 if_idx = self.pg0.sw_if_index
4501 cnt = self.statistics.get_counter('/nat44/ed/in2out/slowpath/tcp')[0]
4502 self.assertEqual(cnt[if_idx] - tcpn[if_idx], 2)
4503 cnt = self.statistics.get_counter('/nat44/ed/in2out/slowpath/udp')[0]
4504 self.assertEqual(cnt[if_idx] - udpn[if_idx], 1)
4505 cnt = self.statistics.get_counter('/nat44/ed/in2out/slowpath/icmp')[0]
4506 self.assertEqual(cnt[if_idx] - icmpn[if_idx], 1)
4507 cnt = self.statistics.get_counter('/nat44/ed/in2out/slowpath/drops')[0]
4508 self.assertEqual(cnt[if_idx] - drops[if_idx], 0)
4511 tcpn = self.statistics.get_counter('/nat44/ed/out2in/fastpath/tcp')[0]
4512 udpn = self.statistics.get_counter('/nat44/ed/out2in/fastpath/udp')[0]
4513 icmpn = self.statistics.get_counter(
4514 '/nat44/ed/out2in/slowpath/icmp')[0]
4515 drops = self.statistics.get_counter(
4516 '/nat44/ed/out2in/fastpath/drops')[0]
4518 pkts = self.create_stream_out(self.pg1)
4519 self.pg1.add_stream(pkts)
4520 self.pg_enable_capture(self.pg_interfaces)
4522 capture = self.pg0.get_capture(len(pkts))
4523 self.verify_capture_in(capture, self.pg0)
4525 if_idx = self.pg1.sw_if_index
4526 cnt = self.statistics.get_counter('/nat44/ed/out2in/fastpath/tcp')[0]
4527 self.assertEqual(cnt[if_idx] - tcpn[if_idx], 2)
4528 cnt = self.statistics.get_counter('/nat44/ed/out2in/fastpath/udp')[0]
4529 self.assertEqual(cnt[if_idx] - udpn[if_idx], 1)
4530 cnt = self.statistics.get_counter('/nat44/ed/out2in/slowpath/icmp')[0]
4531 self.assertEqual(cnt[if_idx] - icmpn[if_idx], 1)
4532 cnt = self.statistics.get_counter('/nat44/ed/out2in/fastpath/drops')[0]
4533 self.assertEqual(cnt[if_idx] - drops[if_idx], 0)
4535 sessions = self.statistics.get_counter('/nat44/total-sessions')
4536 self.assertEqual(sessions[0][0], 3)
4538 def test_dynamic_out_of_ports(self):
4539 """ NAT44 dynamic translation test: out of ports """
4541 flags = self.config_flags.NAT_IS_INSIDE
4542 self.vapi.nat44_interface_add_del_feature(
4543 sw_if_index=self.pg0.sw_if_index,
4544 flags=flags, is_add=1)
4545 self.vapi.nat44_interface_add_del_feature(
4546 sw_if_index=self.pg1.sw_if_index,
4549 nat_config = self.vapi.nat_show_config()
4550 self.assertEqual(1, nat_config.endpoint_dependent)
4552 # in2out and no NAT addresses added
4553 err_old = self.statistics.get_err_counter(
4554 '/err/nat44-ed-in2out-slowpath/out of ports')
4556 pkts = self.create_stream_in(self.pg0, self.pg1)
4557 self.pg0.add_stream(pkts)
4558 self.pg_enable_capture(self.pg_interfaces)
4560 self.pg1.get_capture(0, timeout=1)
4562 err_new = self.statistics.get_err_counter(
4563 '/err/nat44-ed-in2out-slowpath/out of ports')
4565 self.assertEqual(err_new - err_old, len(pkts))
4567 # in2out after NAT addresses added
4568 self.nat44_add_address(self.nat_addr)
4570 err_old = self.statistics.get_err_counter(
4571 '/err/nat44-ed-in2out-slowpath/out of ports')
4573 pkts = self.create_stream_in(self.pg0, self.pg1)
4574 self.pg0.add_stream(pkts)
4575 self.pg_enable_capture(self.pg_interfaces)
4577 capture = self.pg1.get_capture(len(pkts))
4578 self.verify_capture_out(capture, ignore_port=True)
4580 err_new = self.statistics.get_err_counter(
4581 '/err/nat44-ed-in2out-slowpath/out of ports')
4583 self.assertEqual(err_new, err_old)
4585 def test_dynamic_output_feature_vrf(self):
4586 """ NAT44 dynamic translation test: output-feature, VRF"""
4588 # other then default (0)
4591 self.nat44_add_address(self.nat_addr)
4592 flags = self.config_flags.NAT_IS_INSIDE
4593 self.vapi.nat44_interface_add_del_output_feature(
4594 sw_if_index=self.pg7.sw_if_index,
4595 flags=flags, is_add=1)
4596 self.vapi.nat44_interface_add_del_output_feature(
4597 sw_if_index=self.pg8.sw_if_index,
4601 self.vapi.ip_table_add_del(is_add=1,
4602 table={'table_id': new_vrf_id})
4604 self.pg7.unconfig_ip4()
4605 self.pg7.set_table_ip4(new_vrf_id)
4606 self.pg7.config_ip4()
4607 self.pg7.resolve_arp()
4609 self.pg8.unconfig_ip4()
4610 self.pg8.set_table_ip4(new_vrf_id)
4611 self.pg8.config_ip4()
4612 self.pg8.resolve_arp()
4614 nat_config = self.vapi.nat_show_config()
4615 self.assertEqual(1, nat_config.endpoint_dependent)
4618 tcpn = self.statistics.get_counter(
4619 '/nat44/ed/in2out/slowpath/tcp')[0]
4620 udpn = self.statistics.get_counter(
4621 '/nat44/ed/in2out/slowpath/udp')[0]
4622 icmpn = self.statistics.get_counter(
4623 '/nat44/ed/in2out/slowpath/icmp')[0]
4624 drops = self.statistics.get_counter(
4625 '/nat44/ed/in2out/slowpath/drops')[0]
4627 pkts = self.create_stream_in(self.pg7, self.pg8)
4628 self.pg7.add_stream(pkts)
4629 self.pg_enable_capture(self.pg_interfaces)
4631 capture = self.pg8.get_capture(len(pkts))
4632 self.verify_capture_out(capture, ignore_port=True)
4634 if_idx = self.pg7.sw_if_index
4635 cnt = self.statistics.get_counter(
4636 '/nat44/ed/in2out/slowpath/tcp')[0]
4637 self.assertEqual(cnt[if_idx] - tcpn[if_idx], 2)
4638 cnt = self.statistics.get_counter(
4639 '/nat44/ed/in2out/slowpath/udp')[0]
4640 self.assertEqual(cnt[if_idx] - udpn[if_idx], 1)
4641 cnt = self.statistics.get_counter(
4642 '/nat44/ed/in2out/slowpath/icmp')[0]
4643 self.assertEqual(cnt[if_idx] - icmpn[if_idx], 1)
4644 cnt = self.statistics.get_counter(
4645 '/nat44/ed/in2out/slowpath/drops')[0]
4646 self.assertEqual(cnt[if_idx] - drops[if_idx], 0)
4649 tcpn = self.statistics.get_counter(
4650 '/nat44/ed/out2in/fastpath/tcp')[0]
4651 udpn = self.statistics.get_counter(
4652 '/nat44/ed/out2in/fastpath/udp')[0]
4653 icmpn = self.statistics.get_counter(
4654 '/nat44/ed/out2in/slowpath/icmp')[0]
4655 drops = self.statistics.get_counter(
4656 '/nat44/ed/out2in/fastpath/drops')[0]
4658 pkts = self.create_stream_out(self.pg8)
4659 self.pg8.add_stream(pkts)
4660 self.pg_enable_capture(self.pg_interfaces)
4662 capture = self.pg7.get_capture(len(pkts))
4663 self.verify_capture_in(capture, self.pg7)
4665 if_idx = self.pg8.sw_if_index
4666 cnt = self.statistics.get_counter(
4667 '/nat44/ed/out2in/fastpath/tcp')[0]
4668 self.assertEqual(cnt[if_idx] - tcpn[if_idx], 2)
4669 cnt = self.statistics.get_counter(
4670 '/nat44/ed/out2in/fastpath/udp')[0]
4671 self.assertEqual(cnt[if_idx] - udpn[if_idx], 1)
4672 cnt = self.statistics.get_counter(
4673 '/nat44/ed/out2in/slowpath/icmp')[0]
4674 self.assertEqual(cnt[if_idx] - icmpn[if_idx], 1)
4675 cnt = self.statistics.get_counter(
4676 '/nat44/ed/out2in/fastpath/drops')[0]
4677 self.assertEqual(cnt[if_idx] - drops[if_idx], 0)
4679 sessions = self.statistics.get_counter('/nat44/total-sessions')
4680 self.assertEqual(sessions[0][0], 3)
4683 self.pg7.unconfig_ip4()
4684 self.pg7.set_table_ip4(1)
4685 self.pg7.config_ip4()
4686 self.pg7.resolve_arp()
4688 self.pg8.unconfig_ip4()
4689 self.pg8.set_table_ip4(1)
4690 self.pg8.config_ip4()
4691 self.pg8.resolve_arp()
4693 self.vapi.ip_table_add_del(is_add=0,
4694 table={'table_id': new_vrf_id})
4696 def test_forwarding(self):
4697 """ NAT44 forwarding test """
4699 flags = self.config_flags.NAT_IS_INSIDE
4700 self.vapi.nat44_interface_add_del_feature(
4701 sw_if_index=self.pg0.sw_if_index,
4702 flags=flags, is_add=1)
4703 self.vapi.nat44_interface_add_del_feature(
4704 sw_if_index=self.pg1.sw_if_index,
4706 self.vapi.nat44_forwarding_enable_disable(enable=1)
4708 real_ip = self.pg0.remote_ip4
4709 alias_ip = self.nat_addr
4710 flags = self.config_flags.NAT_IS_ADDR_ONLY
4711 self.vapi.nat44_add_del_static_mapping(is_add=1,
4712 local_ip_address=real_ip,
4713 external_ip_address=alias_ip,
4714 external_sw_if_index=0xFFFFFFFF,
4718 # in2out - static mapping match
4720 pkts = self.create_stream_out(self.pg1)
4721 self.pg1.add_stream(pkts)
4722 self.pg_enable_capture(self.pg_interfaces)
4724 capture = self.pg0.get_capture(len(pkts))
4725 self.verify_capture_in(capture, self.pg0)
4727 pkts = self.create_stream_in(self.pg0, self.pg1)
4728 self.pg0.add_stream(pkts)
4729 self.pg_enable_capture(self.pg_interfaces)
4731 capture = self.pg1.get_capture(len(pkts))
4732 self.verify_capture_out(capture, same_port=True)
4734 # in2out - no static mapping match
4736 host0 = self.pg0.remote_hosts[0]
4737 self.pg0.remote_hosts[0] = self.pg0.remote_hosts[1]
4739 pkts = self.create_stream_out(self.pg1,
4740 dst_ip=self.pg0.remote_ip4,
4741 use_inside_ports=True)
4742 self.pg1.add_stream(pkts)
4743 self.pg_enable_capture(self.pg_interfaces)
4745 capture = self.pg0.get_capture(len(pkts))
4746 self.verify_capture_in(capture, self.pg0)
4748 pkts = self.create_stream_in(self.pg0, self.pg1)
4749 self.pg0.add_stream(pkts)
4750 self.pg_enable_capture(self.pg_interfaces)
4752 capture = self.pg1.get_capture(len(pkts))
4753 self.verify_capture_out(capture, nat_ip=self.pg0.remote_ip4,
4756 self.pg0.remote_hosts[0] = host0
4758 user = self.pg0.remote_hosts[1]
4759 sessions = self.vapi.nat44_user_session_dump(user.ip4, 0)
4760 self.assertEqual(len(sessions), 3)
4761 self.assertTrue(sessions[0].flags &
4762 self.config_flags.NAT_IS_EXT_HOST_VALID)
4763 self.vapi.nat44_del_session(
4764 address=sessions[0].inside_ip_address,
4765 port=sessions[0].inside_port,
4766 protocol=sessions[0].protocol,
4767 flags=(self.config_flags.NAT_IS_INSIDE |
4768 self.config_flags.NAT_IS_EXT_HOST_VALID),
4769 ext_host_address=sessions[0].ext_host_address,
4770 ext_host_port=sessions[0].ext_host_port)
4771 sessions = self.vapi.nat44_user_session_dump(user.ip4, 0)
4772 self.assertEqual(len(sessions), 2)
4775 self.vapi.nat44_forwarding_enable_disable(enable=0)
4776 flags = self.config_flags.NAT_IS_ADDR_ONLY
4777 self.vapi.nat44_add_del_static_mapping(
4779 local_ip_address=real_ip,
4780 external_ip_address=alias_ip,
4781 external_sw_if_index=0xFFFFFFFF,
4784 def test_static_lb(self):
4785 """ NAT44 local service load balancing """
4786 external_addr_n = self.nat_addr
4789 server1 = self.pg0.remote_hosts[0]
4790 server2 = self.pg0.remote_hosts[1]
4792 locals = [{'addr': server1.ip4,
4796 {'addr': server2.ip4,
4801 self.nat44_add_address(self.nat_addr)
4802 self.vapi.nat44_add_del_lb_static_mapping(
4804 external_addr=external_addr_n,
4805 external_port=external_port,
4806 protocol=IP_PROTOS.tcp,
4807 local_num=len(locals),
4809 flags = self.config_flags.NAT_IS_INSIDE
4810 self.vapi.nat44_interface_add_del_feature(
4811 sw_if_index=self.pg0.sw_if_index,
4812 flags=flags, is_add=1)
4813 self.vapi.nat44_interface_add_del_feature(
4814 sw_if_index=self.pg1.sw_if_index,
4817 # from client to service
4818 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
4819 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
4820 TCP(sport=12345, dport=external_port))
4821 self.pg1.add_stream(p)
4822 self.pg_enable_capture(self.pg_interfaces)
4824 capture = self.pg0.get_capture(1)
4830 self.assertIn(ip.dst, [server1.ip4, server2.ip4])
4831 if ip.dst == server1.ip4:
4835 self.assertEqual(tcp.dport, local_port)
4836 self.assert_packet_checksums_valid(p)
4838 self.logger.error(ppp("Unexpected or invalid packet:", p))
4841 # from service back to client
4842 p = (Ether(src=server.mac, dst=self.pg0.local_mac) /
4843 IP(src=server.ip4, dst=self.pg1.remote_ip4) /
4844 TCP(sport=local_port, dport=12345))
4845 self.pg0.add_stream(p)
4846 self.pg_enable_capture(self.pg_interfaces)
4848 capture = self.pg1.get_capture(1)
4853 self.assertEqual(ip.src, self.nat_addr)
4854 self.assertEqual(tcp.sport, external_port)
4855 self.assert_packet_checksums_valid(p)
4857 self.logger.error(ppp("Unexpected or invalid packet:", p))
4860 sessions = self.vapi.nat44_user_session_dump(server.ip4, 0)
4861 self.assertEqual(len(sessions), 1)
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(server.ip4, 0)
4873 self.assertEqual(len(sessions), 0)
4875 @unittest.skipUnless(running_extended_tests, "part of extended tests")
4876 def test_static_lb_multi_clients(self):
4877 """ NAT44 local service load balancing - multiple clients"""
4879 external_addr = self.nat_addr
4882 server1 = self.pg0.remote_hosts[0]
4883 server2 = self.pg0.remote_hosts[1]
4884 server3 = self.pg0.remote_hosts[2]
4886 locals = [{'addr': server1.ip4,
4890 {'addr': server2.ip4,
4895 self.nat44_add_address(self.nat_addr)
4896 self.vapi.nat44_add_del_lb_static_mapping(is_add=1,
4897 external_addr=external_addr,
4898 external_port=external_port,
4899 protocol=IP_PROTOS.tcp,
4900 local_num=len(locals),
4902 flags = self.config_flags.NAT_IS_INSIDE
4903 self.vapi.nat44_interface_add_del_feature(
4904 sw_if_index=self.pg0.sw_if_index,
4905 flags=flags, is_add=1)
4906 self.vapi.nat44_interface_add_del_feature(
4907 sw_if_index=self.pg1.sw_if_index,
4912 clients = ip4_range(self.pg1.remote_ip4, 10, 50)
4914 for client in clients:
4915 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
4916 IP(src=client, dst=self.nat_addr) /
4917 TCP(sport=12345, dport=external_port))
4919 self.pg1.add_stream(pkts)
4920 self.pg_enable_capture(self.pg_interfaces)
4922 capture = self.pg0.get_capture(len(pkts))
4924 if p[IP].dst == server1.ip4:
4928 self.assertGreater(server1_n, server2_n)
4931 'addr': server3.ip4,
4938 self.vapi.nat44_lb_static_mapping_add_del_local(
4940 external_addr=external_addr,
4941 external_port=external_port,
4943 protocol=IP_PROTOS.tcp)
4947 clients = ip4_range(self.pg1.remote_ip4, 60, 110)
4949 for client in clients:
4950 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
4951 IP(src=client, dst=self.nat_addr) /
4952 TCP(sport=12346, dport=external_port))
4954 self.assertGreater(len(pkts), 0)
4955 self.pg1.add_stream(pkts)
4956 self.pg_enable_capture(self.pg_interfaces)
4958 capture = self.pg0.get_capture(len(pkts))
4960 if p[IP].dst == server1.ip4:
4962 elif p[IP].dst == server2.ip4:
4966 self.assertGreater(server1_n, 0)
4967 self.assertGreater(server2_n, 0)
4968 self.assertGreater(server3_n, 0)
4971 'addr': server2.ip4,
4977 # remove one back-end
4978 self.vapi.nat44_lb_static_mapping_add_del_local(
4980 external_addr=external_addr,
4981 external_port=external_port,
4983 protocol=IP_PROTOS.tcp)
4987 self.pg1.add_stream(pkts)
4988 self.pg_enable_capture(self.pg_interfaces)
4990 capture = self.pg0.get_capture(len(pkts))
4992 if p[IP].dst == server1.ip4:
4994 elif p[IP].dst == server2.ip4:
4998 self.assertGreater(server1_n, 0)
4999 self.assertEqual(server2_n, 0)
5000 self.assertGreater(server3_n, 0)
5002 def test_static_lb_2(self):
5003 """ NAT44 local service load balancing (asymmetrical rule) """
5004 external_addr = self.nat_addr
5007 server1 = self.pg0.remote_hosts[0]
5008 server2 = self.pg0.remote_hosts[1]
5010 locals = [{'addr': server1.ip4,
5014 {'addr': server2.ip4,
5019 self.vapi.nat44_forwarding_enable_disable(enable=1)
5020 flags = self.config_flags.NAT_IS_OUT2IN_ONLY
5021 self.vapi.nat44_add_del_lb_static_mapping(is_add=1, flags=flags,
5022 external_addr=external_addr,
5023 external_port=external_port,
5024 protocol=IP_PROTOS.tcp,
5025 local_num=len(locals),
5027 flags = self.config_flags.NAT_IS_INSIDE
5028 self.vapi.nat44_interface_add_del_feature(
5029 sw_if_index=self.pg0.sw_if_index,
5030 flags=flags, is_add=1)
5031 self.vapi.nat44_interface_add_del_feature(
5032 sw_if_index=self.pg1.sw_if_index,
5035 # from client to service
5036 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
5037 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
5038 TCP(sport=12345, dport=external_port))
5039 self.pg1.add_stream(p)
5040 self.pg_enable_capture(self.pg_interfaces)
5042 capture = self.pg0.get_capture(1)
5048 self.assertIn(ip.dst, [server1.ip4, server2.ip4])
5049 if ip.dst == server1.ip4:
5053 self.assertEqual(tcp.dport, local_port)
5054 self.assert_packet_checksums_valid(p)
5056 self.logger.error(ppp("Unexpected or invalid packet:", p))
5059 # from service back to client
5060 p = (Ether(src=server.mac, dst=self.pg0.local_mac) /
5061 IP(src=server.ip4, dst=self.pg1.remote_ip4) /
5062 TCP(sport=local_port, dport=12345))
5063 self.pg0.add_stream(p)
5064 self.pg_enable_capture(self.pg_interfaces)
5066 capture = self.pg1.get_capture(1)
5071 self.assertEqual(ip.src, self.nat_addr)
5072 self.assertEqual(tcp.sport, external_port)
5073 self.assert_packet_checksums_valid(p)
5075 self.logger.error(ppp("Unexpected or invalid packet:", p))
5078 # from client to server (no translation)
5079 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
5080 IP(src=self.pg1.remote_ip4, dst=server1.ip4) /
5081 TCP(sport=12346, dport=local_port))
5082 self.pg1.add_stream(p)
5083 self.pg_enable_capture(self.pg_interfaces)
5085 capture = self.pg0.get_capture(1)
5091 self.assertEqual(ip.dst, server1.ip4)
5092 self.assertEqual(tcp.dport, local_port)
5093 self.assert_packet_checksums_valid(p)
5095 self.logger.error(ppp("Unexpected or invalid packet:", p))
5098 # from service back to client (no translation)
5099 p = (Ether(src=server1.mac, dst=self.pg0.local_mac) /
5100 IP(src=server1.ip4, dst=self.pg1.remote_ip4) /
5101 TCP(sport=local_port, dport=12346))
5102 self.pg0.add_stream(p)
5103 self.pg_enable_capture(self.pg_interfaces)
5105 capture = self.pg1.get_capture(1)
5110 self.assertEqual(ip.src, server1.ip4)
5111 self.assertEqual(tcp.sport, local_port)
5112 self.assert_packet_checksums_valid(p)
5114 self.logger.error(ppp("Unexpected or invalid packet:", p))
5117 def test_lb_affinity(self):
5118 """ NAT44 local service load balancing affinity """
5119 external_addr = self.nat_addr
5122 server1 = self.pg0.remote_hosts[0]
5123 server2 = self.pg0.remote_hosts[1]
5125 locals = [{'addr': server1.ip4,
5129 {'addr': server2.ip4,
5134 self.nat44_add_address(self.nat_addr)
5135 self.vapi.nat44_add_del_lb_static_mapping(is_add=1,
5136 external_addr=external_addr,
5137 external_port=external_port,
5138 protocol=IP_PROTOS.tcp,
5140 local_num=len(locals),
5142 flags = self.config_flags.NAT_IS_INSIDE
5143 self.vapi.nat44_interface_add_del_feature(
5144 sw_if_index=self.pg0.sw_if_index,
5145 flags=flags, is_add=1)
5146 self.vapi.nat44_interface_add_del_feature(
5147 sw_if_index=self.pg1.sw_if_index,
5150 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
5151 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
5152 TCP(sport=1025, dport=external_port))
5153 self.pg1.add_stream(p)
5154 self.pg_enable_capture(self.pg_interfaces)
5156 capture = self.pg0.get_capture(1)
5157 backend = capture[0][IP].dst
5159 sessions = self.vapi.nat44_user_session_dump(backend, 0)
5160 self.assertEqual(len(sessions), 1)
5161 self.assertTrue(sessions[0].flags &
5162 self.config_flags.NAT_IS_EXT_HOST_VALID)
5163 self.vapi.nat44_del_session(
5164 address=sessions[0].inside_ip_address,
5165 port=sessions[0].inside_port,
5166 protocol=sessions[0].protocol,
5167 flags=(self.config_flags.NAT_IS_INSIDE |
5168 self.config_flags.NAT_IS_EXT_HOST_VALID),
5169 ext_host_address=sessions[0].ext_host_address,
5170 ext_host_port=sessions[0].ext_host_port)
5173 for port in range(1030, 1100):
5174 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
5175 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
5176 TCP(sport=port, dport=external_port))
5178 self.pg1.add_stream(pkts)
5179 self.pg_enable_capture(self.pg_interfaces)
5181 capture = self.pg0.get_capture(len(pkts))
5183 self.assertEqual(p[IP].dst, backend)
5185 def test_unknown_proto(self):
5186 """ NAT44 translate packet with unknown protocol """
5187 self.nat44_add_address(self.nat_addr)
5188 flags = self.config_flags.NAT_IS_INSIDE
5189 self.vapi.nat44_interface_add_del_feature(
5190 sw_if_index=self.pg0.sw_if_index,
5191 flags=flags, is_add=1)
5192 self.vapi.nat44_interface_add_del_feature(
5193 sw_if_index=self.pg1.sw_if_index,
5197 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
5198 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
5199 TCP(sport=self.tcp_port_in, dport=20))
5200 self.pg0.add_stream(p)
5201 self.pg_enable_capture(self.pg_interfaces)
5203 p = self.pg1.get_capture(1)
5205 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
5206 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
5208 IP(src=self.pg2.remote_ip4, dst=self.pg2.remote_ip4) /
5209 TCP(sport=1234, dport=1234))
5210 self.pg0.add_stream(p)
5211 self.pg_enable_capture(self.pg_interfaces)
5213 p = self.pg1.get_capture(1)
5216 self.assertEqual(packet[IP].src, self.nat_addr)
5217 self.assertEqual(packet[IP].dst, self.pg1.remote_ip4)
5218 self.assertEqual(packet.haslayer(GRE), 1)
5219 self.assert_packet_checksums_valid(packet)
5221 self.logger.error(ppp("Unexpected or invalid packet:", packet))
5225 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
5226 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
5228 IP(src=self.pg2.remote_ip4, dst=self.pg2.remote_ip4) /
5229 TCP(sport=1234, dport=1234))
5230 self.pg1.add_stream(p)
5231 self.pg_enable_capture(self.pg_interfaces)
5233 p = self.pg0.get_capture(1)
5236 self.assertEqual(packet[IP].src, self.pg1.remote_ip4)
5237 self.assertEqual(packet[IP].dst, self.pg0.remote_ip4)
5238 self.assertEqual(packet.haslayer(GRE), 1)
5239 self.assert_packet_checksums_valid(packet)
5241 self.logger.error(ppp("Unexpected or invalid packet:", packet))
5244 def test_hairpinning_unknown_proto(self):
5245 """ NAT44 translate packet with unknown protocol - hairpinning """
5246 host = self.pg0.remote_hosts[0]
5247 server = self.pg0.remote_hosts[1]
5249 server_out_port = 8765
5250 server_nat_ip = "10.0.0.11"
5252 self.nat44_add_address(self.nat_addr)
5253 flags = self.config_flags.NAT_IS_INSIDE
5254 self.vapi.nat44_interface_add_del_feature(
5255 sw_if_index=self.pg0.sw_if_index,
5256 flags=flags, is_add=1)
5257 self.vapi.nat44_interface_add_del_feature(
5258 sw_if_index=self.pg1.sw_if_index,
5261 # add static mapping for server
5262 self.nat44_add_static_mapping(server.ip4, server_nat_ip)
5265 p = (Ether(src=host.mac, dst=self.pg0.local_mac) /
5266 IP(src=host.ip4, dst=server_nat_ip) /
5267 TCP(sport=host_in_port, dport=server_out_port))
5268 self.pg0.add_stream(p)
5269 self.pg_enable_capture(self.pg_interfaces)
5271 self.pg0.get_capture(1)
5273 p = (Ether(dst=self.pg0.local_mac, src=host.mac) /
5274 IP(src=host.ip4, dst=server_nat_ip) /
5276 IP(src=self.pg2.remote_ip4, dst=self.pg2.remote_ip4) /
5277 TCP(sport=1234, dport=1234))
5278 self.pg0.add_stream(p)
5279 self.pg_enable_capture(self.pg_interfaces)
5281 p = self.pg0.get_capture(1)
5284 self.assertEqual(packet[IP].src, self.nat_addr)
5285 self.assertEqual(packet[IP].dst, server.ip4)
5286 self.assertEqual(packet.haslayer(GRE), 1)
5287 self.assert_packet_checksums_valid(packet)
5289 self.logger.error(ppp("Unexpected or invalid packet:", packet))
5293 p = (Ether(dst=self.pg0.local_mac, src=server.mac) /
5294 IP(src=server.ip4, dst=self.nat_addr) /
5296 IP(src=self.pg2.remote_ip4, dst=self.pg2.remote_ip4) /
5297 TCP(sport=1234, dport=1234))
5298 self.pg0.add_stream(p)
5299 self.pg_enable_capture(self.pg_interfaces)
5301 p = self.pg0.get_capture(1)
5304 self.assertEqual(packet[IP].src, server_nat_ip)
5305 self.assertEqual(packet[IP].dst, host.ip4)
5306 self.assertEqual(packet.haslayer(GRE), 1)
5307 self.assert_packet_checksums_valid(packet)
5309 self.logger.error(ppp("Unexpected or invalid packet:", packet))
5312 def test_output_feature_and_service(self):
5313 """ NAT44 interface output feature and services """
5314 external_addr = '1.2.3.4'
5318 self.vapi.nat44_forwarding_enable_disable(enable=1)
5319 self.nat44_add_address(self.nat_addr)
5320 flags = self.config_flags.NAT_IS_ADDR_ONLY
5321 self.vapi.nat44_add_del_identity_mapping(
5322 ip_address=self.pg1.remote_ip4, sw_if_index=0xFFFFFFFF,
5323 flags=flags, is_add=1)
5324 flags = self.config_flags.NAT_IS_OUT2IN_ONLY
5325 self.nat44_add_static_mapping(self.pg0.remote_ip4, external_addr,
5326 local_port, external_port,
5327 proto=IP_PROTOS.tcp, flags=flags)
5328 flags = self.config_flags.NAT_IS_INSIDE
5329 self.vapi.nat44_interface_add_del_feature(
5330 sw_if_index=self.pg0.sw_if_index,
5332 self.vapi.nat44_interface_add_del_feature(
5333 sw_if_index=self.pg0.sw_if_index,
5334 flags=flags, is_add=1)
5335 self.vapi.nat44_interface_add_del_output_feature(
5337 sw_if_index=self.pg1.sw_if_index)
5339 # from client to service
5340 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
5341 IP(src=self.pg1.remote_ip4, dst=external_addr) /
5342 TCP(sport=12345, dport=external_port))
5343 self.pg1.add_stream(p)
5344 self.pg_enable_capture(self.pg_interfaces)
5346 capture = self.pg0.get_capture(1)
5351 self.assertEqual(ip.dst, self.pg0.remote_ip4)
5352 self.assertEqual(tcp.dport, local_port)
5353 self.assert_packet_checksums_valid(p)
5355 self.logger.error(ppp("Unexpected or invalid packet:", p))
5358 # from service back to client
5359 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5360 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
5361 TCP(sport=local_port, dport=12345))
5362 self.pg0.add_stream(p)
5363 self.pg_enable_capture(self.pg_interfaces)
5365 capture = self.pg1.get_capture(1)
5370 self.assertEqual(ip.src, external_addr)
5371 self.assertEqual(tcp.sport, external_port)
5372 self.assert_packet_checksums_valid(p)
5374 self.logger.error(ppp("Unexpected or invalid packet:", p))
5377 # from local network host to external network
5378 pkts = self.create_stream_in(self.pg0, self.pg1)
5379 self.pg0.add_stream(pkts)
5380 self.pg_enable_capture(self.pg_interfaces)
5382 capture = self.pg1.get_capture(len(pkts))
5383 self.verify_capture_out(capture, ignore_port=True)
5384 pkts = self.create_stream_in(self.pg0, self.pg1)
5385 self.pg0.add_stream(pkts)
5386 self.pg_enable_capture(self.pg_interfaces)
5388 capture = self.pg1.get_capture(len(pkts))
5389 self.verify_capture_out(capture, ignore_port=True)
5391 # from external network back to local network host
5392 pkts = self.create_stream_out(self.pg1)
5393 self.pg1.add_stream(pkts)
5394 self.pg_enable_capture(self.pg_interfaces)
5396 capture = self.pg0.get_capture(len(pkts))
5397 self.verify_capture_in(capture, self.pg0)
5399 def test_output_feature_and_service2(self):
5400 """ NAT44 interface output feature and service host direct access """
5401 self.vapi.nat44_forwarding_enable_disable(enable=1)
5402 self.nat44_add_address(self.nat_addr)
5403 self.vapi.nat44_interface_add_del_output_feature(
5405 sw_if_index=self.pg1.sw_if_index)
5407 # session initiated from service host - translate
5408 pkts = self.create_stream_in(self.pg0, self.pg1)
5409 self.pg0.add_stream(pkts)
5410 self.pg_enable_capture(self.pg_interfaces)
5412 capture = self.pg1.get_capture(len(pkts))
5413 self.verify_capture_out(capture, ignore_port=True)
5415 pkts = self.create_stream_out(self.pg1)
5416 self.pg1.add_stream(pkts)
5417 self.pg_enable_capture(self.pg_interfaces)
5419 capture = self.pg0.get_capture(len(pkts))
5420 self.verify_capture_in(capture, self.pg0)
5422 # session initiated from remote host - do not translate
5423 self.tcp_port_in = 60303
5424 self.udp_port_in = 60304
5425 self.icmp_id_in = 60305
5426 pkts = self.create_stream_out(self.pg1,
5427 self.pg0.remote_ip4,
5428 use_inside_ports=True)
5429 self.pg1.add_stream(pkts)
5430 self.pg_enable_capture(self.pg_interfaces)
5432 capture = self.pg0.get_capture(len(pkts))
5433 self.verify_capture_in(capture, self.pg0)
5435 pkts = self.create_stream_in(self.pg0, self.pg1)
5436 self.pg0.add_stream(pkts)
5437 self.pg_enable_capture(self.pg_interfaces)
5439 capture = self.pg1.get_capture(len(pkts))
5440 self.verify_capture_out(capture, nat_ip=self.pg0.remote_ip4,
5443 def test_output_feature_and_service3(self):
5444 """ NAT44 interface output feature and DST NAT """
5445 external_addr = '1.2.3.4'
5449 self.vapi.nat44_forwarding_enable_disable(enable=1)
5450 self.nat44_add_address(self.nat_addr)
5451 flags = self.config_flags.NAT_IS_OUT2IN_ONLY
5452 self.nat44_add_static_mapping(self.pg1.remote_ip4, external_addr,
5453 local_port, external_port,
5454 proto=IP_PROTOS.tcp, flags=flags)
5455 flags = self.config_flags.NAT_IS_INSIDE
5456 self.vapi.nat44_interface_add_del_feature(
5457 sw_if_index=self.pg0.sw_if_index,
5459 self.vapi.nat44_interface_add_del_feature(
5460 sw_if_index=self.pg0.sw_if_index,
5461 flags=flags, is_add=1)
5462 self.vapi.nat44_interface_add_del_output_feature(
5464 sw_if_index=self.pg1.sw_if_index)
5466 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5467 IP(src=self.pg0.remote_ip4, dst=external_addr) /
5468 TCP(sport=12345, dport=external_port))
5469 self.pg0.add_stream(p)
5470 self.pg_enable_capture(self.pg_interfaces)
5472 capture = self.pg1.get_capture(1)
5477 self.assertEqual(ip.src, self.pg0.remote_ip4)
5478 self.assertEqual(tcp.sport, 12345)
5479 self.assertEqual(ip.dst, self.pg1.remote_ip4)
5480 self.assertEqual(tcp.dport, local_port)
5481 self.assert_packet_checksums_valid(p)
5483 self.logger.error(ppp("Unexpected or invalid packet:", p))
5486 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
5487 IP(src=self.pg1.remote_ip4, dst=self.pg0.remote_ip4) /
5488 TCP(sport=local_port, dport=12345))
5489 self.pg1.add_stream(p)
5490 self.pg_enable_capture(self.pg_interfaces)
5492 capture = self.pg0.get_capture(1)
5497 self.assertEqual(ip.src, external_addr)
5498 self.assertEqual(tcp.sport, external_port)
5499 self.assertEqual(ip.dst, self.pg0.remote_ip4)
5500 self.assertEqual(tcp.dport, 12345)
5501 self.assert_packet_checksums_valid(p)
5503 self.logger.error(ppp("Unexpected or invalid packet:", p))
5506 def test_next_src_nat(self):
5507 """ On way back forward packet to nat44-in2out node. """
5508 twice_nat_addr = '10.0.1.3'
5511 post_twice_nat_port = 0
5513 self.vapi.nat44_forwarding_enable_disable(enable=1)
5514 self.nat44_add_address(twice_nat_addr, twice_nat=1)
5515 flags = (self.config_flags.NAT_IS_OUT2IN_ONLY |
5516 self.config_flags.NAT_IS_SELF_TWICE_NAT)
5517 self.nat44_add_static_mapping(self.pg6.remote_ip4, self.pg1.remote_ip4,
5518 local_port, external_port,
5519 proto=IP_PROTOS.tcp, vrf_id=1,
5521 self.vapi.nat44_interface_add_del_feature(
5522 sw_if_index=self.pg6.sw_if_index,
5525 p = (Ether(src=self.pg6.remote_mac, dst=self.pg6.local_mac) /
5526 IP(src=self.pg6.remote_ip4, dst=self.pg1.remote_ip4) /
5527 TCP(sport=12345, dport=external_port))
5528 self.pg6.add_stream(p)
5529 self.pg_enable_capture(self.pg_interfaces)
5531 capture = self.pg6.get_capture(1)
5536 self.assertEqual(ip.src, twice_nat_addr)
5537 self.assertNotEqual(tcp.sport, 12345)
5538 post_twice_nat_port = tcp.sport
5539 self.assertEqual(ip.dst, self.pg6.remote_ip4)
5540 self.assertEqual(tcp.dport, local_port)
5541 self.assert_packet_checksums_valid(p)
5543 self.logger.error(ppp("Unexpected or invalid packet:", p))
5546 p = (Ether(src=self.pg6.remote_mac, dst=self.pg6.local_mac) /
5547 IP(src=self.pg6.remote_ip4, dst=twice_nat_addr) /
5548 TCP(sport=local_port, dport=post_twice_nat_port))
5549 self.pg6.add_stream(p)
5550 self.pg_enable_capture(self.pg_interfaces)
5552 capture = self.pg6.get_capture(1)
5557 self.assertEqual(ip.src, self.pg1.remote_ip4)
5558 self.assertEqual(tcp.sport, external_port)
5559 self.assertEqual(ip.dst, self.pg6.remote_ip4)
5560 self.assertEqual(tcp.dport, 12345)
5561 self.assert_packet_checksums_valid(p)
5563 self.logger.error(ppp("Unexpected or invalid packet:", p))
5566 def twice_nat_common(self, self_twice_nat=False, same_pg=False, lb=False,
5568 twice_nat_addr = '10.0.1.3'
5576 port_in1 = port_in + 1
5577 port_in2 = port_in + 2
5582 server1 = self.pg0.remote_hosts[0]
5583 server2 = self.pg0.remote_hosts[1]
5595 eh_translate = ((not self_twice_nat) or (not lb and same_pg) or
5598 self.nat44_add_address(self.nat_addr)
5599 self.nat44_add_address(twice_nat_addr, twice_nat=1)
5603 flags |= self.config_flags.NAT_IS_SELF_TWICE_NAT
5605 flags |= self.config_flags.NAT_IS_TWICE_NAT
5608 self.nat44_add_static_mapping(pg0.remote_ip4, self.nat_addr,
5610 proto=IP_PROTOS.tcp,
5613 locals = [{'addr': server1.ip4,
5617 {'addr': server2.ip4,
5621 out_addr = self.nat_addr
5623 self.vapi.nat44_add_del_lb_static_mapping(is_add=1, flags=flags,
5624 external_addr=out_addr,
5625 external_port=port_out,
5626 protocol=IP_PROTOS.tcp,
5627 local_num=len(locals),
5629 flags = self.config_flags.NAT_IS_INSIDE
5630 self.vapi.nat44_interface_add_del_feature(
5631 sw_if_index=pg0.sw_if_index,
5632 flags=flags, is_add=1)
5633 self.vapi.nat44_interface_add_del_feature(
5634 sw_if_index=pg1.sw_if_index,
5641 assert client_id is not None
5643 client = self.pg0.remote_hosts[0]
5644 elif client_id == 2:
5645 client = self.pg0.remote_hosts[1]
5647 client = pg1.remote_hosts[0]
5648 p = (Ether(src=pg1.remote_mac, dst=pg1.local_mac) /
5649 IP(src=client.ip4, dst=self.nat_addr) /
5650 TCP(sport=eh_port_out, dport=port_out))
5652 self.pg_enable_capture(self.pg_interfaces)
5654 capture = pg0.get_capture(1)
5660 if ip.dst == server1.ip4:
5666 self.assertEqual(ip.dst, server.ip4)
5668 self.assertIn(tcp.dport, [port_in1, port_in2])
5670 self.assertEqual(tcp.dport, port_in)
5672 self.assertEqual(ip.src, twice_nat_addr)
5673 self.assertNotEqual(tcp.sport, eh_port_out)
5675 self.assertEqual(ip.src, client.ip4)
5676 self.assertEqual(tcp.sport, eh_port_out)
5678 eh_port_in = tcp.sport
5679 saved_port_in = tcp.dport
5680 self.assert_packet_checksums_valid(p)
5682 self.logger.error(ppp("Unexpected or invalid packet:", p))
5685 p = (Ether(src=server.mac, dst=pg0.local_mac) /
5686 IP(src=server.ip4, dst=eh_addr_in) /
5687 TCP(sport=saved_port_in, dport=eh_port_in))
5689 self.pg_enable_capture(self.pg_interfaces)
5691 capture = pg1.get_capture(1)
5696 self.assertEqual(ip.dst, client.ip4)
5697 self.assertEqual(ip.src, self.nat_addr)
5698 self.assertEqual(tcp.dport, eh_port_out)
5699 self.assertEqual(tcp.sport, port_out)
5700 self.assert_packet_checksums_valid(p)
5702 self.logger.error(ppp("Unexpected or invalid packet:", p))
5706 sessions = self.vapi.nat44_user_session_dump(server.ip4, 0)
5707 self.assertEqual(len(sessions), 1)
5708 self.assertTrue(sessions[0].flags &
5709 self.config_flags.NAT_IS_EXT_HOST_VALID)
5710 self.assertTrue(sessions[0].flags &
5711 self.config_flags.NAT_IS_TWICE_NAT)
5712 self.logger.info(self.vapi.cli("show nat44 sessions detail"))
5713 self.vapi.nat44_del_session(
5714 address=sessions[0].inside_ip_address,
5715 port=sessions[0].inside_port,
5716 protocol=sessions[0].protocol,
5717 flags=(self.config_flags.NAT_IS_INSIDE |
5718 self.config_flags.NAT_IS_EXT_HOST_VALID),
5719 ext_host_address=sessions[0].ext_host_nat_address,
5720 ext_host_port=sessions[0].ext_host_nat_port)
5721 sessions = self.vapi.nat44_user_session_dump(server.ip4, 0)
5722 self.assertEqual(len(sessions), 0)
5724 def test_twice_nat(self):
5726 self.twice_nat_common()
5728 def test_self_twice_nat_positive(self):
5729 """ Self Twice NAT44 (positive test) """
5730 self.twice_nat_common(self_twice_nat=True, same_pg=True)
5732 def test_self_twice_nat_negative(self):
5733 """ Self Twice NAT44 (negative test) """
5734 self.twice_nat_common(self_twice_nat=True)
5736 def test_twice_nat_lb(self):
5737 """ Twice NAT44 local service load balancing """
5738 self.twice_nat_common(lb=True)
5740 def test_self_twice_nat_lb_positive(self):
5741 """ Self Twice NAT44 local service load balancing (positive test) """
5742 self.twice_nat_common(lb=True, self_twice_nat=True, same_pg=True,
5745 def test_self_twice_nat_lb_negative(self):
5746 """ Self Twice NAT44 local service load balancing (negative test) """
5747 self.twice_nat_common(lb=True, self_twice_nat=True, same_pg=True,
5750 def test_twice_nat_interface_addr(self):
5751 """ Acquire twice NAT44 addresses from interface """
5752 flags = self.config_flags.NAT_IS_TWICE_NAT
5753 self.vapi.nat44_add_del_interface_addr(
5755 sw_if_index=self.pg3.sw_if_index,
5758 # no address in NAT pool
5759 adresses = self.vapi.nat44_address_dump()
5760 self.assertEqual(0, len(adresses))
5762 # configure interface address and check NAT address pool
5763 self.pg3.config_ip4()
5764 adresses = self.vapi.nat44_address_dump()
5765 self.assertEqual(1, len(adresses))
5766 self.assertEqual(str(adresses[0].ip_address),
5768 self.assertEqual(adresses[0].flags, flags)
5770 # remove interface address and check NAT address pool
5771 self.pg3.unconfig_ip4()
5772 adresses = self.vapi.nat44_address_dump()
5773 self.assertEqual(0, len(adresses))
5775 def test_tcp_close(self):
5776 """ Close TCP session from inside network - output feature """
5777 self.vapi.nat44_forwarding_enable_disable(enable=1)
5778 self.nat44_add_address(self.pg1.local_ip4)
5779 twice_nat_addr = '10.0.1.3'
5780 service_ip = '192.168.16.150'
5781 self.nat44_add_address(twice_nat_addr, twice_nat=1)
5782 flags = self.config_flags.NAT_IS_INSIDE
5783 self.vapi.nat44_interface_add_del_feature(
5784 sw_if_index=self.pg0.sw_if_index,
5786 self.vapi.nat44_interface_add_del_feature(
5787 sw_if_index=self.pg0.sw_if_index,
5788 flags=flags, is_add=1)
5789 self.vapi.nat44_interface_add_del_output_feature(
5791 sw_if_index=self.pg1.sw_if_index)
5792 flags = (self.config_flags.NAT_IS_OUT2IN_ONLY |
5793 self.config_flags.NAT_IS_TWICE_NAT)
5794 self.nat44_add_static_mapping(self.pg0.remote_ip4,
5798 proto=IP_PROTOS.tcp,
5800 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4, 0)
5801 start_sessnum = len(sessions)
5803 # SYN packet out->in
5804 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
5805 IP(src=self.pg1.remote_ip4, dst=service_ip) /
5806 TCP(sport=33898, dport=80, flags="S"))
5807 self.pg1.add_stream(p)
5808 self.pg_enable_capture(self.pg_interfaces)
5810 capture = self.pg0.get_capture(1)
5812 tcp_port = p[TCP].sport
5814 # SYN + ACK packet in->out
5815 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5816 IP(src=self.pg0.remote_ip4, dst=twice_nat_addr) /
5817 TCP(sport=80, dport=tcp_port, flags="SA"))
5818 self.pg0.add_stream(p)
5819 self.pg_enable_capture(self.pg_interfaces)
5821 self.pg1.get_capture(1)
5823 # ACK packet out->in
5824 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
5825 IP(src=self.pg1.remote_ip4, dst=service_ip) /
5826 TCP(sport=33898, dport=80, flags="A"))
5827 self.pg1.add_stream(p)
5828 self.pg_enable_capture(self.pg_interfaces)
5830 self.pg0.get_capture(1)
5832 # FIN packet in -> out
5833 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5834 IP(src=self.pg0.remote_ip4, dst=twice_nat_addr) /
5835 TCP(sport=80, dport=tcp_port, flags="FA", seq=100, ack=300))
5836 self.pg0.add_stream(p)
5837 self.pg_enable_capture(self.pg_interfaces)
5839 self.pg1.get_capture(1)
5841 # FIN+ACK packet out -> in
5842 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
5843 IP(src=self.pg1.remote_ip4, dst=service_ip) /
5844 TCP(sport=33898, dport=80, flags="FA", seq=300, ack=101))
5845 self.pg1.add_stream(p)
5846 self.pg_enable_capture(self.pg_interfaces)
5848 self.pg0.get_capture(1)
5850 # ACK packet in -> out
5851 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5852 IP(src=self.pg0.remote_ip4, dst=twice_nat_addr) /
5853 TCP(sport=80, dport=tcp_port, flags="A", seq=101, ack=301))
5854 self.pg0.add_stream(p)
5855 self.pg_enable_capture(self.pg_interfaces)
5857 self.pg1.get_capture(1)
5859 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4,
5861 self.assertEqual(len(sessions) - start_sessnum, 0)
5863 def test_tcp_session_close_in(self):
5864 """ Close TCP session from inside network """
5865 self.tcp_port_out = 10505
5866 self.nat44_add_address(self.nat_addr)
5867 flags = self.config_flags.NAT_IS_TWICE_NAT
5868 self.nat44_add_static_mapping(self.pg0.remote_ip4,
5872 proto=IP_PROTOS.tcp,
5874 flags = self.config_flags.NAT_IS_INSIDE
5875 self.vapi.nat44_interface_add_del_feature(
5876 sw_if_index=self.pg0.sw_if_index,
5877 flags=flags, is_add=1)
5878 self.vapi.nat44_interface_add_del_feature(
5879 sw_if_index=self.pg1.sw_if_index,
5882 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4, 0)
5883 start_sessnum = len(sessions)
5885 self.vapi.nat_set_timeouts(udp=300, tcp_established=7440,
5886 tcp_transitory=2, icmp=5)
5888 self.initiate_tcp_session(self.pg0, self.pg1)
5890 # FIN packet in -> out
5891 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5892 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
5893 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
5894 flags="FA", seq=100, ack=300))
5895 self.pg0.add_stream(p)
5896 self.pg_enable_capture(self.pg_interfaces)
5898 self.pg1.get_capture(1)
5902 # ACK packet out -> in
5903 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
5904 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
5905 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
5906 flags="A", seq=300, ack=101))
5909 # FIN packet out -> in
5910 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
5911 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
5912 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
5913 flags="FA", seq=300, ack=101))
5916 self.pg1.add_stream(pkts)
5917 self.pg_enable_capture(self.pg_interfaces)
5919 self.pg0.get_capture(2)
5921 # ACK packet in -> out
5922 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5923 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
5924 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
5925 flags="A", seq=101, ack=301))
5926 self.pg0.add_stream(p)
5927 self.pg_enable_capture(self.pg_interfaces)
5929 self.pg1.get_capture(1)
5931 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4, 0)
5932 self.assertEqual(len(sessions) - start_sessnum, 1)
5934 stats = self.statistics.get_counter(
5935 '/err/nat44-ed-out2in/drops due to TCP in transitory timeout')
5936 out2in_drops = stats[0]
5937 stats = self.statistics.get_counter(
5938 '/err/nat44-ed-in2out/drops due to TCP in transitory timeout')
5939 in2out_drops = stats[0]
5941 # extra FIN packet out -> in - this should be dropped
5942 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
5943 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
5944 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
5945 flags="FA", seq=300, ack=101))
5947 self.pg1.add_stream(p)
5948 self.pg_enable_capture(self.pg_interfaces)
5950 self.pg0.assert_nothing_captured()
5952 # extra ACK packet in -> out - this should be dropped
5953 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5954 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
5955 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
5956 flags="A", seq=101, ack=301))
5957 self.pg0.add_stream(p)
5958 self.pg_enable_capture(self.pg_interfaces)
5960 self.pg1.assert_nothing_captured()
5962 stats = self.statistics.get_counter(
5963 '/err/nat44-ed-out2in/drops due to TCP in transitory timeout')
5964 self.assertEqual(stats[0] - out2in_drops, 1)
5965 stats = self.statistics.get_counter(
5966 '/err/nat44-ed-in2out/drops due to TCP in transitory timeout')
5967 self.assertEqual(stats[0] - in2out_drops, 1)
5970 # extra ACK packet in -> out - this will cause session to be wiped
5971 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5972 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
5973 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
5974 flags="A", seq=101, ack=301))
5975 self.pg0.add_stream(p)
5976 self.pg_enable_capture(self.pg_interfaces)
5978 self.pg1.assert_nothing_captured()
5979 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4, 0)
5980 self.assertEqual(len(sessions) - start_sessnum, 0)
5982 def test_tcp_session_close_out(self):
5983 """ Close TCP session from outside network """
5984 self.tcp_port_out = 10505
5985 self.nat44_add_address(self.nat_addr)
5986 flags = self.config_flags.NAT_IS_TWICE_NAT
5987 self.nat44_add_static_mapping(self.pg0.remote_ip4,
5991 proto=IP_PROTOS.tcp,
5993 flags = self.config_flags.NAT_IS_INSIDE
5994 self.vapi.nat44_interface_add_del_feature(
5995 sw_if_index=self.pg0.sw_if_index,
5996 flags=flags, is_add=1)
5997 self.vapi.nat44_interface_add_del_feature(
5998 sw_if_index=self.pg1.sw_if_index,
6001 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4, 0)
6002 start_sessnum = len(sessions)
6004 self.vapi.nat_set_timeouts(udp=300, tcp_established=7440,
6005 tcp_transitory=2, icmp=5)
6007 self.initiate_tcp_session(self.pg0, self.pg1)
6009 # FIN packet out -> in
6010 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
6011 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
6012 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
6013 flags="FA", seq=100, ack=300))
6014 self.pg1.add_stream(p)
6015 self.pg_enable_capture(self.pg_interfaces)
6017 self.pg0.get_capture(1)
6019 # FIN+ACK packet in -> out
6020 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6021 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6022 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
6023 flags="FA", seq=300, ack=101))
6025 self.pg0.add_stream(p)
6026 self.pg_enable_capture(self.pg_interfaces)
6028 self.pg1.get_capture(1)
6030 # ACK packet out -> in
6031 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
6032 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
6033 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
6034 flags="A", seq=101, ack=301))
6035 self.pg1.add_stream(p)
6036 self.pg_enable_capture(self.pg_interfaces)
6038 self.pg0.get_capture(1)
6040 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4, 0)
6041 self.assertEqual(len(sessions) - start_sessnum, 1)
6043 stats = self.statistics.get_counter(
6044 '/err/nat44-ed-out2in/drops due to TCP in transitory timeout')
6045 out2in_drops = stats[0]
6046 stats = self.statistics.get_counter(
6047 '/err/nat44-ed-in2out/drops due to TCP in transitory timeout')
6048 in2out_drops = stats[0]
6050 # extra FIN packet out -> in - this should be dropped
6051 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
6052 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
6053 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
6054 flags="FA", seq=300, ack=101))
6056 self.pg1.add_stream(p)
6057 self.pg_enable_capture(self.pg_interfaces)
6059 self.pg0.assert_nothing_captured()
6061 # extra ACK packet in -> out - this should be dropped
6062 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6063 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6064 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
6065 flags="A", seq=101, ack=301))
6066 self.pg0.add_stream(p)
6067 self.pg_enable_capture(self.pg_interfaces)
6069 self.pg1.assert_nothing_captured()
6071 stats = self.statistics.get_counter(
6072 '/err/nat44-ed-out2in/drops due to TCP in transitory timeout')
6073 self.assertEqual(stats[0] - out2in_drops, 1)
6074 stats = self.statistics.get_counter(
6075 '/err/nat44-ed-in2out/drops due to TCP in transitory timeout')
6076 self.assertEqual(stats[0] - in2out_drops, 1)
6079 # extra ACK packet in -> out - this will cause session to be wiped
6080 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6081 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6082 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
6083 flags="A", seq=101, ack=301))
6084 self.pg0.add_stream(p)
6085 self.pg_enable_capture(self.pg_interfaces)
6087 self.pg1.assert_nothing_captured()
6088 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4, 0)
6089 self.assertEqual(len(sessions) - start_sessnum, 0)
6091 def test_tcp_session_close_simultaneous(self):
6092 """ Close TCP session from inside network """
6093 self.tcp_port_out = 10505
6094 self.nat44_add_address(self.nat_addr)
6095 flags = self.config_flags.NAT_IS_TWICE_NAT
6096 self.nat44_add_static_mapping(self.pg0.remote_ip4,
6100 proto=IP_PROTOS.tcp,
6102 flags = self.config_flags.NAT_IS_INSIDE
6103 self.vapi.nat44_interface_add_del_feature(
6104 sw_if_index=self.pg0.sw_if_index,
6105 flags=flags, is_add=1)
6106 self.vapi.nat44_interface_add_del_feature(
6107 sw_if_index=self.pg1.sw_if_index,
6110 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4, 0)
6111 start_sessnum = len(sessions)
6113 self.vapi.nat_set_timeouts(udp=300, tcp_established=7440,
6114 tcp_transitory=2, icmp=5)
6116 self.initiate_tcp_session(self.pg0, self.pg1)
6118 # FIN packet in -> out
6119 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6120 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6121 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
6122 flags="FA", seq=100, ack=300))
6123 self.pg0.add_stream(p)
6124 self.pg_enable_capture(self.pg_interfaces)
6126 self.pg1.get_capture(1)
6128 # FIN packet out -> in
6129 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
6130 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
6131 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
6132 flags="FA", seq=300, ack=100))
6133 self.pg1.add_stream(p)
6134 self.pg_enable_capture(self.pg_interfaces)
6136 self.pg0.get_capture(1)
6138 # ACK packet in -> out
6139 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6140 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6141 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
6142 flags="A", seq=101, ack=301))
6143 self.pg0.add_stream(p)
6144 self.pg_enable_capture(self.pg_interfaces)
6146 self.pg1.get_capture(1)
6148 # ACK packet out -> in
6149 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
6150 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
6151 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
6152 flags="A", seq=301, ack=101))
6153 self.pg1.add_stream(p)
6154 self.pg_enable_capture(self.pg_interfaces)
6156 self.pg0.get_capture(1)
6158 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4, 0)
6159 self.assertEqual(len(sessions) - start_sessnum, 1)
6161 stats = self.statistics.get_counter(
6162 '/err/nat44-ed-out2in/drops due to TCP in transitory timeout')
6163 out2in_drops = stats[0]
6164 stats = self.statistics.get_counter(
6165 '/err/nat44-ed-in2out/drops due to TCP in transitory timeout')
6166 in2out_drops = stats[0]
6168 # extra FIN packet out -> in - this should be dropped
6169 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
6170 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
6171 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
6172 flags="FA", seq=300, ack=101))
6174 self.pg1.add_stream(p)
6175 self.pg_enable_capture(self.pg_interfaces)
6177 self.pg0.assert_nothing_captured()
6179 # extra ACK packet in -> out - this should be dropped
6180 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6181 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6182 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
6183 flags="A", seq=101, ack=301))
6184 self.pg0.add_stream(p)
6185 self.pg_enable_capture(self.pg_interfaces)
6187 self.pg1.assert_nothing_captured()
6189 stats = self.statistics.get_counter(
6190 '/err/nat44-ed-out2in/drops due to TCP in transitory timeout')
6191 self.assertEqual(stats[0] - out2in_drops, 1)
6192 stats = self.statistics.get_counter(
6193 '/err/nat44-ed-in2out/drops due to TCP in transitory timeout')
6194 self.assertEqual(stats[0] - in2out_drops, 1)
6197 # extra ACK packet in -> out - this will cause session to be wiped
6198 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6199 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6200 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
6201 flags="A", seq=101, ack=301))
6202 self.pg0.add_stream(p)
6203 self.pg_enable_capture(self.pg_interfaces)
6205 self.pg1.assert_nothing_captured()
6206 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4, 0)
6207 self.assertEqual(len(sessions) - start_sessnum, 0)
6209 def test_one_armed_nat44_static(self):
6210 """ One armed NAT44 and 1:1 NAPT asymmetrical rule """
6211 remote_host = self.pg4.remote_hosts[0]
6212 local_host = self.pg4.remote_hosts[1]
6217 self.vapi.nat44_forwarding_enable_disable(enable=1)
6218 self.nat44_add_address(self.nat_addr, twice_nat=1)
6219 flags = (self.config_flags.NAT_IS_OUT2IN_ONLY |
6220 self.config_flags.NAT_IS_TWICE_NAT)
6221 self.nat44_add_static_mapping(local_host.ip4, self.nat_addr,
6222 local_port, external_port,
6223 proto=IP_PROTOS.tcp, flags=flags)
6224 flags = self.config_flags.NAT_IS_INSIDE
6225 self.vapi.nat44_interface_add_del_feature(
6226 sw_if_index=self.pg4.sw_if_index,
6228 self.vapi.nat44_interface_add_del_feature(
6229 sw_if_index=self.pg4.sw_if_index,
6230 flags=flags, is_add=1)
6232 # from client to service
6233 p = (Ether(src=self.pg4.remote_mac, dst=self.pg4.local_mac) /
6234 IP(src=remote_host.ip4, dst=self.nat_addr) /
6235 TCP(sport=12345, dport=external_port))
6236 self.pg4.add_stream(p)
6237 self.pg_enable_capture(self.pg_interfaces)
6239 capture = self.pg4.get_capture(1)
6244 self.assertEqual(ip.dst, local_host.ip4)
6245 self.assertEqual(ip.src, self.nat_addr)
6246 self.assertEqual(tcp.dport, local_port)
6247 self.assertNotEqual(tcp.sport, 12345)
6248 eh_port_in = tcp.sport
6249 self.assert_packet_checksums_valid(p)
6251 self.logger.error(ppp("Unexpected or invalid packet:", p))
6254 # from service back to client
6255 p = (Ether(src=self.pg4.remote_mac, dst=self.pg4.local_mac) /
6256 IP(src=local_host.ip4, dst=self.nat_addr) /
6257 TCP(sport=local_port, dport=eh_port_in))
6258 self.pg4.add_stream(p)
6259 self.pg_enable_capture(self.pg_interfaces)
6261 capture = self.pg4.get_capture(1)
6266 self.assertEqual(ip.src, self.nat_addr)
6267 self.assertEqual(ip.dst, remote_host.ip4)
6268 self.assertEqual(tcp.sport, external_port)
6269 self.assertEqual(tcp.dport, 12345)
6270 self.assert_packet_checksums_valid(p)
6272 self.logger.error(ppp("Unexpected or invalid packet:", p))
6275 def test_static_with_port_out2(self):
6276 """ 1:1 NAPT asymmetrical rule """
6281 self.vapi.nat44_forwarding_enable_disable(enable=1)
6282 flags = self.config_flags.NAT_IS_OUT2IN_ONLY
6283 self.nat44_add_static_mapping(self.pg0.remote_ip4, self.nat_addr,
6284 local_port, external_port,
6285 proto=IP_PROTOS.tcp, flags=flags)
6286 flags = self.config_flags.NAT_IS_INSIDE
6287 self.vapi.nat44_interface_add_del_feature(
6288 sw_if_index=self.pg0.sw_if_index,
6289 flags=flags, is_add=1)
6290 self.vapi.nat44_interface_add_del_feature(
6291 sw_if_index=self.pg1.sw_if_index,
6294 # from client to service
6295 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
6296 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
6297 TCP(sport=12345, dport=external_port))
6298 self.pg1.add_stream(p)
6299 self.pg_enable_capture(self.pg_interfaces)
6301 capture = self.pg0.get_capture(1)
6306 self.assertEqual(ip.dst, self.pg0.remote_ip4)
6307 self.assertEqual(tcp.dport, local_port)
6308 self.assert_packet_checksums_valid(p)
6310 self.logger.error(ppp("Unexpected or invalid packet:", p))
6314 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
6315 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6316 ICMP(type=11) / capture[0][IP])
6317 self.pg0.add_stream(p)
6318 self.pg_enable_capture(self.pg_interfaces)
6320 capture = self.pg1.get_capture(1)
6323 self.assertEqual(p[IP].src, self.nat_addr)
6325 self.assertEqual(inner.dst, self.nat_addr)
6326 self.assertEqual(inner[TCPerror].dport, external_port)
6328 self.logger.error(ppp("Unexpected or invalid packet:", p))
6331 # from service back to client
6332 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6333 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6334 TCP(sport=local_port, dport=12345))
6335 self.pg0.add_stream(p)
6336 self.pg_enable_capture(self.pg_interfaces)
6338 capture = self.pg1.get_capture(1)
6343 self.assertEqual(ip.src, self.nat_addr)
6344 self.assertEqual(tcp.sport, external_port)
6345 self.assert_packet_checksums_valid(p)
6347 self.logger.error(ppp("Unexpected or invalid packet:", p))
6351 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
6352 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
6353 ICMP(type=11) / capture[0][IP])
6354 self.pg1.add_stream(p)
6355 self.pg_enable_capture(self.pg_interfaces)
6357 capture = self.pg0.get_capture(1)
6360 self.assertEqual(p[IP].dst, self.pg0.remote_ip4)
6362 self.assertEqual(inner.src, self.pg0.remote_ip4)
6363 self.assertEqual(inner[TCPerror].sport, local_port)
6365 self.logger.error(ppp("Unexpected or invalid packet:", p))
6368 # from client to server (no translation)
6369 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
6370 IP(src=self.pg1.remote_ip4, dst=self.pg0.remote_ip4) /
6371 TCP(sport=12346, dport=local_port))
6372 self.pg1.add_stream(p)
6373 self.pg_enable_capture(self.pg_interfaces)
6375 capture = self.pg0.get_capture(1)
6380 self.assertEqual(ip.dst, self.pg0.remote_ip4)
6381 self.assertEqual(tcp.dport, local_port)
6382 self.assert_packet_checksums_valid(p)
6384 self.logger.error(ppp("Unexpected or invalid packet:", p))
6387 # from service back to client (no translation)
6388 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6389 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6390 TCP(sport=local_port, dport=12346))
6391 self.pg0.add_stream(p)
6392 self.pg_enable_capture(self.pg_interfaces)
6394 capture = self.pg1.get_capture(1)
6399 self.assertEqual(ip.src, self.pg0.remote_ip4)
6400 self.assertEqual(tcp.sport, local_port)
6401 self.assert_packet_checksums_valid(p)
6403 self.logger.error(ppp("Unexpected or invalid packet:", p))
6406 def test_output_feature(self):
6407 """ NAT44 interface output feature (in2out postrouting) """
6408 self.vapi.nat44_forwarding_enable_disable(enable=1)
6409 self.nat44_add_address(self.nat_addr)
6410 self.vapi.nat44_interface_add_del_feature(
6411 sw_if_index=self.pg0.sw_if_index,
6413 self.vapi.nat44_interface_add_del_output_feature(
6415 sw_if_index=self.pg1.sw_if_index)
6418 pkts = self.create_stream_in(self.pg0, self.pg1)
6419 self.pg0.add_stream(pkts)
6420 self.pg_enable_capture(self.pg_interfaces)
6422 capture = self.pg1.get_capture(len(pkts))
6423 self.verify_capture_out(capture, ignore_port=True)
6426 pkts = self.create_stream_out(self.pg1)
6427 self.pg1.add_stream(pkts)
6428 self.pg_enable_capture(self.pg_interfaces)
6430 capture = self.pg0.get_capture(len(pkts))
6431 self.verify_capture_in(capture, self.pg0)
6433 def test_output_feature_stateful_acl(self):
6434 """ NAT44 endpoint-dependent output feature works with stateful ACL """
6435 self.nat44_add_address(self.nat_addr)
6436 self.vapi.nat44_interface_add_del_output_feature(
6437 sw_if_index=self.pg0.sw_if_index,
6438 flags=self.config_flags.NAT_IS_INSIDE,
6440 self.vapi.nat44_interface_add_del_output_feature(
6441 sw_if_index=self.pg1.sw_if_index,
6442 flags=self.config_flags.NAT_IS_OUTSIDE,
6445 # First ensure that the NAT is working sans ACL
6447 # send packets out2in, no sessions yet so packets should drop
6448 pkts_out2in = self.create_stream_out(self.pg1)
6449 self.send_and_assert_no_replies(self.pg1, pkts_out2in)
6451 # send packets into inside intf, ensure received via outside intf
6452 pkts_in2out = self.create_stream_in(self.pg0, self.pg1)
6453 capture = self.send_and_expect(self.pg0, pkts_in2out, self.pg1,
6455 self.verify_capture_out(capture, ignore_port=True)
6457 # send out2in again, with sessions created it should work now
6458 pkts_out2in = self.create_stream_out(self.pg1)
6459 capture = self.send_and_expect(self.pg1, pkts_out2in, self.pg0,
6461 self.verify_capture_in(capture, self.pg0)
6463 # Create an ACL blocking everything
6464 out2in_deny_rule = AclRule(is_permit=0)
6465 out2in_acl = VppAcl(self, rules=[out2in_deny_rule])
6466 out2in_acl.add_vpp_config()
6468 # create an ACL to permit/reflect everything
6469 in2out_reflect_rule = AclRule(is_permit=2)
6470 in2out_acl = VppAcl(self, rules=[in2out_reflect_rule])
6471 in2out_acl.add_vpp_config()
6473 # apply as input acl on interface and confirm it blocks everything
6474 acl_if = VppAclInterface(self, sw_if_index=self.pg1.sw_if_index,
6475 n_input=1, acls=[out2in_acl])
6476 acl_if.add_vpp_config()
6477 self.send_and_assert_no_replies(self.pg1, pkts_out2in)
6480 acl_if.acls = [out2in_acl, in2out_acl]
6481 acl_if.add_vpp_config()
6482 # send in2out to generate ACL state (NAT state was created earlier)
6483 capture = self.send_and_expect(self.pg0, pkts_in2out, self.pg1,
6485 self.verify_capture_out(capture, ignore_port=True)
6487 # send out2in again. ACL state exists so it should work now.
6488 # TCP packets with the syn flag set also need the ack flag
6489 for p in pkts_out2in:
6490 if p.haslayer(TCP) and p[TCP].flags & 0x02:
6491 p[TCP].flags |= 0x10
6492 capture = self.send_and_expect(self.pg1, pkts_out2in, self.pg0,
6494 self.verify_capture_in(capture, self.pg0)
6495 self.logger.info(self.vapi.cli("show trace"))
6497 def test_multiple_vrf(self):
6498 """ Multiple VRF setup """
6499 external_addr = '1.2.3.4'
6504 self.vapi.nat44_forwarding_enable_disable(enable=1)
6505 self.nat44_add_address(self.nat_addr)
6506 flags = self.config_flags.NAT_IS_INSIDE
6507 self.vapi.nat44_interface_add_del_feature(
6508 sw_if_index=self.pg0.sw_if_index,
6510 self.vapi.nat44_interface_add_del_feature(
6511 sw_if_index=self.pg0.sw_if_index,
6512 is_add=1, flags=flags)
6513 self.vapi.nat44_interface_add_del_output_feature(
6514 sw_if_index=self.pg1.sw_if_index,
6516 self.vapi.nat44_interface_add_del_feature(
6517 sw_if_index=self.pg5.sw_if_index,
6519 self.vapi.nat44_interface_add_del_feature(
6520 sw_if_index=self.pg5.sw_if_index,
6521 is_add=1, flags=flags)
6522 self.vapi.nat44_interface_add_del_feature(
6523 sw_if_index=self.pg6.sw_if_index,
6525 flags = self.config_flags.NAT_IS_OUT2IN_ONLY
6526 self.nat44_add_static_mapping(self.pg5.remote_ip4, external_addr,
6527 local_port, external_port, vrf_id=1,
6528 proto=IP_PROTOS.tcp, flags=flags)
6529 self.nat44_add_static_mapping(
6530 self.pg0.remote_ip4,
6531 external_sw_if_index=self.pg0.sw_if_index,
6532 local_port=local_port,
6534 external_port=external_port,
6535 proto=IP_PROTOS.tcp,
6539 # from client to service (both VRF1)
6540 p = (Ether(src=self.pg6.remote_mac, dst=self.pg6.local_mac) /
6541 IP(src=self.pg6.remote_ip4, dst=external_addr) /
6542 TCP(sport=12345, dport=external_port))
6543 self.pg6.add_stream(p)
6544 self.pg_enable_capture(self.pg_interfaces)
6546 capture = self.pg5.get_capture(1)
6551 self.assertEqual(ip.dst, self.pg5.remote_ip4)
6552 self.assertEqual(tcp.dport, local_port)
6553 self.assert_packet_checksums_valid(p)
6555 self.logger.error(ppp("Unexpected or invalid packet:", p))
6558 # from service back to client (both VRF1)
6559 p = (Ether(src=self.pg5.remote_mac, dst=self.pg5.local_mac) /
6560 IP(src=self.pg5.remote_ip4, dst=self.pg6.remote_ip4) /
6561 TCP(sport=local_port, dport=12345))
6562 self.pg5.add_stream(p)
6563 self.pg_enable_capture(self.pg_interfaces)
6565 capture = self.pg6.get_capture(1)
6570 self.assertEqual(ip.src, external_addr)
6571 self.assertEqual(tcp.sport, external_port)
6572 self.assert_packet_checksums_valid(p)
6574 self.logger.error(ppp("Unexpected or invalid packet:", p))
6577 # dynamic NAT from VRF1 to VRF0 (output-feature)
6578 p = (Ether(src=self.pg5.remote_mac, dst=self.pg5.local_mac) /
6579 IP(src=self.pg5.remote_ip4, dst=self.pg1.remote_ip4) /
6580 TCP(sport=2345, dport=22))
6581 self.pg5.add_stream(p)
6582 self.pg_enable_capture(self.pg_interfaces)
6584 capture = self.pg1.get_capture(1)
6589 self.assertEqual(ip.src, self.nat_addr)
6590 self.assert_packet_checksums_valid(p)
6593 self.logger.error(ppp("Unexpected or invalid packet:", p))
6596 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
6597 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
6598 TCP(sport=22, dport=port))
6599 self.pg1.add_stream(p)
6600 self.pg_enable_capture(self.pg_interfaces)
6602 capture = self.pg5.get_capture(1)
6607 self.assertEqual(ip.dst, self.pg5.remote_ip4)
6608 self.assertEqual(tcp.dport, 2345)
6609 self.assert_packet_checksums_valid(p)
6611 self.logger.error(ppp("Unexpected or invalid packet:", p))
6614 # from client VRF1 to service VRF0
6615 p = (Ether(src=self.pg6.remote_mac, dst=self.pg6.local_mac) /
6616 IP(src=self.pg6.remote_ip4, dst=self.pg0.local_ip4) /
6617 TCP(sport=12346, dport=external_port))
6618 self.pg6.add_stream(p)
6619 self.pg_enable_capture(self.pg_interfaces)
6621 capture = self.pg0.get_capture(1)
6626 self.assertEqual(ip.dst, self.pg0.remote_ip4)
6627 self.assertEqual(tcp.dport, local_port)
6628 self.assert_packet_checksums_valid(p)
6630 self.logger.error(ppp("Unexpected or invalid packet:", p))
6633 # from service VRF0 back to client VRF1
6634 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6635 IP(src=self.pg0.remote_ip4, dst=self.pg6.remote_ip4) /
6636 TCP(sport=local_port, dport=12346))
6637 self.pg0.add_stream(p)
6638 self.pg_enable_capture(self.pg_interfaces)
6640 capture = self.pg6.get_capture(1)
6645 self.assertEqual(ip.src, self.pg0.local_ip4)
6646 self.assertEqual(tcp.sport, external_port)
6647 self.assert_packet_checksums_valid(p)
6649 self.logger.error(ppp("Unexpected or invalid packet:", p))
6652 # from client VRF0 to service VRF1
6653 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6654 IP(src=self.pg0.remote_ip4, dst=external_addr) /
6655 TCP(sport=12347, dport=external_port))
6656 self.pg0.add_stream(p)
6657 self.pg_enable_capture(self.pg_interfaces)
6659 capture = self.pg5.get_capture(1)
6664 self.assertEqual(ip.dst, self.pg5.remote_ip4)
6665 self.assertEqual(tcp.dport, local_port)
6666 self.assert_packet_checksums_valid(p)
6668 self.logger.error(ppp("Unexpected or invalid packet:", p))
6671 # from service VRF1 back to client VRF0
6672 p = (Ether(src=self.pg5.remote_mac, dst=self.pg5.local_mac) /
6673 IP(src=self.pg5.remote_ip4, dst=self.pg0.remote_ip4) /
6674 TCP(sport=local_port, dport=12347))
6675 self.pg5.add_stream(p)
6676 self.pg_enable_capture(self.pg_interfaces)
6678 capture = self.pg0.get_capture(1)
6683 self.assertEqual(ip.src, external_addr)
6684 self.assertEqual(tcp.sport, external_port)
6685 self.assert_packet_checksums_valid(p)
6687 self.logger.error(ppp("Unexpected or invalid packet:", p))
6690 # from client to server (both VRF1, no translation)
6691 p = (Ether(src=self.pg6.remote_mac, dst=self.pg6.local_mac) /
6692 IP(src=self.pg6.remote_ip4, dst=self.pg5.remote_ip4) /
6693 TCP(sport=12348, dport=local_port))
6694 self.pg6.add_stream(p)
6695 self.pg_enable_capture(self.pg_interfaces)
6697 capture = self.pg5.get_capture(1)
6702 self.assertEqual(ip.dst, self.pg5.remote_ip4)
6703 self.assertEqual(tcp.dport, local_port)
6704 self.assert_packet_checksums_valid(p)
6706 self.logger.error(ppp("Unexpected or invalid packet:", p))
6709 # from server back to client (both VRF1, no translation)
6710 p = (Ether(src=self.pg5.remote_mac, dst=self.pg5.local_mac) /
6711 IP(src=self.pg5.remote_ip4, dst=self.pg6.remote_ip4) /
6712 TCP(sport=local_port, dport=12348))
6713 self.pg5.add_stream(p)
6714 self.pg_enable_capture(self.pg_interfaces)
6716 capture = self.pg6.get_capture(1)
6721 self.assertEqual(ip.src, self.pg5.remote_ip4)
6722 self.assertEqual(tcp.sport, local_port)
6723 self.assert_packet_checksums_valid(p)
6725 self.logger.error(ppp("Unexpected or invalid packet:", p))
6728 # from client VRF1 to server VRF0 (no translation)
6729 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6730 IP(src=self.pg0.remote_ip4, dst=self.pg6.remote_ip4) /
6731 TCP(sport=local_port, dport=12349))
6732 self.pg0.add_stream(p)
6733 self.pg_enable_capture(self.pg_interfaces)
6735 capture = self.pg6.get_capture(1)
6740 self.assertEqual(ip.src, self.pg0.remote_ip4)
6741 self.assertEqual(tcp.sport, local_port)
6742 self.assert_packet_checksums_valid(p)
6744 self.logger.error(ppp("Unexpected or invalid packet:", p))
6747 # from server VRF0 back to client VRF1 (no translation)
6748 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6749 IP(src=self.pg0.remote_ip4, dst=self.pg6.remote_ip4) /
6750 TCP(sport=local_port, dport=12349))
6751 self.pg0.add_stream(p)
6752 self.pg_enable_capture(self.pg_interfaces)
6754 capture = self.pg6.get_capture(1)
6759 self.assertEqual(ip.src, self.pg0.remote_ip4)
6760 self.assertEqual(tcp.sport, local_port)
6761 self.assert_packet_checksums_valid(p)
6763 self.logger.error(ppp("Unexpected or invalid packet:", p))
6766 # from client VRF0 to server VRF1 (no translation)
6767 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6768 IP(src=self.pg0.remote_ip4, dst=self.pg5.remote_ip4) /
6769 TCP(sport=12344, dport=local_port))
6770 self.pg0.add_stream(p)
6771 self.pg_enable_capture(self.pg_interfaces)
6773 capture = self.pg5.get_capture(1)
6778 self.assertEqual(ip.dst, self.pg5.remote_ip4)
6779 self.assertEqual(tcp.dport, local_port)
6780 self.assert_packet_checksums_valid(p)
6782 self.logger.error(ppp("Unexpected or invalid packet:", p))
6785 # from server VRF1 back to client VRF0 (no translation)
6786 p = (Ether(src=self.pg5.remote_mac, dst=self.pg5.local_mac) /
6787 IP(src=self.pg5.remote_ip4, dst=self.pg0.remote_ip4) /
6788 TCP(sport=local_port, dport=12344))
6789 self.pg5.add_stream(p)
6790 self.pg_enable_capture(self.pg_interfaces)
6792 capture = self.pg0.get_capture(1)
6797 self.assertEqual(ip.src, self.pg5.remote_ip4)
6798 self.assertEqual(tcp.sport, local_port)
6799 self.assert_packet_checksums_valid(p)
6801 self.logger.error(ppp("Unexpected or invalid packet:", p))
6804 @unittest.skipUnless(running_extended_tests, "part of extended tests")
6805 def test_session_timeout(self):
6806 """ NAT44 session timeouts """
6807 self.nat44_add_address(self.nat_addr)
6808 flags = self.config_flags.NAT_IS_INSIDE
6809 self.vapi.nat44_interface_add_del_feature(
6810 sw_if_index=self.pg0.sw_if_index,
6811 flags=flags, is_add=1)
6812 self.vapi.nat44_interface_add_del_feature(
6813 sw_if_index=self.pg1.sw_if_index,
6815 self.vapi.nat_set_timeouts(udp=300, tcp_established=7440,
6816 tcp_transitory=240, icmp=5)
6820 for i in range(0, max_sessions):
6821 src = "10.10.%u.%u" % ((i & 0xFF00) >> 8, i & 0xFF)
6822 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
6823 IP(src=src, dst=self.pg1.remote_ip4) /
6824 ICMP(id=1025, type='echo-request'))
6826 self.pg0.add_stream(pkts)
6827 self.pg_enable_capture(self.pg_interfaces)
6829 self.pg1.get_capture(max_sessions)
6834 for i in range(0, max_sessions):
6835 src = "10.11.%u.%u" % ((i & 0xFF00) >> 8, i & 0xFF)
6836 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
6837 IP(src=src, dst=self.pg1.remote_ip4) /
6838 ICMP(id=1026, type='echo-request'))
6840 self.pg0.add_stream(pkts)
6841 self.pg_enable_capture(self.pg_interfaces)
6843 self.pg1.get_capture(max_sessions)
6846 users = self.vapi.nat44_user_dump()
6848 nsessions = nsessions + user.nsessions
6849 self.assertLess(nsessions, 2 * max_sessions)
6851 @unittest.skipUnless(running_extended_tests, "part of extended tests")
6852 def test_session_rst_timeout(self):
6853 """ NAT44 session RST timeouts """
6854 self.nat44_add_address(self.nat_addr)
6855 flags = self.config_flags.NAT_IS_INSIDE
6856 self.vapi.nat44_interface_add_del_feature(
6857 sw_if_index=self.pg0.sw_if_index,
6858 flags=flags, is_add=1)
6859 self.vapi.nat44_interface_add_del_feature(
6860 sw_if_index=self.pg1.sw_if_index,
6862 self.vapi.nat_set_timeouts(udp=300, tcp_established=7440,
6863 tcp_transitory=5, icmp=60)
6865 self.initiate_tcp_session(self.pg0, self.pg1)
6866 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6867 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6868 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
6870 self.pg0.add_stream(p)
6871 self.pg_enable_capture(self.pg_interfaces)
6873 self.pg1.get_capture(1)
6877 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6878 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6879 TCP(sport=self.tcp_port_in + 1, dport=self.tcp_external_port + 1,
6881 self.pg0.add_stream(p)
6882 self.pg_enable_capture(self.pg_interfaces)
6884 self.pg1.get_capture(1)
6886 def test_syslog_sess(self):
6887 """ Test syslog session creation and deletion """
6888 self.vapi.syslog_set_filter(
6889 self.SYSLOG_SEVERITY.SYSLOG_API_SEVERITY_INFO)
6890 self.vapi.syslog_set_sender(self.pg2.local_ip4, self.pg2.remote_ip4)
6891 self.nat44_add_address(self.nat_addr)
6892 flags = self.config_flags.NAT_IS_INSIDE
6893 self.vapi.nat44_interface_add_del_feature(
6894 sw_if_index=self.pg0.sw_if_index,
6895 flags=flags, is_add=1)
6896 self.vapi.nat44_interface_add_del_feature(
6897 sw_if_index=self.pg1.sw_if_index,
6900 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
6901 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6902 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port))
6903 self.pg0.add_stream(p)
6904 self.pg_enable_capture(self.pg_interfaces)
6906 capture = self.pg1.get_capture(1)
6907 self.tcp_port_out = capture[0][TCP].sport
6908 capture = self.pg2.get_capture(1)
6909 self.verify_syslog_sess(capture[0][Raw].load)
6911 self.pg_enable_capture(self.pg_interfaces)
6913 self.nat44_add_address(self.nat_addr, is_add=0)
6914 capture = self.pg2.get_capture(1)
6915 self.verify_syslog_sess(capture[0][Raw].load, False)
6917 def test_ed_users_dump(self):
6918 """ API test - nat44_user_dump """
6919 flags = self.config_flags.NAT_IS_INSIDE
6920 self.vapi.nat44_interface_add_del_feature(
6921 sw_if_index=self.pg0.sw_if_index,
6922 flags=flags, is_add=1)
6923 self.vapi.nat44_interface_add_del_feature(
6924 sw_if_index=self.pg1.sw_if_index,
6926 self.vapi.nat44_forwarding_enable_disable(enable=1)
6928 real_ip = self.pg0.remote_ip4
6929 alias_ip = self.nat_addr
6930 flags = self.config_flags.NAT_IS_ADDR_ONLY
6931 self.vapi.nat44_add_del_static_mapping(is_add=1,
6932 local_ip_address=real_ip,
6933 external_ip_address=alias_ip,
6934 external_sw_if_index=0xFFFFFFFF,
6937 users = self.vapi.nat44_user_dump()
6938 self.assertEqual(len(users), 0)
6940 # in2out - static mapping match
6942 pkts = self.create_stream_out(self.pg1)
6943 self.pg1.add_stream(pkts)
6944 self.pg_enable_capture(self.pg_interfaces)
6946 capture = self.pg0.get_capture(len(pkts))
6947 self.verify_capture_in(capture, self.pg0)
6949 pkts = self.create_stream_in(self.pg0, self.pg1)
6950 self.pg0.add_stream(pkts)
6951 self.pg_enable_capture(self.pg_interfaces)
6953 capture = self.pg1.get_capture(len(pkts))
6954 self.verify_capture_out(capture, same_port=True)
6956 users = self.vapi.nat44_user_dump()
6957 self.assertEqual(len(users), 1)
6958 static_user = users[0]
6959 self.assertEqual(static_user.nstaticsessions, 3)
6960 self.assertEqual(static_user.nsessions, 0)
6962 # in2out - no static mapping match
6964 host0 = self.pg0.remote_hosts[0]
6965 self.pg0.remote_hosts[0] = self.pg0.remote_hosts[1]
6967 pkts = self.create_stream_out(self.pg1,
6968 dst_ip=self.pg0.remote_ip4,
6969 use_inside_ports=True)
6970 self.pg1.add_stream(pkts)
6971 self.pg_enable_capture(self.pg_interfaces)
6973 capture = self.pg0.get_capture(len(pkts))
6974 self.verify_capture_in(capture, self.pg0)
6976 pkts = self.create_stream_in(self.pg0, self.pg1)
6977 self.pg0.add_stream(pkts)
6978 self.pg_enable_capture(self.pg_interfaces)
6980 capture = self.pg1.get_capture(len(pkts))
6981 self.verify_capture_out(capture, nat_ip=self.pg0.remote_ip4,
6984 self.pg0.remote_hosts[0] = host0
6986 users = self.vapi.nat44_user_dump()
6987 self.assertEqual(len(users), 2)
6988 if str(users[0].ip_address) == self.pg0.remote_hosts[0].ip4:
6989 non_static_user = users[1]
6990 static_user = users[0]
6992 non_static_user = users[0]
6993 static_user = users[1]
6994 self.assertEqual(static_user.nstaticsessions, 3)
6995 self.assertEqual(static_user.nsessions, 0)
6996 self.assertEqual(non_static_user.nstaticsessions, 0)
6997 self.assertEqual(non_static_user.nsessions, 3)
6999 users = self.vapi.nat44_user_dump()
7000 self.assertEqual(len(users), 2)
7001 if str(users[0].ip_address) == self.pg0.remote_hosts[0].ip4:
7002 non_static_user = users[1]
7003 static_user = users[0]
7005 non_static_user = users[0]
7006 static_user = users[1]
7007 self.assertEqual(static_user.nstaticsessions, 3)
7008 self.assertEqual(static_user.nsessions, 0)
7009 self.assertEqual(non_static_user.nstaticsessions, 0)
7010 self.assertEqual(non_static_user.nsessions, 3)
7013 self.vapi.nat44_forwarding_enable_disable(enable=0)
7014 flags = self.config_flags.NAT_IS_ADDR_ONLY
7015 self.vapi.nat44_add_del_static_mapping(
7017 local_ip_address=real_ip,
7018 external_ip_address=alias_ip,
7019 external_sw_if_index=0xFFFFFFFF,
7022 def show_commands_at_teardown(self):
7023 self.logger.info(self.vapi.cli("show errors"))
7024 self.logger.info(self.vapi.cli("show nat44 addresses"))
7025 self.logger.info(self.vapi.cli("show nat44 interfaces"))
7026 self.logger.info(self.vapi.cli("show nat44 static mappings"))
7027 self.logger.info(self.vapi.cli("show nat44 interface address"))
7028 self.logger.info(self.vapi.cli("show nat44 sessions detail"))
7029 self.logger.info(self.vapi.cli("show nat44 hash tables detail"))
7030 self.logger.info(self.vapi.cli("show nat timeouts"))
7031 self.logger.info(self.vapi.cli("debug nat44 fib registration"))
7034 class TestNAT44EndpointDependent3(MethodHolder):
7035 """ Endpoint-Dependent mapping and filtering extra test cases """
7037 max_translations = 50
7040 def setUpClass(cls):
7041 super(TestNAT44EndpointDependent3, cls).setUpClass()
7042 cls.vapi.cli("set log class nat level debug")
7044 cls.nat_addr = '10.0.0.3'
7046 cls.create_pg_interfaces(range(2))
7048 for i in cls.pg_interfaces:
7054 super(TestNAT44EndpointDependent3, self).setUp()
7055 flags = self.nat44_config_flags.NAT44_IS_ENDPOINT_DEPENDENT
7056 self.vapi.nat44_plugin_enable_disable(
7057 sessions=self.max_translations,
7058 flags=flags, enable=1)
7059 self.vapi.nat_set_timeouts(
7060 udp=1, tcp_established=7440, tcp_transitory=30, icmp=1)
7062 self.nat44_add_address(self.nat_addr)
7063 flags = self.config_flags.NAT_IS_INSIDE
7064 self.vapi.nat44_interface_add_del_feature(
7065 sw_if_index=self.pg0.sw_if_index, flags=flags, is_add=1)
7066 self.vapi.nat44_interface_add_del_feature(
7067 sw_if_index=self.pg1.sw_if_index, is_add=1)
7070 def tearDownClass(cls):
7071 super(TestNAT44EndpointDependent3, cls).tearDownClass()
7074 super(TestNAT44EndpointDependent3, self).tearDown()
7075 if not self.vpp_dead:
7076 self.vapi.nat44_plugin_enable_disable(enable=0)
7077 self.vapi.cli("clear logging")
7079 def init_tcp_session(self, in_if, out_if, sport, ext_dport):
7080 # SYN packet in->out
7081 p = (Ether(src=in_if.remote_mac, dst=in_if.local_mac) /
7082 IP(src=in_if.remote_ip4, dst=out_if.remote_ip4) /
7083 TCP(sport=sport, dport=ext_dport, flags="S"))
7085 self.pg_enable_capture(self.pg_interfaces)
7087 capture = out_if.get_capture(1)
7089 tcp_port_out = p[TCP].sport
7091 # SYN + ACK packet out->in
7092 p = (Ether(src=out_if.remote_mac, dst=out_if.local_mac) /
7093 IP(src=out_if.remote_ip4, dst=self.nat_addr) /
7094 TCP(sport=ext_dport, dport=tcp_port_out, flags="SA"))
7095 out_if.add_stream(p)
7096 self.pg_enable_capture(self.pg_interfaces)
7098 in_if.get_capture(1)
7100 # ACK packet in->out
7101 p = (Ether(src=in_if.remote_mac, dst=in_if.local_mac) /
7102 IP(src=in_if.remote_ip4, dst=out_if.remote_ip4) /
7103 TCP(sport=sport, dport=ext_dport, flags="A"))
7105 self.pg_enable_capture(self.pg_interfaces)
7107 out_if.get_capture(1)
7111 def test_lru_cleanup(self):
7112 """ LRU cleanup algorithm """
7113 tcp_port_out = self.init_tcp_session(self.pg0, self.pg1, 2000, 80)
7115 for i in range(0, self.max_translations - 1):
7116 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
7117 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4, ttl=64) /
7118 UDP(sport=7000+i, dport=80))
7121 self.pg0.add_stream(pkts)
7122 self.pg_enable_capture(self.pg_interfaces)
7124 self.pg1.get_capture(len(pkts))
7125 self.sleep(1.5, "wait for timeouts")
7128 for i in range(0, self.max_translations - 1):
7129 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
7130 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4, ttl=64) /
7131 ICMP(id=8000+i, type='echo-request'))
7134 self.pg0.add_stream(pkts)
7135 self.pg_enable_capture(self.pg_interfaces)
7137 self.pg1.get_capture(len(pkts))
7140 class TestNAT44Out2InDPO(MethodHolder):
7141 """ NAT44 Test Cases using out2in DPO """
7144 def setUpClass(cls):
7145 super(TestNAT44Out2InDPO, cls).setUpClass()
7146 cls.vapi.cli("set log class nat level debug")
7148 cls.tcp_port_in = 6303
7149 cls.tcp_port_out = 6303
7150 cls.udp_port_in = 6304
7151 cls.udp_port_out = 6304
7152 cls.icmp_id_in = 6305
7153 cls.icmp_id_out = 6305
7154 cls.nat_addr = '10.0.0.3'
7155 cls.dst_ip4 = '192.168.70.1'
7157 cls.create_pg_interfaces(range(2))
7160 cls.pg0.config_ip4()
7161 cls.pg0.resolve_arp()
7164 cls.pg1.config_ip6()
7165 cls.pg1.resolve_ndp()
7167 r1 = VppIpRoute(cls, "::", 0,
7168 [VppRoutePath(cls.pg1.remote_ip6,
7169 cls.pg1.sw_if_index)],
7174 def tearDownClass(cls):
7175 super(TestNAT44Out2InDPO, cls).tearDownClass()
7178 super(TestNAT44Out2InDPO, self).setUp()
7179 flags = self.nat44_config_flags.NAT44_API_IS_OUT2IN_DPO
7180 self.vapi.nat44_plugin_enable_disable(enable=1, flags=flags)
7183 super(TestNAT44Out2InDPO, self).tearDown()
7184 if not self.vpp_dead:
7185 self.vapi.nat44_plugin_enable_disable(enable=0)
7186 self.vapi.cli("clear logging")
7188 def configure_xlat(self):
7189 self.dst_ip6_pfx = '1:2:3::'
7190 self.dst_ip6_pfx_n = socket.inet_pton(socket.AF_INET6,
7192 self.dst_ip6_pfx_len = 96
7193 self.src_ip6_pfx = '4:5:6::'
7194 self.src_ip6_pfx_n = socket.inet_pton(socket.AF_INET6,
7196 self.src_ip6_pfx_len = 96
7197 self.vapi.map_add_domain(self.dst_ip6_pfx_n, self.dst_ip6_pfx_len,
7198 self.src_ip6_pfx_n, self.src_ip6_pfx_len,
7199 '\x00\x00\x00\x00', 0)
7201 @unittest.skip('Temporary disabled')
7202 def test_464xlat_ce(self):
7203 """ Test 464XLAT CE with NAT44 """
7205 nat_config = self.vapi.nat_show_config()
7206 self.assertEqual(1, nat_config.out2in_dpo)
7208 self.configure_xlat()
7210 flags = self.config_flags.NAT_IS_INSIDE
7211 self.vapi.nat44_interface_add_del_feature(
7212 sw_if_index=self.pg0.sw_if_index,
7213 flags=flags, is_add=1)
7214 self.vapi.nat44_add_del_address_range(first_ip_address=self.nat_addr_n,
7215 last_ip_address=self.nat_addr_n,
7216 vrf_id=0xFFFFFFFF, is_add=1)
7218 out_src_ip6 = self.compose_ip6(self.dst_ip4, self.dst_ip6_pfx,
7219 self.dst_ip6_pfx_len)
7220 out_dst_ip6 = self.compose_ip6(self.nat_addr, self.src_ip6_pfx,
7221 self.src_ip6_pfx_len)
7224 pkts = self.create_stream_in(self.pg0, self.pg1, self.dst_ip4)
7225 self.pg0.add_stream(pkts)
7226 self.pg_enable_capture(self.pg_interfaces)
7228 capture = self.pg1.get_capture(len(pkts))
7229 self.verify_capture_out_ip6(capture, nat_ip=out_dst_ip6,
7232 pkts = self.create_stream_out_ip6(self.pg1, out_src_ip6,
7234 self.pg1.add_stream(pkts)
7235 self.pg_enable_capture(self.pg_interfaces)
7237 capture = self.pg0.get_capture(len(pkts))
7238 self.verify_capture_in(capture, self.pg0)
7240 self.vapi.nat44_interface_add_del_feature(
7241 sw_if_index=self.pg0.sw_if_index,
7243 self.vapi.nat44_add_del_address_range(
7244 first_ip_address=self.nat_addr_n,
7245 last_ip_address=self.nat_addr_n,
7248 @unittest.skip('Temporary disabled')
7249 def test_464xlat_ce_no_nat(self):
7250 """ Test 464XLAT CE without NAT44 """
7252 self.configure_xlat()
7254 out_src_ip6 = self.compose_ip6(self.dst_ip4, self.dst_ip6_pfx,
7255 self.dst_ip6_pfx_len)
7256 out_dst_ip6 = self.compose_ip6(self.pg0.remote_ip4, self.src_ip6_pfx,
7257 self.src_ip6_pfx_len)
7259 pkts = self.create_stream_in(self.pg0, self.pg1, self.dst_ip4)
7260 self.pg0.add_stream(pkts)
7261 self.pg_enable_capture(self.pg_interfaces)
7263 capture = self.pg1.get_capture(len(pkts))
7264 self.verify_capture_out_ip6(capture, dst_ip=out_src_ip6,
7265 nat_ip=out_dst_ip6, same_port=True)
7267 pkts = self.create_stream_out_ip6(self.pg1, out_src_ip6, out_dst_ip6)
7268 self.pg1.add_stream(pkts)
7269 self.pg_enable_capture(self.pg_interfaces)
7271 capture = self.pg0.get_capture(len(pkts))
7272 self.verify_capture_in(capture, self.pg0)
7275 if __name__ == '__main__':
7276 unittest.main(testRunner=VppTestRunner)