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_config(self):
1182 """ NAT config translation memory """
1184 nat_config = self.vapi.nat_show_config()
1185 mem = nat_config.translation_memory_size
1186 self.assertTrue(mem > 0)
1187 self.logger.info("max translation memory: %d" % mem)
1189 def test_show_config_2(self):
1190 """ NAT config2 translation memory """
1192 nat_config = self.vapi.nat_show_config_2()
1193 mem = nat_config.translation_memory_size
1194 self.assertTrue(mem > 0)
1195 self.logger.info("max translation memory: %d" % mem)
1197 def test_show_max_translations(self):
1198 """ API test - max translations per thread """
1199 nat_config = self.vapi.nat_show_config_2()
1200 self.assertEqual(self.max_translations,
1201 nat_config.max_translations_per_thread)
1204 class TestNAT44(MethodHolder):
1205 """ NAT44 Test Cases """
1207 max_translations = 10240
1211 def setUpClass(cls):
1212 super(TestNAT44, cls).setUpClass()
1213 cls.vapi.cli("set log class nat level debug")
1215 cls.tcp_port_in = 6303
1216 cls.tcp_port_out = 6303
1217 cls.udp_port_in = 6304
1218 cls.udp_port_out = 6304
1219 cls.icmp_id_in = 6305
1220 cls.icmp_id_out = 6305
1221 cls.nat_addr = '10.0.0.3'
1222 cls.ipfix_src_port = 4739
1223 cls.ipfix_domain_id = 1
1224 cls.tcp_external_port = 80
1225 cls.udp_external_port = 69
1227 cls.create_pg_interfaces(range(10))
1228 cls.interfaces = list(cls.pg_interfaces[0:4])
1230 for i in cls.interfaces:
1235 cls.pg0.generate_remote_hosts(3)
1236 cls.pg0.configure_ipv4_neighbors()
1238 cls.pg1.generate_remote_hosts(1)
1239 cls.pg1.configure_ipv4_neighbors()
1241 cls.overlapping_interfaces = list(list(cls.pg_interfaces[4:7]))
1242 cls.vapi.ip_table_add_del(is_add=1, table={'table_id': 10})
1243 cls.vapi.ip_table_add_del(is_add=1, table={'table_id': 20})
1245 cls.pg4._local_ip4 = "172.16.255.1"
1246 cls.pg4._remote_hosts[0]._ip4 = "172.16.255.2"
1247 cls.pg4.set_table_ip4(10)
1248 cls.pg5._local_ip4 = "172.17.255.3"
1249 cls.pg5._remote_hosts[0]._ip4 = "172.17.255.4"
1250 cls.pg5.set_table_ip4(10)
1251 cls.pg6._local_ip4 = "172.16.255.1"
1252 cls.pg6._remote_hosts[0]._ip4 = "172.16.255.2"
1253 cls.pg6.set_table_ip4(20)
1254 for i in cls.overlapping_interfaces:
1262 cls.pg9.generate_remote_hosts(2)
1263 cls.pg9.config_ip4()
1264 cls.vapi.sw_interface_add_del_address(
1265 sw_if_index=cls.pg9.sw_if_index,
1266 prefix="10.0.0.1/24")
1269 cls.pg9.resolve_arp()
1270 cls.pg9._remote_hosts[1]._ip4 = cls.pg9._remote_hosts[0]._ip4
1271 cls.pg4._remote_ip4 = cls.pg9._remote_hosts[0]._ip4 = "10.0.0.2"
1272 cls.pg9.resolve_arp()
1275 super(TestNAT44, self).setUp()
1276 self.vapi.nat44_plugin_enable_disable(
1277 sessions=self.max_translations,
1278 users=self.max_users, enable=1)
1281 def tearDownClass(cls):
1282 super(TestNAT44, cls).tearDownClass()
1285 super(TestNAT44, self).tearDown()
1286 if not self.vpp_dead:
1287 self.vapi.nat_ipfix_enable_disable(domain_id=self.ipfix_domain_id,
1288 src_port=self.ipfix_src_port,
1290 self.ipfix_src_port = 4739
1291 self.ipfix_domain_id = 1
1293 self.vapi.nat44_plugin_enable_disable(enable=0)
1294 self.vapi.cli("clear logging")
1296 def test_clear_sessions(self):
1297 """ NAT44 session clearing test """
1299 self.nat44_add_address(self.nat_addr)
1300 flags = self.config_flags.NAT_IS_INSIDE
1301 self.vapi.nat44_interface_add_del_feature(
1302 sw_if_index=self.pg0.sw_if_index,
1303 flags=flags, is_add=1)
1304 self.vapi.nat44_interface_add_del_feature(
1305 sw_if_index=self.pg1.sw_if_index,
1308 nat_config = self.vapi.nat_show_config()
1309 self.assertEqual(0, nat_config.endpoint_dependent)
1311 pkts = self.create_stream_in(self.pg0, self.pg1)
1312 self.pg0.add_stream(pkts)
1313 self.pg_enable_capture(self.pg_interfaces)
1315 capture = self.pg1.get_capture(len(pkts))
1316 self.verify_capture_out(capture)
1318 sessions = self.statistics.get_counter('/nat44/total-sessions')
1319 self.assertTrue(sessions[0][0] > 0)
1320 self.logger.info("sessions before clearing: %s" % sessions[0][0])
1322 self.vapi.cli("clear nat44 sessions")
1324 sessions = self.statistics.get_counter('/nat44/total-sessions')
1325 self.assertEqual(sessions[0][0], 0)
1326 self.logger.info("sessions after clearing: %s" % sessions[0][0])
1328 def test_dynamic(self):
1329 """ NAT44 dynamic translation test """
1330 self.nat44_add_address(self.nat_addr)
1331 flags = self.config_flags.NAT_IS_INSIDE
1332 self.vapi.nat44_interface_add_del_feature(
1333 sw_if_index=self.pg0.sw_if_index,
1334 flags=flags, is_add=1)
1335 self.vapi.nat44_interface_add_del_feature(
1336 sw_if_index=self.pg1.sw_if_index,
1340 tcpn = self.statistics.get_counter('/nat44/in2out/slowpath/tcp')[0]
1341 udpn = self.statistics.get_counter('/nat44/in2out/slowpath/udp')[0]
1342 icmpn = self.statistics.get_counter('/nat44/in2out/slowpath/icmp')[0]
1343 drops = self.statistics.get_counter('/nat44/in2out/slowpath/drops')[0]
1345 pkts = self.create_stream_in(self.pg0, self.pg1)
1346 self.pg0.add_stream(pkts)
1347 self.pg_enable_capture(self.pg_interfaces)
1349 capture = self.pg1.get_capture(len(pkts))
1350 self.verify_capture_out(capture)
1352 if_idx = self.pg0.sw_if_index
1353 cnt = self.statistics.get_counter('/nat44/in2out/slowpath/tcp')[0]
1354 self.assertEqual(cnt[if_idx] - tcpn[if_idx], 2)
1355 cnt = self.statistics.get_counter('/nat44/in2out/slowpath/udp')[0]
1356 self.assertEqual(cnt[if_idx] - udpn[if_idx], 1)
1357 cnt = self.statistics.get_counter('/nat44/in2out/slowpath/icmp')[0]
1358 self.assertEqual(cnt[if_idx] - icmpn[if_idx], 1)
1359 cnt = self.statistics.get_counter('/nat44/in2out/slowpath/drops')[0]
1360 self.assertEqual(cnt[if_idx] - drops[if_idx], 0)
1363 tcpn = self.statistics.get_counter('/nat44/out2in/slowpath/tcp')[0]
1364 udpn = self.statistics.get_counter('/nat44/out2in/slowpath/udp')[0]
1365 icmpn = self.statistics.get_counter('/nat44/out2in/slowpath/icmp')[0]
1366 drops = self.statistics.get_counter('/nat44/out2in/slowpath/drops')[0]
1368 pkts = self.create_stream_out(self.pg1)
1369 self.pg1.add_stream(pkts)
1370 self.pg_enable_capture(self.pg_interfaces)
1372 capture = self.pg0.get_capture(len(pkts))
1373 self.verify_capture_in(capture, self.pg0)
1375 if_idx = self.pg1.sw_if_index
1376 cnt = self.statistics.get_counter('/nat44/out2in/slowpath/tcp')[0]
1377 self.assertEqual(cnt[if_idx] - tcpn[if_idx], 2)
1378 cnt = self.statistics.get_counter('/nat44/out2in/slowpath/udp')[0]
1379 self.assertEqual(cnt[if_idx] - udpn[if_idx], 1)
1380 cnt = self.statistics.get_counter('/nat44/out2in/slowpath/icmp')[0]
1381 self.assertEqual(cnt[if_idx] - icmpn[if_idx], 1)
1382 cnt = self.statistics.get_counter('/nat44/out2in/slowpath/drops')[0]
1383 self.assertEqual(cnt[if_idx] - drops[if_idx], 0)
1385 users = self.statistics.get_counter('/nat44/total-users')
1386 self.assertEqual(users[0][0], 1)
1387 sessions = self.statistics.get_counter('/nat44/total-sessions')
1388 self.assertEqual(sessions[0][0], 3)
1390 def test_dynamic_icmp_errors_in2out_ttl_1(self):
1391 """ NAT44 handling of client packets with TTL=1 """
1393 self.nat44_add_address(self.nat_addr)
1394 flags = self.config_flags.NAT_IS_INSIDE
1395 self.vapi.nat44_interface_add_del_feature(
1396 sw_if_index=self.pg0.sw_if_index,
1397 flags=flags, is_add=1)
1398 self.vapi.nat44_interface_add_del_feature(
1399 sw_if_index=self.pg1.sw_if_index,
1402 # Client side - generate traffic
1403 pkts = self.create_stream_in(self.pg0, self.pg1, ttl=1)
1404 self.pg0.add_stream(pkts)
1405 self.pg_enable_capture(self.pg_interfaces)
1408 # Client side - verify ICMP type 11 packets
1409 capture = self.pg0.get_capture(len(pkts))
1410 self.verify_capture_in_with_icmp_errors(capture, self.pg0)
1412 def test_dynamic_icmp_errors_out2in_ttl_1(self):
1413 """ NAT44 handling of server packets with TTL=1 """
1415 self.nat44_add_address(self.nat_addr)
1416 flags = self.config_flags.NAT_IS_INSIDE
1417 self.vapi.nat44_interface_add_del_feature(
1418 sw_if_index=self.pg0.sw_if_index,
1419 flags=flags, is_add=1)
1420 self.vapi.nat44_interface_add_del_feature(
1421 sw_if_index=self.pg1.sw_if_index,
1424 # Client side - create sessions
1425 pkts = self.create_stream_in(self.pg0, self.pg1)
1426 self.pg0.add_stream(pkts)
1427 self.pg_enable_capture(self.pg_interfaces)
1430 # Server side - generate traffic
1431 capture = self.pg1.get_capture(len(pkts))
1432 self.verify_capture_out(capture)
1433 pkts = self.create_stream_out(self.pg1, ttl=1)
1434 self.pg1.add_stream(pkts)
1435 self.pg_enable_capture(self.pg_interfaces)
1438 # Server side - verify ICMP type 11 packets
1439 capture = self.pg1.get_capture(len(pkts))
1440 self.verify_capture_out_with_icmp_errors(capture,
1441 src_ip=self.pg1.local_ip4)
1443 def test_dynamic_icmp_errors_in2out_ttl_2(self):
1444 """ NAT44 handling of error responses to client packets with TTL=2 """
1446 self.nat44_add_address(self.nat_addr)
1447 flags = self.config_flags.NAT_IS_INSIDE
1448 self.vapi.nat44_interface_add_del_feature(
1449 sw_if_index=self.pg0.sw_if_index,
1450 flags=flags, is_add=1)
1451 self.vapi.nat44_interface_add_del_feature(
1452 sw_if_index=self.pg1.sw_if_index,
1455 # Client side - generate traffic
1456 pkts = self.create_stream_in(self.pg0, self.pg1, ttl=2)
1457 self.pg0.add_stream(pkts)
1458 self.pg_enable_capture(self.pg_interfaces)
1461 # Server side - simulate ICMP type 11 response
1462 capture = self.pg1.get_capture(len(pkts))
1463 pkts = [Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
1464 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
1465 ICMP(type=11) / packet[IP] for packet in capture]
1466 self.pg1.add_stream(pkts)
1467 self.pg_enable_capture(self.pg_interfaces)
1470 # Client side - verify ICMP type 11 packets
1471 capture = self.pg0.get_capture(len(pkts))
1472 self.verify_capture_in_with_icmp_errors(capture, self.pg0)
1474 def test_dynamic_icmp_errors_out2in_ttl_2(self):
1475 """ NAT44 handling of error responses to server packets with TTL=2 """
1477 self.nat44_add_address(self.nat_addr)
1478 flags = self.config_flags.NAT_IS_INSIDE
1479 self.vapi.nat44_interface_add_del_feature(
1480 sw_if_index=self.pg0.sw_if_index,
1481 flags=flags, is_add=1)
1482 self.vapi.nat44_interface_add_del_feature(
1483 sw_if_index=self.pg1.sw_if_index,
1486 # Client side - create sessions
1487 pkts = self.create_stream_in(self.pg0, self.pg1)
1488 self.pg0.add_stream(pkts)
1489 self.pg_enable_capture(self.pg_interfaces)
1492 # Server side - generate traffic
1493 capture = self.pg1.get_capture(len(pkts))
1494 self.verify_capture_out(capture)
1495 pkts = self.create_stream_out(self.pg1, ttl=2)
1496 self.pg1.add_stream(pkts)
1497 self.pg_enable_capture(self.pg_interfaces)
1500 # Client side - simulate ICMP type 11 response
1501 capture = self.pg0.get_capture(len(pkts))
1502 pkts = [Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
1503 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
1504 ICMP(type=11) / packet[IP] for packet in capture]
1505 self.pg0.add_stream(pkts)
1506 self.pg_enable_capture(self.pg_interfaces)
1509 # Server side - verify ICMP type 11 packets
1510 capture = self.pg1.get_capture(len(pkts))
1511 self.verify_capture_out_with_icmp_errors(capture)
1513 def test_ping_out_interface_from_outside(self):
1514 """ Ping NAT44 out interface from outside network """
1516 self.nat44_add_address(self.nat_addr)
1517 flags = self.config_flags.NAT_IS_INSIDE
1518 self.vapi.nat44_interface_add_del_feature(
1519 sw_if_index=self.pg0.sw_if_index,
1520 flags=flags, is_add=1)
1521 self.vapi.nat44_interface_add_del_feature(
1522 sw_if_index=self.pg1.sw_if_index,
1525 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
1526 IP(src=self.pg1.remote_ip4, dst=self.pg1.local_ip4) /
1527 ICMP(id=self.icmp_id_out, type='echo-request'))
1529 self.pg1.add_stream(pkts)
1530 self.pg_enable_capture(self.pg_interfaces)
1532 capture = self.pg1.get_capture(len(pkts))
1535 self.assertEqual(packet[IP].src, self.pg1.local_ip4)
1536 self.assertEqual(packet[IP].dst, self.pg1.remote_ip4)
1537 self.assertEqual(packet[ICMP].id, self.icmp_id_in)
1538 self.assertEqual(packet[ICMP].type, 0) # echo reply
1540 self.logger.error(ppp("Unexpected or invalid packet "
1541 "(outside network):", packet))
1544 def test_ping_internal_host_from_outside(self):
1545 """ Ping internal host from outside network """
1547 self.nat44_add_static_mapping(self.pg0.remote_ip4, self.nat_addr)
1548 flags = self.config_flags.NAT_IS_INSIDE
1549 self.vapi.nat44_interface_add_del_feature(
1550 sw_if_index=self.pg0.sw_if_index,
1551 flags=flags, is_add=1)
1552 self.vapi.nat44_interface_add_del_feature(
1553 sw_if_index=self.pg1.sw_if_index,
1557 pkt = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
1558 IP(src=self.pg1.remote_ip4, dst=self.nat_addr, ttl=64) /
1559 ICMP(id=self.icmp_id_out, type='echo-request'))
1560 self.pg1.add_stream(pkt)
1561 self.pg_enable_capture(self.pg_interfaces)
1563 capture = self.pg0.get_capture(1)
1564 self.verify_capture_in(capture, self.pg0)
1565 self.assert_equal(capture[0][IP].proto, IP_PROTOS.icmp)
1568 pkt = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
1569 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4, ttl=64) /
1570 ICMP(id=self.icmp_id_in, type='echo-reply'))
1571 self.pg0.add_stream(pkt)
1572 self.pg_enable_capture(self.pg_interfaces)
1574 capture = self.pg1.get_capture(1)
1575 self.verify_capture_out(capture, same_port=True)
1576 self.assert_equal(capture[0][IP].proto, IP_PROTOS.icmp)
1578 def test_forwarding(self):
1579 """ NAT44 forwarding test """
1581 flags = self.config_flags.NAT_IS_INSIDE
1582 self.vapi.nat44_interface_add_del_feature(
1583 sw_if_index=self.pg0.sw_if_index,
1584 flags=flags, is_add=1)
1585 self.vapi.nat44_interface_add_del_feature(
1586 sw_if_index=self.pg1.sw_if_index,
1588 self.vapi.nat44_forwarding_enable_disable(enable=1)
1590 real_ip = self.pg0.remote_ip4
1591 alias_ip = self.nat_addr
1592 flags = self.config_flags.NAT_IS_ADDR_ONLY
1593 self.vapi.nat44_add_del_static_mapping(is_add=1,
1594 local_ip_address=real_ip,
1595 external_ip_address=alias_ip,
1596 external_sw_if_index=0xFFFFFFFF,
1600 # static mapping match
1602 pkts = self.create_stream_out(self.pg1)
1603 self.pg1.add_stream(pkts)
1604 self.pg_enable_capture(self.pg_interfaces)
1606 capture = self.pg0.get_capture(len(pkts))
1607 self.verify_capture_in(capture, self.pg0)
1609 pkts = self.create_stream_in(self.pg0, self.pg1)
1610 self.pg0.add_stream(pkts)
1611 self.pg_enable_capture(self.pg_interfaces)
1613 capture = self.pg1.get_capture(len(pkts))
1614 self.verify_capture_out(capture, same_port=True)
1616 # no static mapping match
1618 host0 = self.pg0.remote_hosts[0]
1619 self.pg0.remote_hosts[0] = self.pg0.remote_hosts[1]
1621 pkts = self.create_stream_out(self.pg1,
1622 dst_ip=self.pg0.remote_ip4,
1623 use_inside_ports=True)
1624 self.pg1.add_stream(pkts)
1625 self.pg_enable_capture(self.pg_interfaces)
1627 capture = self.pg0.get_capture(len(pkts))
1628 self.verify_capture_in(capture, self.pg0)
1630 pkts = self.create_stream_in(self.pg0, self.pg1)
1631 self.pg0.add_stream(pkts)
1632 self.pg_enable_capture(self.pg_interfaces)
1634 capture = self.pg1.get_capture(len(pkts))
1635 self.verify_capture_out(capture, nat_ip=self.pg0.remote_ip4,
1638 self.pg0.remote_hosts[0] = host0
1641 self.vapi.nat44_forwarding_enable_disable(enable=0)
1642 flags = self.config_flags.NAT_IS_ADDR_ONLY
1643 self.vapi.nat44_add_del_static_mapping(
1645 local_ip_address=real_ip,
1646 external_ip_address=alias_ip,
1647 external_sw_if_index=0xFFFFFFFF,
1650 def test_static_in(self):
1651 """ 1:1 NAT initialized from inside network """
1653 nat_ip = "10.0.0.10"
1654 self.tcp_port_out = 6303
1655 self.udp_port_out = 6304
1656 self.icmp_id_out = 6305
1658 self.nat44_add_static_mapping(self.pg0.remote_ip4, nat_ip)
1659 flags = self.config_flags.NAT_IS_INSIDE
1660 self.vapi.nat44_interface_add_del_feature(
1661 sw_if_index=self.pg0.sw_if_index,
1662 flags=flags, is_add=1)
1663 self.vapi.nat44_interface_add_del_feature(
1664 sw_if_index=self.pg1.sw_if_index,
1666 sm = self.vapi.nat44_static_mapping_dump()
1667 self.assertEqual(len(sm), 1)
1668 self.assertEqual(sm[0].tag, '')
1669 self.assertEqual(sm[0].protocol, 0)
1670 self.assertEqual(sm[0].local_port, 0)
1671 self.assertEqual(sm[0].external_port, 0)
1674 pkts = self.create_stream_in(self.pg0, self.pg1)
1675 self.pg0.add_stream(pkts)
1676 self.pg_enable_capture(self.pg_interfaces)
1678 capture = self.pg1.get_capture(len(pkts))
1679 self.verify_capture_out(capture, nat_ip, True)
1682 pkts = self.create_stream_out(self.pg1, nat_ip)
1683 self.pg1.add_stream(pkts)
1684 self.pg_enable_capture(self.pg_interfaces)
1686 capture = self.pg0.get_capture(len(pkts))
1687 self.verify_capture_in(capture, self.pg0)
1689 def test_static_out(self):
1690 """ 1:1 NAT initialized from outside network """
1692 nat_ip = "10.0.0.20"
1693 self.tcp_port_out = 6303
1694 self.udp_port_out = 6304
1695 self.icmp_id_out = 6305
1698 self.nat44_add_static_mapping(self.pg0.remote_ip4, nat_ip, tag=tag)
1699 flags = self.config_flags.NAT_IS_INSIDE
1700 self.vapi.nat44_interface_add_del_feature(
1701 sw_if_index=self.pg0.sw_if_index,
1702 flags=flags, is_add=1)
1703 self.vapi.nat44_interface_add_del_feature(
1704 sw_if_index=self.pg1.sw_if_index,
1706 sm = self.vapi.nat44_static_mapping_dump()
1707 self.assertEqual(len(sm), 1)
1708 self.assertEqual(sm[0].tag, tag)
1711 pkts = self.create_stream_out(self.pg1, nat_ip)
1712 self.pg1.add_stream(pkts)
1713 self.pg_enable_capture(self.pg_interfaces)
1715 capture = self.pg0.get_capture(len(pkts))
1716 self.verify_capture_in(capture, self.pg0)
1719 pkts = self.create_stream_in(self.pg0, self.pg1)
1720 self.pg0.add_stream(pkts)
1721 self.pg_enable_capture(self.pg_interfaces)
1723 capture = self.pg1.get_capture(len(pkts))
1724 self.verify_capture_out(capture, nat_ip, True)
1726 def test_static_with_port_in(self):
1727 """ 1:1 NAPT initialized from inside network """
1729 self.tcp_port_out = 3606
1730 self.udp_port_out = 3607
1731 self.icmp_id_out = 3608
1733 self.nat44_add_address(self.nat_addr)
1734 self.nat44_add_static_mapping(self.pg0.remote_ip4, self.nat_addr,
1735 self.tcp_port_in, self.tcp_port_out,
1736 proto=IP_PROTOS.tcp)
1737 self.nat44_add_static_mapping(self.pg0.remote_ip4, self.nat_addr,
1738 self.udp_port_in, self.udp_port_out,
1739 proto=IP_PROTOS.udp)
1740 self.nat44_add_static_mapping(self.pg0.remote_ip4, self.nat_addr,
1741 self.icmp_id_in, self.icmp_id_out,
1742 proto=IP_PROTOS.icmp)
1743 flags = self.config_flags.NAT_IS_INSIDE
1744 self.vapi.nat44_interface_add_del_feature(
1745 sw_if_index=self.pg0.sw_if_index,
1746 flags=flags, is_add=1)
1747 self.vapi.nat44_interface_add_del_feature(
1748 sw_if_index=self.pg1.sw_if_index,
1752 pkts = self.create_stream_in(self.pg0, self.pg1)
1753 self.pg0.add_stream(pkts)
1754 self.pg_enable_capture(self.pg_interfaces)
1756 capture = self.pg1.get_capture(len(pkts))
1757 self.verify_capture_out(capture)
1760 pkts = self.create_stream_out(self.pg1)
1761 self.pg1.add_stream(pkts)
1762 self.pg_enable_capture(self.pg_interfaces)
1764 capture = self.pg0.get_capture(len(pkts))
1765 self.verify_capture_in(capture, self.pg0)
1767 def test_static_with_port_out(self):
1768 """ 1:1 NAPT initialized from outside network """
1770 self.tcp_port_out = 30606
1771 self.udp_port_out = 30607
1772 self.icmp_id_out = 30608
1774 self.nat44_add_address(self.nat_addr)
1775 self.nat44_add_static_mapping(self.pg0.remote_ip4, self.nat_addr,
1776 self.tcp_port_in, self.tcp_port_out,
1777 proto=IP_PROTOS.tcp)
1778 self.nat44_add_static_mapping(self.pg0.remote_ip4, self.nat_addr,
1779 self.udp_port_in, self.udp_port_out,
1780 proto=IP_PROTOS.udp)
1781 self.nat44_add_static_mapping(self.pg0.remote_ip4, self.nat_addr,
1782 self.icmp_id_in, self.icmp_id_out,
1783 proto=IP_PROTOS.icmp)
1784 flags = self.config_flags.NAT_IS_INSIDE
1785 self.vapi.nat44_interface_add_del_feature(
1786 sw_if_index=self.pg0.sw_if_index,
1787 flags=flags, is_add=1)
1788 self.vapi.nat44_interface_add_del_feature(
1789 sw_if_index=self.pg1.sw_if_index,
1793 pkts = self.create_stream_out(self.pg1)
1794 self.pg1.add_stream(pkts)
1795 self.pg_enable_capture(self.pg_interfaces)
1797 capture = self.pg0.get_capture(len(pkts))
1798 self.verify_capture_in(capture, self.pg0)
1801 pkts = self.create_stream_in(self.pg0, self.pg1)
1802 self.pg0.add_stream(pkts)
1803 self.pg_enable_capture(self.pg_interfaces)
1805 capture = self.pg1.get_capture(len(pkts))
1806 self.verify_capture_out(capture)
1808 def test_static_vrf_aware(self):
1809 """ 1:1 NAT VRF awareness """
1811 nat_ip1 = "10.0.0.30"
1812 nat_ip2 = "10.0.0.40"
1813 self.tcp_port_out = 6303
1814 self.udp_port_out = 6304
1815 self.icmp_id_out = 6305
1817 self.nat44_add_static_mapping(self.pg4.remote_ip4, nat_ip1,
1819 self.nat44_add_static_mapping(self.pg0.remote_ip4, nat_ip2,
1821 flags = self.config_flags.NAT_IS_INSIDE
1822 self.vapi.nat44_interface_add_del_feature(
1823 sw_if_index=self.pg3.sw_if_index,
1825 self.vapi.nat44_interface_add_del_feature(
1826 sw_if_index=self.pg0.sw_if_index,
1827 flags=flags, is_add=1)
1828 self.vapi.nat44_interface_add_del_feature(
1829 sw_if_index=self.pg4.sw_if_index,
1830 flags=flags, is_add=1)
1832 # inside interface VRF match NAT44 static mapping VRF
1833 pkts = self.create_stream_in(self.pg4, self.pg3)
1834 self.pg4.add_stream(pkts)
1835 self.pg_enable_capture(self.pg_interfaces)
1837 capture = self.pg3.get_capture(len(pkts))
1838 self.verify_capture_out(capture, nat_ip1, True)
1840 # inside interface VRF don't match NAT44 static mapping VRF (packets
1842 pkts = self.create_stream_in(self.pg0, self.pg3)
1843 self.pg0.add_stream(pkts)
1844 self.pg_enable_capture(self.pg_interfaces)
1846 self.pg3.assert_nothing_captured()
1848 def test_dynamic_to_static(self):
1849 """ Switch from dynamic translation to 1:1NAT """
1850 nat_ip = "10.0.0.10"
1851 self.tcp_port_out = 6303
1852 self.udp_port_out = 6304
1853 self.icmp_id_out = 6305
1855 self.nat44_add_address(self.nat_addr)
1856 flags = self.config_flags.NAT_IS_INSIDE
1857 self.vapi.nat44_interface_add_del_feature(
1858 sw_if_index=self.pg0.sw_if_index,
1859 flags=flags, is_add=1)
1860 self.vapi.nat44_interface_add_del_feature(
1861 sw_if_index=self.pg1.sw_if_index,
1865 pkts = self.create_stream_in(self.pg0, self.pg1)
1866 self.pg0.add_stream(pkts)
1867 self.pg_enable_capture(self.pg_interfaces)
1869 capture = self.pg1.get_capture(len(pkts))
1870 self.verify_capture_out(capture)
1873 self.nat44_add_static_mapping(self.pg0.remote_ip4, nat_ip)
1874 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4, 0)
1875 self.assertEqual(len(sessions), 0)
1876 pkts = self.create_stream_in(self.pg0, self.pg1)
1877 self.pg0.add_stream(pkts)
1878 self.pg_enable_capture(self.pg_interfaces)
1880 capture = self.pg1.get_capture(len(pkts))
1881 self.verify_capture_out(capture, nat_ip, True)
1883 def test_identity_nat(self):
1884 """ Identity NAT """
1885 flags = self.config_flags.NAT_IS_ADDR_ONLY
1886 self.vapi.nat44_add_del_identity_mapping(
1887 ip_address=self.pg0.remote_ip4, sw_if_index=0xFFFFFFFF,
1888 flags=flags, is_add=1)
1889 flags = self.config_flags.NAT_IS_INSIDE
1890 self.vapi.nat44_interface_add_del_feature(
1891 sw_if_index=self.pg0.sw_if_index,
1892 flags=flags, is_add=1)
1893 self.vapi.nat44_interface_add_del_feature(
1894 sw_if_index=self.pg1.sw_if_index,
1897 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
1898 IP(src=self.pg1.remote_ip4, dst=self.pg0.remote_ip4) /
1899 TCP(sport=12345, dport=56789))
1900 self.pg1.add_stream(p)
1901 self.pg_enable_capture(self.pg_interfaces)
1903 capture = self.pg0.get_capture(1)
1908 self.assertEqual(ip.dst, self.pg0.remote_ip4)
1909 self.assertEqual(ip.src, self.pg1.remote_ip4)
1910 self.assertEqual(tcp.dport, 56789)
1911 self.assertEqual(tcp.sport, 12345)
1912 self.assert_packet_checksums_valid(p)
1914 self.logger.error(ppp("Unexpected or invalid packet:", p))
1917 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4, 0)
1918 self.assertEqual(len(sessions), 0)
1919 flags = self.config_flags.NAT_IS_ADDR_ONLY
1920 self.vapi.nat44_add_del_identity_mapping(
1921 ip_address=self.pg0.remote_ip4, sw_if_index=0xFFFFFFFF,
1922 flags=flags, vrf_id=1, is_add=1)
1923 identity_mappings = self.vapi.nat44_identity_mapping_dump()
1924 self.assertEqual(len(identity_mappings), 2)
1926 def test_multiple_inside_interfaces(self):
1927 """ NAT44 multiple non-overlapping address space inside interfaces """
1929 self.nat44_add_address(self.nat_addr)
1930 flags = self.config_flags.NAT_IS_INSIDE
1931 self.vapi.nat44_interface_add_del_feature(
1932 sw_if_index=self.pg0.sw_if_index,
1933 flags=flags, is_add=1)
1934 self.vapi.nat44_interface_add_del_feature(
1935 sw_if_index=self.pg1.sw_if_index,
1936 flags=flags, is_add=1)
1937 self.vapi.nat44_interface_add_del_feature(
1938 sw_if_index=self.pg3.sw_if_index,
1941 # between two NAT44 inside interfaces (no translation)
1942 pkts = self.create_stream_in(self.pg0, self.pg1)
1943 self.pg0.add_stream(pkts)
1944 self.pg_enable_capture(self.pg_interfaces)
1946 capture = self.pg1.get_capture(len(pkts))
1947 self.verify_capture_no_translation(capture, self.pg0, self.pg1)
1949 # from NAT44 inside to interface without NAT44 feature (no translation)
1950 pkts = self.create_stream_in(self.pg0, self.pg2)
1951 self.pg0.add_stream(pkts)
1952 self.pg_enable_capture(self.pg_interfaces)
1954 capture = self.pg2.get_capture(len(pkts))
1955 self.verify_capture_no_translation(capture, self.pg0, self.pg2)
1957 # in2out 1st interface
1958 pkts = self.create_stream_in(self.pg0, self.pg3)
1959 self.pg0.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 1st 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.pg0.get_capture(len(pkts))
1971 self.verify_capture_in(capture, self.pg0)
1973 # in2out 2nd interface
1974 pkts = self.create_stream_in(self.pg1, self.pg3)
1975 self.pg1.add_stream(pkts)
1976 self.pg_enable_capture(self.pg_interfaces)
1978 capture = self.pg3.get_capture(len(pkts))
1979 self.verify_capture_out(capture)
1981 # out2in 2nd interface
1982 pkts = self.create_stream_out(self.pg3)
1983 self.pg3.add_stream(pkts)
1984 self.pg_enable_capture(self.pg_interfaces)
1986 capture = self.pg1.get_capture(len(pkts))
1987 self.verify_capture_in(capture, self.pg1)
1989 def test_inside_overlapping_interfaces(self):
1990 """ NAT44 multiple inside interfaces with overlapping address space """
1992 static_nat_ip = "10.0.0.10"
1993 self.nat44_add_address(self.nat_addr)
1994 flags = self.config_flags.NAT_IS_INSIDE
1995 self.vapi.nat44_interface_add_del_feature(
1996 sw_if_index=self.pg3.sw_if_index,
1998 self.vapi.nat44_interface_add_del_feature(
1999 sw_if_index=self.pg4.sw_if_index,
2000 flags=flags, is_add=1)
2001 self.vapi.nat44_interface_add_del_feature(
2002 sw_if_index=self.pg5.sw_if_index,
2003 flags=flags, is_add=1)
2004 self.vapi.nat44_interface_add_del_feature(
2005 sw_if_index=self.pg6.sw_if_index,
2006 flags=flags, is_add=1)
2007 self.nat44_add_static_mapping(self.pg6.remote_ip4, static_nat_ip,
2010 # between NAT44 inside interfaces with same VRF (no translation)
2011 pkts = self.create_stream_in(self.pg4, self.pg5)
2012 self.pg4.add_stream(pkts)
2013 self.pg_enable_capture(self.pg_interfaces)
2015 capture = self.pg5.get_capture(len(pkts))
2016 self.verify_capture_no_translation(capture, self.pg4, self.pg5)
2018 # between NAT44 inside interfaces with different VRF (hairpinning)
2019 p = (Ether(src=self.pg4.remote_mac, dst=self.pg4.local_mac) /
2020 IP(src=self.pg4.remote_ip4, dst=static_nat_ip) /
2021 TCP(sport=1234, dport=5678))
2022 self.pg4.add_stream(p)
2023 self.pg_enable_capture(self.pg_interfaces)
2025 capture = self.pg6.get_capture(1)
2030 self.assertEqual(ip.src, self.nat_addr)
2031 self.assertEqual(ip.dst, self.pg6.remote_ip4)
2032 self.assertNotEqual(tcp.sport, 1234)
2033 self.assertEqual(tcp.dport, 5678)
2035 self.logger.error(ppp("Unexpected or invalid packet:", p))
2038 # in2out 1st interface
2039 pkts = self.create_stream_in(self.pg4, self.pg3)
2040 self.pg4.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 1st 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.pg4.get_capture(len(pkts))
2052 self.verify_capture_in(capture, self.pg4)
2054 # in2out 2nd interface
2055 pkts = self.create_stream_in(self.pg5, self.pg3)
2056 self.pg5.add_stream(pkts)
2057 self.pg_enable_capture(self.pg_interfaces)
2059 capture = self.pg3.get_capture(len(pkts))
2060 self.verify_capture_out(capture)
2062 # out2in 2nd interface
2063 pkts = self.create_stream_out(self.pg3)
2064 self.pg3.add_stream(pkts)
2065 self.pg_enable_capture(self.pg_interfaces)
2067 capture = self.pg5.get_capture(len(pkts))
2068 self.verify_capture_in(capture, self.pg5)
2071 addresses = self.vapi.nat44_address_dump()
2072 self.assertEqual(len(addresses), 1)
2073 sessions = self.vapi.nat44_user_session_dump(self.pg5.remote_ip4, 10)
2074 self.assertEqual(len(sessions), 3)
2075 for session in sessions:
2076 self.assertFalse(session.flags & self.config_flags.NAT_IS_STATIC)
2077 self.assertEqual(str(session.inside_ip_address),
2078 self.pg5.remote_ip4)
2079 self.assertEqual(session.outside_ip_address,
2080 addresses[0].ip_address)
2081 self.assertEqual(sessions[0].protocol, IP_PROTOS.tcp)
2082 self.assertEqual(sessions[1].protocol, IP_PROTOS.udp)
2083 self.assertEqual(sessions[2].protocol, IP_PROTOS.icmp)
2084 self.assertEqual(sessions[0].inside_port, self.tcp_port_in)
2085 self.assertEqual(sessions[1].inside_port, self.udp_port_in)
2086 self.assertEqual(sessions[2].inside_port, self.icmp_id_in)
2087 self.assertEqual(sessions[0].outside_port, self.tcp_port_out)
2088 self.assertEqual(sessions[1].outside_port, self.udp_port_out)
2089 self.assertEqual(sessions[2].outside_port, self.icmp_id_out)
2091 # in2out 3rd interface
2092 pkts = self.create_stream_in(self.pg6, self.pg3)
2093 self.pg6.add_stream(pkts)
2094 self.pg_enable_capture(self.pg_interfaces)
2096 capture = self.pg3.get_capture(len(pkts))
2097 self.verify_capture_out(capture, static_nat_ip, True)
2099 # out2in 3rd interface
2100 pkts = self.create_stream_out(self.pg3, static_nat_ip)
2101 self.pg3.add_stream(pkts)
2102 self.pg_enable_capture(self.pg_interfaces)
2104 capture = self.pg6.get_capture(len(pkts))
2105 self.verify_capture_in(capture, self.pg6)
2107 # general user and session dump verifications
2108 users = self.vapi.nat44_user_dump()
2109 self.assertGreaterEqual(len(users), 3)
2110 addresses = self.vapi.nat44_address_dump()
2111 self.assertEqual(len(addresses), 1)
2113 sessions = self.vapi.nat44_user_session_dump(user.ip_address,
2115 for session in sessions:
2116 self.assertEqual(user.ip_address, session.inside_ip_address)
2117 self.assertTrue(session.total_bytes > session.total_pkts > 0)
2118 self.assertTrue(session.protocol in
2119 [IP_PROTOS.tcp, IP_PROTOS.udp,
2121 self.assertFalse(session.flags &
2122 self.config_flags.NAT_IS_EXT_HOST_VALID)
2125 sessions = self.vapi.nat44_user_session_dump(self.pg4.remote_ip4, 10)
2126 self.assertGreaterEqual(len(sessions), 4)
2127 for session in sessions:
2128 self.assertFalse(session.flags & self.config_flags.NAT_IS_STATIC)
2129 self.assertEqual(str(session.inside_ip_address),
2130 self.pg4.remote_ip4)
2131 self.assertEqual(session.outside_ip_address,
2132 addresses[0].ip_address)
2135 sessions = self.vapi.nat44_user_session_dump(self.pg6.remote_ip4, 20)
2136 self.assertGreaterEqual(len(sessions), 3)
2137 for session in sessions:
2138 self.assertTrue(session.flags & self.config_flags.NAT_IS_STATIC)
2139 self.assertEqual(str(session.inside_ip_address),
2140 self.pg6.remote_ip4)
2141 self.assertEqual(str(session.outside_ip_address),
2143 self.assertTrue(session.inside_port in
2144 [self.tcp_port_in, self.udp_port_in,
2147 def test_hairpinning(self):
2148 """ NAT44 hairpinning - 1:1 NAPT """
2150 host = self.pg0.remote_hosts[0]
2151 server = self.pg0.remote_hosts[1]
2154 server_in_port = 5678
2155 server_out_port = 8765
2157 self.nat44_add_address(self.nat_addr)
2158 flags = self.config_flags.NAT_IS_INSIDE
2159 self.vapi.nat44_interface_add_del_feature(
2160 sw_if_index=self.pg0.sw_if_index,
2161 flags=flags, is_add=1)
2162 self.vapi.nat44_interface_add_del_feature(
2163 sw_if_index=self.pg1.sw_if_index,
2166 # add static mapping for server
2167 self.nat44_add_static_mapping(server.ip4, self.nat_addr,
2168 server_in_port, server_out_port,
2169 proto=IP_PROTOS.tcp)
2171 cnt = self.statistics.get_counter('/nat44/hairpinning')[0]
2172 # send packet from host to server
2173 p = (Ether(src=host.mac, dst=self.pg0.local_mac) /
2174 IP(src=host.ip4, dst=self.nat_addr) /
2175 TCP(sport=host_in_port, dport=server_out_port))
2176 self.pg0.add_stream(p)
2177 self.pg_enable_capture(self.pg_interfaces)
2179 capture = self.pg0.get_capture(1)
2184 self.assertEqual(ip.src, self.nat_addr)
2185 self.assertEqual(ip.dst, server.ip4)
2186 self.assertNotEqual(tcp.sport, host_in_port)
2187 self.assertEqual(tcp.dport, server_in_port)
2188 self.assert_packet_checksums_valid(p)
2189 host_out_port = tcp.sport
2191 self.logger.error(ppp("Unexpected or invalid packet:", p))
2194 after = self.statistics.get_counter('/nat44/hairpinning')[0]
2195 if_idx = self.pg0.sw_if_index
2196 self.assertEqual(after[if_idx] - cnt[if_idx], 1)
2198 # send reply from server to host
2199 p = (Ether(src=server.mac, dst=self.pg0.local_mac) /
2200 IP(src=server.ip4, dst=self.nat_addr) /
2201 TCP(sport=server_in_port, dport=host_out_port))
2202 self.pg0.add_stream(p)
2203 self.pg_enable_capture(self.pg_interfaces)
2205 capture = self.pg0.get_capture(1)
2210 self.assertEqual(ip.src, self.nat_addr)
2211 self.assertEqual(ip.dst, host.ip4)
2212 self.assertEqual(tcp.sport, server_out_port)
2213 self.assertEqual(tcp.dport, host_in_port)
2214 self.assert_packet_checksums_valid(p)
2216 self.logger.error(ppp("Unexpected or invalid packet:", p))
2219 after = self.statistics.get_counter('/nat44/hairpinning')[0]
2220 if_idx = self.pg0.sw_if_index
2221 self.assertEqual(after[if_idx] - cnt[if_idx], 2)
2223 def test_hairpinning2(self):
2224 """ NAT44 hairpinning - 1:1 NAT"""
2226 server1_nat_ip = "10.0.0.10"
2227 server2_nat_ip = "10.0.0.11"
2228 host = self.pg0.remote_hosts[0]
2229 server1 = self.pg0.remote_hosts[1]
2230 server2 = self.pg0.remote_hosts[2]
2231 server_tcp_port = 22
2232 server_udp_port = 20
2234 self.nat44_add_address(self.nat_addr)
2235 flags = self.config_flags.NAT_IS_INSIDE
2236 self.vapi.nat44_interface_add_del_feature(
2237 sw_if_index=self.pg0.sw_if_index,
2238 flags=flags, is_add=1)
2239 self.vapi.nat44_interface_add_del_feature(
2240 sw_if_index=self.pg1.sw_if_index,
2243 # add static mapping for servers
2244 self.nat44_add_static_mapping(server1.ip4, server1_nat_ip)
2245 self.nat44_add_static_mapping(server2.ip4, server2_nat_ip)
2249 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2250 IP(src=host.ip4, dst=server1_nat_ip) /
2251 TCP(sport=self.tcp_port_in, dport=server_tcp_port))
2253 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2254 IP(src=host.ip4, dst=server1_nat_ip) /
2255 UDP(sport=self.udp_port_in, dport=server_udp_port))
2257 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2258 IP(src=host.ip4, dst=server1_nat_ip) /
2259 ICMP(id=self.icmp_id_in, type='echo-request'))
2261 self.pg0.add_stream(pkts)
2262 self.pg_enable_capture(self.pg_interfaces)
2264 capture = self.pg0.get_capture(len(pkts))
2265 for packet in capture:
2267 self.assertEqual(packet[IP].src, self.nat_addr)
2268 self.assertEqual(packet[IP].dst, server1.ip4)
2269 if packet.haslayer(TCP):
2270 self.assertNotEqual(packet[TCP].sport, self.tcp_port_in)
2271 self.assertEqual(packet[TCP].dport, server_tcp_port)
2272 self.tcp_port_out = packet[TCP].sport
2273 self.assert_packet_checksums_valid(packet)
2274 elif packet.haslayer(UDP):
2275 self.assertNotEqual(packet[UDP].sport, self.udp_port_in)
2276 self.assertEqual(packet[UDP].dport, server_udp_port)
2277 self.udp_port_out = packet[UDP].sport
2279 self.assertNotEqual(packet[ICMP].id, self.icmp_id_in)
2280 self.icmp_id_out = packet[ICMP].id
2282 self.logger.error(ppp("Unexpected or invalid packet:", packet))
2287 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2288 IP(src=server1.ip4, dst=self.nat_addr) /
2289 TCP(sport=server_tcp_port, dport=self.tcp_port_out))
2291 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2292 IP(src=server1.ip4, dst=self.nat_addr) /
2293 UDP(sport=server_udp_port, dport=self.udp_port_out))
2295 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2296 IP(src=server1.ip4, dst=self.nat_addr) /
2297 ICMP(id=self.icmp_id_out, type='echo-reply'))
2299 self.pg0.add_stream(pkts)
2300 self.pg_enable_capture(self.pg_interfaces)
2302 capture = self.pg0.get_capture(len(pkts))
2303 for packet in capture:
2305 self.assertEqual(packet[IP].src, server1_nat_ip)
2306 self.assertEqual(packet[IP].dst, host.ip4)
2307 if packet.haslayer(TCP):
2308 self.assertEqual(packet[TCP].dport, self.tcp_port_in)
2309 self.assertEqual(packet[TCP].sport, server_tcp_port)
2310 self.assert_packet_checksums_valid(packet)
2311 elif packet.haslayer(UDP):
2312 self.assertEqual(packet[UDP].dport, self.udp_port_in)
2313 self.assertEqual(packet[UDP].sport, server_udp_port)
2315 self.assertEqual(packet[ICMP].id, self.icmp_id_in)
2317 self.logger.error(ppp("Unexpected or invalid packet:", packet))
2320 # server2 to server1
2322 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2323 IP(src=server2.ip4, dst=server1_nat_ip) /
2324 TCP(sport=self.tcp_port_in, dport=server_tcp_port))
2326 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2327 IP(src=server2.ip4, dst=server1_nat_ip) /
2328 UDP(sport=self.udp_port_in, dport=server_udp_port))
2330 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2331 IP(src=server2.ip4, dst=server1_nat_ip) /
2332 ICMP(id=self.icmp_id_in, type='echo-request'))
2334 self.pg0.add_stream(pkts)
2335 self.pg_enable_capture(self.pg_interfaces)
2337 capture = self.pg0.get_capture(len(pkts))
2338 for packet in capture:
2340 self.assertEqual(packet[IP].src, server2_nat_ip)
2341 self.assertEqual(packet[IP].dst, server1.ip4)
2342 if packet.haslayer(TCP):
2343 self.assertEqual(packet[TCP].sport, self.tcp_port_in)
2344 self.assertEqual(packet[TCP].dport, server_tcp_port)
2345 self.tcp_port_out = packet[TCP].sport
2346 self.assert_packet_checksums_valid(packet)
2347 elif packet.haslayer(UDP):
2348 self.assertEqual(packet[UDP].sport, self.udp_port_in)
2349 self.assertEqual(packet[UDP].dport, server_udp_port)
2350 self.udp_port_out = packet[UDP].sport
2352 self.assertEqual(packet[ICMP].id, self.icmp_id_in)
2353 self.icmp_id_out = packet[ICMP].id
2355 self.logger.error(ppp("Unexpected or invalid packet:", packet))
2358 # server1 to server2
2360 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2361 IP(src=server1.ip4, dst=server2_nat_ip) /
2362 TCP(sport=server_tcp_port, dport=self.tcp_port_out))
2364 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2365 IP(src=server1.ip4, dst=server2_nat_ip) /
2366 UDP(sport=server_udp_port, dport=self.udp_port_out))
2368 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2369 IP(src=server1.ip4, dst=server2_nat_ip) /
2370 ICMP(id=self.icmp_id_out, type='echo-reply'))
2372 self.pg0.add_stream(pkts)
2373 self.pg_enable_capture(self.pg_interfaces)
2375 capture = self.pg0.get_capture(len(pkts))
2376 for packet in capture:
2378 self.assertEqual(packet[IP].src, server1_nat_ip)
2379 self.assertEqual(packet[IP].dst, server2.ip4)
2380 if packet.haslayer(TCP):
2381 self.assertEqual(packet[TCP].dport, self.tcp_port_in)
2382 self.assertEqual(packet[TCP].sport, server_tcp_port)
2383 self.assert_packet_checksums_valid(packet)
2384 elif packet.haslayer(UDP):
2385 self.assertEqual(packet[UDP].dport, self.udp_port_in)
2386 self.assertEqual(packet[UDP].sport, server_udp_port)
2388 self.assertEqual(packet[ICMP].id, self.icmp_id_in)
2390 self.logger.error(ppp("Unexpected or invalid packet:", packet))
2393 def test_interface_addr(self):
2394 """ Acquire NAT44 addresses from interface """
2395 self.vapi.nat44_add_del_interface_addr(
2397 sw_if_index=self.pg7.sw_if_index)
2399 # no address in NAT pool
2400 addresses = self.vapi.nat44_address_dump()
2401 self.assertEqual(0, len(addresses))
2403 # configure interface address and check NAT address pool
2404 self.pg7.config_ip4()
2405 addresses = self.vapi.nat44_address_dump()
2406 self.assertEqual(1, len(addresses))
2407 self.assertEqual(str(addresses[0].ip_address), self.pg7.local_ip4)
2409 # remove interface address and check NAT address pool
2410 self.pg7.unconfig_ip4()
2411 addresses = self.vapi.nat44_address_dump()
2412 self.assertEqual(0, len(addresses))
2414 def test_interface_addr_static_mapping(self):
2415 """ Static mapping with addresses from interface """
2418 self.vapi.nat44_add_del_interface_addr(
2420 sw_if_index=self.pg7.sw_if_index)
2421 self.nat44_add_static_mapping(
2423 external_sw_if_index=self.pg7.sw_if_index,
2426 # static mappings with external interface
2427 static_mappings = self.vapi.nat44_static_mapping_dump()
2428 self.assertEqual(1, len(static_mappings))
2429 self.assertEqual(self.pg7.sw_if_index,
2430 static_mappings[0].external_sw_if_index)
2431 self.assertEqual(static_mappings[0].tag, tag)
2433 # configure interface address and check static mappings
2434 self.pg7.config_ip4()
2435 static_mappings = self.vapi.nat44_static_mapping_dump()
2436 self.assertEqual(2, len(static_mappings))
2438 for sm in static_mappings:
2439 if sm.external_sw_if_index == 0xFFFFFFFF:
2440 self.assertEqual(str(sm.external_ip_address),
2442 self.assertEqual(sm.tag, tag)
2444 self.assertTrue(resolved)
2446 # remove interface address and check static mappings
2447 self.pg7.unconfig_ip4()
2448 static_mappings = self.vapi.nat44_static_mapping_dump()
2449 self.assertEqual(1, len(static_mappings))
2450 self.assertEqual(self.pg7.sw_if_index,
2451 static_mappings[0].external_sw_if_index)
2452 self.assertEqual(static_mappings[0].tag, tag)
2454 # configure interface address again and check static mappings
2455 self.pg7.config_ip4()
2456 static_mappings = self.vapi.nat44_static_mapping_dump()
2457 self.assertEqual(2, len(static_mappings))
2459 for sm in static_mappings:
2460 if sm.external_sw_if_index == 0xFFFFFFFF:
2461 self.assertEqual(str(sm.external_ip_address),
2463 self.assertEqual(sm.tag, tag)
2465 self.assertTrue(resolved)
2467 # remove static mapping
2468 self.nat44_add_static_mapping(
2470 external_sw_if_index=self.pg7.sw_if_index,
2473 static_mappings = self.vapi.nat44_static_mapping_dump()
2474 self.assertEqual(0, len(static_mappings))
2476 def test_interface_addr_identity_nat(self):
2477 """ Identity NAT with addresses from interface """
2480 self.vapi.nat44_add_del_interface_addr(
2482 sw_if_index=self.pg7.sw_if_index)
2483 self.vapi.nat44_add_del_identity_mapping(
2485 sw_if_index=self.pg7.sw_if_index,
2487 protocol=IP_PROTOS.tcp,
2490 # identity mappings with external interface
2491 identity_mappings = self.vapi.nat44_identity_mapping_dump()
2492 self.assertEqual(1, len(identity_mappings))
2493 self.assertEqual(self.pg7.sw_if_index,
2494 identity_mappings[0].sw_if_index)
2496 # configure interface address and check identity mappings
2497 self.pg7.config_ip4()
2498 identity_mappings = self.vapi.nat44_identity_mapping_dump()
2500 self.assertEqual(2, len(identity_mappings))
2501 for sm in identity_mappings:
2502 if sm.sw_if_index == 0xFFFFFFFF:
2503 self.assertEqual(str(identity_mappings[0].ip_address),
2505 self.assertEqual(port, identity_mappings[0].port)
2506 self.assertEqual(IP_PROTOS.tcp, identity_mappings[0].protocol)
2508 self.assertTrue(resolved)
2510 # remove interface address and check identity mappings
2511 self.pg7.unconfig_ip4()
2512 identity_mappings = self.vapi.nat44_identity_mapping_dump()
2513 self.assertEqual(1, len(identity_mappings))
2514 self.assertEqual(self.pg7.sw_if_index,
2515 identity_mappings[0].sw_if_index)
2517 def test_ipfix_nat44_sess(self):
2518 """ IPFIX logging NAT44 session created/deleted """
2519 self.ipfix_domain_id = 10
2520 self.ipfix_src_port = 20202
2521 collector_port = 30303
2522 bind_layers(UDP, IPFIX, dport=30303)
2523 self.nat44_add_address(self.nat_addr)
2524 flags = self.config_flags.NAT_IS_INSIDE
2525 self.vapi.nat44_interface_add_del_feature(
2526 sw_if_index=self.pg0.sw_if_index,
2527 flags=flags, is_add=1)
2528 self.vapi.nat44_interface_add_del_feature(
2529 sw_if_index=self.pg1.sw_if_index,
2531 self.vapi.set_ipfix_exporter(collector_address=self.pg3.remote_ip4,
2532 src_address=self.pg3.local_ip4,
2534 template_interval=10,
2535 collector_port=collector_port)
2536 self.vapi.nat_ipfix_enable_disable(domain_id=self.ipfix_domain_id,
2537 src_port=self.ipfix_src_port,
2540 pkts = self.create_stream_in(self.pg0, self.pg1)
2541 self.pg0.add_stream(pkts)
2542 self.pg_enable_capture(self.pg_interfaces)
2544 capture = self.pg1.get_capture(len(pkts))
2545 self.verify_capture_out(capture)
2546 self.nat44_add_address(self.nat_addr, is_add=0)
2547 self.vapi.ipfix_flush()
2548 capture = self.pg3.get_capture(7)
2549 ipfix = IPFIXDecoder()
2550 # first load template
2552 self.assertTrue(p.haslayer(IPFIX))
2553 self.assertEqual(p[IP].src, self.pg3.local_ip4)
2554 self.assertEqual(p[IP].dst, self.pg3.remote_ip4)
2555 self.assertEqual(p[UDP].sport, self.ipfix_src_port)
2556 self.assertEqual(p[UDP].dport, collector_port)
2557 self.assertEqual(p[IPFIX].observationDomainID,
2558 self.ipfix_domain_id)
2559 if p.haslayer(Template):
2560 ipfix.add_template(p.getlayer(Template))
2561 # verify events in data set
2563 if p.haslayer(Data):
2564 data = ipfix.decode_data_set(p.getlayer(Set))
2565 self.verify_ipfix_nat44_ses(data)
2567 def test_ipfix_addr_exhausted(self):
2568 """ IPFIX logging NAT addresses exhausted """
2569 flags = self.config_flags.NAT_IS_INSIDE
2570 self.vapi.nat44_interface_add_del_feature(
2571 sw_if_index=self.pg0.sw_if_index,
2572 flags=flags, is_add=1)
2573 self.vapi.nat44_interface_add_del_feature(
2574 sw_if_index=self.pg1.sw_if_index,
2576 self.vapi.set_ipfix_exporter(collector_address=self.pg3.remote_ip4,
2577 src_address=self.pg3.local_ip4,
2579 template_interval=10)
2580 self.vapi.nat_ipfix_enable_disable(domain_id=self.ipfix_domain_id,
2581 src_port=self.ipfix_src_port,
2584 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
2585 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
2587 self.pg0.add_stream(p)
2588 self.pg_enable_capture(self.pg_interfaces)
2590 self.pg1.assert_nothing_captured()
2592 self.vapi.ipfix_flush()
2593 capture = self.pg3.get_capture(7)
2594 ipfix = IPFIXDecoder()
2595 # first load template
2597 self.assertTrue(p.haslayer(IPFIX))
2598 self.assertEqual(p[IP].src, self.pg3.local_ip4)
2599 self.assertEqual(p[IP].dst, self.pg3.remote_ip4)
2600 self.assertEqual(p[UDP].sport, self.ipfix_src_port)
2601 self.assertEqual(p[UDP].dport, 4739)
2602 self.assertEqual(p[IPFIX].observationDomainID,
2603 self.ipfix_domain_id)
2604 if p.haslayer(Template):
2605 ipfix.add_template(p.getlayer(Template))
2606 # verify events in data set
2608 if p.haslayer(Data):
2609 data = ipfix.decode_data_set(p.getlayer(Set))
2610 self.verify_ipfix_addr_exhausted(data)
2612 @unittest.skipUnless(running_extended_tests, "part of extended tests")
2613 def test_ipfix_max_sessions(self):
2614 """ IPFIX logging maximum session entries exceeded """
2615 self.nat44_add_address(self.nat_addr)
2616 flags = self.config_flags.NAT_IS_INSIDE
2617 self.vapi.nat44_interface_add_del_feature(
2618 sw_if_index=self.pg0.sw_if_index,
2619 flags=flags, is_add=1)
2620 self.vapi.nat44_interface_add_del_feature(
2621 sw_if_index=self.pg1.sw_if_index,
2624 max_sessions = self.max_translations
2627 for i in range(0, max_sessions):
2628 src = "10.10.%u.%u" % ((i & 0xFF00) >> 8, i & 0xFF)
2629 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2630 IP(src=src, dst=self.pg1.remote_ip4) /
2633 self.pg0.add_stream(pkts)
2634 self.pg_enable_capture(self.pg_interfaces)
2637 self.pg1.get_capture(max_sessions)
2638 self.vapi.set_ipfix_exporter(collector_address=self.pg3.remote_ip4,
2639 src_address=self.pg3.local_ip4,
2641 template_interval=10)
2642 self.vapi.nat_ipfix_enable_disable(domain_id=self.ipfix_domain_id,
2643 src_port=self.ipfix_src_port,
2646 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2647 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
2649 self.pg0.add_stream(p)
2650 self.pg_enable_capture(self.pg_interfaces)
2652 self.pg1.assert_nothing_captured()
2654 self.vapi.ipfix_flush()
2655 capture = self.pg3.get_capture(7)
2656 ipfix = IPFIXDecoder()
2657 # first load template
2659 self.assertTrue(p.haslayer(IPFIX))
2660 self.assertEqual(p[IP].src, self.pg3.local_ip4)
2661 self.assertEqual(p[IP].dst, self.pg3.remote_ip4)
2662 self.assertEqual(p[UDP].sport, self.ipfix_src_port)
2663 self.assertEqual(p[UDP].dport, 4739)
2664 self.assertEqual(p[IPFIX].observationDomainID,
2665 self.ipfix_domain_id)
2666 if p.haslayer(Template):
2667 ipfix.add_template(p.getlayer(Template))
2668 # verify events in data set
2670 if p.haslayer(Data):
2671 data = ipfix.decode_data_set(p.getlayer(Set))
2672 self.verify_ipfix_max_sessions(data, max_sessions)
2674 def test_syslog_apmap(self):
2675 """ Test syslog address and port mapping creation and deletion """
2676 self.vapi.syslog_set_filter(
2677 self.SYSLOG_SEVERITY.SYSLOG_API_SEVERITY_INFO)
2678 self.vapi.syslog_set_sender(self.pg3.local_ip4, self.pg3.remote_ip4)
2679 self.nat44_add_address(self.nat_addr)
2680 flags = self.config_flags.NAT_IS_INSIDE
2681 self.vapi.nat44_interface_add_del_feature(
2682 sw_if_index=self.pg0.sw_if_index,
2683 flags=flags, is_add=1)
2684 self.vapi.nat44_interface_add_del_feature(
2685 sw_if_index=self.pg1.sw_if_index,
2688 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2689 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
2690 TCP(sport=self.tcp_port_in, dport=20))
2691 self.pg0.add_stream(p)
2692 self.pg_enable_capture(self.pg_interfaces)
2694 capture = self.pg1.get_capture(1)
2695 self.tcp_port_out = capture[0][TCP].sport
2696 capture = self.pg3.get_capture(1)
2697 self.verify_syslog_apmap(capture[0][Raw].load)
2699 self.pg_enable_capture(self.pg_interfaces)
2701 self.nat44_add_address(self.nat_addr, is_add=0)
2702 capture = self.pg3.get_capture(1)
2703 self.verify_syslog_apmap(capture[0][Raw].load, False)
2705 def test_pool_addr_fib(self):
2706 """ NAT44 add pool addresses to FIB """
2707 static_addr = '10.0.0.10'
2708 self.nat44_add_address(self.nat_addr)
2709 flags = self.config_flags.NAT_IS_INSIDE
2710 self.vapi.nat44_interface_add_del_feature(
2711 sw_if_index=self.pg0.sw_if_index,
2712 flags=flags, is_add=1)
2713 self.vapi.nat44_interface_add_del_feature(
2714 sw_if_index=self.pg1.sw_if_index,
2716 self.nat44_add_static_mapping(self.pg0.remote_ip4, static_addr)
2719 p = (Ether(src=self.pg1.remote_mac, dst='ff:ff:ff:ff:ff:ff') /
2720 ARP(op=ARP.who_has, pdst=self.nat_addr,
2721 psrc=self.pg1.remote_ip4, hwsrc=self.pg1.remote_mac))
2722 self.pg1.add_stream(p)
2723 self.pg_enable_capture(self.pg_interfaces)
2725 capture = self.pg1.get_capture(1)
2726 self.assertTrue(capture[0].haslayer(ARP))
2727 self.assertTrue(capture[0][ARP].op, ARP.is_at)
2730 p = (Ether(src=self.pg1.remote_mac, dst='ff:ff:ff:ff:ff:ff') /
2731 ARP(op=ARP.who_has, pdst=static_addr,
2732 psrc=self.pg1.remote_ip4, hwsrc=self.pg1.remote_mac))
2733 self.pg1.add_stream(p)
2734 self.pg_enable_capture(self.pg_interfaces)
2736 capture = self.pg1.get_capture(1)
2737 self.assertTrue(capture[0].haslayer(ARP))
2738 self.assertTrue(capture[0][ARP].op, ARP.is_at)
2740 # send ARP to non-NAT44 interface
2741 p = (Ether(src=self.pg2.remote_mac, dst='ff:ff:ff:ff:ff:ff') /
2742 ARP(op=ARP.who_has, pdst=self.nat_addr,
2743 psrc=self.pg2.remote_ip4, hwsrc=self.pg2.remote_mac))
2744 self.pg2.add_stream(p)
2745 self.pg_enable_capture(self.pg_interfaces)
2747 self.pg1.assert_nothing_captured()
2749 # remove addresses and verify
2750 self.nat44_add_address(self.nat_addr, is_add=0)
2751 self.nat44_add_static_mapping(self.pg0.remote_ip4, static_addr,
2754 p = (Ether(src=self.pg1.remote_mac, dst='ff:ff:ff:ff:ff:ff') /
2755 ARP(op=ARP.who_has, pdst=self.nat_addr,
2756 psrc=self.pg1.remote_ip4, hwsrc=self.pg1.remote_mac))
2757 self.pg1.add_stream(p)
2758 self.pg_enable_capture(self.pg_interfaces)
2760 self.pg1.assert_nothing_captured()
2762 p = (Ether(src=self.pg1.remote_mac, dst='ff:ff:ff:ff:ff:ff') /
2763 ARP(op=ARP.who_has, pdst=static_addr,
2764 psrc=self.pg1.remote_ip4, hwsrc=self.pg1.remote_mac))
2765 self.pg1.add_stream(p)
2766 self.pg_enable_capture(self.pg_interfaces)
2768 self.pg1.assert_nothing_captured()
2770 def test_vrf_mode(self):
2771 """ NAT44 tenant VRF aware address pool mode """
2775 nat_ip1 = "10.0.0.10"
2776 nat_ip2 = "10.0.0.11"
2778 self.pg0.unconfig_ip4()
2779 self.pg1.unconfig_ip4()
2780 self.vapi.ip_table_add_del(is_add=1, table={'table_id': vrf_id1})
2781 self.vapi.ip_table_add_del(is_add=1, table={'table_id': vrf_id2})
2782 self.pg0.set_table_ip4(vrf_id1)
2783 self.pg1.set_table_ip4(vrf_id2)
2784 self.pg0.config_ip4()
2785 self.pg1.config_ip4()
2786 self.pg0.resolve_arp()
2787 self.pg1.resolve_arp()
2789 self.nat44_add_address(nat_ip1, vrf_id=vrf_id1)
2790 self.nat44_add_address(nat_ip2, vrf_id=vrf_id2)
2791 flags = self.config_flags.NAT_IS_INSIDE
2792 self.vapi.nat44_interface_add_del_feature(
2793 sw_if_index=self.pg0.sw_if_index,
2794 flags=flags, is_add=1)
2795 self.vapi.nat44_interface_add_del_feature(
2796 sw_if_index=self.pg1.sw_if_index,
2797 flags=flags, is_add=1)
2798 self.vapi.nat44_interface_add_del_feature(
2799 sw_if_index=self.pg2.sw_if_index,
2804 pkts = self.create_stream_in(self.pg0, self.pg2)
2805 self.pg0.add_stream(pkts)
2806 self.pg_enable_capture(self.pg_interfaces)
2808 capture = self.pg2.get_capture(len(pkts))
2809 self.verify_capture_out(capture, nat_ip1)
2812 pkts = self.create_stream_in(self.pg1, self.pg2)
2813 self.pg1.add_stream(pkts)
2814 self.pg_enable_capture(self.pg_interfaces)
2816 capture = self.pg2.get_capture(len(pkts))
2817 self.verify_capture_out(capture, nat_ip2)
2820 self.pg0.unconfig_ip4()
2821 self.pg1.unconfig_ip4()
2822 self.pg0.set_table_ip4(0)
2823 self.pg1.set_table_ip4(0)
2824 self.pg0.config_ip4()
2825 self.pg1.config_ip4()
2826 self.pg0.resolve_arp()
2827 self.pg1.resolve_arp()
2828 self.vapi.ip_table_add_del(is_add=0, table={'table_id': vrf_id1})
2829 self.vapi.ip_table_add_del(is_add=0, table={'table_id': vrf_id2})
2831 def test_vrf_feature_independent(self):
2832 """ NAT44 tenant VRF independent address pool mode """
2834 nat_ip1 = "10.0.0.10"
2835 nat_ip2 = "10.0.0.11"
2837 self.nat44_add_address(nat_ip1)
2838 self.nat44_add_address(nat_ip2, vrf_id=99)
2839 flags = self.config_flags.NAT_IS_INSIDE
2840 self.vapi.nat44_interface_add_del_feature(
2841 sw_if_index=self.pg0.sw_if_index,
2842 flags=flags, is_add=1)
2843 self.vapi.nat44_interface_add_del_feature(
2844 sw_if_index=self.pg1.sw_if_index,
2845 flags=flags, is_add=1)
2846 self.vapi.nat44_interface_add_del_feature(
2847 sw_if_index=self.pg2.sw_if_index,
2851 pkts = self.create_stream_in(self.pg0, self.pg2)
2852 self.pg0.add_stream(pkts)
2853 self.pg_enable_capture(self.pg_interfaces)
2855 capture = self.pg2.get_capture(len(pkts))
2856 self.verify_capture_out(capture, nat_ip1)
2859 pkts = self.create_stream_in(self.pg1, self.pg2)
2860 self.pg1.add_stream(pkts)
2861 self.pg_enable_capture(self.pg_interfaces)
2863 capture = self.pg2.get_capture(len(pkts))
2864 self.verify_capture_out(capture, nat_ip1)
2866 def create_routes_and_neigbors(self):
2867 r1 = VppIpRoute(self, self.pg7.remote_ip4, 32,
2868 [VppRoutePath(self.pg7.remote_ip4,
2869 self.pg7.sw_if_index)])
2870 r2 = VppIpRoute(self, self.pg8.remote_ip4, 32,
2871 [VppRoutePath(self.pg8.remote_ip4,
2872 self.pg8.sw_if_index)])
2876 n1 = VppNeighbor(self,
2877 self.pg7.sw_if_index,
2878 self.pg7.remote_mac,
2879 self.pg7.remote_ip4,
2881 n2 = VppNeighbor(self,
2882 self.pg8.sw_if_index,
2883 self.pg8.remote_mac,
2884 self.pg8.remote_ip4,
2889 def test_dynamic_ipless_interfaces(self):
2890 """ NAT44 interfaces without configured IP address """
2891 self.create_routes_and_neigbors()
2892 self.nat44_add_address(self.nat_addr)
2893 flags = self.config_flags.NAT_IS_INSIDE
2894 self.vapi.nat44_interface_add_del_feature(
2895 sw_if_index=self.pg7.sw_if_index,
2896 flags=flags, is_add=1)
2897 self.vapi.nat44_interface_add_del_feature(
2898 sw_if_index=self.pg8.sw_if_index,
2902 pkts = self.create_stream_in(self.pg7, self.pg8)
2903 self.pg7.add_stream(pkts)
2904 self.pg_enable_capture(self.pg_interfaces)
2906 capture = self.pg8.get_capture(len(pkts))
2907 self.verify_capture_out(capture)
2910 pkts = self.create_stream_out(self.pg8, self.nat_addr)
2911 self.pg8.add_stream(pkts)
2912 self.pg_enable_capture(self.pg_interfaces)
2914 capture = self.pg7.get_capture(len(pkts))
2915 self.verify_capture_in(capture, self.pg7)
2917 def test_static_ipless_interfaces(self):
2918 """ NAT44 interfaces without configured IP address - 1:1 NAT """
2920 self.create_routes_and_neigbors()
2921 self.nat44_add_static_mapping(self.pg7.remote_ip4, self.nat_addr)
2922 flags = self.config_flags.NAT_IS_INSIDE
2923 self.vapi.nat44_interface_add_del_feature(
2924 sw_if_index=self.pg7.sw_if_index,
2925 flags=flags, is_add=1)
2926 self.vapi.nat44_interface_add_del_feature(
2927 sw_if_index=self.pg8.sw_if_index,
2931 pkts = self.create_stream_out(self.pg8)
2932 self.pg8.add_stream(pkts)
2933 self.pg_enable_capture(self.pg_interfaces)
2935 capture = self.pg7.get_capture(len(pkts))
2936 self.verify_capture_in(capture, self.pg7)
2939 pkts = self.create_stream_in(self.pg7, self.pg8)
2940 self.pg7.add_stream(pkts)
2941 self.pg_enable_capture(self.pg_interfaces)
2943 capture = self.pg8.get_capture(len(pkts))
2944 self.verify_capture_out(capture, self.nat_addr, True)
2946 def test_static_with_port_ipless_interfaces(self):
2947 """ NAT44 interfaces without configured IP address - 1:1 NAPT """
2949 self.tcp_port_out = 30606
2950 self.udp_port_out = 30607
2951 self.icmp_id_out = 30608
2953 self.create_routes_and_neigbors()
2954 self.nat44_add_address(self.nat_addr)
2955 self.nat44_add_static_mapping(self.pg7.remote_ip4, self.nat_addr,
2956 self.tcp_port_in, self.tcp_port_out,
2957 proto=IP_PROTOS.tcp)
2958 self.nat44_add_static_mapping(self.pg7.remote_ip4, self.nat_addr,
2959 self.udp_port_in, self.udp_port_out,
2960 proto=IP_PROTOS.udp)
2961 self.nat44_add_static_mapping(self.pg7.remote_ip4, self.nat_addr,
2962 self.icmp_id_in, self.icmp_id_out,
2963 proto=IP_PROTOS.icmp)
2964 flags = self.config_flags.NAT_IS_INSIDE
2965 self.vapi.nat44_interface_add_del_feature(
2966 sw_if_index=self.pg7.sw_if_index,
2967 flags=flags, is_add=1)
2968 self.vapi.nat44_interface_add_del_feature(
2969 sw_if_index=self.pg8.sw_if_index,
2973 pkts = self.create_stream_out(self.pg8)
2974 self.pg8.add_stream(pkts)
2975 self.pg_enable_capture(self.pg_interfaces)
2977 capture = self.pg7.get_capture(len(pkts))
2978 self.verify_capture_in(capture, self.pg7)
2981 pkts = self.create_stream_in(self.pg7, self.pg8)
2982 self.pg7.add_stream(pkts)
2983 self.pg_enable_capture(self.pg_interfaces)
2985 capture = self.pg8.get_capture(len(pkts))
2986 self.verify_capture_out(capture)
2988 def test_static_unknown_proto(self):
2989 """ 1:1 NAT translate packet with unknown protocol """
2990 nat_ip = "10.0.0.10"
2991 self.nat44_add_static_mapping(self.pg0.remote_ip4, nat_ip)
2992 flags = self.config_flags.NAT_IS_INSIDE
2993 self.vapi.nat44_interface_add_del_feature(
2994 sw_if_index=self.pg0.sw_if_index,
2995 flags=flags, is_add=1)
2996 self.vapi.nat44_interface_add_del_feature(
2997 sw_if_index=self.pg1.sw_if_index,
3001 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
3002 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
3004 IP(src=self.pg2.remote_ip4, dst=self.pg3.remote_ip4) /
3005 TCP(sport=1234, dport=1234))
3006 self.pg0.add_stream(p)
3007 self.pg_enable_capture(self.pg_interfaces)
3009 p = self.pg1.get_capture(1)
3012 self.assertEqual(packet[IP].src, nat_ip)
3013 self.assertEqual(packet[IP].dst, self.pg1.remote_ip4)
3014 self.assertEqual(packet.haslayer(GRE), 1)
3015 self.assert_packet_checksums_valid(packet)
3017 self.logger.error(ppp("Unexpected or invalid packet:", packet))
3021 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
3022 IP(src=self.pg1.remote_ip4, dst=nat_ip) /
3024 IP(src=self.pg3.remote_ip4, dst=self.pg2.remote_ip4) /
3025 TCP(sport=1234, dport=1234))
3026 self.pg1.add_stream(p)
3027 self.pg_enable_capture(self.pg_interfaces)
3029 p = self.pg0.get_capture(1)
3032 self.assertEqual(packet[IP].src, self.pg1.remote_ip4)
3033 self.assertEqual(packet[IP].dst, self.pg0.remote_ip4)
3034 self.assertEqual(packet.haslayer(GRE), 1)
3035 self.assert_packet_checksums_valid(packet)
3037 self.logger.error(ppp("Unexpected or invalid packet:", packet))
3040 def test_hairpinning_static_unknown_proto(self):
3041 """ 1:1 NAT translate packet with unknown protocol - hairpinning """
3043 host = self.pg0.remote_hosts[0]
3044 server = self.pg0.remote_hosts[1]
3046 host_nat_ip = "10.0.0.10"
3047 server_nat_ip = "10.0.0.11"
3049 self.nat44_add_static_mapping(host.ip4, host_nat_ip)
3050 self.nat44_add_static_mapping(server.ip4, server_nat_ip)
3051 flags = self.config_flags.NAT_IS_INSIDE
3052 self.vapi.nat44_interface_add_del_feature(
3053 sw_if_index=self.pg0.sw_if_index,
3054 flags=flags, is_add=1)
3055 self.vapi.nat44_interface_add_del_feature(
3056 sw_if_index=self.pg1.sw_if_index,
3060 p = (Ether(dst=self.pg0.local_mac, src=host.mac) /
3061 IP(src=host.ip4, dst=server_nat_ip) /
3063 IP(src=self.pg2.remote_ip4, dst=self.pg3.remote_ip4) /
3064 TCP(sport=1234, dport=1234))
3065 self.pg0.add_stream(p)
3066 self.pg_enable_capture(self.pg_interfaces)
3068 p = self.pg0.get_capture(1)
3071 self.assertEqual(packet[IP].src, host_nat_ip)
3072 self.assertEqual(packet[IP].dst, server.ip4)
3073 self.assertEqual(packet.haslayer(GRE), 1)
3074 self.assert_packet_checksums_valid(packet)
3076 self.logger.error(ppp("Unexpected or invalid packet:", packet))
3080 p = (Ether(dst=self.pg0.local_mac, src=server.mac) /
3081 IP(src=server.ip4, dst=host_nat_ip) /
3083 IP(src=self.pg3.remote_ip4, dst=self.pg2.remote_ip4) /
3084 TCP(sport=1234, dport=1234))
3085 self.pg0.add_stream(p)
3086 self.pg_enable_capture(self.pg_interfaces)
3088 p = self.pg0.get_capture(1)
3091 self.assertEqual(packet[IP].src, server_nat_ip)
3092 self.assertEqual(packet[IP].dst, host.ip4)
3093 self.assertEqual(packet.haslayer(GRE), 1)
3094 self.assert_packet_checksums_valid(packet)
3096 self.logger.error(ppp("Unexpected or invalid packet:", packet))
3099 def test_output_feature(self):
3100 """ NAT44 interface output feature (in2out postrouting) """
3101 self.nat44_add_address(self.nat_addr)
3102 flags = self.config_flags.NAT_IS_INSIDE
3103 self.vapi.nat44_interface_add_del_output_feature(
3104 is_add=1, flags=flags,
3105 sw_if_index=self.pg0.sw_if_index)
3106 self.vapi.nat44_interface_add_del_output_feature(
3107 is_add=1, flags=flags,
3108 sw_if_index=self.pg1.sw_if_index)
3109 self.vapi.nat44_interface_add_del_output_feature(
3111 sw_if_index=self.pg3.sw_if_index)
3114 pkts = self.create_stream_in(self.pg0, self.pg3)
3115 self.pg0.add_stream(pkts)
3116 self.pg_enable_capture(self.pg_interfaces)
3118 capture = self.pg3.get_capture(len(pkts))
3119 self.verify_capture_out(capture)
3122 pkts = self.create_stream_out(self.pg3)
3123 self.pg3.add_stream(pkts)
3124 self.pg_enable_capture(self.pg_interfaces)
3126 capture = self.pg0.get_capture(len(pkts))
3127 self.verify_capture_in(capture, self.pg0)
3129 # from non-NAT interface to NAT inside interface
3130 pkts = self.create_stream_in(self.pg2, self.pg0)
3131 self.pg2.add_stream(pkts)
3132 self.pg_enable_capture(self.pg_interfaces)
3134 capture = self.pg0.get_capture(len(pkts))
3135 self.verify_capture_no_translation(capture, self.pg2, self.pg0)
3137 def test_output_feature_vrf_aware(self):
3138 """ NAT44 interface output feature VRF aware (in2out postrouting) """
3139 nat_ip_vrf10 = "10.0.0.10"
3140 nat_ip_vrf20 = "10.0.0.20"
3142 r1 = VppIpRoute(self, self.pg3.remote_ip4, 32,
3143 [VppRoutePath(self.pg3.remote_ip4,
3144 self.pg3.sw_if_index)],
3146 r2 = VppIpRoute(self, self.pg3.remote_ip4, 32,
3147 [VppRoutePath(self.pg3.remote_ip4,
3148 self.pg3.sw_if_index)],
3153 self.nat44_add_address(nat_ip_vrf10, vrf_id=10)
3154 self.nat44_add_address(nat_ip_vrf20, vrf_id=20)
3155 flags = self.config_flags.NAT_IS_INSIDE
3156 self.vapi.nat44_interface_add_del_output_feature(
3157 is_add=1, flags=flags,
3158 sw_if_index=self.pg4.sw_if_index)
3159 self.vapi.nat44_interface_add_del_output_feature(
3160 is_add=1, flags=flags,
3161 sw_if_index=self.pg6.sw_if_index)
3162 self.vapi.nat44_interface_add_del_output_feature(
3164 sw_if_index=self.pg3.sw_if_index)
3167 pkts = self.create_stream_in(self.pg4, self.pg3)
3168 self.pg4.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_vrf10)
3175 pkts = self.create_stream_out(self.pg3, dst_ip=nat_ip_vrf10)
3176 self.pg3.add_stream(pkts)
3177 self.pg_enable_capture(self.pg_interfaces)
3179 capture = self.pg4.get_capture(len(pkts))
3180 self.verify_capture_in(capture, self.pg4)
3183 pkts = self.create_stream_in(self.pg6, self.pg3)
3184 self.pg6.add_stream(pkts)
3185 self.pg_enable_capture(self.pg_interfaces)
3187 capture = self.pg3.get_capture(len(pkts))
3188 self.verify_capture_out(capture, nat_ip=nat_ip_vrf20)
3191 pkts = self.create_stream_out(self.pg3, dst_ip=nat_ip_vrf20)
3192 self.pg3.add_stream(pkts)
3193 self.pg_enable_capture(self.pg_interfaces)
3195 capture = self.pg6.get_capture(len(pkts))
3196 self.verify_capture_in(capture, self.pg6)
3198 def test_output_feature_hairpinning(self):
3199 """ NAT44 interface output feature hairpinning (in2out postrouting) """
3200 host = self.pg0.remote_hosts[0]
3201 server = self.pg0.remote_hosts[1]
3204 server_in_port = 5678
3205 server_out_port = 8765
3207 self.nat44_add_address(self.nat_addr)
3208 flags = self.config_flags.NAT_IS_INSIDE
3209 self.vapi.nat44_interface_add_del_output_feature(
3210 is_add=1, flags=flags,
3211 sw_if_index=self.pg0.sw_if_index)
3212 self.vapi.nat44_interface_add_del_output_feature(
3214 sw_if_index=self.pg1.sw_if_index)
3216 # add static mapping for server
3217 self.nat44_add_static_mapping(server.ip4, self.nat_addr,
3218 server_in_port, server_out_port,
3219 proto=IP_PROTOS.tcp)
3221 # send packet from host to server
3222 p = (Ether(src=host.mac, dst=self.pg0.local_mac) /
3223 IP(src=host.ip4, dst=self.nat_addr) /
3224 TCP(sport=host_in_port, dport=server_out_port))
3225 self.pg0.add_stream(p)
3226 self.pg_enable_capture(self.pg_interfaces)
3228 capture = self.pg0.get_capture(1)
3233 self.assertEqual(ip.src, self.nat_addr)
3234 self.assertEqual(ip.dst, server.ip4)
3235 self.assertNotEqual(tcp.sport, host_in_port)
3236 self.assertEqual(tcp.dport, server_in_port)
3237 self.assert_packet_checksums_valid(p)
3238 host_out_port = tcp.sport
3240 self.logger.error(ppp("Unexpected or invalid packet:", p))
3243 # send reply from server to host
3244 p = (Ether(src=server.mac, dst=self.pg0.local_mac) /
3245 IP(src=server.ip4, dst=self.nat_addr) /
3246 TCP(sport=server_in_port, dport=host_out_port))
3247 self.pg0.add_stream(p)
3248 self.pg_enable_capture(self.pg_interfaces)
3250 capture = self.pg0.get_capture(1)
3255 self.assertEqual(ip.src, self.nat_addr)
3256 self.assertEqual(ip.dst, host.ip4)
3257 self.assertEqual(tcp.sport, server_out_port)
3258 self.assertEqual(tcp.dport, host_in_port)
3259 self.assert_packet_checksums_valid(p)
3261 self.logger.error(ppp("Unexpected or invalid packet:", p))
3264 def test_one_armed_nat44(self):
3265 """ One armed NAT44 """
3266 remote_host = self.pg9.remote_hosts[0]
3267 local_host = self.pg9.remote_hosts[1]
3270 self.nat44_add_address(self.nat_addr)
3271 flags = self.config_flags.NAT_IS_INSIDE
3272 self.vapi.nat44_interface_add_del_feature(
3273 sw_if_index=self.pg9.sw_if_index,
3275 self.vapi.nat44_interface_add_del_feature(
3276 sw_if_index=self.pg9.sw_if_index,
3277 flags=flags, is_add=1)
3280 p = (Ether(src=self.pg9.remote_mac, dst=self.pg9.local_mac) /
3281 IP(src=local_host.ip4, dst=remote_host.ip4) /
3282 TCP(sport=12345, dport=80))
3283 self.pg9.add_stream(p)
3284 self.pg_enable_capture(self.pg_interfaces)
3286 capture = self.pg9.get_capture(1)
3291 self.assertEqual(ip.src, self.nat_addr)
3292 self.assertEqual(ip.dst, remote_host.ip4)
3293 self.assertNotEqual(tcp.sport, 12345)
3294 external_port = tcp.sport
3295 self.assertEqual(tcp.dport, 80)
3296 self.assert_packet_checksums_valid(p)
3298 self.logger.error(ppp("Unexpected or invalid packet:", p))
3302 p = (Ether(src=self.pg9.remote_mac, dst=self.pg9.local_mac) /
3303 IP(src=remote_host.ip4, dst=self.nat_addr) /
3304 TCP(sport=80, dport=external_port))
3305 self.pg9.add_stream(p)
3306 self.pg_enable_capture(self.pg_interfaces)
3308 capture = self.pg9.get_capture(1)
3313 self.assertEqual(ip.src, remote_host.ip4)
3314 self.assertEqual(ip.dst, local_host.ip4)
3315 self.assertEqual(tcp.sport, 80)
3316 self.assertEqual(tcp.dport, 12345)
3317 self.assert_packet_checksums_valid(p)
3319 self.logger.error(ppp("Unexpected or invalid packet:", p))
3322 err = self.statistics.get_err_counter(
3323 '/err/nat44-classify/next in2out')
3324 self.assertEqual(err, 1)
3325 err = self.statistics.get_err_counter(
3326 '/err/nat44-classify/next out2in')
3327 self.assertEqual(err, 1)
3329 def test_del_session(self):
3330 """ Delete NAT44 session """
3331 self.nat44_add_address(self.nat_addr)
3332 flags = self.config_flags.NAT_IS_INSIDE
3333 self.vapi.nat44_interface_add_del_feature(
3334 sw_if_index=self.pg0.sw_if_index,
3335 flags=flags, is_add=1)
3336 self.vapi.nat44_interface_add_del_feature(
3337 sw_if_index=self.pg1.sw_if_index,
3340 pkts = self.create_stream_in(self.pg0, self.pg1)
3341 self.pg0.add_stream(pkts)
3342 self.pg_enable_capture(self.pg_interfaces)
3344 self.pg1.get_capture(len(pkts))
3346 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4, 0)
3347 nsessions = len(sessions)
3349 self.vapi.nat44_del_session(address=sessions[0].inside_ip_address,
3350 port=sessions[0].inside_port,
3351 protocol=sessions[0].protocol,
3352 flags=self.config_flags.NAT_IS_INSIDE)
3353 self.vapi.nat44_del_session(address=sessions[1].outside_ip_address,
3354 port=sessions[1].outside_port,
3355 protocol=sessions[1].protocol)
3357 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4, 0)
3358 self.assertEqual(nsessions - len(sessions), 2)
3360 self.vapi.nat44_del_session(address=sessions[0].inside_ip_address,
3361 port=sessions[0].inside_port,
3362 protocol=sessions[0].protocol,
3363 flags=self.config_flags.NAT_IS_INSIDE)
3365 self.verify_no_nat44_user()
3367 def test_frag_in_order(self):
3368 """ NAT44 translate fragments arriving in order """
3370 self.nat44_add_address(self.nat_addr)
3371 flags = self.config_flags.NAT_IS_INSIDE
3372 self.vapi.nat44_interface_add_del_feature(
3373 sw_if_index=self.pg0.sw_if_index,
3374 flags=flags, is_add=1)
3375 self.vapi.nat44_interface_add_del_feature(
3376 sw_if_index=self.pg1.sw_if_index,
3379 self.frag_in_order(proto=IP_PROTOS.tcp)
3380 self.frag_in_order(proto=IP_PROTOS.udp)
3381 self.frag_in_order(proto=IP_PROTOS.icmp)
3383 def test_frag_forwarding(self):
3384 """ NAT44 forwarding fragment test """
3385 self.vapi.nat44_add_del_interface_addr(
3387 sw_if_index=self.pg1.sw_if_index)
3388 flags = self.config_flags.NAT_IS_INSIDE
3389 self.vapi.nat44_interface_add_del_feature(
3390 sw_if_index=self.pg0.sw_if_index,
3391 flags=flags, is_add=1)
3392 self.vapi.nat44_interface_add_del_feature(
3393 sw_if_index=self.pg1.sw_if_index,
3395 self.vapi.nat44_forwarding_enable_disable(enable=1)
3397 data = b"A" * 16 + b"B" * 16 + b"C" * 3
3398 pkts = self.create_stream_frag(self.pg1,
3399 self.pg0.remote_ip4,
3403 proto=IP_PROTOS.udp)
3404 self.pg1.add_stream(pkts)
3405 self.pg_enable_capture(self.pg_interfaces)
3407 frags = self.pg0.get_capture(len(pkts))
3408 p = self.reass_frags_and_verify(frags,
3409 self.pg1.remote_ip4,
3410 self.pg0.remote_ip4)
3411 self.assertEqual(p[UDP].sport, 4789)
3412 self.assertEqual(p[UDP].dport, 4789)
3413 self.assertEqual(data, p[Raw].load)
3415 def test_reass_hairpinning(self):
3416 """ NAT44 fragments hairpinning """
3418 self.server = self.pg0.remote_hosts[1]
3419 self.host_in_port = random.randint(1025, 65535)
3420 self.server_in_port = random.randint(1025, 65535)
3421 self.server_out_port = random.randint(1025, 65535)
3423 self.nat44_add_address(self.nat_addr)
3424 flags = self.config_flags.NAT_IS_INSIDE
3425 self.vapi.nat44_interface_add_del_feature(
3426 sw_if_index=self.pg0.sw_if_index,
3427 flags=flags, is_add=1)
3428 self.vapi.nat44_interface_add_del_feature(
3429 sw_if_index=self.pg1.sw_if_index,
3431 # add static mapping for server
3432 self.nat44_add_static_mapping(self.server.ip4, self.nat_addr,
3433 self.server_in_port,
3434 self.server_out_port,
3435 proto=IP_PROTOS.tcp)
3436 self.nat44_add_static_mapping(self.server.ip4, self.nat_addr,
3437 self.server_in_port,
3438 self.server_out_port,
3439 proto=IP_PROTOS.udp)
3440 self.nat44_add_static_mapping(self.server.ip4, self.nat_addr)
3442 self.reass_hairpinning(proto=IP_PROTOS.tcp)
3443 self.reass_hairpinning(proto=IP_PROTOS.udp)
3444 self.reass_hairpinning(proto=IP_PROTOS.icmp)
3446 def test_frag_out_of_order(self):
3447 """ NAT44 translate fragments arriving out of order """
3449 self.nat44_add_address(self.nat_addr)
3450 flags = self.config_flags.NAT_IS_INSIDE
3451 self.vapi.nat44_interface_add_del_feature(
3452 sw_if_index=self.pg0.sw_if_index,
3453 flags=flags, is_add=1)
3454 self.vapi.nat44_interface_add_del_feature(
3455 sw_if_index=self.pg1.sw_if_index,
3458 self.frag_out_of_order(proto=IP_PROTOS.tcp)
3459 self.frag_out_of_order(proto=IP_PROTOS.udp)
3460 self.frag_out_of_order(proto=IP_PROTOS.icmp)
3462 def test_port_restricted(self):
3463 """ Port restricted NAT44 (MAP-E CE) """
3464 self.nat44_add_address(self.nat_addr)
3465 flags = self.config_flags.NAT_IS_INSIDE
3466 self.vapi.nat44_interface_add_del_feature(
3467 sw_if_index=self.pg0.sw_if_index,
3468 flags=flags, is_add=1)
3469 self.vapi.nat44_interface_add_del_feature(
3470 sw_if_index=self.pg1.sw_if_index,
3472 self.vapi.nat_set_addr_and_port_alloc_alg(alg=1,
3477 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
3478 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
3479 TCP(sport=4567, dport=22))
3480 self.pg0.add_stream(p)
3481 self.pg_enable_capture(self.pg_interfaces)
3483 capture = self.pg1.get_capture(1)
3488 self.assertEqual(ip.dst, self.pg1.remote_ip4)
3489 self.assertEqual(ip.src, self.nat_addr)
3490 self.assertEqual(tcp.dport, 22)
3491 self.assertNotEqual(tcp.sport, 4567)
3492 self.assertEqual((tcp.sport >> 6) & 63, 10)
3493 self.assert_packet_checksums_valid(p)
3495 self.logger.error(ppp("Unexpected or invalid packet:", p))
3498 def test_port_range(self):
3499 """ External address port range """
3500 self.nat44_add_address(self.nat_addr)
3501 flags = self.config_flags.NAT_IS_INSIDE
3502 self.vapi.nat44_interface_add_del_feature(
3503 sw_if_index=self.pg0.sw_if_index,
3504 flags=flags, is_add=1)
3505 self.vapi.nat44_interface_add_del_feature(
3506 sw_if_index=self.pg1.sw_if_index,
3508 self.vapi.nat_set_addr_and_port_alloc_alg(alg=2,
3513 for port in range(0, 5):
3514 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
3515 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
3516 TCP(sport=1125 + port))
3518 self.pg0.add_stream(pkts)
3519 self.pg_enable_capture(self.pg_interfaces)
3521 capture = self.pg1.get_capture(3)
3524 self.assertGreaterEqual(tcp.sport, 1025)
3525 self.assertLessEqual(tcp.sport, 1027)
3527 def test_multiple_outside_vrf(self):
3528 """ Multiple outside VRF """
3532 self.pg1.unconfig_ip4()
3533 self.pg2.unconfig_ip4()
3534 self.vapi.ip_table_add_del(is_add=1, table={'table_id': vrf_id1})
3535 self.vapi.ip_table_add_del(is_add=1, table={'table_id': vrf_id2})
3536 self.pg1.set_table_ip4(vrf_id1)
3537 self.pg2.set_table_ip4(vrf_id2)
3538 self.pg1.config_ip4()
3539 self.pg2.config_ip4()
3540 self.pg1.resolve_arp()
3541 self.pg2.resolve_arp()
3543 self.nat44_add_address(self.nat_addr)
3544 flags = self.config_flags.NAT_IS_INSIDE
3545 self.vapi.nat44_interface_add_del_feature(
3546 sw_if_index=self.pg0.sw_if_index,
3547 flags=flags, is_add=1)
3548 self.vapi.nat44_interface_add_del_feature(
3549 sw_if_index=self.pg1.sw_if_index,
3551 self.vapi.nat44_interface_add_del_feature(
3552 sw_if_index=self.pg2.sw_if_index,
3557 pkts = self.create_stream_in(self.pg0, self.pg1)
3558 self.pg0.add_stream(pkts)
3559 self.pg_enable_capture(self.pg_interfaces)
3561 capture = self.pg1.get_capture(len(pkts))
3562 self.verify_capture_out(capture, self.nat_addr)
3564 pkts = self.create_stream_out(self.pg1, self.nat_addr)
3565 self.pg1.add_stream(pkts)
3566 self.pg_enable_capture(self.pg_interfaces)
3568 capture = self.pg0.get_capture(len(pkts))
3569 self.verify_capture_in(capture, self.pg0)
3571 self.tcp_port_in = 60303
3572 self.udp_port_in = 60304
3573 self.icmp_id_in = 60305
3576 pkts = self.create_stream_in(self.pg0, self.pg2)
3577 self.pg0.add_stream(pkts)
3578 self.pg_enable_capture(self.pg_interfaces)
3580 capture = self.pg2.get_capture(len(pkts))
3581 self.verify_capture_out(capture, self.nat_addr)
3583 pkts = self.create_stream_out(self.pg2, self.nat_addr)
3584 self.pg2.add_stream(pkts)
3585 self.pg_enable_capture(self.pg_interfaces)
3587 capture = self.pg0.get_capture(len(pkts))
3588 self.verify_capture_in(capture, self.pg0)
3591 self.nat44_add_address(self.nat_addr, is_add=0)
3592 self.pg1.unconfig_ip4()
3593 self.pg2.unconfig_ip4()
3594 self.pg1.set_table_ip4(0)
3595 self.pg2.set_table_ip4(0)
3596 self.pg1.config_ip4()
3597 self.pg2.config_ip4()
3598 self.pg1.resolve_arp()
3599 self.pg2.resolve_arp()
3601 @unittest.skipUnless(running_extended_tests, "part of extended tests")
3602 def test_session_timeout(self):
3603 """ NAT44 session timeouts """
3604 self.nat44_add_address(self.nat_addr)
3605 flags = self.config_flags.NAT_IS_INSIDE
3606 self.vapi.nat44_interface_add_del_feature(
3607 sw_if_index=self.pg0.sw_if_index,
3608 flags=flags, is_add=1)
3609 self.vapi.nat44_interface_add_del_feature(
3610 sw_if_index=self.pg1.sw_if_index,
3612 self.vapi.nat_set_timeouts(udp=5, tcp_established=7440,
3613 tcp_transitory=240, icmp=60)
3617 for i in range(0, max_sessions):
3618 src = "10.10.%u.%u" % ((i & 0xFF00) >> 8, i & 0xFF)
3619 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
3620 IP(src=src, dst=self.pg1.remote_ip4) /
3621 UDP(sport=1025, dport=53))
3623 self.pg0.add_stream(pkts)
3624 self.pg_enable_capture(self.pg_interfaces)
3626 self.pg1.get_capture(max_sessions)
3631 for i in range(0, max_sessions):
3632 src = "10.10.%u.%u" % ((i & 0xFF00) >> 8, i & 0xFF)
3633 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
3634 IP(src=src, dst=self.pg1.remote_ip4) /
3635 UDP(sport=1026, dport=53))
3637 self.pg0.add_stream(pkts)
3638 self.pg_enable_capture(self.pg_interfaces)
3640 self.pg1.get_capture(max_sessions)
3643 users = self.vapi.nat44_user_dump()
3645 nsessions = nsessions + user.nsessions
3646 self.assertLess(nsessions, 2 * max_sessions)
3648 def test_mss_clamping(self):
3649 """ TCP MSS clamping """
3650 self.nat44_add_address(self.nat_addr)
3651 flags = self.config_flags.NAT_IS_INSIDE
3652 self.vapi.nat44_interface_add_del_feature(
3653 sw_if_index=self.pg0.sw_if_index,
3654 flags=flags, is_add=1)
3655 self.vapi.nat44_interface_add_del_feature(
3656 sw_if_index=self.pg1.sw_if_index,
3659 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
3660 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
3661 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
3662 flags="S", options=[('MSS', 1400)]))
3664 self.vapi.nat_set_mss_clamping(enable=1, mss_value=1000)
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 greater than configured - changed
3670 self.verify_mss_value(capture[0], 1000)
3672 self.vapi.nat_set_mss_clamping(enable=0, mss_value=1500)
3673 self.pg0.add_stream(p)
3674 self.pg_enable_capture(self.pg_interfaces)
3676 capture = self.pg1.get_capture(1)
3677 # MSS clamping disabled - negotiated MSS unchanged
3678 self.verify_mss_value(capture[0], 1400)
3680 self.vapi.nat_set_mss_clamping(enable=1, mss_value=1500)
3681 self.pg0.add_stream(p)
3682 self.pg_enable_capture(self.pg_interfaces)
3684 capture = self.pg1.get_capture(1)
3685 # Negotiated MSS value smaller than configured - unchanged
3686 self.verify_mss_value(capture[0], 1400)
3688 @unittest.skipUnless(running_extended_tests, "part of extended tests")
3689 def test_ha_send(self):
3690 """ Send HA session synchronization events (active) """
3691 self.nat44_add_address(self.nat_addr)
3692 flags = self.config_flags.NAT_IS_INSIDE
3693 self.vapi.nat44_interface_add_del_feature(
3694 sw_if_index=self.pg0.sw_if_index,
3695 flags=flags, is_add=1)
3696 self.vapi.nat44_interface_add_del_feature(
3697 sw_if_index=self.pg1.sw_if_index,
3699 self.vapi.nat_ha_set_listener(ip_address=self.pg3.local_ip4,
3702 self.vapi.nat_ha_set_failover(ip_address=self.pg3.remote_ip4,
3703 port=12346, session_refresh_interval=10)
3704 bind_layers(UDP, HANATStateSync, sport=12345)
3707 pkts = self.create_stream_in(self.pg0, self.pg1)
3708 self.pg0.add_stream(pkts)
3709 self.pg_enable_capture(self.pg_interfaces)
3711 capture = self.pg1.get_capture(len(pkts))
3712 self.verify_capture_out(capture)
3713 # active send HA events
3714 self.vapi.nat_ha_flush()
3715 stats = self.statistics.get_counter('/nat44/ha/add-event-send')
3716 self.assertEqual(stats[0][0], 3)
3717 capture = self.pg3.get_capture(1)
3719 self.assert_packet_checksums_valid(p)
3723 hanat = p[HANATStateSync]
3725 self.logger.error(ppp("Invalid packet:", p))
3728 self.assertEqual(ip.src, self.pg3.local_ip4)
3729 self.assertEqual(ip.dst, self.pg3.remote_ip4)
3730 self.assertEqual(udp.sport, 12345)
3731 self.assertEqual(udp.dport, 12346)
3732 self.assertEqual(hanat.version, 1)
3733 self.assertEqual(hanat.thread_index, 0)
3734 self.assertEqual(hanat.count, 3)
3735 seq = hanat.sequence_number
3736 for event in hanat.events:
3737 self.assertEqual(event.event_type, 1)
3738 self.assertEqual(event.in_addr, self.pg0.remote_ip4)
3739 self.assertEqual(event.out_addr, self.nat_addr)
3740 self.assertEqual(event.fib_index, 0)
3742 # ACK received events
3743 ack = (Ether(dst=self.pg3.local_mac, src=self.pg3.remote_mac) /
3744 IP(src=self.pg3.remote_ip4, dst=self.pg3.local_ip4) /
3745 UDP(sport=12346, dport=12345) /
3746 HANATStateSync(sequence_number=seq, flags='ACK'))
3747 self.pg3.add_stream(ack)
3749 stats = self.statistics.get_counter('/nat44/ha/ack-recv')
3750 self.assertEqual(stats[0][0], 1)
3752 # delete one session
3753 self.pg_enable_capture(self.pg_interfaces)
3754 self.vapi.nat44_del_session(address=self.pg0.remote_ip4,
3755 port=self.tcp_port_in,
3756 protocol=IP_PROTOS.tcp,
3757 flags=self.config_flags.NAT_IS_INSIDE)
3758 self.vapi.nat_ha_flush()
3759 stats = self.statistics.get_counter('/nat44/ha/del-event-send')
3760 self.assertEqual(stats[0][0], 1)
3761 capture = self.pg3.get_capture(1)
3764 hanat = p[HANATStateSync]
3766 self.logger.error(ppp("Invalid packet:", p))
3769 self.assertGreater(hanat.sequence_number, seq)
3771 # do not send ACK, active retry send HA event again
3772 self.pg_enable_capture(self.pg_interfaces)
3774 stats = self.statistics.get_counter('/nat44/ha/retry-count')
3775 self.assertEqual(stats[0][0], 3)
3776 stats = self.statistics.get_counter('/nat44/ha/missed-count')
3777 self.assertEqual(stats[0][0], 1)
3778 capture = self.pg3.get_capture(3)
3779 for packet in capture:
3780 self.assertEqual(packet, p)
3782 # session counters refresh
3783 pkts = self.create_stream_out(self.pg1)
3784 self.pg1.add_stream(pkts)
3785 self.pg_enable_capture(self.pg_interfaces)
3787 self.pg0.get_capture(2)
3788 self.vapi.nat_ha_flush()
3789 stats = self.statistics.get_counter('/nat44/ha/refresh-event-send')
3790 self.assertEqual(stats[0][0], 2)
3791 capture = self.pg3.get_capture(1)
3793 self.assert_packet_checksums_valid(p)
3797 hanat = p[HANATStateSync]
3799 self.logger.error(ppp("Invalid packet:", p))
3802 self.assertEqual(ip.src, self.pg3.local_ip4)
3803 self.assertEqual(ip.dst, self.pg3.remote_ip4)
3804 self.assertEqual(udp.sport, 12345)
3805 self.assertEqual(udp.dport, 12346)
3806 self.assertEqual(hanat.version, 1)
3807 self.assertEqual(hanat.count, 2)
3808 seq = hanat.sequence_number
3809 for event in hanat.events:
3810 self.assertEqual(event.event_type, 3)
3811 self.assertEqual(event.out_addr, self.nat_addr)
3812 self.assertEqual(event.fib_index, 0)
3813 self.assertEqual(event.total_pkts, 2)
3814 self.assertGreater(event.total_bytes, 0)
3816 ack = (Ether(dst=self.pg3.local_mac, src=self.pg3.remote_mac) /
3817 IP(src=self.pg3.remote_ip4, dst=self.pg3.local_ip4) /
3818 UDP(sport=12346, dport=12345) /
3819 HANATStateSync(sequence_number=seq, flags='ACK'))
3820 self.pg3.add_stream(ack)
3822 stats = self.statistics.get_counter('/nat44/ha/ack-recv')
3823 self.assertEqual(stats[0][0], 2)
3825 def test_ha_recv(self):
3826 """ Receive HA session synchronization events (passive) """
3827 self.nat44_add_address(self.nat_addr)
3828 flags = self.config_flags.NAT_IS_INSIDE
3829 self.vapi.nat44_interface_add_del_feature(
3830 sw_if_index=self.pg0.sw_if_index,
3831 flags=flags, is_add=1)
3832 self.vapi.nat44_interface_add_del_feature(
3833 sw_if_index=self.pg1.sw_if_index,
3835 self.vapi.nat_ha_set_listener(ip_address=self.pg3.local_ip4,
3838 bind_layers(UDP, HANATStateSync, sport=12345)
3840 self.tcp_port_out = random.randint(1025, 65535)
3841 self.udp_port_out = random.randint(1025, 65535)
3843 # send HA session add events to failover/passive
3844 p = (Ether(dst=self.pg3.local_mac, src=self.pg3.remote_mac) /
3845 IP(src=self.pg3.remote_ip4, dst=self.pg3.local_ip4) /
3846 UDP(sport=12346, dport=12345) /
3847 HANATStateSync(sequence_number=1, events=[
3848 Event(event_type='add', protocol='tcp',
3849 in_addr=self.pg0.remote_ip4, out_addr=self.nat_addr,
3850 in_port=self.tcp_port_in, out_port=self.tcp_port_out,
3851 eh_addr=self.pg1.remote_ip4,
3852 ehn_addr=self.pg1.remote_ip4,
3853 eh_port=self.tcp_external_port,
3854 ehn_port=self.tcp_external_port, fib_index=0),
3855 Event(event_type='add', protocol='udp',
3856 in_addr=self.pg0.remote_ip4, out_addr=self.nat_addr,
3857 in_port=self.udp_port_in, out_port=self.udp_port_out,
3858 eh_addr=self.pg1.remote_ip4,
3859 ehn_addr=self.pg1.remote_ip4,
3860 eh_port=self.udp_external_port,
3861 ehn_port=self.udp_external_port, fib_index=0)]))
3863 self.pg3.add_stream(p)
3864 self.pg_enable_capture(self.pg_interfaces)
3867 capture = self.pg3.get_capture(1)
3870 hanat = p[HANATStateSync]
3872 self.logger.error(ppp("Invalid packet:", p))
3875 self.assertEqual(hanat.sequence_number, 1)
3876 self.assertEqual(hanat.flags, 'ACK')
3877 self.assertEqual(hanat.version, 1)
3878 self.assertEqual(hanat.thread_index, 0)
3879 stats = self.statistics.get_counter('/nat44/ha/ack-send')
3880 self.assertEqual(stats[0][0], 1)
3881 stats = self.statistics.get_counter('/nat44/ha/add-event-recv')
3882 self.assertEqual(stats[0][0], 2)
3883 users = self.statistics.get_counter('/nat44/total-users')
3884 self.assertEqual(users[0][0], 1)
3885 sessions = self.statistics.get_counter('/nat44/total-sessions')
3886 self.assertEqual(sessions[0][0], 2)
3887 users = self.vapi.nat44_user_dump()
3888 self.assertEqual(len(users), 1)
3889 self.assertEqual(str(users[0].ip_address),
3890 self.pg0.remote_ip4)
3891 # there should be 2 sessions created by HA
3892 sessions = self.vapi.nat44_user_session_dump(users[0].ip_address,
3894 self.assertEqual(len(sessions), 2)
3895 for session in sessions:
3896 self.assertEqual(str(session.inside_ip_address),
3897 self.pg0.remote_ip4)
3898 self.assertEqual(str(session.outside_ip_address),
3900 self.assertIn(session.inside_port,
3901 [self.tcp_port_in, self.udp_port_in])
3902 self.assertIn(session.outside_port,
3903 [self.tcp_port_out, self.udp_port_out])
3904 self.assertIn(session.protocol, [IP_PROTOS.tcp, IP_PROTOS.udp])
3906 # send HA session delete event to failover/passive
3907 p = (Ether(dst=self.pg3.local_mac, src=self.pg3.remote_mac) /
3908 IP(src=self.pg3.remote_ip4, dst=self.pg3.local_ip4) /
3909 UDP(sport=12346, dport=12345) /
3910 HANATStateSync(sequence_number=2, events=[
3911 Event(event_type='del', protocol='udp',
3912 in_addr=self.pg0.remote_ip4, out_addr=self.nat_addr,
3913 in_port=self.udp_port_in, out_port=self.udp_port_out,
3914 eh_addr=self.pg1.remote_ip4,
3915 ehn_addr=self.pg1.remote_ip4,
3916 eh_port=self.udp_external_port,
3917 ehn_port=self.udp_external_port, fib_index=0)]))
3919 self.pg3.add_stream(p)
3920 self.pg_enable_capture(self.pg_interfaces)
3923 capture = self.pg3.get_capture(1)
3926 hanat = p[HANATStateSync]
3928 self.logger.error(ppp("Invalid packet:", p))
3931 self.assertEqual(hanat.sequence_number, 2)
3932 self.assertEqual(hanat.flags, 'ACK')
3933 self.assertEqual(hanat.version, 1)
3934 users = self.vapi.nat44_user_dump()
3935 self.assertEqual(len(users), 1)
3936 self.assertEqual(str(users[0].ip_address),
3937 self.pg0.remote_ip4)
3938 # now we should have only 1 session, 1 deleted by HA
3939 sessions = self.vapi.nat44_user_session_dump(users[0].ip_address,
3941 self.assertEqual(len(sessions), 1)
3942 stats = self.statistics.get_counter('/nat44/ha/del-event-recv')
3943 self.assertEqual(stats[0][0], 1)
3945 stats = self.statistics.get_err_counter('/err/nat-ha/pkts-processed')
3946 self.assertEqual(stats, 2)
3948 # send HA session refresh event to failover/passive
3949 p = (Ether(dst=self.pg3.local_mac, src=self.pg3.remote_mac) /
3950 IP(src=self.pg3.remote_ip4, dst=self.pg3.local_ip4) /
3951 UDP(sport=12346, dport=12345) /
3952 HANATStateSync(sequence_number=3, events=[
3953 Event(event_type='refresh', protocol='tcp',
3954 in_addr=self.pg0.remote_ip4, out_addr=self.nat_addr,
3955 in_port=self.tcp_port_in, out_port=self.tcp_port_out,
3956 eh_addr=self.pg1.remote_ip4,
3957 ehn_addr=self.pg1.remote_ip4,
3958 eh_port=self.tcp_external_port,
3959 ehn_port=self.tcp_external_port, fib_index=0,
3960 total_bytes=1024, total_pkts=2)]))
3961 self.pg3.add_stream(p)
3962 self.pg_enable_capture(self.pg_interfaces)
3965 capture = self.pg3.get_capture(1)
3968 hanat = p[HANATStateSync]
3970 self.logger.error(ppp("Invalid packet:", p))
3973 self.assertEqual(hanat.sequence_number, 3)
3974 self.assertEqual(hanat.flags, 'ACK')
3975 self.assertEqual(hanat.version, 1)
3976 users = self.vapi.nat44_user_dump()
3977 self.assertEqual(len(users), 1)
3978 self.assertEqual(str(users[0].ip_address),
3979 self.pg0.remote_ip4)
3980 sessions = self.vapi.nat44_user_session_dump(users[0].ip_address,
3982 self.assertEqual(len(sessions), 1)
3983 session = sessions[0]
3984 self.assertEqual(session.total_bytes, 1024)
3985 self.assertEqual(session.total_pkts, 2)
3986 stats = self.statistics.get_counter('/nat44/ha/refresh-event-recv')
3987 self.assertEqual(stats[0][0], 1)
3989 stats = self.statistics.get_err_counter('/err/nat-ha/pkts-processed')
3990 self.assertEqual(stats, 3)
3992 # send packet to test session created by HA
3993 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
3994 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
3995 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out))
3996 self.pg1.add_stream(p)
3997 self.pg_enable_capture(self.pg_interfaces)
3999 capture = self.pg0.get_capture(1)
4005 self.logger.error(ppp("Invalid packet:", p))
4008 self.assertEqual(ip.src, self.pg1.remote_ip4)
4009 self.assertEqual(ip.dst, self.pg0.remote_ip4)
4010 self.assertEqual(tcp.sport, self.tcp_external_port)
4011 self.assertEqual(tcp.dport, self.tcp_port_in)
4013 def show_commands_at_teardown(self):
4014 self.logger.info(self.vapi.cli("show nat44 addresses"))
4015 self.logger.info(self.vapi.cli("show nat44 interfaces"))
4016 self.logger.info(self.vapi.cli("show nat44 static mappings"))
4017 self.logger.info(self.vapi.cli("show nat44 interface address"))
4018 self.logger.info(self.vapi.cli("show nat44 sessions detail"))
4019 self.logger.info(self.vapi.cli("show nat44 hash tables detail"))
4020 self.logger.info(self.vapi.cli("show nat timeouts"))
4022 self.vapi.cli("show nat addr-port-assignment-alg"))
4023 self.logger.info(self.vapi.cli("show nat ha"))
4026 class TestNAT44EndpointDependent2(MethodHolder):
4027 """ Endpoint-Dependent mapping and filtering test cases """
4030 def tearDownClass(cls):
4031 super(TestNAT44EndpointDependent2, cls).tearDownClass()
4034 super(TestNAT44EndpointDependent2, self).tearDown()
4037 def create_and_add_ip4_table(cls, i, table_id):
4038 cls.vapi.ip_table_add_del(is_add=1, table={'table_id': table_id})
4039 i.set_table_ip4(table_id)
4042 def setUpClass(cls):
4043 super(TestNAT44EndpointDependent2, cls).setUpClass()
4045 cls.create_pg_interfaces(range(3))
4046 cls.interfaces = list(cls.pg_interfaces)
4048 cls.create_and_add_ip4_table(cls.pg1, 10)
4050 for i in cls.interfaces:
4055 i.generate_remote_hosts(1)
4056 i.configure_ipv4_neighbors()
4059 super(TestNAT44EndpointDependent2, self).setUp()
4060 flags = self.nat44_config_flags.NAT44_IS_ENDPOINT_DEPENDENT
4061 self.vapi.nat44_plugin_enable_disable(enable=1, flags=flags)
4064 super(TestNAT44EndpointDependent2, self).tearDown()
4065 if not self.vpp_dead:
4066 self.vapi.nat44_plugin_enable_disable(enable=0)
4067 self.vapi.cli("clear logging")
4069 def nat_add_inside_interface(self, i):
4070 self.vapi.nat44_interface_add_del_feature(
4071 flags=self.config_flags.NAT_IS_INSIDE,
4072 sw_if_index=i.sw_if_index, is_add=1)
4074 def nat_add_outside_interface(self, i):
4075 self.vapi.nat44_interface_add_del_feature(
4076 flags=self.config_flags.NAT_IS_OUTSIDE,
4077 sw_if_index=i.sw_if_index, is_add=1)
4079 def nat_add_interface_address(self, i):
4080 self.nat_addr = i.local_ip4
4081 self.vapi.nat44_add_del_interface_addr(
4082 sw_if_index=i.sw_if_index, is_add=1)
4084 def nat_add_address(self, address, vrf_id=0xFFFFFFFF):
4085 self.nat_addr = address
4086 self.nat44_add_address(address, vrf_id=vrf_id)
4088 def cli(self, command):
4089 result = self.vapi.cli(command)
4090 self.logger.info(result)
4093 def show_configuration(self):
4094 self.cli("show interface")
4095 self.cli("show interface address")
4096 self.cli("show nat44 addresses")
4097 self.cli("show nat44 interfaces")
4099 def create_tcp_stream(self, in_if, out_if, count):
4101 Create tcp packet stream
4103 :param in_if: Inside interface
4104 :param out_if: Outside interface
4105 :param count: count of packets to generate
4110 for i in range(count):
4111 p = (Ether(dst=in_if.local_mac, src=in_if.remote_mac) /
4112 IP(src=in_if.remote_ip4, dst=out_if.remote_ip4, ttl=64) /
4113 TCP(sport=port + i, dport=20))
4118 def test_session_limit_per_vrf(self):
4121 inside_vrf10 = self.pg1
4126 # 2 interfaces pg0, pg1 (vrf10, limit 1 tcp session)
4127 # non existing vrf_id makes process core dump
4128 self.vapi.nat44_set_session_limit(session_limit=limit, vrf_id=10)
4130 self.nat_add_inside_interface(inside)
4131 self.nat_add_inside_interface(inside_vrf10)
4132 self.nat_add_outside_interface(outside)
4135 self.nat_add_interface_address(outside)
4137 # BUG: causing core dump - when bad vrf_id is specified
4138 # self.nat44_add_address(outside.local_ip4, vrf_id=20)
4140 self.show_configuration()
4142 stream = self.create_tcp_stream(inside_vrf10, outside, limit * 2)
4143 inside_vrf10.add_stream(stream)
4145 self.pg_enable_capture(self.pg_interfaces)
4148 capture = outside.get_capture(limit)
4150 stream = self.create_tcp_stream(inside, outside, limit * 2)
4151 inside.add_stream(stream)
4153 self.pg_enable_capture(self.pg_interfaces)
4156 capture = outside.get_capture(len(stream))
4159 class TestNAT44EndpointDependent(MethodHolder):
4160 """ Endpoint-Dependent mapping and filtering test cases """
4163 def setUpClass(cls):
4164 super(TestNAT44EndpointDependent, cls).setUpClass()
4165 cls.vapi.cli("set log class nat level debug")
4167 cls.tcp_port_in = 6303
4168 cls.tcp_port_out = 6303
4169 cls.udp_port_in = 6304
4170 cls.udp_port_out = 6304
4171 cls.icmp_id_in = 6305
4172 cls.icmp_id_out = 6305
4173 cls.nat_addr = '10.0.0.3'
4174 cls.ipfix_src_port = 4739
4175 cls.ipfix_domain_id = 1
4176 cls.tcp_external_port = 80
4178 cls.create_pg_interfaces(range(9))
4179 cls.interfaces = list(cls.pg_interfaces[0:3])
4181 for i in cls.interfaces:
4186 cls.pg0.generate_remote_hosts(3)
4187 cls.pg0.configure_ipv4_neighbors()
4191 cls.pg4.generate_remote_hosts(2)
4192 cls.pg4.config_ip4()
4193 cls.vapi.sw_interface_add_del_address(
4194 sw_if_index=cls.pg4.sw_if_index,
4195 prefix="10.0.0.1/24")
4198 cls.pg4.resolve_arp()
4199 cls.pg4._remote_hosts[1]._ip4 = cls.pg4._remote_hosts[0]._ip4
4200 cls.pg4.resolve_arp()
4202 zero_ip4 = socket.inet_pton(socket.AF_INET, "0.0.0.0")
4203 cls.vapi.ip_table_add_del(is_add=1, table={'table_id': 1})
4205 cls.pg5._local_ip4 = "10.1.1.1"
4206 cls.pg5._remote_hosts[0]._ip4 = "10.1.1.2"
4207 cls.pg5.set_table_ip4(1)
4208 cls.pg5.config_ip4()
4210 r1 = VppIpRoute(cls, cls.pg5.remote_ip4, 32,
4211 [VppRoutePath("0.0.0.0",
4212 cls.pg5.sw_if_index)],
4217 cls.pg6._local_ip4 = "10.1.2.1"
4218 cls.pg6._remote_hosts[0]._ip4 = "10.1.2.2"
4219 cls.pg6.set_table_ip4(1)
4220 cls.pg6.config_ip4()
4223 r2 = VppIpRoute(cls, cls.pg6.remote_ip4, 32,
4224 [VppRoutePath("0.0.0.0",
4225 cls.pg6.sw_if_index)],
4228 r3 = VppIpRoute(cls, cls.pg6.remote_ip4, 16,
4229 [VppRoutePath("0.0.0.0",
4234 r4 = VppIpRoute(cls, "0.0.0.0", 0,
4235 [VppRoutePath("0.0.0.0", 0xffffffff,
4239 r5 = VppIpRoute(cls, "0.0.0.0", 0,
4240 [VppRoutePath(cls.pg1.local_ip4,
4241 cls.pg1.sw_if_index)],
4248 cls.pg5.resolve_arp()
4249 cls.pg6.resolve_arp()
4252 cls.pg7.config_ip4()
4253 cls.pg7.resolve_arp()
4254 cls.pg7.generate_remote_hosts(3)
4255 cls.pg7.configure_ipv4_neighbors()
4258 cls.pg8.config_ip4()
4259 cls.pg8.resolve_arp()
4262 def tearDownClass(cls):
4263 super(TestNAT44EndpointDependent, cls).tearDownClass()
4266 super(TestNAT44EndpointDependent, self).setUp()
4267 flags = self.nat44_config_flags.NAT44_IS_ENDPOINT_DEPENDENT
4268 self.vapi.nat44_plugin_enable_disable(enable=1, flags=flags)
4269 self.vapi.nat_set_timeouts(
4270 udp=300, tcp_established=7440,
4271 tcp_transitory=240, icmp=60)
4274 super(TestNAT44EndpointDependent, self).tearDown()
4275 if not self.vpp_dead:
4276 self.vapi.nat44_plugin_enable_disable(enable=0)
4277 self.vapi.cli("clear logging")
4279 def test_frag_in_order(self):
4280 """ NAT44 translate fragments arriving in order """
4281 self.nat44_add_address(self.nat_addr)
4282 flags = self.config_flags.NAT_IS_INSIDE
4283 self.vapi.nat44_interface_add_del_feature(
4284 sw_if_index=self.pg0.sw_if_index,
4285 flags=flags, is_add=1)
4286 self.vapi.nat44_interface_add_del_feature(
4287 sw_if_index=self.pg1.sw_if_index,
4289 self.frag_in_order(proto=IP_PROTOS.tcp, ignore_port=True)
4290 self.frag_in_order(proto=IP_PROTOS.udp, ignore_port=True)
4291 self.frag_in_order(proto=IP_PROTOS.icmp, ignore_port=True)
4293 def test_frag_in_order_dont_translate(self):
4294 """ NAT44 don't translate fragments arriving in order """
4295 flags = self.config_flags.NAT_IS_INSIDE
4296 self.vapi.nat44_interface_add_del_feature(
4297 sw_if_index=self.pg0.sw_if_index,
4298 flags=flags, is_add=1)
4299 self.vapi.nat44_interface_add_del_feature(
4300 sw_if_index=self.pg1.sw_if_index,
4302 self.vapi.nat44_forwarding_enable_disable(enable=True)
4303 self.frag_in_order(proto=IP_PROTOS.tcp, dont_translate=True)
4305 def test_frag_out_of_order(self):
4306 """ NAT44 translate fragments arriving out of order """
4307 self.nat44_add_address(self.nat_addr)
4308 flags = self.config_flags.NAT_IS_INSIDE
4309 self.vapi.nat44_interface_add_del_feature(
4310 sw_if_index=self.pg0.sw_if_index,
4311 flags=flags, is_add=1)
4312 self.vapi.nat44_interface_add_del_feature(
4313 sw_if_index=self.pg1.sw_if_index,
4315 self.frag_out_of_order(proto=IP_PROTOS.tcp, ignore_port=True)
4316 self.frag_out_of_order(proto=IP_PROTOS.udp, ignore_port=True)
4317 self.frag_out_of_order(proto=IP_PROTOS.icmp, ignore_port=True)
4319 def test_frag_out_of_order_dont_translate(self):
4320 """ NAT44 don't translate fragments arriving out of order """
4321 flags = self.config_flags.NAT_IS_INSIDE
4322 self.vapi.nat44_interface_add_del_feature(
4323 sw_if_index=self.pg0.sw_if_index,
4324 flags=flags, is_add=1)
4325 self.vapi.nat44_interface_add_del_feature(
4326 sw_if_index=self.pg1.sw_if_index,
4328 self.vapi.nat44_forwarding_enable_disable(enable=True)
4329 self.frag_out_of_order(proto=IP_PROTOS.tcp, dont_translate=True)
4331 def test_frag_in_order_in_plus_out(self):
4332 """ in+out interface fragments in order """
4333 flags = self.config_flags.NAT_IS_INSIDE
4334 self.vapi.nat44_interface_add_del_feature(
4335 sw_if_index=self.pg0.sw_if_index,
4337 self.vapi.nat44_interface_add_del_feature(
4338 sw_if_index=self.pg0.sw_if_index,
4339 flags=flags, is_add=1)
4340 self.vapi.nat44_interface_add_del_feature(
4341 sw_if_index=self.pg1.sw_if_index,
4343 self.vapi.nat44_interface_add_del_feature(
4344 sw_if_index=self.pg1.sw_if_index,
4345 flags=flags, is_add=1)
4347 self.server = self.pg1.remote_hosts[0]
4349 self.server_in_addr = self.server.ip4
4350 self.server_out_addr = '11.11.11.11'
4351 self.server_in_port = random.randint(1025, 65535)
4352 self.server_out_port = random.randint(1025, 65535)
4354 self.nat44_add_address(self.server_out_addr)
4356 # add static mappings for server
4357 self.nat44_add_static_mapping(self.server_in_addr,
4358 self.server_out_addr,
4359 self.server_in_port,
4360 self.server_out_port,
4361 proto=IP_PROTOS.tcp)
4362 self.nat44_add_static_mapping(self.server_in_addr,
4363 self.server_out_addr,
4364 self.server_in_port,
4365 self.server_out_port,
4366 proto=IP_PROTOS.udp)
4367 self.nat44_add_static_mapping(self.server_in_addr,
4368 self.server_out_addr,
4369 proto=IP_PROTOS.icmp)
4371 self.frag_in_order_in_plus_out(proto=IP_PROTOS.tcp)
4372 self.frag_in_order_in_plus_out(proto=IP_PROTOS.udp)
4373 self.frag_in_order_in_plus_out(proto=IP_PROTOS.icmp)
4375 def test_frag_out_of_order_in_plus_out(self):
4376 """ in+out interface fragments out of order """
4377 flags = self.config_flags.NAT_IS_INSIDE
4378 self.vapi.nat44_interface_add_del_feature(
4379 sw_if_index=self.pg0.sw_if_index,
4381 self.vapi.nat44_interface_add_del_feature(
4382 sw_if_index=self.pg0.sw_if_index,
4383 flags=flags, is_add=1)
4384 self.vapi.nat44_interface_add_del_feature(
4385 sw_if_index=self.pg1.sw_if_index,
4387 self.vapi.nat44_interface_add_del_feature(
4388 sw_if_index=self.pg1.sw_if_index,
4389 flags=flags, is_add=1)
4391 self.server = self.pg1.remote_hosts[0]
4393 self.server_in_addr = self.server.ip4
4394 self.server_out_addr = '11.11.11.11'
4395 self.server_in_port = random.randint(1025, 65535)
4396 self.server_out_port = random.randint(1025, 65535)
4398 self.nat44_add_address(self.server_out_addr)
4400 # add static mappings for server
4401 self.nat44_add_static_mapping(self.server_in_addr,
4402 self.server_out_addr,
4403 self.server_in_port,
4404 self.server_out_port,
4405 proto=IP_PROTOS.tcp)
4406 self.nat44_add_static_mapping(self.server_in_addr,
4407 self.server_out_addr,
4408 self.server_in_port,
4409 self.server_out_port,
4410 proto=IP_PROTOS.udp)
4411 self.nat44_add_static_mapping(self.server_in_addr,
4412 self.server_out_addr,
4413 proto=IP_PROTOS.icmp)
4415 self.frag_out_of_order_in_plus_out(proto=IP_PROTOS.tcp)
4416 self.frag_out_of_order_in_plus_out(proto=IP_PROTOS.udp)
4417 self.frag_out_of_order_in_plus_out(proto=IP_PROTOS.icmp)
4419 def test_reass_hairpinning(self):
4420 """ NAT44 fragments hairpinning """
4421 self.server = self.pg0.remote_hosts[1]
4422 self.host_in_port = random.randint(1025, 65535)
4423 self.server_in_port = random.randint(1025, 65535)
4424 self.server_out_port = random.randint(1025, 65535)
4426 self.nat44_add_address(self.nat_addr)
4427 flags = self.config_flags.NAT_IS_INSIDE
4428 self.vapi.nat44_interface_add_del_feature(
4429 sw_if_index=self.pg0.sw_if_index,
4430 flags=flags, is_add=1)
4431 self.vapi.nat44_interface_add_del_feature(
4432 sw_if_index=self.pg1.sw_if_index,
4434 # add static mapping for server
4435 self.nat44_add_static_mapping(self.server.ip4, self.nat_addr,
4436 self.server_in_port,
4437 self.server_out_port,
4438 proto=IP_PROTOS.tcp)
4439 self.nat44_add_static_mapping(self.server.ip4, self.nat_addr,
4440 self.server_in_port,
4441 self.server_out_port,
4442 proto=IP_PROTOS.udp)
4443 self.nat44_add_static_mapping(self.server.ip4, self.nat_addr)
4445 self.reass_hairpinning(proto=IP_PROTOS.tcp, ignore_port=True)
4446 self.reass_hairpinning(proto=IP_PROTOS.udp, ignore_port=True)
4447 self.reass_hairpinning(proto=IP_PROTOS.icmp, ignore_port=True)
4449 def test_clear_sessions(self):
4450 """ NAT44 ED session clearing test """
4452 self.nat44_add_address(self.nat_addr)
4453 flags = self.config_flags.NAT_IS_INSIDE
4454 self.vapi.nat44_interface_add_del_feature(
4455 sw_if_index=self.pg0.sw_if_index,
4456 flags=flags, is_add=1)
4457 self.vapi.nat44_interface_add_del_feature(
4458 sw_if_index=self.pg1.sw_if_index,
4461 nat_config = self.vapi.nat_show_config()
4462 self.assertEqual(1, nat_config.endpoint_dependent)
4464 pkts = self.create_stream_in(self.pg0, self.pg1)
4465 self.pg0.add_stream(pkts)
4466 self.pg_enable_capture(self.pg_interfaces)
4468 capture = self.pg1.get_capture(len(pkts))
4469 self.verify_capture_out(capture, ignore_port=True)
4471 sessions = self.statistics.get_counter('/nat44/total-sessions')
4472 self.assertTrue(sessions[0][0] > 0)
4473 self.logger.info("sessions before clearing: %s" % sessions[0][0])
4475 # just for testing purposes
4476 self.logger.info(self.vapi.cli("show nat44 summary"))
4478 self.vapi.cli("clear nat44 sessions")
4480 self.logger.info(self.vapi.cli("show nat44 summary"))
4482 sessions = self.statistics.get_counter('/nat44/total-sessions')
4483 self.assertEqual(sessions[0][0], 0)
4484 self.logger.info("sessions after clearing: %s" % sessions[0][0])
4486 def test_dynamic(self):
4487 """ NAT44 dynamic translation test """
4489 self.nat44_add_address(self.nat_addr)
4490 flags = self.config_flags.NAT_IS_INSIDE
4491 self.vapi.nat44_interface_add_del_feature(
4492 sw_if_index=self.pg0.sw_if_index,
4493 flags=flags, is_add=1)
4494 self.vapi.nat44_interface_add_del_feature(
4495 sw_if_index=self.pg1.sw_if_index,
4498 nat_config = self.vapi.nat_show_config()
4499 self.assertEqual(1, nat_config.endpoint_dependent)
4502 tcpn = self.statistics.get_counter('/nat44/ed/in2out/slowpath/tcp')[0]
4503 udpn = self.statistics.get_counter('/nat44/ed/in2out/slowpath/udp')[0]
4504 icmpn = self.statistics.get_counter(
4505 '/nat44/ed/in2out/slowpath/icmp')[0]
4506 drops = self.statistics.get_counter(
4507 '/nat44/ed/in2out/slowpath/drops')[0]
4509 pkts = self.create_stream_in(self.pg0, self.pg1)
4510 self.pg0.add_stream(pkts)
4511 self.pg_enable_capture(self.pg_interfaces)
4513 capture = self.pg1.get_capture(len(pkts))
4514 self.verify_capture_out(capture, ignore_port=True)
4516 if_idx = self.pg0.sw_if_index
4517 cnt = self.statistics.get_counter('/nat44/ed/in2out/slowpath/tcp')[0]
4518 self.assertEqual(cnt[if_idx] - tcpn[if_idx], 2)
4519 cnt = self.statistics.get_counter('/nat44/ed/in2out/slowpath/udp')[0]
4520 self.assertEqual(cnt[if_idx] - udpn[if_idx], 1)
4521 cnt = self.statistics.get_counter('/nat44/ed/in2out/slowpath/icmp')[0]
4522 self.assertEqual(cnt[if_idx] - icmpn[if_idx], 1)
4523 cnt = self.statistics.get_counter('/nat44/ed/in2out/slowpath/drops')[0]
4524 self.assertEqual(cnt[if_idx] - drops[if_idx], 0)
4527 tcpn = self.statistics.get_counter('/nat44/ed/out2in/fastpath/tcp')[0]
4528 udpn = self.statistics.get_counter('/nat44/ed/out2in/fastpath/udp')[0]
4529 icmpn = self.statistics.get_counter(
4530 '/nat44/ed/out2in/slowpath/icmp')[0]
4531 drops = self.statistics.get_counter(
4532 '/nat44/ed/out2in/fastpath/drops')[0]
4534 pkts = self.create_stream_out(self.pg1)
4535 self.pg1.add_stream(pkts)
4536 self.pg_enable_capture(self.pg_interfaces)
4538 capture = self.pg0.get_capture(len(pkts))
4539 self.verify_capture_in(capture, self.pg0)
4541 if_idx = self.pg1.sw_if_index
4542 cnt = self.statistics.get_counter('/nat44/ed/out2in/fastpath/tcp')[0]
4543 self.assertEqual(cnt[if_idx] - tcpn[if_idx], 2)
4544 cnt = self.statistics.get_counter('/nat44/ed/out2in/fastpath/udp')[0]
4545 self.assertEqual(cnt[if_idx] - udpn[if_idx], 1)
4546 cnt = self.statistics.get_counter('/nat44/ed/out2in/slowpath/icmp')[0]
4547 self.assertEqual(cnt[if_idx] - icmpn[if_idx], 1)
4548 cnt = self.statistics.get_counter('/nat44/ed/out2in/fastpath/drops')[0]
4549 self.assertEqual(cnt[if_idx] - drops[if_idx], 0)
4551 sessions = self.statistics.get_counter('/nat44/total-sessions')
4552 self.assertEqual(sessions[0][0], 3)
4554 def test_dynamic_out_of_ports(self):
4555 """ NAT44 dynamic translation test: out of ports """
4557 flags = self.config_flags.NAT_IS_INSIDE
4558 self.vapi.nat44_interface_add_del_feature(
4559 sw_if_index=self.pg0.sw_if_index,
4560 flags=flags, is_add=1)
4561 self.vapi.nat44_interface_add_del_feature(
4562 sw_if_index=self.pg1.sw_if_index,
4565 nat_config = self.vapi.nat_show_config()
4566 self.assertEqual(1, nat_config.endpoint_dependent)
4568 # in2out and no NAT addresses added
4569 err_old = self.statistics.get_err_counter(
4570 '/err/nat44-ed-in2out-slowpath/out of ports')
4572 pkts = self.create_stream_in(self.pg0, self.pg1)
4573 self.pg0.add_stream(pkts)
4574 self.pg_enable_capture(self.pg_interfaces)
4576 self.pg1.get_capture(0, timeout=1)
4578 err_new = self.statistics.get_err_counter(
4579 '/err/nat44-ed-in2out-slowpath/out of ports')
4581 self.assertEqual(err_new - err_old, len(pkts))
4583 # in2out after NAT addresses added
4584 self.nat44_add_address(self.nat_addr)
4586 err_old = self.statistics.get_err_counter(
4587 '/err/nat44-ed-in2out-slowpath/out of ports')
4589 pkts = self.create_stream_in(self.pg0, self.pg1)
4590 self.pg0.add_stream(pkts)
4591 self.pg_enable_capture(self.pg_interfaces)
4593 capture = self.pg1.get_capture(len(pkts))
4594 self.verify_capture_out(capture, ignore_port=True)
4596 err_new = self.statistics.get_err_counter(
4597 '/err/nat44-ed-in2out-slowpath/out of ports')
4599 self.assertEqual(err_new, err_old)
4601 def test_dynamic_output_feature_vrf(self):
4602 """ NAT44 dynamic translation test: output-feature, VRF"""
4604 # other then default (0)
4607 self.nat44_add_address(self.nat_addr)
4608 flags = self.config_flags.NAT_IS_INSIDE
4609 self.vapi.nat44_interface_add_del_output_feature(
4610 sw_if_index=self.pg7.sw_if_index,
4611 flags=flags, is_add=1)
4612 self.vapi.nat44_interface_add_del_output_feature(
4613 sw_if_index=self.pg8.sw_if_index,
4617 self.vapi.ip_table_add_del(is_add=1,
4618 table={'table_id': new_vrf_id})
4620 self.pg7.unconfig_ip4()
4621 self.pg7.set_table_ip4(new_vrf_id)
4622 self.pg7.config_ip4()
4623 self.pg7.resolve_arp()
4625 self.pg8.unconfig_ip4()
4626 self.pg8.set_table_ip4(new_vrf_id)
4627 self.pg8.config_ip4()
4628 self.pg8.resolve_arp()
4630 nat_config = self.vapi.nat_show_config()
4631 self.assertEqual(1, nat_config.endpoint_dependent)
4634 tcpn = self.statistics.get_counter(
4635 '/nat44/ed/in2out/slowpath/tcp')[0]
4636 udpn = self.statistics.get_counter(
4637 '/nat44/ed/in2out/slowpath/udp')[0]
4638 icmpn = self.statistics.get_counter(
4639 '/nat44/ed/in2out/slowpath/icmp')[0]
4640 drops = self.statistics.get_counter(
4641 '/nat44/ed/in2out/slowpath/drops')[0]
4643 pkts = self.create_stream_in(self.pg7, self.pg8)
4644 self.pg7.add_stream(pkts)
4645 self.pg_enable_capture(self.pg_interfaces)
4647 capture = self.pg8.get_capture(len(pkts))
4648 self.verify_capture_out(capture, ignore_port=True)
4650 if_idx = self.pg7.sw_if_index
4651 cnt = self.statistics.get_counter(
4652 '/nat44/ed/in2out/slowpath/tcp')[0]
4653 self.assertEqual(cnt[if_idx] - tcpn[if_idx], 2)
4654 cnt = self.statistics.get_counter(
4655 '/nat44/ed/in2out/slowpath/udp')[0]
4656 self.assertEqual(cnt[if_idx] - udpn[if_idx], 1)
4657 cnt = self.statistics.get_counter(
4658 '/nat44/ed/in2out/slowpath/icmp')[0]
4659 self.assertEqual(cnt[if_idx] - icmpn[if_idx], 1)
4660 cnt = self.statistics.get_counter(
4661 '/nat44/ed/in2out/slowpath/drops')[0]
4662 self.assertEqual(cnt[if_idx] - drops[if_idx], 0)
4665 tcpn = self.statistics.get_counter(
4666 '/nat44/ed/out2in/fastpath/tcp')[0]
4667 udpn = self.statistics.get_counter(
4668 '/nat44/ed/out2in/fastpath/udp')[0]
4669 icmpn = self.statistics.get_counter(
4670 '/nat44/ed/out2in/slowpath/icmp')[0]
4671 drops = self.statistics.get_counter(
4672 '/nat44/ed/out2in/fastpath/drops')[0]
4674 pkts = self.create_stream_out(self.pg8)
4675 self.pg8.add_stream(pkts)
4676 self.pg_enable_capture(self.pg_interfaces)
4678 capture = self.pg7.get_capture(len(pkts))
4679 self.verify_capture_in(capture, self.pg7)
4681 if_idx = self.pg8.sw_if_index
4682 cnt = self.statistics.get_counter(
4683 '/nat44/ed/out2in/fastpath/tcp')[0]
4684 self.assertEqual(cnt[if_idx] - tcpn[if_idx], 2)
4685 cnt = self.statistics.get_counter(
4686 '/nat44/ed/out2in/fastpath/udp')[0]
4687 self.assertEqual(cnt[if_idx] - udpn[if_idx], 1)
4688 cnt = self.statistics.get_counter(
4689 '/nat44/ed/out2in/slowpath/icmp')[0]
4690 self.assertEqual(cnt[if_idx] - icmpn[if_idx], 1)
4691 cnt = self.statistics.get_counter(
4692 '/nat44/ed/out2in/fastpath/drops')[0]
4693 self.assertEqual(cnt[if_idx] - drops[if_idx], 0)
4695 sessions = self.statistics.get_counter('/nat44/total-sessions')
4696 self.assertEqual(sessions[0][0], 3)
4699 self.pg7.unconfig_ip4()
4700 self.pg7.set_table_ip4(1)
4701 self.pg7.config_ip4()
4702 self.pg7.resolve_arp()
4704 self.pg8.unconfig_ip4()
4705 self.pg8.set_table_ip4(1)
4706 self.pg8.config_ip4()
4707 self.pg8.resolve_arp()
4709 self.vapi.ip_table_add_del(is_add=0,
4710 table={'table_id': new_vrf_id})
4712 def test_forwarding(self):
4713 """ NAT44 forwarding test """
4715 flags = self.config_flags.NAT_IS_INSIDE
4716 self.vapi.nat44_interface_add_del_feature(
4717 sw_if_index=self.pg0.sw_if_index,
4718 flags=flags, is_add=1)
4719 self.vapi.nat44_interface_add_del_feature(
4720 sw_if_index=self.pg1.sw_if_index,
4722 self.vapi.nat44_forwarding_enable_disable(enable=1)
4724 real_ip = self.pg0.remote_ip4
4725 alias_ip = self.nat_addr
4726 flags = self.config_flags.NAT_IS_ADDR_ONLY
4727 self.vapi.nat44_add_del_static_mapping(is_add=1,
4728 local_ip_address=real_ip,
4729 external_ip_address=alias_ip,
4730 external_sw_if_index=0xFFFFFFFF,
4734 # in2out - static mapping match
4736 pkts = self.create_stream_out(self.pg1)
4737 self.pg1.add_stream(pkts)
4738 self.pg_enable_capture(self.pg_interfaces)
4740 capture = self.pg0.get_capture(len(pkts))
4741 self.verify_capture_in(capture, self.pg0)
4743 pkts = self.create_stream_in(self.pg0, self.pg1)
4744 self.pg0.add_stream(pkts)
4745 self.pg_enable_capture(self.pg_interfaces)
4747 capture = self.pg1.get_capture(len(pkts))
4748 self.verify_capture_out(capture, same_port=True)
4750 # in2out - no static mapping match
4752 host0 = self.pg0.remote_hosts[0]
4753 self.pg0.remote_hosts[0] = self.pg0.remote_hosts[1]
4755 pkts = self.create_stream_out(self.pg1,
4756 dst_ip=self.pg0.remote_ip4,
4757 use_inside_ports=True)
4758 self.pg1.add_stream(pkts)
4759 self.pg_enable_capture(self.pg_interfaces)
4761 capture = self.pg0.get_capture(len(pkts))
4762 self.verify_capture_in(capture, self.pg0)
4764 pkts = self.create_stream_in(self.pg0, self.pg1)
4765 self.pg0.add_stream(pkts)
4766 self.pg_enable_capture(self.pg_interfaces)
4768 capture = self.pg1.get_capture(len(pkts))
4769 self.verify_capture_out(capture, nat_ip=self.pg0.remote_ip4,
4772 self.pg0.remote_hosts[0] = host0
4774 user = self.pg0.remote_hosts[1]
4775 sessions = self.vapi.nat44_user_session_dump(user.ip4, 0)
4776 self.assertEqual(len(sessions), 3)
4777 self.assertTrue(sessions[0].flags &
4778 self.config_flags.NAT_IS_EXT_HOST_VALID)
4779 self.vapi.nat44_del_session(
4780 address=sessions[0].inside_ip_address,
4781 port=sessions[0].inside_port,
4782 protocol=sessions[0].protocol,
4783 flags=(self.config_flags.NAT_IS_INSIDE |
4784 self.config_flags.NAT_IS_EXT_HOST_VALID),
4785 ext_host_address=sessions[0].ext_host_address,
4786 ext_host_port=sessions[0].ext_host_port)
4787 sessions = self.vapi.nat44_user_session_dump(user.ip4, 0)
4788 self.assertEqual(len(sessions), 2)
4791 self.vapi.nat44_forwarding_enable_disable(enable=0)
4792 flags = self.config_flags.NAT_IS_ADDR_ONLY
4793 self.vapi.nat44_add_del_static_mapping(
4795 local_ip_address=real_ip,
4796 external_ip_address=alias_ip,
4797 external_sw_if_index=0xFFFFFFFF,
4800 def test_static_lb(self):
4801 """ NAT44 local service load balancing """
4802 external_addr_n = self.nat_addr
4805 server1 = self.pg0.remote_hosts[0]
4806 server2 = self.pg0.remote_hosts[1]
4808 locals = [{'addr': server1.ip4,
4812 {'addr': server2.ip4,
4817 self.nat44_add_address(self.nat_addr)
4818 self.vapi.nat44_add_del_lb_static_mapping(
4820 external_addr=external_addr_n,
4821 external_port=external_port,
4822 protocol=IP_PROTOS.tcp,
4823 local_num=len(locals),
4825 flags = self.config_flags.NAT_IS_INSIDE
4826 self.vapi.nat44_interface_add_del_feature(
4827 sw_if_index=self.pg0.sw_if_index,
4828 flags=flags, is_add=1)
4829 self.vapi.nat44_interface_add_del_feature(
4830 sw_if_index=self.pg1.sw_if_index,
4833 # from client to service
4834 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
4835 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
4836 TCP(sport=12345, dport=external_port))
4837 self.pg1.add_stream(p)
4838 self.pg_enable_capture(self.pg_interfaces)
4840 capture = self.pg0.get_capture(1)
4846 self.assertIn(ip.dst, [server1.ip4, server2.ip4])
4847 if ip.dst == server1.ip4:
4851 self.assertEqual(tcp.dport, local_port)
4852 self.assert_packet_checksums_valid(p)
4854 self.logger.error(ppp("Unexpected or invalid packet:", p))
4857 # from service back to client
4858 p = (Ether(src=server.mac, dst=self.pg0.local_mac) /
4859 IP(src=server.ip4, dst=self.pg1.remote_ip4) /
4860 TCP(sport=local_port, dport=12345))
4861 self.pg0.add_stream(p)
4862 self.pg_enable_capture(self.pg_interfaces)
4864 capture = self.pg1.get_capture(1)
4869 self.assertEqual(ip.src, self.nat_addr)
4870 self.assertEqual(tcp.sport, external_port)
4871 self.assert_packet_checksums_valid(p)
4873 self.logger.error(ppp("Unexpected or invalid packet:", p))
4876 sessions = self.vapi.nat44_user_session_dump(server.ip4, 0)
4877 self.assertEqual(len(sessions), 1)
4878 self.assertTrue(sessions[0].flags &
4879 self.config_flags.NAT_IS_EXT_HOST_VALID)
4880 self.vapi.nat44_del_session(
4881 address=sessions[0].inside_ip_address,
4882 port=sessions[0].inside_port,
4883 protocol=sessions[0].protocol,
4884 flags=(self.config_flags.NAT_IS_INSIDE |
4885 self.config_flags.NAT_IS_EXT_HOST_VALID),
4886 ext_host_address=sessions[0].ext_host_address,
4887 ext_host_port=sessions[0].ext_host_port)
4888 sessions = self.vapi.nat44_user_session_dump(server.ip4, 0)
4889 self.assertEqual(len(sessions), 0)
4891 @unittest.skipUnless(running_extended_tests, "part of extended tests")
4892 def test_static_lb_multi_clients(self):
4893 """ NAT44 local service load balancing - multiple clients"""
4895 external_addr = self.nat_addr
4898 server1 = self.pg0.remote_hosts[0]
4899 server2 = self.pg0.remote_hosts[1]
4900 server3 = self.pg0.remote_hosts[2]
4902 locals = [{'addr': server1.ip4,
4906 {'addr': server2.ip4,
4911 self.nat44_add_address(self.nat_addr)
4912 self.vapi.nat44_add_del_lb_static_mapping(is_add=1,
4913 external_addr=external_addr,
4914 external_port=external_port,
4915 protocol=IP_PROTOS.tcp,
4916 local_num=len(locals),
4918 flags = self.config_flags.NAT_IS_INSIDE
4919 self.vapi.nat44_interface_add_del_feature(
4920 sw_if_index=self.pg0.sw_if_index,
4921 flags=flags, is_add=1)
4922 self.vapi.nat44_interface_add_del_feature(
4923 sw_if_index=self.pg1.sw_if_index,
4928 clients = ip4_range(self.pg1.remote_ip4, 10, 50)
4930 for client in clients:
4931 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
4932 IP(src=client, dst=self.nat_addr) /
4933 TCP(sport=12345, dport=external_port))
4935 self.pg1.add_stream(pkts)
4936 self.pg_enable_capture(self.pg_interfaces)
4938 capture = self.pg0.get_capture(len(pkts))
4940 if p[IP].dst == server1.ip4:
4944 self.assertGreater(server1_n, server2_n)
4947 'addr': server3.ip4,
4954 self.vapi.nat44_lb_static_mapping_add_del_local(
4956 external_addr=external_addr,
4957 external_port=external_port,
4959 protocol=IP_PROTOS.tcp)
4963 clients = ip4_range(self.pg1.remote_ip4, 60, 110)
4965 for client in clients:
4966 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
4967 IP(src=client, dst=self.nat_addr) /
4968 TCP(sport=12346, dport=external_port))
4970 self.assertGreater(len(pkts), 0)
4971 self.pg1.add_stream(pkts)
4972 self.pg_enable_capture(self.pg_interfaces)
4974 capture = self.pg0.get_capture(len(pkts))
4976 if p[IP].dst == server1.ip4:
4978 elif p[IP].dst == server2.ip4:
4982 self.assertGreater(server1_n, 0)
4983 self.assertGreater(server2_n, 0)
4984 self.assertGreater(server3_n, 0)
4987 'addr': server2.ip4,
4993 # remove one back-end
4994 self.vapi.nat44_lb_static_mapping_add_del_local(
4996 external_addr=external_addr,
4997 external_port=external_port,
4999 protocol=IP_PROTOS.tcp)
5003 self.pg1.add_stream(pkts)
5004 self.pg_enable_capture(self.pg_interfaces)
5006 capture = self.pg0.get_capture(len(pkts))
5008 if p[IP].dst == server1.ip4:
5010 elif p[IP].dst == server2.ip4:
5014 self.assertGreater(server1_n, 0)
5015 self.assertEqual(server2_n, 0)
5016 self.assertGreater(server3_n, 0)
5018 def test_static_lb_2(self):
5019 """ NAT44 local service load balancing (asymmetrical rule) """
5020 external_addr = self.nat_addr
5023 server1 = self.pg0.remote_hosts[0]
5024 server2 = self.pg0.remote_hosts[1]
5026 locals = [{'addr': server1.ip4,
5030 {'addr': server2.ip4,
5035 self.vapi.nat44_forwarding_enable_disable(enable=1)
5036 flags = self.config_flags.NAT_IS_OUT2IN_ONLY
5037 self.vapi.nat44_add_del_lb_static_mapping(is_add=1, flags=flags,
5038 external_addr=external_addr,
5039 external_port=external_port,
5040 protocol=IP_PROTOS.tcp,
5041 local_num=len(locals),
5043 flags = self.config_flags.NAT_IS_INSIDE
5044 self.vapi.nat44_interface_add_del_feature(
5045 sw_if_index=self.pg0.sw_if_index,
5046 flags=flags, is_add=1)
5047 self.vapi.nat44_interface_add_del_feature(
5048 sw_if_index=self.pg1.sw_if_index,
5051 # from client to service
5052 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
5053 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
5054 TCP(sport=12345, dport=external_port))
5055 self.pg1.add_stream(p)
5056 self.pg_enable_capture(self.pg_interfaces)
5058 capture = self.pg0.get_capture(1)
5064 self.assertIn(ip.dst, [server1.ip4, server2.ip4])
5065 if ip.dst == server1.ip4:
5069 self.assertEqual(tcp.dport, local_port)
5070 self.assert_packet_checksums_valid(p)
5072 self.logger.error(ppp("Unexpected or invalid packet:", p))
5075 # from service back to client
5076 p = (Ether(src=server.mac, dst=self.pg0.local_mac) /
5077 IP(src=server.ip4, dst=self.pg1.remote_ip4) /
5078 TCP(sport=local_port, dport=12345))
5079 self.pg0.add_stream(p)
5080 self.pg_enable_capture(self.pg_interfaces)
5082 capture = self.pg1.get_capture(1)
5087 self.assertEqual(ip.src, self.nat_addr)
5088 self.assertEqual(tcp.sport, external_port)
5089 self.assert_packet_checksums_valid(p)
5091 self.logger.error(ppp("Unexpected or invalid packet:", p))
5094 # from client to server (no translation)
5095 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
5096 IP(src=self.pg1.remote_ip4, dst=server1.ip4) /
5097 TCP(sport=12346, dport=local_port))
5098 self.pg1.add_stream(p)
5099 self.pg_enable_capture(self.pg_interfaces)
5101 capture = self.pg0.get_capture(1)
5107 self.assertEqual(ip.dst, server1.ip4)
5108 self.assertEqual(tcp.dport, local_port)
5109 self.assert_packet_checksums_valid(p)
5111 self.logger.error(ppp("Unexpected or invalid packet:", p))
5114 # from service back to client (no translation)
5115 p = (Ether(src=server1.mac, dst=self.pg0.local_mac) /
5116 IP(src=server1.ip4, dst=self.pg1.remote_ip4) /
5117 TCP(sport=local_port, dport=12346))
5118 self.pg0.add_stream(p)
5119 self.pg_enable_capture(self.pg_interfaces)
5121 capture = self.pg1.get_capture(1)
5126 self.assertEqual(ip.src, server1.ip4)
5127 self.assertEqual(tcp.sport, local_port)
5128 self.assert_packet_checksums_valid(p)
5130 self.logger.error(ppp("Unexpected or invalid packet:", p))
5133 def test_lb_affinity(self):
5134 """ NAT44 local service load balancing affinity """
5135 external_addr = self.nat_addr
5138 server1 = self.pg0.remote_hosts[0]
5139 server2 = self.pg0.remote_hosts[1]
5141 locals = [{'addr': server1.ip4,
5145 {'addr': server2.ip4,
5150 self.nat44_add_address(self.nat_addr)
5151 self.vapi.nat44_add_del_lb_static_mapping(is_add=1,
5152 external_addr=external_addr,
5153 external_port=external_port,
5154 protocol=IP_PROTOS.tcp,
5156 local_num=len(locals),
5158 flags = self.config_flags.NAT_IS_INSIDE
5159 self.vapi.nat44_interface_add_del_feature(
5160 sw_if_index=self.pg0.sw_if_index,
5161 flags=flags, is_add=1)
5162 self.vapi.nat44_interface_add_del_feature(
5163 sw_if_index=self.pg1.sw_if_index,
5166 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
5167 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
5168 TCP(sport=1025, dport=external_port))
5169 self.pg1.add_stream(p)
5170 self.pg_enable_capture(self.pg_interfaces)
5172 capture = self.pg0.get_capture(1)
5173 backend = capture[0][IP].dst
5175 sessions = self.vapi.nat44_user_session_dump(backend, 0)
5176 self.assertEqual(len(sessions), 1)
5177 self.assertTrue(sessions[0].flags &
5178 self.config_flags.NAT_IS_EXT_HOST_VALID)
5179 self.vapi.nat44_del_session(
5180 address=sessions[0].inside_ip_address,
5181 port=sessions[0].inside_port,
5182 protocol=sessions[0].protocol,
5183 flags=(self.config_flags.NAT_IS_INSIDE |
5184 self.config_flags.NAT_IS_EXT_HOST_VALID),
5185 ext_host_address=sessions[0].ext_host_address,
5186 ext_host_port=sessions[0].ext_host_port)
5189 for port in range(1030, 1100):
5190 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
5191 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
5192 TCP(sport=port, dport=external_port))
5194 self.pg1.add_stream(pkts)
5195 self.pg_enable_capture(self.pg_interfaces)
5197 capture = self.pg0.get_capture(len(pkts))
5199 self.assertEqual(p[IP].dst, backend)
5201 def test_unknown_proto(self):
5202 """ NAT44 translate packet with unknown protocol """
5203 self.nat44_add_address(self.nat_addr)
5204 flags = self.config_flags.NAT_IS_INSIDE
5205 self.vapi.nat44_interface_add_del_feature(
5206 sw_if_index=self.pg0.sw_if_index,
5207 flags=flags, is_add=1)
5208 self.vapi.nat44_interface_add_del_feature(
5209 sw_if_index=self.pg1.sw_if_index,
5213 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
5214 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
5215 TCP(sport=self.tcp_port_in, dport=20))
5216 self.pg0.add_stream(p)
5217 self.pg_enable_capture(self.pg_interfaces)
5219 p = self.pg1.get_capture(1)
5221 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
5222 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
5224 IP(src=self.pg2.remote_ip4, dst=self.pg2.remote_ip4) /
5225 TCP(sport=1234, dport=1234))
5226 self.pg0.add_stream(p)
5227 self.pg_enable_capture(self.pg_interfaces)
5229 p = self.pg1.get_capture(1)
5232 self.assertEqual(packet[IP].src, self.nat_addr)
5233 self.assertEqual(packet[IP].dst, self.pg1.remote_ip4)
5234 self.assertEqual(packet.haslayer(GRE), 1)
5235 self.assert_packet_checksums_valid(packet)
5237 self.logger.error(ppp("Unexpected or invalid packet:", packet))
5241 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
5242 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
5244 IP(src=self.pg2.remote_ip4, dst=self.pg2.remote_ip4) /
5245 TCP(sport=1234, dport=1234))
5246 self.pg1.add_stream(p)
5247 self.pg_enable_capture(self.pg_interfaces)
5249 p = self.pg0.get_capture(1)
5252 self.assertEqual(packet[IP].src, self.pg1.remote_ip4)
5253 self.assertEqual(packet[IP].dst, self.pg0.remote_ip4)
5254 self.assertEqual(packet.haslayer(GRE), 1)
5255 self.assert_packet_checksums_valid(packet)
5257 self.logger.error(ppp("Unexpected or invalid packet:", packet))
5260 def test_hairpinning_unknown_proto(self):
5261 """ NAT44 translate packet with unknown protocol - hairpinning """
5262 host = self.pg0.remote_hosts[0]
5263 server = self.pg0.remote_hosts[1]
5265 server_out_port = 8765
5266 server_nat_ip = "10.0.0.11"
5268 self.nat44_add_address(self.nat_addr)
5269 flags = self.config_flags.NAT_IS_INSIDE
5270 self.vapi.nat44_interface_add_del_feature(
5271 sw_if_index=self.pg0.sw_if_index,
5272 flags=flags, is_add=1)
5273 self.vapi.nat44_interface_add_del_feature(
5274 sw_if_index=self.pg1.sw_if_index,
5277 # add static mapping for server
5278 self.nat44_add_static_mapping(server.ip4, server_nat_ip)
5281 p = (Ether(src=host.mac, dst=self.pg0.local_mac) /
5282 IP(src=host.ip4, dst=server_nat_ip) /
5283 TCP(sport=host_in_port, dport=server_out_port))
5284 self.pg0.add_stream(p)
5285 self.pg_enable_capture(self.pg_interfaces)
5287 self.pg0.get_capture(1)
5289 p = (Ether(dst=self.pg0.local_mac, src=host.mac) /
5290 IP(src=host.ip4, dst=server_nat_ip) /
5292 IP(src=self.pg2.remote_ip4, dst=self.pg2.remote_ip4) /
5293 TCP(sport=1234, dport=1234))
5294 self.pg0.add_stream(p)
5295 self.pg_enable_capture(self.pg_interfaces)
5297 p = self.pg0.get_capture(1)
5300 self.assertEqual(packet[IP].src, self.nat_addr)
5301 self.assertEqual(packet[IP].dst, server.ip4)
5302 self.assertEqual(packet.haslayer(GRE), 1)
5303 self.assert_packet_checksums_valid(packet)
5305 self.logger.error(ppp("Unexpected or invalid packet:", packet))
5309 p = (Ether(dst=self.pg0.local_mac, src=server.mac) /
5310 IP(src=server.ip4, dst=self.nat_addr) /
5312 IP(src=self.pg2.remote_ip4, dst=self.pg2.remote_ip4) /
5313 TCP(sport=1234, dport=1234))
5314 self.pg0.add_stream(p)
5315 self.pg_enable_capture(self.pg_interfaces)
5317 p = self.pg0.get_capture(1)
5320 self.assertEqual(packet[IP].src, server_nat_ip)
5321 self.assertEqual(packet[IP].dst, host.ip4)
5322 self.assertEqual(packet.haslayer(GRE), 1)
5323 self.assert_packet_checksums_valid(packet)
5325 self.logger.error(ppp("Unexpected or invalid packet:", packet))
5328 def test_output_feature_and_service(self):
5329 """ NAT44 interface output feature and services """
5330 external_addr = '1.2.3.4'
5334 self.vapi.nat44_forwarding_enable_disable(enable=1)
5335 self.nat44_add_address(self.nat_addr)
5336 flags = self.config_flags.NAT_IS_ADDR_ONLY
5337 self.vapi.nat44_add_del_identity_mapping(
5338 ip_address=self.pg1.remote_ip4, sw_if_index=0xFFFFFFFF,
5339 flags=flags, is_add=1)
5340 flags = self.config_flags.NAT_IS_OUT2IN_ONLY
5341 self.nat44_add_static_mapping(self.pg0.remote_ip4, external_addr,
5342 local_port, external_port,
5343 proto=IP_PROTOS.tcp, flags=flags)
5344 flags = self.config_flags.NAT_IS_INSIDE
5345 self.vapi.nat44_interface_add_del_feature(
5346 sw_if_index=self.pg0.sw_if_index,
5348 self.vapi.nat44_interface_add_del_feature(
5349 sw_if_index=self.pg0.sw_if_index,
5350 flags=flags, is_add=1)
5351 self.vapi.nat44_interface_add_del_output_feature(
5353 sw_if_index=self.pg1.sw_if_index)
5355 # from client to service
5356 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
5357 IP(src=self.pg1.remote_ip4, dst=external_addr) /
5358 TCP(sport=12345, dport=external_port))
5359 self.pg1.add_stream(p)
5360 self.pg_enable_capture(self.pg_interfaces)
5362 capture = self.pg0.get_capture(1)
5367 self.assertEqual(ip.dst, self.pg0.remote_ip4)
5368 self.assertEqual(tcp.dport, local_port)
5369 self.assert_packet_checksums_valid(p)
5371 self.logger.error(ppp("Unexpected or invalid packet:", p))
5374 # from service back to client
5375 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5376 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
5377 TCP(sport=local_port, dport=12345))
5378 self.pg0.add_stream(p)
5379 self.pg_enable_capture(self.pg_interfaces)
5381 capture = self.pg1.get_capture(1)
5386 self.assertEqual(ip.src, external_addr)
5387 self.assertEqual(tcp.sport, external_port)
5388 self.assert_packet_checksums_valid(p)
5390 self.logger.error(ppp("Unexpected or invalid packet:", p))
5393 # from local network host to external network
5394 pkts = self.create_stream_in(self.pg0, self.pg1)
5395 self.pg0.add_stream(pkts)
5396 self.pg_enable_capture(self.pg_interfaces)
5398 capture = self.pg1.get_capture(len(pkts))
5399 self.verify_capture_out(capture, ignore_port=True)
5400 pkts = self.create_stream_in(self.pg0, self.pg1)
5401 self.pg0.add_stream(pkts)
5402 self.pg_enable_capture(self.pg_interfaces)
5404 capture = self.pg1.get_capture(len(pkts))
5405 self.verify_capture_out(capture, ignore_port=True)
5407 # from external network back to local network host
5408 pkts = self.create_stream_out(self.pg1)
5409 self.pg1.add_stream(pkts)
5410 self.pg_enable_capture(self.pg_interfaces)
5412 capture = self.pg0.get_capture(len(pkts))
5413 self.verify_capture_in(capture, self.pg0)
5415 def test_output_feature_and_service2(self):
5416 """ NAT44 interface output feature and service host direct access """
5417 self.vapi.nat44_forwarding_enable_disable(enable=1)
5418 self.nat44_add_address(self.nat_addr)
5419 self.vapi.nat44_interface_add_del_output_feature(
5421 sw_if_index=self.pg1.sw_if_index)
5423 # session initiated from service host - translate
5424 pkts = self.create_stream_in(self.pg0, self.pg1)
5425 self.pg0.add_stream(pkts)
5426 self.pg_enable_capture(self.pg_interfaces)
5428 capture = self.pg1.get_capture(len(pkts))
5429 self.verify_capture_out(capture, ignore_port=True)
5431 pkts = self.create_stream_out(self.pg1)
5432 self.pg1.add_stream(pkts)
5433 self.pg_enable_capture(self.pg_interfaces)
5435 capture = self.pg0.get_capture(len(pkts))
5436 self.verify_capture_in(capture, self.pg0)
5438 # session initiated from remote host - do not translate
5439 self.tcp_port_in = 60303
5440 self.udp_port_in = 60304
5441 self.icmp_id_in = 60305
5442 pkts = self.create_stream_out(self.pg1,
5443 self.pg0.remote_ip4,
5444 use_inside_ports=True)
5445 self.pg1.add_stream(pkts)
5446 self.pg_enable_capture(self.pg_interfaces)
5448 capture = self.pg0.get_capture(len(pkts))
5449 self.verify_capture_in(capture, self.pg0)
5451 pkts = self.create_stream_in(self.pg0, self.pg1)
5452 self.pg0.add_stream(pkts)
5453 self.pg_enable_capture(self.pg_interfaces)
5455 capture = self.pg1.get_capture(len(pkts))
5456 self.verify_capture_out(capture, nat_ip=self.pg0.remote_ip4,
5459 def test_output_feature_and_service3(self):
5460 """ NAT44 interface output feature and DST NAT """
5461 external_addr = '1.2.3.4'
5465 self.vapi.nat44_forwarding_enable_disable(enable=1)
5466 self.nat44_add_address(self.nat_addr)
5467 flags = self.config_flags.NAT_IS_OUT2IN_ONLY
5468 self.nat44_add_static_mapping(self.pg1.remote_ip4, external_addr,
5469 local_port, external_port,
5470 proto=IP_PROTOS.tcp, flags=flags)
5471 flags = self.config_flags.NAT_IS_INSIDE
5472 self.vapi.nat44_interface_add_del_feature(
5473 sw_if_index=self.pg0.sw_if_index,
5475 self.vapi.nat44_interface_add_del_feature(
5476 sw_if_index=self.pg0.sw_if_index,
5477 flags=flags, is_add=1)
5478 self.vapi.nat44_interface_add_del_output_feature(
5480 sw_if_index=self.pg1.sw_if_index)
5482 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5483 IP(src=self.pg0.remote_ip4, dst=external_addr) /
5484 TCP(sport=12345, dport=external_port))
5485 self.pg0.add_stream(p)
5486 self.pg_enable_capture(self.pg_interfaces)
5488 capture = self.pg1.get_capture(1)
5493 self.assertEqual(ip.src, self.pg0.remote_ip4)
5494 self.assertEqual(tcp.sport, 12345)
5495 self.assertEqual(ip.dst, self.pg1.remote_ip4)
5496 self.assertEqual(tcp.dport, local_port)
5497 self.assert_packet_checksums_valid(p)
5499 self.logger.error(ppp("Unexpected or invalid packet:", p))
5502 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
5503 IP(src=self.pg1.remote_ip4, dst=self.pg0.remote_ip4) /
5504 TCP(sport=local_port, dport=12345))
5505 self.pg1.add_stream(p)
5506 self.pg_enable_capture(self.pg_interfaces)
5508 capture = self.pg0.get_capture(1)
5513 self.assertEqual(ip.src, external_addr)
5514 self.assertEqual(tcp.sport, external_port)
5515 self.assertEqual(ip.dst, self.pg0.remote_ip4)
5516 self.assertEqual(tcp.dport, 12345)
5517 self.assert_packet_checksums_valid(p)
5519 self.logger.error(ppp("Unexpected or invalid packet:", p))
5522 def test_next_src_nat(self):
5523 """ On way back forward packet to nat44-in2out node. """
5524 twice_nat_addr = '10.0.1.3'
5527 post_twice_nat_port = 0
5529 self.vapi.nat44_forwarding_enable_disable(enable=1)
5530 self.nat44_add_address(twice_nat_addr, twice_nat=1)
5531 flags = (self.config_flags.NAT_IS_OUT2IN_ONLY |
5532 self.config_flags.NAT_IS_SELF_TWICE_NAT)
5533 self.nat44_add_static_mapping(self.pg6.remote_ip4, self.pg1.remote_ip4,
5534 local_port, external_port,
5535 proto=IP_PROTOS.tcp, vrf_id=1,
5537 self.vapi.nat44_interface_add_del_feature(
5538 sw_if_index=self.pg6.sw_if_index,
5541 p = (Ether(src=self.pg6.remote_mac, dst=self.pg6.local_mac) /
5542 IP(src=self.pg6.remote_ip4, dst=self.pg1.remote_ip4) /
5543 TCP(sport=12345, dport=external_port))
5544 self.pg6.add_stream(p)
5545 self.pg_enable_capture(self.pg_interfaces)
5547 capture = self.pg6.get_capture(1)
5552 self.assertEqual(ip.src, twice_nat_addr)
5553 self.assertNotEqual(tcp.sport, 12345)
5554 post_twice_nat_port = tcp.sport
5555 self.assertEqual(ip.dst, self.pg6.remote_ip4)
5556 self.assertEqual(tcp.dport, local_port)
5557 self.assert_packet_checksums_valid(p)
5559 self.logger.error(ppp("Unexpected or invalid packet:", p))
5562 p = (Ether(src=self.pg6.remote_mac, dst=self.pg6.local_mac) /
5563 IP(src=self.pg6.remote_ip4, dst=twice_nat_addr) /
5564 TCP(sport=local_port, dport=post_twice_nat_port))
5565 self.pg6.add_stream(p)
5566 self.pg_enable_capture(self.pg_interfaces)
5568 capture = self.pg6.get_capture(1)
5573 self.assertEqual(ip.src, self.pg1.remote_ip4)
5574 self.assertEqual(tcp.sport, external_port)
5575 self.assertEqual(ip.dst, self.pg6.remote_ip4)
5576 self.assertEqual(tcp.dport, 12345)
5577 self.assert_packet_checksums_valid(p)
5579 self.logger.error(ppp("Unexpected or invalid packet:", p))
5582 def twice_nat_common(self, self_twice_nat=False, same_pg=False, lb=False,
5584 twice_nat_addr = '10.0.1.3'
5592 port_in1 = port_in + 1
5593 port_in2 = port_in + 2
5598 server1 = self.pg0.remote_hosts[0]
5599 server2 = self.pg0.remote_hosts[1]
5611 eh_translate = ((not self_twice_nat) or (not lb and same_pg) or
5614 self.nat44_add_address(self.nat_addr)
5615 self.nat44_add_address(twice_nat_addr, twice_nat=1)
5619 flags |= self.config_flags.NAT_IS_SELF_TWICE_NAT
5621 flags |= self.config_flags.NAT_IS_TWICE_NAT
5624 self.nat44_add_static_mapping(pg0.remote_ip4, self.nat_addr,
5626 proto=IP_PROTOS.tcp,
5629 locals = [{'addr': server1.ip4,
5633 {'addr': server2.ip4,
5637 out_addr = self.nat_addr
5639 self.vapi.nat44_add_del_lb_static_mapping(is_add=1, flags=flags,
5640 external_addr=out_addr,
5641 external_port=port_out,
5642 protocol=IP_PROTOS.tcp,
5643 local_num=len(locals),
5645 flags = self.config_flags.NAT_IS_INSIDE
5646 self.vapi.nat44_interface_add_del_feature(
5647 sw_if_index=pg0.sw_if_index,
5648 flags=flags, is_add=1)
5649 self.vapi.nat44_interface_add_del_feature(
5650 sw_if_index=pg1.sw_if_index,
5657 assert client_id is not None
5659 client = self.pg0.remote_hosts[0]
5660 elif client_id == 2:
5661 client = self.pg0.remote_hosts[1]
5663 client = pg1.remote_hosts[0]
5664 p = (Ether(src=pg1.remote_mac, dst=pg1.local_mac) /
5665 IP(src=client.ip4, dst=self.nat_addr) /
5666 TCP(sport=eh_port_out, dport=port_out))
5668 self.pg_enable_capture(self.pg_interfaces)
5670 capture = pg0.get_capture(1)
5676 if ip.dst == server1.ip4:
5682 self.assertEqual(ip.dst, server.ip4)
5684 self.assertIn(tcp.dport, [port_in1, port_in2])
5686 self.assertEqual(tcp.dport, port_in)
5688 self.assertEqual(ip.src, twice_nat_addr)
5689 self.assertNotEqual(tcp.sport, eh_port_out)
5691 self.assertEqual(ip.src, client.ip4)
5692 self.assertEqual(tcp.sport, eh_port_out)
5694 eh_port_in = tcp.sport
5695 saved_port_in = tcp.dport
5696 self.assert_packet_checksums_valid(p)
5698 self.logger.error(ppp("Unexpected or invalid packet:", p))
5701 p = (Ether(src=server.mac, dst=pg0.local_mac) /
5702 IP(src=server.ip4, dst=eh_addr_in) /
5703 TCP(sport=saved_port_in, dport=eh_port_in))
5705 self.pg_enable_capture(self.pg_interfaces)
5707 capture = pg1.get_capture(1)
5712 self.assertEqual(ip.dst, client.ip4)
5713 self.assertEqual(ip.src, self.nat_addr)
5714 self.assertEqual(tcp.dport, eh_port_out)
5715 self.assertEqual(tcp.sport, port_out)
5716 self.assert_packet_checksums_valid(p)
5718 self.logger.error(ppp("Unexpected or invalid packet:", p))
5722 sessions = self.vapi.nat44_user_session_dump(server.ip4, 0)
5723 self.assertEqual(len(sessions), 1)
5724 self.assertTrue(sessions[0].flags &
5725 self.config_flags.NAT_IS_EXT_HOST_VALID)
5726 self.assertTrue(sessions[0].flags &
5727 self.config_flags.NAT_IS_TWICE_NAT)
5728 self.logger.info(self.vapi.cli("show nat44 sessions detail"))
5729 self.vapi.nat44_del_session(
5730 address=sessions[0].inside_ip_address,
5731 port=sessions[0].inside_port,
5732 protocol=sessions[0].protocol,
5733 flags=(self.config_flags.NAT_IS_INSIDE |
5734 self.config_flags.NAT_IS_EXT_HOST_VALID),
5735 ext_host_address=sessions[0].ext_host_nat_address,
5736 ext_host_port=sessions[0].ext_host_nat_port)
5737 sessions = self.vapi.nat44_user_session_dump(server.ip4, 0)
5738 self.assertEqual(len(sessions), 0)
5740 def test_twice_nat(self):
5742 self.twice_nat_common()
5744 def test_self_twice_nat_positive(self):
5745 """ Self Twice NAT44 (positive test) """
5746 self.twice_nat_common(self_twice_nat=True, same_pg=True)
5748 def test_self_twice_nat_negative(self):
5749 """ Self Twice NAT44 (negative test) """
5750 self.twice_nat_common(self_twice_nat=True)
5752 def test_twice_nat_lb(self):
5753 """ Twice NAT44 local service load balancing """
5754 self.twice_nat_common(lb=True)
5756 def test_self_twice_nat_lb_positive(self):
5757 """ Self Twice NAT44 local service load balancing (positive test) """
5758 self.twice_nat_common(lb=True, self_twice_nat=True, same_pg=True,
5761 def test_self_twice_nat_lb_negative(self):
5762 """ Self Twice NAT44 local service load balancing (negative test) """
5763 self.twice_nat_common(lb=True, self_twice_nat=True, same_pg=True,
5766 def test_twice_nat_interface_addr(self):
5767 """ Acquire twice NAT44 addresses from interface """
5768 flags = self.config_flags.NAT_IS_TWICE_NAT
5769 self.vapi.nat44_add_del_interface_addr(
5771 sw_if_index=self.pg3.sw_if_index,
5774 # no address in NAT pool
5775 adresses = self.vapi.nat44_address_dump()
5776 self.assertEqual(0, len(adresses))
5778 # configure interface address and check NAT address pool
5779 self.pg3.config_ip4()
5780 adresses = self.vapi.nat44_address_dump()
5781 self.assertEqual(1, len(adresses))
5782 self.assertEqual(str(adresses[0].ip_address),
5784 self.assertEqual(adresses[0].flags, flags)
5786 # remove interface address and check NAT address pool
5787 self.pg3.unconfig_ip4()
5788 adresses = self.vapi.nat44_address_dump()
5789 self.assertEqual(0, len(adresses))
5791 def test_tcp_close(self):
5792 """ Close TCP session from inside network - output feature """
5793 self.vapi.nat44_forwarding_enable_disable(enable=1)
5794 self.nat44_add_address(self.pg1.local_ip4)
5795 twice_nat_addr = '10.0.1.3'
5796 service_ip = '192.168.16.150'
5797 self.nat44_add_address(twice_nat_addr, twice_nat=1)
5798 flags = self.config_flags.NAT_IS_INSIDE
5799 self.vapi.nat44_interface_add_del_feature(
5800 sw_if_index=self.pg0.sw_if_index,
5802 self.vapi.nat44_interface_add_del_feature(
5803 sw_if_index=self.pg0.sw_if_index,
5804 flags=flags, is_add=1)
5805 self.vapi.nat44_interface_add_del_output_feature(
5807 sw_if_index=self.pg1.sw_if_index)
5808 flags = (self.config_flags.NAT_IS_OUT2IN_ONLY |
5809 self.config_flags.NAT_IS_TWICE_NAT)
5810 self.nat44_add_static_mapping(self.pg0.remote_ip4,
5814 proto=IP_PROTOS.tcp,
5816 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4, 0)
5817 start_sessnum = len(sessions)
5819 # SYN packet out->in
5820 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
5821 IP(src=self.pg1.remote_ip4, dst=service_ip) /
5822 TCP(sport=33898, dport=80, flags="S"))
5823 self.pg1.add_stream(p)
5824 self.pg_enable_capture(self.pg_interfaces)
5826 capture = self.pg0.get_capture(1)
5828 tcp_port = p[TCP].sport
5830 # SYN + ACK packet in->out
5831 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5832 IP(src=self.pg0.remote_ip4, dst=twice_nat_addr) /
5833 TCP(sport=80, dport=tcp_port, flags="SA"))
5834 self.pg0.add_stream(p)
5835 self.pg_enable_capture(self.pg_interfaces)
5837 self.pg1.get_capture(1)
5839 # ACK packet out->in
5840 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
5841 IP(src=self.pg1.remote_ip4, dst=service_ip) /
5842 TCP(sport=33898, dport=80, flags="A"))
5843 self.pg1.add_stream(p)
5844 self.pg_enable_capture(self.pg_interfaces)
5846 self.pg0.get_capture(1)
5848 # FIN packet in -> out
5849 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5850 IP(src=self.pg0.remote_ip4, dst=twice_nat_addr) /
5851 TCP(sport=80, dport=tcp_port, flags="FA", seq=100, ack=300))
5852 self.pg0.add_stream(p)
5853 self.pg_enable_capture(self.pg_interfaces)
5855 self.pg1.get_capture(1)
5857 # FIN+ACK packet out -> in
5858 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
5859 IP(src=self.pg1.remote_ip4, dst=service_ip) /
5860 TCP(sport=33898, dport=80, flags="FA", seq=300, ack=101))
5861 self.pg1.add_stream(p)
5862 self.pg_enable_capture(self.pg_interfaces)
5864 self.pg0.get_capture(1)
5866 # ACK packet in -> out
5867 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5868 IP(src=self.pg0.remote_ip4, dst=twice_nat_addr) /
5869 TCP(sport=80, dport=tcp_port, flags="A", seq=101, ack=301))
5870 self.pg0.add_stream(p)
5871 self.pg_enable_capture(self.pg_interfaces)
5873 self.pg1.get_capture(1)
5875 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4,
5877 self.assertEqual(len(sessions) - start_sessnum, 0)
5879 def test_tcp_session_close_in(self):
5880 """ Close TCP session from inside network """
5881 self.tcp_port_out = 10505
5882 self.nat44_add_address(self.nat_addr)
5883 flags = self.config_flags.NAT_IS_TWICE_NAT
5884 self.nat44_add_static_mapping(self.pg0.remote_ip4,
5888 proto=IP_PROTOS.tcp,
5890 flags = self.config_flags.NAT_IS_INSIDE
5891 self.vapi.nat44_interface_add_del_feature(
5892 sw_if_index=self.pg0.sw_if_index,
5893 flags=flags, is_add=1)
5894 self.vapi.nat44_interface_add_del_feature(
5895 sw_if_index=self.pg1.sw_if_index,
5898 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4, 0)
5899 start_sessnum = len(sessions)
5901 self.vapi.nat_set_timeouts(udp=300, tcp_established=7440,
5902 tcp_transitory=2, icmp=5)
5904 self.initiate_tcp_session(self.pg0, self.pg1)
5906 # FIN packet in -> out
5907 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5908 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
5909 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
5910 flags="FA", seq=100, ack=300))
5911 self.pg0.add_stream(p)
5912 self.pg_enable_capture(self.pg_interfaces)
5914 self.pg1.get_capture(1)
5918 # ACK packet out -> in
5919 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
5920 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
5921 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
5922 flags="A", seq=300, ack=101))
5925 # FIN packet out -> in
5926 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
5927 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
5928 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
5929 flags="FA", seq=300, ack=101))
5932 self.pg1.add_stream(pkts)
5933 self.pg_enable_capture(self.pg_interfaces)
5935 self.pg0.get_capture(2)
5937 # ACK packet in -> out
5938 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5939 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
5940 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
5941 flags="A", seq=101, ack=301))
5942 self.pg0.add_stream(p)
5943 self.pg_enable_capture(self.pg_interfaces)
5945 self.pg1.get_capture(1)
5947 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4, 0)
5948 self.assertEqual(len(sessions) - start_sessnum, 1)
5950 stats = self.statistics.get_counter(
5951 '/err/nat44-ed-out2in/drops due to TCP in transitory timeout')
5952 out2in_drops = stats[0]
5953 stats = self.statistics.get_counter(
5954 '/err/nat44-ed-in2out/drops due to TCP in transitory timeout')
5955 in2out_drops = stats[0]
5957 # extra FIN packet out -> in - this should be dropped
5958 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
5959 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
5960 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
5961 flags="FA", seq=300, ack=101))
5963 self.pg1.add_stream(p)
5964 self.pg_enable_capture(self.pg_interfaces)
5966 self.pg0.assert_nothing_captured()
5968 # extra ACK packet in -> out - this should be dropped
5969 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5970 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
5971 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
5972 flags="A", seq=101, ack=301))
5973 self.pg0.add_stream(p)
5974 self.pg_enable_capture(self.pg_interfaces)
5976 self.pg1.assert_nothing_captured()
5978 stats = self.statistics.get_counter(
5979 '/err/nat44-ed-out2in/drops due to TCP in transitory timeout')
5980 self.assertEqual(stats[0] - out2in_drops, 1)
5981 stats = self.statistics.get_counter(
5982 '/err/nat44-ed-in2out/drops due to TCP in transitory timeout')
5983 self.assertEqual(stats[0] - in2out_drops, 1)
5986 # extra ACK packet in -> out - this will cause session to be wiped
5987 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5988 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
5989 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
5990 flags="A", seq=101, ack=301))
5991 self.pg0.add_stream(p)
5992 self.pg_enable_capture(self.pg_interfaces)
5994 self.pg1.assert_nothing_captured()
5995 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4, 0)
5996 self.assertEqual(len(sessions) - start_sessnum, 0)
5998 def test_tcp_session_close_out(self):
5999 """ Close TCP session from outside network """
6000 self.tcp_port_out = 10505
6001 self.nat44_add_address(self.nat_addr)
6002 flags = self.config_flags.NAT_IS_TWICE_NAT
6003 self.nat44_add_static_mapping(self.pg0.remote_ip4,
6007 proto=IP_PROTOS.tcp,
6009 flags = self.config_flags.NAT_IS_INSIDE
6010 self.vapi.nat44_interface_add_del_feature(
6011 sw_if_index=self.pg0.sw_if_index,
6012 flags=flags, is_add=1)
6013 self.vapi.nat44_interface_add_del_feature(
6014 sw_if_index=self.pg1.sw_if_index,
6017 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4, 0)
6018 start_sessnum = len(sessions)
6020 self.vapi.nat_set_timeouts(udp=300, tcp_established=7440,
6021 tcp_transitory=2, icmp=5)
6023 self.initiate_tcp_session(self.pg0, self.pg1)
6025 # FIN packet out -> in
6026 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
6027 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
6028 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
6029 flags="FA", seq=100, ack=300))
6030 self.pg1.add_stream(p)
6031 self.pg_enable_capture(self.pg_interfaces)
6033 self.pg0.get_capture(1)
6035 # FIN+ACK packet in -> out
6036 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6037 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6038 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
6039 flags="FA", seq=300, ack=101))
6041 self.pg0.add_stream(p)
6042 self.pg_enable_capture(self.pg_interfaces)
6044 self.pg1.get_capture(1)
6046 # ACK packet out -> in
6047 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
6048 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
6049 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
6050 flags="A", seq=101, ack=301))
6051 self.pg1.add_stream(p)
6052 self.pg_enable_capture(self.pg_interfaces)
6054 self.pg0.get_capture(1)
6056 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4, 0)
6057 self.assertEqual(len(sessions) - start_sessnum, 1)
6059 stats = self.statistics.get_counter(
6060 '/err/nat44-ed-out2in/drops due to TCP in transitory timeout')
6061 out2in_drops = stats[0]
6062 stats = self.statistics.get_counter(
6063 '/err/nat44-ed-in2out/drops due to TCP in transitory timeout')
6064 in2out_drops = stats[0]
6066 # extra FIN packet out -> in - this should be dropped
6067 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
6068 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
6069 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
6070 flags="FA", seq=300, ack=101))
6072 self.pg1.add_stream(p)
6073 self.pg_enable_capture(self.pg_interfaces)
6075 self.pg0.assert_nothing_captured()
6077 # extra ACK packet in -> out - this should be dropped
6078 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6079 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6080 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
6081 flags="A", seq=101, ack=301))
6082 self.pg0.add_stream(p)
6083 self.pg_enable_capture(self.pg_interfaces)
6085 self.pg1.assert_nothing_captured()
6087 stats = self.statistics.get_counter(
6088 '/err/nat44-ed-out2in/drops due to TCP in transitory timeout')
6089 self.assertEqual(stats[0] - out2in_drops, 1)
6090 stats = self.statistics.get_counter(
6091 '/err/nat44-ed-in2out/drops due to TCP in transitory timeout')
6092 self.assertEqual(stats[0] - in2out_drops, 1)
6095 # extra ACK packet in -> out - this will cause session to be wiped
6096 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6097 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6098 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
6099 flags="A", seq=101, ack=301))
6100 self.pg0.add_stream(p)
6101 self.pg_enable_capture(self.pg_interfaces)
6103 self.pg1.assert_nothing_captured()
6104 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4, 0)
6105 self.assertEqual(len(sessions) - start_sessnum, 0)
6107 def test_tcp_session_close_simultaneous(self):
6108 """ Close TCP session from inside network """
6109 self.tcp_port_out = 10505
6110 self.nat44_add_address(self.nat_addr)
6111 flags = self.config_flags.NAT_IS_TWICE_NAT
6112 self.nat44_add_static_mapping(self.pg0.remote_ip4,
6116 proto=IP_PROTOS.tcp,
6118 flags = self.config_flags.NAT_IS_INSIDE
6119 self.vapi.nat44_interface_add_del_feature(
6120 sw_if_index=self.pg0.sw_if_index,
6121 flags=flags, is_add=1)
6122 self.vapi.nat44_interface_add_del_feature(
6123 sw_if_index=self.pg1.sw_if_index,
6126 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4, 0)
6127 start_sessnum = len(sessions)
6129 self.vapi.nat_set_timeouts(udp=300, tcp_established=7440,
6130 tcp_transitory=2, icmp=5)
6132 self.initiate_tcp_session(self.pg0, self.pg1)
6134 # FIN packet in -> out
6135 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6136 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6137 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
6138 flags="FA", seq=100, ack=300))
6139 self.pg0.add_stream(p)
6140 self.pg_enable_capture(self.pg_interfaces)
6142 self.pg1.get_capture(1)
6144 # FIN packet out -> in
6145 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
6146 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
6147 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
6148 flags="FA", seq=300, ack=100))
6149 self.pg1.add_stream(p)
6150 self.pg_enable_capture(self.pg_interfaces)
6152 self.pg0.get_capture(1)
6154 # ACK packet in -> out
6155 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6156 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6157 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
6158 flags="A", seq=101, ack=301))
6159 self.pg0.add_stream(p)
6160 self.pg_enable_capture(self.pg_interfaces)
6162 self.pg1.get_capture(1)
6164 # ACK packet out -> in
6165 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
6166 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
6167 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
6168 flags="A", seq=301, ack=101))
6169 self.pg1.add_stream(p)
6170 self.pg_enable_capture(self.pg_interfaces)
6172 self.pg0.get_capture(1)
6174 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4, 0)
6175 self.assertEqual(len(sessions) - start_sessnum, 1)
6177 stats = self.statistics.get_counter(
6178 '/err/nat44-ed-out2in/drops due to TCP in transitory timeout')
6179 out2in_drops = stats[0]
6180 stats = self.statistics.get_counter(
6181 '/err/nat44-ed-in2out/drops due to TCP in transitory timeout')
6182 in2out_drops = stats[0]
6184 # extra FIN packet out -> in - this should be dropped
6185 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
6186 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
6187 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
6188 flags="FA", seq=300, ack=101))
6190 self.pg1.add_stream(p)
6191 self.pg_enable_capture(self.pg_interfaces)
6193 self.pg0.assert_nothing_captured()
6195 # extra ACK packet in -> out - this should be dropped
6196 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6197 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6198 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
6199 flags="A", seq=101, ack=301))
6200 self.pg0.add_stream(p)
6201 self.pg_enable_capture(self.pg_interfaces)
6203 self.pg1.assert_nothing_captured()
6205 stats = self.statistics.get_counter(
6206 '/err/nat44-ed-out2in/drops due to TCP in transitory timeout')
6207 self.assertEqual(stats[0] - out2in_drops, 1)
6208 stats = self.statistics.get_counter(
6209 '/err/nat44-ed-in2out/drops due to TCP in transitory timeout')
6210 self.assertEqual(stats[0] - in2out_drops, 1)
6213 # extra ACK packet in -> out - this will cause session to be wiped
6214 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6215 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6216 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
6217 flags="A", seq=101, ack=301))
6218 self.pg0.add_stream(p)
6219 self.pg_enable_capture(self.pg_interfaces)
6221 self.pg1.assert_nothing_captured()
6222 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4, 0)
6223 self.assertEqual(len(sessions) - start_sessnum, 0)
6225 def test_one_armed_nat44_static(self):
6226 """ One armed NAT44 and 1:1 NAPT asymmetrical rule """
6227 remote_host = self.pg4.remote_hosts[0]
6228 local_host = self.pg4.remote_hosts[1]
6233 self.vapi.nat44_forwarding_enable_disable(enable=1)
6234 self.nat44_add_address(self.nat_addr, twice_nat=1)
6235 flags = (self.config_flags.NAT_IS_OUT2IN_ONLY |
6236 self.config_flags.NAT_IS_TWICE_NAT)
6237 self.nat44_add_static_mapping(local_host.ip4, self.nat_addr,
6238 local_port, external_port,
6239 proto=IP_PROTOS.tcp, flags=flags)
6240 flags = self.config_flags.NAT_IS_INSIDE
6241 self.vapi.nat44_interface_add_del_feature(
6242 sw_if_index=self.pg4.sw_if_index,
6244 self.vapi.nat44_interface_add_del_feature(
6245 sw_if_index=self.pg4.sw_if_index,
6246 flags=flags, is_add=1)
6248 # from client to service
6249 p = (Ether(src=self.pg4.remote_mac, dst=self.pg4.local_mac) /
6250 IP(src=remote_host.ip4, dst=self.nat_addr) /
6251 TCP(sport=12345, dport=external_port))
6252 self.pg4.add_stream(p)
6253 self.pg_enable_capture(self.pg_interfaces)
6255 capture = self.pg4.get_capture(1)
6260 self.assertEqual(ip.dst, local_host.ip4)
6261 self.assertEqual(ip.src, self.nat_addr)
6262 self.assertEqual(tcp.dport, local_port)
6263 self.assertNotEqual(tcp.sport, 12345)
6264 eh_port_in = tcp.sport
6265 self.assert_packet_checksums_valid(p)
6267 self.logger.error(ppp("Unexpected or invalid packet:", p))
6270 # from service back to client
6271 p = (Ether(src=self.pg4.remote_mac, dst=self.pg4.local_mac) /
6272 IP(src=local_host.ip4, dst=self.nat_addr) /
6273 TCP(sport=local_port, dport=eh_port_in))
6274 self.pg4.add_stream(p)
6275 self.pg_enable_capture(self.pg_interfaces)
6277 capture = self.pg4.get_capture(1)
6282 self.assertEqual(ip.src, self.nat_addr)
6283 self.assertEqual(ip.dst, remote_host.ip4)
6284 self.assertEqual(tcp.sport, external_port)
6285 self.assertEqual(tcp.dport, 12345)
6286 self.assert_packet_checksums_valid(p)
6288 self.logger.error(ppp("Unexpected or invalid packet:", p))
6291 def test_static_with_port_out2(self):
6292 """ 1:1 NAPT asymmetrical rule """
6297 self.vapi.nat44_forwarding_enable_disable(enable=1)
6298 flags = self.config_flags.NAT_IS_OUT2IN_ONLY
6299 self.nat44_add_static_mapping(self.pg0.remote_ip4, self.nat_addr,
6300 local_port, external_port,
6301 proto=IP_PROTOS.tcp, flags=flags)
6302 flags = self.config_flags.NAT_IS_INSIDE
6303 self.vapi.nat44_interface_add_del_feature(
6304 sw_if_index=self.pg0.sw_if_index,
6305 flags=flags, is_add=1)
6306 self.vapi.nat44_interface_add_del_feature(
6307 sw_if_index=self.pg1.sw_if_index,
6310 # from client to service
6311 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
6312 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
6313 TCP(sport=12345, dport=external_port))
6314 self.pg1.add_stream(p)
6315 self.pg_enable_capture(self.pg_interfaces)
6317 capture = self.pg0.get_capture(1)
6322 self.assertEqual(ip.dst, self.pg0.remote_ip4)
6323 self.assertEqual(tcp.dport, local_port)
6324 self.assert_packet_checksums_valid(p)
6326 self.logger.error(ppp("Unexpected or invalid packet:", p))
6330 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
6331 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6332 ICMP(type=11) / capture[0][IP])
6333 self.pg0.add_stream(p)
6334 self.pg_enable_capture(self.pg_interfaces)
6336 capture = self.pg1.get_capture(1)
6339 self.assertEqual(p[IP].src, self.nat_addr)
6341 self.assertEqual(inner.dst, self.nat_addr)
6342 self.assertEqual(inner[TCPerror].dport, external_port)
6344 self.logger.error(ppp("Unexpected or invalid packet:", p))
6347 # from service back to client
6348 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6349 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6350 TCP(sport=local_port, dport=12345))
6351 self.pg0.add_stream(p)
6352 self.pg_enable_capture(self.pg_interfaces)
6354 capture = self.pg1.get_capture(1)
6359 self.assertEqual(ip.src, self.nat_addr)
6360 self.assertEqual(tcp.sport, external_port)
6361 self.assert_packet_checksums_valid(p)
6363 self.logger.error(ppp("Unexpected or invalid packet:", p))
6367 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
6368 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
6369 ICMP(type=11) / capture[0][IP])
6370 self.pg1.add_stream(p)
6371 self.pg_enable_capture(self.pg_interfaces)
6373 capture = self.pg0.get_capture(1)
6376 self.assertEqual(p[IP].dst, self.pg0.remote_ip4)
6378 self.assertEqual(inner.src, self.pg0.remote_ip4)
6379 self.assertEqual(inner[TCPerror].sport, local_port)
6381 self.logger.error(ppp("Unexpected or invalid packet:", p))
6384 # from client to server (no translation)
6385 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
6386 IP(src=self.pg1.remote_ip4, dst=self.pg0.remote_ip4) /
6387 TCP(sport=12346, dport=local_port))
6388 self.pg1.add_stream(p)
6389 self.pg_enable_capture(self.pg_interfaces)
6391 capture = self.pg0.get_capture(1)
6396 self.assertEqual(ip.dst, self.pg0.remote_ip4)
6397 self.assertEqual(tcp.dport, local_port)
6398 self.assert_packet_checksums_valid(p)
6400 self.logger.error(ppp("Unexpected or invalid packet:", p))
6403 # from service back to client (no translation)
6404 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6405 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6406 TCP(sport=local_port, dport=12346))
6407 self.pg0.add_stream(p)
6408 self.pg_enable_capture(self.pg_interfaces)
6410 capture = self.pg1.get_capture(1)
6415 self.assertEqual(ip.src, self.pg0.remote_ip4)
6416 self.assertEqual(tcp.sport, local_port)
6417 self.assert_packet_checksums_valid(p)
6419 self.logger.error(ppp("Unexpected or invalid packet:", p))
6422 def test_output_feature(self):
6423 """ NAT44 interface output feature (in2out postrouting) """
6424 self.vapi.nat44_forwarding_enable_disable(enable=1)
6425 self.nat44_add_address(self.nat_addr)
6426 self.vapi.nat44_interface_add_del_feature(
6427 sw_if_index=self.pg0.sw_if_index,
6429 self.vapi.nat44_interface_add_del_output_feature(
6431 sw_if_index=self.pg1.sw_if_index)
6434 pkts = self.create_stream_in(self.pg0, self.pg1)
6435 self.pg0.add_stream(pkts)
6436 self.pg_enable_capture(self.pg_interfaces)
6438 capture = self.pg1.get_capture(len(pkts))
6439 self.verify_capture_out(capture, ignore_port=True)
6442 pkts = self.create_stream_out(self.pg1)
6443 self.pg1.add_stream(pkts)
6444 self.pg_enable_capture(self.pg_interfaces)
6446 capture = self.pg0.get_capture(len(pkts))
6447 self.verify_capture_in(capture, self.pg0)
6449 def test_output_feature_stateful_acl(self):
6450 """ NAT44 endpoint-dependent output feature works with stateful ACL """
6451 self.nat44_add_address(self.nat_addr)
6452 self.vapi.nat44_interface_add_del_output_feature(
6453 sw_if_index=self.pg0.sw_if_index,
6454 flags=self.config_flags.NAT_IS_INSIDE,
6456 self.vapi.nat44_interface_add_del_output_feature(
6457 sw_if_index=self.pg1.sw_if_index,
6458 flags=self.config_flags.NAT_IS_OUTSIDE,
6461 # First ensure that the NAT is working sans ACL
6463 # send packets out2in, no sessions yet so packets should drop
6464 pkts_out2in = self.create_stream_out(self.pg1)
6465 self.send_and_assert_no_replies(self.pg1, pkts_out2in)
6467 # send packets into inside intf, ensure received via outside intf
6468 pkts_in2out = self.create_stream_in(self.pg0, self.pg1)
6469 capture = self.send_and_expect(self.pg0, pkts_in2out, self.pg1,
6471 self.verify_capture_out(capture, ignore_port=True)
6473 # send out2in again, with sessions created it should work now
6474 pkts_out2in = self.create_stream_out(self.pg1)
6475 capture = self.send_and_expect(self.pg1, pkts_out2in, self.pg0,
6477 self.verify_capture_in(capture, self.pg0)
6479 # Create an ACL blocking everything
6480 out2in_deny_rule = AclRule(is_permit=0)
6481 out2in_acl = VppAcl(self, rules=[out2in_deny_rule])
6482 out2in_acl.add_vpp_config()
6484 # create an ACL to permit/reflect everything
6485 in2out_reflect_rule = AclRule(is_permit=2)
6486 in2out_acl = VppAcl(self, rules=[in2out_reflect_rule])
6487 in2out_acl.add_vpp_config()
6489 # apply as input acl on interface and confirm it blocks everything
6490 acl_if = VppAclInterface(self, sw_if_index=self.pg1.sw_if_index,
6491 n_input=1, acls=[out2in_acl])
6492 acl_if.add_vpp_config()
6493 self.send_and_assert_no_replies(self.pg1, pkts_out2in)
6496 acl_if.acls = [out2in_acl, in2out_acl]
6497 acl_if.add_vpp_config()
6498 # send in2out to generate ACL state (NAT state was created earlier)
6499 capture = self.send_and_expect(self.pg0, pkts_in2out, self.pg1,
6501 self.verify_capture_out(capture, ignore_port=True)
6503 # send out2in again. ACL state exists so it should work now.
6504 # TCP packets with the syn flag set also need the ack flag
6505 for p in pkts_out2in:
6506 if p.haslayer(TCP) and p[TCP].flags & 0x02:
6507 p[TCP].flags |= 0x10
6508 capture = self.send_and_expect(self.pg1, pkts_out2in, self.pg0,
6510 self.verify_capture_in(capture, self.pg0)
6511 self.logger.info(self.vapi.cli("show trace"))
6513 def test_multiple_vrf(self):
6514 """ Multiple VRF setup """
6515 external_addr = '1.2.3.4'
6520 self.vapi.nat44_forwarding_enable_disable(enable=1)
6521 self.nat44_add_address(self.nat_addr)
6522 flags = self.config_flags.NAT_IS_INSIDE
6523 self.vapi.nat44_interface_add_del_feature(
6524 sw_if_index=self.pg0.sw_if_index,
6526 self.vapi.nat44_interface_add_del_feature(
6527 sw_if_index=self.pg0.sw_if_index,
6528 is_add=1, flags=flags)
6529 self.vapi.nat44_interface_add_del_output_feature(
6530 sw_if_index=self.pg1.sw_if_index,
6532 self.vapi.nat44_interface_add_del_feature(
6533 sw_if_index=self.pg5.sw_if_index,
6535 self.vapi.nat44_interface_add_del_feature(
6536 sw_if_index=self.pg5.sw_if_index,
6537 is_add=1, flags=flags)
6538 self.vapi.nat44_interface_add_del_feature(
6539 sw_if_index=self.pg6.sw_if_index,
6541 flags = self.config_flags.NAT_IS_OUT2IN_ONLY
6542 self.nat44_add_static_mapping(self.pg5.remote_ip4, external_addr,
6543 local_port, external_port, vrf_id=1,
6544 proto=IP_PROTOS.tcp, flags=flags)
6545 self.nat44_add_static_mapping(
6546 self.pg0.remote_ip4,
6547 external_sw_if_index=self.pg0.sw_if_index,
6548 local_port=local_port,
6550 external_port=external_port,
6551 proto=IP_PROTOS.tcp,
6555 # from client to service (both VRF1)
6556 p = (Ether(src=self.pg6.remote_mac, dst=self.pg6.local_mac) /
6557 IP(src=self.pg6.remote_ip4, dst=external_addr) /
6558 TCP(sport=12345, dport=external_port))
6559 self.pg6.add_stream(p)
6560 self.pg_enable_capture(self.pg_interfaces)
6562 capture = self.pg5.get_capture(1)
6567 self.assertEqual(ip.dst, self.pg5.remote_ip4)
6568 self.assertEqual(tcp.dport, local_port)
6569 self.assert_packet_checksums_valid(p)
6571 self.logger.error(ppp("Unexpected or invalid packet:", p))
6574 # from service back to client (both VRF1)
6575 p = (Ether(src=self.pg5.remote_mac, dst=self.pg5.local_mac) /
6576 IP(src=self.pg5.remote_ip4, dst=self.pg6.remote_ip4) /
6577 TCP(sport=local_port, dport=12345))
6578 self.pg5.add_stream(p)
6579 self.pg_enable_capture(self.pg_interfaces)
6581 capture = self.pg6.get_capture(1)
6586 self.assertEqual(ip.src, external_addr)
6587 self.assertEqual(tcp.sport, external_port)
6588 self.assert_packet_checksums_valid(p)
6590 self.logger.error(ppp("Unexpected or invalid packet:", p))
6593 # dynamic NAT from VRF1 to VRF0 (output-feature)
6594 p = (Ether(src=self.pg5.remote_mac, dst=self.pg5.local_mac) /
6595 IP(src=self.pg5.remote_ip4, dst=self.pg1.remote_ip4) /
6596 TCP(sport=2345, dport=22))
6597 self.pg5.add_stream(p)
6598 self.pg_enable_capture(self.pg_interfaces)
6600 capture = self.pg1.get_capture(1)
6605 self.assertEqual(ip.src, self.nat_addr)
6606 self.assert_packet_checksums_valid(p)
6609 self.logger.error(ppp("Unexpected or invalid packet:", p))
6612 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
6613 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
6614 TCP(sport=22, dport=port))
6615 self.pg1.add_stream(p)
6616 self.pg_enable_capture(self.pg_interfaces)
6618 capture = self.pg5.get_capture(1)
6623 self.assertEqual(ip.dst, self.pg5.remote_ip4)
6624 self.assertEqual(tcp.dport, 2345)
6625 self.assert_packet_checksums_valid(p)
6627 self.logger.error(ppp("Unexpected or invalid packet:", p))
6630 # from client VRF1 to service VRF0
6631 p = (Ether(src=self.pg6.remote_mac, dst=self.pg6.local_mac) /
6632 IP(src=self.pg6.remote_ip4, dst=self.pg0.local_ip4) /
6633 TCP(sport=12346, dport=external_port))
6634 self.pg6.add_stream(p)
6635 self.pg_enable_capture(self.pg_interfaces)
6637 capture = self.pg0.get_capture(1)
6642 self.assertEqual(ip.dst, self.pg0.remote_ip4)
6643 self.assertEqual(tcp.dport, local_port)
6644 self.assert_packet_checksums_valid(p)
6646 self.logger.error(ppp("Unexpected or invalid packet:", p))
6649 # from service VRF0 back to client VRF1
6650 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6651 IP(src=self.pg0.remote_ip4, dst=self.pg6.remote_ip4) /
6652 TCP(sport=local_port, dport=12346))
6653 self.pg0.add_stream(p)
6654 self.pg_enable_capture(self.pg_interfaces)
6656 capture = self.pg6.get_capture(1)
6661 self.assertEqual(ip.src, self.pg0.local_ip4)
6662 self.assertEqual(tcp.sport, external_port)
6663 self.assert_packet_checksums_valid(p)
6665 self.logger.error(ppp("Unexpected or invalid packet:", p))
6668 # from client VRF0 to service VRF1
6669 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6670 IP(src=self.pg0.remote_ip4, dst=external_addr) /
6671 TCP(sport=12347, dport=external_port))
6672 self.pg0.add_stream(p)
6673 self.pg_enable_capture(self.pg_interfaces)
6675 capture = self.pg5.get_capture(1)
6680 self.assertEqual(ip.dst, self.pg5.remote_ip4)
6681 self.assertEqual(tcp.dport, local_port)
6682 self.assert_packet_checksums_valid(p)
6684 self.logger.error(ppp("Unexpected or invalid packet:", p))
6687 # from service VRF1 back to client VRF0
6688 p = (Ether(src=self.pg5.remote_mac, dst=self.pg5.local_mac) /
6689 IP(src=self.pg5.remote_ip4, dst=self.pg0.remote_ip4) /
6690 TCP(sport=local_port, dport=12347))
6691 self.pg5.add_stream(p)
6692 self.pg_enable_capture(self.pg_interfaces)
6694 capture = self.pg0.get_capture(1)
6699 self.assertEqual(ip.src, external_addr)
6700 self.assertEqual(tcp.sport, external_port)
6701 self.assert_packet_checksums_valid(p)
6703 self.logger.error(ppp("Unexpected or invalid packet:", p))
6706 # from client to server (both VRF1, no translation)
6707 p = (Ether(src=self.pg6.remote_mac, dst=self.pg6.local_mac) /
6708 IP(src=self.pg6.remote_ip4, dst=self.pg5.remote_ip4) /
6709 TCP(sport=12348, dport=local_port))
6710 self.pg6.add_stream(p)
6711 self.pg_enable_capture(self.pg_interfaces)
6713 capture = self.pg5.get_capture(1)
6718 self.assertEqual(ip.dst, self.pg5.remote_ip4)
6719 self.assertEqual(tcp.dport, local_port)
6720 self.assert_packet_checksums_valid(p)
6722 self.logger.error(ppp("Unexpected or invalid packet:", p))
6725 # from server back to client (both VRF1, no translation)
6726 p = (Ether(src=self.pg5.remote_mac, dst=self.pg5.local_mac) /
6727 IP(src=self.pg5.remote_ip4, dst=self.pg6.remote_ip4) /
6728 TCP(sport=local_port, dport=12348))
6729 self.pg5.add_stream(p)
6730 self.pg_enable_capture(self.pg_interfaces)
6732 capture = self.pg6.get_capture(1)
6737 self.assertEqual(ip.src, self.pg5.remote_ip4)
6738 self.assertEqual(tcp.sport, local_port)
6739 self.assert_packet_checksums_valid(p)
6741 self.logger.error(ppp("Unexpected or invalid packet:", p))
6744 # from client VRF1 to server VRF0 (no translation)
6745 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6746 IP(src=self.pg0.remote_ip4, dst=self.pg6.remote_ip4) /
6747 TCP(sport=local_port, dport=12349))
6748 self.pg0.add_stream(p)
6749 self.pg_enable_capture(self.pg_interfaces)
6751 capture = self.pg6.get_capture(1)
6756 self.assertEqual(ip.src, self.pg0.remote_ip4)
6757 self.assertEqual(tcp.sport, local_port)
6758 self.assert_packet_checksums_valid(p)
6760 self.logger.error(ppp("Unexpected or invalid packet:", p))
6763 # from server VRF0 back to client VRF1 (no translation)
6764 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6765 IP(src=self.pg0.remote_ip4, dst=self.pg6.remote_ip4) /
6766 TCP(sport=local_port, dport=12349))
6767 self.pg0.add_stream(p)
6768 self.pg_enable_capture(self.pg_interfaces)
6770 capture = self.pg6.get_capture(1)
6775 self.assertEqual(ip.src, self.pg0.remote_ip4)
6776 self.assertEqual(tcp.sport, local_port)
6777 self.assert_packet_checksums_valid(p)
6779 self.logger.error(ppp("Unexpected or invalid packet:", p))
6782 # from client VRF0 to server VRF1 (no translation)
6783 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6784 IP(src=self.pg0.remote_ip4, dst=self.pg5.remote_ip4) /
6785 TCP(sport=12344, dport=local_port))
6786 self.pg0.add_stream(p)
6787 self.pg_enable_capture(self.pg_interfaces)
6789 capture = self.pg5.get_capture(1)
6794 self.assertEqual(ip.dst, self.pg5.remote_ip4)
6795 self.assertEqual(tcp.dport, local_port)
6796 self.assert_packet_checksums_valid(p)
6798 self.logger.error(ppp("Unexpected or invalid packet:", p))
6801 # from server VRF1 back to client VRF0 (no translation)
6802 p = (Ether(src=self.pg5.remote_mac, dst=self.pg5.local_mac) /
6803 IP(src=self.pg5.remote_ip4, dst=self.pg0.remote_ip4) /
6804 TCP(sport=local_port, dport=12344))
6805 self.pg5.add_stream(p)
6806 self.pg_enable_capture(self.pg_interfaces)
6808 capture = self.pg0.get_capture(1)
6813 self.assertEqual(ip.src, self.pg5.remote_ip4)
6814 self.assertEqual(tcp.sport, local_port)
6815 self.assert_packet_checksums_valid(p)
6817 self.logger.error(ppp("Unexpected or invalid packet:", p))
6820 @unittest.skipUnless(running_extended_tests, "part of extended tests")
6821 def test_session_timeout(self):
6822 """ NAT44 session timeouts """
6823 self.nat44_add_address(self.nat_addr)
6824 flags = self.config_flags.NAT_IS_INSIDE
6825 self.vapi.nat44_interface_add_del_feature(
6826 sw_if_index=self.pg0.sw_if_index,
6827 flags=flags, is_add=1)
6828 self.vapi.nat44_interface_add_del_feature(
6829 sw_if_index=self.pg1.sw_if_index,
6831 self.vapi.nat_set_timeouts(udp=300, tcp_established=7440,
6832 tcp_transitory=240, icmp=5)
6836 for i in range(0, max_sessions):
6837 src = "10.10.%u.%u" % ((i & 0xFF00) >> 8, i & 0xFF)
6838 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
6839 IP(src=src, dst=self.pg1.remote_ip4) /
6840 ICMP(id=1025, type='echo-request'))
6842 self.pg0.add_stream(pkts)
6843 self.pg_enable_capture(self.pg_interfaces)
6845 self.pg1.get_capture(max_sessions)
6850 for i in range(0, max_sessions):
6851 src = "10.11.%u.%u" % ((i & 0xFF00) >> 8, i & 0xFF)
6852 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
6853 IP(src=src, dst=self.pg1.remote_ip4) /
6854 ICMP(id=1026, type='echo-request'))
6856 self.pg0.add_stream(pkts)
6857 self.pg_enable_capture(self.pg_interfaces)
6859 self.pg1.get_capture(max_sessions)
6862 users = self.vapi.nat44_user_dump()
6864 nsessions = nsessions + user.nsessions
6865 self.assertLess(nsessions, 2 * max_sessions)
6867 @unittest.skipUnless(running_extended_tests, "part of extended tests")
6868 def test_session_rst_timeout(self):
6869 """ NAT44 session RST timeouts """
6870 self.nat44_add_address(self.nat_addr)
6871 flags = self.config_flags.NAT_IS_INSIDE
6872 self.vapi.nat44_interface_add_del_feature(
6873 sw_if_index=self.pg0.sw_if_index,
6874 flags=flags, is_add=1)
6875 self.vapi.nat44_interface_add_del_feature(
6876 sw_if_index=self.pg1.sw_if_index,
6878 self.vapi.nat_set_timeouts(udp=300, tcp_established=7440,
6879 tcp_transitory=5, icmp=60)
6881 self.initiate_tcp_session(self.pg0, self.pg1)
6882 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6883 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6884 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
6886 self.pg0.add_stream(p)
6887 self.pg_enable_capture(self.pg_interfaces)
6889 self.pg1.get_capture(1)
6893 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6894 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6895 TCP(sport=self.tcp_port_in + 1, dport=self.tcp_external_port + 1,
6897 self.pg0.add_stream(p)
6898 self.pg_enable_capture(self.pg_interfaces)
6900 self.pg1.get_capture(1)
6902 def test_syslog_sess(self):
6903 """ Test syslog session creation and deletion """
6904 self.vapi.syslog_set_filter(
6905 self.SYSLOG_SEVERITY.SYSLOG_API_SEVERITY_INFO)
6906 self.vapi.syslog_set_sender(self.pg2.local_ip4, self.pg2.remote_ip4)
6907 self.nat44_add_address(self.nat_addr)
6908 flags = self.config_flags.NAT_IS_INSIDE
6909 self.vapi.nat44_interface_add_del_feature(
6910 sw_if_index=self.pg0.sw_if_index,
6911 flags=flags, is_add=1)
6912 self.vapi.nat44_interface_add_del_feature(
6913 sw_if_index=self.pg1.sw_if_index,
6916 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
6917 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6918 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port))
6919 self.pg0.add_stream(p)
6920 self.pg_enable_capture(self.pg_interfaces)
6922 capture = self.pg1.get_capture(1)
6923 self.tcp_port_out = capture[0][TCP].sport
6924 capture = self.pg2.get_capture(1)
6925 self.verify_syslog_sess(capture[0][Raw].load)
6927 self.pg_enable_capture(self.pg_interfaces)
6929 self.nat44_add_address(self.nat_addr, is_add=0)
6930 capture = self.pg2.get_capture(1)
6931 self.verify_syslog_sess(capture[0][Raw].load, False)
6933 def test_ed_users_dump(self):
6934 """ API test - nat44_user_dump """
6935 flags = self.config_flags.NAT_IS_INSIDE
6936 self.vapi.nat44_interface_add_del_feature(
6937 sw_if_index=self.pg0.sw_if_index,
6938 flags=flags, is_add=1)
6939 self.vapi.nat44_interface_add_del_feature(
6940 sw_if_index=self.pg1.sw_if_index,
6942 self.vapi.nat44_forwarding_enable_disable(enable=1)
6944 real_ip = self.pg0.remote_ip4
6945 alias_ip = self.nat_addr
6946 flags = self.config_flags.NAT_IS_ADDR_ONLY
6947 self.vapi.nat44_add_del_static_mapping(is_add=1,
6948 local_ip_address=real_ip,
6949 external_ip_address=alias_ip,
6950 external_sw_if_index=0xFFFFFFFF,
6953 users = self.vapi.nat44_user_dump()
6954 self.assertEqual(len(users), 0)
6956 # in2out - static mapping match
6958 pkts = self.create_stream_out(self.pg1)
6959 self.pg1.add_stream(pkts)
6960 self.pg_enable_capture(self.pg_interfaces)
6962 capture = self.pg0.get_capture(len(pkts))
6963 self.verify_capture_in(capture, self.pg0)
6965 pkts = self.create_stream_in(self.pg0, self.pg1)
6966 self.pg0.add_stream(pkts)
6967 self.pg_enable_capture(self.pg_interfaces)
6969 capture = self.pg1.get_capture(len(pkts))
6970 self.verify_capture_out(capture, same_port=True)
6972 users = self.vapi.nat44_user_dump()
6973 self.assertEqual(len(users), 1)
6974 static_user = users[0]
6975 self.assertEqual(static_user.nstaticsessions, 3)
6976 self.assertEqual(static_user.nsessions, 0)
6978 # in2out - no static mapping match
6980 host0 = self.pg0.remote_hosts[0]
6981 self.pg0.remote_hosts[0] = self.pg0.remote_hosts[1]
6983 pkts = self.create_stream_out(self.pg1,
6984 dst_ip=self.pg0.remote_ip4,
6985 use_inside_ports=True)
6986 self.pg1.add_stream(pkts)
6987 self.pg_enable_capture(self.pg_interfaces)
6989 capture = self.pg0.get_capture(len(pkts))
6990 self.verify_capture_in(capture, self.pg0)
6992 pkts = self.create_stream_in(self.pg0, self.pg1)
6993 self.pg0.add_stream(pkts)
6994 self.pg_enable_capture(self.pg_interfaces)
6996 capture = self.pg1.get_capture(len(pkts))
6997 self.verify_capture_out(capture, nat_ip=self.pg0.remote_ip4,
7000 self.pg0.remote_hosts[0] = host0
7002 users = self.vapi.nat44_user_dump()
7003 self.assertEqual(len(users), 2)
7004 if str(users[0].ip_address) == self.pg0.remote_hosts[0].ip4:
7005 non_static_user = users[1]
7006 static_user = users[0]
7008 non_static_user = users[0]
7009 static_user = users[1]
7010 self.assertEqual(static_user.nstaticsessions, 3)
7011 self.assertEqual(static_user.nsessions, 0)
7012 self.assertEqual(non_static_user.nstaticsessions, 0)
7013 self.assertEqual(non_static_user.nsessions, 3)
7015 users = self.vapi.nat44_user_dump()
7016 self.assertEqual(len(users), 2)
7017 if str(users[0].ip_address) == self.pg0.remote_hosts[0].ip4:
7018 non_static_user = users[1]
7019 static_user = users[0]
7021 non_static_user = users[0]
7022 static_user = users[1]
7023 self.assertEqual(static_user.nstaticsessions, 3)
7024 self.assertEqual(static_user.nsessions, 0)
7025 self.assertEqual(non_static_user.nstaticsessions, 0)
7026 self.assertEqual(non_static_user.nsessions, 3)
7029 self.vapi.nat44_forwarding_enable_disable(enable=0)
7030 flags = self.config_flags.NAT_IS_ADDR_ONLY
7031 self.vapi.nat44_add_del_static_mapping(
7033 local_ip_address=real_ip,
7034 external_ip_address=alias_ip,
7035 external_sw_if_index=0xFFFFFFFF,
7038 def show_commands_at_teardown(self):
7039 self.logger.info(self.vapi.cli("show errors"))
7040 self.logger.info(self.vapi.cli("show nat44 addresses"))
7041 self.logger.info(self.vapi.cli("show nat44 interfaces"))
7042 self.logger.info(self.vapi.cli("show nat44 static mappings"))
7043 self.logger.info(self.vapi.cli("show nat44 interface address"))
7044 self.logger.info(self.vapi.cli("show nat44 sessions detail"))
7045 self.logger.info(self.vapi.cli("show nat44 hash tables detail"))
7046 self.logger.info(self.vapi.cli("show nat timeouts"))
7047 self.logger.info(self.vapi.cli("debug nat44 fib registration"))
7050 class TestNAT44EndpointDependent3(MethodHolder):
7051 """ Endpoint-Dependent mapping and filtering extra test cases """
7053 max_translations = 50
7056 def setUpClass(cls):
7057 super(TestNAT44EndpointDependent3, cls).setUpClass()
7058 cls.vapi.cli("set log class nat level debug")
7060 cls.nat_addr = '10.0.0.3'
7062 cls.create_pg_interfaces(range(2))
7064 for i in cls.pg_interfaces:
7070 super(TestNAT44EndpointDependent3, self).setUp()
7071 flags = self.nat44_config_flags.NAT44_IS_ENDPOINT_DEPENDENT
7072 self.vapi.nat44_plugin_enable_disable(
7073 sessions=self.max_translations,
7074 flags=flags, enable=1)
7075 self.vapi.nat_set_timeouts(
7076 udp=1, tcp_established=7440, tcp_transitory=30, icmp=1)
7078 self.nat44_add_address(self.nat_addr)
7079 flags = self.config_flags.NAT_IS_INSIDE
7080 self.vapi.nat44_interface_add_del_feature(
7081 sw_if_index=self.pg0.sw_if_index, flags=flags, is_add=1)
7082 self.vapi.nat44_interface_add_del_feature(
7083 sw_if_index=self.pg1.sw_if_index, is_add=1)
7086 def tearDownClass(cls):
7087 super(TestNAT44EndpointDependent3, cls).tearDownClass()
7090 super(TestNAT44EndpointDependent3, self).tearDown()
7091 if not self.vpp_dead:
7092 self.vapi.nat44_plugin_enable_disable(enable=0)
7093 self.vapi.cli("clear logging")
7095 def init_tcp_session(self, in_if, out_if, sport, ext_dport):
7096 # SYN packet in->out
7097 p = (Ether(src=in_if.remote_mac, dst=in_if.local_mac) /
7098 IP(src=in_if.remote_ip4, dst=out_if.remote_ip4) /
7099 TCP(sport=sport, dport=ext_dport, flags="S"))
7101 self.pg_enable_capture(self.pg_interfaces)
7103 capture = out_if.get_capture(1)
7105 tcp_port_out = p[TCP].sport
7107 # SYN + ACK packet out->in
7108 p = (Ether(src=out_if.remote_mac, dst=out_if.local_mac) /
7109 IP(src=out_if.remote_ip4, dst=self.nat_addr) /
7110 TCP(sport=ext_dport, dport=tcp_port_out, flags="SA"))
7111 out_if.add_stream(p)
7112 self.pg_enable_capture(self.pg_interfaces)
7114 in_if.get_capture(1)
7116 # ACK packet in->out
7117 p = (Ether(src=in_if.remote_mac, dst=in_if.local_mac) /
7118 IP(src=in_if.remote_ip4, dst=out_if.remote_ip4) /
7119 TCP(sport=sport, dport=ext_dport, flags="A"))
7121 self.pg_enable_capture(self.pg_interfaces)
7123 out_if.get_capture(1)
7127 def test_lru_cleanup(self):
7128 """ LRU cleanup algorithm """
7129 tcp_port_out = self.init_tcp_session(self.pg0, self.pg1, 2000, 80)
7131 for i in range(0, self.max_translations - 1):
7132 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
7133 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4, ttl=64) /
7134 UDP(sport=7000+i, dport=80))
7137 self.pg0.add_stream(pkts)
7138 self.pg_enable_capture(self.pg_interfaces)
7140 self.pg1.get_capture(len(pkts))
7141 self.sleep(1.5, "wait for timeouts")
7144 for i in range(0, self.max_translations - 1):
7145 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
7146 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4, ttl=64) /
7147 ICMP(id=8000+i, type='echo-request'))
7150 self.pg0.add_stream(pkts)
7151 self.pg_enable_capture(self.pg_interfaces)
7153 self.pg1.get_capture(len(pkts))
7156 class TestNAT44Out2InDPO(MethodHolder):
7157 """ NAT44 Test Cases using out2in DPO """
7160 def setUpClass(cls):
7161 super(TestNAT44Out2InDPO, cls).setUpClass()
7162 cls.vapi.cli("set log class nat level debug")
7164 cls.tcp_port_in = 6303
7165 cls.tcp_port_out = 6303
7166 cls.udp_port_in = 6304
7167 cls.udp_port_out = 6304
7168 cls.icmp_id_in = 6305
7169 cls.icmp_id_out = 6305
7170 cls.nat_addr = '10.0.0.3'
7171 cls.dst_ip4 = '192.168.70.1'
7173 cls.create_pg_interfaces(range(2))
7176 cls.pg0.config_ip4()
7177 cls.pg0.resolve_arp()
7180 cls.pg1.config_ip6()
7181 cls.pg1.resolve_ndp()
7183 r1 = VppIpRoute(cls, "::", 0,
7184 [VppRoutePath(cls.pg1.remote_ip6,
7185 cls.pg1.sw_if_index)],
7190 def tearDownClass(cls):
7191 super(TestNAT44Out2InDPO, cls).tearDownClass()
7194 super(TestNAT44Out2InDPO, self).setUp()
7195 flags = self.nat44_config_flags.NAT44_API_IS_OUT2IN_DPO
7196 self.vapi.nat44_plugin_enable_disable(enable=1, flags=flags)
7199 super(TestNAT44Out2InDPO, self).tearDown()
7200 if not self.vpp_dead:
7201 self.vapi.nat44_plugin_enable_disable(enable=0)
7202 self.vapi.cli("clear logging")
7204 def configure_xlat(self):
7205 self.dst_ip6_pfx = '1:2:3::'
7206 self.dst_ip6_pfx_n = socket.inet_pton(socket.AF_INET6,
7208 self.dst_ip6_pfx_len = 96
7209 self.src_ip6_pfx = '4:5:6::'
7210 self.src_ip6_pfx_n = socket.inet_pton(socket.AF_INET6,
7212 self.src_ip6_pfx_len = 96
7213 self.vapi.map_add_domain(self.dst_ip6_pfx_n, self.dst_ip6_pfx_len,
7214 self.src_ip6_pfx_n, self.src_ip6_pfx_len,
7215 '\x00\x00\x00\x00', 0)
7217 @unittest.skip('Temporary disabled')
7218 def test_464xlat_ce(self):
7219 """ Test 464XLAT CE with NAT44 """
7221 nat_config = self.vapi.nat_show_config()
7222 self.assertEqual(1, nat_config.out2in_dpo)
7224 self.configure_xlat()
7226 flags = self.config_flags.NAT_IS_INSIDE
7227 self.vapi.nat44_interface_add_del_feature(
7228 sw_if_index=self.pg0.sw_if_index,
7229 flags=flags, is_add=1)
7230 self.vapi.nat44_add_del_address_range(first_ip_address=self.nat_addr_n,
7231 last_ip_address=self.nat_addr_n,
7232 vrf_id=0xFFFFFFFF, is_add=1)
7234 out_src_ip6 = self.compose_ip6(self.dst_ip4, self.dst_ip6_pfx,
7235 self.dst_ip6_pfx_len)
7236 out_dst_ip6 = self.compose_ip6(self.nat_addr, self.src_ip6_pfx,
7237 self.src_ip6_pfx_len)
7240 pkts = self.create_stream_in(self.pg0, self.pg1, self.dst_ip4)
7241 self.pg0.add_stream(pkts)
7242 self.pg_enable_capture(self.pg_interfaces)
7244 capture = self.pg1.get_capture(len(pkts))
7245 self.verify_capture_out_ip6(capture, nat_ip=out_dst_ip6,
7248 pkts = self.create_stream_out_ip6(self.pg1, out_src_ip6,
7250 self.pg1.add_stream(pkts)
7251 self.pg_enable_capture(self.pg_interfaces)
7253 capture = self.pg0.get_capture(len(pkts))
7254 self.verify_capture_in(capture, self.pg0)
7256 self.vapi.nat44_interface_add_del_feature(
7257 sw_if_index=self.pg0.sw_if_index,
7259 self.vapi.nat44_add_del_address_range(
7260 first_ip_address=self.nat_addr_n,
7261 last_ip_address=self.nat_addr_n,
7264 @unittest.skip('Temporary disabled')
7265 def test_464xlat_ce_no_nat(self):
7266 """ Test 464XLAT CE without NAT44 """
7268 self.configure_xlat()
7270 out_src_ip6 = self.compose_ip6(self.dst_ip4, self.dst_ip6_pfx,
7271 self.dst_ip6_pfx_len)
7272 out_dst_ip6 = self.compose_ip6(self.pg0.remote_ip4, self.src_ip6_pfx,
7273 self.src_ip6_pfx_len)
7275 pkts = self.create_stream_in(self.pg0, self.pg1, self.dst_ip4)
7276 self.pg0.add_stream(pkts)
7277 self.pg_enable_capture(self.pg_interfaces)
7279 capture = self.pg1.get_capture(len(pkts))
7280 self.verify_capture_out_ip6(capture, dst_ip=out_src_ip6,
7281 nat_ip=out_dst_ip6, same_port=True)
7283 pkts = self.create_stream_out_ip6(self.pg1, out_src_ip6, out_dst_ip6)
7284 self.pg1.add_stream(pkts)
7285 self.pg_enable_capture(self.pg_interfaces)
7287 capture = self.pg0.get_capture(len(pkts))
7288 self.verify_capture_in(capture, self.pg0)
7291 if __name__ == '__main__':
7292 unittest.main(testRunner=VppTestRunner)