8 from framework import VppTestCase, VppTestRunner, running_extended_tests
11 from scapy.layers.inet import IP, TCP, UDP, ICMP
12 from scapy.layers.inet import IPerror, TCPerror, UDPerror, ICMPerror
13 from scapy.layers.inet6 import IPv6, ICMPv6EchoRequest, ICMPv6EchoReply, \
14 ICMPv6ND_NS, ICMPv6ND_NA, ICMPv6NDOptDstLLAddr, fragment6
15 from scapy.layers.inet6 import ICMPv6DestUnreach, IPerror6, IPv6ExtHdrFragment
16 from scapy.layers.l2 import Ether, ARP, GRE
17 from scapy.data import IP_PROTOS
18 from scapy.packet import bind_layers, Raw
20 from ipfix import IPFIX, Set, Template, Data, IPFIXDecoder
21 from time import sleep
22 from util import ip4_range
23 from vpp_papi import mac_pton
24 from syslog_rfc5424_parser import SyslogMessage, ParseError
25 from syslog_rfc5424_parser.constants import SyslogFacility, SyslogSeverity
26 from io import BytesIO
27 from vpp_papi import VppEnum
28 from scapy.all import bind_layers, Packet, ByteEnumField, ShortField, \
29 IPField, IntField, LongField, XByteField, FlagsField, FieldLenField, \
31 from ipaddress import IPv6Network
34 # NAT HA protocol event data
37 fields_desc = [ByteEnumField("event_type", None,
38 {1: "add", 2: "del", 3: "refresh"}),
39 ByteEnumField("protocol", None,
40 {0: "udp", 1: "tcp", 2: "icmp"}),
41 ShortField("flags", 0),
42 IPField("in_addr", None),
43 IPField("out_addr", None),
44 ShortField("in_port", None),
45 ShortField("out_port", None),
46 IPField("eh_addr", None),
47 IPField("ehn_addr", None),
48 ShortField("eh_port", None),
49 ShortField("ehn_port", None),
50 IntField("fib_index", None),
51 IntField("total_pkts", 0),
52 LongField("total_bytes", 0)]
54 def extract_padding(self, s):
58 # NAT HA protocol header
59 class HANATStateSync(Packet):
60 name = "HA NAT state sync"
61 fields_desc = [XByteField("version", 1),
62 FlagsField("flags", 0, 8, ['ACK']),
63 FieldLenField("count", None, count_of="events"),
64 IntField("sequence_number", 1),
65 IntField("thread_index", 0),
66 PacketListField("events", [], Event,
67 count_from=lambda pkt: pkt.count)]
70 class MethodHolder(VppTestCase):
71 """ NAT create capture and verify method holder """
74 def config_flags(self):
75 return VppEnum.vl_api_nat_config_flags_t
78 def SYSLOG_SEVERITY(self):
79 return VppEnum.vl_api_syslog_severity_t
81 def clear_nat44(self):
83 Clear NAT44 configuration.
85 if hasattr(self, 'pg7') and hasattr(self, 'pg8'):
86 # I found no elegant way to do this
87 self.vapi.ip_add_del_route(
88 dst_address=self.pg7.remote_ip4n,
89 dst_address_length=32,
90 next_hop_address=self.pg7.remote_ip4n,
91 next_hop_sw_if_index=self.pg7.sw_if_index,
93 self.vapi.ip_add_del_route(
94 dst_address=self.pg8.remote_ip4n,
95 dst_address_length=32,
96 next_hop_address=self.pg8.remote_ip4n,
97 next_hop_sw_if_index=self.pg8.sw_if_index,
100 for intf in [self.pg7, self.pg8]:
101 self.vapi.ip_neighbor_add_del(
105 flags=(VppEnum.vl_api_ip_neighbor_flags_t.
106 IP_API_NEIGHBOR_FLAG_STATIC),
109 if self.pg7.has_ip4_config:
110 self.pg7.unconfig_ip4()
112 self.vapi.nat44_forwarding_enable_disable(enable=0)
114 interfaces = self.vapi.nat44_interface_addr_dump()
115 for intf in interfaces:
116 self.vapi.nat44_add_del_interface_addr(
118 sw_if_index=intf.sw_if_index,
121 self.vapi.nat_ipfix_enable_disable(domain_id=self.ipfix_domain_id,
122 src_port=self.ipfix_src_port,
124 self.ipfix_src_port = 4739
125 self.ipfix_domain_id = 1
127 self.vapi.syslog_set_filter(
128 self.SYSLOG_SEVERITY.SYSLOG_API_SEVERITY_EMERG)
130 self.vapi.nat_ha_set_listener(ip_address='0.0.0.0', port=0,
132 self.vapi.nat_ha_set_failover(ip_address='0.0.0.0', port=0,
133 session_refresh_interval=10)
135 interfaces = self.vapi.nat44_interface_dump()
136 for intf in interfaces:
137 if intf.flags & self.config_flags.NAT_IS_INSIDE and \
138 intf.flags & self.config_flags.NAT_IS_OUTSIDE:
139 self.vapi.nat44_interface_add_del_feature(
140 sw_if_index=intf.sw_if_index)
141 self.vapi.nat44_interface_add_del_feature(
142 sw_if_index=intf.sw_if_index,
145 interfaces = self.vapi.nat44_interface_output_feature_dump()
146 for intf in interfaces:
147 self.vapi.nat44_interface_add_del_output_feature(
150 sw_if_index=intf.sw_if_index)
151 static_mappings = self.vapi.nat44_static_mapping_dump()
152 for sm in static_mappings:
153 self.vapi.nat44_add_del_static_mapping(
155 local_ip_address=sm.local_ip_address,
156 external_ip_address=sm.external_ip_address,
157 external_sw_if_index=sm.external_sw_if_index,
158 local_port=sm.local_port,
159 external_port=sm.external_port,
161 protocol=sm.protocol,
162 flags=sm.flags, tag=sm.tag)
164 lb_static_mappings = self.vapi.nat44_lb_static_mapping_dump()
165 for lb_sm in lb_static_mappings:
166 self.vapi.nat44_add_del_lb_static_mapping(
169 external_addr=lb_sm.external_addr,
170 external_port=lb_sm.external_port,
171 protocol=lb_sm.protocol,
172 local_num=0, locals=[],
175 identity_mappings = self.vapi.nat44_identity_mapping_dump()
176 for id_m in identity_mappings:
177 self.vapi.nat44_add_del_identity_mapping(
178 ip_address=id_m.ip_address,
179 sw_if_index=id_m.sw_if_index,
183 protocol=id_m.protocol)
185 addresses = self.vapi.nat44_address_dump()
186 for addr in addresses:
187 self.vapi.nat44_add_del_address_range(
188 first_ip_address=addr.ip_address,
189 last_ip_address=addr.ip_address,
190 vrf_id=0xFFFFFFFF, flags=addr.flags)
192 self.vapi.nat_set_reass(timeout=2, max_reass=1024, max_frag=5,
194 self.vapi.nat_set_reass(timeout=2, max_reass=1024, max_frag=5,
195 drop_frag=0, is_ip6=1)
196 self.verify_no_nat44_user()
197 self.vapi.nat_set_timeouts(udp=300, tcp_established=7440,
198 tcp_transitory=240, icmp=60)
199 self.vapi.nat_set_addr_and_port_alloc_alg()
200 self.vapi.nat_set_mss_clamping(enable=0, mss_value=1500)
202 def nat44_add_static_mapping(self, local_ip, external_ip='0.0.0.0',
203 local_port=0, external_port=0, vrf_id=0,
204 is_add=1, external_sw_if_index=0xFFFFFFFF,
205 proto=0, tag="", flags=0):
207 Add/delete NAT44 static mapping
209 :param local_ip: Local IP address
210 :param external_ip: External IP address
211 :param local_port: Local port number (Optional)
212 :param external_port: External port number (Optional)
213 :param vrf_id: VRF ID (Default 0)
214 :param is_add: 1 if add, 0 if delete (Default add)
215 :param external_sw_if_index: External interface instead of IP address
216 :param proto: IP protocol (Mandatory if port specified)
217 :param tag: Opaque string tag
218 :param flags: NAT configuration flags
221 if not (local_port and external_port):
222 flags |= self.config_flags.NAT_IS_ADDR_ONLY
224 self.vapi.nat44_add_del_static_mapping(
226 local_ip_address=local_ip,
227 external_ip_address=external_ip,
228 external_sw_if_index=external_sw_if_index,
229 local_port=local_port,
230 external_port=external_port,
231 vrf_id=vrf_id, protocol=proto,
235 def nat44_add_address(self, ip, is_add=1, vrf_id=0xFFFFFFFF, twice_nat=0):
237 Add/delete NAT44 address
239 :param ip: IP address
240 :param is_add: 1 if add, 0 if delete (Default add)
241 :param twice_nat: twice NAT address for external hosts
243 flags = self.config_flags.NAT_IS_TWICE_NAT if twice_nat else 0
244 self.vapi.nat44_add_del_address_range(first_ip_address=ip,
250 def create_stream_in(self, in_if, out_if, dst_ip=None, ttl=64):
252 Create packet stream for inside network
254 :param in_if: Inside interface
255 :param out_if: Outside interface
256 :param dst_ip: Destination address
257 :param ttl: TTL of generated packets
260 dst_ip = out_if.remote_ip4
264 p = (Ether(dst=in_if.local_mac, src=in_if.remote_mac) /
265 IP(src=in_if.remote_ip4, dst=dst_ip, ttl=ttl) /
266 TCP(sport=self.tcp_port_in, dport=20))
270 p = (Ether(dst=in_if.local_mac, src=in_if.remote_mac) /
271 IP(src=in_if.remote_ip4, dst=dst_ip, ttl=ttl) /
272 UDP(sport=self.udp_port_in, dport=20))
276 p = (Ether(dst=in_if.local_mac, src=in_if.remote_mac) /
277 IP(src=in_if.remote_ip4, dst=dst_ip, ttl=ttl) /
278 ICMP(id=self.icmp_id_in, type='echo-request'))
283 def compose_ip6(self, ip4, pref, plen):
285 Compose IPv4-embedded IPv6 addresses
287 :param ip4: IPv4 address
288 :param pref: IPv6 prefix
289 :param plen: IPv6 prefix length
290 :returns: IPv4-embedded IPv6 addresses
292 pref_n = list(socket.inet_pton(socket.AF_INET6, pref))
293 ip4_n = list(socket.inet_pton(socket.AF_INET, ip4))
308 pref_n[10] = ip4_n[3]
312 pref_n[10] = ip4_n[2]
313 pref_n[11] = ip4_n[3]
316 pref_n[10] = ip4_n[1]
317 pref_n[11] = ip4_n[2]
318 pref_n[12] = ip4_n[3]
320 pref_n[12] = ip4_n[0]
321 pref_n[13] = ip4_n[1]
322 pref_n[14] = ip4_n[2]
323 pref_n[15] = ip4_n[3]
324 packed_pref_n = b''.join([scapy.compat.chb(x) for x in pref_n])
325 return socket.inet_ntop(socket.AF_INET6, packed_pref_n)
327 def extract_ip4(self, ip6, plen):
329 Extract IPv4 address embedded in IPv6 addresses
331 :param ip6: IPv6 address
332 :param plen: IPv6 prefix length
333 :returns: extracted IPv4 address
335 ip6_n = list(socket.inet_pton(socket.AF_INET6, ip6))
367 return socket.inet_ntop(socket.AF_INET, ''.join(ip4_n))
369 def create_stream_in_ip6(self, in_if, out_if, hlim=64, pref=None, plen=0):
371 Create IPv6 packet stream for inside network
373 :param in_if: Inside interface
374 :param out_if: Outside interface
375 :param ttl: Hop Limit of generated packets
376 :param pref: NAT64 prefix
377 :param plen: NAT64 prefix length
381 dst = ''.join(['64:ff9b::', out_if.remote_ip4])
383 dst = self.compose_ip6(out_if.remote_ip4, pref, plen)
386 p = (Ether(dst=in_if.local_mac, src=in_if.remote_mac) /
387 IPv6(src=in_if.remote_ip6, dst=dst, hlim=hlim) /
388 TCP(sport=self.tcp_port_in, dport=20))
392 p = (Ether(dst=in_if.local_mac, src=in_if.remote_mac) /
393 IPv6(src=in_if.remote_ip6, dst=dst, hlim=hlim) /
394 UDP(sport=self.udp_port_in, dport=20))
398 p = (Ether(dst=in_if.local_mac, src=in_if.remote_mac) /
399 IPv6(src=in_if.remote_ip6, dst=dst, hlim=hlim) /
400 ICMPv6EchoRequest(id=self.icmp_id_in))
405 def create_stream_out(self, out_if, dst_ip=None, ttl=64,
406 use_inside_ports=False):
408 Create packet stream for outside network
410 :param out_if: Outside interface
411 :param dst_ip: Destination IP address (Default use global NAT address)
412 :param ttl: TTL of generated packets
413 :param use_inside_ports: Use inside NAT ports as destination ports
414 instead of outside ports
417 dst_ip = self.nat_addr
418 if not use_inside_ports:
419 tcp_port = self.tcp_port_out
420 udp_port = self.udp_port_out
421 icmp_id = self.icmp_id_out
423 tcp_port = self.tcp_port_in
424 udp_port = self.udp_port_in
425 icmp_id = self.icmp_id_in
428 p = (Ether(dst=out_if.local_mac, src=out_if.remote_mac) /
429 IP(src=out_if.remote_ip4, dst=dst_ip, ttl=ttl) /
430 TCP(dport=tcp_port, sport=20))
434 p = (Ether(dst=out_if.local_mac, src=out_if.remote_mac) /
435 IP(src=out_if.remote_ip4, dst=dst_ip, ttl=ttl) /
436 UDP(dport=udp_port, sport=20))
440 p = (Ether(dst=out_if.local_mac, src=out_if.remote_mac) /
441 IP(src=out_if.remote_ip4, dst=dst_ip, ttl=ttl) /
442 ICMP(id=icmp_id, type='echo-reply'))
447 def create_stream_out_ip6(self, out_if, src_ip, dst_ip, hl=64):
449 Create packet stream for outside network
451 :param out_if: Outside interface
452 :param dst_ip: Destination IP address (Default use global NAT address)
453 :param hl: HL of generated packets
457 p = (Ether(dst=out_if.local_mac, src=out_if.remote_mac) /
458 IPv6(src=src_ip, dst=dst_ip, hlim=hl) /
459 TCP(dport=self.tcp_port_out, sport=20))
463 p = (Ether(dst=out_if.local_mac, src=out_if.remote_mac) /
464 IPv6(src=src_ip, dst=dst_ip, hlim=hl) /
465 UDP(dport=self.udp_port_out, sport=20))
469 p = (Ether(dst=out_if.local_mac, src=out_if.remote_mac) /
470 IPv6(src=src_ip, dst=dst_ip, hlim=hl) /
471 ICMPv6EchoReply(id=self.icmp_id_out))
476 def verify_capture_out(self, capture, nat_ip=None, same_port=False,
477 dst_ip=None, is_ip6=False):
479 Verify captured packets on outside network
481 :param capture: Captured packets
482 :param nat_ip: Translated IP address (Default use global NAT address)
483 :param same_port: Source port number is not translated (Default False)
484 :param dst_ip: Destination IP address (Default do not verify)
485 :param is_ip6: If L3 protocol is IPv6 (Default False)
489 ICMP46 = ICMPv6EchoRequest
494 nat_ip = self.nat_addr
495 for packet in capture:
498 self.assert_packet_checksums_valid(packet)
499 self.assertEqual(packet[IP46].src, nat_ip)
500 if dst_ip is not None:
501 self.assertEqual(packet[IP46].dst, dst_ip)
502 if packet.haslayer(TCP):
504 self.assertEqual(packet[TCP].sport, self.tcp_port_in)
507 packet[TCP].sport, self.tcp_port_in)
508 self.tcp_port_out = packet[TCP].sport
509 self.assert_packet_checksums_valid(packet)
510 elif packet.haslayer(UDP):
512 self.assertEqual(packet[UDP].sport, self.udp_port_in)
515 packet[UDP].sport, self.udp_port_in)
516 self.udp_port_out = packet[UDP].sport
519 self.assertEqual(packet[ICMP46].id, self.icmp_id_in)
521 self.assertNotEqual(packet[ICMP46].id, self.icmp_id_in)
522 self.icmp_id_out = packet[ICMP46].id
523 self.assert_packet_checksums_valid(packet)
525 self.logger.error(ppp("Unexpected or invalid packet "
526 "(outside network):", packet))
529 def verify_capture_out_ip6(self, capture, nat_ip, same_port=False,
532 Verify captured packets on outside network
534 :param capture: Captured packets
535 :param nat_ip: Translated IP address
536 :param same_port: Source port number is not translated (Default False)
537 :param dst_ip: Destination IP address (Default do not verify)
539 return self.verify_capture_out(capture, nat_ip, same_port, dst_ip,
542 def verify_capture_in(self, capture, in_if):
544 Verify captured packets on inside network
546 :param capture: Captured packets
547 :param in_if: Inside interface
549 for packet in capture:
551 self.assert_packet_checksums_valid(packet)
552 self.assertEqual(packet[IP].dst, in_if.remote_ip4)
553 if packet.haslayer(TCP):
554 self.assertEqual(packet[TCP].dport, self.tcp_port_in)
555 elif packet.haslayer(UDP):
556 self.assertEqual(packet[UDP].dport, self.udp_port_in)
558 self.assertEqual(packet[ICMP].id, self.icmp_id_in)
560 self.logger.error(ppp("Unexpected or invalid packet "
561 "(inside network):", packet))
564 def verify_capture_in_ip6(self, capture, src_ip, dst_ip):
566 Verify captured IPv6 packets on inside network
568 :param capture: Captured packets
569 :param src_ip: Source IP
570 :param dst_ip: Destination IP address
572 for packet in capture:
574 self.assertEqual(packet[IPv6].src, src_ip)
575 self.assertEqual(packet[IPv6].dst, dst_ip)
576 self.assert_packet_checksums_valid(packet)
577 if packet.haslayer(TCP):
578 self.assertEqual(packet[TCP].dport, self.tcp_port_in)
579 elif packet.haslayer(UDP):
580 self.assertEqual(packet[UDP].dport, self.udp_port_in)
582 self.assertEqual(packet[ICMPv6EchoReply].id,
585 self.logger.error(ppp("Unexpected or invalid packet "
586 "(inside network):", packet))
589 def verify_capture_no_translation(self, capture, ingress_if, egress_if):
591 Verify captured packet that don't have to be translated
593 :param capture: Captured packets
594 :param ingress_if: Ingress interface
595 :param egress_if: Egress interface
597 for packet in capture:
599 self.assertEqual(packet[IP].src, ingress_if.remote_ip4)
600 self.assertEqual(packet[IP].dst, egress_if.remote_ip4)
601 if packet.haslayer(TCP):
602 self.assertEqual(packet[TCP].sport, self.tcp_port_in)
603 elif packet.haslayer(UDP):
604 self.assertEqual(packet[UDP].sport, self.udp_port_in)
606 self.assertEqual(packet[ICMP].id, self.icmp_id_in)
608 self.logger.error(ppp("Unexpected or invalid packet "
609 "(inside network):", packet))
612 def verify_capture_out_with_icmp_errors(self, capture, src_ip=None,
615 Verify captured packets with ICMP errors on outside network
617 :param capture: Captured packets
618 :param src_ip: Translated IP address or IP address of VPP
619 (Default use global NAT address)
620 :param icmp_type: Type of error ICMP packet
621 we are expecting (Default 11)
624 src_ip = self.nat_addr
625 for packet in capture:
627 self.assertEqual(packet[IP].src, src_ip)
628 self.assertEqual(packet.haslayer(ICMP), 1)
630 self.assertEqual(icmp.type, icmp_type)
631 self.assertTrue(icmp.haslayer(IPerror))
632 inner_ip = icmp[IPerror]
633 if inner_ip.haslayer(TCPerror):
634 self.assertEqual(inner_ip[TCPerror].dport,
636 elif inner_ip.haslayer(UDPerror):
637 self.assertEqual(inner_ip[UDPerror].dport,
640 self.assertEqual(inner_ip[ICMPerror].id, self.icmp_id_out)
642 self.logger.error(ppp("Unexpected or invalid packet "
643 "(outside network):", packet))
646 def verify_capture_in_with_icmp_errors(self, capture, in_if, icmp_type=11):
648 Verify captured packets with ICMP errors on inside network
650 :param capture: Captured packets
651 :param in_if: Inside interface
652 :param icmp_type: Type of error ICMP packet
653 we are expecting (Default 11)
655 for packet in capture:
657 self.assertEqual(packet[IP].dst, in_if.remote_ip4)
658 self.assertEqual(packet.haslayer(ICMP), 1)
660 self.assertEqual(icmp.type, icmp_type)
661 self.assertTrue(icmp.haslayer(IPerror))
662 inner_ip = icmp[IPerror]
663 if inner_ip.haslayer(TCPerror):
664 self.assertEqual(inner_ip[TCPerror].sport,
666 elif inner_ip.haslayer(UDPerror):
667 self.assertEqual(inner_ip[UDPerror].sport,
670 self.assertEqual(inner_ip[ICMPerror].id, self.icmp_id_in)
672 self.logger.error(ppp("Unexpected or invalid packet "
673 "(inside network):", packet))
676 def create_stream_frag(self, src_if, dst, sport, dport, data,
677 proto=IP_PROTOS.tcp, echo_reply=False):
679 Create fragmented packet stream
681 :param src_if: Source interface
682 :param dst: Destination IPv4 address
683 :param sport: Source port
684 :param dport: Destination port
685 :param data: Payload data
686 :param proto: protocol (TCP, UDP, ICMP)
687 :param echo_reply: use echo_reply if protocol is ICMP
690 if proto == IP_PROTOS.tcp:
691 p = (IP(src=src_if.remote_ip4, dst=dst) /
692 TCP(sport=sport, dport=dport) /
694 p = p.__class__(scapy.compat.raw(p))
695 chksum = p[TCP].chksum
696 proto_header = TCP(sport=sport, dport=dport, chksum=chksum)
697 elif proto == IP_PROTOS.udp:
698 proto_header = UDP(sport=sport, dport=dport)
699 elif proto == IP_PROTOS.icmp:
701 proto_header = ICMP(id=sport, type='echo-request')
703 proto_header = ICMP(id=sport, type='echo-reply')
705 raise Exception("Unsupported protocol")
706 id = random.randint(0, 65535)
708 if proto == IP_PROTOS.tcp:
711 raw = Raw(data[0:16])
712 p = (Ether(src=src_if.remote_mac, dst=src_if.local_mac) /
713 IP(src=src_if.remote_ip4, dst=dst, flags="MF", frag=0, id=id) /
717 if proto == IP_PROTOS.tcp:
718 raw = Raw(data[4:20])
720 raw = Raw(data[16:32])
721 p = (Ether(src=src_if.remote_mac, dst=src_if.local_mac) /
722 IP(src=src_if.remote_ip4, dst=dst, flags="MF", frag=3, id=id,
726 if proto == IP_PROTOS.tcp:
730 p = (Ether(src=src_if.remote_mac, dst=src_if.local_mac) /
731 IP(src=src_if.remote_ip4, dst=dst, frag=5, proto=proto,
737 def create_stream_frag_ip6(self, src_if, dst, sport, dport, data,
738 pref=None, plen=0, frag_size=128):
740 Create fragmented packet stream
742 :param src_if: Source interface
743 :param dst: Destination IPv4 address
744 :param sport: Source TCP port
745 :param dport: Destination TCP port
746 :param data: Payload data
747 :param pref: NAT64 prefix
748 :param plen: NAT64 prefix length
749 :param fragsize: size of fragments
753 dst_ip6 = ''.join(['64:ff9b::', dst])
755 dst_ip6 = self.compose_ip6(dst, pref, plen)
757 p = (Ether(dst=src_if.local_mac, src=src_if.remote_mac) /
758 IPv6(src=src_if.remote_ip6, dst=dst_ip6) /
759 IPv6ExtHdrFragment(id=random.randint(0, 65535)) /
760 TCP(sport=sport, dport=dport) /
763 return fragment6(p, frag_size)
765 def reass_frags_and_verify(self, frags, src, dst):
767 Reassemble and verify fragmented packet
769 :param frags: Captured fragments
770 :param src: Source IPv4 address to verify
771 :param dst: Destination IPv4 address to verify
773 :returns: Reassembled IPv4 packet
777 self.assertEqual(p[IP].src, src)
778 self.assertEqual(p[IP].dst, dst)
779 self.assert_ip_checksum_valid(p)
780 buffer.seek(p[IP].frag * 8)
781 buffer.write(bytes(p[IP].payload))
782 ip = IP(src=frags[0][IP].src, dst=frags[0][IP].dst,
783 proto=frags[0][IP].proto)
784 if ip.proto == IP_PROTOS.tcp:
785 p = (ip / TCP(buffer.getvalue()))
786 self.assert_tcp_checksum_valid(p)
787 elif ip.proto == IP_PROTOS.udp:
788 p = (ip / UDP(buffer.getvalue()[:8]) /
789 Raw(buffer.getvalue()[8:]))
790 elif ip.proto == IP_PROTOS.icmp:
791 p = (ip / ICMP(buffer.getvalue()))
794 def reass_frags_and_verify_ip6(self, frags, src, dst):
796 Reassemble and verify fragmented packet
798 :param frags: Captured fragments
799 :param src: Source IPv6 address to verify
800 :param dst: Destination IPv6 address to verify
802 :returns: Reassembled IPv6 packet
806 self.assertEqual(p[IPv6].src, src)
807 self.assertEqual(p[IPv6].dst, dst)
808 buffer.seek(p[IPv6ExtHdrFragment].offset * 8)
809 buffer.write(bytes(p[IPv6ExtHdrFragment].payload))
810 ip = IPv6(src=frags[0][IPv6].src, dst=frags[0][IPv6].dst,
811 nh=frags[0][IPv6ExtHdrFragment].nh)
812 if ip.nh == IP_PROTOS.tcp:
813 p = (ip / TCP(buffer.getvalue()))
814 elif ip.nh == IP_PROTOS.udp:
815 p = (ip / UDP(buffer.getvalue()))
816 self.assert_packet_checksums_valid(p)
819 def initiate_tcp_session(self, in_if, out_if):
821 Initiates TCP session
823 :param in_if: Inside interface
824 :param out_if: Outside interface
828 p = (Ether(src=in_if.remote_mac, dst=in_if.local_mac) /
829 IP(src=in_if.remote_ip4, dst=out_if.remote_ip4) /
830 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
833 self.pg_enable_capture(self.pg_interfaces)
835 capture = out_if.get_capture(1)
837 self.tcp_port_out = p[TCP].sport
839 # SYN + ACK packet out->in
840 p = (Ether(src=out_if.remote_mac, dst=out_if.local_mac) /
841 IP(src=out_if.remote_ip4, dst=self.nat_addr) /
842 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
845 self.pg_enable_capture(self.pg_interfaces)
850 p = (Ether(src=in_if.remote_mac, dst=in_if.local_mac) /
851 IP(src=in_if.remote_ip4, dst=out_if.remote_ip4) /
852 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
855 self.pg_enable_capture(self.pg_interfaces)
857 out_if.get_capture(1)
860 self.logger.error("TCP 3 way handshake failed")
863 def verify_ipfix_nat44_ses(self, data):
865 Verify IPFIX NAT44 session create/delete event
867 :param data: Decoded IPFIX data records
869 nat44_ses_create_num = 0
870 nat44_ses_delete_num = 0
871 self.assertEqual(6, len(data))
874 self.assertIn(scapy.compat.orb(record[230]), [4, 5])
875 if scapy.compat.orb(record[230]) == 4:
876 nat44_ses_create_num += 1
878 nat44_ses_delete_num += 1
880 self.assertEqual(self.pg0.remote_ip4n, record[8])
881 # postNATSourceIPv4Address
882 self.assertEqual(socket.inet_pton(socket.AF_INET, self.nat_addr),
885 self.assertEqual(struct.pack("!I", 0), record[234])
886 # protocolIdentifier/sourceTransportPort
887 # /postNAPTSourceTransportPort
888 if IP_PROTOS.icmp == scapy.compat.orb(record[4]):
889 self.assertEqual(struct.pack("!H", self.icmp_id_in), record[7])
890 self.assertEqual(struct.pack("!H", self.icmp_id_out),
892 elif IP_PROTOS.tcp == scapy.compat.orb(record[4]):
893 self.assertEqual(struct.pack("!H", self.tcp_port_in),
895 self.assertEqual(struct.pack("!H", self.tcp_port_out),
897 elif IP_PROTOS.udp == scapy.compat.orb(record[4]):
898 self.assertEqual(struct.pack("!H", self.udp_port_in),
900 self.assertEqual(struct.pack("!H", self.udp_port_out),
903 self.fail("Invalid protocol")
904 self.assertEqual(3, nat44_ses_create_num)
905 self.assertEqual(3, nat44_ses_delete_num)
907 def verify_ipfix_addr_exhausted(self, data):
909 Verify IPFIX NAT addresses event
911 :param data: Decoded IPFIX data records
913 self.assertEqual(1, len(data))
916 self.assertEqual(scapy.compat.orb(record[230]), 3)
918 self.assertEqual(struct.pack("!I", 0), record[283])
920 def verify_ipfix_max_sessions(self, data, limit):
922 Verify IPFIX maximum session entries exceeded event
924 :param data: Decoded IPFIX data records
925 :param limit: Number of maximum session entries that can be created.
927 self.assertEqual(1, len(data))
930 self.assertEqual(scapy.compat.orb(record[230]), 13)
931 # natQuotaExceededEvent
932 self.assertEqual(struct.pack("I", 1), record[466])
934 self.assertEqual(struct.pack("I", limit), record[471])
936 def verify_ipfix_max_bibs(self, data, limit):
938 Verify IPFIX maximum BIB entries exceeded event
940 :param data: Decoded IPFIX data records
941 :param limit: Number of maximum BIB entries that can be created.
943 self.assertEqual(1, len(data))
946 self.assertEqual(scapy.compat.orb(record[230]), 13)
947 # natQuotaExceededEvent
948 self.assertEqual(struct.pack("I", 2), record[466])
950 self.assertEqual(struct.pack("I", limit), record[472])
952 def verify_ipfix_max_fragments_ip6(self, data, limit, src_addr):
954 Verify IPFIX maximum IPv6 fragments pending reassembly exceeded event
956 :param data: Decoded IPFIX data records
957 :param limit: Number of maximum fragments pending reassembly
958 :param src_addr: IPv6 source address
960 self.assertEqual(1, len(data))
963 self.assertEqual(scapy.compat.orb(record[230]), 13)
964 # natQuotaExceededEvent
965 self.assertEqual(struct.pack("I", 5), record[466])
966 # maxFragmentsPendingReassembly
967 self.assertEqual(struct.pack("I", limit), record[475])
969 self.assertEqual(src_addr, record[27])
971 def verify_ipfix_max_fragments_ip4(self, data, limit, src_addr):
973 Verify IPFIX maximum IPv4 fragments pending reassembly exceeded event
975 :param data: Decoded IPFIX data records
976 :param limit: Number of maximum fragments pending reassembly
977 :param src_addr: IPv4 source address
979 self.assertEqual(1, len(data))
982 self.assertEqual(scapy.compat.orb(record[230]), 13)
983 # natQuotaExceededEvent
984 self.assertEqual(struct.pack("I", 5), record[466])
985 # maxFragmentsPendingReassembly
986 self.assertEqual(struct.pack("I", limit), record[475])
988 self.assertEqual(src_addr, record[8])
990 def verify_ipfix_bib(self, data, is_create, src_addr):
992 Verify IPFIX NAT64 BIB create and delete events
994 :param data: Decoded IPFIX data records
995 :param is_create: Create event if nonzero value otherwise delete event
996 :param src_addr: IPv6 source address
998 self.assertEqual(1, len(data))
1002 self.assertEqual(scapy.compat.orb(record[230]), 10)
1004 self.assertEqual(scapy.compat.orb(record[230]), 11)
1006 self.assertEqual(src_addr, record[27])
1007 # postNATSourceIPv4Address
1008 self.assertEqual(self.nat_addr_n, record[225])
1009 # protocolIdentifier
1010 self.assertEqual(IP_PROTOS.tcp, scapy.compat.orb(record[4]))
1012 self.assertEqual(struct.pack("!I", 0), record[234])
1013 # sourceTransportPort
1014 self.assertEqual(struct.pack("!H", self.tcp_port_in), record[7])
1015 # postNAPTSourceTransportPort
1016 self.assertEqual(struct.pack("!H", self.tcp_port_out), record[227])
1018 def verify_ipfix_nat64_ses(self, data, is_create, src_addr, dst_addr,
1021 Verify IPFIX NAT64 session create and delete events
1023 :param data: Decoded IPFIX data records
1024 :param is_create: Create event if nonzero value otherwise delete event
1025 :param src_addr: IPv6 source address
1026 :param dst_addr: IPv4 destination address
1027 :param dst_port: destination TCP port
1029 self.assertEqual(1, len(data))
1033 self.assertEqual(scapy.compat.orb(record[230]), 6)
1035 self.assertEqual(scapy.compat.orb(record[230]), 7)
1037 self.assertEqual(src_addr, record[27])
1038 # destinationIPv6Address
1039 self.assertEqual(socket.inet_pton(socket.AF_INET6,
1040 self.compose_ip6(dst_addr,
1044 # postNATSourceIPv4Address
1045 self.assertEqual(self.nat_addr_n, record[225])
1046 # postNATDestinationIPv4Address
1047 self.assertEqual(socket.inet_pton(socket.AF_INET, dst_addr),
1049 # protocolIdentifier
1050 self.assertEqual(IP_PROTOS.tcp, scapy.compat.orb(record[4]))
1052 self.assertEqual(struct.pack("!I", 0), record[234])
1053 # sourceTransportPort
1054 self.assertEqual(struct.pack("!H", self.tcp_port_in), record[7])
1055 # postNAPTSourceTransportPort
1056 self.assertEqual(struct.pack("!H", self.tcp_port_out), record[227])
1057 # destinationTransportPort
1058 self.assertEqual(struct.pack("!H", dst_port), record[11])
1059 # postNAPTDestinationTransportPort
1060 self.assertEqual(struct.pack("!H", dst_port), record[228])
1062 def verify_no_nat44_user(self):
1063 """ Verify that there is no NAT44 user """
1064 users = self.vapi.nat44_user_dump()
1065 self.assertEqual(len(users), 0)
1066 users = self.statistics.get_counter('/nat44/total-users')
1067 self.assertEqual(users[0][0], 0)
1068 sessions = self.statistics.get_counter('/nat44/total-sessions')
1069 self.assertEqual(sessions[0][0], 0)
1071 def verify_ipfix_max_entries_per_user(self, data, limit, src_addr):
1073 Verify IPFIX maximum entries per user exceeded event
1075 :param data: Decoded IPFIX data records
1076 :param limit: Number of maximum entries per user
1077 :param src_addr: IPv4 source address
1079 self.assertEqual(1, len(data))
1082 self.assertEqual(scapy.compat.orb(record[230]), 13)
1083 # natQuotaExceededEvent
1084 self.assertEqual(struct.pack("I", 3), record[466])
1086 self.assertEqual(struct.pack("I", limit), record[473])
1088 self.assertEqual(src_addr, record[8])
1090 def verify_syslog_apmap(self, data, is_add=True):
1091 message = data.decode('utf-8')
1093 message = SyslogMessage.parse(message)
1094 except ParseError as e:
1095 self.logger.error(e)
1098 self.assertEqual(message.severity, SyslogSeverity.info)
1099 self.assertEqual(message.appname, 'NAT')
1100 self.assertEqual(message.msgid, 'APMADD' if is_add else 'APMDEL')
1101 sd_params = message.sd.get('napmap')
1102 self.assertTrue(sd_params is not None)
1103 self.assertEqual(sd_params.get('IATYP'), 'IPv4')
1104 self.assertEqual(sd_params.get('ISADDR'), self.pg0.remote_ip4)
1105 self.assertEqual(sd_params.get('ISPORT'), "%d" % self.tcp_port_in)
1106 self.assertEqual(sd_params.get('XATYP'), 'IPv4')
1107 self.assertEqual(sd_params.get('XSADDR'), self.nat_addr)
1108 self.assertEqual(sd_params.get('XSPORT'), "%d" % self.tcp_port_out)
1109 self.assertEqual(sd_params.get('PROTO'), "%d" % IP_PROTOS.tcp)
1110 self.assertTrue(sd_params.get('SSUBIX') is not None)
1111 self.assertEqual(sd_params.get('SVLAN'), '0')
1113 def verify_syslog_sess(self, data, is_add=True, is_ip6=False):
1114 message = data.decode('utf-8')
1116 message = SyslogMessage.parse(message)
1117 except ParseError as e:
1118 self.logger.error(e)
1121 self.assertEqual(message.severity, SyslogSeverity.info)
1122 self.assertEqual(message.appname, 'NAT')
1123 self.assertEqual(message.msgid, 'SADD' if is_add else 'SDEL')
1124 sd_params = message.sd.get('nsess')
1125 self.assertTrue(sd_params is not None)
1127 self.assertEqual(sd_params.get('IATYP'), 'IPv6')
1128 self.assertEqual(sd_params.get('ISADDR'), self.pg0.remote_ip6)
1130 self.assertEqual(sd_params.get('IATYP'), 'IPv4')
1131 self.assertEqual(sd_params.get('ISADDR'), self.pg0.remote_ip4)
1132 self.assertTrue(sd_params.get('SSUBIX') is not None)
1133 self.assertEqual(sd_params.get('ISPORT'), "%d" % self.tcp_port_in)
1134 self.assertEqual(sd_params.get('XATYP'), 'IPv4')
1135 self.assertEqual(sd_params.get('XSADDR'), self.nat_addr)
1136 self.assertEqual(sd_params.get('XSPORT'), "%d" % self.tcp_port_out)
1137 self.assertEqual(sd_params.get('PROTO'), "%d" % IP_PROTOS.tcp)
1138 self.assertEqual(sd_params.get('SVLAN'), '0')
1139 self.assertEqual(sd_params.get('XDADDR'), self.pg1.remote_ip4)
1140 self.assertEqual(sd_params.get('XDPORT'),
1141 "%d" % self.tcp_external_port)
1143 def verify_mss_value(self, pkt, mss):
1145 Verify TCP MSS value
1150 if not pkt.haslayer(IP) or not pkt.haslayer(TCP):
1151 raise TypeError("Not a TCP/IP packet")
1153 for option in pkt[TCP].options:
1154 if option[0] == 'MSS':
1155 self.assertEqual(option[1], mss)
1156 self.assert_tcp_checksum_valid(pkt)
1159 def proto2layer(proto):
1160 if proto == IP_PROTOS.tcp:
1162 elif proto == IP_PROTOS.udp:
1164 elif proto == IP_PROTOS.icmp:
1167 raise Exception("Unsupported protocol")
1169 def frag_in_order(self, proto=IP_PROTOS.tcp, dont_translate=False):
1170 layer = self.proto2layer(proto)
1172 if proto == IP_PROTOS.tcp:
1173 data = b"A" * 4 + b"B" * 16 + b"C" * 3
1175 data = b"A" * 16 + b"B" * 16 + b"C" * 3
1176 self.port_in = random.randint(1025, 65535)
1178 reass = self.vapi.nat_reass_dump()
1179 reass_n_start = len(reass)
1182 pkts = self.create_stream_frag(self.pg0,
1183 self.pg1.remote_ip4,
1188 self.pg0.add_stream(pkts)
1189 self.pg_enable_capture(self.pg_interfaces)
1191 frags = self.pg1.get_capture(len(pkts))
1192 if not dont_translate:
1193 p = self.reass_frags_and_verify(frags,
1195 self.pg1.remote_ip4)
1197 p = self.reass_frags_and_verify(frags,
1198 self.pg0.remote_ip4,
1199 self.pg1.remote_ip4)
1200 if proto != IP_PROTOS.icmp:
1201 if not dont_translate:
1202 self.assertEqual(p[layer].dport, 20)
1203 self.assertNotEqual(p[layer].sport, self.port_in)
1205 self.assertEqual(p[layer].sport, self.port_in)
1207 if not dont_translate:
1208 self.assertNotEqual(p[layer].id, self.port_in)
1210 self.assertEqual(p[layer].id, self.port_in)
1211 self.assertEqual(data, p[Raw].load)
1214 if not dont_translate:
1215 dst_addr = self.nat_addr
1217 dst_addr = self.pg0.remote_ip4
1218 if proto != IP_PROTOS.icmp:
1220 dport = p[layer].sport
1224 pkts = self.create_stream_frag(self.pg1,
1231 self.pg1.add_stream(pkts)
1232 self.pg_enable_capture(self.pg_interfaces)
1234 frags = self.pg0.get_capture(len(pkts))
1235 p = self.reass_frags_and_verify(frags,
1236 self.pg1.remote_ip4,
1237 self.pg0.remote_ip4)
1238 if proto != IP_PROTOS.icmp:
1239 self.assertEqual(p[layer].sport, 20)
1240 self.assertEqual(p[layer].dport, self.port_in)
1242 self.assertEqual(p[layer].id, self.port_in)
1243 self.assertEqual(data, p[Raw].load)
1245 reass = self.vapi.nat_reass_dump()
1246 reass_n_end = len(reass)
1248 self.assertEqual(reass_n_end - reass_n_start, 2)
1250 def frag_in_order_in_plus_out(self, proto=IP_PROTOS.tcp):
1251 layer = self.proto2layer(proto)
1253 if proto == IP_PROTOS.tcp:
1254 data = b"A" * 4 + b"B" * 16 + b"C" * 3
1256 data = b"A" * 16 + b"B" * 16 + b"C" * 3
1257 self.port_in = random.randint(1025, 65535)
1260 reass = self.vapi.nat_reass_dump()
1261 reass_n_start = len(reass)
1264 pkts = self.create_stream_frag(self.pg0,
1265 self.server_out_addr,
1267 self.server_out_port,
1270 self.pg0.add_stream(pkts)
1271 self.pg_enable_capture(self.pg_interfaces)
1273 frags = self.pg1.get_capture(len(pkts))
1274 p = self.reass_frags_and_verify(frags,
1275 self.pg0.remote_ip4,
1276 self.server_in_addr)
1277 if proto != IP_PROTOS.icmp:
1278 self.assertEqual(p[layer].sport, self.port_in)
1279 self.assertEqual(p[layer].dport, self.server_in_port)
1281 self.assertEqual(p[layer].id, self.port_in)
1282 self.assertEqual(data, p[Raw].load)
1285 if proto != IP_PROTOS.icmp:
1286 pkts = self.create_stream_frag(self.pg1,
1287 self.pg0.remote_ip4,
1288 self.server_in_port,
1293 pkts = self.create_stream_frag(self.pg1,
1294 self.pg0.remote_ip4,
1300 self.pg1.add_stream(pkts)
1301 self.pg_enable_capture(self.pg_interfaces)
1303 frags = self.pg0.get_capture(len(pkts))
1304 p = self.reass_frags_and_verify(frags,
1305 self.server_out_addr,
1306 self.pg0.remote_ip4)
1307 if proto != IP_PROTOS.icmp:
1308 self.assertEqual(p[layer].sport, self.server_out_port)
1309 self.assertEqual(p[layer].dport, self.port_in)
1311 self.assertEqual(p[layer].id, self.port_in)
1312 self.assertEqual(data, p[Raw].load)
1314 reass = self.vapi.nat_reass_dump()
1315 reass_n_end = len(reass)
1317 self.assertEqual(reass_n_end - reass_n_start, 2)
1319 def reass_hairpinning(self, proto=IP_PROTOS.tcp):
1320 layer = self.proto2layer(proto)
1322 if proto == IP_PROTOS.tcp:
1323 data = b"A" * 4 + b"B" * 16 + b"C" * 3
1325 data = b"A" * 16 + b"B" * 16 + b"C" * 3
1327 # send packet from host to server
1328 pkts = self.create_stream_frag(self.pg0,
1331 self.server_out_port,
1334 self.pg0.add_stream(pkts)
1335 self.pg_enable_capture(self.pg_interfaces)
1337 frags = self.pg0.get_capture(len(pkts))
1338 p = self.reass_frags_and_verify(frags,
1341 if proto != IP_PROTOS.icmp:
1342 self.assertNotEqual(p[layer].sport, self.host_in_port)
1343 self.assertEqual(p[layer].dport, self.server_in_port)
1345 self.assertNotEqual(p[layer].id, self.host_in_port)
1346 self.assertEqual(data, p[Raw].load)
1348 def frag_out_of_order(self, proto=IP_PROTOS.tcp, dont_translate=False):
1349 layer = self.proto2layer(proto)
1351 if proto == IP_PROTOS.tcp:
1352 data = b"A" * 4 + b"B" * 16 + b"C" * 3
1354 data = b"A" * 16 + b"B" * 16 + b"C" * 3
1355 self.port_in = random.randint(1025, 65535)
1359 pkts = self.create_stream_frag(self.pg0,
1360 self.pg1.remote_ip4,
1366 self.pg0.add_stream(pkts)
1367 self.pg_enable_capture(self.pg_interfaces)
1369 frags = self.pg1.get_capture(len(pkts))
1370 if not dont_translate:
1371 p = self.reass_frags_and_verify(frags,
1373 self.pg1.remote_ip4)
1375 p = self.reass_frags_and_verify(frags,
1376 self.pg0.remote_ip4,
1377 self.pg1.remote_ip4)
1378 if proto != IP_PROTOS.icmp:
1379 if not dont_translate:
1380 self.assertEqual(p[layer].dport, 20)
1381 self.assertNotEqual(p[layer].sport, self.port_in)
1383 self.assertEqual(p[layer].sport, self.port_in)
1385 if not dont_translate:
1386 self.assertNotEqual(p[layer].id, self.port_in)
1388 self.assertEqual(p[layer].id, self.port_in)
1389 self.assertEqual(data, p[Raw].load)
1392 if not dont_translate:
1393 dst_addr = self.nat_addr
1395 dst_addr = self.pg0.remote_ip4
1396 if proto != IP_PROTOS.icmp:
1398 dport = p[layer].sport
1402 pkts = self.create_stream_frag(self.pg1,
1410 self.pg1.add_stream(pkts)
1411 self.pg_enable_capture(self.pg_interfaces)
1413 frags = self.pg0.get_capture(len(pkts))
1414 p = self.reass_frags_and_verify(frags,
1415 self.pg1.remote_ip4,
1416 self.pg0.remote_ip4)
1417 if proto != IP_PROTOS.icmp:
1418 self.assertEqual(p[layer].sport, 20)
1419 self.assertEqual(p[layer].dport, self.port_in)
1421 self.assertEqual(p[layer].id, self.port_in)
1422 self.assertEqual(data, p[Raw].load)
1424 def frag_out_of_order_in_plus_out(self, proto=IP_PROTOS.tcp):
1425 layer = self.proto2layer(proto)
1427 if proto == IP_PROTOS.tcp:
1428 data = b"A" * 4 + b"B" * 16 + b"C" * 3
1430 data = b"A" * 16 + b"B" * 16 + b"C" * 3
1431 self.port_in = random.randint(1025, 65535)
1435 pkts = self.create_stream_frag(self.pg0,
1436 self.server_out_addr,
1438 self.server_out_port,
1442 self.pg0.add_stream(pkts)
1443 self.pg_enable_capture(self.pg_interfaces)
1445 frags = self.pg1.get_capture(len(pkts))
1446 p = self.reass_frags_and_verify(frags,
1447 self.pg0.remote_ip4,
1448 self.server_in_addr)
1449 if proto != IP_PROTOS.icmp:
1450 self.assertEqual(p[layer].dport, self.server_in_port)
1451 self.assertEqual(p[layer].sport, self.port_in)
1452 self.assertEqual(p[layer].dport, self.server_in_port)
1454 self.assertEqual(p[layer].id, self.port_in)
1455 self.assertEqual(data, p[Raw].load)
1458 if proto != IP_PROTOS.icmp:
1459 pkts = self.create_stream_frag(self.pg1,
1460 self.pg0.remote_ip4,
1461 self.server_in_port,
1466 pkts = self.create_stream_frag(self.pg1,
1467 self.pg0.remote_ip4,
1474 self.pg1.add_stream(pkts)
1475 self.pg_enable_capture(self.pg_interfaces)
1477 frags = self.pg0.get_capture(len(pkts))
1478 p = self.reass_frags_and_verify(frags,
1479 self.server_out_addr,
1480 self.pg0.remote_ip4)
1481 if proto != IP_PROTOS.icmp:
1482 self.assertEqual(p[layer].sport, self.server_out_port)
1483 self.assertEqual(p[layer].dport, self.port_in)
1485 self.assertEqual(p[layer].id, self.port_in)
1486 self.assertEqual(data, p[Raw].load)
1489 class TestNAT44(MethodHolder):
1490 """ NAT44 Test Cases """
1493 def setUpClass(cls):
1494 super(TestNAT44, cls).setUpClass()
1495 cls.vapi.cli("set log class nat level debug")
1498 cls.tcp_port_in = 6303
1499 cls.tcp_port_out = 6303
1500 cls.udp_port_in = 6304
1501 cls.udp_port_out = 6304
1502 cls.icmp_id_in = 6305
1503 cls.icmp_id_out = 6305
1504 cls.nat_addr = '10.0.0.3'
1505 cls.ipfix_src_port = 4739
1506 cls.ipfix_domain_id = 1
1507 cls.tcp_external_port = 80
1508 cls.udp_external_port = 69
1510 cls.create_pg_interfaces(range(10))
1511 cls.interfaces = list(cls.pg_interfaces[0:4])
1513 for i in cls.interfaces:
1518 cls.pg0.generate_remote_hosts(3)
1519 cls.pg0.configure_ipv4_neighbors()
1521 cls.pg1.generate_remote_hosts(1)
1522 cls.pg1.configure_ipv4_neighbors()
1524 cls.overlapping_interfaces = list(list(cls.pg_interfaces[4:7]))
1525 cls.vapi.ip_table_add_del(is_add=1, table_id=10)
1526 cls.vapi.ip_table_add_del(is_add=1, table_id=20)
1528 cls.pg4._local_ip4 = "172.16.255.1"
1529 cls.pg4._local_ip4n = socket.inet_pton(socket.AF_INET, i.local_ip4)
1530 cls.pg4._remote_hosts[0]._ip4 = "172.16.255.2"
1531 cls.pg4.set_table_ip4(10)
1532 cls.pg5._local_ip4 = "172.17.255.3"
1533 cls.pg5._local_ip4n = socket.inet_pton(socket.AF_INET, i.local_ip4)
1534 cls.pg5._remote_hosts[0]._ip4 = "172.17.255.4"
1535 cls.pg5.set_table_ip4(10)
1536 cls.pg6._local_ip4 = "172.16.255.1"
1537 cls.pg6._local_ip4n = socket.inet_pton(socket.AF_INET, i.local_ip4)
1538 cls.pg6._remote_hosts[0]._ip4 = "172.16.255.2"
1539 cls.pg6.set_table_ip4(20)
1540 for i in cls.overlapping_interfaces:
1548 cls.pg9.generate_remote_hosts(2)
1549 cls.pg9.config_ip4()
1550 ip_addr_n = socket.inet_pton(socket.AF_INET, "10.0.0.1")
1551 cls.vapi.sw_interface_add_del_address(
1552 sw_if_index=cls.pg9.sw_if_index, address=ip_addr_n,
1555 cls.pg9.resolve_arp()
1556 cls.pg9._remote_hosts[1]._ip4 = cls.pg9._remote_hosts[0]._ip4
1557 cls.pg4._remote_ip4 = cls.pg9._remote_hosts[0]._ip4 = "10.0.0.2"
1558 cls.pg9.resolve_arp()
1561 super(TestNAT44, cls).tearDownClass()
1565 def tearDownClass(cls):
1566 super(TestNAT44, cls).tearDownClass()
1568 def test_dynamic(self):
1569 """ NAT44 dynamic translation test """
1570 self.nat44_add_address(self.nat_addr)
1571 flags = self.config_flags.NAT_IS_INSIDE
1572 self.vapi.nat44_interface_add_del_feature(
1573 sw_if_index=self.pg0.sw_if_index,
1574 flags=flags, is_add=1)
1575 self.vapi.nat44_interface_add_del_feature(
1576 sw_if_index=self.pg1.sw_if_index,
1580 tcpn = self.statistics.get_err_counter(
1581 '/err/nat44-in2out-slowpath/TCP packets')
1582 udpn = self.statistics.get_err_counter(
1583 '/err/nat44-in2out-slowpath/UDP packets')
1584 icmpn = self.statistics.get_err_counter(
1585 '/err/nat44-in2out-slowpath/ICMP packets')
1586 totaln = self.statistics.get_err_counter(
1587 '/err/nat44-in2out-slowpath/good in2out packets processed')
1589 pkts = self.create_stream_in(self.pg0, self.pg1)
1590 self.pg0.add_stream(pkts)
1591 self.pg_enable_capture(self.pg_interfaces)
1593 capture = self.pg1.get_capture(len(pkts))
1594 self.verify_capture_out(capture)
1596 err = self.statistics.get_err_counter(
1597 '/err/nat44-in2out-slowpath/TCP packets')
1598 self.assertEqual(err - tcpn, 1)
1599 err = self.statistics.get_err_counter(
1600 '/err/nat44-in2out-slowpath/UDP packets')
1601 self.assertEqual(err - udpn, 1)
1602 err = self.statistics.get_err_counter(
1603 '/err/nat44-in2out-slowpath/ICMP packets')
1604 self.assertEqual(err - icmpn, 1)
1605 err = self.statistics.get_err_counter(
1606 '/err/nat44-in2out-slowpath/good in2out packets processed')
1607 self.assertEqual(err - totaln, 3)
1610 tcpn = self.statistics.get_err_counter('/err/nat44-out2in/TCP packets')
1611 udpn = self.statistics.get_err_counter('/err/nat44-out2in/UDP packets')
1612 icmpn = self.statistics.get_err_counter(
1613 '/err/nat44-out2in/ICMP packets')
1614 totaln = self.statistics.get_err_counter(
1615 '/err/nat44-out2in/good out2in packets processed')
1617 pkts = self.create_stream_out(self.pg1)
1618 self.pg1.add_stream(pkts)
1619 self.pg_enable_capture(self.pg_interfaces)
1621 capture = self.pg0.get_capture(len(pkts))
1622 self.verify_capture_in(capture, self.pg0)
1624 err = self.statistics.get_err_counter('/err/nat44-out2in/TCP packets')
1625 self.assertEqual(err - tcpn, 1)
1626 err = self.statistics.get_err_counter('/err/nat44-out2in/UDP packets')
1627 self.assertEqual(err - udpn, 1)
1628 err = self.statistics.get_err_counter('/err/nat44-out2in/ICMP packets')
1629 self.assertEqual(err - icmpn, 1)
1630 err = self.statistics.get_err_counter(
1631 '/err/nat44-out2in/good out2in packets processed')
1632 self.assertEqual(err - totaln, 3)
1634 users = self.statistics.get_counter('/nat44/total-users')
1635 self.assertEqual(users[0][0], 1)
1636 sessions = self.statistics.get_counter('/nat44/total-sessions')
1637 self.assertEqual(sessions[0][0], 3)
1639 def test_dynamic_icmp_errors_in2out_ttl_1(self):
1640 """ NAT44 handling of client packets with TTL=1 """
1642 self.nat44_add_address(self.nat_addr)
1643 flags = self.config_flags.NAT_IS_INSIDE
1644 self.vapi.nat44_interface_add_del_feature(
1645 sw_if_index=self.pg0.sw_if_index,
1646 flags=flags, is_add=1)
1647 self.vapi.nat44_interface_add_del_feature(
1648 sw_if_index=self.pg1.sw_if_index,
1651 # Client side - generate traffic
1652 pkts = self.create_stream_in(self.pg0, self.pg1, ttl=1)
1653 self.pg0.add_stream(pkts)
1654 self.pg_enable_capture(self.pg_interfaces)
1657 # Client side - verify ICMP type 11 packets
1658 capture = self.pg0.get_capture(len(pkts))
1659 self.verify_capture_in_with_icmp_errors(capture, self.pg0)
1661 def test_dynamic_icmp_errors_out2in_ttl_1(self):
1662 """ NAT44 handling of server packets with TTL=1 """
1664 self.nat44_add_address(self.nat_addr)
1665 flags = self.config_flags.NAT_IS_INSIDE
1666 self.vapi.nat44_interface_add_del_feature(
1667 sw_if_index=self.pg0.sw_if_index,
1668 flags=flags, is_add=1)
1669 self.vapi.nat44_interface_add_del_feature(
1670 sw_if_index=self.pg1.sw_if_index,
1673 # Client side - create sessions
1674 pkts = self.create_stream_in(self.pg0, self.pg1)
1675 self.pg0.add_stream(pkts)
1676 self.pg_enable_capture(self.pg_interfaces)
1679 # Server side - generate traffic
1680 capture = self.pg1.get_capture(len(pkts))
1681 self.verify_capture_out(capture)
1682 pkts = self.create_stream_out(self.pg1, ttl=1)
1683 self.pg1.add_stream(pkts)
1684 self.pg_enable_capture(self.pg_interfaces)
1687 # Server side - verify ICMP type 11 packets
1688 capture = self.pg1.get_capture(len(pkts))
1689 self.verify_capture_out_with_icmp_errors(capture,
1690 src_ip=self.pg1.local_ip4)
1692 def test_dynamic_icmp_errors_in2out_ttl_2(self):
1693 """ NAT44 handling of error responses to client packets with TTL=2 """
1695 self.nat44_add_address(self.nat_addr)
1696 flags = self.config_flags.NAT_IS_INSIDE
1697 self.vapi.nat44_interface_add_del_feature(
1698 sw_if_index=self.pg0.sw_if_index,
1699 flags=flags, is_add=1)
1700 self.vapi.nat44_interface_add_del_feature(
1701 sw_if_index=self.pg1.sw_if_index,
1704 # Client side - generate traffic
1705 pkts = self.create_stream_in(self.pg0, self.pg1, ttl=2)
1706 self.pg0.add_stream(pkts)
1707 self.pg_enable_capture(self.pg_interfaces)
1710 # Server side - simulate ICMP type 11 response
1711 capture = self.pg1.get_capture(len(pkts))
1712 pkts = [Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
1713 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
1714 ICMP(type=11) / packet[IP] for packet in capture]
1715 self.pg1.add_stream(pkts)
1716 self.pg_enable_capture(self.pg_interfaces)
1719 # Client side - verify ICMP type 11 packets
1720 capture = self.pg0.get_capture(len(pkts))
1721 self.verify_capture_in_with_icmp_errors(capture, self.pg0)
1723 def test_dynamic_icmp_errors_out2in_ttl_2(self):
1724 """ NAT44 handling of error responses to server packets with TTL=2 """
1726 self.nat44_add_address(self.nat_addr)
1727 flags = self.config_flags.NAT_IS_INSIDE
1728 self.vapi.nat44_interface_add_del_feature(
1729 sw_if_index=self.pg0.sw_if_index,
1730 flags=flags, is_add=1)
1731 self.vapi.nat44_interface_add_del_feature(
1732 sw_if_index=self.pg1.sw_if_index,
1735 # Client side - create sessions
1736 pkts = self.create_stream_in(self.pg0, self.pg1)
1737 self.pg0.add_stream(pkts)
1738 self.pg_enable_capture(self.pg_interfaces)
1741 # Server side - generate traffic
1742 capture = self.pg1.get_capture(len(pkts))
1743 self.verify_capture_out(capture)
1744 pkts = self.create_stream_out(self.pg1, ttl=2)
1745 self.pg1.add_stream(pkts)
1746 self.pg_enable_capture(self.pg_interfaces)
1749 # Client side - simulate ICMP type 11 response
1750 capture = self.pg0.get_capture(len(pkts))
1751 pkts = [Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
1752 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
1753 ICMP(type=11) / packet[IP] for packet in capture]
1754 self.pg0.add_stream(pkts)
1755 self.pg_enable_capture(self.pg_interfaces)
1758 # Server side - verify ICMP type 11 packets
1759 capture = self.pg1.get_capture(len(pkts))
1760 self.verify_capture_out_with_icmp_errors(capture)
1762 def test_ping_out_interface_from_outside(self):
1763 """ Ping NAT44 out interface from outside network """
1765 self.nat44_add_address(self.nat_addr)
1766 flags = self.config_flags.NAT_IS_INSIDE
1767 self.vapi.nat44_interface_add_del_feature(
1768 sw_if_index=self.pg0.sw_if_index,
1769 flags=flags, is_add=1)
1770 self.vapi.nat44_interface_add_del_feature(
1771 sw_if_index=self.pg1.sw_if_index,
1774 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
1775 IP(src=self.pg1.remote_ip4, dst=self.pg1.local_ip4) /
1776 ICMP(id=self.icmp_id_out, type='echo-request'))
1778 self.pg1.add_stream(pkts)
1779 self.pg_enable_capture(self.pg_interfaces)
1781 capture = self.pg1.get_capture(len(pkts))
1784 self.assertEqual(packet[IP].src, self.pg1.local_ip4)
1785 self.assertEqual(packet[IP].dst, self.pg1.remote_ip4)
1786 self.assertEqual(packet[ICMP].id, self.icmp_id_in)
1787 self.assertEqual(packet[ICMP].type, 0) # echo reply
1789 self.logger.error(ppp("Unexpected or invalid packet "
1790 "(outside network):", packet))
1793 def test_ping_internal_host_from_outside(self):
1794 """ Ping internal host from outside network """
1796 self.nat44_add_static_mapping(self.pg0.remote_ip4, self.nat_addr)
1797 flags = self.config_flags.NAT_IS_INSIDE
1798 self.vapi.nat44_interface_add_del_feature(
1799 sw_if_index=self.pg0.sw_if_index,
1800 flags=flags, is_add=1)
1801 self.vapi.nat44_interface_add_del_feature(
1802 sw_if_index=self.pg1.sw_if_index,
1806 pkt = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
1807 IP(src=self.pg1.remote_ip4, dst=self.nat_addr, ttl=64) /
1808 ICMP(id=self.icmp_id_out, type='echo-request'))
1809 self.pg1.add_stream(pkt)
1810 self.pg_enable_capture(self.pg_interfaces)
1812 capture = self.pg0.get_capture(1)
1813 self.verify_capture_in(capture, self.pg0)
1814 self.assert_equal(capture[0][IP].proto, IP_PROTOS.icmp)
1817 pkt = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
1818 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4, ttl=64) /
1819 ICMP(id=self.icmp_id_in, type='echo-reply'))
1820 self.pg0.add_stream(pkt)
1821 self.pg_enable_capture(self.pg_interfaces)
1823 capture = self.pg1.get_capture(1)
1824 self.verify_capture_out(capture, same_port=True)
1825 self.assert_equal(capture[0][IP].proto, IP_PROTOS.icmp)
1827 def test_forwarding(self):
1828 """ NAT44 forwarding test """
1830 flags = self.config_flags.NAT_IS_INSIDE
1831 self.vapi.nat44_interface_add_del_feature(
1832 sw_if_index=self.pg0.sw_if_index,
1833 flags=flags, is_add=1)
1834 self.vapi.nat44_interface_add_del_feature(
1835 sw_if_index=self.pg1.sw_if_index,
1837 self.vapi.nat44_forwarding_enable_disable(enable=1)
1839 real_ip = self.pg0.remote_ip4n
1840 alias_ip = self.nat_addr
1841 flags = self.config_flags.NAT_IS_ADDR_ONLY
1842 self.vapi.nat44_add_del_static_mapping(is_add=1,
1843 local_ip_address=real_ip,
1844 external_ip_address=alias_ip,
1845 external_sw_if_index=0xFFFFFFFF,
1849 # static mapping match
1851 pkts = self.create_stream_out(self.pg1)
1852 self.pg1.add_stream(pkts)
1853 self.pg_enable_capture(self.pg_interfaces)
1855 capture = self.pg0.get_capture(len(pkts))
1856 self.verify_capture_in(capture, self.pg0)
1858 pkts = self.create_stream_in(self.pg0, self.pg1)
1859 self.pg0.add_stream(pkts)
1860 self.pg_enable_capture(self.pg_interfaces)
1862 capture = self.pg1.get_capture(len(pkts))
1863 self.verify_capture_out(capture, same_port=True)
1865 # no static mapping match
1867 host0 = self.pg0.remote_hosts[0]
1868 self.pg0.remote_hosts[0] = self.pg0.remote_hosts[1]
1870 pkts = self.create_stream_out(self.pg1,
1871 dst_ip=self.pg0.remote_ip4,
1872 use_inside_ports=True)
1873 self.pg1.add_stream(pkts)
1874 self.pg_enable_capture(self.pg_interfaces)
1876 capture = self.pg0.get_capture(len(pkts))
1877 self.verify_capture_in(capture, self.pg0)
1879 pkts = self.create_stream_in(self.pg0, self.pg1)
1880 self.pg0.add_stream(pkts)
1881 self.pg_enable_capture(self.pg_interfaces)
1883 capture = self.pg1.get_capture(len(pkts))
1884 self.verify_capture_out(capture, nat_ip=self.pg0.remote_ip4,
1887 self.pg0.remote_hosts[0] = host0
1890 self.vapi.nat44_forwarding_enable_disable(enable=0)
1891 flags = self.config_flags.NAT_IS_ADDR_ONLY
1892 self.vapi.nat44_add_del_static_mapping(
1894 local_ip_address=real_ip,
1895 external_ip_address=alias_ip,
1896 external_sw_if_index=0xFFFFFFFF,
1899 def test_static_in(self):
1900 """ 1:1 NAT initialized from inside network """
1902 nat_ip = "10.0.0.10"
1903 self.tcp_port_out = 6303
1904 self.udp_port_out = 6304
1905 self.icmp_id_out = 6305
1907 self.nat44_add_static_mapping(self.pg0.remote_ip4, nat_ip)
1908 flags = self.config_flags.NAT_IS_INSIDE
1909 self.vapi.nat44_interface_add_del_feature(
1910 sw_if_index=self.pg0.sw_if_index,
1911 flags=flags, is_add=1)
1912 self.vapi.nat44_interface_add_del_feature(
1913 sw_if_index=self.pg1.sw_if_index,
1915 sm = self.vapi.nat44_static_mapping_dump()
1916 self.assertEqual(len(sm), 1)
1917 self.assertEqual((sm[0].tag).split(b'\0', 1)[0], b'')
1918 self.assertEqual(sm[0].protocol, 0)
1919 self.assertEqual(sm[0].local_port, 0)
1920 self.assertEqual(sm[0].external_port, 0)
1923 pkts = self.create_stream_in(self.pg0, self.pg1)
1924 self.pg0.add_stream(pkts)
1925 self.pg_enable_capture(self.pg_interfaces)
1927 capture = self.pg1.get_capture(len(pkts))
1928 self.verify_capture_out(capture, nat_ip, True)
1931 pkts = self.create_stream_out(self.pg1, nat_ip)
1932 self.pg1.add_stream(pkts)
1933 self.pg_enable_capture(self.pg_interfaces)
1935 capture = self.pg0.get_capture(len(pkts))
1936 self.verify_capture_in(capture, self.pg0)
1938 def test_static_out(self):
1939 """ 1:1 NAT initialized from outside network """
1941 nat_ip = "10.0.0.20"
1942 self.tcp_port_out = 6303
1943 self.udp_port_out = 6304
1944 self.icmp_id_out = 6305
1947 self.nat44_add_static_mapping(self.pg0.remote_ip4, nat_ip, tag=tag)
1948 flags = self.config_flags.NAT_IS_INSIDE
1949 self.vapi.nat44_interface_add_del_feature(
1950 sw_if_index=self.pg0.sw_if_index,
1951 flags=flags, is_add=1)
1952 self.vapi.nat44_interface_add_del_feature(
1953 sw_if_index=self.pg1.sw_if_index,
1955 sm = self.vapi.nat44_static_mapping_dump()
1956 self.assertEqual(len(sm), 1)
1957 self.assertEqual((sm[0].tag).split(b'\0', 1)[0], tag)
1960 pkts = self.create_stream_out(self.pg1, nat_ip)
1961 self.pg1.add_stream(pkts)
1962 self.pg_enable_capture(self.pg_interfaces)
1964 capture = self.pg0.get_capture(len(pkts))
1965 self.verify_capture_in(capture, self.pg0)
1968 pkts = self.create_stream_in(self.pg0, self.pg1)
1969 self.pg0.add_stream(pkts)
1970 self.pg_enable_capture(self.pg_interfaces)
1972 capture = self.pg1.get_capture(len(pkts))
1973 self.verify_capture_out(capture, nat_ip, True)
1975 def test_static_with_port_in(self):
1976 """ 1:1 NAPT initialized from inside network """
1978 self.tcp_port_out = 3606
1979 self.udp_port_out = 3607
1980 self.icmp_id_out = 3608
1982 self.nat44_add_address(self.nat_addr)
1983 self.nat44_add_static_mapping(self.pg0.remote_ip4, self.nat_addr,
1984 self.tcp_port_in, self.tcp_port_out,
1985 proto=IP_PROTOS.tcp)
1986 self.nat44_add_static_mapping(self.pg0.remote_ip4, self.nat_addr,
1987 self.udp_port_in, self.udp_port_out,
1988 proto=IP_PROTOS.udp)
1989 self.nat44_add_static_mapping(self.pg0.remote_ip4, self.nat_addr,
1990 self.icmp_id_in, self.icmp_id_out,
1991 proto=IP_PROTOS.icmp)
1992 flags = self.config_flags.NAT_IS_INSIDE
1993 self.vapi.nat44_interface_add_del_feature(
1994 sw_if_index=self.pg0.sw_if_index,
1995 flags=flags, is_add=1)
1996 self.vapi.nat44_interface_add_del_feature(
1997 sw_if_index=self.pg1.sw_if_index,
2001 pkts = self.create_stream_in(self.pg0, self.pg1)
2002 self.pg0.add_stream(pkts)
2003 self.pg_enable_capture(self.pg_interfaces)
2005 capture = self.pg1.get_capture(len(pkts))
2006 self.verify_capture_out(capture)
2009 pkts = self.create_stream_out(self.pg1)
2010 self.pg1.add_stream(pkts)
2011 self.pg_enable_capture(self.pg_interfaces)
2013 capture = self.pg0.get_capture(len(pkts))
2014 self.verify_capture_in(capture, self.pg0)
2016 def test_static_with_port_out(self):
2017 """ 1:1 NAPT initialized from outside network """
2019 self.tcp_port_out = 30606
2020 self.udp_port_out = 30607
2021 self.icmp_id_out = 30608
2023 self.nat44_add_address(self.nat_addr)
2024 self.nat44_add_static_mapping(self.pg0.remote_ip4, self.nat_addr,
2025 self.tcp_port_in, self.tcp_port_out,
2026 proto=IP_PROTOS.tcp)
2027 self.nat44_add_static_mapping(self.pg0.remote_ip4, self.nat_addr,
2028 self.udp_port_in, self.udp_port_out,
2029 proto=IP_PROTOS.udp)
2030 self.nat44_add_static_mapping(self.pg0.remote_ip4, self.nat_addr,
2031 self.icmp_id_in, self.icmp_id_out,
2032 proto=IP_PROTOS.icmp)
2033 flags = self.config_flags.NAT_IS_INSIDE
2034 self.vapi.nat44_interface_add_del_feature(
2035 sw_if_index=self.pg0.sw_if_index,
2036 flags=flags, is_add=1)
2037 self.vapi.nat44_interface_add_del_feature(
2038 sw_if_index=self.pg1.sw_if_index,
2042 pkts = self.create_stream_out(self.pg1)
2043 self.pg1.add_stream(pkts)
2044 self.pg_enable_capture(self.pg_interfaces)
2046 capture = self.pg0.get_capture(len(pkts))
2047 self.verify_capture_in(capture, self.pg0)
2050 pkts = self.create_stream_in(self.pg0, self.pg1)
2051 self.pg0.add_stream(pkts)
2052 self.pg_enable_capture(self.pg_interfaces)
2054 capture = self.pg1.get_capture(len(pkts))
2055 self.verify_capture_out(capture)
2057 def test_static_vrf_aware(self):
2058 """ 1:1 NAT VRF awareness """
2060 nat_ip1 = "10.0.0.30"
2061 nat_ip2 = "10.0.0.40"
2062 self.tcp_port_out = 6303
2063 self.udp_port_out = 6304
2064 self.icmp_id_out = 6305
2066 self.nat44_add_static_mapping(self.pg4.remote_ip4, nat_ip1,
2068 self.nat44_add_static_mapping(self.pg0.remote_ip4, nat_ip2,
2070 flags = self.config_flags.NAT_IS_INSIDE
2071 self.vapi.nat44_interface_add_del_feature(
2072 sw_if_index=self.pg3.sw_if_index,
2074 self.vapi.nat44_interface_add_del_feature(
2075 sw_if_index=self.pg0.sw_if_index,
2076 flags=flags, is_add=1)
2077 self.vapi.nat44_interface_add_del_feature(
2078 sw_if_index=self.pg4.sw_if_index,
2079 flags=flags, is_add=1)
2081 # inside interface VRF match NAT44 static mapping VRF
2082 pkts = self.create_stream_in(self.pg4, self.pg3)
2083 self.pg4.add_stream(pkts)
2084 self.pg_enable_capture(self.pg_interfaces)
2086 capture = self.pg3.get_capture(len(pkts))
2087 self.verify_capture_out(capture, nat_ip1, True)
2089 # inside interface VRF don't match NAT44 static mapping VRF (packets
2091 pkts = self.create_stream_in(self.pg0, self.pg3)
2092 self.pg0.add_stream(pkts)
2093 self.pg_enable_capture(self.pg_interfaces)
2095 self.pg3.assert_nothing_captured()
2097 def test_dynamic_to_static(self):
2098 """ Switch from dynamic translation to 1:1NAT """
2099 nat_ip = "10.0.0.10"
2100 self.tcp_port_out = 6303
2101 self.udp_port_out = 6304
2102 self.icmp_id_out = 6305
2104 self.nat44_add_address(self.nat_addr)
2105 flags = self.config_flags.NAT_IS_INSIDE
2106 self.vapi.nat44_interface_add_del_feature(
2107 sw_if_index=self.pg0.sw_if_index,
2108 flags=flags, is_add=1)
2109 self.vapi.nat44_interface_add_del_feature(
2110 sw_if_index=self.pg1.sw_if_index,
2114 pkts = self.create_stream_in(self.pg0, self.pg1)
2115 self.pg0.add_stream(pkts)
2116 self.pg_enable_capture(self.pg_interfaces)
2118 capture = self.pg1.get_capture(len(pkts))
2119 self.verify_capture_out(capture)
2122 self.nat44_add_static_mapping(self.pg0.remote_ip4, nat_ip)
2123 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4n, 0)
2124 self.assertEqual(len(sessions), 0)
2125 pkts = self.create_stream_in(self.pg0, self.pg1)
2126 self.pg0.add_stream(pkts)
2127 self.pg_enable_capture(self.pg_interfaces)
2129 capture = self.pg1.get_capture(len(pkts))
2130 self.verify_capture_out(capture, nat_ip, True)
2132 def test_identity_nat(self):
2133 """ Identity NAT """
2134 flags = self.config_flags.NAT_IS_ADDR_ONLY
2135 self.vapi.nat44_add_del_identity_mapping(
2136 ip_address=self.pg0.remote_ip4n, sw_if_index=0xFFFFFFFF,
2137 flags=flags, is_add=1)
2138 flags = self.config_flags.NAT_IS_INSIDE
2139 self.vapi.nat44_interface_add_del_feature(
2140 sw_if_index=self.pg0.sw_if_index,
2141 flags=flags, is_add=1)
2142 self.vapi.nat44_interface_add_del_feature(
2143 sw_if_index=self.pg1.sw_if_index,
2146 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
2147 IP(src=self.pg1.remote_ip4, dst=self.pg0.remote_ip4) /
2148 TCP(sport=12345, dport=56789))
2149 self.pg1.add_stream(p)
2150 self.pg_enable_capture(self.pg_interfaces)
2152 capture = self.pg0.get_capture(1)
2157 self.assertEqual(ip.dst, self.pg0.remote_ip4)
2158 self.assertEqual(ip.src, self.pg1.remote_ip4)
2159 self.assertEqual(tcp.dport, 56789)
2160 self.assertEqual(tcp.sport, 12345)
2161 self.assert_packet_checksums_valid(p)
2163 self.logger.error(ppp("Unexpected or invalid packet:", p))
2166 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4n, 0)
2167 self.assertEqual(len(sessions), 0)
2168 flags = self.config_flags.NAT_IS_ADDR_ONLY
2169 self.vapi.nat44_add_del_identity_mapping(
2170 ip_address=self.pg0.remote_ip4n, sw_if_index=0xFFFFFFFF,
2171 flags=flags, vrf_id=1, is_add=1)
2172 identity_mappings = self.vapi.nat44_identity_mapping_dump()
2173 self.assertEqual(len(identity_mappings), 2)
2175 def test_multiple_inside_interfaces(self):
2176 """ NAT44 multiple non-overlapping address space inside interfaces """
2178 self.nat44_add_address(self.nat_addr)
2179 flags = self.config_flags.NAT_IS_INSIDE
2180 self.vapi.nat44_interface_add_del_feature(
2181 sw_if_index=self.pg0.sw_if_index,
2182 flags=flags, is_add=1)
2183 self.vapi.nat44_interface_add_del_feature(
2184 sw_if_index=self.pg1.sw_if_index,
2185 flags=flags, is_add=1)
2186 self.vapi.nat44_interface_add_del_feature(
2187 sw_if_index=self.pg3.sw_if_index,
2190 # between two NAT44 inside interfaces (no translation)
2191 pkts = self.create_stream_in(self.pg0, self.pg1)
2192 self.pg0.add_stream(pkts)
2193 self.pg_enable_capture(self.pg_interfaces)
2195 capture = self.pg1.get_capture(len(pkts))
2196 self.verify_capture_no_translation(capture, self.pg0, self.pg1)
2198 # from NAT44 inside to interface without NAT44 feature (no translation)
2199 pkts = self.create_stream_in(self.pg0, self.pg2)
2200 self.pg0.add_stream(pkts)
2201 self.pg_enable_capture(self.pg_interfaces)
2203 capture = self.pg2.get_capture(len(pkts))
2204 self.verify_capture_no_translation(capture, self.pg0, self.pg2)
2206 # in2out 1st interface
2207 pkts = self.create_stream_in(self.pg0, self.pg3)
2208 self.pg0.add_stream(pkts)
2209 self.pg_enable_capture(self.pg_interfaces)
2211 capture = self.pg3.get_capture(len(pkts))
2212 self.verify_capture_out(capture)
2214 # out2in 1st interface
2215 pkts = self.create_stream_out(self.pg3)
2216 self.pg3.add_stream(pkts)
2217 self.pg_enable_capture(self.pg_interfaces)
2219 capture = self.pg0.get_capture(len(pkts))
2220 self.verify_capture_in(capture, self.pg0)
2222 # in2out 2nd interface
2223 pkts = self.create_stream_in(self.pg1, self.pg3)
2224 self.pg1.add_stream(pkts)
2225 self.pg_enable_capture(self.pg_interfaces)
2227 capture = self.pg3.get_capture(len(pkts))
2228 self.verify_capture_out(capture)
2230 # out2in 2nd interface
2231 pkts = self.create_stream_out(self.pg3)
2232 self.pg3.add_stream(pkts)
2233 self.pg_enable_capture(self.pg_interfaces)
2235 capture = self.pg1.get_capture(len(pkts))
2236 self.verify_capture_in(capture, self.pg1)
2238 def test_inside_overlapping_interfaces(self):
2239 """ NAT44 multiple inside interfaces with overlapping address space """
2241 static_nat_ip = "10.0.0.10"
2242 self.nat44_add_address(self.nat_addr)
2243 flags = self.config_flags.NAT_IS_INSIDE
2244 self.vapi.nat44_interface_add_del_feature(
2245 sw_if_index=self.pg3.sw_if_index,
2247 self.vapi.nat44_interface_add_del_feature(
2248 sw_if_index=self.pg4.sw_if_index,
2249 flags=flags, is_add=1)
2250 self.vapi.nat44_interface_add_del_feature(
2251 sw_if_index=self.pg5.sw_if_index,
2252 flags=flags, is_add=1)
2253 self.vapi.nat44_interface_add_del_feature(
2254 sw_if_index=self.pg6.sw_if_index,
2255 flags=flags, is_add=1)
2256 self.nat44_add_static_mapping(self.pg6.remote_ip4, static_nat_ip,
2259 # between NAT44 inside interfaces with same VRF (no translation)
2260 pkts = self.create_stream_in(self.pg4, self.pg5)
2261 self.pg4.add_stream(pkts)
2262 self.pg_enable_capture(self.pg_interfaces)
2264 capture = self.pg5.get_capture(len(pkts))
2265 self.verify_capture_no_translation(capture, self.pg4, self.pg5)
2267 # between NAT44 inside interfaces with different VRF (hairpinning)
2268 p = (Ether(src=self.pg4.remote_mac, dst=self.pg4.local_mac) /
2269 IP(src=self.pg4.remote_ip4, dst=static_nat_ip) /
2270 TCP(sport=1234, dport=5678))
2271 self.pg4.add_stream(p)
2272 self.pg_enable_capture(self.pg_interfaces)
2274 capture = self.pg6.get_capture(1)
2279 self.assertEqual(ip.src, self.nat_addr)
2280 self.assertEqual(ip.dst, self.pg6.remote_ip4)
2281 self.assertNotEqual(tcp.sport, 1234)
2282 self.assertEqual(tcp.dport, 5678)
2284 self.logger.error(ppp("Unexpected or invalid packet:", p))
2287 # in2out 1st interface
2288 pkts = self.create_stream_in(self.pg4, self.pg3)
2289 self.pg4.add_stream(pkts)
2290 self.pg_enable_capture(self.pg_interfaces)
2292 capture = self.pg3.get_capture(len(pkts))
2293 self.verify_capture_out(capture)
2295 # out2in 1st interface
2296 pkts = self.create_stream_out(self.pg3)
2297 self.pg3.add_stream(pkts)
2298 self.pg_enable_capture(self.pg_interfaces)
2300 capture = self.pg4.get_capture(len(pkts))
2301 self.verify_capture_in(capture, self.pg4)
2303 # in2out 2nd interface
2304 pkts = self.create_stream_in(self.pg5, self.pg3)
2305 self.pg5.add_stream(pkts)
2306 self.pg_enable_capture(self.pg_interfaces)
2308 capture = self.pg3.get_capture(len(pkts))
2309 self.verify_capture_out(capture)
2311 # out2in 2nd interface
2312 pkts = self.create_stream_out(self.pg3)
2313 self.pg3.add_stream(pkts)
2314 self.pg_enable_capture(self.pg_interfaces)
2316 capture = self.pg5.get_capture(len(pkts))
2317 self.verify_capture_in(capture, self.pg5)
2320 addresses = self.vapi.nat44_address_dump()
2321 self.assertEqual(len(addresses), 1)
2322 sessions = self.vapi.nat44_user_session_dump(self.pg5.remote_ip4n, 10)
2323 self.assertEqual(len(sessions), 3)
2324 for session in sessions:
2325 self.assertFalse(session.flags & self.config_flags.NAT_IS_STATIC)
2326 self.assertEqual(str(session.inside_ip_address),
2327 self.pg5.remote_ip4)
2328 self.assertEqual(session.outside_ip_address,
2329 addresses[0].ip_address)
2330 self.assertEqual(sessions[0].protocol, IP_PROTOS.tcp)
2331 self.assertEqual(sessions[1].protocol, IP_PROTOS.udp)
2332 self.assertEqual(sessions[2].protocol, IP_PROTOS.icmp)
2333 self.assertEqual(sessions[0].inside_port, self.tcp_port_in)
2334 self.assertEqual(sessions[1].inside_port, self.udp_port_in)
2335 self.assertEqual(sessions[2].inside_port, self.icmp_id_in)
2336 self.assertEqual(sessions[0].outside_port, self.tcp_port_out)
2337 self.assertEqual(sessions[1].outside_port, self.udp_port_out)
2338 self.assertEqual(sessions[2].outside_port, self.icmp_id_out)
2340 # in2out 3rd interface
2341 pkts = self.create_stream_in(self.pg6, self.pg3)
2342 self.pg6.add_stream(pkts)
2343 self.pg_enable_capture(self.pg_interfaces)
2345 capture = self.pg3.get_capture(len(pkts))
2346 self.verify_capture_out(capture, static_nat_ip, True)
2348 # out2in 3rd interface
2349 pkts = self.create_stream_out(self.pg3, static_nat_ip)
2350 self.pg3.add_stream(pkts)
2351 self.pg_enable_capture(self.pg_interfaces)
2353 capture = self.pg6.get_capture(len(pkts))
2354 self.verify_capture_in(capture, self.pg6)
2356 # general user and session dump verifications
2357 users = self.vapi.nat44_user_dump()
2358 self.assertGreaterEqual(len(users), 3)
2359 addresses = self.vapi.nat44_address_dump()
2360 self.assertEqual(len(addresses), 1)
2362 sessions = self.vapi.nat44_user_session_dump(user.ip_address,
2364 for session in sessions:
2365 self.assertEqual(user.ip_address, session.inside_ip_address)
2366 self.assertTrue(session.total_bytes > session.total_pkts > 0)
2367 self.assertTrue(session.protocol in
2368 [IP_PROTOS.tcp, IP_PROTOS.udp,
2370 self.assertFalse(session.flags &
2371 self.config_flags.NAT_IS_EXT_HOST_VALID)
2374 sessions = self.vapi.nat44_user_session_dump(self.pg4.remote_ip4n, 10)
2375 self.assertGreaterEqual(len(sessions), 4)
2376 for session in sessions:
2377 self.assertFalse(session.flags & self.config_flags.NAT_IS_STATIC)
2378 self.assertEqual(str(session.inside_ip_address),
2379 self.pg4.remote_ip4)
2380 self.assertEqual(session.outside_ip_address,
2381 addresses[0].ip_address)
2384 sessions = self.vapi.nat44_user_session_dump(self.pg6.remote_ip4n, 20)
2385 self.assertGreaterEqual(len(sessions), 3)
2386 for session in sessions:
2387 self.assertTrue(session.flags & self.config_flags.NAT_IS_STATIC)
2388 self.assertEqual(str(session.inside_ip_address),
2389 self.pg6.remote_ip4)
2390 self.assertEqual(str(session.outside_ip_address),
2392 self.assertTrue(session.inside_port in
2393 [self.tcp_port_in, self.udp_port_in,
2396 def test_hairpinning(self):
2397 """ NAT44 hairpinning - 1:1 NAPT """
2399 host = self.pg0.remote_hosts[0]
2400 server = self.pg0.remote_hosts[1]
2403 server_in_port = 5678
2404 server_out_port = 8765
2406 self.nat44_add_address(self.nat_addr)
2407 flags = self.config_flags.NAT_IS_INSIDE
2408 self.vapi.nat44_interface_add_del_feature(
2409 sw_if_index=self.pg0.sw_if_index,
2410 flags=flags, is_add=1)
2411 self.vapi.nat44_interface_add_del_feature(
2412 sw_if_index=self.pg1.sw_if_index,
2415 # add static mapping for server
2416 self.nat44_add_static_mapping(server.ip4, self.nat_addr,
2417 server_in_port, server_out_port,
2418 proto=IP_PROTOS.tcp)
2420 # send packet from host to server
2421 p = (Ether(src=host.mac, dst=self.pg0.local_mac) /
2422 IP(src=host.ip4, dst=self.nat_addr) /
2423 TCP(sport=host_in_port, dport=server_out_port))
2424 self.pg0.add_stream(p)
2425 self.pg_enable_capture(self.pg_interfaces)
2427 capture = self.pg0.get_capture(1)
2432 self.assertEqual(ip.src, self.nat_addr)
2433 self.assertEqual(ip.dst, server.ip4)
2434 self.assertNotEqual(tcp.sport, host_in_port)
2435 self.assertEqual(tcp.dport, server_in_port)
2436 self.assert_packet_checksums_valid(p)
2437 host_out_port = tcp.sport
2439 self.logger.error(ppp("Unexpected or invalid packet:", p))
2442 # send reply from server to host
2443 p = (Ether(src=server.mac, dst=self.pg0.local_mac) /
2444 IP(src=server.ip4, dst=self.nat_addr) /
2445 TCP(sport=server_in_port, dport=host_out_port))
2446 self.pg0.add_stream(p)
2447 self.pg_enable_capture(self.pg_interfaces)
2449 capture = self.pg0.get_capture(1)
2454 self.assertEqual(ip.src, self.nat_addr)
2455 self.assertEqual(ip.dst, host.ip4)
2456 self.assertEqual(tcp.sport, server_out_port)
2457 self.assertEqual(tcp.dport, host_in_port)
2458 self.assert_packet_checksums_valid(p)
2460 self.logger.error(ppp("Unexpected or invalid packet:", p))
2463 def test_hairpinning2(self):
2464 """ NAT44 hairpinning - 1:1 NAT"""
2466 server1_nat_ip = "10.0.0.10"
2467 server2_nat_ip = "10.0.0.11"
2468 host = self.pg0.remote_hosts[0]
2469 server1 = self.pg0.remote_hosts[1]
2470 server2 = self.pg0.remote_hosts[2]
2471 server_tcp_port = 22
2472 server_udp_port = 20
2474 self.nat44_add_address(self.nat_addr)
2475 flags = self.config_flags.NAT_IS_INSIDE
2476 self.vapi.nat44_interface_add_del_feature(
2477 sw_if_index=self.pg0.sw_if_index,
2478 flags=flags, is_add=1)
2479 self.vapi.nat44_interface_add_del_feature(
2480 sw_if_index=self.pg1.sw_if_index,
2483 # add static mapping for servers
2484 self.nat44_add_static_mapping(server1.ip4, server1_nat_ip)
2485 self.nat44_add_static_mapping(server2.ip4, server2_nat_ip)
2489 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2490 IP(src=host.ip4, dst=server1_nat_ip) /
2491 TCP(sport=self.tcp_port_in, dport=server_tcp_port))
2493 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2494 IP(src=host.ip4, dst=server1_nat_ip) /
2495 UDP(sport=self.udp_port_in, dport=server_udp_port))
2497 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2498 IP(src=host.ip4, dst=server1_nat_ip) /
2499 ICMP(id=self.icmp_id_in, type='echo-request'))
2501 self.pg0.add_stream(pkts)
2502 self.pg_enable_capture(self.pg_interfaces)
2504 capture = self.pg0.get_capture(len(pkts))
2505 for packet in capture:
2507 self.assertEqual(packet[IP].src, self.nat_addr)
2508 self.assertEqual(packet[IP].dst, server1.ip4)
2509 if packet.haslayer(TCP):
2510 self.assertNotEqual(packet[TCP].sport, self.tcp_port_in)
2511 self.assertEqual(packet[TCP].dport, server_tcp_port)
2512 self.tcp_port_out = packet[TCP].sport
2513 self.assert_packet_checksums_valid(packet)
2514 elif packet.haslayer(UDP):
2515 self.assertNotEqual(packet[UDP].sport, self.udp_port_in)
2516 self.assertEqual(packet[UDP].dport, server_udp_port)
2517 self.udp_port_out = packet[UDP].sport
2519 self.assertNotEqual(packet[ICMP].id, self.icmp_id_in)
2520 self.icmp_id_out = packet[ICMP].id
2522 self.logger.error(ppp("Unexpected or invalid packet:", packet))
2527 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2528 IP(src=server1.ip4, dst=self.nat_addr) /
2529 TCP(sport=server_tcp_port, dport=self.tcp_port_out))
2531 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2532 IP(src=server1.ip4, dst=self.nat_addr) /
2533 UDP(sport=server_udp_port, dport=self.udp_port_out))
2535 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2536 IP(src=server1.ip4, dst=self.nat_addr) /
2537 ICMP(id=self.icmp_id_out, type='echo-reply'))
2539 self.pg0.add_stream(pkts)
2540 self.pg_enable_capture(self.pg_interfaces)
2542 capture = self.pg0.get_capture(len(pkts))
2543 for packet in capture:
2545 self.assertEqual(packet[IP].src, server1_nat_ip)
2546 self.assertEqual(packet[IP].dst, host.ip4)
2547 if packet.haslayer(TCP):
2548 self.assertEqual(packet[TCP].dport, self.tcp_port_in)
2549 self.assertEqual(packet[TCP].sport, server_tcp_port)
2550 self.assert_packet_checksums_valid(packet)
2551 elif packet.haslayer(UDP):
2552 self.assertEqual(packet[UDP].dport, self.udp_port_in)
2553 self.assertEqual(packet[UDP].sport, server_udp_port)
2555 self.assertEqual(packet[ICMP].id, self.icmp_id_in)
2557 self.logger.error(ppp("Unexpected or invalid packet:", packet))
2560 # server2 to server1
2562 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2563 IP(src=server2.ip4, dst=server1_nat_ip) /
2564 TCP(sport=self.tcp_port_in, dport=server_tcp_port))
2566 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2567 IP(src=server2.ip4, dst=server1_nat_ip) /
2568 UDP(sport=self.udp_port_in, dport=server_udp_port))
2570 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2571 IP(src=server2.ip4, dst=server1_nat_ip) /
2572 ICMP(id=self.icmp_id_in, type='echo-request'))
2574 self.pg0.add_stream(pkts)
2575 self.pg_enable_capture(self.pg_interfaces)
2577 capture = self.pg0.get_capture(len(pkts))
2578 for packet in capture:
2580 self.assertEqual(packet[IP].src, server2_nat_ip)
2581 self.assertEqual(packet[IP].dst, server1.ip4)
2582 if packet.haslayer(TCP):
2583 self.assertEqual(packet[TCP].sport, self.tcp_port_in)
2584 self.assertEqual(packet[TCP].dport, server_tcp_port)
2585 self.tcp_port_out = packet[TCP].sport
2586 self.assert_packet_checksums_valid(packet)
2587 elif packet.haslayer(UDP):
2588 self.assertEqual(packet[UDP].sport, self.udp_port_in)
2589 self.assertEqual(packet[UDP].dport, server_udp_port)
2590 self.udp_port_out = packet[UDP].sport
2592 self.assertEqual(packet[ICMP].id, self.icmp_id_in)
2593 self.icmp_id_out = packet[ICMP].id
2595 self.logger.error(ppp("Unexpected or invalid packet:", packet))
2598 # server1 to server2
2600 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2601 IP(src=server1.ip4, dst=server2_nat_ip) /
2602 TCP(sport=server_tcp_port, dport=self.tcp_port_out))
2604 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2605 IP(src=server1.ip4, dst=server2_nat_ip) /
2606 UDP(sport=server_udp_port, dport=self.udp_port_out))
2608 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2609 IP(src=server1.ip4, dst=server2_nat_ip) /
2610 ICMP(id=self.icmp_id_out, type='echo-reply'))
2612 self.pg0.add_stream(pkts)
2613 self.pg_enable_capture(self.pg_interfaces)
2615 capture = self.pg0.get_capture(len(pkts))
2616 for packet in capture:
2618 self.assertEqual(packet[IP].src, server1_nat_ip)
2619 self.assertEqual(packet[IP].dst, server2.ip4)
2620 if packet.haslayer(TCP):
2621 self.assertEqual(packet[TCP].dport, self.tcp_port_in)
2622 self.assertEqual(packet[TCP].sport, server_tcp_port)
2623 self.assert_packet_checksums_valid(packet)
2624 elif packet.haslayer(UDP):
2625 self.assertEqual(packet[UDP].dport, self.udp_port_in)
2626 self.assertEqual(packet[UDP].sport, server_udp_port)
2628 self.assertEqual(packet[ICMP].id, self.icmp_id_in)
2630 self.logger.error(ppp("Unexpected or invalid packet:", packet))
2633 def test_max_translations_per_user(self):
2634 """ MAX translations per user - recycle the least recently used """
2636 self.nat44_add_address(self.nat_addr)
2637 flags = self.config_flags.NAT_IS_INSIDE
2638 self.vapi.nat44_interface_add_del_feature(
2639 sw_if_index=self.pg0.sw_if_index,
2640 flags=flags, is_add=1)
2641 self.vapi.nat44_interface_add_del_feature(
2642 sw_if_index=self.pg1.sw_if_index,
2645 # get maximum number of translations per user
2646 nat44_config = self.vapi.nat_show_config()
2648 # send more than maximum number of translations per user packets
2649 pkts_num = nat44_config.max_translations_per_user + 5
2651 for port in range(0, pkts_num):
2652 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2653 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
2654 TCP(sport=1025 + port))
2656 self.pg0.add_stream(pkts)
2657 self.pg_enable_capture(self.pg_interfaces)
2660 # verify number of translated packet
2661 self.pg1.get_capture(pkts_num)
2663 users = self.vapi.nat44_user_dump()
2665 if user.ip_address == self.pg0.remote_ip4n:
2666 self.assertEqual(user.nsessions,
2667 nat44_config.max_translations_per_user)
2668 self.assertEqual(user.nstaticsessions, 0)
2671 self.nat44_add_static_mapping(self.pg0.remote_ip4, self.nat_addr,
2673 proto=IP_PROTOS.tcp)
2674 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2675 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
2676 TCP(sport=tcp_port))
2677 self.pg0.add_stream(p)
2678 self.pg_enable_capture(self.pg_interfaces)
2680 self.pg1.get_capture(1)
2681 users = self.vapi.nat44_user_dump()
2683 if user.ip_address == self.pg0.remote_ip4n:
2684 self.assertEqual(user.nsessions,
2685 nat44_config.max_translations_per_user - 1)
2686 self.assertEqual(user.nstaticsessions, 1)
2688 def test_interface_addr(self):
2689 """ Acquire NAT44 addresses from interface """
2690 self.vapi.nat44_add_del_interface_addr(
2692 sw_if_index=self.pg7.sw_if_index)
2694 # no address in NAT pool
2695 addresses = self.vapi.nat44_address_dump()
2696 self.assertEqual(0, len(addresses))
2698 # configure interface address and check NAT address pool
2699 self.pg7.config_ip4()
2700 addresses = self.vapi.nat44_address_dump()
2701 self.assertEqual(1, len(addresses))
2702 self.assertEqual(str(addresses[0].ip_address), self.pg7.local_ip4)
2704 # remove interface address and check NAT address pool
2705 self.pg7.unconfig_ip4()
2706 addresses = self.vapi.nat44_address_dump()
2707 self.assertEqual(0, len(addresses))
2709 def test_interface_addr_static_mapping(self):
2710 """ Static mapping with addresses from interface """
2713 self.vapi.nat44_add_del_interface_addr(
2715 sw_if_index=self.pg7.sw_if_index)
2716 self.nat44_add_static_mapping(
2718 external_sw_if_index=self.pg7.sw_if_index,
2721 # static mappings with external interface
2722 static_mappings = self.vapi.nat44_static_mapping_dump()
2723 self.assertEqual(1, len(static_mappings))
2724 self.assertEqual(self.pg7.sw_if_index,
2725 static_mappings[0].external_sw_if_index)
2726 self.assertEqual((static_mappings[0].tag).split(b'\0', 1)[0], tag)
2728 # configure interface address and check static mappings
2729 self.pg7.config_ip4()
2730 static_mappings = self.vapi.nat44_static_mapping_dump()
2731 self.assertEqual(2, len(static_mappings))
2733 for sm in static_mappings:
2734 if sm.external_sw_if_index == 0xFFFFFFFF:
2735 self.assertEqual(str(sm.external_ip_address),
2737 self.assertEqual((sm.tag).split(b'\0', 1)[0], tag)
2739 self.assertTrue(resolved)
2741 # remove interface address and check static mappings
2742 self.pg7.unconfig_ip4()
2743 static_mappings = self.vapi.nat44_static_mapping_dump()
2744 self.assertEqual(1, len(static_mappings))
2745 self.assertEqual(self.pg7.sw_if_index,
2746 static_mappings[0].external_sw_if_index)
2747 self.assertEqual((static_mappings[0].tag).split(b'\0', 1)[0], tag)
2749 # configure interface address again and check static mappings
2750 self.pg7.config_ip4()
2751 static_mappings = self.vapi.nat44_static_mapping_dump()
2752 self.assertEqual(2, len(static_mappings))
2754 for sm in static_mappings:
2755 if sm.external_sw_if_index == 0xFFFFFFFF:
2756 self.assertEqual(str(sm.external_ip_address),
2758 self.assertEqual((sm.tag).split(b'\0', 1)[0], tag)
2760 self.assertTrue(resolved)
2762 # remove static mapping
2763 self.nat44_add_static_mapping(
2765 external_sw_if_index=self.pg7.sw_if_index,
2768 static_mappings = self.vapi.nat44_static_mapping_dump()
2769 self.assertEqual(0, len(static_mappings))
2771 def test_interface_addr_identity_nat(self):
2772 """ Identity NAT with addresses from interface """
2775 self.vapi.nat44_add_del_interface_addr(
2777 sw_if_index=self.pg7.sw_if_index)
2778 self.vapi.nat44_add_del_identity_mapping(
2780 sw_if_index=self.pg7.sw_if_index,
2782 protocol=IP_PROTOS.tcp,
2785 # identity mappings with external interface
2786 identity_mappings = self.vapi.nat44_identity_mapping_dump()
2787 self.assertEqual(1, len(identity_mappings))
2788 self.assertEqual(self.pg7.sw_if_index,
2789 identity_mappings[0].sw_if_index)
2791 # configure interface address and check identity mappings
2792 self.pg7.config_ip4()
2793 identity_mappings = self.vapi.nat44_identity_mapping_dump()
2795 self.assertEqual(2, len(identity_mappings))
2796 for sm in identity_mappings:
2797 if sm.sw_if_index == 0xFFFFFFFF:
2798 self.assertEqual(str(identity_mappings[0].ip_address),
2800 self.assertEqual(port, identity_mappings[0].port)
2801 self.assertEqual(IP_PROTOS.tcp, identity_mappings[0].protocol)
2803 self.assertTrue(resolved)
2805 # remove interface address and check identity mappings
2806 self.pg7.unconfig_ip4()
2807 identity_mappings = self.vapi.nat44_identity_mapping_dump()
2808 self.assertEqual(1, len(identity_mappings))
2809 self.assertEqual(self.pg7.sw_if_index,
2810 identity_mappings[0].sw_if_index)
2812 def test_ipfix_nat44_sess(self):
2813 """ IPFIX logging NAT44 session created/deleted """
2814 self.ipfix_domain_id = 10
2815 self.ipfix_src_port = 20202
2816 collector_port = 30303
2817 bind_layers(UDP, IPFIX, dport=30303)
2818 self.nat44_add_address(self.nat_addr)
2819 flags = self.config_flags.NAT_IS_INSIDE
2820 self.vapi.nat44_interface_add_del_feature(
2821 sw_if_index=self.pg0.sw_if_index,
2822 flags=flags, is_add=1)
2823 self.vapi.nat44_interface_add_del_feature(
2824 sw_if_index=self.pg1.sw_if_index,
2826 self.vapi.set_ipfix_exporter(collector_address=self.pg3.remote_ip4n,
2827 src_address=self.pg3.local_ip4n,
2829 template_interval=10,
2830 collector_port=collector_port)
2831 self.vapi.nat_ipfix_enable_disable(domain_id=self.ipfix_domain_id,
2832 src_port=self.ipfix_src_port,
2835 pkts = self.create_stream_in(self.pg0, self.pg1)
2836 self.pg0.add_stream(pkts)
2837 self.pg_enable_capture(self.pg_interfaces)
2839 capture = self.pg1.get_capture(len(pkts))
2840 self.verify_capture_out(capture)
2841 self.nat44_add_address(self.nat_addr, is_add=0)
2842 self.vapi.cli("ipfix flush") # FIXME this should be an API call
2843 capture = self.pg3.get_capture(9)
2844 ipfix = IPFIXDecoder()
2845 # first load template
2847 self.assertTrue(p.haslayer(IPFIX))
2848 self.assertEqual(p[IP].src, self.pg3.local_ip4)
2849 self.assertEqual(p[IP].dst, self.pg3.remote_ip4)
2850 self.assertEqual(p[UDP].sport, self.ipfix_src_port)
2851 self.assertEqual(p[UDP].dport, collector_port)
2852 self.assertEqual(p[IPFIX].observationDomainID,
2853 self.ipfix_domain_id)
2854 if p.haslayer(Template):
2855 ipfix.add_template(p.getlayer(Template))
2856 # verify events in data set
2858 if p.haslayer(Data):
2859 data = ipfix.decode_data_set(p.getlayer(Set))
2860 self.verify_ipfix_nat44_ses(data)
2862 def test_ipfix_addr_exhausted(self):
2863 """ IPFIX logging NAT addresses exhausted """
2864 flags = self.config_flags.NAT_IS_INSIDE
2865 self.vapi.nat44_interface_add_del_feature(
2866 sw_if_index=self.pg0.sw_if_index,
2867 flags=flags, is_add=1)
2868 self.vapi.nat44_interface_add_del_feature(
2869 sw_if_index=self.pg1.sw_if_index,
2871 self.vapi.set_ipfix_exporter(collector_address=self.pg3.remote_ip4n,
2872 src_address=self.pg3.local_ip4n,
2874 template_interval=10)
2875 self.vapi.nat_ipfix_enable_disable(domain_id=self.ipfix_domain_id,
2876 src_port=self.ipfix_src_port,
2879 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
2880 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
2882 self.pg0.add_stream(p)
2883 self.pg_enable_capture(self.pg_interfaces)
2885 self.pg1.assert_nothing_captured()
2887 self.vapi.cli("ipfix flush") # FIXME this should be an API call
2888 capture = self.pg3.get_capture(9)
2889 ipfix = IPFIXDecoder()
2890 # first load template
2892 self.assertTrue(p.haslayer(IPFIX))
2893 self.assertEqual(p[IP].src, self.pg3.local_ip4)
2894 self.assertEqual(p[IP].dst, self.pg3.remote_ip4)
2895 self.assertEqual(p[UDP].sport, self.ipfix_src_port)
2896 self.assertEqual(p[UDP].dport, 4739)
2897 self.assertEqual(p[IPFIX].observationDomainID,
2898 self.ipfix_domain_id)
2899 if p.haslayer(Template):
2900 ipfix.add_template(p.getlayer(Template))
2901 # verify events in data set
2903 if p.haslayer(Data):
2904 data = ipfix.decode_data_set(p.getlayer(Set))
2905 self.verify_ipfix_addr_exhausted(data)
2907 @unittest.skipUnless(running_extended_tests, "part of extended tests")
2908 def test_ipfix_max_sessions(self):
2909 """ IPFIX logging maximum session entries exceeded """
2910 self.nat44_add_address(self.nat_addr)
2911 flags = self.config_flags.NAT_IS_INSIDE
2912 self.vapi.nat44_interface_add_del_feature(
2913 sw_if_index=self.pg0.sw_if_index,
2914 flags=flags, is_add=1)
2915 self.vapi.nat44_interface_add_del_feature(
2916 sw_if_index=self.pg1.sw_if_index,
2919 nat44_config = self.vapi.nat_show_config()
2920 max_sessions = 10 * nat44_config.translation_buckets
2923 for i in range(0, max_sessions):
2924 src = "10.10.%u.%u" % ((i & 0xFF00) >> 8, i & 0xFF)
2925 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2926 IP(src=src, dst=self.pg1.remote_ip4) /
2929 self.pg0.add_stream(pkts)
2930 self.pg_enable_capture(self.pg_interfaces)
2933 self.pg1.get_capture(max_sessions)
2934 self.vapi.set_ipfix_exporter(collector_address=self.pg3.remote_ip4n,
2935 src_address=self.pg3.local_ip4n,
2937 template_interval=10)
2938 self.vapi.nat_ipfix_enable_disable(domain_id=self.ipfix_domain_id,
2939 src_port=self.ipfix_src_port,
2942 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2943 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
2945 self.pg0.add_stream(p)
2946 self.pg_enable_capture(self.pg_interfaces)
2948 self.pg1.assert_nothing_captured()
2950 self.vapi.cli("ipfix flush") # FIXME this should be an API call
2951 capture = self.pg3.get_capture(9)
2952 ipfix = IPFIXDecoder()
2953 # first load template
2955 self.assertTrue(p.haslayer(IPFIX))
2956 self.assertEqual(p[IP].src, self.pg3.local_ip4)
2957 self.assertEqual(p[IP].dst, self.pg3.remote_ip4)
2958 self.assertEqual(p[UDP].sport, self.ipfix_src_port)
2959 self.assertEqual(p[UDP].dport, 4739)
2960 self.assertEqual(p[IPFIX].observationDomainID,
2961 self.ipfix_domain_id)
2962 if p.haslayer(Template):
2963 ipfix.add_template(p.getlayer(Template))
2964 # verify events in data set
2966 if p.haslayer(Data):
2967 data = ipfix.decode_data_set(p.getlayer(Set))
2968 self.verify_ipfix_max_sessions(data, max_sessions)
2970 def test_syslog_apmap(self):
2971 """ Test syslog address and port mapping creation and deletion """
2972 self.vapi.syslog_set_filter(
2973 self.SYSLOG_SEVERITY.SYSLOG_API_SEVERITY_INFO)
2974 self.vapi.syslog_set_sender(self.pg3.local_ip4n, self.pg3.remote_ip4n)
2975 self.nat44_add_address(self.nat_addr)
2976 flags = self.config_flags.NAT_IS_INSIDE
2977 self.vapi.nat44_interface_add_del_feature(
2978 sw_if_index=self.pg0.sw_if_index,
2979 flags=flags, is_add=1)
2980 self.vapi.nat44_interface_add_del_feature(
2981 sw_if_index=self.pg1.sw_if_index,
2984 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2985 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
2986 TCP(sport=self.tcp_port_in, dport=20))
2987 self.pg0.add_stream(p)
2988 self.pg_enable_capture(self.pg_interfaces)
2990 capture = self.pg1.get_capture(1)
2991 self.tcp_port_out = capture[0][TCP].sport
2992 capture = self.pg3.get_capture(1)
2993 self.verify_syslog_apmap(capture[0][Raw].load)
2995 self.pg_enable_capture(self.pg_interfaces)
2997 self.nat44_add_address(self.nat_addr, is_add=0)
2998 capture = self.pg3.get_capture(1)
2999 self.verify_syslog_apmap(capture[0][Raw].load, False)
3001 def test_pool_addr_fib(self):
3002 """ NAT44 add pool addresses to FIB """
3003 static_addr = '10.0.0.10'
3004 self.nat44_add_address(self.nat_addr)
3005 flags = self.config_flags.NAT_IS_INSIDE
3006 self.vapi.nat44_interface_add_del_feature(
3007 sw_if_index=self.pg0.sw_if_index,
3008 flags=flags, is_add=1)
3009 self.vapi.nat44_interface_add_del_feature(
3010 sw_if_index=self.pg1.sw_if_index,
3012 self.nat44_add_static_mapping(self.pg0.remote_ip4, static_addr)
3015 p = (Ether(src=self.pg1.remote_mac, dst='ff:ff:ff:ff:ff:ff') /
3016 ARP(op=ARP.who_has, pdst=self.nat_addr,
3017 psrc=self.pg1.remote_ip4, hwsrc=self.pg1.remote_mac))
3018 self.pg1.add_stream(p)
3019 self.pg_enable_capture(self.pg_interfaces)
3021 capture = self.pg1.get_capture(1)
3022 self.assertTrue(capture[0].haslayer(ARP))
3023 self.assertTrue(capture[0][ARP].op, ARP.is_at)
3026 p = (Ether(src=self.pg1.remote_mac, dst='ff:ff:ff:ff:ff:ff') /
3027 ARP(op=ARP.who_has, pdst=static_addr,
3028 psrc=self.pg1.remote_ip4, hwsrc=self.pg1.remote_mac))
3029 self.pg1.add_stream(p)
3030 self.pg_enable_capture(self.pg_interfaces)
3032 capture = self.pg1.get_capture(1)
3033 self.assertTrue(capture[0].haslayer(ARP))
3034 self.assertTrue(capture[0][ARP].op, ARP.is_at)
3036 # send ARP to non-NAT44 interface
3037 p = (Ether(src=self.pg2.remote_mac, dst='ff:ff:ff:ff:ff:ff') /
3038 ARP(op=ARP.who_has, pdst=self.nat_addr,
3039 psrc=self.pg2.remote_ip4, hwsrc=self.pg2.remote_mac))
3040 self.pg2.add_stream(p)
3041 self.pg_enable_capture(self.pg_interfaces)
3043 self.pg1.assert_nothing_captured()
3045 # remove addresses and verify
3046 self.nat44_add_address(self.nat_addr, is_add=0)
3047 self.nat44_add_static_mapping(self.pg0.remote_ip4, static_addr,
3050 p = (Ether(src=self.pg1.remote_mac, dst='ff:ff:ff:ff:ff:ff') /
3051 ARP(op=ARP.who_has, pdst=self.nat_addr,
3052 psrc=self.pg1.remote_ip4, hwsrc=self.pg1.remote_mac))
3053 self.pg1.add_stream(p)
3054 self.pg_enable_capture(self.pg_interfaces)
3056 self.pg1.assert_nothing_captured()
3058 p = (Ether(src=self.pg1.remote_mac, dst='ff:ff:ff:ff:ff:ff') /
3059 ARP(op=ARP.who_has, pdst=static_addr,
3060 psrc=self.pg1.remote_ip4, hwsrc=self.pg1.remote_mac))
3061 self.pg1.add_stream(p)
3062 self.pg_enable_capture(self.pg_interfaces)
3064 self.pg1.assert_nothing_captured()
3066 def test_vrf_mode(self):
3067 """ NAT44 tenant VRF aware address pool mode """
3071 nat_ip1 = "10.0.0.10"
3072 nat_ip2 = "10.0.0.11"
3074 self.pg0.unconfig_ip4()
3075 self.pg1.unconfig_ip4()
3076 self.vapi.ip_table_add_del(is_add=1, table_id=vrf_id1)
3077 self.vapi.ip_table_add_del(is_add=1, table_id=vrf_id2)
3078 self.pg0.set_table_ip4(vrf_id1)
3079 self.pg1.set_table_ip4(vrf_id2)
3080 self.pg0.config_ip4()
3081 self.pg1.config_ip4()
3082 self.pg0.resolve_arp()
3083 self.pg1.resolve_arp()
3085 self.nat44_add_address(nat_ip1, vrf_id=vrf_id1)
3086 self.nat44_add_address(nat_ip2, vrf_id=vrf_id2)
3087 flags = self.config_flags.NAT_IS_INSIDE
3088 self.vapi.nat44_interface_add_del_feature(
3089 sw_if_index=self.pg0.sw_if_index,
3090 flags=flags, is_add=1)
3091 self.vapi.nat44_interface_add_del_feature(
3092 sw_if_index=self.pg1.sw_if_index,
3093 flags=flags, is_add=1)
3094 self.vapi.nat44_interface_add_del_feature(
3095 sw_if_index=self.pg2.sw_if_index,
3100 pkts = self.create_stream_in(self.pg0, self.pg2)
3101 self.pg0.add_stream(pkts)
3102 self.pg_enable_capture(self.pg_interfaces)
3104 capture = self.pg2.get_capture(len(pkts))
3105 self.verify_capture_out(capture, nat_ip1)
3108 pkts = self.create_stream_in(self.pg1, self.pg2)
3109 self.pg1.add_stream(pkts)
3110 self.pg_enable_capture(self.pg_interfaces)
3112 capture = self.pg2.get_capture(len(pkts))
3113 self.verify_capture_out(capture, nat_ip2)
3116 self.pg0.unconfig_ip4()
3117 self.pg1.unconfig_ip4()
3118 self.pg0.set_table_ip4(0)
3119 self.pg1.set_table_ip4(0)
3120 self.pg0.config_ip4()
3121 self.pg1.config_ip4()
3122 self.pg0.resolve_arp()
3123 self.pg1.resolve_arp()
3124 self.vapi.ip_table_add_del(is_add=0, table_id=vrf_id1)
3125 self.vapi.ip_table_add_del(is_add=0, table_id=vrf_id2)
3127 def test_vrf_feature_independent(self):
3128 """ NAT44 tenant VRF independent address pool mode """
3130 nat_ip1 = "10.0.0.10"
3131 nat_ip2 = "10.0.0.11"
3133 self.nat44_add_address(nat_ip1)
3134 self.nat44_add_address(nat_ip2, vrf_id=99)
3135 flags = self.config_flags.NAT_IS_INSIDE
3136 self.vapi.nat44_interface_add_del_feature(
3137 sw_if_index=self.pg0.sw_if_index,
3138 flags=flags, is_add=1)
3139 self.vapi.nat44_interface_add_del_feature(
3140 sw_if_index=self.pg1.sw_if_index,
3141 flags=flags, is_add=1)
3142 self.vapi.nat44_interface_add_del_feature(
3143 sw_if_index=self.pg2.sw_if_index,
3147 pkts = self.create_stream_in(self.pg0, self.pg2)
3148 self.pg0.add_stream(pkts)
3149 self.pg_enable_capture(self.pg_interfaces)
3151 capture = self.pg2.get_capture(len(pkts))
3152 self.verify_capture_out(capture, nat_ip1)
3155 pkts = self.create_stream_in(self.pg1, self.pg2)
3156 self.pg1.add_stream(pkts)
3157 self.pg_enable_capture(self.pg_interfaces)
3159 capture = self.pg2.get_capture(len(pkts))
3160 self.verify_capture_out(capture, nat_ip1)
3162 def test_dynamic_ipless_interfaces(self):
3163 """ NAT44 interfaces without configured IP address """
3165 self.vapi.ip_neighbor_add_del(
3166 self.pg7.sw_if_index,
3167 self.pg7.remote_mac,
3168 self.pg7.remote_ip4,
3169 flags=(VppEnum.vl_api_ip_neighbor_flags_t.
3170 IP_API_NEIGHBOR_FLAG_STATIC))
3171 self.vapi.ip_neighbor_add_del(
3172 self.pg8.sw_if_index,
3173 self.pg8.remote_mac,
3174 self.pg8.remote_ip4,
3175 flags=(VppEnum.vl_api_ip_neighbor_flags_t.
3176 IP_API_NEIGHBOR_FLAG_STATIC))
3178 self.vapi.ip_add_del_route(dst_address=self.pg7.remote_ip4n,
3179 dst_address_length=32,
3180 next_hop_address=self.pg7.remote_ip4n,
3181 next_hop_sw_if_index=self.pg7.sw_if_index)
3182 self.vapi.ip_add_del_route(dst_address=self.pg8.remote_ip4n,
3183 dst_address_length=32,
3184 next_hop_address=self.pg8.remote_ip4n,
3185 next_hop_sw_if_index=self.pg8.sw_if_index)
3187 self.nat44_add_address(self.nat_addr)
3188 flags = self.config_flags.NAT_IS_INSIDE
3189 self.vapi.nat44_interface_add_del_feature(
3190 sw_if_index=self.pg7.sw_if_index,
3191 flags=flags, is_add=1)
3192 self.vapi.nat44_interface_add_del_feature(
3193 sw_if_index=self.pg8.sw_if_index,
3197 pkts = self.create_stream_in(self.pg7, self.pg8)
3198 self.pg7.add_stream(pkts)
3199 self.pg_enable_capture(self.pg_interfaces)
3201 capture = self.pg8.get_capture(len(pkts))
3202 self.verify_capture_out(capture)
3205 pkts = self.create_stream_out(self.pg8, self.nat_addr)
3206 self.pg8.add_stream(pkts)
3207 self.pg_enable_capture(self.pg_interfaces)
3209 capture = self.pg7.get_capture(len(pkts))
3210 self.verify_capture_in(capture, self.pg7)
3212 def test_static_ipless_interfaces(self):
3213 """ NAT44 interfaces without configured IP address - 1:1 NAT """
3215 self.vapi.ip_neighbor_add_del(
3216 self.pg7.sw_if_index,
3217 self.pg7.remote_mac,
3218 self.pg7.remote_ip4,
3219 flags=(VppEnum.vl_api_ip_neighbor_flags_t.
3220 IP_API_NEIGHBOR_FLAG_STATIC))
3221 self.vapi.ip_neighbor_add_del(
3222 self.pg8.sw_if_index,
3223 self.pg8.remote_mac,
3224 self.pg8.remote_ip4,
3225 flags=(VppEnum.vl_api_ip_neighbor_flags_t.
3226 IP_API_NEIGHBOR_FLAG_STATIC))
3228 self.vapi.ip_add_del_route(dst_address=self.pg7.remote_ip4n,
3229 dst_address_length=32,
3230 next_hop_address=self.pg7.remote_ip4n,
3231 next_hop_sw_if_index=self.pg7.sw_if_index)
3232 self.vapi.ip_add_del_route(dst_address=self.pg8.remote_ip4n,
3233 dst_address_length=32,
3234 next_hop_address=self.pg8.remote_ip4n,
3235 next_hop_sw_if_index=self.pg8.sw_if_index)
3237 self.nat44_add_static_mapping(self.pg7.remote_ip4, self.nat_addr)
3238 flags = self.config_flags.NAT_IS_INSIDE
3239 self.vapi.nat44_interface_add_del_feature(
3240 sw_if_index=self.pg7.sw_if_index,
3241 flags=flags, is_add=1)
3242 self.vapi.nat44_interface_add_del_feature(
3243 sw_if_index=self.pg8.sw_if_index,
3247 pkts = self.create_stream_out(self.pg8)
3248 self.pg8.add_stream(pkts)
3249 self.pg_enable_capture(self.pg_interfaces)
3251 capture = self.pg7.get_capture(len(pkts))
3252 self.verify_capture_in(capture, self.pg7)
3255 pkts = self.create_stream_in(self.pg7, self.pg8)
3256 self.pg7.add_stream(pkts)
3257 self.pg_enable_capture(self.pg_interfaces)
3259 capture = self.pg8.get_capture(len(pkts))
3260 self.verify_capture_out(capture, self.nat_addr, True)
3262 def test_static_with_port_ipless_interfaces(self):
3263 """ NAT44 interfaces without configured IP address - 1:1 NAPT """
3265 self.tcp_port_out = 30606
3266 self.udp_port_out = 30607
3267 self.icmp_id_out = 30608
3269 self.vapi.ip_neighbor_add_del(
3270 self.pg7.sw_if_index,
3271 self.pg7.remote_mac,
3272 self.pg7.remote_ip4,
3273 flags=(VppEnum.vl_api_ip_neighbor_flags_t.
3274 IP_API_NEIGHBOR_FLAG_STATIC))
3275 self.vapi.ip_neighbor_add_del(
3276 self.pg8.sw_if_index,
3277 self.pg8.remote_mac,
3278 self.pg8.remote_ip4,
3279 flags=(VppEnum.vl_api_ip_neighbor_flags_t.
3280 IP_API_NEIGHBOR_FLAG_STATIC))
3282 self.vapi.ip_add_del_route(dst_address=self.pg7.remote_ip4n,
3283 dst_address_length=32,
3284 next_hop_address=self.pg7.remote_ip4n,
3285 next_hop_sw_if_index=self.pg7.sw_if_index)
3286 self.vapi.ip_add_del_route(dst_address=self.pg8.remote_ip4n,
3287 dst_address_length=32,
3288 next_hop_address=self.pg8.remote_ip4n,
3289 next_hop_sw_if_index=self.pg8.sw_if_index)
3291 self.nat44_add_address(self.nat_addr)
3292 self.nat44_add_static_mapping(self.pg7.remote_ip4, self.nat_addr,
3293 self.tcp_port_in, self.tcp_port_out,
3294 proto=IP_PROTOS.tcp)
3295 self.nat44_add_static_mapping(self.pg7.remote_ip4, self.nat_addr,
3296 self.udp_port_in, self.udp_port_out,
3297 proto=IP_PROTOS.udp)
3298 self.nat44_add_static_mapping(self.pg7.remote_ip4, self.nat_addr,
3299 self.icmp_id_in, self.icmp_id_out,
3300 proto=IP_PROTOS.icmp)
3301 flags = self.config_flags.NAT_IS_INSIDE
3302 self.vapi.nat44_interface_add_del_feature(
3303 sw_if_index=self.pg7.sw_if_index,
3304 flags=flags, is_add=1)
3305 self.vapi.nat44_interface_add_del_feature(
3306 sw_if_index=self.pg8.sw_if_index,
3310 pkts = self.create_stream_out(self.pg8)
3311 self.pg8.add_stream(pkts)
3312 self.pg_enable_capture(self.pg_interfaces)
3314 capture = self.pg7.get_capture(len(pkts))
3315 self.verify_capture_in(capture, self.pg7)
3318 pkts = self.create_stream_in(self.pg7, self.pg8)
3319 self.pg7.add_stream(pkts)
3320 self.pg_enable_capture(self.pg_interfaces)
3322 capture = self.pg8.get_capture(len(pkts))
3323 self.verify_capture_out(capture)
3325 def test_static_unknown_proto(self):
3326 """ 1:1 NAT translate packet with unknown protocol """
3327 nat_ip = "10.0.0.10"
3328 self.nat44_add_static_mapping(self.pg0.remote_ip4, nat_ip)
3329 flags = self.config_flags.NAT_IS_INSIDE
3330 self.vapi.nat44_interface_add_del_feature(
3331 sw_if_index=self.pg0.sw_if_index,
3332 flags=flags, is_add=1)
3333 self.vapi.nat44_interface_add_del_feature(
3334 sw_if_index=self.pg1.sw_if_index,
3338 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
3339 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
3341 IP(src=self.pg2.remote_ip4, dst=self.pg3.remote_ip4) /
3342 TCP(sport=1234, dport=1234))
3343 self.pg0.add_stream(p)
3344 self.pg_enable_capture(self.pg_interfaces)
3346 p = self.pg1.get_capture(1)
3349 self.assertEqual(packet[IP].src, nat_ip)
3350 self.assertEqual(packet[IP].dst, self.pg1.remote_ip4)
3351 self.assertEqual(packet.haslayer(GRE), 1)
3352 self.assert_packet_checksums_valid(packet)
3354 self.logger.error(ppp("Unexpected or invalid packet:", packet))
3358 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
3359 IP(src=self.pg1.remote_ip4, dst=nat_ip) /
3361 IP(src=self.pg3.remote_ip4, dst=self.pg2.remote_ip4) /
3362 TCP(sport=1234, dport=1234))
3363 self.pg1.add_stream(p)
3364 self.pg_enable_capture(self.pg_interfaces)
3366 p = self.pg0.get_capture(1)
3369 self.assertEqual(packet[IP].src, self.pg1.remote_ip4)
3370 self.assertEqual(packet[IP].dst, self.pg0.remote_ip4)
3371 self.assertEqual(packet.haslayer(GRE), 1)
3372 self.assert_packet_checksums_valid(packet)
3374 self.logger.error(ppp("Unexpected or invalid packet:", packet))
3377 def test_hairpinning_static_unknown_proto(self):
3378 """ 1:1 NAT translate packet with unknown protocol - hairpinning """
3380 host = self.pg0.remote_hosts[0]
3381 server = self.pg0.remote_hosts[1]
3383 host_nat_ip = "10.0.0.10"
3384 server_nat_ip = "10.0.0.11"
3386 self.nat44_add_static_mapping(host.ip4, host_nat_ip)
3387 self.nat44_add_static_mapping(server.ip4, server_nat_ip)
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,
3397 p = (Ether(dst=self.pg0.local_mac, src=host.mac) /
3398 IP(src=host.ip4, dst=server_nat_ip) /
3400 IP(src=self.pg2.remote_ip4, dst=self.pg3.remote_ip4) /
3401 TCP(sport=1234, dport=1234))
3402 self.pg0.add_stream(p)
3403 self.pg_enable_capture(self.pg_interfaces)
3405 p = self.pg0.get_capture(1)
3408 self.assertEqual(packet[IP].src, host_nat_ip)
3409 self.assertEqual(packet[IP].dst, server.ip4)
3410 self.assertEqual(packet.haslayer(GRE), 1)
3411 self.assert_packet_checksums_valid(packet)
3413 self.logger.error(ppp("Unexpected or invalid packet:", packet))
3417 p = (Ether(dst=self.pg0.local_mac, src=server.mac) /
3418 IP(src=server.ip4, dst=host_nat_ip) /
3420 IP(src=self.pg3.remote_ip4, dst=self.pg2.remote_ip4) /
3421 TCP(sport=1234, dport=1234))
3422 self.pg0.add_stream(p)
3423 self.pg_enable_capture(self.pg_interfaces)
3425 p = self.pg0.get_capture(1)
3428 self.assertEqual(packet[IP].src, server_nat_ip)
3429 self.assertEqual(packet[IP].dst, host.ip4)
3430 self.assertEqual(packet.haslayer(GRE), 1)
3431 self.assert_packet_checksums_valid(packet)
3433 self.logger.error(ppp("Unexpected or invalid packet:", packet))
3436 def test_output_feature(self):
3437 """ NAT44 interface output feature (in2out postrouting) """
3438 self.nat44_add_address(self.nat_addr)
3439 flags = self.config_flags.NAT_IS_INSIDE
3440 self.vapi.nat44_interface_add_del_output_feature(
3441 is_add=1, flags=flags,
3442 sw_if_index=self.pg0.sw_if_index)
3443 self.vapi.nat44_interface_add_del_output_feature(
3444 is_add=1, flags=flags,
3445 sw_if_index=self.pg1.sw_if_index)
3446 self.vapi.nat44_interface_add_del_output_feature(
3448 sw_if_index=self.pg3.sw_if_index)
3451 pkts = self.create_stream_in(self.pg0, self.pg3)
3452 self.pg0.add_stream(pkts)
3453 self.pg_enable_capture(self.pg_interfaces)
3455 capture = self.pg3.get_capture(len(pkts))
3456 self.verify_capture_out(capture)
3459 pkts = self.create_stream_out(self.pg3)
3460 self.pg3.add_stream(pkts)
3461 self.pg_enable_capture(self.pg_interfaces)
3463 capture = self.pg0.get_capture(len(pkts))
3464 self.verify_capture_in(capture, self.pg0)
3466 # from non-NAT interface to NAT inside interface
3467 pkts = self.create_stream_in(self.pg2, self.pg0)
3468 self.pg2.add_stream(pkts)
3469 self.pg_enable_capture(self.pg_interfaces)
3471 capture = self.pg0.get_capture(len(pkts))
3472 self.verify_capture_no_translation(capture, self.pg2, self.pg0)
3474 def test_output_feature_vrf_aware(self):
3475 """ NAT44 interface output feature VRF aware (in2out postrouting) """
3476 nat_ip_vrf10 = "10.0.0.10"
3477 nat_ip_vrf20 = "10.0.0.20"
3479 self.vapi.ip_add_del_route(dst_address=self.pg3.remote_ip4n,
3480 dst_address_length=32,
3481 next_hop_address=self.pg3.remote_ip4n,
3482 next_hop_sw_if_index=self.pg3.sw_if_index,
3484 self.vapi.ip_add_del_route(dst_address=self.pg3.remote_ip4n,
3485 dst_address_length=32,
3486 next_hop_address=self.pg3.remote_ip4n,
3487 next_hop_sw_if_index=self.pg3.sw_if_index,
3490 self.nat44_add_address(nat_ip_vrf10, vrf_id=10)
3491 self.nat44_add_address(nat_ip_vrf20, vrf_id=20)
3492 flags = self.config_flags.NAT_IS_INSIDE
3493 self.vapi.nat44_interface_add_del_output_feature(
3494 is_add=1, flags=flags,
3495 sw_if_index=self.pg4.sw_if_index)
3496 self.vapi.nat44_interface_add_del_output_feature(
3497 is_add=1, flags=flags,
3498 sw_if_index=self.pg6.sw_if_index)
3499 self.vapi.nat44_interface_add_del_output_feature(
3501 sw_if_index=self.pg3.sw_if_index)
3504 pkts = self.create_stream_in(self.pg4, self.pg3)
3505 self.pg4.add_stream(pkts)
3506 self.pg_enable_capture(self.pg_interfaces)
3508 capture = self.pg3.get_capture(len(pkts))
3509 self.verify_capture_out(capture, nat_ip=nat_ip_vrf10)
3512 pkts = self.create_stream_out(self.pg3, dst_ip=nat_ip_vrf10)
3513 self.pg3.add_stream(pkts)
3514 self.pg_enable_capture(self.pg_interfaces)
3516 capture = self.pg4.get_capture(len(pkts))
3517 self.verify_capture_in(capture, self.pg4)
3520 pkts = self.create_stream_in(self.pg6, self.pg3)
3521 self.pg6.add_stream(pkts)
3522 self.pg_enable_capture(self.pg_interfaces)
3524 capture = self.pg3.get_capture(len(pkts))
3525 self.verify_capture_out(capture, nat_ip=nat_ip_vrf20)
3528 pkts = self.create_stream_out(self.pg3, dst_ip=nat_ip_vrf20)
3529 self.pg3.add_stream(pkts)
3530 self.pg_enable_capture(self.pg_interfaces)
3532 capture = self.pg6.get_capture(len(pkts))
3533 self.verify_capture_in(capture, self.pg6)
3535 def test_output_feature_hairpinning(self):
3536 """ NAT44 interface output feature hairpinning (in2out postrouting) """
3537 host = self.pg0.remote_hosts[0]
3538 server = self.pg0.remote_hosts[1]
3541 server_in_port = 5678
3542 server_out_port = 8765
3544 self.nat44_add_address(self.nat_addr)
3545 flags = self.config_flags.NAT_IS_INSIDE
3546 self.vapi.nat44_interface_add_del_output_feature(
3547 is_add=1, flags=flags,
3548 sw_if_index=self.pg0.sw_if_index)
3549 self.vapi.nat44_interface_add_del_output_feature(
3551 sw_if_index=self.pg1.sw_if_index)
3553 # add static mapping for server
3554 self.nat44_add_static_mapping(server.ip4, self.nat_addr,
3555 server_in_port, server_out_port,
3556 proto=IP_PROTOS.tcp)
3558 # send packet from host to server
3559 p = (Ether(src=host.mac, dst=self.pg0.local_mac) /
3560 IP(src=host.ip4, dst=self.nat_addr) /
3561 TCP(sport=host_in_port, dport=server_out_port))
3562 self.pg0.add_stream(p)
3563 self.pg_enable_capture(self.pg_interfaces)
3565 capture = self.pg0.get_capture(1)
3570 self.assertEqual(ip.src, self.nat_addr)
3571 self.assertEqual(ip.dst, server.ip4)
3572 self.assertNotEqual(tcp.sport, host_in_port)
3573 self.assertEqual(tcp.dport, server_in_port)
3574 self.assert_packet_checksums_valid(p)
3575 host_out_port = tcp.sport
3577 self.logger.error(ppp("Unexpected or invalid packet:", p))
3580 # send reply from server to host
3581 p = (Ether(src=server.mac, dst=self.pg0.local_mac) /
3582 IP(src=server.ip4, dst=self.nat_addr) /
3583 TCP(sport=server_in_port, dport=host_out_port))
3584 self.pg0.add_stream(p)
3585 self.pg_enable_capture(self.pg_interfaces)
3587 capture = self.pg0.get_capture(1)
3592 self.assertEqual(ip.src, self.nat_addr)
3593 self.assertEqual(ip.dst, host.ip4)
3594 self.assertEqual(tcp.sport, server_out_port)
3595 self.assertEqual(tcp.dport, host_in_port)
3596 self.assert_packet_checksums_valid(p)
3598 self.logger.error(ppp("Unexpected or invalid packet:", p))
3601 def test_one_armed_nat44(self):
3602 """ One armed NAT44 """
3603 remote_host = self.pg9.remote_hosts[0]
3604 local_host = self.pg9.remote_hosts[1]
3607 self.nat44_add_address(self.nat_addr)
3608 flags = self.config_flags.NAT_IS_INSIDE
3609 self.vapi.nat44_interface_add_del_feature(
3610 sw_if_index=self.pg9.sw_if_index,
3612 self.vapi.nat44_interface_add_del_feature(
3613 sw_if_index=self.pg9.sw_if_index,
3614 flags=flags, is_add=1)
3617 p = (Ether(src=self.pg9.remote_mac, dst=self.pg9.local_mac) /
3618 IP(src=local_host.ip4, dst=remote_host.ip4) /
3619 TCP(sport=12345, dport=80))
3620 self.pg9.add_stream(p)
3621 self.pg_enable_capture(self.pg_interfaces)
3623 capture = self.pg9.get_capture(1)
3628 self.assertEqual(ip.src, self.nat_addr)
3629 self.assertEqual(ip.dst, remote_host.ip4)
3630 self.assertNotEqual(tcp.sport, 12345)
3631 external_port = tcp.sport
3632 self.assertEqual(tcp.dport, 80)
3633 self.assert_packet_checksums_valid(p)
3635 self.logger.error(ppp("Unexpected or invalid packet:", p))
3639 p = (Ether(src=self.pg9.remote_mac, dst=self.pg9.local_mac) /
3640 IP(src=remote_host.ip4, dst=self.nat_addr) /
3641 TCP(sport=80, dport=external_port))
3642 self.pg9.add_stream(p)
3643 self.pg_enable_capture(self.pg_interfaces)
3645 capture = self.pg9.get_capture(1)
3650 self.assertEqual(ip.src, remote_host.ip4)
3651 self.assertEqual(ip.dst, local_host.ip4)
3652 self.assertEqual(tcp.sport, 80)
3653 self.assertEqual(tcp.dport, 12345)
3654 self.assert_packet_checksums_valid(p)
3656 self.logger.error(ppp("Unexpected or invalid packet:", p))
3659 err = self.statistics.get_err_counter(
3660 '/err/nat44-classify/next in2out')
3661 self.assertEqual(err, 1)
3662 err = self.statistics.get_err_counter(
3663 '/err/nat44-classify/next out2in')
3664 self.assertEqual(err, 1)
3666 def test_del_session(self):
3667 """ Delete NAT44 session """
3668 self.nat44_add_address(self.nat_addr)
3669 flags = self.config_flags.NAT_IS_INSIDE
3670 self.vapi.nat44_interface_add_del_feature(
3671 sw_if_index=self.pg0.sw_if_index,
3672 flags=flags, is_add=1)
3673 self.vapi.nat44_interface_add_del_feature(
3674 sw_if_index=self.pg1.sw_if_index,
3677 pkts = self.create_stream_in(self.pg0, self.pg1)
3678 self.pg0.add_stream(pkts)
3679 self.pg_enable_capture(self.pg_interfaces)
3681 self.pg1.get_capture(len(pkts))
3683 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4n, 0)
3684 nsessions = len(sessions)
3686 self.vapi.nat44_del_session(address=sessions[0].inside_ip_address,
3687 port=sessions[0].inside_port,
3688 protocol=sessions[0].protocol,
3689 flags=self.config_flags.NAT_IS_INSIDE)
3690 self.vapi.nat44_del_session(address=sessions[1].outside_ip_address,
3691 port=sessions[1].outside_port,
3692 protocol=sessions[1].protocol)
3694 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4n, 0)
3695 self.assertEqual(nsessions - len(sessions), 2)
3697 self.vapi.nat44_del_session(address=sessions[0].inside_ip_address,
3698 port=sessions[0].inside_port,
3699 protocol=sessions[0].protocol,
3700 flags=self.config_flags.NAT_IS_INSIDE)
3702 self.verify_no_nat44_user()
3704 def test_set_get_reass(self):
3705 """ NAT44 set/get virtual fragmentation reassembly """
3706 reas_cfg1 = self.vapi.nat_get_reass()
3708 self.vapi.nat_set_reass(timeout=reas_cfg1.ip4_timeout + 5,
3709 max_reass=reas_cfg1.ip4_max_reass * 2,
3710 max_frag=reas_cfg1.ip4_max_frag * 2,
3713 reas_cfg2 = self.vapi.nat_get_reass()
3715 self.assertEqual(reas_cfg1.ip4_timeout + 5, reas_cfg2.ip4_timeout)
3716 self.assertEqual(reas_cfg1.ip4_max_reass * 2, reas_cfg2.ip4_max_reass)
3717 self.assertEqual(reas_cfg1.ip4_max_frag * 2, reas_cfg2.ip4_max_frag)
3719 self.vapi.nat_set_reass(timeout=2, max_reass=1024, max_frag=5,
3721 self.assertTrue(self.vapi.nat_get_reass().ip4_drop_frag)
3723 def test_frag_in_order(self):
3724 """ NAT44 translate fragments arriving in order """
3726 self.nat44_add_address(self.nat_addr)
3727 flags = self.config_flags.NAT_IS_INSIDE
3728 self.vapi.nat44_interface_add_del_feature(
3729 sw_if_index=self.pg0.sw_if_index,
3730 flags=flags, is_add=1)
3731 self.vapi.nat44_interface_add_del_feature(
3732 sw_if_index=self.pg1.sw_if_index,
3735 self.frag_in_order(proto=IP_PROTOS.tcp)
3736 self.frag_in_order(proto=IP_PROTOS.udp)
3737 self.frag_in_order(proto=IP_PROTOS.icmp)
3739 def test_frag_forwarding(self):
3740 """ NAT44 forwarding fragment test """
3741 self.vapi.nat44_add_del_interface_addr(
3743 sw_if_index=self.pg1.sw_if_index)
3744 flags = self.config_flags.NAT_IS_INSIDE
3745 self.vapi.nat44_interface_add_del_feature(
3746 sw_if_index=self.pg0.sw_if_index,
3747 flags=flags, is_add=1)
3748 self.vapi.nat44_interface_add_del_feature(
3749 sw_if_index=self.pg1.sw_if_index,
3751 self.vapi.nat44_forwarding_enable_disable(enable=1)
3753 data = b"A" * 16 + b"B" * 16 + b"C" * 3
3754 pkts = self.create_stream_frag(self.pg1,
3755 self.pg0.remote_ip4,
3759 proto=IP_PROTOS.udp)
3760 self.pg1.add_stream(pkts)
3761 self.pg_enable_capture(self.pg_interfaces)
3763 frags = self.pg0.get_capture(len(pkts))
3764 p = self.reass_frags_and_verify(frags,
3765 self.pg1.remote_ip4,
3766 self.pg0.remote_ip4)
3767 self.assertEqual(p[UDP].sport, 4789)
3768 self.assertEqual(p[UDP].dport, 4789)
3769 self.assertEqual(data, p[Raw].load)
3771 def test_reass_hairpinning(self):
3772 """ NAT44 fragments hairpinning """
3774 self.server = self.pg0.remote_hosts[1]
3775 self.host_in_port = random.randint(1025, 65535)
3776 self.server_in_port = random.randint(1025, 65535)
3777 self.server_out_port = random.randint(1025, 65535)
3779 self.nat44_add_address(self.nat_addr)
3780 flags = self.config_flags.NAT_IS_INSIDE
3781 self.vapi.nat44_interface_add_del_feature(
3782 sw_if_index=self.pg0.sw_if_index,
3783 flags=flags, is_add=1)
3784 self.vapi.nat44_interface_add_del_feature(
3785 sw_if_index=self.pg1.sw_if_index,
3787 # add static mapping for server
3788 self.nat44_add_static_mapping(self.server.ip4, self.nat_addr,
3789 self.server_in_port,
3790 self.server_out_port,
3791 proto=IP_PROTOS.tcp)
3792 self.nat44_add_static_mapping(self.server.ip4, self.nat_addr,
3793 self.server_in_port,
3794 self.server_out_port,
3795 proto=IP_PROTOS.udp)
3796 self.nat44_add_static_mapping(self.server.ip4, self.nat_addr)
3798 self.reass_hairpinning(proto=IP_PROTOS.tcp)
3799 self.reass_hairpinning(proto=IP_PROTOS.udp)
3800 self.reass_hairpinning(proto=IP_PROTOS.icmp)
3802 def test_frag_out_of_order(self):
3803 """ NAT44 translate fragments arriving out of order """
3805 self.nat44_add_address(self.nat_addr)
3806 flags = self.config_flags.NAT_IS_INSIDE
3807 self.vapi.nat44_interface_add_del_feature(
3808 sw_if_index=self.pg0.sw_if_index,
3809 flags=flags, is_add=1)
3810 self.vapi.nat44_interface_add_del_feature(
3811 sw_if_index=self.pg1.sw_if_index,
3814 self.frag_out_of_order(proto=IP_PROTOS.tcp)
3815 self.frag_out_of_order(proto=IP_PROTOS.udp)
3816 self.frag_out_of_order(proto=IP_PROTOS.icmp)
3818 def test_port_restricted(self):
3819 """ Port restricted NAT44 (MAP-E CE) """
3820 self.nat44_add_address(self.nat_addr)
3821 flags = self.config_flags.NAT_IS_INSIDE
3822 self.vapi.nat44_interface_add_del_feature(
3823 sw_if_index=self.pg0.sw_if_index,
3824 flags=flags, is_add=1)
3825 self.vapi.nat44_interface_add_del_feature(
3826 sw_if_index=self.pg1.sw_if_index,
3828 self.vapi.nat_set_addr_and_port_alloc_alg(alg=1,
3833 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
3834 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
3835 TCP(sport=4567, dport=22))
3836 self.pg0.add_stream(p)
3837 self.pg_enable_capture(self.pg_interfaces)
3839 capture = self.pg1.get_capture(1)
3844 self.assertEqual(ip.dst, self.pg1.remote_ip4)
3845 self.assertEqual(ip.src, self.nat_addr)
3846 self.assertEqual(tcp.dport, 22)
3847 self.assertNotEqual(tcp.sport, 4567)
3848 self.assertEqual((tcp.sport >> 6) & 63, 10)
3849 self.assert_packet_checksums_valid(p)
3851 self.logger.error(ppp("Unexpected or invalid packet:", p))
3854 def test_port_range(self):
3855 """ External address port range """
3856 self.nat44_add_address(self.nat_addr)
3857 flags = self.config_flags.NAT_IS_INSIDE
3858 self.vapi.nat44_interface_add_del_feature(
3859 sw_if_index=self.pg0.sw_if_index,
3860 flags=flags, is_add=1)
3861 self.vapi.nat44_interface_add_del_feature(
3862 sw_if_index=self.pg1.sw_if_index,
3864 self.vapi.nat_set_addr_and_port_alloc_alg(alg=2,
3869 for port in range(0, 5):
3870 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
3871 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
3872 TCP(sport=1125 + port))
3874 self.pg0.add_stream(pkts)
3875 self.pg_enable_capture(self.pg_interfaces)
3877 capture = self.pg1.get_capture(3)
3880 self.assertGreaterEqual(tcp.sport, 1025)
3881 self.assertLessEqual(tcp.sport, 1027)
3883 def test_ipfix_max_frags(self):
3884 """ IPFIX logging maximum fragments pending reassembly exceeded """
3885 self.nat44_add_address(self.nat_addr)
3886 flags = self.config_flags.NAT_IS_INSIDE
3887 self.vapi.nat44_interface_add_del_feature(
3888 sw_if_index=self.pg0.sw_if_index,
3889 flags=flags, is_add=1)
3890 self.vapi.nat44_interface_add_del_feature(
3891 sw_if_index=self.pg1.sw_if_index,
3893 self.vapi.nat_set_reass(timeout=2, max_reass=1024, max_frag=1,
3895 self.vapi.set_ipfix_exporter(collector_address=self.pg3.remote_ip4n,
3896 src_address=self.pg3.local_ip4n,
3898 template_interval=10)
3899 self.vapi.nat_ipfix_enable_disable(domain_id=self.ipfix_domain_id,
3900 src_port=self.ipfix_src_port,
3903 data = b"A" * 4 + b"B" * 16 + b"C" * 3
3904 self.tcp_port_in = random.randint(1025, 65535)
3905 pkts = self.create_stream_frag(self.pg0,
3906 self.pg1.remote_ip4,
3911 self.pg0.add_stream(pkts)
3912 self.pg_enable_capture(self.pg_interfaces)
3914 self.pg1.assert_nothing_captured()
3916 self.vapi.cli("ipfix flush") # FIXME this should be an API call
3917 capture = self.pg3.get_capture(9)
3918 ipfix = IPFIXDecoder()
3919 # first load template
3921 self.assertTrue(p.haslayer(IPFIX))
3922 self.assertEqual(p[IP].src, self.pg3.local_ip4)
3923 self.assertEqual(p[IP].dst, self.pg3.remote_ip4)
3924 self.assertEqual(p[UDP].sport, self.ipfix_src_port)
3925 self.assertEqual(p[UDP].dport, 4739)
3926 self.assertEqual(p[IPFIX].observationDomainID,
3927 self.ipfix_domain_id)
3928 if p.haslayer(Template):
3929 ipfix.add_template(p.getlayer(Template))
3930 # verify events in data set
3932 if p.haslayer(Data):
3933 data = ipfix.decode_data_set(p.getlayer(Set))
3934 self.verify_ipfix_max_fragments_ip4(data, 1,
3935 self.pg0.remote_ip4n)
3937 def test_multiple_outside_vrf(self):
3938 """ Multiple outside VRF """
3942 self.pg1.unconfig_ip4()
3943 self.pg2.unconfig_ip4()
3944 self.vapi.ip_table_add_del(is_add=1, table_id=vrf_id1)
3945 self.vapi.ip_table_add_del(is_add=1, table_id=vrf_id2)
3946 self.pg1.set_table_ip4(vrf_id1)
3947 self.pg2.set_table_ip4(vrf_id2)
3948 self.pg1.config_ip4()
3949 self.pg2.config_ip4()
3950 self.pg1.resolve_arp()
3951 self.pg2.resolve_arp()
3953 self.nat44_add_address(self.nat_addr)
3954 flags = self.config_flags.NAT_IS_INSIDE
3955 self.vapi.nat44_interface_add_del_feature(
3956 sw_if_index=self.pg0.sw_if_index,
3957 flags=flags, is_add=1)
3958 self.vapi.nat44_interface_add_del_feature(
3959 sw_if_index=self.pg1.sw_if_index,
3961 self.vapi.nat44_interface_add_del_feature(
3962 sw_if_index=self.pg2.sw_if_index,
3967 pkts = self.create_stream_in(self.pg0, self.pg1)
3968 self.pg0.add_stream(pkts)
3969 self.pg_enable_capture(self.pg_interfaces)
3971 capture = self.pg1.get_capture(len(pkts))
3972 self.verify_capture_out(capture, self.nat_addr)
3974 pkts = self.create_stream_out(self.pg1, self.nat_addr)
3975 self.pg1.add_stream(pkts)
3976 self.pg_enable_capture(self.pg_interfaces)
3978 capture = self.pg0.get_capture(len(pkts))
3979 self.verify_capture_in(capture, self.pg0)
3981 self.tcp_port_in = 60303
3982 self.udp_port_in = 60304
3983 self.icmp_id_in = 60305
3986 pkts = self.create_stream_in(self.pg0, self.pg2)
3987 self.pg0.add_stream(pkts)
3988 self.pg_enable_capture(self.pg_interfaces)
3990 capture = self.pg2.get_capture(len(pkts))
3991 self.verify_capture_out(capture, self.nat_addr)
3993 pkts = self.create_stream_out(self.pg2, self.nat_addr)
3994 self.pg2.add_stream(pkts)
3995 self.pg_enable_capture(self.pg_interfaces)
3997 capture = self.pg0.get_capture(len(pkts))
3998 self.verify_capture_in(capture, self.pg0)
4001 self.nat44_add_address(self.nat_addr, is_add=0)
4002 self.pg1.unconfig_ip4()
4003 self.pg2.unconfig_ip4()
4004 self.pg1.set_table_ip4(0)
4005 self.pg2.set_table_ip4(0)
4006 self.pg1.config_ip4()
4007 self.pg2.config_ip4()
4008 self.pg1.resolve_arp()
4009 self.pg2.resolve_arp()
4011 @unittest.skipUnless(running_extended_tests, "part of extended tests")
4012 def test_session_timeout(self):
4013 """ NAT44 session timeouts """
4014 self.nat44_add_address(self.nat_addr)
4015 flags = self.config_flags.NAT_IS_INSIDE
4016 self.vapi.nat44_interface_add_del_feature(
4017 sw_if_index=self.pg0.sw_if_index,
4018 flags=flags, is_add=1)
4019 self.vapi.nat44_interface_add_del_feature(
4020 sw_if_index=self.pg1.sw_if_index,
4022 self.vapi.nat_set_timeouts(udp=5, tcp_established=7440,
4023 tcp_transitory=240, icmp=60)
4027 for i in range(0, max_sessions):
4028 src = "10.10.%u.%u" % ((i & 0xFF00) >> 8, i & 0xFF)
4029 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
4030 IP(src=src, dst=self.pg1.remote_ip4) /
4031 UDP(sport=1025, dport=53))
4033 self.pg0.add_stream(pkts)
4034 self.pg_enable_capture(self.pg_interfaces)
4036 self.pg1.get_capture(max_sessions)
4041 for i in range(0, max_sessions):
4042 src = "10.10.%u.%u" % ((i & 0xFF00) >> 8, i & 0xFF)
4043 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
4044 IP(src=src, dst=self.pg1.remote_ip4) /
4045 UDP(sport=1026, dport=53))
4047 self.pg0.add_stream(pkts)
4048 self.pg_enable_capture(self.pg_interfaces)
4050 self.pg1.get_capture(max_sessions)
4053 users = self.vapi.nat44_user_dump()
4055 nsessions = nsessions + user.nsessions
4056 self.assertLess(nsessions, 2 * max_sessions)
4058 def test_mss_clamping(self):
4059 """ TCP MSS clamping """
4060 self.nat44_add_address(self.nat_addr)
4061 flags = self.config_flags.NAT_IS_INSIDE
4062 self.vapi.nat44_interface_add_del_feature(
4063 sw_if_index=self.pg0.sw_if_index,
4064 flags=flags, is_add=1)
4065 self.vapi.nat44_interface_add_del_feature(
4066 sw_if_index=self.pg1.sw_if_index,
4069 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
4070 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
4071 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
4072 flags="S", options=[('MSS', 1400)]))
4074 self.vapi.nat_set_mss_clamping(enable=1, mss_value=1000)
4075 self.pg0.add_stream(p)
4076 self.pg_enable_capture(self.pg_interfaces)
4078 capture = self.pg1.get_capture(1)
4079 # Negotiated MSS value greater than configured - changed
4080 self.verify_mss_value(capture[0], 1000)
4082 self.vapi.nat_set_mss_clamping(enable=0, mss_value=1500)
4083 self.pg0.add_stream(p)
4084 self.pg_enable_capture(self.pg_interfaces)
4086 capture = self.pg1.get_capture(1)
4087 # MSS clamping disabled - negotiated MSS unchanged
4088 self.verify_mss_value(capture[0], 1400)
4090 self.vapi.nat_set_mss_clamping(enable=1, mss_value=1500)
4091 self.pg0.add_stream(p)
4092 self.pg_enable_capture(self.pg_interfaces)
4094 capture = self.pg1.get_capture(1)
4095 # Negotiated MSS value smaller than configured - unchanged
4096 self.verify_mss_value(capture[0], 1400)
4098 @unittest.skipUnless(running_extended_tests, "part of extended tests")
4099 def test_ha_send(self):
4100 """ Send HA session synchronization events (active) """
4101 self.nat44_add_address(self.nat_addr)
4102 flags = self.config_flags.NAT_IS_INSIDE
4103 self.vapi.nat44_interface_add_del_feature(
4104 sw_if_index=self.pg0.sw_if_index,
4105 flags=flags, is_add=1)
4106 self.vapi.nat44_interface_add_del_feature(
4107 sw_if_index=self.pg1.sw_if_index,
4109 self.vapi.nat_ha_set_listener(ip_address=self.pg3.local_ip4,
4112 self.vapi.nat_ha_set_failover(ip_address=self.pg3.remote_ip4,
4113 port=12346, session_refresh_interval=10)
4114 bind_layers(UDP, HANATStateSync, sport=12345)
4117 pkts = self.create_stream_in(self.pg0, self.pg1)
4118 self.pg0.add_stream(pkts)
4119 self.pg_enable_capture(self.pg_interfaces)
4121 capture = self.pg1.get_capture(len(pkts))
4122 self.verify_capture_out(capture)
4123 # active send HA events
4124 self.vapi.nat_ha_flush()
4125 stats = self.statistics.get_counter('/nat44/ha/add-event-send')
4126 self.assertEqual(stats[0][0], 3)
4127 capture = self.pg3.get_capture(1)
4129 self.assert_packet_checksums_valid(p)
4133 hanat = p[HANATStateSync]
4135 self.logger.error(ppp("Invalid packet:", p))
4138 self.assertEqual(ip.src, self.pg3.local_ip4)
4139 self.assertEqual(ip.dst, self.pg3.remote_ip4)
4140 self.assertEqual(udp.sport, 12345)
4141 self.assertEqual(udp.dport, 12346)
4142 self.assertEqual(hanat.version, 1)
4143 self.assertEqual(hanat.thread_index, 0)
4144 self.assertEqual(hanat.count, 3)
4145 seq = hanat.sequence_number
4146 for event in hanat.events:
4147 self.assertEqual(event.event_type, 1)
4148 self.assertEqual(event.in_addr, self.pg0.remote_ip4)
4149 self.assertEqual(event.out_addr, self.nat_addr)
4150 self.assertEqual(event.fib_index, 0)
4152 # ACK received events
4153 ack = (Ether(dst=self.pg3.local_mac, src=self.pg3.remote_mac) /
4154 IP(src=self.pg3.remote_ip4, dst=self.pg3.local_ip4) /
4155 UDP(sport=12346, dport=12345) /
4156 HANATStateSync(sequence_number=seq, flags='ACK'))
4157 self.pg3.add_stream(ack)
4159 stats = self.statistics.get_counter('/nat44/ha/ack-recv')
4160 self.assertEqual(stats[0][0], 1)
4162 # delete one session
4163 self.pg_enable_capture(self.pg_interfaces)
4164 self.vapi.nat44_del_session(address=self.pg0.remote_ip4n,
4165 port=self.tcp_port_in,
4166 protocol=IP_PROTOS.tcp,
4167 flags=self.config_flags.NAT_IS_INSIDE)
4168 self.vapi.nat_ha_flush()
4169 stats = self.statistics.get_counter('/nat44/ha/del-event-send')
4170 self.assertEqual(stats[0][0], 1)
4171 capture = self.pg3.get_capture(1)
4174 hanat = p[HANATStateSync]
4176 self.logger.error(ppp("Invalid packet:", p))
4179 self.assertGreater(hanat.sequence_number, seq)
4181 # do not send ACK, active retry send HA event again
4182 self.pg_enable_capture(self.pg_interfaces)
4184 stats = self.statistics.get_counter('/nat44/ha/retry-count')
4185 self.assertEqual(stats[0][0], 3)
4186 stats = self.statistics.get_counter('/nat44/ha/missed-count')
4187 self.assertEqual(stats[0][0], 1)
4188 capture = self.pg3.get_capture(3)
4189 for packet in capture:
4190 self.assertEqual(packet, p)
4192 # session counters refresh
4193 pkts = self.create_stream_out(self.pg1)
4194 self.pg1.add_stream(pkts)
4195 self.pg_enable_capture(self.pg_interfaces)
4197 self.pg0.get_capture(2)
4198 self.vapi.nat_ha_flush()
4199 stats = self.statistics.get_counter('/nat44/ha/refresh-event-send')
4200 self.assertEqual(stats[0][0], 2)
4201 capture = self.pg3.get_capture(1)
4203 self.assert_packet_checksums_valid(p)
4207 hanat = p[HANATStateSync]
4209 self.logger.error(ppp("Invalid packet:", p))
4212 self.assertEqual(ip.src, self.pg3.local_ip4)
4213 self.assertEqual(ip.dst, self.pg3.remote_ip4)
4214 self.assertEqual(udp.sport, 12345)
4215 self.assertEqual(udp.dport, 12346)
4216 self.assertEqual(hanat.version, 1)
4217 self.assertEqual(hanat.count, 2)
4218 seq = hanat.sequence_number
4219 for event in hanat.events:
4220 self.assertEqual(event.event_type, 3)
4221 self.assertEqual(event.out_addr, self.nat_addr)
4222 self.assertEqual(event.fib_index, 0)
4223 self.assertEqual(event.total_pkts, 2)
4224 self.assertGreater(event.total_bytes, 0)
4226 ack = (Ether(dst=self.pg3.local_mac, src=self.pg3.remote_mac) /
4227 IP(src=self.pg3.remote_ip4, dst=self.pg3.local_ip4) /
4228 UDP(sport=12346, dport=12345) /
4229 HANATStateSync(sequence_number=seq, flags='ACK'))
4230 self.pg3.add_stream(ack)
4232 stats = self.statistics.get_counter('/nat44/ha/ack-recv')
4233 self.assertEqual(stats[0][0], 2)
4235 def test_ha_recv(self):
4236 """ Receive HA session synchronization events (passive) """
4237 self.nat44_add_address(self.nat_addr)
4238 flags = self.config_flags.NAT_IS_INSIDE
4239 self.vapi.nat44_interface_add_del_feature(
4240 sw_if_index=self.pg0.sw_if_index,
4241 flags=flags, is_add=1)
4242 self.vapi.nat44_interface_add_del_feature(
4243 sw_if_index=self.pg1.sw_if_index,
4245 self.vapi.nat_ha_set_listener(ip_address=self.pg3.local_ip4,
4248 bind_layers(UDP, HANATStateSync, sport=12345)
4250 self.tcp_port_out = random.randint(1025, 65535)
4251 self.udp_port_out = random.randint(1025, 65535)
4253 # send HA session add events to failover/passive
4254 p = (Ether(dst=self.pg3.local_mac, src=self.pg3.remote_mac) /
4255 IP(src=self.pg3.remote_ip4, dst=self.pg3.local_ip4) /
4256 UDP(sport=12346, dport=12345) /
4257 HANATStateSync(sequence_number=1, events=[
4258 Event(event_type='add', protocol='tcp',
4259 in_addr=self.pg0.remote_ip4, out_addr=self.nat_addr,
4260 in_port=self.tcp_port_in, out_port=self.tcp_port_out,
4261 eh_addr=self.pg1.remote_ip4,
4262 ehn_addr=self.pg1.remote_ip4,
4263 eh_port=self.tcp_external_port,
4264 ehn_port=self.tcp_external_port, fib_index=0),
4265 Event(event_type='add', protocol='udp',
4266 in_addr=self.pg0.remote_ip4, out_addr=self.nat_addr,
4267 in_port=self.udp_port_in, out_port=self.udp_port_out,
4268 eh_addr=self.pg1.remote_ip4,
4269 ehn_addr=self.pg1.remote_ip4,
4270 eh_port=self.udp_external_port,
4271 ehn_port=self.udp_external_port, fib_index=0)]))
4273 self.pg3.add_stream(p)
4274 self.pg_enable_capture(self.pg_interfaces)
4277 capture = self.pg3.get_capture(1)
4280 hanat = p[HANATStateSync]
4282 self.logger.error(ppp("Invalid packet:", p))
4285 self.assertEqual(hanat.sequence_number, 1)
4286 self.assertEqual(hanat.flags, 'ACK')
4287 self.assertEqual(hanat.version, 1)
4288 self.assertEqual(hanat.thread_index, 0)
4289 stats = self.statistics.get_counter('/nat44/ha/ack-send')
4290 self.assertEqual(stats[0][0], 1)
4291 stats = self.statistics.get_counter('/nat44/ha/add-event-recv')
4292 self.assertEqual(stats[0][0], 2)
4293 users = self.statistics.get_counter('/nat44/total-users')
4294 self.assertEqual(users[0][0], 1)
4295 sessions = self.statistics.get_counter('/nat44/total-sessions')
4296 self.assertEqual(sessions[0][0], 2)
4297 users = self.vapi.nat44_user_dump()
4298 self.assertEqual(len(users), 1)
4299 self.assertEqual(str(users[0].ip_address),
4300 self.pg0.remote_ip4)
4301 # there should be 2 sessions created by HA
4302 sessions = self.vapi.nat44_user_session_dump(users[0].ip_address,
4304 self.assertEqual(len(sessions), 2)
4305 for session in sessions:
4306 self.assertEqual(str(session.inside_ip_address),
4307 self.pg0.remote_ip4)
4308 self.assertEqual(str(session.outside_ip_address),
4310 self.assertIn(session.inside_port,
4311 [self.tcp_port_in, self.udp_port_in])
4312 self.assertIn(session.outside_port,
4313 [self.tcp_port_out, self.udp_port_out])
4314 self.assertIn(session.protocol, [IP_PROTOS.tcp, IP_PROTOS.udp])
4316 # send HA session delete event to failover/passive
4317 p = (Ether(dst=self.pg3.local_mac, src=self.pg3.remote_mac) /
4318 IP(src=self.pg3.remote_ip4, dst=self.pg3.local_ip4) /
4319 UDP(sport=12346, dport=12345) /
4320 HANATStateSync(sequence_number=2, events=[
4321 Event(event_type='del', protocol='udp',
4322 in_addr=self.pg0.remote_ip4, out_addr=self.nat_addr,
4323 in_port=self.udp_port_in, out_port=self.udp_port_out,
4324 eh_addr=self.pg1.remote_ip4,
4325 ehn_addr=self.pg1.remote_ip4,
4326 eh_port=self.udp_external_port,
4327 ehn_port=self.udp_external_port, fib_index=0)]))
4329 self.pg3.add_stream(p)
4330 self.pg_enable_capture(self.pg_interfaces)
4333 capture = self.pg3.get_capture(1)
4336 hanat = p[HANATStateSync]
4338 self.logger.error(ppp("Invalid packet:", p))
4341 self.assertEqual(hanat.sequence_number, 2)
4342 self.assertEqual(hanat.flags, 'ACK')
4343 self.assertEqual(hanat.version, 1)
4344 users = self.vapi.nat44_user_dump()
4345 self.assertEqual(len(users), 1)
4346 self.assertEqual(str(users[0].ip_address),
4347 self.pg0.remote_ip4)
4348 # now we should have only 1 session, 1 deleted by HA
4349 sessions = self.vapi.nat44_user_session_dump(users[0].ip_address,
4351 self.assertEqual(len(sessions), 1)
4352 stats = self.statistics.get_counter('/nat44/ha/del-event-recv')
4353 self.assertEqual(stats[0][0], 1)
4355 stats = self.statistics.get_err_counter('/err/nat-ha/pkts-processed')
4356 self.assertEqual(stats, 2)
4358 # send HA session refresh event to failover/passive
4359 p = (Ether(dst=self.pg3.local_mac, src=self.pg3.remote_mac) /
4360 IP(src=self.pg3.remote_ip4, dst=self.pg3.local_ip4) /
4361 UDP(sport=12346, dport=12345) /
4362 HANATStateSync(sequence_number=3, events=[
4363 Event(event_type='refresh', protocol='tcp',
4364 in_addr=self.pg0.remote_ip4, out_addr=self.nat_addr,
4365 in_port=self.tcp_port_in, out_port=self.tcp_port_out,
4366 eh_addr=self.pg1.remote_ip4,
4367 ehn_addr=self.pg1.remote_ip4,
4368 eh_port=self.tcp_external_port,
4369 ehn_port=self.tcp_external_port, fib_index=0,
4370 total_bytes=1024, total_pkts=2)]))
4371 self.pg3.add_stream(p)
4372 self.pg_enable_capture(self.pg_interfaces)
4375 capture = self.pg3.get_capture(1)
4378 hanat = p[HANATStateSync]
4380 self.logger.error(ppp("Invalid packet:", p))
4383 self.assertEqual(hanat.sequence_number, 3)
4384 self.assertEqual(hanat.flags, 'ACK')
4385 self.assertEqual(hanat.version, 1)
4386 users = self.vapi.nat44_user_dump()
4387 self.assertEqual(len(users), 1)
4388 self.assertEqual(str(users[0].ip_address),
4389 self.pg0.remote_ip4)
4390 sessions = self.vapi.nat44_user_session_dump(users[0].ip_address,
4392 self.assertEqual(len(sessions), 1)
4393 session = sessions[0]
4394 self.assertEqual(session.total_bytes, 1024)
4395 self.assertEqual(session.total_pkts, 2)
4396 stats = self.statistics.get_counter('/nat44/ha/refresh-event-recv')
4397 self.assertEqual(stats[0][0], 1)
4399 stats = self.statistics.get_err_counter('/err/nat-ha/pkts-processed')
4400 self.assertEqual(stats, 3)
4402 # send packet to test session created by HA
4403 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
4404 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
4405 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out))
4406 self.pg1.add_stream(p)
4407 self.pg_enable_capture(self.pg_interfaces)
4409 capture = self.pg0.get_capture(1)
4415 self.logger.error(ppp("Invalid packet:", p))
4418 self.assertEqual(ip.src, self.pg1.remote_ip4)
4419 self.assertEqual(ip.dst, self.pg0.remote_ip4)
4420 self.assertEqual(tcp.sport, self.tcp_external_port)
4421 self.assertEqual(tcp.dport, self.tcp_port_in)
4424 super(TestNAT44, self).tearDown()
4426 self.vapi.cli("clear logging")
4428 def show_commands_at_teardown(self):
4429 self.logger.info(self.vapi.cli("show nat44 addresses"))
4430 self.logger.info(self.vapi.cli("show nat44 interfaces"))
4431 self.logger.info(self.vapi.cli("show nat44 static mappings"))
4432 self.logger.info(self.vapi.cli("show nat44 interface address"))
4433 self.logger.info(self.vapi.cli("show nat44 sessions detail"))
4434 self.logger.info(self.vapi.cli("show nat virtual-reassembly"))
4435 self.logger.info(self.vapi.cli("show nat44 hash tables detail"))
4436 self.logger.info(self.vapi.cli("show nat timeouts"))
4438 self.vapi.cli("show nat addr-port-assignment-alg"))
4439 self.logger.info(self.vapi.cli("show nat ha"))
4442 class TestNAT44EndpointDependent(MethodHolder):
4443 """ Endpoint-Dependent mapping and filtering test cases """
4446 def setUpConstants(cls):
4447 super(TestNAT44EndpointDependent, cls).setUpConstants()
4448 cls.vpp_cmdline.extend(["nat", "{", "endpoint-dependent", "}"])
4451 def setUpClass(cls):
4452 super(TestNAT44EndpointDependent, cls).setUpClass()
4453 cls.vapi.cli("set log class nat level debug")
4455 cls.tcp_port_in = 6303
4456 cls.tcp_port_out = 6303
4457 cls.udp_port_in = 6304
4458 cls.udp_port_out = 6304
4459 cls.icmp_id_in = 6305
4460 cls.icmp_id_out = 6305
4461 cls.nat_addr = '10.0.0.3'
4462 cls.ipfix_src_port = 4739
4463 cls.ipfix_domain_id = 1
4464 cls.tcp_external_port = 80
4466 cls.create_pg_interfaces(range(7))
4467 cls.interfaces = list(cls.pg_interfaces[0:3])
4469 for i in cls.interfaces:
4474 cls.pg0.generate_remote_hosts(3)
4475 cls.pg0.configure_ipv4_neighbors()
4479 cls.pg4.generate_remote_hosts(2)
4480 cls.pg4.config_ip4()
4481 ip_addr_n = socket.inet_pton(socket.AF_INET, "10.0.0.1")
4482 cls.vapi.sw_interface_add_del_address(
4483 sw_if_index=cls.pg4.sw_if_index, address=ip_addr_n,
4486 cls.pg4.resolve_arp()
4487 cls.pg4._remote_hosts[1]._ip4 = cls.pg4._remote_hosts[0]._ip4
4488 cls.pg4.resolve_arp()
4490 zero_ip4n = socket.inet_pton(socket.AF_INET, "0.0.0.0")
4491 cls.vapi.ip_table_add_del(is_add=1, table_id=1)
4493 cls.pg5._local_ip4 = "10.1.1.1"
4494 cls.pg5._local_ip4n = socket.inet_pton(socket.AF_INET,
4496 cls.pg5._remote_hosts[0]._ip4 = "10.1.1.2"
4497 cls.pg5._remote_hosts[0]._ip4n = socket.inet_pton(
4498 socket.AF_INET, cls.pg5.remote_ip4)
4499 cls.pg5.set_table_ip4(1)
4500 cls.pg5.config_ip4()
4502 cls.vapi.ip_add_del_route(dst_address=cls.pg5.remote_ip4n,
4503 dst_address_length=32,
4504 next_hop_address=zero_ip4n,
4505 next_hop_sw_if_index=cls.pg5.sw_if_index,
4508 cls.pg6._local_ip4 = "10.1.2.1"
4509 cls.pg6._local_ip4n = socket.inet_pton(socket.AF_INET,
4511 cls.pg6._remote_hosts[0]._ip4 = "10.1.2.2"
4512 cls.pg6._remote_hosts[0]._ip4n = socket.inet_pton(
4513 socket.AF_INET, cls.pg6.remote_ip4)
4514 cls.pg6.set_table_ip4(1)
4515 cls.pg6.config_ip4()
4517 cls.vapi.ip_add_del_route(dst_address=cls.pg6.remote_ip4n,
4518 dst_address_length=32,
4519 next_hop_address=zero_ip4n,
4520 next_hop_sw_if_index=cls.pg6.sw_if_index,
4523 cls.vapi.ip_add_del_route(dst_address=cls.pg6.remote_ip4n,
4524 dst_address_length=16,
4525 next_hop_address=zero_ip4n, table_id=0,
4526 next_hop_table_id=1)
4527 cls.vapi.ip_add_del_route(dst_address=zero_ip4n,
4528 dst_address_length=0,
4529 next_hop_address=zero_ip4n, table_id=1,
4530 next_hop_table_id=0)
4531 cls.vapi.ip_add_del_route(dst_address=zero_ip4n,
4532 dst_address_length=0,
4533 next_hop_address=cls.pg1.local_ip4n,
4534 next_hop_sw_if_index=cls.pg1.sw_if_index,
4537 cls.pg5.resolve_arp()
4538 cls.pg6.resolve_arp()
4541 super(TestNAT44EndpointDependent, cls).tearDownClass()
4545 def tearDownClass(cls):
4546 super(TestNAT44EndpointDependent, cls).tearDownClass()
4548 def test_frag_in_order(self):
4549 """ NAT44 translate fragments arriving in order """
4550 self.nat44_add_address(self.nat_addr)
4551 flags = self.config_flags.NAT_IS_INSIDE
4552 self.vapi.nat44_interface_add_del_feature(
4553 sw_if_index=self.pg0.sw_if_index,
4554 flags=flags, is_add=1)
4555 self.vapi.nat44_interface_add_del_feature(
4556 sw_if_index=self.pg1.sw_if_index,
4558 self.frag_in_order(proto=IP_PROTOS.tcp)
4559 self.frag_in_order(proto=IP_PROTOS.udp)
4560 self.frag_in_order(proto=IP_PROTOS.icmp)
4562 def test_frag_in_order_dont_translate(self):
4563 """ NAT44 don't translate fragments arriving in order """
4564 flags = self.config_flags.NAT_IS_INSIDE
4565 self.vapi.nat44_interface_add_del_feature(
4566 sw_if_index=self.pg0.sw_if_index,
4567 flags=flags, is_add=1)
4568 self.vapi.nat44_interface_add_del_feature(
4569 sw_if_index=self.pg1.sw_if_index,
4571 self.vapi.nat44_forwarding_enable_disable(enable=True)
4572 self.frag_in_order(proto=IP_PROTOS.tcp, dont_translate=True)
4574 def test_frag_out_of_order(self):
4575 """ NAT44 translate fragments arriving out of order """
4576 self.nat44_add_address(self.nat_addr)
4577 flags = self.config_flags.NAT_IS_INSIDE
4578 self.vapi.nat44_interface_add_del_feature(
4579 sw_if_index=self.pg0.sw_if_index,
4580 flags=flags, is_add=1)
4581 self.vapi.nat44_interface_add_del_feature(
4582 sw_if_index=self.pg1.sw_if_index,
4584 self.frag_out_of_order(proto=IP_PROTOS.tcp)
4585 self.frag_out_of_order(proto=IP_PROTOS.udp)
4586 self.frag_out_of_order(proto=IP_PROTOS.icmp)
4588 def test_frag_out_of_order_dont_translate(self):
4589 """ NAT44 don't translate fragments arriving out of order """
4590 flags = self.config_flags.NAT_IS_INSIDE
4591 self.vapi.nat44_interface_add_del_feature(
4592 sw_if_index=self.pg0.sw_if_index,
4593 flags=flags, is_add=1)
4594 self.vapi.nat44_interface_add_del_feature(
4595 sw_if_index=self.pg1.sw_if_index,
4597 self.vapi.nat44_forwarding_enable_disable(enable=True)
4598 self.frag_out_of_order(proto=IP_PROTOS.tcp, dont_translate=True)
4600 def test_frag_in_order_in_plus_out(self):
4601 """ in+out interface fragments in order """
4602 flags = self.config_flags.NAT_IS_INSIDE
4603 self.vapi.nat44_interface_add_del_feature(
4604 sw_if_index=self.pg0.sw_if_index,
4606 self.vapi.nat44_interface_add_del_feature(
4607 sw_if_index=self.pg0.sw_if_index,
4608 flags=flags, is_add=1)
4609 self.vapi.nat44_interface_add_del_feature(
4610 sw_if_index=self.pg1.sw_if_index,
4612 self.vapi.nat44_interface_add_del_feature(
4613 sw_if_index=self.pg1.sw_if_index,
4614 flags=flags, is_add=1)
4616 self.server = self.pg1.remote_hosts[0]
4618 self.server_in_addr = self.server.ip4
4619 self.server_out_addr = '11.11.11.11'
4620 self.server_in_port = random.randint(1025, 65535)
4621 self.server_out_port = random.randint(1025, 65535)
4623 self.nat44_add_address(self.server_out_addr)
4625 # add static mappings for server
4626 self.nat44_add_static_mapping(self.server_in_addr,
4627 self.server_out_addr,
4628 self.server_in_port,
4629 self.server_out_port,
4630 proto=IP_PROTOS.tcp)
4631 self.nat44_add_static_mapping(self.server_in_addr,
4632 self.server_out_addr,
4633 self.server_in_port,
4634 self.server_out_port,
4635 proto=IP_PROTOS.udp)
4636 self.nat44_add_static_mapping(self.server_in_addr,
4637 self.server_out_addr,
4638 proto=IP_PROTOS.icmp)
4640 self.vapi.nat_set_reass(timeout=10, max_reass=1024, max_frag=5,
4643 self.frag_in_order_in_plus_out(proto=IP_PROTOS.tcp)
4644 self.frag_in_order_in_plus_out(proto=IP_PROTOS.udp)
4645 self.frag_in_order_in_plus_out(proto=IP_PROTOS.icmp)
4647 def test_frag_out_of_order_in_plus_out(self):
4648 """ in+out interface fragments out of order """
4649 flags = self.config_flags.NAT_IS_INSIDE
4650 self.vapi.nat44_interface_add_del_feature(
4651 sw_if_index=self.pg0.sw_if_index,
4653 self.vapi.nat44_interface_add_del_feature(
4654 sw_if_index=self.pg0.sw_if_index,
4655 flags=flags, is_add=1)
4656 self.vapi.nat44_interface_add_del_feature(
4657 sw_if_index=self.pg1.sw_if_index,
4659 self.vapi.nat44_interface_add_del_feature(
4660 sw_if_index=self.pg1.sw_if_index,
4661 flags=flags, is_add=1)
4663 self.server = self.pg1.remote_hosts[0]
4665 self.server_in_addr = self.server.ip4
4666 self.server_out_addr = '11.11.11.11'
4667 self.server_in_port = random.randint(1025, 65535)
4668 self.server_out_port = random.randint(1025, 65535)
4670 self.nat44_add_address(self.server_out_addr)
4672 # add static mappings for server
4673 self.nat44_add_static_mapping(self.server_in_addr,
4674 self.server_out_addr,
4675 self.server_in_port,
4676 self.server_out_port,
4677 proto=IP_PROTOS.tcp)
4678 self.nat44_add_static_mapping(self.server_in_addr,
4679 self.server_out_addr,
4680 self.server_in_port,
4681 self.server_out_port,
4682 proto=IP_PROTOS.udp)
4683 self.nat44_add_static_mapping(self.server_in_addr,
4684 self.server_out_addr,
4685 proto=IP_PROTOS.icmp)
4687 self.vapi.nat_set_reass(timeout=10, max_reass=1024, max_frag=5,
4690 self.frag_out_of_order_in_plus_out(proto=IP_PROTOS.tcp)
4691 self.frag_out_of_order_in_plus_out(proto=IP_PROTOS.udp)
4692 self.frag_out_of_order_in_plus_out(proto=IP_PROTOS.icmp)
4694 def test_reass_hairpinning(self):
4695 """ NAT44 fragments hairpinning """
4696 self.server = self.pg0.remote_hosts[1]
4697 self.host_in_port = random.randint(1025, 65535)
4698 self.server_in_port = random.randint(1025, 65535)
4699 self.server_out_port = random.randint(1025, 65535)
4701 self.nat44_add_address(self.nat_addr)
4702 flags = self.config_flags.NAT_IS_INSIDE
4703 self.vapi.nat44_interface_add_del_feature(
4704 sw_if_index=self.pg0.sw_if_index,
4705 flags=flags, is_add=1)
4706 self.vapi.nat44_interface_add_del_feature(
4707 sw_if_index=self.pg1.sw_if_index,
4709 # add static mapping for server
4710 self.nat44_add_static_mapping(self.server.ip4, self.nat_addr,
4711 self.server_in_port,
4712 self.server_out_port,
4713 proto=IP_PROTOS.tcp)
4714 self.nat44_add_static_mapping(self.server.ip4, self.nat_addr,
4715 self.server_in_port,
4716 self.server_out_port,
4717 proto=IP_PROTOS.udp)
4718 self.nat44_add_static_mapping(self.server.ip4, self.nat_addr)
4720 self.reass_hairpinning(proto=IP_PROTOS.tcp)
4721 self.reass_hairpinning(proto=IP_PROTOS.udp)
4722 self.reass_hairpinning(proto=IP_PROTOS.icmp)
4724 def test_dynamic(self):
4725 """ NAT44 dynamic translation test """
4727 self.nat44_add_address(self.nat_addr)
4728 flags = self.config_flags.NAT_IS_INSIDE
4729 self.vapi.nat44_interface_add_del_feature(
4730 sw_if_index=self.pg0.sw_if_index,
4731 flags=flags, is_add=1)
4732 self.vapi.nat44_interface_add_del_feature(
4733 sw_if_index=self.pg1.sw_if_index,
4736 nat_config = self.vapi.nat_show_config()
4737 self.assertEqual(1, nat_config.endpoint_dependent)
4740 tcpn = self.statistics.get_err_counter(
4741 '/err/nat44-ed-in2out-slowpath/TCP packets')
4742 udpn = self.statistics.get_err_counter(
4743 '/err/nat44-ed-in2out-slowpath/UDP packets')
4744 icmpn = self.statistics.get_err_counter(
4745 '/err/nat44-ed-in2out-slowpath/ICMP packets')
4746 totaln = self.statistics.get_err_counter(
4747 '/err/nat44-ed-in2out-slowpath/good in2out packets processed')
4749 pkts = self.create_stream_in(self.pg0, self.pg1)
4750 self.pg0.add_stream(pkts)
4751 self.pg_enable_capture(self.pg_interfaces)
4753 capture = self.pg1.get_capture(len(pkts))
4754 self.verify_capture_out(capture)
4756 err = self.statistics.get_err_counter(
4757 '/err/nat44-ed-in2out-slowpath/TCP packets')
4758 self.assertEqual(err - tcpn, 1)
4759 err = self.statistics.get_err_counter(
4760 '/err/nat44-ed-in2out-slowpath/UDP packets')
4761 self.assertEqual(err - udpn, 1)
4762 err = self.statistics.get_err_counter(
4763 '/err/nat44-ed-in2out-slowpath/ICMP packets')
4764 self.assertEqual(err - icmpn, 1)
4765 err = self.statistics.get_err_counter(
4766 '/err/nat44-ed-in2out-slowpath/good in2out packets processed')
4767 self.assertEqual(err - totaln, 3)
4770 tcpn = self.statistics.get_err_counter(
4771 '/err/nat44-ed-out2in/TCP packets')
4772 udpn = self.statistics.get_err_counter(
4773 '/err/nat44-ed-out2in/UDP packets')
4774 icmpn = self.statistics.get_err_counter(
4775 '/err/nat44-ed-out2in-slowpath/ICMP packets')
4776 totaln = self.statistics.get_err_counter(
4777 '/err/nat44-ed-out2in/good out2in packets processed')
4779 pkts = self.create_stream_out(self.pg1)
4780 self.pg1.add_stream(pkts)
4781 self.pg_enable_capture(self.pg_interfaces)
4783 capture = self.pg0.get_capture(len(pkts))
4784 self.verify_capture_in(capture, self.pg0)
4786 err = self.statistics.get_err_counter(
4787 '/err/nat44-ed-out2in/TCP packets')
4788 self.assertEqual(err - tcpn, 1)
4789 err = self.statistics.get_err_counter(
4790 '/err/nat44-ed-out2in/UDP packets')
4791 self.assertEqual(err - udpn, 1)
4792 err = self.statistics.get_err_counter(
4793 '/err/nat44-ed-out2in-slowpath/ICMP packets')
4794 self.assertEqual(err - icmpn, 1)
4795 err = self.statistics.get_err_counter(
4796 '/err/nat44-ed-out2in/good out2in packets processed')
4797 self.assertEqual(err - totaln, 2)
4799 users = self.statistics.get_counter('/nat44/total-users')
4800 self.assertEqual(users[0][0], 1)
4801 sessions = self.statistics.get_counter('/nat44/total-sessions')
4802 self.assertEqual(sessions[0][0], 3)
4804 def test_forwarding(self):
4805 """ NAT44 forwarding test """
4807 flags = self.config_flags.NAT_IS_INSIDE
4808 self.vapi.nat44_interface_add_del_feature(
4809 sw_if_index=self.pg0.sw_if_index,
4810 flags=flags, is_add=1)
4811 self.vapi.nat44_interface_add_del_feature(
4812 sw_if_index=self.pg1.sw_if_index,
4814 self.vapi.nat44_forwarding_enable_disable(enable=1)
4816 real_ip = self.pg0.remote_ip4
4817 alias_ip = self.nat_addr
4818 flags = self.config_flags.NAT_IS_ADDR_ONLY
4819 self.vapi.nat44_add_del_static_mapping(is_add=1,
4820 local_ip_address=real_ip,
4821 external_ip_address=alias_ip,
4822 external_sw_if_index=0xFFFFFFFF,
4826 # in2out - static mapping match
4828 pkts = self.create_stream_out(self.pg1)
4829 self.pg1.add_stream(pkts)
4830 self.pg_enable_capture(self.pg_interfaces)
4832 capture = self.pg0.get_capture(len(pkts))
4833 self.verify_capture_in(capture, self.pg0)
4835 pkts = self.create_stream_in(self.pg0, self.pg1)
4836 self.pg0.add_stream(pkts)
4837 self.pg_enable_capture(self.pg_interfaces)
4839 capture = self.pg1.get_capture(len(pkts))
4840 self.verify_capture_out(capture, same_port=True)
4842 # in2out - no static mapping match
4844 host0 = self.pg0.remote_hosts[0]
4845 self.pg0.remote_hosts[0] = self.pg0.remote_hosts[1]
4847 pkts = self.create_stream_out(self.pg1,
4848 dst_ip=self.pg0.remote_ip4,
4849 use_inside_ports=True)
4850 self.pg1.add_stream(pkts)
4851 self.pg_enable_capture(self.pg_interfaces)
4853 capture = self.pg0.get_capture(len(pkts))
4854 self.verify_capture_in(capture, self.pg0)
4856 pkts = self.create_stream_in(self.pg0, self.pg1)
4857 self.pg0.add_stream(pkts)
4858 self.pg_enable_capture(self.pg_interfaces)
4860 capture = self.pg1.get_capture(len(pkts))
4861 self.verify_capture_out(capture, nat_ip=self.pg0.remote_ip4,
4864 self.pg0.remote_hosts[0] = host0
4866 user = self.pg0.remote_hosts[1]
4867 sessions = self.vapi.nat44_user_session_dump(user.ip4n, 0)
4868 self.assertEqual(len(sessions), 3)
4869 self.assertTrue(sessions[0].flags &
4870 self.config_flags.NAT_IS_EXT_HOST_VALID)
4871 self.vapi.nat44_del_session(
4872 address=sessions[0].inside_ip_address,
4873 port=sessions[0].inside_port,
4874 protocol=sessions[0].protocol,
4875 flags=(self.config_flags.NAT_IS_INSIDE |
4876 self.config_flags.NAT_IS_EXT_HOST_VALID),
4877 ext_host_address=sessions[0].ext_host_address,
4878 ext_host_port=sessions[0].ext_host_port)
4879 sessions = self.vapi.nat44_user_session_dump(user.ip4n, 0)
4880 self.assertEqual(len(sessions), 2)
4883 self.vapi.nat44_forwarding_enable_disable(enable=0)
4884 flags = self.config_flags.NAT_IS_ADDR_ONLY
4885 self.vapi.nat44_add_del_static_mapping(
4887 local_ip_address=real_ip,
4888 external_ip_address=alias_ip,
4889 external_sw_if_index=0xFFFFFFFF,
4892 def test_static_lb(self):
4893 """ NAT44 local service load balancing """
4894 external_addr_n = self.nat_addr
4897 server1 = self.pg0.remote_hosts[0]
4898 server2 = self.pg0.remote_hosts[1]
4900 locals = [{'addr': server1.ip4n,
4904 {'addr': server2.ip4n,
4909 self.nat44_add_address(self.nat_addr)
4910 self.vapi.nat44_add_del_lb_static_mapping(
4912 external_addr=external_addr_n,
4913 external_port=external_port,
4914 protocol=IP_PROTOS.tcp,
4915 local_num=len(locals),
4917 flags = self.config_flags.NAT_IS_INSIDE
4918 self.vapi.nat44_interface_add_del_feature(
4919 sw_if_index=self.pg0.sw_if_index,
4920 flags=flags, is_add=1)
4921 self.vapi.nat44_interface_add_del_feature(
4922 sw_if_index=self.pg1.sw_if_index,
4925 # from client to service
4926 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
4927 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
4928 TCP(sport=12345, dport=external_port))
4929 self.pg1.add_stream(p)
4930 self.pg_enable_capture(self.pg_interfaces)
4932 capture = self.pg0.get_capture(1)
4938 self.assertIn(ip.dst, [server1.ip4, server2.ip4])
4939 if ip.dst == server1.ip4:
4943 self.assertEqual(tcp.dport, local_port)
4944 self.assert_packet_checksums_valid(p)
4946 self.logger.error(ppp("Unexpected or invalid packet:", p))
4949 # from service back to client
4950 p = (Ether(src=server.mac, dst=self.pg0.local_mac) /
4951 IP(src=server.ip4, dst=self.pg1.remote_ip4) /
4952 TCP(sport=local_port, dport=12345))
4953 self.pg0.add_stream(p)
4954 self.pg_enable_capture(self.pg_interfaces)
4956 capture = self.pg1.get_capture(1)
4961 self.assertEqual(ip.src, self.nat_addr)
4962 self.assertEqual(tcp.sport, external_port)
4963 self.assert_packet_checksums_valid(p)
4965 self.logger.error(ppp("Unexpected or invalid packet:", p))
4968 sessions = self.vapi.nat44_user_session_dump(server.ip4n, 0)
4969 self.assertEqual(len(sessions), 1)
4970 self.assertTrue(sessions[0].flags &
4971 self.config_flags.NAT_IS_EXT_HOST_VALID)
4972 self.vapi.nat44_del_session(
4973 address=sessions[0].inside_ip_address,
4974 port=sessions[0].inside_port,
4975 protocol=sessions[0].protocol,
4976 flags=(self.config_flags.NAT_IS_INSIDE |
4977 self.config_flags.NAT_IS_EXT_HOST_VALID),
4978 ext_host_address=sessions[0].ext_host_address,
4979 ext_host_port=sessions[0].ext_host_port)
4980 sessions = self.vapi.nat44_user_session_dump(server.ip4n, 0)
4981 self.assertEqual(len(sessions), 0)
4983 @unittest.skipUnless(running_extended_tests, "part of extended tests")
4984 def test_static_lb_multi_clients(self):
4985 """ NAT44 local service load balancing - multiple clients"""
4987 external_addr = self.nat_addr
4990 server1 = self.pg0.remote_hosts[0]
4991 server2 = self.pg0.remote_hosts[1]
4992 server3 = self.pg0.remote_hosts[2]
4994 locals = [{'addr': server1.ip4n,
4998 {'addr': server2.ip4n,
5003 self.nat44_add_address(self.nat_addr)
5004 self.vapi.nat44_add_del_lb_static_mapping(is_add=1,
5005 external_addr=external_addr,
5006 external_port=external_port,
5007 protocol=IP_PROTOS.tcp,
5008 local_num=len(locals),
5010 flags = self.config_flags.NAT_IS_INSIDE
5011 self.vapi.nat44_interface_add_del_feature(
5012 sw_if_index=self.pg0.sw_if_index,
5013 flags=flags, is_add=1)
5014 self.vapi.nat44_interface_add_del_feature(
5015 sw_if_index=self.pg1.sw_if_index,
5020 clients = ip4_range(self.pg1.remote_ip4, 10, 50)
5022 for client in clients:
5023 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
5024 IP(src=client, dst=self.nat_addr) /
5025 TCP(sport=12345, dport=external_port))
5027 self.pg1.add_stream(pkts)
5028 self.pg_enable_capture(self.pg_interfaces)
5030 capture = self.pg0.get_capture(len(pkts))
5032 if p[IP].dst == server1.ip4:
5036 self.assertGreater(server1_n, server2_n)
5039 'addr': server3.ip4n,
5046 self.vapi.nat44_lb_static_mapping_add_del_local(
5048 external_addr=external_addr,
5049 external_port=external_port,
5051 protocol=IP_PROTOS.tcp)
5055 clients = ip4_range(self.pg1.remote_ip4, 60, 110)
5057 for client in clients:
5058 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
5059 IP(src=client, dst=self.nat_addr) /
5060 TCP(sport=12346, dport=external_port))
5062 self.assertGreater(len(pkts), 0)
5063 self.pg1.add_stream(pkts)
5064 self.pg_enable_capture(self.pg_interfaces)
5066 capture = self.pg0.get_capture(len(pkts))
5068 if p[IP].dst == server1.ip4:
5070 elif p[IP].dst == server2.ip4:
5074 self.assertGreater(server1_n, 0)
5075 self.assertGreater(server2_n, 0)
5076 self.assertGreater(server3_n, 0)
5079 'addr': server2.ip4n,
5085 # remove one back-end
5086 self.vapi.nat44_lb_static_mapping_add_del_local(
5088 external_addr=external_addr,
5089 external_port=external_port,
5091 protocol=IP_PROTOS.tcp)
5095 self.pg1.add_stream(pkts)
5096 self.pg_enable_capture(self.pg_interfaces)
5098 capture = self.pg0.get_capture(len(pkts))
5100 if p[IP].dst == server1.ip4:
5102 elif p[IP].dst == server2.ip4:
5106 self.assertGreater(server1_n, 0)
5107 self.assertEqual(server2_n, 0)
5108 self.assertGreater(server3_n, 0)
5110 def test_static_lb_2(self):
5111 """ NAT44 local service load balancing (asymmetrical rule) """
5112 external_addr = self.nat_addr
5115 server1 = self.pg0.remote_hosts[0]
5116 server2 = self.pg0.remote_hosts[1]
5118 locals = [{'addr': server1.ip4n,
5122 {'addr': server2.ip4n,
5127 self.vapi.nat44_forwarding_enable_disable(enable=1)
5128 flags = self.config_flags.NAT_IS_OUT2IN_ONLY
5129 self.vapi.nat44_add_del_lb_static_mapping(is_add=1, flags=flags,
5130 external_addr=external_addr,
5131 external_port=external_port,
5132 protocol=IP_PROTOS.tcp,
5133 local_num=len(locals),
5135 flags = self.config_flags.NAT_IS_INSIDE
5136 self.vapi.nat44_interface_add_del_feature(
5137 sw_if_index=self.pg0.sw_if_index,
5138 flags=flags, is_add=1)
5139 self.vapi.nat44_interface_add_del_feature(
5140 sw_if_index=self.pg1.sw_if_index,
5143 # from client to service
5144 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
5145 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
5146 TCP(sport=12345, dport=external_port))
5147 self.pg1.add_stream(p)
5148 self.pg_enable_capture(self.pg_interfaces)
5150 capture = self.pg0.get_capture(1)
5156 self.assertIn(ip.dst, [server1.ip4, server2.ip4])
5157 if ip.dst == server1.ip4:
5161 self.assertEqual(tcp.dport, local_port)
5162 self.assert_packet_checksums_valid(p)
5164 self.logger.error(ppp("Unexpected or invalid packet:", p))
5167 # from service back to client
5168 p = (Ether(src=server.mac, dst=self.pg0.local_mac) /
5169 IP(src=server.ip4, dst=self.pg1.remote_ip4) /
5170 TCP(sport=local_port, dport=12345))
5171 self.pg0.add_stream(p)
5172 self.pg_enable_capture(self.pg_interfaces)
5174 capture = self.pg1.get_capture(1)
5179 self.assertEqual(ip.src, self.nat_addr)
5180 self.assertEqual(tcp.sport, external_port)
5181 self.assert_packet_checksums_valid(p)
5183 self.logger.error(ppp("Unexpected or invalid packet:", p))
5186 # from client to server (no translation)
5187 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
5188 IP(src=self.pg1.remote_ip4, dst=server1.ip4) /
5189 TCP(sport=12346, dport=local_port))
5190 self.pg1.add_stream(p)
5191 self.pg_enable_capture(self.pg_interfaces)
5193 capture = self.pg0.get_capture(1)
5199 self.assertEqual(ip.dst, server1.ip4)
5200 self.assertEqual(tcp.dport, local_port)
5201 self.assert_packet_checksums_valid(p)
5203 self.logger.error(ppp("Unexpected or invalid packet:", p))
5206 # from service back to client (no translation)
5207 p = (Ether(src=server1.mac, dst=self.pg0.local_mac) /
5208 IP(src=server1.ip4, dst=self.pg1.remote_ip4) /
5209 TCP(sport=local_port, dport=12346))
5210 self.pg0.add_stream(p)
5211 self.pg_enable_capture(self.pg_interfaces)
5213 capture = self.pg1.get_capture(1)
5218 self.assertEqual(ip.src, server1.ip4)
5219 self.assertEqual(tcp.sport, local_port)
5220 self.assert_packet_checksums_valid(p)
5222 self.logger.error(ppp("Unexpected or invalid packet:", p))
5225 def test_lb_affinity(self):
5226 """ NAT44 local service load balancing affinity """
5227 external_addr = self.nat_addr
5230 server1 = self.pg0.remote_hosts[0]
5231 server2 = self.pg0.remote_hosts[1]
5233 locals = [{'addr': server1.ip4n,
5237 {'addr': server2.ip4n,
5242 self.nat44_add_address(self.nat_addr)
5243 self.vapi.nat44_add_del_lb_static_mapping(is_add=1,
5244 external_addr=external_addr,
5245 external_port=external_port,
5246 protocol=IP_PROTOS.tcp,
5248 local_num=len(locals),
5250 flags = self.config_flags.NAT_IS_INSIDE
5251 self.vapi.nat44_interface_add_del_feature(
5252 sw_if_index=self.pg0.sw_if_index,
5253 flags=flags, is_add=1)
5254 self.vapi.nat44_interface_add_del_feature(
5255 sw_if_index=self.pg1.sw_if_index,
5258 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
5259 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
5260 TCP(sport=1025, dport=external_port))
5261 self.pg1.add_stream(p)
5262 self.pg_enable_capture(self.pg_interfaces)
5264 capture = self.pg0.get_capture(1)
5265 backend = capture[0][IP].dst
5267 sessions = self.vapi.nat44_user_session_dump(backend, 0)
5268 self.assertEqual(len(sessions), 1)
5269 self.assertTrue(sessions[0].flags &
5270 self.config_flags.NAT_IS_EXT_HOST_VALID)
5271 self.vapi.nat44_del_session(
5272 address=sessions[0].inside_ip_address,
5273 port=sessions[0].inside_port,
5274 protocol=sessions[0].protocol,
5275 flags=(self.config_flags.NAT_IS_INSIDE |
5276 self.config_flags.NAT_IS_EXT_HOST_VALID),
5277 ext_host_address=sessions[0].ext_host_address,
5278 ext_host_port=sessions[0].ext_host_port)
5281 for port in range(1030, 1100):
5282 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
5283 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
5284 TCP(sport=port, dport=external_port))
5286 self.pg1.add_stream(pkts)
5287 self.pg_enable_capture(self.pg_interfaces)
5289 capture = self.pg0.get_capture(len(pkts))
5291 self.assertEqual(p[IP].dst, backend)
5293 def test_unknown_proto(self):
5294 """ NAT44 translate packet with unknown protocol """
5295 self.nat44_add_address(self.nat_addr)
5296 flags = self.config_flags.NAT_IS_INSIDE
5297 self.vapi.nat44_interface_add_del_feature(
5298 sw_if_index=self.pg0.sw_if_index,
5299 flags=flags, is_add=1)
5300 self.vapi.nat44_interface_add_del_feature(
5301 sw_if_index=self.pg1.sw_if_index,
5305 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
5306 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
5307 TCP(sport=self.tcp_port_in, dport=20))
5308 self.pg0.add_stream(p)
5309 self.pg_enable_capture(self.pg_interfaces)
5311 p = self.pg1.get_capture(1)
5313 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
5314 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
5316 IP(src=self.pg2.remote_ip4, dst=self.pg2.remote_ip4) /
5317 TCP(sport=1234, dport=1234))
5318 self.pg0.add_stream(p)
5319 self.pg_enable_capture(self.pg_interfaces)
5321 p = self.pg1.get_capture(1)
5324 self.assertEqual(packet[IP].src, self.nat_addr)
5325 self.assertEqual(packet[IP].dst, self.pg1.remote_ip4)
5326 self.assertEqual(packet.haslayer(GRE), 1)
5327 self.assert_packet_checksums_valid(packet)
5329 self.logger.error(ppp("Unexpected or invalid packet:", packet))
5333 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
5334 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
5336 IP(src=self.pg2.remote_ip4, dst=self.pg2.remote_ip4) /
5337 TCP(sport=1234, dport=1234))
5338 self.pg1.add_stream(p)
5339 self.pg_enable_capture(self.pg_interfaces)
5341 p = self.pg0.get_capture(1)
5344 self.assertEqual(packet[IP].src, self.pg1.remote_ip4)
5345 self.assertEqual(packet[IP].dst, self.pg0.remote_ip4)
5346 self.assertEqual(packet.haslayer(GRE), 1)
5347 self.assert_packet_checksums_valid(packet)
5349 self.logger.error(ppp("Unexpected or invalid packet:", packet))
5352 def test_hairpinning_unknown_proto(self):
5353 """ NAT44 translate packet with unknown protocol - hairpinning """
5354 host = self.pg0.remote_hosts[0]
5355 server = self.pg0.remote_hosts[1]
5357 server_out_port = 8765
5358 server_nat_ip = "10.0.0.11"
5360 self.nat44_add_address(self.nat_addr)
5361 flags = self.config_flags.NAT_IS_INSIDE
5362 self.vapi.nat44_interface_add_del_feature(
5363 sw_if_index=self.pg0.sw_if_index,
5364 flags=flags, is_add=1)
5365 self.vapi.nat44_interface_add_del_feature(
5366 sw_if_index=self.pg1.sw_if_index,
5369 # add static mapping for server
5370 self.nat44_add_static_mapping(server.ip4, server_nat_ip)
5373 p = (Ether(src=host.mac, dst=self.pg0.local_mac) /
5374 IP(src=host.ip4, dst=server_nat_ip) /
5375 TCP(sport=host_in_port, dport=server_out_port))
5376 self.pg0.add_stream(p)
5377 self.pg_enable_capture(self.pg_interfaces)
5379 self.pg0.get_capture(1)
5381 p = (Ether(dst=self.pg0.local_mac, src=host.mac) /
5382 IP(src=host.ip4, dst=server_nat_ip) /
5384 IP(src=self.pg2.remote_ip4, dst=self.pg2.remote_ip4) /
5385 TCP(sport=1234, dport=1234))
5386 self.pg0.add_stream(p)
5387 self.pg_enable_capture(self.pg_interfaces)
5389 p = self.pg0.get_capture(1)
5392 self.assertEqual(packet[IP].src, self.nat_addr)
5393 self.assertEqual(packet[IP].dst, server.ip4)
5394 self.assertEqual(packet.haslayer(GRE), 1)
5395 self.assert_packet_checksums_valid(packet)
5397 self.logger.error(ppp("Unexpected or invalid packet:", packet))
5401 p = (Ether(dst=self.pg0.local_mac, src=server.mac) /
5402 IP(src=server.ip4, dst=self.nat_addr) /
5404 IP(src=self.pg2.remote_ip4, dst=self.pg2.remote_ip4) /
5405 TCP(sport=1234, dport=1234))
5406 self.pg0.add_stream(p)
5407 self.pg_enable_capture(self.pg_interfaces)
5409 p = self.pg0.get_capture(1)
5412 self.assertEqual(packet[IP].src, server_nat_ip)
5413 self.assertEqual(packet[IP].dst, host.ip4)
5414 self.assertEqual(packet.haslayer(GRE), 1)
5415 self.assert_packet_checksums_valid(packet)
5417 self.logger.error(ppp("Unexpected or invalid packet:", packet))
5420 def test_output_feature_and_service(self):
5421 """ NAT44 interface output feature and services """
5422 external_addr = '1.2.3.4'
5426 self.vapi.nat44_forwarding_enable_disable(enable=1)
5427 self.nat44_add_address(self.nat_addr)
5428 flags = self.config_flags.NAT_IS_ADDR_ONLY
5429 self.vapi.nat44_add_del_identity_mapping(
5430 ip_address=self.pg1.remote_ip4n, sw_if_index=0xFFFFFFFF,
5431 flags=flags, is_add=1)
5432 flags = self.config_flags.NAT_IS_OUT2IN_ONLY
5433 self.nat44_add_static_mapping(self.pg0.remote_ip4, external_addr,
5434 local_port, external_port,
5435 proto=IP_PROTOS.tcp, flags=flags)
5436 flags = self.config_flags.NAT_IS_INSIDE
5437 self.vapi.nat44_interface_add_del_feature(
5438 sw_if_index=self.pg0.sw_if_index,
5440 self.vapi.nat44_interface_add_del_feature(
5441 sw_if_index=self.pg0.sw_if_index,
5442 flags=flags, is_add=1)
5443 self.vapi.nat44_interface_add_del_output_feature(
5445 sw_if_index=self.pg1.sw_if_index)
5447 # from client to service
5448 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
5449 IP(src=self.pg1.remote_ip4, dst=external_addr) /
5450 TCP(sport=12345, dport=external_port))
5451 self.pg1.add_stream(p)
5452 self.pg_enable_capture(self.pg_interfaces)
5454 capture = self.pg0.get_capture(1)
5459 self.assertEqual(ip.dst, self.pg0.remote_ip4)
5460 self.assertEqual(tcp.dport, local_port)
5461 self.assert_packet_checksums_valid(p)
5463 self.logger.error(ppp("Unexpected or invalid packet:", p))
5466 # from service back to client
5467 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5468 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
5469 TCP(sport=local_port, dport=12345))
5470 self.pg0.add_stream(p)
5471 self.pg_enable_capture(self.pg_interfaces)
5473 capture = self.pg1.get_capture(1)
5478 self.assertEqual(ip.src, external_addr)
5479 self.assertEqual(tcp.sport, external_port)
5480 self.assert_packet_checksums_valid(p)
5482 self.logger.error(ppp("Unexpected or invalid packet:", p))
5485 # from local network host to external network
5486 pkts = self.create_stream_in(self.pg0, self.pg1)
5487 self.pg0.add_stream(pkts)
5488 self.pg_enable_capture(self.pg_interfaces)
5490 capture = self.pg1.get_capture(len(pkts))
5491 self.verify_capture_out(capture)
5492 pkts = self.create_stream_in(self.pg0, self.pg1)
5493 self.pg0.add_stream(pkts)
5494 self.pg_enable_capture(self.pg_interfaces)
5496 capture = self.pg1.get_capture(len(pkts))
5497 self.verify_capture_out(capture)
5499 # from external network back to local network host
5500 pkts = self.create_stream_out(self.pg1)
5501 self.pg1.add_stream(pkts)
5502 self.pg_enable_capture(self.pg_interfaces)
5504 capture = self.pg0.get_capture(len(pkts))
5505 self.verify_capture_in(capture, self.pg0)
5507 def test_output_feature_and_service2(self):
5508 """ NAT44 interface output feature and service host direct access """
5509 self.vapi.nat44_forwarding_enable_disable(enable=1)
5510 self.nat44_add_address(self.nat_addr)
5511 self.vapi.nat44_interface_add_del_output_feature(
5513 sw_if_index=self.pg1.sw_if_index)
5515 # session initiated from service host - translate
5516 pkts = self.create_stream_in(self.pg0, self.pg1)
5517 self.pg0.add_stream(pkts)
5518 self.pg_enable_capture(self.pg_interfaces)
5520 capture = self.pg1.get_capture(len(pkts))
5521 self.verify_capture_out(capture)
5523 pkts = self.create_stream_out(self.pg1)
5524 self.pg1.add_stream(pkts)
5525 self.pg_enable_capture(self.pg_interfaces)
5527 capture = self.pg0.get_capture(len(pkts))
5528 self.verify_capture_in(capture, self.pg0)
5530 # session initiated from remote host - do not translate
5531 self.tcp_port_in = 60303
5532 self.udp_port_in = 60304
5533 self.icmp_id_in = 60305
5534 pkts = self.create_stream_out(self.pg1,
5535 self.pg0.remote_ip4,
5536 use_inside_ports=True)
5537 self.pg1.add_stream(pkts)
5538 self.pg_enable_capture(self.pg_interfaces)
5540 capture = self.pg0.get_capture(len(pkts))
5541 self.verify_capture_in(capture, self.pg0)
5543 pkts = self.create_stream_in(self.pg0, self.pg1)
5544 self.pg0.add_stream(pkts)
5545 self.pg_enable_capture(self.pg_interfaces)
5547 capture = self.pg1.get_capture(len(pkts))
5548 self.verify_capture_out(capture, nat_ip=self.pg0.remote_ip4,
5551 def test_output_feature_and_service3(self):
5552 """ NAT44 interface output feature and DST NAT """
5553 external_addr = '1.2.3.4'
5557 self.vapi.nat44_forwarding_enable_disable(enable=1)
5558 self.nat44_add_address(self.nat_addr)
5559 flags = self.config_flags.NAT_IS_OUT2IN_ONLY
5560 self.nat44_add_static_mapping(self.pg1.remote_ip4, external_addr,
5561 local_port, external_port,
5562 proto=IP_PROTOS.tcp, flags=flags)
5563 flags = self.config_flags.NAT_IS_INSIDE
5564 self.vapi.nat44_interface_add_del_feature(
5565 sw_if_index=self.pg0.sw_if_index,
5567 self.vapi.nat44_interface_add_del_feature(
5568 sw_if_index=self.pg0.sw_if_index,
5569 flags=flags, is_add=1)
5570 self.vapi.nat44_interface_add_del_output_feature(
5572 sw_if_index=self.pg1.sw_if_index)
5574 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5575 IP(src=self.pg0.remote_ip4, dst=external_addr) /
5576 TCP(sport=12345, dport=external_port))
5577 self.pg0.add_stream(p)
5578 self.pg_enable_capture(self.pg_interfaces)
5580 capture = self.pg1.get_capture(1)
5585 self.assertEqual(ip.src, self.pg0.remote_ip4)
5586 self.assertEqual(tcp.sport, 12345)
5587 self.assertEqual(ip.dst, self.pg1.remote_ip4)
5588 self.assertEqual(tcp.dport, local_port)
5589 self.assert_packet_checksums_valid(p)
5591 self.logger.error(ppp("Unexpected or invalid packet:", p))
5594 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
5595 IP(src=self.pg1.remote_ip4, dst=self.pg0.remote_ip4) /
5596 TCP(sport=local_port, dport=12345))
5597 self.pg1.add_stream(p)
5598 self.pg_enable_capture(self.pg_interfaces)
5600 capture = self.pg0.get_capture(1)
5605 self.assertEqual(ip.src, external_addr)
5606 self.assertEqual(tcp.sport, external_port)
5607 self.assertEqual(ip.dst, self.pg0.remote_ip4)
5608 self.assertEqual(tcp.dport, 12345)
5609 self.assert_packet_checksums_valid(p)
5611 self.logger.error(ppp("Unexpected or invalid packet:", p))
5614 def test_next_src_nat(self):
5615 """ On way back forward packet to nat44-in2out node. """
5616 twice_nat_addr = '10.0.1.3'
5619 post_twice_nat_port = 0
5621 self.vapi.nat44_forwarding_enable_disable(enable=1)
5622 self.nat44_add_address(twice_nat_addr, twice_nat=1)
5623 flags = (self.config_flags.NAT_IS_OUT2IN_ONLY |
5624 self.config_flags.NAT_IS_SELF_TWICE_NAT)
5625 self.nat44_add_static_mapping(self.pg6.remote_ip4, self.pg1.remote_ip4,
5626 local_port, external_port,
5627 proto=IP_PROTOS.tcp, vrf_id=1,
5629 self.vapi.nat44_interface_add_del_feature(
5630 sw_if_index=self.pg6.sw_if_index,
5633 p = (Ether(src=self.pg6.remote_mac, dst=self.pg6.local_mac) /
5634 IP(src=self.pg6.remote_ip4, dst=self.pg1.remote_ip4) /
5635 TCP(sport=12345, dport=external_port))
5636 self.pg6.add_stream(p)
5637 self.pg_enable_capture(self.pg_interfaces)
5639 capture = self.pg6.get_capture(1)
5644 self.assertEqual(ip.src, twice_nat_addr)
5645 self.assertNotEqual(tcp.sport, 12345)
5646 post_twice_nat_port = tcp.sport
5647 self.assertEqual(ip.dst, self.pg6.remote_ip4)
5648 self.assertEqual(tcp.dport, local_port)
5649 self.assert_packet_checksums_valid(p)
5651 self.logger.error(ppp("Unexpected or invalid packet:", p))
5654 p = (Ether(src=self.pg6.remote_mac, dst=self.pg6.local_mac) /
5655 IP(src=self.pg6.remote_ip4, dst=twice_nat_addr) /
5656 TCP(sport=local_port, dport=post_twice_nat_port))
5657 self.pg6.add_stream(p)
5658 self.pg_enable_capture(self.pg_interfaces)
5660 capture = self.pg6.get_capture(1)
5665 self.assertEqual(ip.src, self.pg1.remote_ip4)
5666 self.assertEqual(tcp.sport, external_port)
5667 self.assertEqual(ip.dst, self.pg6.remote_ip4)
5668 self.assertEqual(tcp.dport, 12345)
5669 self.assert_packet_checksums_valid(p)
5671 self.logger.error(ppp("Unexpected or invalid packet:", p))
5674 def twice_nat_common(self, self_twice_nat=False, same_pg=False, lb=False,
5676 twice_nat_addr = '10.0.1.3'
5684 port_in1 = port_in + 1
5685 port_in2 = port_in + 2
5690 server1 = self.pg0.remote_hosts[0]
5691 server2 = self.pg0.remote_hosts[1]
5703 eh_translate = ((not self_twice_nat) or (not lb and same_pg) or
5706 self.nat44_add_address(self.nat_addr)
5707 self.nat44_add_address(twice_nat_addr, twice_nat=1)
5711 flags |= self.config_flags.NAT_IS_SELF_TWICE_NAT
5713 flags |= self.config_flags.NAT_IS_TWICE_NAT
5716 self.nat44_add_static_mapping(pg0.remote_ip4, self.nat_addr,
5718 proto=IP_PROTOS.tcp,
5721 locals = [{'addr': server1.ip4n,
5725 {'addr': server2.ip4n,
5729 out_addr = self.nat_addr
5731 self.vapi.nat44_add_del_lb_static_mapping(is_add=1, flags=flags,
5732 external_addr=out_addr,
5733 external_port=port_out,
5734 protocol=IP_PROTOS.tcp,
5735 local_num=len(locals),
5737 flags = self.config_flags.NAT_IS_INSIDE
5738 self.vapi.nat44_interface_add_del_feature(
5739 sw_if_index=pg0.sw_if_index,
5740 flags=flags, is_add=1)
5741 self.vapi.nat44_interface_add_del_feature(
5742 sw_if_index=pg1.sw_if_index,
5749 assert client_id is not None
5751 client = self.pg0.remote_hosts[0]
5752 elif client_id == 2:
5753 client = self.pg0.remote_hosts[1]
5755 client = pg1.remote_hosts[0]
5756 p = (Ether(src=pg1.remote_mac, dst=pg1.local_mac) /
5757 IP(src=client.ip4, dst=self.nat_addr) /
5758 TCP(sport=eh_port_out, dport=port_out))
5760 self.pg_enable_capture(self.pg_interfaces)
5762 capture = pg0.get_capture(1)
5768 if ip.dst == server1.ip4:
5774 self.assertEqual(ip.dst, server.ip4)
5776 self.assertIn(tcp.dport, [port_in1, port_in2])
5778 self.assertEqual(tcp.dport, port_in)
5780 self.assertEqual(ip.src, twice_nat_addr)
5781 self.assertNotEqual(tcp.sport, eh_port_out)
5783 self.assertEqual(ip.src, client.ip4)
5784 self.assertEqual(tcp.sport, eh_port_out)
5786 eh_port_in = tcp.sport
5787 saved_port_in = tcp.dport
5788 self.assert_packet_checksums_valid(p)
5790 self.logger.error(ppp("Unexpected or invalid packet:", p))
5793 p = (Ether(src=server.mac, dst=pg0.local_mac) /
5794 IP(src=server.ip4, dst=eh_addr_in) /
5795 TCP(sport=saved_port_in, dport=eh_port_in))
5797 self.pg_enable_capture(self.pg_interfaces)
5799 capture = pg1.get_capture(1)
5804 self.assertEqual(ip.dst, client.ip4)
5805 self.assertEqual(ip.src, self.nat_addr)
5806 self.assertEqual(tcp.dport, eh_port_out)
5807 self.assertEqual(tcp.sport, port_out)
5808 self.assert_packet_checksums_valid(p)
5810 self.logger.error(ppp("Unexpected or invalid packet:", p))
5814 sessions = self.vapi.nat44_user_session_dump(server.ip4n, 0)
5815 self.assertEqual(len(sessions), 1)
5816 self.assertTrue(sessions[0].flags &
5817 self.config_flags.NAT_IS_EXT_HOST_VALID)
5818 self.assertTrue(sessions[0].flags &
5819 self.config_flags.NAT_IS_TWICE_NAT)
5820 self.logger.error(self.vapi.cli("show nat44 sessions detail"))
5821 self.vapi.nat44_del_session(
5822 address=sessions[0].inside_ip_address,
5823 port=sessions[0].inside_port,
5824 protocol=sessions[0].protocol,
5825 flags=(self.config_flags.NAT_IS_INSIDE |
5826 self.config_flags.NAT_IS_EXT_HOST_VALID),
5827 ext_host_address=sessions[0].ext_host_nat_address,
5828 ext_host_port=sessions[0].ext_host_nat_port)
5829 sessions = self.vapi.nat44_user_session_dump(server.ip4n, 0)
5830 self.assertEqual(len(sessions), 0)
5832 def test_twice_nat(self):
5834 self.twice_nat_common()
5836 def test_self_twice_nat_positive(self):
5837 """ Self Twice NAT44 (positive test) """
5838 self.twice_nat_common(self_twice_nat=True, same_pg=True)
5840 def test_self_twice_nat_negative(self):
5841 """ Self Twice NAT44 (negative test) """
5842 self.twice_nat_common(self_twice_nat=True)
5844 def test_twice_nat_lb(self):
5845 """ Twice NAT44 local service load balancing """
5846 self.twice_nat_common(lb=True)
5848 def test_self_twice_nat_lb_positive(self):
5849 """ Self Twice NAT44 local service load balancing (positive test) """
5850 self.twice_nat_common(lb=True, self_twice_nat=True, same_pg=True,
5853 def test_self_twice_nat_lb_negative(self):
5854 """ Self Twice NAT44 local service load balancing (negative test) """
5855 self.twice_nat_common(lb=True, self_twice_nat=True, same_pg=True,
5858 def test_twice_nat_interface_addr(self):
5859 """ Acquire twice NAT44 addresses from interface """
5860 flags = self.config_flags.NAT_IS_TWICE_NAT
5861 self.vapi.nat44_add_del_interface_addr(
5863 sw_if_index=self.pg3.sw_if_index,
5866 # no address in NAT pool
5867 adresses = self.vapi.nat44_address_dump()
5868 self.assertEqual(0, len(adresses))
5870 # configure interface address and check NAT address pool
5871 self.pg3.config_ip4()
5872 adresses = self.vapi.nat44_address_dump()
5873 self.assertEqual(1, len(adresses))
5874 self.assertEqual(str(adresses[0].ip_address),
5876 self.assertEqual(adresses[0].flags, flags)
5878 # remove interface address and check NAT address pool
5879 self.pg3.unconfig_ip4()
5880 adresses = self.vapi.nat44_address_dump()
5881 self.assertEqual(0, len(adresses))
5883 def test_tcp_close(self):
5884 """ Close TCP session from inside network - output feature """
5885 self.vapi.nat44_forwarding_enable_disable(enable=1)
5886 self.nat44_add_address(self.pg1.local_ip4)
5887 twice_nat_addr = '10.0.1.3'
5888 service_ip = '192.168.16.150'
5889 self.nat44_add_address(twice_nat_addr, twice_nat=1)
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,
5894 self.vapi.nat44_interface_add_del_feature(
5895 sw_if_index=self.pg0.sw_if_index,
5896 flags=flags, is_add=1)
5897 self.vapi.nat44_interface_add_del_output_feature(
5899 sw_if_index=self.pg1.sw_if_index)
5900 flags = (self.config_flags.NAT_IS_OUT2IN_ONLY |
5901 self.config_flags.NAT_IS_TWICE_NAT)
5902 self.nat44_add_static_mapping(self.pg0.remote_ip4,
5906 proto=IP_PROTOS.tcp,
5908 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4n, 0)
5909 start_sessnum = len(sessions)
5911 # SYN packet out->in
5912 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
5913 IP(src=self.pg1.remote_ip4, dst=service_ip) /
5914 TCP(sport=33898, dport=80, flags="S"))
5915 self.pg1.add_stream(p)
5916 self.pg_enable_capture(self.pg_interfaces)
5918 capture = self.pg0.get_capture(1)
5920 tcp_port = p[TCP].sport
5922 # SYN + ACK packet in->out
5923 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5924 IP(src=self.pg0.remote_ip4, dst=twice_nat_addr) /
5925 TCP(sport=80, dport=tcp_port, flags="SA"))
5926 self.pg0.add_stream(p)
5927 self.pg_enable_capture(self.pg_interfaces)
5929 self.pg1.get_capture(1)
5931 # ACK packet out->in
5932 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
5933 IP(src=self.pg1.remote_ip4, dst=service_ip) /
5934 TCP(sport=33898, dport=80, flags="A"))
5935 self.pg1.add_stream(p)
5936 self.pg_enable_capture(self.pg_interfaces)
5938 self.pg0.get_capture(1)
5940 # FIN packet in -> out
5941 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5942 IP(src=self.pg0.remote_ip4, dst=twice_nat_addr) /
5943 TCP(sport=80, dport=tcp_port, flags="FA", seq=100, ack=300))
5944 self.pg0.add_stream(p)
5945 self.pg_enable_capture(self.pg_interfaces)
5947 self.pg1.get_capture(1)
5949 # FIN+ACK packet out -> in
5950 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
5951 IP(src=self.pg1.remote_ip4, dst=service_ip) /
5952 TCP(sport=33898, dport=80, flags="FA", seq=300, ack=101))
5953 self.pg1.add_stream(p)
5954 self.pg_enable_capture(self.pg_interfaces)
5956 self.pg0.get_capture(1)
5958 # ACK packet in -> out
5959 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5960 IP(src=self.pg0.remote_ip4, dst=twice_nat_addr) /
5961 TCP(sport=80, dport=tcp_port, flags="A", seq=101, ack=301))
5962 self.pg0.add_stream(p)
5963 self.pg_enable_capture(self.pg_interfaces)
5965 self.pg1.get_capture(1)
5967 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4n,
5969 self.assertEqual(len(sessions) - start_sessnum, 0)
5971 def test_tcp_session_close_in(self):
5972 """ Close TCP session from inside network """
5973 self.tcp_port_out = 10505
5974 self.nat44_add_address(self.nat_addr)
5975 flags = self.config_flags.NAT_IS_TWICE_NAT
5976 self.nat44_add_static_mapping(self.pg0.remote_ip4,
5980 proto=IP_PROTOS.tcp,
5982 flags = self.config_flags.NAT_IS_INSIDE
5983 self.vapi.nat44_interface_add_del_feature(
5984 sw_if_index=self.pg0.sw_if_index,
5985 flags=flags, is_add=1)
5986 self.vapi.nat44_interface_add_del_feature(
5987 sw_if_index=self.pg1.sw_if_index,
5990 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4n, 0)
5991 start_sessnum = len(sessions)
5993 self.initiate_tcp_session(self.pg0, self.pg1)
5995 # FIN packet in -> out
5996 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5997 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
5998 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
5999 flags="FA", seq=100, ack=300))
6000 self.pg0.add_stream(p)
6001 self.pg_enable_capture(self.pg_interfaces)
6003 self.pg1.get_capture(1)
6007 # ACK packet out -> in
6008 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
6009 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
6010 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
6011 flags="A", seq=300, ack=101))
6014 # FIN packet out -> in
6015 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
6016 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
6017 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
6018 flags="FA", seq=300, ack=101))
6021 self.pg1.add_stream(pkts)
6022 self.pg_enable_capture(self.pg_interfaces)
6024 self.pg0.get_capture(2)
6026 # ACK packet in -> out
6027 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6028 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6029 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
6030 flags="A", seq=101, ack=301))
6031 self.pg0.add_stream(p)
6032 self.pg_enable_capture(self.pg_interfaces)
6034 self.pg1.get_capture(1)
6036 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4n,
6038 self.assertEqual(len(sessions) - start_sessnum, 0)
6040 def test_tcp_session_close_out(self):
6041 """ Close TCP session from outside network """
6042 self.tcp_port_out = 10505
6043 self.nat44_add_address(self.nat_addr)
6044 flags = self.config_flags.NAT_IS_TWICE_NAT
6045 self.nat44_add_static_mapping(self.pg0.remote_ip4,
6049 proto=IP_PROTOS.tcp,
6051 flags = self.config_flags.NAT_IS_INSIDE
6052 self.vapi.nat44_interface_add_del_feature(
6053 sw_if_index=self.pg0.sw_if_index,
6054 flags=flags, is_add=1)
6055 self.vapi.nat44_interface_add_del_feature(
6056 sw_if_index=self.pg1.sw_if_index,
6059 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4n, 0)
6060 start_sessnum = len(sessions)
6062 self.initiate_tcp_session(self.pg0, self.pg1)
6064 # FIN packet out -> in
6065 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
6066 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
6067 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
6068 flags="FA", seq=100, ack=300))
6069 self.pg1.add_stream(p)
6070 self.pg_enable_capture(self.pg_interfaces)
6072 self.pg0.get_capture(1)
6074 # FIN+ACK packet in -> out
6075 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6076 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6077 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
6078 flags="FA", seq=300, ack=101))
6080 self.pg0.add_stream(p)
6081 self.pg_enable_capture(self.pg_interfaces)
6083 self.pg1.get_capture(1)
6085 # ACK packet out -> in
6086 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
6087 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
6088 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
6089 flags="A", seq=101, ack=301))
6090 self.pg1.add_stream(p)
6091 self.pg_enable_capture(self.pg_interfaces)
6093 self.pg0.get_capture(1)
6095 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4n,
6097 self.assertEqual(len(sessions) - start_sessnum, 0)
6099 def test_tcp_session_close_simultaneous(self):
6100 """ Close TCP session from inside network """
6101 self.tcp_port_out = 10505
6102 self.nat44_add_address(self.nat_addr)
6103 flags = self.config_flags.NAT_IS_TWICE_NAT
6104 self.nat44_add_static_mapping(self.pg0.remote_ip4,
6108 proto=IP_PROTOS.tcp,
6110 flags = self.config_flags.NAT_IS_INSIDE
6111 self.vapi.nat44_interface_add_del_feature(
6112 sw_if_index=self.pg0.sw_if_index,
6113 flags=flags, is_add=1)
6114 self.vapi.nat44_interface_add_del_feature(
6115 sw_if_index=self.pg1.sw_if_index,
6118 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4n, 0)
6119 start_sessnum = len(sessions)
6121 self.initiate_tcp_session(self.pg0, self.pg1)
6123 # FIN packet in -> out
6124 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6125 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6126 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
6127 flags="FA", seq=100, ack=300))
6128 self.pg0.add_stream(p)
6129 self.pg_enable_capture(self.pg_interfaces)
6131 self.pg1.get_capture(1)
6133 # FIN packet out -> in
6134 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
6135 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
6136 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
6137 flags="FA", seq=300, ack=100))
6138 self.pg1.add_stream(p)
6139 self.pg_enable_capture(self.pg_interfaces)
6141 self.pg0.get_capture(1)
6143 # ACK packet in -> out
6144 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6145 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6146 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
6147 flags="A", seq=101, ack=301))
6148 self.pg0.add_stream(p)
6149 self.pg_enable_capture(self.pg_interfaces)
6151 self.pg1.get_capture(1)
6153 # ACK packet out -> in
6154 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
6155 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
6156 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
6157 flags="A", seq=301, ack=101))
6158 self.pg1.add_stream(p)
6159 self.pg_enable_capture(self.pg_interfaces)
6161 self.pg0.get_capture(1)
6163 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4n,
6165 self.assertEqual(len(sessions) - start_sessnum, 0)
6167 def test_one_armed_nat44_static(self):
6168 """ One armed NAT44 and 1:1 NAPT asymmetrical rule """
6169 remote_host = self.pg4.remote_hosts[0]
6170 local_host = self.pg4.remote_hosts[1]
6175 self.vapi.nat44_forwarding_enable_disable(enable=1)
6176 self.nat44_add_address(self.nat_addr, twice_nat=1)
6177 flags = (self.config_flags.NAT_IS_OUT2IN_ONLY |
6178 self.config_flags.NAT_IS_TWICE_NAT)
6179 self.nat44_add_static_mapping(local_host.ip4, self.nat_addr,
6180 local_port, external_port,
6181 proto=IP_PROTOS.tcp, flags=flags)
6182 flags = self.config_flags.NAT_IS_INSIDE
6183 self.vapi.nat44_interface_add_del_feature(
6184 sw_if_index=self.pg4.sw_if_index,
6186 self.vapi.nat44_interface_add_del_feature(
6187 sw_if_index=self.pg4.sw_if_index,
6188 flags=flags, is_add=1)
6190 # from client to service
6191 p = (Ether(src=self.pg4.remote_mac, dst=self.pg4.local_mac) /
6192 IP(src=remote_host.ip4, dst=self.nat_addr) /
6193 TCP(sport=12345, dport=external_port))
6194 self.pg4.add_stream(p)
6195 self.pg_enable_capture(self.pg_interfaces)
6197 capture = self.pg4.get_capture(1)
6202 self.assertEqual(ip.dst, local_host.ip4)
6203 self.assertEqual(ip.src, self.nat_addr)
6204 self.assertEqual(tcp.dport, local_port)
6205 self.assertNotEqual(tcp.sport, 12345)
6206 eh_port_in = tcp.sport
6207 self.assert_packet_checksums_valid(p)
6209 self.logger.error(ppp("Unexpected or invalid packet:", p))
6212 # from service back to client
6213 p = (Ether(src=self.pg4.remote_mac, dst=self.pg4.local_mac) /
6214 IP(src=local_host.ip4, dst=self.nat_addr) /
6215 TCP(sport=local_port, dport=eh_port_in))
6216 self.pg4.add_stream(p)
6217 self.pg_enable_capture(self.pg_interfaces)
6219 capture = self.pg4.get_capture(1)
6224 self.assertEqual(ip.src, self.nat_addr)
6225 self.assertEqual(ip.dst, remote_host.ip4)
6226 self.assertEqual(tcp.sport, external_port)
6227 self.assertEqual(tcp.dport, 12345)
6228 self.assert_packet_checksums_valid(p)
6230 self.logger.error(ppp("Unexpected or invalid packet:", p))
6233 def test_static_with_port_out2(self):
6234 """ 1:1 NAPT asymmetrical rule """
6239 self.vapi.nat44_forwarding_enable_disable(enable=1)
6240 flags = self.config_flags.NAT_IS_OUT2IN_ONLY
6241 self.nat44_add_static_mapping(self.pg0.remote_ip4, self.nat_addr,
6242 local_port, external_port,
6243 proto=IP_PROTOS.tcp, flags=flags)
6244 flags = self.config_flags.NAT_IS_INSIDE
6245 self.vapi.nat44_interface_add_del_feature(
6246 sw_if_index=self.pg0.sw_if_index,
6247 flags=flags, is_add=1)
6248 self.vapi.nat44_interface_add_del_feature(
6249 sw_if_index=self.pg1.sw_if_index,
6252 # from client to service
6253 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
6254 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
6255 TCP(sport=12345, dport=external_port))
6256 self.pg1.add_stream(p)
6257 self.pg_enable_capture(self.pg_interfaces)
6259 capture = self.pg0.get_capture(1)
6264 self.assertEqual(ip.dst, self.pg0.remote_ip4)
6265 self.assertEqual(tcp.dport, local_port)
6266 self.assert_packet_checksums_valid(p)
6268 self.logger.error(ppp("Unexpected or invalid packet:", p))
6272 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
6273 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6274 ICMP(type=11) / capture[0][IP])
6275 self.pg0.add_stream(p)
6276 self.pg_enable_capture(self.pg_interfaces)
6278 capture = self.pg1.get_capture(1)
6281 self.assertEqual(p[IP].src, self.nat_addr)
6283 self.assertEqual(inner.dst, self.nat_addr)
6284 self.assertEqual(inner[TCPerror].dport, external_port)
6286 self.logger.error(ppp("Unexpected or invalid packet:", p))
6289 # from service back to client
6290 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6291 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6292 TCP(sport=local_port, dport=12345))
6293 self.pg0.add_stream(p)
6294 self.pg_enable_capture(self.pg_interfaces)
6296 capture = self.pg1.get_capture(1)
6301 self.assertEqual(ip.src, self.nat_addr)
6302 self.assertEqual(tcp.sport, external_port)
6303 self.assert_packet_checksums_valid(p)
6305 self.logger.error(ppp("Unexpected or invalid packet:", p))
6309 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
6310 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
6311 ICMP(type=11) / capture[0][IP])
6312 self.pg1.add_stream(p)
6313 self.pg_enable_capture(self.pg_interfaces)
6315 capture = self.pg0.get_capture(1)
6318 self.assertEqual(p[IP].dst, self.pg0.remote_ip4)
6320 self.assertEqual(inner.src, self.pg0.remote_ip4)
6321 self.assertEqual(inner[TCPerror].sport, local_port)
6323 self.logger.error(ppp("Unexpected or invalid packet:", p))
6326 # from client to server (no translation)
6327 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
6328 IP(src=self.pg1.remote_ip4, dst=self.pg0.remote_ip4) /
6329 TCP(sport=12346, dport=local_port))
6330 self.pg1.add_stream(p)
6331 self.pg_enable_capture(self.pg_interfaces)
6333 capture = self.pg0.get_capture(1)
6338 self.assertEqual(ip.dst, self.pg0.remote_ip4)
6339 self.assertEqual(tcp.dport, local_port)
6340 self.assert_packet_checksums_valid(p)
6342 self.logger.error(ppp("Unexpected or invalid packet:", p))
6345 # from service back to client (no translation)
6346 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6347 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6348 TCP(sport=local_port, dport=12346))
6349 self.pg0.add_stream(p)
6350 self.pg_enable_capture(self.pg_interfaces)
6352 capture = self.pg1.get_capture(1)
6357 self.assertEqual(ip.src, self.pg0.remote_ip4)
6358 self.assertEqual(tcp.sport, local_port)
6359 self.assert_packet_checksums_valid(p)
6361 self.logger.error(ppp("Unexpected or invalid packet:", p))
6364 def test_output_feature(self):
6365 """ NAT44 interface output feature (in2out postrouting) """
6366 self.vapi.nat44_forwarding_enable_disable(enable=1)
6367 self.nat44_add_address(self.nat_addr)
6368 self.vapi.nat44_interface_add_del_feature(
6369 sw_if_index=self.pg0.sw_if_index,
6371 self.vapi.nat44_interface_add_del_output_feature(
6373 sw_if_index=self.pg1.sw_if_index)
6376 pkts = self.create_stream_in(self.pg0, self.pg1)
6377 self.pg0.add_stream(pkts)
6378 self.pg_enable_capture(self.pg_interfaces)
6380 capture = self.pg1.get_capture(len(pkts))
6381 self.verify_capture_out(capture)
6384 pkts = self.create_stream_out(self.pg1)
6385 self.pg1.add_stream(pkts)
6386 self.pg_enable_capture(self.pg_interfaces)
6388 capture = self.pg0.get_capture(len(pkts))
6389 self.verify_capture_in(capture, self.pg0)
6391 def test_multiple_vrf(self):
6392 """ Multiple VRF setup """
6393 external_addr = '1.2.3.4'
6398 self.vapi.nat44_forwarding_enable_disable(enable=1)
6399 self.nat44_add_address(self.nat_addr)
6400 flags = self.config_flags.NAT_IS_INSIDE
6401 self.vapi.nat44_interface_add_del_feature(
6402 sw_if_index=self.pg0.sw_if_index,
6404 self.vapi.nat44_interface_add_del_feature(
6405 sw_if_index=self.pg0.sw_if_index,
6406 flags=flags, is_add=1)
6407 self.vapi.nat44_interface_add_del_output_feature(
6409 sw_if_index=self.pg1.sw_if_index)
6410 self.vapi.nat44_interface_add_del_feature(
6411 sw_if_index=self.pg5.sw_if_index,
6413 self.vapi.nat44_interface_add_del_feature(
6414 sw_if_index=self.pg5.sw_if_index,
6415 flags=flags, is_add=1)
6416 self.vapi.nat44_interface_add_del_feature(
6417 sw_if_index=self.pg6.sw_if_index,
6419 flags = self.config_flags.NAT_IS_OUT2IN_ONLY
6420 self.nat44_add_static_mapping(self.pg5.remote_ip4, external_addr,
6421 local_port, external_port, vrf_id=1,
6422 proto=IP_PROTOS.tcp, flags=flags)
6423 self.nat44_add_static_mapping(
6424 self.pg0.remote_ip4,
6425 external_sw_if_index=self.pg0.sw_if_index,
6426 local_port=local_port,
6428 external_port=external_port,
6429 proto=IP_PROTOS.tcp,
6433 # from client to service (both VRF1)
6434 p = (Ether(src=self.pg6.remote_mac, dst=self.pg6.local_mac) /
6435 IP(src=self.pg6.remote_ip4, dst=external_addr) /
6436 TCP(sport=12345, dport=external_port))
6437 self.pg6.add_stream(p)
6438 self.pg_enable_capture(self.pg_interfaces)
6440 capture = self.pg5.get_capture(1)
6445 self.assertEqual(ip.dst, self.pg5.remote_ip4)
6446 self.assertEqual(tcp.dport, local_port)
6447 self.assert_packet_checksums_valid(p)
6449 self.logger.error(ppp("Unexpected or invalid packet:", p))
6452 # from service back to client (both VRF1)
6453 p = (Ether(src=self.pg5.remote_mac, dst=self.pg5.local_mac) /
6454 IP(src=self.pg5.remote_ip4, dst=self.pg6.remote_ip4) /
6455 TCP(sport=local_port, dport=12345))
6456 self.pg5.add_stream(p)
6457 self.pg_enable_capture(self.pg_interfaces)
6459 capture = self.pg6.get_capture(1)
6464 self.assertEqual(ip.src, external_addr)
6465 self.assertEqual(tcp.sport, external_port)
6466 self.assert_packet_checksums_valid(p)
6468 self.logger.error(ppp("Unexpected or invalid packet:", p))
6471 # dynamic NAT from VRF1 to VRF0 (output-feature)
6472 p = (Ether(src=self.pg5.remote_mac, dst=self.pg5.local_mac) /
6473 IP(src=self.pg5.remote_ip4, dst=self.pg1.remote_ip4) /
6474 TCP(sport=2345, dport=22))
6475 self.pg5.add_stream(p)
6476 self.pg_enable_capture(self.pg_interfaces)
6478 capture = self.pg1.get_capture(1)
6483 self.assertEqual(ip.src, self.nat_addr)
6484 self.assertNotEqual(tcp.sport, 2345)
6485 self.assert_packet_checksums_valid(p)
6488 self.logger.error(ppp("Unexpected or invalid packet:", p))
6491 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
6492 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
6493 TCP(sport=22, dport=port))
6494 self.pg1.add_stream(p)
6495 self.pg_enable_capture(self.pg_interfaces)
6497 capture = self.pg5.get_capture(1)
6502 self.assertEqual(ip.dst, self.pg5.remote_ip4)
6503 self.assertEqual(tcp.dport, 2345)
6504 self.assert_packet_checksums_valid(p)
6506 self.logger.error(ppp("Unexpected or invalid packet:", p))
6509 # from client VRF1 to service VRF0
6510 p = (Ether(src=self.pg6.remote_mac, dst=self.pg6.local_mac) /
6511 IP(src=self.pg6.remote_ip4, dst=self.pg0.local_ip4) /
6512 TCP(sport=12346, dport=external_port))
6513 self.pg6.add_stream(p)
6514 self.pg_enable_capture(self.pg_interfaces)
6516 capture = self.pg0.get_capture(1)
6521 self.assertEqual(ip.dst, self.pg0.remote_ip4)
6522 self.assertEqual(tcp.dport, local_port)
6523 self.assert_packet_checksums_valid(p)
6525 self.logger.error(ppp("Unexpected or invalid packet:", p))
6528 # from service VRF0 back to client VRF1
6529 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6530 IP(src=self.pg0.remote_ip4, dst=self.pg6.remote_ip4) /
6531 TCP(sport=local_port, dport=12346))
6532 self.pg0.add_stream(p)
6533 self.pg_enable_capture(self.pg_interfaces)
6535 capture = self.pg6.get_capture(1)
6540 self.assertEqual(ip.src, self.pg0.local_ip4)
6541 self.assertEqual(tcp.sport, external_port)
6542 self.assert_packet_checksums_valid(p)
6544 self.logger.error(ppp("Unexpected or invalid packet:", p))
6547 # from client VRF0 to service VRF1
6548 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6549 IP(src=self.pg0.remote_ip4, dst=external_addr) /
6550 TCP(sport=12347, dport=external_port))
6551 self.pg0.add_stream(p)
6552 self.pg_enable_capture(self.pg_interfaces)
6554 capture = self.pg5.get_capture(1)
6559 self.assertEqual(ip.dst, self.pg5.remote_ip4)
6560 self.assertEqual(tcp.dport, local_port)
6561 self.assert_packet_checksums_valid(p)
6563 self.logger.error(ppp("Unexpected or invalid packet:", p))
6566 # from service VRF1 back to client VRF0
6567 p = (Ether(src=self.pg5.remote_mac, dst=self.pg5.local_mac) /
6568 IP(src=self.pg5.remote_ip4, dst=self.pg0.remote_ip4) /
6569 TCP(sport=local_port, dport=12347))
6570 self.pg5.add_stream(p)
6571 self.pg_enable_capture(self.pg_interfaces)
6573 capture = self.pg0.get_capture(1)
6578 self.assertEqual(ip.src, external_addr)
6579 self.assertEqual(tcp.sport, external_port)
6580 self.assert_packet_checksums_valid(p)
6582 self.logger.error(ppp("Unexpected or invalid packet:", p))
6585 # from client to server (both VRF1, no translation)
6586 p = (Ether(src=self.pg6.remote_mac, dst=self.pg6.local_mac) /
6587 IP(src=self.pg6.remote_ip4, dst=self.pg5.remote_ip4) /
6588 TCP(sport=12348, dport=local_port))
6589 self.pg6.add_stream(p)
6590 self.pg_enable_capture(self.pg_interfaces)
6592 capture = self.pg5.get_capture(1)
6597 self.assertEqual(ip.dst, self.pg5.remote_ip4)
6598 self.assertEqual(tcp.dport, local_port)
6599 self.assert_packet_checksums_valid(p)
6601 self.logger.error(ppp("Unexpected or invalid packet:", p))
6604 # from server back to client (both VRF1, no translation)
6605 p = (Ether(src=self.pg5.remote_mac, dst=self.pg5.local_mac) /
6606 IP(src=self.pg5.remote_ip4, dst=self.pg6.remote_ip4) /
6607 TCP(sport=local_port, dport=12348))
6608 self.pg5.add_stream(p)
6609 self.pg_enable_capture(self.pg_interfaces)
6611 capture = self.pg6.get_capture(1)
6616 self.assertEqual(ip.src, self.pg5.remote_ip4)
6617 self.assertEqual(tcp.sport, local_port)
6618 self.assert_packet_checksums_valid(p)
6620 self.logger.error(ppp("Unexpected or invalid packet:", p))
6623 # from client VRF1 to server VRF0 (no translation)
6624 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6625 IP(src=self.pg0.remote_ip4, dst=self.pg6.remote_ip4) /
6626 TCP(sport=local_port, dport=12349))
6627 self.pg0.add_stream(p)
6628 self.pg_enable_capture(self.pg_interfaces)
6630 capture = self.pg6.get_capture(1)
6635 self.assertEqual(ip.src, self.pg0.remote_ip4)
6636 self.assertEqual(tcp.sport, local_port)
6637 self.assert_packet_checksums_valid(p)
6639 self.logger.error(ppp("Unexpected or invalid packet:", p))
6642 # from server VRF0 back to client VRF1 (no translation)
6643 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6644 IP(src=self.pg0.remote_ip4, dst=self.pg6.remote_ip4) /
6645 TCP(sport=local_port, dport=12349))
6646 self.pg0.add_stream(p)
6647 self.pg_enable_capture(self.pg_interfaces)
6649 capture = self.pg6.get_capture(1)
6654 self.assertEqual(ip.src, self.pg0.remote_ip4)
6655 self.assertEqual(tcp.sport, local_port)
6656 self.assert_packet_checksums_valid(p)
6658 self.logger.error(ppp("Unexpected or invalid packet:", p))
6661 # from client VRF0 to server VRF1 (no translation)
6662 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6663 IP(src=self.pg0.remote_ip4, dst=self.pg5.remote_ip4) /
6664 TCP(sport=12344, dport=local_port))
6665 self.pg0.add_stream(p)
6666 self.pg_enable_capture(self.pg_interfaces)
6668 capture = self.pg5.get_capture(1)
6673 self.assertEqual(ip.dst, self.pg5.remote_ip4)
6674 self.assertEqual(tcp.dport, local_port)
6675 self.assert_packet_checksums_valid(p)
6677 self.logger.error(ppp("Unexpected or invalid packet:", p))
6680 # from server VRF1 back to client VRF0 (no translation)
6681 p = (Ether(src=self.pg5.remote_mac, dst=self.pg5.local_mac) /
6682 IP(src=self.pg5.remote_ip4, dst=self.pg0.remote_ip4) /
6683 TCP(sport=local_port, dport=12344))
6684 self.pg5.add_stream(p)
6685 self.pg_enable_capture(self.pg_interfaces)
6687 capture = self.pg0.get_capture(1)
6692 self.assertEqual(ip.src, self.pg5.remote_ip4)
6693 self.assertEqual(tcp.sport, local_port)
6694 self.assert_packet_checksums_valid(p)
6696 self.logger.error(ppp("Unexpected or invalid packet:", p))
6699 @unittest.skipUnless(running_extended_tests, "part of extended tests")
6700 def test_session_timeout(self):
6701 """ NAT44 session timeouts """
6702 self.nat44_add_address(self.nat_addr)
6703 flags = self.config_flags.NAT_IS_INSIDE
6704 self.vapi.nat44_interface_add_del_feature(
6705 sw_if_index=self.pg0.sw_if_index,
6706 flags=flags, is_add=1)
6707 self.vapi.nat44_interface_add_del_feature(
6708 sw_if_index=self.pg1.sw_if_index,
6710 self.vapi.nat_set_timeouts(udp=300, tcp_established=7440,
6711 tcp_transitory=240, icmp=5)
6715 for i in range(0, max_sessions):
6716 src = "10.10.%u.%u" % ((i & 0xFF00) >> 8, i & 0xFF)
6717 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
6718 IP(src=src, dst=self.pg1.remote_ip4) /
6719 ICMP(id=1025, type='echo-request'))
6721 self.pg0.add_stream(pkts)
6722 self.pg_enable_capture(self.pg_interfaces)
6724 self.pg1.get_capture(max_sessions)
6729 for i in range(0, max_sessions):
6730 src = "10.11.%u.%u" % ((i & 0xFF00) >> 8, i & 0xFF)
6731 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
6732 IP(src=src, dst=self.pg1.remote_ip4) /
6733 ICMP(id=1026, type='echo-request'))
6735 self.pg0.add_stream(pkts)
6736 self.pg_enable_capture(self.pg_interfaces)
6738 self.pg1.get_capture(max_sessions)
6741 users = self.vapi.nat44_user_dump()
6743 nsessions = nsessions + user.nsessions
6744 self.assertLess(nsessions, 2 * max_sessions)
6746 @unittest.skipUnless(running_extended_tests, "part of extended tests")
6747 def test_session_rst_timeout(self):
6748 """ NAT44 session RST timeouts """
6749 self.nat44_add_address(self.nat_addr)
6750 flags = self.config_flags.NAT_IS_INSIDE
6751 self.vapi.nat44_interface_add_del_feature(
6752 sw_if_index=self.pg0.sw_if_index,
6753 flags=flags, is_add=1)
6754 self.vapi.nat44_interface_add_del_feature(
6755 sw_if_index=self.pg1.sw_if_index,
6757 self.vapi.nat_set_timeouts(udp=300, tcp_established=7440,
6758 tcp_transitory=5, icmp=60)
6760 self.initiate_tcp_session(self.pg0, self.pg1)
6761 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6762 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6763 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
6765 self.pg0.add_stream(p)
6766 self.pg_enable_capture(self.pg_interfaces)
6768 self.pg1.get_capture(1)
6772 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6773 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6774 TCP(sport=self.tcp_port_in + 1, dport=self.tcp_external_port + 1,
6776 self.pg0.add_stream(p)
6777 self.pg_enable_capture(self.pg_interfaces)
6779 self.pg1.get_capture(1)
6782 users = self.vapi.nat44_user_dump()
6783 self.assertEqual(len(users), 1)
6784 self.assertEqual(str(users[0].ip_address),
6785 self.pg0.remote_ip4)
6786 self.assertEqual(users[0].nsessions, 1)
6788 @unittest.skipUnless(running_extended_tests, "part of extended tests")
6789 def test_session_limit_per_user(self):
6790 """ Maximum sessions per user limit """
6791 self.nat44_add_address(self.nat_addr)
6792 flags = self.config_flags.NAT_IS_INSIDE
6793 self.vapi.nat44_interface_add_del_feature(
6794 sw_if_index=self.pg0.sw_if_index,
6795 flags=flags, is_add=1)
6796 self.vapi.nat44_interface_add_del_feature(
6797 sw_if_index=self.pg1.sw_if_index,
6799 self.vapi.set_ipfix_exporter(collector_address=self.pg2.remote_ip4n,
6800 src_address=self.pg2.local_ip4n,
6802 template_interval=10)
6803 self.vapi.nat_set_timeouts(udp=5, tcp_established=7440,
6804 tcp_transitory=240, icmp=60)
6806 # get maximum number of translations per user
6807 nat44_config = self.vapi.nat_show_config()
6810 for port in range(0, nat44_config.max_translations_per_user):
6811 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6812 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6813 UDP(sport=1025 + port, dport=1025 + port))
6816 self.pg0.add_stream(pkts)
6817 self.pg_enable_capture(self.pg_interfaces)
6819 capture = self.pg1.get_capture(len(pkts))
6821 self.vapi.nat_ipfix_enable_disable(domain_id=self.ipfix_domain_id,
6822 src_port=self.ipfix_src_port,
6825 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6826 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6827 UDP(sport=3001, dport=3002))
6828 self.pg0.add_stream(p)
6829 self.pg_enable_capture(self.pg_interfaces)
6831 capture = self.pg1.assert_nothing_captured()
6833 # verify IPFIX logging
6834 self.vapi.cli("ipfix flush") # FIXME this should be an API call
6836 capture = self.pg2.get_capture(10)
6837 ipfix = IPFIXDecoder()
6838 # first load template
6840 self.assertTrue(p.haslayer(IPFIX))
6841 if p.haslayer(Template):
6842 ipfix.add_template(p.getlayer(Template))
6843 # verify events in data set
6845 if p.haslayer(Data):
6846 data = ipfix.decode_data_set(p.getlayer(Set))
6847 self.verify_ipfix_max_entries_per_user(
6849 nat44_config.max_translations_per_user,
6850 self.pg0.remote_ip4n)
6853 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6854 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6855 UDP(sport=3001, dport=3002))
6856 self.pg0.add_stream(p)
6857 self.pg_enable_capture(self.pg_interfaces)
6859 self.pg1.get_capture(1)
6861 def test_syslog_sess(self):
6862 """ Test syslog session creation and deletion """
6863 self.vapi.syslog_set_filter(
6864 self.SYSLOG_SEVERITY.SYSLOG_API_SEVERITY_INFO)
6865 self.vapi.syslog_set_sender(self.pg2.local_ip4n, self.pg2.remote_ip4n)
6866 self.nat44_add_address(self.nat_addr)
6867 flags = self.config_flags.NAT_IS_INSIDE
6868 self.vapi.nat44_interface_add_del_feature(
6869 sw_if_index=self.pg0.sw_if_index,
6870 flags=flags, is_add=1)
6871 self.vapi.nat44_interface_add_del_feature(
6872 sw_if_index=self.pg1.sw_if_index,
6875 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
6876 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6877 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port))
6878 self.pg0.add_stream(p)
6879 self.pg_enable_capture(self.pg_interfaces)
6881 capture = self.pg1.get_capture(1)
6882 self.tcp_port_out = capture[0][TCP].sport
6883 capture = self.pg2.get_capture(1)
6884 self.verify_syslog_sess(capture[0][Raw].load)
6886 self.pg_enable_capture(self.pg_interfaces)
6888 self.nat44_add_address(self.nat_addr, is_add=0)
6889 capture = self.pg2.get_capture(1)
6890 self.verify_syslog_sess(capture[0][Raw].load, False)
6893 super(TestNAT44EndpointDependent, self).tearDown()
6894 if not self.vpp_dead:
6896 self.vapi.cli("clear logging")
6898 def show_commands_at_teardown(self):
6899 self.logger.info(self.vapi.cli("show nat44 addresses"))
6900 self.logger.info(self.vapi.cli("show nat44 interfaces"))
6901 self.logger.info(self.vapi.cli("show nat44 static mappings"))
6902 self.logger.info(self.vapi.cli("show nat44 interface address"))
6903 self.logger.info(self.vapi.cli("show nat44 sessions detail"))
6904 self.logger.info(self.vapi.cli("show nat44 hash tables detail"))
6905 self.logger.info(self.vapi.cli("show nat timeouts"))
6908 class TestNAT44Out2InDPO(MethodHolder):
6909 """ NAT44 Test Cases using out2in DPO """
6912 def setUpConstants(cls):
6913 super(TestNAT44Out2InDPO, cls).setUpConstants()
6914 cls.vpp_cmdline.extend(["nat", "{", "out2in dpo", "}"])
6917 def setUpClass(cls):
6918 super(TestNAT44Out2InDPO, cls).setUpClass()
6919 cls.vapi.cli("set log class nat level debug")
6922 cls.tcp_port_in = 6303
6923 cls.tcp_port_out = 6303
6924 cls.udp_port_in = 6304
6925 cls.udp_port_out = 6304
6926 cls.icmp_id_in = 6305
6927 cls.icmp_id_out = 6305
6928 cls.nat_addr = '10.0.0.3'
6929 cls.dst_ip4 = '192.168.70.1'
6931 cls.create_pg_interfaces(range(2))
6934 cls.pg0.config_ip4()
6935 cls.pg0.resolve_arp()
6938 cls.pg1.config_ip6()
6939 cls.pg1.resolve_ndp()
6941 cls.vapi.ip_add_del_route(dst_address=b'\x00' * 16,
6942 dst_address_length=0,
6943 next_hop_address=cls.pg1.remote_ip6n,
6944 next_hop_sw_if_index=cls.pg1.sw_if_index,
6948 super(TestNAT44Out2InDPO, cls).tearDownClass()
6952 def tearDownClass(cls):
6953 super(TestNAT44Out2InDPO, cls).tearDownClass()
6955 def configure_xlat(self):
6956 self.dst_ip6_pfx = '1:2:3::'
6957 self.dst_ip6_pfx_n = socket.inet_pton(socket.AF_INET6,
6959 self.dst_ip6_pfx_len = 96
6960 self.src_ip6_pfx = '4:5:6::'
6961 self.src_ip6_pfx_n = socket.inet_pton(socket.AF_INET6,
6963 self.src_ip6_pfx_len = 96
6964 self.vapi.map_add_domain(self.dst_ip6_pfx_n, self.dst_ip6_pfx_len,
6965 self.src_ip6_pfx_n, self.src_ip6_pfx_len,
6966 '\x00\x00\x00\x00', 0)
6968 @unittest.skip('Temporary disabled')
6969 def test_464xlat_ce(self):
6970 """ Test 464XLAT CE with NAT44 """
6972 nat_config = self.vapi.nat_show_config()
6973 self.assertEqual(1, nat_config.out2in_dpo)
6975 self.configure_xlat()
6977 flags = self.config_flags.NAT_IS_INSIDE
6978 self.vapi.nat44_interface_add_del_feature(
6979 sw_if_index=self.pg0.sw_if_index,
6980 flags=flags, is_add=1)
6981 self.vapi.nat44_add_del_address_range(first_ip_address=self.nat_addr_n,
6982 last_ip_address=self.nat_addr_n,
6983 vrf_id=0xFFFFFFFF, is_add=1)
6985 out_src_ip6 = self.compose_ip6(self.dst_ip4, self.dst_ip6_pfx,
6986 self.dst_ip6_pfx_len)
6987 out_dst_ip6 = self.compose_ip6(self.nat_addr, self.src_ip6_pfx,
6988 self.src_ip6_pfx_len)
6991 pkts = self.create_stream_in(self.pg0, self.pg1, self.dst_ip4)
6992 self.pg0.add_stream(pkts)
6993 self.pg_enable_capture(self.pg_interfaces)
6995 capture = self.pg1.get_capture(len(pkts))
6996 self.verify_capture_out_ip6(capture, nat_ip=out_dst_ip6,
6999 pkts = self.create_stream_out_ip6(self.pg1, out_src_ip6,
7001 self.pg1.add_stream(pkts)
7002 self.pg_enable_capture(self.pg_interfaces)
7004 capture = self.pg0.get_capture(len(pkts))
7005 self.verify_capture_in(capture, self.pg0)
7007 self.vapi.nat44_interface_add_del_feature(
7008 sw_if_index=self.pg0.sw_if_index,
7010 self.vapi.nat44_add_del_address_range(
7011 first_ip_address=self.nat_addr_n,
7012 last_ip_address=self.nat_addr_n,
7015 @unittest.skip('Temporary disabled')
7016 def test_464xlat_ce_no_nat(self):
7017 """ Test 464XLAT CE without NAT44 """
7019 self.configure_xlat()
7021 out_src_ip6 = self.compose_ip6(self.dst_ip4, self.dst_ip6_pfx,
7022 self.dst_ip6_pfx_len)
7023 out_dst_ip6 = self.compose_ip6(self.pg0.remote_ip4, self.src_ip6_pfx,
7024 self.src_ip6_pfx_len)
7026 pkts = self.create_stream_in(self.pg0, self.pg1, self.dst_ip4)
7027 self.pg0.add_stream(pkts)
7028 self.pg_enable_capture(self.pg_interfaces)
7030 capture = self.pg1.get_capture(len(pkts))
7031 self.verify_capture_out_ip6(capture, dst_ip=out_src_ip6,
7032 nat_ip=out_dst_ip6, same_port=True)
7034 pkts = self.create_stream_out_ip6(self.pg1, out_src_ip6, out_dst_ip6)
7035 self.pg1.add_stream(pkts)
7036 self.pg_enable_capture(self.pg_interfaces)
7038 capture = self.pg0.get_capture(len(pkts))
7039 self.verify_capture_in(capture, self.pg0)
7042 class TestDeterministicNAT(MethodHolder):
7043 """ Deterministic NAT Test Cases """
7046 def setUpConstants(cls):
7047 super(TestDeterministicNAT, cls).setUpConstants()
7048 cls.vpp_cmdline.extend(["nat", "{", "deterministic", "}"])
7051 def setUpClass(cls):
7052 super(TestDeterministicNAT, cls).setUpClass()
7053 cls.vapi.cli("set log class nat level debug")
7056 cls.tcp_port_in = 6303
7057 cls.tcp_external_port = 6303
7058 cls.udp_port_in = 6304
7059 cls.udp_external_port = 6304
7060 cls.icmp_id_in = 6305
7061 cls.nat_addr = '10.0.0.3'
7063 cls.create_pg_interfaces(range(3))
7064 cls.interfaces = list(cls.pg_interfaces)
7066 for i in cls.interfaces:
7071 cls.pg0.generate_remote_hosts(2)
7072 cls.pg0.configure_ipv4_neighbors()
7075 super(TestDeterministicNAT, cls).tearDownClass()
7079 def tearDownClass(cls):
7080 super(TestDeterministicNAT, cls).tearDownClass()
7082 def create_stream_in(self, in_if, out_if, ttl=64):
7084 Create packet stream for inside network
7086 :param in_if: Inside interface
7087 :param out_if: Outside interface
7088 :param ttl: TTL of generated packets
7092 p = (Ether(dst=in_if.local_mac, src=in_if.remote_mac) /
7093 IP(src=in_if.remote_ip4, dst=out_if.remote_ip4, ttl=ttl) /
7094 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port))
7098 p = (Ether(dst=in_if.local_mac, src=in_if.remote_mac) /
7099 IP(src=in_if.remote_ip4, dst=out_if.remote_ip4, ttl=ttl) /
7100 UDP(sport=self.udp_port_in, dport=self.udp_external_port))
7104 p = (Ether(dst=in_if.local_mac, src=in_if.remote_mac) /
7105 IP(src=in_if.remote_ip4, dst=out_if.remote_ip4, ttl=ttl) /
7106 ICMP(id=self.icmp_id_in, type='echo-request'))
7111 def create_stream_out(self, out_if, dst_ip=None, ttl=64):
7113 Create packet stream for outside network
7115 :param out_if: Outside interface
7116 :param dst_ip: Destination IP address (Default use global NAT address)
7117 :param ttl: TTL of generated packets
7120 dst_ip = self.nat_addr
7123 p = (Ether(dst=out_if.local_mac, src=out_if.remote_mac) /
7124 IP(src=out_if.remote_ip4, dst=dst_ip, ttl=ttl) /
7125 TCP(dport=self.tcp_port_out, sport=self.tcp_external_port))
7129 p = (Ether(dst=out_if.local_mac, src=out_if.remote_mac) /
7130 IP(src=out_if.remote_ip4, dst=dst_ip, ttl=ttl) /
7131 UDP(dport=self.udp_port_out, sport=self.udp_external_port))
7135 p = (Ether(dst=out_if.local_mac, src=out_if.remote_mac) /
7136 IP(src=out_if.remote_ip4, dst=dst_ip, ttl=ttl) /
7137 ICMP(id=self.icmp_external_id, type='echo-reply'))
7142 def verify_capture_out(self, capture, nat_ip=None):
7144 Verify captured packets on outside network
7146 :param capture: Captured packets
7147 :param nat_ip: Translated IP address (Default use global NAT address)
7148 :param same_port: Source port number is not translated (Default False)
7151 nat_ip = self.nat_addr
7152 for packet in capture:
7154 self.assertEqual(packet[IP].src, nat_ip)
7155 if packet.haslayer(TCP):
7156 self.tcp_port_out = packet[TCP].sport
7157 elif packet.haslayer(UDP):
7158 self.udp_port_out = packet[UDP].sport
7160 self.icmp_external_id = packet[ICMP].id
7162 self.logger.error(ppp("Unexpected or invalid packet "
7163 "(outside network):", packet))
7166 def test_deterministic_mode(self):
7167 """ NAT plugin run deterministic mode """
7168 in_addr = '172.16.255.0'
7169 out_addr = '172.17.255.50'
7170 in_addr_t = '172.16.255.20'
7174 nat_config = self.vapi.nat_show_config()
7175 self.assertEqual(1, nat_config.deterministic)
7177 self.vapi.nat_det_add_del_map(is_add=1, in_addr=in_addr,
7178 in_plen=in_plen, out_addr=out_addr,
7181 rep1 = self.vapi.nat_det_forward(in_addr_t)
7182 self.assertEqual(str(rep1.out_addr), out_addr)
7183 rep2 = self.vapi.nat_det_reverse(rep1.out_port_hi, out_addr)
7185 self.assertEqual(str(rep2.in_addr), in_addr_t)
7187 deterministic_mappings = self.vapi.nat_det_map_dump()
7188 self.assertEqual(len(deterministic_mappings), 1)
7189 dsm = deterministic_mappings[0]
7190 self.assertEqual(in_addr, str(dsm.in_addr))
7191 self.assertEqual(in_plen, dsm.in_plen)
7192 self.assertEqual(out_addr, str(dsm.out_addr))
7193 self.assertEqual(out_plen, dsm.out_plen)
7195 self.clear_nat_det()
7196 deterministic_mappings = self.vapi.nat_det_map_dump()
7197 self.assertEqual(len(deterministic_mappings), 0)
7199 def test_set_timeouts(self):
7200 """ Set deterministic NAT timeouts """
7201 timeouts_before = self.vapi.nat_get_timeouts()
7203 self.vapi.nat_set_timeouts(
7204 udp=timeouts_before.udp + 10,
7205 tcp_established=timeouts_before.tcp_established + 10,
7206 tcp_transitory=timeouts_before.tcp_transitory + 10,
7207 icmp=timeouts_before.icmp + 10)
7209 timeouts_after = self.vapi.nat_get_timeouts()
7211 self.assertNotEqual(timeouts_before.udp, timeouts_after.udp)
7212 self.assertNotEqual(timeouts_before.icmp, timeouts_after.icmp)
7213 self.assertNotEqual(timeouts_before.tcp_established,
7214 timeouts_after.tcp_established)
7215 self.assertNotEqual(timeouts_before.tcp_transitory,
7216 timeouts_after.tcp_transitory)
7218 def test_det_in(self):
7219 """ Deterministic NAT translation test (TCP, UDP, ICMP) """
7221 nat_ip = "10.0.0.10"
7223 self.vapi.nat_det_add_del_map(is_add=1, in_addr=self.pg0.remote_ip4n,
7225 out_addr=socket.inet_aton(nat_ip),
7228 flags = self.config_flags.NAT_IS_INSIDE
7229 self.vapi.nat44_interface_add_del_feature(
7230 sw_if_index=self.pg0.sw_if_index,
7231 flags=flags, is_add=1)
7232 self.vapi.nat44_interface_add_del_feature(
7233 sw_if_index=self.pg1.sw_if_index,
7237 pkts = self.create_stream_in(self.pg0, self.pg1)
7238 self.pg0.add_stream(pkts)
7239 self.pg_enable_capture(self.pg_interfaces)
7241 capture = self.pg1.get_capture(len(pkts))
7242 self.verify_capture_out(capture, nat_ip)
7245 pkts = self.create_stream_out(self.pg1, nat_ip)
7246 self.pg1.add_stream(pkts)
7247 self.pg_enable_capture(self.pg_interfaces)
7249 capture = self.pg0.get_capture(len(pkts))
7250 self.verify_capture_in(capture, self.pg0)
7253 sessions = self.vapi.nat_det_session_dump(self.pg0.remote_ip4n)
7254 self.assertEqual(len(sessions), 3)
7258 self.assertEqual(str(s.ext_addr), self.pg1.remote_ip4)
7259 self.assertEqual(s.in_port, self.tcp_port_in)
7260 self.assertEqual(s.out_port, self.tcp_port_out)
7261 self.assertEqual(s.ext_port, self.tcp_external_port)
7265 self.assertEqual(str(s.ext_addr), self.pg1.remote_ip4)
7266 self.assertEqual(s.in_port, self.udp_port_in)
7267 self.assertEqual(s.out_port, self.udp_port_out)
7268 self.assertEqual(s.ext_port, self.udp_external_port)
7272 self.assertEqual(str(s.ext_addr), self.pg1.remote_ip4)
7273 self.assertEqual(s.in_port, self.icmp_id_in)
7274 self.assertEqual(s.out_port, self.icmp_external_id)
7276 def test_multiple_users(self):
7277 """ Deterministic NAT multiple users """
7279 nat_ip = "10.0.0.10"
7281 external_port = 6303
7283 host0 = self.pg0.remote_hosts[0]
7284 host1 = self.pg0.remote_hosts[1]
7286 self.vapi.nat_det_add_del_map(is_add=1, in_addr=host0.ip4n, in_plen=24,
7287 out_addr=socket.inet_aton(nat_ip),
7289 flags = self.config_flags.NAT_IS_INSIDE
7290 self.vapi.nat44_interface_add_del_feature(
7291 sw_if_index=self.pg0.sw_if_index,
7292 flags=flags, is_add=1)
7293 self.vapi.nat44_interface_add_del_feature(
7294 sw_if_index=self.pg1.sw_if_index,
7298 p = (Ether(src=host0.mac, dst=self.pg0.local_mac) /
7299 IP(src=host0.ip4, dst=self.pg1.remote_ip4) /
7300 TCP(sport=port_in, dport=external_port))
7301 self.pg0.add_stream(p)
7302 self.pg_enable_capture(self.pg_interfaces)
7304 capture = self.pg1.get_capture(1)
7309 self.assertEqual(ip.src, nat_ip)
7310 self.assertEqual(ip.dst, self.pg1.remote_ip4)
7311 self.assertEqual(tcp.dport, external_port)
7312 port_out0 = tcp.sport
7314 self.logger.error(ppp("Unexpected or invalid packet:", p))
7318 p = (Ether(src=host1.mac, dst=self.pg0.local_mac) /
7319 IP(src=host1.ip4, dst=self.pg1.remote_ip4) /
7320 TCP(sport=port_in, dport=external_port))
7321 self.pg0.add_stream(p)
7322 self.pg_enable_capture(self.pg_interfaces)
7324 capture = self.pg1.get_capture(1)
7329 self.assertEqual(ip.src, nat_ip)
7330 self.assertEqual(ip.dst, self.pg1.remote_ip4)
7331 self.assertEqual(tcp.dport, external_port)
7332 port_out1 = tcp.sport
7334 self.logger.error(ppp("Unexpected or invalid packet:", p))
7337 dms = self.vapi.nat_det_map_dump()
7338 self.assertEqual(1, len(dms))
7339 self.assertEqual(2, dms[0].ses_num)
7342 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
7343 IP(src=self.pg1.remote_ip4, dst=nat_ip) /
7344 TCP(sport=external_port, dport=port_out0))
7345 self.pg1.add_stream(p)
7346 self.pg_enable_capture(self.pg_interfaces)
7348 capture = self.pg0.get_capture(1)
7353 self.assertEqual(ip.src, self.pg1.remote_ip4)
7354 self.assertEqual(ip.dst, host0.ip4)
7355 self.assertEqual(tcp.dport, port_in)
7356 self.assertEqual(tcp.sport, external_port)
7358 self.logger.error(ppp("Unexpected or invalid packet:", p))
7362 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
7363 IP(src=self.pg1.remote_ip4, dst=nat_ip) /
7364 TCP(sport=external_port, dport=port_out1))
7365 self.pg1.add_stream(p)
7366 self.pg_enable_capture(self.pg_interfaces)
7368 capture = self.pg0.get_capture(1)
7373 self.assertEqual(ip.src, self.pg1.remote_ip4)
7374 self.assertEqual(ip.dst, host1.ip4)
7375 self.assertEqual(tcp.dport, port_in)
7376 self.assertEqual(tcp.sport, external_port)
7378 self.logger.error(ppp("Unexpected or invalid packet", p))
7381 # session close api test
7382 self.vapi.nat_det_close_session_out(socket.inet_aton(nat_ip),
7384 self.pg1.remote_ip4n,
7386 dms = self.vapi.nat_det_map_dump()
7387 self.assertEqual(dms[0].ses_num, 1)
7389 self.vapi.nat_det_close_session_in(host0.ip4n,
7391 self.pg1.remote_ip4n,
7393 dms = self.vapi.nat_det_map_dump()
7394 self.assertEqual(dms[0].ses_num, 0)
7396 def test_tcp_session_close_detection_in(self):
7397 """ Deterministic NAT TCP session close from inside network """
7398 self.vapi.nat_det_add_del_map(is_add=1, in_addr=self.pg0.remote_ip4n,
7400 out_addr=socket.inet_aton(self.nat_addr),
7402 flags = self.config_flags.NAT_IS_INSIDE
7403 self.vapi.nat44_interface_add_del_feature(
7404 sw_if_index=self.pg0.sw_if_index,
7405 flags=flags, is_add=1)
7406 self.vapi.nat44_interface_add_del_feature(
7407 sw_if_index=self.pg1.sw_if_index,
7410 self.initiate_tcp_session(self.pg0, self.pg1)
7412 # close the session from inside
7414 # FIN packet in -> out
7415 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
7416 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
7417 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
7419 self.pg0.add_stream(p)
7420 self.pg_enable_capture(self.pg_interfaces)
7422 self.pg1.get_capture(1)
7426 # ACK packet out -> in
7427 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
7428 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
7429 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
7433 # FIN packet out -> in
7434 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
7435 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
7436 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
7440 self.pg1.add_stream(pkts)
7441 self.pg_enable_capture(self.pg_interfaces)
7443 self.pg0.get_capture(2)
7445 # ACK packet in -> out
7446 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
7447 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
7448 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
7450 self.pg0.add_stream(p)
7451 self.pg_enable_capture(self.pg_interfaces)
7453 self.pg1.get_capture(1)
7455 # Check if deterministic NAT44 closed the session
7456 dms = self.vapi.nat_det_map_dump()
7457 self.assertEqual(0, dms[0].ses_num)
7459 self.logger.error("TCP session termination failed")
7462 def test_tcp_session_close_detection_out(self):
7463 """ Deterministic NAT TCP session close from outside network """
7464 self.vapi.nat_det_add_del_map(is_add=1, in_addr=self.pg0.remote_ip4n,
7466 out_addr=socket.inet_aton(self.nat_addr),
7468 flags = self.config_flags.NAT_IS_INSIDE
7469 self.vapi.nat44_interface_add_del_feature(
7470 sw_if_index=self.pg0.sw_if_index,
7471 flags=flags, is_add=1)
7472 self.vapi.nat44_interface_add_del_feature(
7473 sw_if_index=self.pg1.sw_if_index,
7476 self.initiate_tcp_session(self.pg0, self.pg1)
7478 # close the session from outside
7480 # FIN packet out -> in
7481 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
7482 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
7483 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
7485 self.pg1.add_stream(p)
7486 self.pg_enable_capture(self.pg_interfaces)
7488 self.pg0.get_capture(1)
7492 # ACK packet in -> out
7493 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
7494 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
7495 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
7499 # ACK packet in -> out
7500 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
7501 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
7502 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
7506 self.pg0.add_stream(pkts)
7507 self.pg_enable_capture(self.pg_interfaces)
7509 self.pg1.get_capture(2)
7511 # ACK packet out -> in
7512 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
7513 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
7514 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
7516 self.pg1.add_stream(p)
7517 self.pg_enable_capture(self.pg_interfaces)
7519 self.pg0.get_capture(1)
7521 # Check if deterministic NAT44 closed the session
7522 dms = self.vapi.nat_det_map_dump()
7523 self.assertEqual(0, dms[0].ses_num)
7525 self.logger.error("TCP session termination failed")
7528 @unittest.skipUnless(running_extended_tests, "part of extended tests")
7529 def test_session_timeout(self):
7530 """ Deterministic NAT session timeouts """
7531 self.vapi.nat_det_add_del_map(is_add=1, in_addr=self.pg0.remote_ip4n,
7533 out_addr=socket.inet_aton(self.nat_addr),
7535 flags = self.config_flags.NAT_IS_INSIDE
7536 self.vapi.nat44_interface_add_del_feature(
7537 sw_if_index=self.pg0.sw_if_index,
7538 flags=flags, is_add=1)
7539 self.vapi.nat44_interface_add_del_feature(
7540 sw_if_index=self.pg1.sw_if_index,
7543 self.initiate_tcp_session(self.pg0, self.pg1)
7544 self.vapi.nat_set_timeouts(udp=5, tcp_established=5, tcp_transitory=5,
7546 pkts = self.create_stream_in(self.pg0, self.pg1)
7547 self.pg0.add_stream(pkts)
7548 self.pg_enable_capture(self.pg_interfaces)
7550 capture = self.pg1.get_capture(len(pkts))
7553 dms = self.vapi.nat_det_map_dump()
7554 self.assertEqual(0, dms[0].ses_num)
7556 @unittest.skipUnless(running_extended_tests, "part of extended tests")
7557 def test_session_limit_per_user(self):
7558 """ Deterministic NAT maximum sessions per user limit """
7559 self.vapi.nat_det_add_del_map(is_add=1, in_addr=self.pg0.remote_ip4n,
7561 out_addr=socket.inet_aton(self.nat_addr),
7563 flags = self.config_flags.NAT_IS_INSIDE
7564 self.vapi.nat44_interface_add_del_feature(
7565 sw_if_index=self.pg0.sw_if_index,
7566 flags=flags, is_add=1)
7567 self.vapi.nat44_interface_add_del_feature(
7568 sw_if_index=self.pg1.sw_if_index,
7570 self.vapi.set_ipfix_exporter(collector_address=self.pg2.remote_ip4n,
7571 src_address=self.pg2.local_ip4n,
7573 template_interval=10)
7574 self.vapi.nat_ipfix_enable_disable(domain_id=1, src_port=4739,
7578 for port in range(1025, 2025):
7579 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
7580 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
7581 UDP(sport=port, dport=port))
7584 self.pg0.add_stream(pkts)
7585 self.pg_enable_capture(self.pg_interfaces)
7587 capture = self.pg1.get_capture(len(pkts))
7589 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
7590 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
7591 UDP(sport=3001, dport=3002))
7592 self.pg0.add_stream(p)
7593 self.pg_enable_capture(self.pg_interfaces)
7595 capture = self.pg1.assert_nothing_captured()
7597 # verify ICMP error packet
7598 capture = self.pg0.get_capture(1)
7600 self.assertTrue(p.haslayer(ICMP))
7602 self.assertEqual(icmp.type, 3)
7603 self.assertEqual(icmp.code, 1)
7604 self.assertTrue(icmp.haslayer(IPerror))
7605 inner_ip = icmp[IPerror]
7606 self.assertEqual(inner_ip[UDPerror].sport, 3001)
7607 self.assertEqual(inner_ip[UDPerror].dport, 3002)
7609 dms = self.vapi.nat_det_map_dump()
7611 self.assertEqual(1000, dms[0].ses_num)
7613 # verify IPFIX logging
7614 self.vapi.cli("ipfix flush") # FIXME this should be an API call
7616 capture = self.pg2.get_capture(2)
7617 ipfix = IPFIXDecoder()
7618 # first load template
7620 self.assertTrue(p.haslayer(IPFIX))
7621 if p.haslayer(Template):
7622 ipfix.add_template(p.getlayer(Template))
7623 # verify events in data set
7625 if p.haslayer(Data):
7626 data = ipfix.decode_data_set(p.getlayer(Set))
7627 self.verify_ipfix_max_entries_per_user(data,
7629 self.pg0.remote_ip4n)
7631 def clear_nat_det(self):
7633 Clear deterministic NAT configuration.
7635 self.vapi.nat_ipfix_enable_disable(domain_id=1, src_port=4739,
7637 self.vapi.nat_set_timeouts(udp=300, tcp_established=7440,
7638 tcp_transitory=240, icmp=60)
7639 deterministic_mappings = self.vapi.nat_det_map_dump()
7640 for dsm in deterministic_mappings:
7641 self.vapi.nat_det_add_del_map(is_add=0, in_addr=dsm.in_addr,
7642 in_plen=dsm.in_plen,
7643 out_addr=dsm.out_addr,
7644 out_plen=dsm.out_plen)
7646 interfaces = self.vapi.nat44_interface_dump()
7647 for intf in interfaces:
7648 self.vapi.nat44_interface_add_del_feature(
7649 sw_if_index=intf.sw_if_index,
7653 super(TestDeterministicNAT, self).tearDown()
7654 if not self.vpp_dead:
7655 self.clear_nat_det()
7657 def show_commands_at_teardown(self):
7658 self.logger.info(self.vapi.cli("show nat44 interfaces"))
7659 self.logger.info(self.vapi.cli("show nat timeouts"))
7661 self.vapi.cli("show nat44 deterministic mappings"))
7663 self.vapi.cli("show nat44 deterministic sessions"))
7666 class TestNAT64(MethodHolder):
7667 """ NAT64 Test Cases """
7670 def setUpConstants(cls):
7671 super(TestNAT64, cls).setUpConstants()
7672 cls.vpp_cmdline.extend(["nat", "{", "nat64 bib hash buckets 128",
7673 "nat64 st hash buckets 256", "}"])
7676 def setUpClass(cls):
7677 super(TestNAT64, cls).setUpClass()
7680 cls.tcp_port_in = 6303
7681 cls.tcp_port_out = 6303
7682 cls.udp_port_in = 6304
7683 cls.udp_port_out = 6304
7684 cls.icmp_id_in = 6305
7685 cls.icmp_id_out = 6305
7686 cls.tcp_external_port = 80
7687 cls.nat_addr = '10.0.0.3'
7688 cls.nat_addr_n = socket.inet_pton(socket.AF_INET, cls.nat_addr)
7690 cls.vrf1_nat_addr = '10.0.10.3'
7691 cls.ipfix_src_port = 4739
7692 cls.ipfix_domain_id = 1
7694 cls.create_pg_interfaces(range(6))
7695 cls.ip6_interfaces = list(cls.pg_interfaces[0:1])
7696 cls.ip6_interfaces.append(cls.pg_interfaces[2])
7697 cls.ip4_interfaces = list(cls.pg_interfaces[1:2])
7699 cls.vapi.ip_table_add_del(is_ipv6=1, is_add=1,
7700 table_id=cls.vrf1_id)
7702 cls.pg_interfaces[2].set_table_ip6(cls.vrf1_id)
7704 cls.pg0.generate_remote_hosts(2)
7706 for i in cls.ip6_interfaces:
7709 i.configure_ipv6_neighbors()
7711 for i in cls.ip4_interfaces:
7717 cls.pg3.config_ip4()
7718 cls.pg3.resolve_arp()
7719 cls.pg3.config_ip6()
7720 cls.pg3.configure_ipv6_neighbors()
7723 cls.pg5.config_ip6()
7726 super(TestNAT64, cls).tearDownClass()
7730 def tearDownClass(cls):
7731 super(TestNAT64, cls).tearDownClass()
7733 def test_nat64_inside_interface_handles_neighbor_advertisement(self):
7734 """ NAT64 inside interface handles Neighbor Advertisement """
7736 flags = self.config_flags.NAT_IS_INSIDE
7737 self.vapi.nat64_add_del_interface(is_add=1, flags=flags,
7738 sw_if_index=self.pg5.sw_if_index)
7741 ping = (Ether(dst=self.pg5.local_mac, src=self.pg5.remote_mac) /
7742 IPv6(src=self.pg5.remote_ip6, dst=self.pg5.local_ip6) /
7743 ICMPv6EchoRequest())
7745 self.pg5.add_stream(pkts)
7746 self.pg_enable_capture(self.pg_interfaces)
7749 # Wait for Neighbor Solicitation
7750 capture = self.pg5.get_capture(len(pkts))
7753 self.assertEqual(packet[IPv6].src, self.pg5.local_ip6)
7754 self.assertEqual(packet.haslayer(ICMPv6ND_NS), 1)
7755 tgt = packet[ICMPv6ND_NS].tgt
7757 self.logger.error(ppp("Unexpected or invalid packet:", packet))
7760 # Send Neighbor Advertisement
7761 p = (Ether(dst=self.pg5.local_mac, src=self.pg5.remote_mac) /
7762 IPv6(src=self.pg5.remote_ip6, dst=self.pg5.local_ip6) /
7763 ICMPv6ND_NA(tgt=tgt) /
7764 ICMPv6NDOptDstLLAddr(lladdr=self.pg5.remote_mac))
7766 self.pg5.add_stream(pkts)
7767 self.pg_enable_capture(self.pg_interfaces)
7770 # Try to send ping again
7772 self.pg5.add_stream(pkts)
7773 self.pg_enable_capture(self.pg_interfaces)
7776 # Wait for ping reply
7777 capture = self.pg5.get_capture(len(pkts))
7780 self.assertEqual(packet[IPv6].src, self.pg5.local_ip6)
7781 self.assertEqual(packet[IPv6].dst, self.pg5.remote_ip6)
7782 self.assertEqual(packet.haslayer(ICMPv6EchoReply), 1)
7784 self.logger.error(ppp("Unexpected or invalid packet:", packet))
7787 def test_pool(self):
7788 """ Add/delete address to NAT64 pool """
7789 nat_addr = '1.2.3.4'
7791 self.vapi.nat64_add_del_pool_addr_range(start_addr=nat_addr,
7793 vrf_id=0xFFFFFFFF, is_add=1)
7795 addresses = self.vapi.nat64_pool_addr_dump()
7796 self.assertEqual(len(addresses), 1)
7797 self.assertEqual(str(addresses[0].address), nat_addr)
7799 self.vapi.nat64_add_del_pool_addr_range(start_addr=nat_addr,
7801 vrf_id=0xFFFFFFFF, is_add=0)
7803 addresses = self.vapi.nat64_pool_addr_dump()
7804 self.assertEqual(len(addresses), 0)
7806 def test_interface(self):
7807 """ Enable/disable NAT64 feature on the interface """
7808 flags = self.config_flags.NAT_IS_INSIDE
7809 self.vapi.nat64_add_del_interface(is_add=1, flags=flags,
7810 sw_if_index=self.pg0.sw_if_index)
7811 self.vapi.nat64_add_del_interface(is_add=1, flags=0,
7812 sw_if_index=self.pg1.sw_if_index)
7814 interfaces = self.vapi.nat64_interface_dump()
7815 self.assertEqual(len(interfaces), 2)
7818 for intf in interfaces:
7819 if intf.sw_if_index == self.pg0.sw_if_index:
7820 self.assertEqual(intf.flags, self.config_flags.NAT_IS_INSIDE)
7822 elif intf.sw_if_index == self.pg1.sw_if_index:
7823 self.assertEqual(intf.flags, self.config_flags.NAT_IS_OUTSIDE)
7825 self.assertTrue(pg0_found)
7826 self.assertTrue(pg1_found)
7828 features = self.vapi.cli("show interface features pg0")
7829 self.assertIn('nat64-in2out', features)
7830 features = self.vapi.cli("show interface features pg1")
7831 self.assertIn('nat64-out2in', features)
7833 self.vapi.nat64_add_del_interface(is_add=0, flags=flags,
7834 sw_if_index=self.pg0.sw_if_index)
7835 self.vapi.nat64_add_del_interface(is_add=0, flags=flags,
7836 sw_if_index=self.pg1.sw_if_index)
7838 interfaces = self.vapi.nat64_interface_dump()
7839 self.assertEqual(len(interfaces), 0)
7841 def test_static_bib(self):
7842 """ Add/delete static BIB entry """
7843 in_addr = '2001:db8:85a3::8a2e:370:7334'
7844 out_addr = '10.1.1.3'
7847 proto = IP_PROTOS.tcp
7849 self.vapi.nat64_add_del_static_bib(i_addr=in_addr, o_addr=out_addr,
7850 i_port=in_port, o_port=out_port,
7851 proto=proto, vrf_id=0, is_add=1)
7852 bib = self.vapi.nat64_bib_dump(proto=IP_PROTOS.tcp)
7855 if bibe.flags & self.config_flags.NAT_IS_STATIC:
7857 self.assertEqual(str(bibe.i_addr), in_addr)
7858 self.assertEqual(str(bibe.o_addr), out_addr)
7859 self.assertEqual(bibe.i_port, in_port)
7860 self.assertEqual(bibe.o_port, out_port)
7861 self.assertEqual(static_bib_num, 1)
7862 bibs = self.statistics.get_counter('/nat64/total-bibs')
7863 self.assertEqual(bibs[0][0], 1)
7865 self.vapi.nat64_add_del_static_bib(i_addr=in_addr, o_addr=out_addr,
7866 i_port=in_port, o_port=out_port,
7867 proto=proto, vrf_id=0, is_add=0)
7868 bib = self.vapi.nat64_bib_dump(proto=IP_PROTOS.tcp)
7871 if bibe.flags & self.config_flags.NAT_IS_STATIC:
7873 self.assertEqual(static_bib_num, 0)
7874 bibs = self.statistics.get_counter('/nat64/total-bibs')
7875 self.assertEqual(bibs[0][0], 0)
7877 def test_set_timeouts(self):
7878 """ Set NAT64 timeouts """
7879 # verify default values
7880 timeouts = self.vapi.nat_get_timeouts()
7881 self.assertEqual(timeouts.udp, 300)
7882 self.assertEqual(timeouts.icmp, 60)
7883 self.assertEqual(timeouts.tcp_transitory, 240)
7884 self.assertEqual(timeouts.tcp_established, 7440)
7886 # set and verify custom values
7887 self.vapi.nat_set_timeouts(udp=200, tcp_established=7450,
7888 tcp_transitory=250, icmp=30)
7889 timeouts = self.vapi.nat_get_timeouts()
7890 self.assertEqual(timeouts.udp, 200)
7891 self.assertEqual(timeouts.icmp, 30)
7892 self.assertEqual(timeouts.tcp_transitory, 250)
7893 self.assertEqual(timeouts.tcp_established, 7450)
7895 def test_dynamic(self):
7896 """ NAT64 dynamic translation test """
7897 self.tcp_port_in = 6303
7898 self.udp_port_in = 6304
7899 self.icmp_id_in = 6305
7901 ses_num_start = self.nat64_get_ses_num()
7903 self.vapi.nat64_add_del_pool_addr_range(start_addr=self.nat_addr,
7904 end_addr=self.nat_addr,
7907 flags = self.config_flags.NAT_IS_INSIDE
7908 self.vapi.nat64_add_del_interface(is_add=1, flags=flags,
7909 sw_if_index=self.pg0.sw_if_index)
7910 self.vapi.nat64_add_del_interface(is_add=1, flags=0,
7911 sw_if_index=self.pg1.sw_if_index)
7914 tcpn = self.statistics.get_err_counter('/err/nat64-in2out/TCP packets')
7915 udpn = self.statistics.get_err_counter('/err/nat64-in2out/UDP packets')
7916 icmpn = self.statistics.get_err_counter(
7917 '/err/nat64-in2out/ICMP packets')
7918 totaln = self.statistics.get_err_counter(
7919 '/err/nat64-in2out/good in2out packets processed')
7921 pkts = self.create_stream_in_ip6(self.pg0, self.pg1)
7922 self.pg0.add_stream(pkts)
7923 self.pg_enable_capture(self.pg_interfaces)
7925 capture = self.pg1.get_capture(len(pkts))
7926 self.verify_capture_out(capture, nat_ip=self.nat_addr,
7927 dst_ip=self.pg1.remote_ip4)
7929 err = self.statistics.get_err_counter('/err/nat64-in2out/TCP packets')
7930 self.assertEqual(err - tcpn, 1)
7931 err = self.statistics.get_err_counter('/err/nat64-in2out/UDP packets')
7932 self.assertEqual(err - udpn, 1)
7933 err = self.statistics.get_err_counter('/err/nat64-in2out/ICMP packets')
7934 self.assertEqual(err - icmpn, 1)
7935 err = self.statistics.get_err_counter(
7936 '/err/nat64-in2out/good in2out packets processed')
7937 self.assertEqual(err - totaln, 3)
7940 tcpn = self.statistics.get_err_counter('/err/nat64-out2in/TCP packets')
7941 udpn = self.statistics.get_err_counter('/err/nat64-out2in/UDP packets')
7942 icmpn = self.statistics.get_err_counter(
7943 '/err/nat64-out2in/ICMP packets')
7944 totaln = self.statistics.get_err_counter(
7945 '/err/nat64-out2in/good out2in packets processed')
7947 pkts = self.create_stream_out(self.pg1, dst_ip=self.nat_addr)
7948 self.pg1.add_stream(pkts)
7949 self.pg_enable_capture(self.pg_interfaces)
7951 capture = self.pg0.get_capture(len(pkts))
7952 ip = IPv6(src=''.join(['64:ff9b::', self.pg1.remote_ip4]))
7953 self.verify_capture_in_ip6(capture, ip[IPv6].src, self.pg0.remote_ip6)
7955 err = self.statistics.get_err_counter('/err/nat64-out2in/TCP packets')
7956 self.assertEqual(err - tcpn, 1)
7957 err = self.statistics.get_err_counter('/err/nat64-out2in/UDP packets')
7958 self.assertEqual(err - udpn, 1)
7959 err = self.statistics.get_err_counter('/err/nat64-out2in/ICMP packets')
7960 self.assertEqual(err - icmpn, 1)
7961 err = self.statistics.get_err_counter(
7962 '/err/nat64-out2in/good out2in packets processed')
7963 self.assertEqual(err - totaln, 3)
7965 bibs = self.statistics.get_counter('/nat64/total-bibs')
7966 self.assertEqual(bibs[0][0], 3)
7967 sessions = self.statistics.get_counter('/nat64/total-sessions')
7968 self.assertEqual(sessions[0][0], 3)
7971 pkts = self.create_stream_in_ip6(self.pg0, self.pg1)
7972 self.pg0.add_stream(pkts)
7973 self.pg_enable_capture(self.pg_interfaces)
7975 capture = self.pg1.get_capture(len(pkts))
7976 self.verify_capture_out(capture, nat_ip=self.nat_addr,
7977 dst_ip=self.pg1.remote_ip4)
7980 pkts = self.create_stream_out(self.pg1, dst_ip=self.nat_addr)
7981 self.pg1.add_stream(pkts)
7982 self.pg_enable_capture(self.pg_interfaces)
7984 capture = self.pg0.get_capture(len(pkts))
7985 self.verify_capture_in_ip6(capture, ip[IPv6].src, self.pg0.remote_ip6)
7987 ses_num_end = self.nat64_get_ses_num()
7989 self.assertEqual(ses_num_end - ses_num_start, 3)
7991 # tenant with specific VRF
7992 self.vapi.nat64_add_del_pool_addr_range(start_addr=self.vrf1_nat_addr,
7993 end_addr=self.vrf1_nat_addr,
7994 vrf_id=self.vrf1_id, is_add=1)
7995 flags = self.config_flags.NAT_IS_INSIDE
7996 self.vapi.nat64_add_del_interface(is_add=1, flags=flags,
7997 sw_if_index=self.pg2.sw_if_index)
7999 pkts = self.create_stream_in_ip6(self.pg2, self.pg1)
8000 self.pg2.add_stream(pkts)
8001 self.pg_enable_capture(self.pg_interfaces)
8003 capture = self.pg1.get_capture(len(pkts))
8004 self.verify_capture_out(capture, nat_ip=self.vrf1_nat_addr,
8005 dst_ip=self.pg1.remote_ip4)
8007 pkts = self.create_stream_out(self.pg1, dst_ip=self.vrf1_nat_addr)
8008 self.pg1.add_stream(pkts)
8009 self.pg_enable_capture(self.pg_interfaces)
8011 capture = self.pg2.get_capture(len(pkts))
8012 self.verify_capture_in_ip6(capture, ip[IPv6].src, self.pg2.remote_ip6)
8014 def test_static(self):
8015 """ NAT64 static translation test """
8016 self.tcp_port_in = 60303
8017 self.udp_port_in = 60304
8018 self.icmp_id_in = 60305
8019 self.tcp_port_out = 60303
8020 self.udp_port_out = 60304
8021 self.icmp_id_out = 60305
8023 ses_num_start = self.nat64_get_ses_num()
8025 self.vapi.nat64_add_del_pool_addr_range(start_addr=self.nat_addr,
8026 end_addr=self.nat_addr,
8029 flags = self.config_flags.NAT_IS_INSIDE
8030 self.vapi.nat64_add_del_interface(is_add=1, flags=flags,
8031 sw_if_index=self.pg0.sw_if_index)
8032 self.vapi.nat64_add_del_interface(is_add=1, flags=0,
8033 sw_if_index=self.pg1.sw_if_index)
8035 self.vapi.nat64_add_del_static_bib(i_addr=self.pg0.remote_ip6n,
8036 o_addr=self.nat_addr,
8037 i_port=self.tcp_port_in,
8038 o_port=self.tcp_port_out,
8039 proto=IP_PROTOS.tcp, vrf_id=0,
8041 self.vapi.nat64_add_del_static_bib(i_addr=self.pg0.remote_ip6n,
8042 o_addr=self.nat_addr,
8043 i_port=self.udp_port_in,
8044 o_port=self.udp_port_out,
8045 proto=IP_PROTOS.udp, vrf_id=0,
8047 self.vapi.nat64_add_del_static_bib(i_addr=self.pg0.remote_ip6n,
8048 o_addr=self.nat_addr,
8049 i_port=self.icmp_id_in,
8050 o_port=self.icmp_id_out,
8051 proto=IP_PROTOS.icmp, vrf_id=0,
8055 pkts = self.create_stream_in_ip6(self.pg0, self.pg1)
8056 self.pg0.add_stream(pkts)
8057 self.pg_enable_capture(self.pg_interfaces)
8059 capture = self.pg1.get_capture(len(pkts))
8060 self.verify_capture_out(capture, nat_ip=self.nat_addr,
8061 dst_ip=self.pg1.remote_ip4, same_port=True)
8064 pkts = self.create_stream_out(self.pg1, dst_ip=self.nat_addr)
8065 self.pg1.add_stream(pkts)
8066 self.pg_enable_capture(self.pg_interfaces)
8068 capture = self.pg0.get_capture(len(pkts))
8069 ip = IPv6(src=''.join(['64:ff9b::', self.pg1.remote_ip4]))
8070 self.verify_capture_in_ip6(capture, ip[IPv6].src, self.pg0.remote_ip6)
8072 ses_num_end = self.nat64_get_ses_num()
8074 self.assertEqual(ses_num_end - ses_num_start, 3)
8076 @unittest.skipUnless(running_extended_tests, "part of extended tests")
8077 def test_session_timeout(self):
8078 """ NAT64 session timeout """
8079 self.icmp_id_in = 1234
8080 self.vapi.nat64_add_del_pool_addr_range(start_addr=self.nat_addr,
8081 end_addr=self.nat_addr,
8084 flags = self.config_flags.NAT_IS_INSIDE
8085 self.vapi.nat64_add_del_interface(is_add=1, flags=flags,
8086 sw_if_index=self.pg0.sw_if_index)
8087 self.vapi.nat64_add_del_interface(is_add=1, flags=0,
8088 sw_if_index=self.pg1.sw_if_index)
8089 self.vapi.nat_set_timeouts(udp=300, tcp_established=5,
8093 pkts = self.create_stream_in_ip6(self.pg0, self.pg1)
8094 self.pg0.add_stream(pkts)
8095 self.pg_enable_capture(self.pg_interfaces)
8097 capture = self.pg1.get_capture(len(pkts))
8099 ses_num_before_timeout = self.nat64_get_ses_num()
8103 # ICMP and TCP session after timeout
8104 ses_num_after_timeout = self.nat64_get_ses_num()
8105 self.assertEqual(ses_num_before_timeout - ses_num_after_timeout, 2)
8107 def test_icmp_error(self):
8108 """ NAT64 ICMP Error message translation """
8109 self.tcp_port_in = 6303
8110 self.udp_port_in = 6304
8111 self.icmp_id_in = 6305
8113 self.vapi.nat64_add_del_pool_addr_range(start_addr=self.nat_addr,
8114 end_addr=self.nat_addr,
8117 flags = self.config_flags.NAT_IS_INSIDE
8118 self.vapi.nat64_add_del_interface(is_add=1, flags=flags,
8119 sw_if_index=self.pg0.sw_if_index)
8120 self.vapi.nat64_add_del_interface(is_add=1, flags=0,
8121 sw_if_index=self.pg1.sw_if_index)
8123 # send some packets to create sessions
8124 pkts = self.create_stream_in_ip6(self.pg0, self.pg1)
8125 self.pg0.add_stream(pkts)
8126 self.pg_enable_capture(self.pg_interfaces)
8128 capture_ip4 = self.pg1.get_capture(len(pkts))
8129 self.verify_capture_out(capture_ip4,
8130 nat_ip=self.nat_addr,
8131 dst_ip=self.pg1.remote_ip4)
8133 pkts = self.create_stream_out(self.pg1, dst_ip=self.nat_addr)
8134 self.pg1.add_stream(pkts)
8135 self.pg_enable_capture(self.pg_interfaces)
8137 capture_ip6 = self.pg0.get_capture(len(pkts))
8138 ip = IPv6(src=''.join(['64:ff9b::', self.pg1.remote_ip4]))
8139 self.verify_capture_in_ip6(capture_ip6, ip[IPv6].src,
8140 self.pg0.remote_ip6)
8143 pkts = [Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
8144 IPv6(src=self.pg0.remote_ip6, dst=ip[IPv6].src) /
8145 ICMPv6DestUnreach(code=1) /
8146 packet[IPv6] for packet in capture_ip6]
8147 self.pg0.add_stream(pkts)
8148 self.pg_enable_capture(self.pg_interfaces)
8150 capture = self.pg1.get_capture(len(pkts))
8151 for packet in capture:
8153 self.assertEqual(packet[IP].src, self.nat_addr)
8154 self.assertEqual(packet[IP].dst, self.pg1.remote_ip4)
8155 self.assertEqual(packet[ICMP].type, 3)
8156 self.assertEqual(packet[ICMP].code, 13)
8157 inner = packet[IPerror]
8158 self.assertEqual(inner.src, self.pg1.remote_ip4)
8159 self.assertEqual(inner.dst, self.nat_addr)
8160 self.assert_packet_checksums_valid(packet)
8161 if inner.haslayer(TCPerror):
8162 self.assertEqual(inner[TCPerror].dport, self.tcp_port_out)
8163 elif inner.haslayer(UDPerror):
8164 self.assertEqual(inner[UDPerror].dport, self.udp_port_out)
8166 self.assertEqual(inner[ICMPerror].id, self.icmp_id_out)
8168 self.logger.error(ppp("Unexpected or invalid packet:", packet))
8172 pkts = [Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
8173 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
8174 ICMP(type=3, code=13) /
8175 packet[IP] for packet in capture_ip4]
8176 self.pg1.add_stream(pkts)
8177 self.pg_enable_capture(self.pg_interfaces)
8179 capture = self.pg0.get_capture(len(pkts))
8180 for packet in capture:
8182 self.assertEqual(packet[IPv6].src, ip.src)
8183 self.assertEqual(packet[IPv6].dst, self.pg0.remote_ip6)
8184 icmp = packet[ICMPv6DestUnreach]
8185 self.assertEqual(icmp.code, 1)
8186 inner = icmp[IPerror6]
8187 self.assertEqual(inner.src, self.pg0.remote_ip6)
8188 self.assertEqual(inner.dst, ip.src)
8189 self.assert_icmpv6_checksum_valid(packet)
8190 if inner.haslayer(TCPerror):
8191 self.assertEqual(inner[TCPerror].sport, self.tcp_port_in)
8192 elif inner.haslayer(UDPerror):
8193 self.assertEqual(inner[UDPerror].sport, self.udp_port_in)
8195 self.assertEqual(inner[ICMPv6EchoRequest].id,
8198 self.logger.error(ppp("Unexpected or invalid packet:", packet))
8201 def test_hairpinning(self):
8202 """ NAT64 hairpinning """
8204 client = self.pg0.remote_hosts[0]
8205 server = self.pg0.remote_hosts[1]
8206 server_tcp_in_port = 22
8207 server_tcp_out_port = 4022
8208 server_udp_in_port = 23
8209 server_udp_out_port = 4023
8210 client_tcp_in_port = 1234
8211 client_udp_in_port = 1235
8212 client_tcp_out_port = 0
8213 client_udp_out_port = 0
8214 ip = IPv6(src=''.join(['64:ff9b::', self.nat_addr]))
8215 nat_addr_ip6 = ip.src
8217 self.vapi.nat64_add_del_pool_addr_range(start_addr=self.nat_addr,
8218 end_addr=self.nat_addr,
8221 flags = self.config_flags.NAT_IS_INSIDE
8222 self.vapi.nat64_add_del_interface(is_add=1, flags=flags,
8223 sw_if_index=self.pg0.sw_if_index)
8224 self.vapi.nat64_add_del_interface(is_add=1, flags=0,
8225 sw_if_index=self.pg1.sw_if_index)
8227 self.vapi.nat64_add_del_static_bib(i_addr=server.ip6n,
8228 o_addr=self.nat_addr,
8229 i_port=server_tcp_in_port,
8230 o_port=server_tcp_out_port,
8231 proto=IP_PROTOS.tcp, vrf_id=0,
8233 self.vapi.nat64_add_del_static_bib(i_addr=server.ip6n,
8234 o_addr=self.nat_addr,
8235 i_port=server_udp_in_port,
8236 o_port=server_udp_out_port,
8237 proto=IP_PROTOS.udp, vrf_id=0,
8242 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
8243 IPv6(src=client.ip6, dst=nat_addr_ip6) /
8244 TCP(sport=client_tcp_in_port, dport=server_tcp_out_port))
8246 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
8247 IPv6(src=client.ip6, dst=nat_addr_ip6) /
8248 UDP(sport=client_udp_in_port, dport=server_udp_out_port))
8250 self.pg0.add_stream(pkts)
8251 self.pg_enable_capture(self.pg_interfaces)
8253 capture = self.pg0.get_capture(len(pkts))
8254 for packet in capture:
8256 self.assertEqual(packet[IPv6].src, nat_addr_ip6)
8257 self.assertEqual(packet[IPv6].dst, server.ip6)
8258 self.assert_packet_checksums_valid(packet)
8259 if packet.haslayer(TCP):
8260 self.assertNotEqual(packet[TCP].sport, client_tcp_in_port)
8261 self.assertEqual(packet[TCP].dport, server_tcp_in_port)
8262 client_tcp_out_port = packet[TCP].sport
8264 self.assertNotEqual(packet[UDP].sport, client_udp_in_port)
8265 self.assertEqual(packet[UDP].dport, server_udp_in_port)
8266 client_udp_out_port = packet[UDP].sport
8268 self.logger.error(ppp("Unexpected or invalid packet:", packet))
8273 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
8274 IPv6(src=server.ip6, dst=nat_addr_ip6) /
8275 TCP(sport=server_tcp_in_port, dport=client_tcp_out_port))
8277 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
8278 IPv6(src=server.ip6, dst=nat_addr_ip6) /
8279 UDP(sport=server_udp_in_port, dport=client_udp_out_port))
8281 self.pg0.add_stream(pkts)
8282 self.pg_enable_capture(self.pg_interfaces)
8284 capture = self.pg0.get_capture(len(pkts))
8285 for packet in capture:
8287 self.assertEqual(packet[IPv6].src, nat_addr_ip6)
8288 self.assertEqual(packet[IPv6].dst, client.ip6)
8289 self.assert_packet_checksums_valid(packet)
8290 if packet.haslayer(TCP):
8291 self.assertEqual(packet[TCP].sport, server_tcp_out_port)
8292 self.assertEqual(packet[TCP].dport, client_tcp_in_port)
8294 self.assertEqual(packet[UDP].sport, server_udp_out_port)
8295 self.assertEqual(packet[UDP].dport, client_udp_in_port)
8297 self.logger.error(ppp("Unexpected or invalid packet:", packet))
8302 pkts = [Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
8303 IPv6(src=client.ip6, dst=nat_addr_ip6) /
8304 ICMPv6DestUnreach(code=1) /
8305 packet[IPv6] for packet in capture]
8306 self.pg0.add_stream(pkts)
8307 self.pg_enable_capture(self.pg_interfaces)
8309 capture = self.pg0.get_capture(len(pkts))
8310 for packet in capture:
8312 self.assertEqual(packet[IPv6].src, nat_addr_ip6)
8313 self.assertEqual(packet[IPv6].dst, server.ip6)
8314 icmp = packet[ICMPv6DestUnreach]
8315 self.assertEqual(icmp.code, 1)
8316 inner = icmp[IPerror6]
8317 self.assertEqual(inner.src, server.ip6)
8318 self.assertEqual(inner.dst, nat_addr_ip6)
8319 self.assert_packet_checksums_valid(packet)
8320 if inner.haslayer(TCPerror):
8321 self.assertEqual(inner[TCPerror].sport, server_tcp_in_port)
8322 self.assertEqual(inner[TCPerror].dport,
8323 client_tcp_out_port)
8325 self.assertEqual(inner[UDPerror].sport, server_udp_in_port)
8326 self.assertEqual(inner[UDPerror].dport,
8327 client_udp_out_port)
8329 self.logger.error(ppp("Unexpected or invalid packet:", packet))
8332 def test_prefix(self):
8333 """ NAT64 Network-Specific Prefix """
8335 self.vapi.nat64_add_del_pool_addr_range(start_addr=self.nat_addr,
8336 end_addr=self.nat_addr,
8339 flags = self.config_flags.NAT_IS_INSIDE
8340 self.vapi.nat64_add_del_interface(is_add=1, flags=flags,
8341 sw_if_index=self.pg0.sw_if_index)
8342 self.vapi.nat64_add_del_interface(is_add=1, flags=0,
8343 sw_if_index=self.pg1.sw_if_index)
8344 self.vapi.nat64_add_del_pool_addr_range(start_addr=self.vrf1_nat_addr,
8345 end_addr=self.vrf1_nat_addr,
8346 vrf_id=self.vrf1_id, is_add=1)
8347 self.vapi.nat64_add_del_interface(is_add=1, flags=flags,
8348 sw_if_index=self.pg2.sw_if_index)
8351 global_pref64 = "2001:db8::"
8352 global_pref64_len = 32
8353 global_pref64_str = "{}/{}".format(global_pref64, global_pref64_len)
8354 self.vapi.nat64_add_del_prefix(prefix=global_pref64_str, vrf_id=0,
8357 prefix = self.vapi.nat64_prefix_dump()
8358 self.assertEqual(len(prefix), 1)
8359 self.assertEqual(prefix[0].prefix,
8360 IPv6Network(unicode(global_pref64_str)))
8361 self.assertEqual(prefix[0].vrf_id, 0)
8363 # Add tenant specific prefix
8364 vrf1_pref64 = "2001:db8:122:300::"
8365 vrf1_pref64_len = 56
8366 vrf1_pref64_str = "{}/{}".format(vrf1_pref64, vrf1_pref64_len)
8367 self.vapi.nat64_add_del_prefix(prefix=vrf1_pref64_str,
8368 vrf_id=self.vrf1_id, is_add=1)
8370 prefix = self.vapi.nat64_prefix_dump()
8371 self.assertEqual(len(prefix), 2)
8374 pkts = self.create_stream_in_ip6(self.pg0,
8377 plen=global_pref64_len)
8378 self.pg0.add_stream(pkts)
8379 self.pg_enable_capture(self.pg_interfaces)
8381 capture = self.pg1.get_capture(len(pkts))
8382 self.verify_capture_out(capture, nat_ip=self.nat_addr,
8383 dst_ip=self.pg1.remote_ip4)
8385 pkts = self.create_stream_out(self.pg1, dst_ip=self.nat_addr)
8386 self.pg1.add_stream(pkts)
8387 self.pg_enable_capture(self.pg_interfaces)
8389 capture = self.pg0.get_capture(len(pkts))
8390 dst_ip = self.compose_ip6(self.pg1.remote_ip4,
8393 self.verify_capture_in_ip6(capture, dst_ip, self.pg0.remote_ip6)
8395 # Tenant specific prefix
8396 pkts = self.create_stream_in_ip6(self.pg2,
8399 plen=vrf1_pref64_len)
8400 self.pg2.add_stream(pkts)
8401 self.pg_enable_capture(self.pg_interfaces)
8403 capture = self.pg1.get_capture(len(pkts))
8404 self.verify_capture_out(capture, nat_ip=self.vrf1_nat_addr,
8405 dst_ip=self.pg1.remote_ip4)
8407 pkts = self.create_stream_out(self.pg1, dst_ip=self.vrf1_nat_addr)
8408 self.pg1.add_stream(pkts)
8409 self.pg_enable_capture(self.pg_interfaces)
8411 capture = self.pg2.get_capture(len(pkts))
8412 dst_ip = self.compose_ip6(self.pg1.remote_ip4,
8415 self.verify_capture_in_ip6(capture, dst_ip, self.pg2.remote_ip6)
8417 def test_unknown_proto(self):
8418 """ NAT64 translate packet with unknown protocol """
8420 self.vapi.nat64_add_del_pool_addr_range(start_addr=self.nat_addr,
8421 end_addr=self.nat_addr,
8424 flags = self.config_flags.NAT_IS_INSIDE
8425 self.vapi.nat64_add_del_interface(is_add=1, flags=flags,
8426 sw_if_index=self.pg0.sw_if_index)
8427 self.vapi.nat64_add_del_interface(is_add=1, flags=0,
8428 sw_if_index=self.pg1.sw_if_index)
8429 remote_ip6 = self.compose_ip6(self.pg1.remote_ip4, '64:ff9b::', 96)
8432 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
8433 IPv6(src=self.pg0.remote_ip6, dst=remote_ip6) /
8434 TCP(sport=self.tcp_port_in, dport=20))
8435 self.pg0.add_stream(p)
8436 self.pg_enable_capture(self.pg_interfaces)
8438 p = self.pg1.get_capture(1)
8440 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
8441 IPv6(src=self.pg0.remote_ip6, dst=remote_ip6, nh=47) /
8443 IP(src=self.pg2.local_ip4, dst=self.pg2.remote_ip4) /
8444 TCP(sport=1234, dport=1234))
8445 self.pg0.add_stream(p)
8446 self.pg_enable_capture(self.pg_interfaces)
8448 p = self.pg1.get_capture(1)
8451 self.assertEqual(packet[IP].src, self.nat_addr)
8452 self.assertEqual(packet[IP].dst, self.pg1.remote_ip4)
8453 self.assertEqual(packet.haslayer(GRE), 1)
8454 self.assert_packet_checksums_valid(packet)
8456 self.logger.error(ppp("Unexpected or invalid packet:", packet))
8460 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
8461 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
8463 IP(src=self.pg2.remote_ip4, dst=self.pg2.local_ip4) /
8464 TCP(sport=1234, dport=1234))
8465 self.pg1.add_stream(p)
8466 self.pg_enable_capture(self.pg_interfaces)
8468 p = self.pg0.get_capture(1)
8471 self.assertEqual(packet[IPv6].src, remote_ip6)
8472 self.assertEqual(packet[IPv6].dst, self.pg0.remote_ip6)
8473 self.assertEqual(packet[IPv6].nh, 47)
8475 self.logger.error(ppp("Unexpected or invalid packet:", packet))
8478 def test_hairpinning_unknown_proto(self):
8479 """ NAT64 translate packet with unknown protocol - hairpinning """
8481 client = self.pg0.remote_hosts[0]
8482 server = self.pg0.remote_hosts[1]
8483 server_tcp_in_port = 22
8484 server_tcp_out_port = 4022
8485 client_tcp_in_port = 1234
8486 client_tcp_out_port = 1235
8487 server_nat_ip = "10.0.0.100"
8488 client_nat_ip = "10.0.0.110"
8489 server_nat_ip6 = self.compose_ip6(server_nat_ip, '64:ff9b::', 96)
8490 client_nat_ip6 = self.compose_ip6(client_nat_ip, '64:ff9b::', 96)
8492 self.vapi.nat64_add_del_pool_addr_range(start_addr=server_nat_ip,
8493 end_addr=client_nat_ip,
8496 flags = self.config_flags.NAT_IS_INSIDE
8497 self.vapi.nat64_add_del_interface(is_add=1, flags=flags,
8498 sw_if_index=self.pg0.sw_if_index)
8499 self.vapi.nat64_add_del_interface(is_add=1, flags=0,
8500 sw_if_index=self.pg1.sw_if_index)
8502 self.vapi.nat64_add_del_static_bib(i_addr=server.ip6n,
8503 o_addr=server_nat_ip,
8504 i_port=server_tcp_in_port,
8505 o_port=server_tcp_out_port,
8506 proto=IP_PROTOS.tcp, vrf_id=0,
8509 self.vapi.nat64_add_del_static_bib(i_addr=server.ip6n,
8510 o_addr=server_nat_ip, i_port=0,
8512 proto=IP_PROTOS.gre, vrf_id=0,
8515 self.vapi.nat64_add_del_static_bib(i_addr=client.ip6n,
8516 o_addr=client_nat_ip,
8517 i_port=client_tcp_in_port,
8518 o_port=client_tcp_out_port,
8519 proto=IP_PROTOS.tcp, vrf_id=0,
8523 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
8524 IPv6(src=client.ip6, dst=server_nat_ip6) /
8525 TCP(sport=client_tcp_in_port, dport=server_tcp_out_port))
8526 self.pg0.add_stream(p)
8527 self.pg_enable_capture(self.pg_interfaces)
8529 p = self.pg0.get_capture(1)
8531 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
8532 IPv6(src=client.ip6, dst=server_nat_ip6, nh=IP_PROTOS.gre) /
8534 IP(src=self.pg2.local_ip4, dst=self.pg2.remote_ip4) /
8535 TCP(sport=1234, dport=1234))
8536 self.pg0.add_stream(p)
8537 self.pg_enable_capture(self.pg_interfaces)
8539 p = self.pg0.get_capture(1)
8542 self.assertEqual(packet[IPv6].src, client_nat_ip6)
8543 self.assertEqual(packet[IPv6].dst, server.ip6)
8544 self.assertEqual(packet[IPv6].nh, IP_PROTOS.gre)
8546 self.logger.error(ppp("Unexpected or invalid packet:", packet))
8550 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
8551 IPv6(src=server.ip6, dst=client_nat_ip6, nh=IP_PROTOS.gre) /
8553 IP(src=self.pg2.remote_ip4, dst=self.pg2.local_ip4) /
8554 TCP(sport=1234, dport=1234))
8555 self.pg0.add_stream(p)
8556 self.pg_enable_capture(self.pg_interfaces)
8558 p = self.pg0.get_capture(1)
8561 self.assertEqual(packet[IPv6].src, server_nat_ip6)
8562 self.assertEqual(packet[IPv6].dst, client.ip6)
8563 self.assertEqual(packet[IPv6].nh, IP_PROTOS.gre)
8565 self.logger.error(ppp("Unexpected or invalid packet:", packet))
8568 def test_one_armed_nat64(self):
8569 """ One armed NAT64 """
8571 remote_host_ip6 = self.compose_ip6(self.pg3.remote_ip4,
8575 self.vapi.nat64_add_del_pool_addr_range(start_addr=self.nat_addr,
8576 end_addr=self.nat_addr,
8579 flags = self.config_flags.NAT_IS_INSIDE
8580 self.vapi.nat64_add_del_interface(is_add=1, flags=flags,
8581 sw_if_index=self.pg3.sw_if_index)
8582 self.vapi.nat64_add_del_interface(is_add=1, flags=0,
8583 sw_if_index=self.pg3.sw_if_index)
8586 p = (Ether(src=self.pg3.remote_mac, dst=self.pg3.local_mac) /
8587 IPv6(src=self.pg3.remote_ip6, dst=remote_host_ip6) /
8588 TCP(sport=12345, dport=80))
8589 self.pg3.add_stream(p)
8590 self.pg_enable_capture(self.pg_interfaces)
8592 capture = self.pg3.get_capture(1)
8597 self.assertEqual(ip.src, self.nat_addr)
8598 self.assertEqual(ip.dst, self.pg3.remote_ip4)
8599 self.assertNotEqual(tcp.sport, 12345)
8600 external_port = tcp.sport
8601 self.assertEqual(tcp.dport, 80)
8602 self.assert_packet_checksums_valid(p)
8604 self.logger.error(ppp("Unexpected or invalid packet:", p))
8608 p = (Ether(src=self.pg3.remote_mac, dst=self.pg3.local_mac) /
8609 IP(src=self.pg3.remote_ip4, dst=self.nat_addr) /
8610 TCP(sport=80, dport=external_port))
8611 self.pg3.add_stream(p)
8612 self.pg_enable_capture(self.pg_interfaces)
8614 capture = self.pg3.get_capture(1)
8619 self.assertEqual(ip.src, remote_host_ip6)
8620 self.assertEqual(ip.dst, self.pg3.remote_ip6)
8621 self.assertEqual(tcp.sport, 80)
8622 self.assertEqual(tcp.dport, 12345)
8623 self.assert_packet_checksums_valid(p)
8625 self.logger.error(ppp("Unexpected or invalid packet:", p))
8628 def test_frag_in_order(self):
8629 """ NAT64 translate fragments arriving in order """
8630 self.tcp_port_in = random.randint(1025, 65535)
8632 self.vapi.nat64_add_del_pool_addr_range(start_addr=self.nat_addr,
8633 end_addr=self.nat_addr,
8636 flags = self.config_flags.NAT_IS_INSIDE
8637 self.vapi.nat64_add_del_interface(is_add=1, flags=flags,
8638 sw_if_index=self.pg0.sw_if_index)
8639 self.vapi.nat64_add_del_interface(is_add=1, flags=0,
8640 sw_if_index=self.pg1.sw_if_index)
8642 reass = self.vapi.nat_reass_dump()
8643 reass_n_start = len(reass)
8647 pkts = self.create_stream_frag_ip6(self.pg0, self.pg1.remote_ip4,
8648 self.tcp_port_in, 20, data)
8649 self.pg0.add_stream(pkts)
8650 self.pg_enable_capture(self.pg_interfaces)
8652 frags = self.pg1.get_capture(len(pkts))
8653 p = self.reass_frags_and_verify(frags,
8655 self.pg1.remote_ip4)
8656 self.assertEqual(p[TCP].dport, 20)
8657 self.assertNotEqual(p[TCP].sport, self.tcp_port_in)
8658 self.tcp_port_out = p[TCP].sport
8659 self.assertEqual(data, p[Raw].load)
8662 data = b"A" * 4 + b"b" * 16 + b"C" * 3
8663 pkts = self.create_stream_frag(self.pg1,
8668 self.pg1.add_stream(pkts)
8669 self.pg_enable_capture(self.pg_interfaces)
8671 frags = self.pg0.get_capture(len(pkts))
8672 src = self.compose_ip6(self.pg1.remote_ip4, '64:ff9b::', 96)
8673 p = self.reass_frags_and_verify_ip6(frags, src, self.pg0.remote_ip6)
8674 self.assertEqual(p[TCP].sport, 20)
8675 self.assertEqual(p[TCP].dport, self.tcp_port_in)
8676 self.assertEqual(data, p[Raw].load)
8678 reass = self.vapi.nat_reass_dump()
8679 reass_n_end = len(reass)
8681 self.assertEqual(reass_n_end - reass_n_start, 2)
8683 def test_reass_hairpinning(self):
8684 """ NAT64 fragments hairpinning """
8686 server = self.pg0.remote_hosts[1]
8687 server_in_port = random.randint(1025, 65535)
8688 server_out_port = random.randint(1025, 65535)
8689 client_in_port = random.randint(1025, 65535)
8690 ip = IPv6(src=''.join(['64:ff9b::', self.nat_addr]))
8691 nat_addr_ip6 = ip.src
8693 self.vapi.nat64_add_del_pool_addr_range(start_addr=self.nat_addr,
8694 end_addr=self.nat_addr,
8697 flags = self.config_flags.NAT_IS_INSIDE
8698 self.vapi.nat64_add_del_interface(is_add=1, flags=flags,
8699 sw_if_index=self.pg0.sw_if_index)
8700 self.vapi.nat64_add_del_interface(is_add=1, flags=0,
8701 sw_if_index=self.pg1.sw_if_index)
8703 # add static BIB entry for server
8704 self.vapi.nat64_add_del_static_bib(i_addr=server.ip6n,
8705 o_addr=self.nat_addr,
8706 i_port=server_in_port,
8707 o_port=server_out_port,
8708 proto=IP_PROTOS.tcp, vrf_id=0,
8711 # send packet from host to server
8712 pkts = self.create_stream_frag_ip6(self.pg0,
8717 self.pg0.add_stream(pkts)
8718 self.pg_enable_capture(self.pg_interfaces)
8720 frags = self.pg0.get_capture(len(pkts))
8721 p = self.reass_frags_and_verify_ip6(frags, nat_addr_ip6, server.ip6)
8722 self.assertNotEqual(p[TCP].sport, client_in_port)
8723 self.assertEqual(p[TCP].dport, server_in_port)
8724 self.assertEqual(data, p[Raw].load)
8726 def test_frag_out_of_order(self):
8727 """ NAT64 translate fragments arriving out of order """
8728 self.tcp_port_in = random.randint(1025, 65535)
8730 self.vapi.nat64_add_del_pool_addr_range(start_addr=self.nat_addr,
8731 end_addr=self.nat_addr,
8734 flags = self.config_flags.NAT_IS_INSIDE
8735 self.vapi.nat64_add_del_interface(is_add=1, flags=flags,
8736 sw_if_index=self.pg0.sw_if_index)
8737 self.vapi.nat64_add_del_interface(is_add=1, flags=0,
8738 sw_if_index=self.pg1.sw_if_index)
8742 pkts = self.create_stream_frag_ip6(self.pg0, self.pg1.remote_ip4,
8743 self.tcp_port_in, 20, data)
8745 self.pg0.add_stream(pkts)
8746 self.pg_enable_capture(self.pg_interfaces)
8748 frags = self.pg1.get_capture(len(pkts))
8749 p = self.reass_frags_and_verify(frags,
8751 self.pg1.remote_ip4)
8752 self.assertEqual(p[TCP].dport, 20)
8753 self.assertNotEqual(p[TCP].sport, self.tcp_port_in)
8754 self.tcp_port_out = p[TCP].sport
8755 self.assertEqual(data, p[Raw].load)
8758 data = b"A" * 4 + b"B" * 16 + b"C" * 3
8759 pkts = self.create_stream_frag(self.pg1,
8765 self.pg1.add_stream(pkts)
8766 self.pg_enable_capture(self.pg_interfaces)
8768 frags = self.pg0.get_capture(len(pkts))
8769 src = self.compose_ip6(self.pg1.remote_ip4, '64:ff9b::', 96)
8770 p = self.reass_frags_and_verify_ip6(frags, src, self.pg0.remote_ip6)
8771 self.assertEqual(p[TCP].sport, 20)
8772 self.assertEqual(p[TCP].dport, self.tcp_port_in)
8773 self.assertEqual(data, p[Raw].load)
8775 def test_interface_addr(self):
8776 """ Acquire NAT64 pool addresses from interface """
8777 self.vapi.nat64_add_del_interface_addr(
8779 sw_if_index=self.pg4.sw_if_index)
8781 # no address in NAT64 pool
8782 addresses = self.vapi.nat44_address_dump()
8783 self.assertEqual(0, len(addresses))
8785 # configure interface address and check NAT64 address pool
8786 self.pg4.config_ip4()
8787 addresses = self.vapi.nat64_pool_addr_dump()
8788 self.assertEqual(len(addresses), 1)
8790 self.assertEqual(str(addresses[0].address),
8793 # remove interface address and check NAT64 address pool
8794 self.pg4.unconfig_ip4()
8795 addresses = self.vapi.nat64_pool_addr_dump()
8796 self.assertEqual(0, len(addresses))
8798 @unittest.skipUnless(running_extended_tests, "part of extended tests")
8799 def test_ipfix_max_bibs_sessions(self):
8800 """ IPFIX logging maximum session and BIB entries exceeded """
8803 remote_host_ip6 = self.compose_ip6(self.pg1.remote_ip4,
8807 self.vapi.nat64_add_del_pool_addr_range(start_addr=self.nat_addr,
8808 end_addr=self.nat_addr,
8811 flags = self.config_flags.NAT_IS_INSIDE
8812 self.vapi.nat64_add_del_interface(is_add=1, flags=flags,
8813 sw_if_index=self.pg0.sw_if_index)
8814 self.vapi.nat64_add_del_interface(is_add=1, flags=0,
8815 sw_if_index=self.pg1.sw_if_index)
8819 for i in range(0, max_bibs):
8820 src = "fd01:aa::%x" % (i)
8821 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
8822 IPv6(src=src, dst=remote_host_ip6) /
8823 TCP(sport=12345, dport=80))
8825 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
8826 IPv6(src=src, dst=remote_host_ip6) /
8827 TCP(sport=12345, dport=22))
8829 self.pg0.add_stream(pkts)
8830 self.pg_enable_capture(self.pg_interfaces)
8832 self.pg1.get_capture(max_sessions)
8834 self.vapi.set_ipfix_exporter(collector_address=self.pg3.remote_ip4n,
8835 src_address=self.pg3.local_ip4n,
8837 template_interval=10)
8838 self.vapi.nat_ipfix_enable_disable(domain_id=self.ipfix_domain_id,
8839 src_port=self.ipfix_src_port,
8842 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
8843 IPv6(src=src, dst=remote_host_ip6) /
8844 TCP(sport=12345, dport=25))
8845 self.pg0.add_stream(p)
8846 self.pg_enable_capture(self.pg_interfaces)
8848 self.pg1.assert_nothing_captured()
8850 self.vapi.cli("ipfix flush") # FIXME this should be an API call
8851 capture = self.pg3.get_capture(9)
8852 ipfix = IPFIXDecoder()
8853 # first load template
8855 self.assertTrue(p.haslayer(IPFIX))
8856 self.assertEqual(p[IP].src, self.pg3.local_ip4)
8857 self.assertEqual(p[IP].dst, self.pg3.remote_ip4)
8858 self.assertEqual(p[UDP].sport, self.ipfix_src_port)
8859 self.assertEqual(p[UDP].dport, 4739)
8860 self.assertEqual(p[IPFIX].observationDomainID,
8861 self.ipfix_domain_id)
8862 if p.haslayer(Template):
8863 ipfix.add_template(p.getlayer(Template))
8864 # verify events in data set
8866 if p.haslayer(Data):
8867 data = ipfix.decode_data_set(p.getlayer(Set))
8868 self.verify_ipfix_max_sessions(data, max_sessions)
8870 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
8871 IPv6(src=self.pg0.remote_ip6, dst=remote_host_ip6) /
8872 TCP(sport=12345, dport=80))
8873 self.pg0.add_stream(p)
8874 self.pg_enable_capture(self.pg_interfaces)
8876 self.pg1.assert_nothing_captured()
8878 self.vapi.cli("ipfix flush") # FIXME this should be an API call
8879 capture = self.pg3.get_capture(1)
8880 # verify events in data set
8882 self.assertTrue(p.haslayer(IPFIX))
8883 self.assertEqual(p[IP].src, self.pg3.local_ip4)
8884 self.assertEqual(p[IP].dst, self.pg3.remote_ip4)
8885 self.assertEqual(p[UDP].sport, self.ipfix_src_port)
8886 self.assertEqual(p[UDP].dport, 4739)
8887 self.assertEqual(p[IPFIX].observationDomainID,
8888 self.ipfix_domain_id)
8889 if p.haslayer(Data):
8890 data = ipfix.decode_data_set(p.getlayer(Set))
8891 self.verify_ipfix_max_bibs(data, max_bibs)
8893 def test_ipfix_max_frags(self):
8894 """ IPFIX logging maximum fragments pending reassembly exceeded """
8895 self.vapi.nat64_add_del_pool_addr_range(start_addr=self.nat_addr,
8896 end_addr=self.nat_addr,
8899 flags = self.config_flags.NAT_IS_INSIDE
8900 self.vapi.nat64_add_del_interface(is_add=1, flags=flags,
8901 sw_if_index=self.pg0.sw_if_index)
8902 self.vapi.nat64_add_del_interface(is_add=1, flags=0,
8903 sw_if_index=self.pg1.sw_if_index)
8904 self.vapi.nat_set_reass(timeout=2, max_reass=1024, max_frag=1,
8905 drop_frag=0, is_ip6=1)
8906 self.vapi.set_ipfix_exporter(collector_address=self.pg3.remote_ip4n,
8907 src_address=self.pg3.local_ip4n,
8909 template_interval=10)
8910 self.vapi.nat_ipfix_enable_disable(domain_id=self.ipfix_domain_id,
8911 src_port=self.ipfix_src_port,
8915 pkts = self.create_stream_frag_ip6(self.pg0, self.pg1.remote_ip4,
8916 self.tcp_port_in, 20, data)
8918 self.pg0.add_stream(pkts)
8919 self.pg_enable_capture(self.pg_interfaces)
8921 self.pg1.assert_nothing_captured()
8923 self.vapi.cli("ipfix flush") # FIXME this should be an API call
8924 capture = self.pg3.get_capture(9)
8925 ipfix = IPFIXDecoder()
8926 # first load template
8928 self.assertTrue(p.haslayer(IPFIX))
8929 self.assertEqual(p[IP].src, self.pg3.local_ip4)
8930 self.assertEqual(p[IP].dst, self.pg3.remote_ip4)
8931 self.assertEqual(p[UDP].sport, self.ipfix_src_port)
8932 self.assertEqual(p[UDP].dport, 4739)
8933 self.assertEqual(p[IPFIX].observationDomainID,
8934 self.ipfix_domain_id)
8935 if p.haslayer(Template):
8936 ipfix.add_template(p.getlayer(Template))
8937 # verify events in data set
8939 if p.haslayer(Data):
8940 data = ipfix.decode_data_set(p.getlayer(Set))
8941 self.verify_ipfix_max_fragments_ip6(data, 1,
8942 self.pg0.remote_ip6n)
8944 def test_ipfix_bib_ses(self):
8945 """ IPFIX logging NAT64 BIB/session create and delete events """
8946 self.tcp_port_in = random.randint(1025, 65535)
8947 remote_host_ip6 = self.compose_ip6(self.pg1.remote_ip4,
8951 self.vapi.nat64_add_del_pool_addr_range(start_addr=self.nat_addr,
8952 end_addr=self.nat_addr,
8955 flags = self.config_flags.NAT_IS_INSIDE
8956 self.vapi.nat64_add_del_interface(is_add=1, flags=flags,
8957 sw_if_index=self.pg0.sw_if_index)
8958 self.vapi.nat64_add_del_interface(is_add=1, flags=0,
8959 sw_if_index=self.pg1.sw_if_index)
8960 self.vapi.set_ipfix_exporter(collector_address=self.pg3.remote_ip4n,
8961 src_address=self.pg3.local_ip4n,
8963 template_interval=10)
8964 self.vapi.nat_ipfix_enable_disable(domain_id=self.ipfix_domain_id,
8965 src_port=self.ipfix_src_port,
8969 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
8970 IPv6(src=self.pg0.remote_ip6, dst=remote_host_ip6) /
8971 TCP(sport=self.tcp_port_in, dport=25))
8972 self.pg0.add_stream(p)
8973 self.pg_enable_capture(self.pg_interfaces)
8975 p = self.pg1.get_capture(1)
8976 self.tcp_port_out = p[0][TCP].sport
8977 self.vapi.cli("ipfix flush") # FIXME this should be an API call
8978 capture = self.pg3.get_capture(10)
8979 ipfix = IPFIXDecoder()
8980 # first load template
8982 self.assertTrue(p.haslayer(IPFIX))
8983 self.assertEqual(p[IP].src, self.pg3.local_ip4)
8984 self.assertEqual(p[IP].dst, self.pg3.remote_ip4)
8985 self.assertEqual(p[UDP].sport, self.ipfix_src_port)
8986 self.assertEqual(p[UDP].dport, 4739)
8987 self.assertEqual(p[IPFIX].observationDomainID,
8988 self.ipfix_domain_id)
8989 if p.haslayer(Template):
8990 ipfix.add_template(p.getlayer(Template))
8991 # verify events in data set
8993 if p.haslayer(Data):
8994 data = ipfix.decode_data_set(p.getlayer(Set))
8995 if scapy.compat.orb(data[0][230]) == 10:
8996 self.verify_ipfix_bib(data, 1, self.pg0.remote_ip6n)
8997 elif scapy.compat.orb(data[0][230]) == 6:
8998 self.verify_ipfix_nat64_ses(data,
9000 self.pg0.remote_ip6n,
9001 self.pg1.remote_ip4,
9004 self.logger.error(ppp("Unexpected or invalid packet: ", p))
9007 self.pg_enable_capture(self.pg_interfaces)
9008 self.vapi.nat64_add_del_pool_addr_range(start_addr=self.nat_addr,
9009 end_addr=self.nat_addr,
9012 self.vapi.cli("ipfix flush") # FIXME this should be an API call
9013 capture = self.pg3.get_capture(2)
9014 # verify events in data set
9016 self.assertTrue(p.haslayer(IPFIX))
9017 self.assertEqual(p[IP].src, self.pg3.local_ip4)
9018 self.assertEqual(p[IP].dst, self.pg3.remote_ip4)
9019 self.assertEqual(p[UDP].sport, self.ipfix_src_port)
9020 self.assertEqual(p[UDP].dport, 4739)
9021 self.assertEqual(p[IPFIX].observationDomainID,
9022 self.ipfix_domain_id)
9023 if p.haslayer(Data):
9024 data = ipfix.decode_data_set(p.getlayer(Set))
9025 if scapy.compat.orb(data[0][230]) == 11:
9026 self.verify_ipfix_bib(data, 0, self.pg0.remote_ip6n)
9027 elif scapy.compat.orb(data[0][230]) == 7:
9028 self.verify_ipfix_nat64_ses(data,
9030 self.pg0.remote_ip6n,
9031 self.pg1.remote_ip4,
9034 self.logger.error(ppp("Unexpected or invalid packet: ", p))
9036 def test_syslog_sess(self):
9037 """ Test syslog session creation and deletion """
9038 self.tcp_port_in = random.randint(1025, 65535)
9039 remote_host_ip6 = self.compose_ip6(self.pg1.remote_ip4,
9043 self.vapi.nat64_add_del_pool_addr_range(start_addr=self.nat_addr,
9044 end_addr=self.nat_addr,
9047 flags = self.config_flags.NAT_IS_INSIDE
9048 self.vapi.nat64_add_del_interface(is_add=1, flags=flags,
9049 sw_if_index=self.pg0.sw_if_index)
9050 self.vapi.nat64_add_del_interface(is_add=1, flags=0,
9051 sw_if_index=self.pg1.sw_if_index)
9052 self.vapi.syslog_set_filter(
9053 self.SYSLOG_SEVERITY.SYSLOG_API_SEVERITY_INFO)
9054 self.vapi.syslog_set_sender(self.pg3.local_ip4n, self.pg3.remote_ip4n)
9056 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
9057 IPv6(src=self.pg0.remote_ip6, dst=remote_host_ip6) /
9058 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port))
9059 self.pg0.add_stream(p)
9060 self.pg_enable_capture(self.pg_interfaces)
9062 p = self.pg1.get_capture(1)
9063 self.tcp_port_out = p[0][TCP].sport
9064 capture = self.pg3.get_capture(1)
9065 self.verify_syslog_sess(capture[0][Raw].load, is_ip6=True)
9067 self.pg_enable_capture(self.pg_interfaces)
9069 self.vapi.nat64_add_del_pool_addr_range(start_addr=self.nat_addr,
9070 end_addr=self.nat_addr,
9073 capture = self.pg3.get_capture(1)
9074 self.verify_syslog_sess(capture[0][Raw].load, False, True)
9076 def nat64_get_ses_num(self):
9078 Return number of active NAT64 sessions.
9080 st = self.vapi.nat64_st_dump(proto=255)
9083 def clear_nat64(self):
9085 Clear NAT64 configuration.
9087 self.vapi.nat_ipfix_enable_disable(domain_id=self.ipfix_domain_id,
9088 src_port=self.ipfix_src_port,
9090 self.ipfix_src_port = 4739
9091 self.ipfix_domain_id = 1
9093 self.vapi.syslog_set_filter(
9094 self.SYSLOG_SEVERITY.SYSLOG_API_SEVERITY_EMERG)
9096 self.vapi.nat_set_timeouts(udp=300, tcp_established=7440,
9097 tcp_transitory=240, icmp=60)
9099 interfaces = self.vapi.nat64_interface_dump()
9100 for intf in interfaces:
9101 self.vapi.nat64_add_del_interface(is_add=0, flags=intf.flags,
9102 sw_if_index=intf.sw_if_index)
9104 bib = self.vapi.nat64_bib_dump(proto=255)
9106 if bibe.flags & self.config_flags.NAT_IS_STATIC:
9107 self.vapi.nat64_add_del_static_bib(i_addr=bibe.i_addr,
9115 adresses = self.vapi.nat64_pool_addr_dump()
9116 for addr in adresses:
9117 self.vapi.nat64_add_del_pool_addr_range(start_addr=addr.address,
9118 end_addr=addr.address,
9122 prefixes = self.vapi.nat64_prefix_dump()
9123 for prefix in prefixes:
9124 self.vapi.nat64_add_del_prefix(prefix=str(prefix.prefix),
9125 vrf_id=prefix.vrf_id, is_add=0)
9127 bibs = self.statistics.get_counter('/nat64/total-bibs')
9128 self.assertEqual(bibs[0][0], 0)
9129 sessions = self.statistics.get_counter('/nat64/total-sessions')
9130 self.assertEqual(sessions[0][0], 0)
9133 super(TestNAT64, self).tearDown()
9134 if not self.vpp_dead:
9137 def show_commands_at_teardown(self):
9138 self.logger.info(self.vapi.cli("show nat64 pool"))
9139 self.logger.info(self.vapi.cli("show nat64 interfaces"))
9140 self.logger.info(self.vapi.cli("show nat64 prefix"))
9141 self.logger.info(self.vapi.cli("show nat64 bib all"))
9142 self.logger.info(self.vapi.cli("show nat64 session table all"))
9143 self.logger.info(self.vapi.cli("show nat virtual-reassembly"))
9146 class TestDSlite(MethodHolder):
9147 """ DS-Lite Test Cases """
9150 def setUpClass(cls):
9151 super(TestDSlite, cls).setUpClass()
9154 cls.nat_addr = '10.0.0.3'
9156 cls.create_pg_interfaces(range(3))
9158 cls.pg0.config_ip4()
9159 cls.pg0.resolve_arp()
9161 cls.pg1.config_ip6()
9162 cls.pg1.generate_remote_hosts(2)
9163 cls.pg1.configure_ipv6_neighbors()
9165 cls.pg2.config_ip4()
9166 cls.pg2.resolve_arp()
9169 super(TestDSlite, cls).tearDownClass()
9173 def tearDownClass(cls):
9174 super(TestDSlite, cls).tearDownClass()
9176 def verify_syslog_apmadd(self, data, isaddr, isport, xsaddr, xsport,
9178 message = data.decode('utf-8')
9180 message = SyslogMessage.parse(message)
9181 except ParseError as e:
9182 self.logger.error(e)
9184 self.assertEqual(message.severity, SyslogSeverity.info)
9185 self.assertEqual(message.appname, 'NAT')
9186 self.assertEqual(message.msgid, 'APMADD')
9187 sd_params = message.sd.get('napmap')
9188 self.assertTrue(sd_params is not None)
9189 self.assertEqual(sd_params.get('IATYP'), 'IPv4')
9190 self.assertEqual(sd_params.get('ISADDR'), isaddr)
9191 self.assertEqual(sd_params.get('ISPORT'), "%d" % isport)
9192 self.assertEqual(sd_params.get('XATYP'), 'IPv4')
9193 self.assertEqual(sd_params.get('XSADDR'), xsaddr)
9194 self.assertEqual(sd_params.get('XSPORT'), "%d" % xsport)
9195 self.assertEqual(sd_params.get('PROTO'), "%d" % proto)
9196 self.assertTrue(sd_params.get('SSUBIX') is not None)
9197 self.assertEqual(sd_params.get('SV6ENC'), sv6enc)
9199 def test_dslite(self):
9200 """ Test DS-Lite """
9201 nat_config = self.vapi.nat_show_config()
9202 self.assertEqual(0, nat_config.dslite_ce)
9204 self.vapi.dslite_add_del_pool_addr_range(start_addr=self.nat_addr,
9205 end_addr=self.nat_addr,
9207 aftr_ip4 = '192.0.0.1'
9208 aftr_ip6 = '2001:db8:85a3::8a2e:370:1'
9209 self.vapi.dslite_set_aftr_addr(ip4_addr=aftr_ip4, ip6_addr=aftr_ip6)
9210 self.vapi.syslog_set_sender(self.pg2.local_ip4n, self.pg2.remote_ip4n)
9213 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
9214 IPv6(dst=aftr_ip6, src=self.pg1.remote_hosts[0].ip6) /
9215 IP(dst=self.pg0.remote_ip4, src='192.168.1.1') /
9216 UDP(sport=20000, dport=10000))
9217 self.pg1.add_stream(p)
9218 self.pg_enable_capture(self.pg_interfaces)
9220 capture = self.pg0.get_capture(1)
9221 capture = capture[0]
9222 self.assertFalse(capture.haslayer(IPv6))
9223 self.assertEqual(capture[IP].src, self.nat_addr)
9224 self.assertEqual(capture[IP].dst, self.pg0.remote_ip4)
9225 self.assertNotEqual(capture[UDP].sport, 20000)
9226 self.assertEqual(capture[UDP].dport, 10000)
9227 self.assert_packet_checksums_valid(capture)
9228 out_port = capture[UDP].sport
9229 capture = self.pg2.get_capture(1)
9230 self.verify_syslog_apmadd(capture[0][Raw].load, '192.168.1.1',
9231 20000, self.nat_addr, out_port,
9232 self.pg1.remote_hosts[0].ip6, IP_PROTOS.udp)
9234 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
9235 IP(dst=self.nat_addr, src=self.pg0.remote_ip4) /
9236 UDP(sport=10000, dport=out_port))
9237 self.pg0.add_stream(p)
9238 self.pg_enable_capture(self.pg_interfaces)
9240 capture = self.pg1.get_capture(1)
9241 capture = capture[0]
9242 self.assertEqual(capture[IPv6].src, aftr_ip6)
9243 self.assertEqual(capture[IPv6].dst, self.pg1.remote_hosts[0].ip6)
9244 self.assertEqual(capture[IP].src, self.pg0.remote_ip4)
9245 self.assertEqual(capture[IP].dst, '192.168.1.1')
9246 self.assertEqual(capture[UDP].sport, 10000)
9247 self.assertEqual(capture[UDP].dport, 20000)
9248 self.assert_packet_checksums_valid(capture)
9251 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
9252 IPv6(dst=aftr_ip6, src=self.pg1.remote_hosts[1].ip6) /
9253 IP(dst=self.pg0.remote_ip4, src='192.168.1.1') /
9254 TCP(sport=20001, dport=10001))
9255 self.pg1.add_stream(p)
9256 self.pg_enable_capture(self.pg_interfaces)
9258 capture = self.pg0.get_capture(1)
9259 capture = capture[0]
9260 self.assertFalse(capture.haslayer(IPv6))
9261 self.assertEqual(capture[IP].src, self.nat_addr)
9262 self.assertEqual(capture[IP].dst, self.pg0.remote_ip4)
9263 self.assertNotEqual(capture[TCP].sport, 20001)
9264 self.assertEqual(capture[TCP].dport, 10001)
9265 self.assert_packet_checksums_valid(capture)
9266 out_port = capture[TCP].sport
9268 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
9269 IP(dst=self.nat_addr, src=self.pg0.remote_ip4) /
9270 TCP(sport=10001, dport=out_port))
9271 self.pg0.add_stream(p)
9272 self.pg_enable_capture(self.pg_interfaces)
9274 capture = self.pg1.get_capture(1)
9275 capture = capture[0]
9276 self.assertEqual(capture[IPv6].src, aftr_ip6)
9277 self.assertEqual(capture[IPv6].dst, self.pg1.remote_hosts[1].ip6)
9278 self.assertEqual(capture[IP].src, self.pg0.remote_ip4)
9279 self.assertEqual(capture[IP].dst, '192.168.1.1')
9280 self.assertEqual(capture[TCP].sport, 10001)
9281 self.assertEqual(capture[TCP].dport, 20001)
9282 self.assert_packet_checksums_valid(capture)
9285 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
9286 IPv6(dst=aftr_ip6, src=self.pg1.remote_hosts[1].ip6) /
9287 IP(dst=self.pg0.remote_ip4, src='192.168.1.1') /
9288 ICMP(id=4000, type='echo-request'))
9289 self.pg1.add_stream(p)
9290 self.pg_enable_capture(self.pg_interfaces)
9292 capture = self.pg0.get_capture(1)
9293 capture = capture[0]
9294 self.assertFalse(capture.haslayer(IPv6))
9295 self.assertEqual(capture[IP].src, self.nat_addr)
9296 self.assertEqual(capture[IP].dst, self.pg0.remote_ip4)
9297 self.assertNotEqual(capture[ICMP].id, 4000)
9298 self.assert_packet_checksums_valid(capture)
9299 out_id = capture[ICMP].id
9301 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
9302 IP(dst=self.nat_addr, src=self.pg0.remote_ip4) /
9303 ICMP(id=out_id, type='echo-reply'))
9304 self.pg0.add_stream(p)
9305 self.pg_enable_capture(self.pg_interfaces)
9307 capture = self.pg1.get_capture(1)
9308 capture = capture[0]
9309 self.assertEqual(capture[IPv6].src, aftr_ip6)
9310 self.assertEqual(capture[IPv6].dst, self.pg1.remote_hosts[1].ip6)
9311 self.assertEqual(capture[IP].src, self.pg0.remote_ip4)
9312 self.assertEqual(capture[IP].dst, '192.168.1.1')
9313 self.assertEqual(capture[ICMP].id, 4000)
9314 self.assert_packet_checksums_valid(capture)
9316 # ping DS-Lite AFTR tunnel endpoint address
9317 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
9318 IPv6(src=self.pg1.remote_hosts[1].ip6, dst=aftr_ip6) /
9319 ICMPv6EchoRequest())
9320 self.pg1.add_stream(p)
9321 self.pg_enable_capture(self.pg_interfaces)
9323 capture = self.pg1.get_capture(1)
9324 capture = capture[0]
9325 self.assertEqual(capture[IPv6].src, aftr_ip6)
9326 self.assertEqual(capture[IPv6].dst, self.pg1.remote_hosts[1].ip6)
9327 self.assertTrue(capture.haslayer(ICMPv6EchoReply))
9329 b4s = self.statistics.get_counter('/dslite/total-b4s')
9330 self.assertEqual(b4s[0][0], 2)
9331 sessions = self.statistics.get_counter('/dslite/total-sessions')
9332 self.assertEqual(sessions[0][0], 3)
9335 super(TestDSlite, self).tearDown()
9337 def show_commands_at_teardown(self):
9338 self.logger.info(self.vapi.cli("show dslite pool"))
9340 self.vapi.cli("show dslite aftr-tunnel-endpoint-address"))
9341 self.logger.info(self.vapi.cli("show dslite sessions"))
9344 class TestDSliteCE(MethodHolder):
9345 """ DS-Lite CE Test Cases """
9348 def setUpConstants(cls):
9349 super(TestDSliteCE, cls).setUpConstants()
9350 cls.vpp_cmdline.extend(["nat", "{", "dslite ce", "}"])
9353 def setUpClass(cls):
9354 super(TestDSliteCE, cls).setUpClass()
9357 cls.create_pg_interfaces(range(2))
9359 cls.pg0.config_ip4()
9360 cls.pg0.resolve_arp()
9362 cls.pg1.config_ip6()
9363 cls.pg1.generate_remote_hosts(1)
9364 cls.pg1.configure_ipv6_neighbors()
9367 super(TestDSliteCE, cls).tearDownClass()
9371 def tearDownClass(cls):
9372 super(TestDSliteCE, cls).tearDownClass()
9374 def test_dslite_ce(self):
9375 """ Test DS-Lite CE """
9377 nat_config = self.vapi.nat_show_config()
9378 self.assertEqual(1, nat_config.dslite_ce)
9380 b4_ip4 = '192.0.0.2'
9381 b4_ip6 = '2001:db8:62aa::375e:f4c1:1'
9382 self.vapi.dslite_set_b4_addr(ip4_addr=b4_ip4, ip6_addr=b4_ip6)
9384 aftr_ip4 = '192.0.0.1'
9385 aftr_ip6 = '2001:db8:85a3::8a2e:370:1'
9386 aftr_ip6_n = socket.inet_pton(socket.AF_INET6, aftr_ip6)
9387 self.vapi.dslite_set_aftr_addr(ip4_addr=aftr_ip4, ip6_addr=aftr_ip6)
9389 self.vapi.ip_add_del_route(dst_address=aftr_ip6_n,
9390 dst_address_length=128,
9391 next_hop_address=self.pg1.remote_ip6n,
9392 next_hop_sw_if_index=self.pg1.sw_if_index,
9396 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
9397 IP(dst=self.pg1.remote_ip4, src=self.pg0.remote_ip4) /
9398 UDP(sport=10000, dport=20000))
9399 self.pg0.add_stream(p)
9400 self.pg_enable_capture(self.pg_interfaces)
9402 capture = self.pg1.get_capture(1)
9403 capture = capture[0]
9404 self.assertEqual(capture[IPv6].src, b4_ip6)
9405 self.assertEqual(capture[IPv6].dst, aftr_ip6)
9406 self.assertEqual(capture[IP].src, self.pg0.remote_ip4)
9407 self.assertEqual(capture[IP].dst, self.pg1.remote_ip4)
9408 self.assertEqual(capture[UDP].sport, 10000)
9409 self.assertEqual(capture[UDP].dport, 20000)
9410 self.assert_packet_checksums_valid(capture)
9413 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
9414 IPv6(dst=b4_ip6, src=aftr_ip6) /
9415 IP(dst=self.pg0.remote_ip4, src=self.pg1.remote_ip4) /
9416 UDP(sport=20000, dport=10000))
9417 self.pg1.add_stream(p)
9418 self.pg_enable_capture(self.pg_interfaces)
9420 capture = self.pg0.get_capture(1)
9421 capture = capture[0]
9422 self.assertFalse(capture.haslayer(IPv6))
9423 self.assertEqual(capture[IP].src, self.pg1.remote_ip4)
9424 self.assertEqual(capture[IP].dst, self.pg0.remote_ip4)
9425 self.assertEqual(capture[UDP].sport, 20000)
9426 self.assertEqual(capture[UDP].dport, 10000)
9427 self.assert_packet_checksums_valid(capture)
9429 # ping DS-Lite B4 tunnel endpoint address
9430 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
9431 IPv6(src=self.pg1.remote_hosts[0].ip6, dst=b4_ip6) /
9432 ICMPv6EchoRequest())
9433 self.pg1.add_stream(p)
9434 self.pg_enable_capture(self.pg_interfaces)
9436 capture = self.pg1.get_capture(1)
9437 capture = capture[0]
9438 self.assertEqual(capture[IPv6].src, b4_ip6)
9439 self.assertEqual(capture[IPv6].dst, self.pg1.remote_hosts[0].ip6)
9440 self.assertTrue(capture.haslayer(ICMPv6EchoReply))
9443 super(TestDSliteCE, self).tearDown()
9445 def show_commands_at_teardown(self):
9447 self.vapi.cli("show dslite aftr-tunnel-endpoint-address"))
9449 self.vapi.cli("show dslite b4-tunnel-endpoint-address"))
9452 class TestNAT66(MethodHolder):
9453 """ NAT66 Test Cases """
9456 def setUpClass(cls):
9457 super(TestNAT66, cls).setUpClass()
9460 cls.nat_addr = 'fd01:ff::2'
9462 cls.create_pg_interfaces(range(2))
9463 cls.interfaces = list(cls.pg_interfaces)
9465 for i in cls.interfaces:
9468 i.configure_ipv6_neighbors()
9471 super(TestNAT66, cls).tearDownClass()
9475 def tearDownClass(cls):
9476 super(TestNAT66, cls).tearDownClass()
9478 def test_static(self):
9479 """ 1:1 NAT66 test """
9480 flags = self.config_flags.NAT_IS_INSIDE
9481 self.vapi.nat66_add_del_interface(is_add=1, flags=flags,
9482 sw_if_index=self.pg0.sw_if_index)
9483 self.vapi.nat66_add_del_interface(is_add=1,
9484 sw_if_index=self.pg1.sw_if_index)
9485 self.vapi.nat66_add_del_static_mapping(
9486 local_ip_address=self.pg0.remote_ip6n,
9487 external_ip_address=self.nat_addr,
9492 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
9493 IPv6(src=self.pg0.remote_ip6, dst=self.pg1.remote_ip6) /
9496 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
9497 IPv6(src=self.pg0.remote_ip6, dst=self.pg1.remote_ip6) /
9500 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
9501 IPv6(src=self.pg0.remote_ip6, dst=self.pg1.remote_ip6) /
9502 ICMPv6EchoRequest())
9504 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
9505 IPv6(src=self.pg0.remote_ip6, dst=self.pg1.remote_ip6) /
9506 GRE() / IP() / TCP())
9508 self.pg0.add_stream(pkts)
9509 self.pg_enable_capture(self.pg_interfaces)
9511 capture = self.pg1.get_capture(len(pkts))
9512 for packet in capture:
9514 self.assertEqual(packet[IPv6].src, self.nat_addr)
9515 self.assertEqual(packet[IPv6].dst, self.pg1.remote_ip6)
9516 self.assert_packet_checksums_valid(packet)
9518 self.logger.error(ppp("Unexpected or invalid packet:", packet))
9523 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
9524 IPv6(src=self.pg1.remote_ip6, dst=self.nat_addr) /
9527 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
9528 IPv6(src=self.pg1.remote_ip6, dst=self.nat_addr) /
9531 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
9532 IPv6(src=self.pg1.remote_ip6, dst=self.nat_addr) /
9535 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
9536 IPv6(src=self.pg1.remote_ip6, dst=self.nat_addr) /
9537 GRE() / IP() / TCP())
9539 self.pg1.add_stream(pkts)
9540 self.pg_enable_capture(self.pg_interfaces)
9542 capture = self.pg0.get_capture(len(pkts))
9543 for packet in capture:
9545 self.assertEqual(packet[IPv6].src, self.pg1.remote_ip6)
9546 self.assertEqual(packet[IPv6].dst, self.pg0.remote_ip6)
9547 self.assert_packet_checksums_valid(packet)
9549 self.logger.error(ppp("Unexpected or invalid packet:", packet))
9552 sm = self.vapi.nat66_static_mapping_dump()
9553 self.assertEqual(len(sm), 1)
9554 self.assertEqual(sm[0].total_pkts, 8)
9556 def test_check_no_translate(self):
9557 """ NAT66 translate only when egress interface is outside interface """
9558 flags = self.config_flags.NAT_IS_INSIDE
9559 self.vapi.nat66_add_del_interface(is_add=1, flags=flags,
9560 sw_if_index=self.pg0.sw_if_index)
9561 self.vapi.nat66_add_del_interface(is_add=1, flags=flags,
9562 sw_if_index=self.pg1.sw_if_index)
9563 self.vapi.nat66_add_del_static_mapping(
9564 local_ip_address=self.pg0.remote_ip6n,
9565 external_ip_address=self.nat_addr,
9569 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
9570 IPv6(src=self.pg0.remote_ip6, dst=self.pg1.remote_ip6) /
9572 self.pg0.add_stream([p])
9573 self.pg_enable_capture(self.pg_interfaces)
9575 capture = self.pg1.get_capture(1)
9578 self.assertEqual(packet[IPv6].src, self.pg0.remote_ip6)
9579 self.assertEqual(packet[IPv6].dst, self.pg1.remote_ip6)
9581 self.logger.error(ppp("Unexpected or invalid packet:", packet))
9584 def clear_nat66(self):
9586 Clear NAT66 configuration.
9588 interfaces = self.vapi.nat66_interface_dump()
9589 for intf in interfaces:
9590 self.vapi.nat66_add_del_interface(is_add=0, flags=intf.flags,
9591 sw_if_index=intf.sw_if_index)
9593 static_mappings = self.vapi.nat66_static_mapping_dump()
9594 for sm in static_mappings:
9595 self.vapi.nat66_add_del_static_mapping(
9596 local_ip_address=sm.local_ip_address,
9597 external_ip_address=sm.external_ip_address, vrf_id=sm.vrf_id,
9601 super(TestNAT66, self).tearDown()
9604 def show_commands_at_teardown(self):
9605 self.logger.info(self.vapi.cli("show nat66 interfaces"))
9606 self.logger.info(self.vapi.cli("show nat66 static mappings"))
9609 if __name__ == '__main__':
9610 unittest.main(testRunner=VppTestRunner)