8 from framework import VppTestCase, VppTestRunner, running_extended_tests
9 from scapy.layers.inet import IP, TCP, UDP, ICMP
10 from scapy.layers.inet import IPerror, TCPerror, UDPerror, ICMPerror
11 from scapy.layers.inet6 import IPv6, ICMPv6EchoRequest, ICMPv6EchoReply, \
12 ICMPv6ND_NS, ICMPv6ND_NA, ICMPv6NDOptDstLLAddr, fragment6
13 from scapy.layers.inet6 import ICMPv6DestUnreach, IPerror6, IPv6ExtHdrFragment
14 from scapy.layers.l2 import Ether, ARP, GRE
15 from scapy.data import IP_PROTOS
16 from scapy.packet import bind_layers, Raw
18 from ipfix import IPFIX, Set, Template, Data, IPFIXDecoder
19 from time import sleep
20 from util import ip4_range
21 from vpp_papi import mac_pton
22 from syslog_rfc5424_parser import SyslogMessage, ParseError
23 from syslog_rfc5424_parser.constants import SyslogFacility, SyslogSeverity
24 from vpp_papi_provider import SYSLOG_SEVERITY
25 from io import BytesIO
26 from vpp_papi import VppEnum
27 from scapy.all import bind_layers, Packet, ByteEnumField, ShortField, \
28 IPField, IntField, LongField, XByteField, FlagsField, FieldLenField, \
32 # NAT HA protocol event data
35 fields_desc = [ByteEnumField("event_type", None,
36 {1: "add", 2: "del", 3: "refresh"}),
37 ByteEnumField("protocol", None,
38 {0: "udp", 1: "tcp", 2: "icmp"}),
39 ShortField("flags", 0),
40 IPField("in_addr", None),
41 IPField("out_addr", None),
42 ShortField("in_port", None),
43 ShortField("out_port", None),
44 IPField("eh_addr", None),
45 IPField("ehn_addr", None),
46 ShortField("eh_port", None),
47 ShortField("ehn_port", None),
48 IntField("fib_index", None),
49 IntField("total_pkts", 0),
50 LongField("total_bytes", 0)]
52 def extract_padding(self, s):
56 # NAT HA protocol header
57 class HANATStateSync(Packet):
58 name = "HA NAT state sync"
59 fields_desc = [XByteField("version", 1),
60 FlagsField("flags", 0, 8, ['ACK']),
61 FieldLenField("count", None, count_of="events"),
62 IntField("sequence_number", 1),
63 IntField("thread_index", 0),
64 PacketListField("events", [], Event,
65 count_from=lambda pkt: pkt.count)]
68 class MethodHolder(VppTestCase):
69 """ NAT create capture and verify method holder """
71 def clear_nat44(self):
73 Clear NAT44 configuration.
75 if hasattr(self, 'pg7') and hasattr(self, 'pg8'):
76 # I found no elegant way to do this
77 self.vapi.ip_add_del_route(
78 dst_address=self.pg7.remote_ip4n,
79 dst_address_length=32,
80 next_hop_address=self.pg7.remote_ip4n,
81 next_hop_sw_if_index=self.pg7.sw_if_index,
83 self.vapi.ip_add_del_route(
84 dst_address=self.pg8.remote_ip4n,
85 dst_address_length=32,
86 next_hop_address=self.pg8.remote_ip4n,
87 next_hop_sw_if_index=self.pg8.sw_if_index,
90 for intf in [self.pg7, self.pg8]:
91 self.vapi.ip_neighbor_add_del(
95 flags=(VppEnum.vl_api_ip_neighbor_flags_t.
96 IP_API_NEIGHBOR_FLAG_STATIC),
99 if self.pg7.has_ip4_config:
100 self.pg7.unconfig_ip4()
102 self.vapi.nat44_forwarding_enable_disable(0)
104 interfaces = self.vapi.nat44_interface_addr_dump()
105 for intf in interfaces:
106 self.vapi.nat44_add_del_interface_addr(intf.sw_if_index,
107 twice_nat=intf.twice_nat,
110 self.vapi.nat_ipfix_enable_disable(enable=0,
111 src_port=self.ipfix_src_port,
112 domain_id=self.ipfix_domain_id)
113 self.ipfix_src_port = 4739
114 self.ipfix_domain_id = 1
116 self.vapi.syslog_set_filter(SYSLOG_SEVERITY.EMERG)
118 self.vapi.nat_ha_set_listener('0.0.0.0', 0)
119 self.vapi.nat_ha_set_failover('0.0.0.0', 0)
121 interfaces = self.vapi.nat44_interface_dump()
122 for intf in interfaces:
123 if intf.is_inside > 1:
124 self.vapi.nat44_interface_add_del_feature(intf.sw_if_index,
127 self.vapi.nat44_interface_add_del_feature(intf.sw_if_index,
131 interfaces = self.vapi.nat44_interface_output_feature_dump()
132 for intf in interfaces:
133 self.vapi.nat44_interface_add_del_output_feature(intf.sw_if_index,
137 static_mappings = self.vapi.nat44_static_mapping_dump()
138 for sm in static_mappings:
139 self.vapi.nat44_add_del_static_mapping(
141 sm.external_ip_address,
142 local_port=sm.local_port,
143 external_port=sm.external_port,
144 addr_only=sm.addr_only,
146 protocol=sm.protocol,
147 twice_nat=sm.twice_nat,
148 self_twice_nat=sm.self_twice_nat,
149 out2in_only=sm.out2in_only,
151 external_sw_if_index=sm.external_sw_if_index,
154 lb_static_mappings = self.vapi.nat44_lb_static_mapping_dump()
155 for lb_sm in lb_static_mappings:
156 self.vapi.nat44_add_del_lb_static_mapping(
160 twice_nat=lb_sm.twice_nat,
161 self_twice_nat=lb_sm.self_twice_nat,
162 out2in_only=lb_sm.out2in_only,
168 identity_mappings = self.vapi.nat44_identity_mapping_dump()
169 for id_m in identity_mappings:
170 self.vapi.nat44_add_del_identity_mapping(
171 addr_only=id_m.addr_only,
174 sw_if_index=id_m.sw_if_index,
176 protocol=id_m.protocol,
179 adresses = self.vapi.nat44_address_dump()
180 for addr in adresses:
181 self.vapi.nat44_add_del_address_range(addr.ip_address,
183 twice_nat=addr.twice_nat,
186 self.vapi.nat_set_reass()
187 self.vapi.nat_set_reass(is_ip6=1)
188 self.verify_no_nat44_user()
189 self.vapi.nat_set_timeouts()
190 self.vapi.nat_set_addr_and_port_alloc_alg()
191 self.vapi.nat_set_mss_clamping()
193 def nat44_add_static_mapping(self, local_ip, external_ip='0.0.0.0',
194 local_port=0, external_port=0, vrf_id=0,
195 is_add=1, external_sw_if_index=0xFFFFFFFF,
196 proto=0, twice_nat=0, self_twice_nat=0,
197 out2in_only=0, tag=""):
199 Add/delete NAT44 static mapping
201 :param local_ip: Local IP address
202 :param external_ip: External IP address
203 :param local_port: Local port number (Optional)
204 :param external_port: External port number (Optional)
205 :param vrf_id: VRF ID (Default 0)
206 :param is_add: 1 if add, 0 if delete (Default add)
207 :param external_sw_if_index: External interface instead of IP address
208 :param proto: IP protocol (Mandatory if port specified)
209 :param twice_nat: 1 if translate external host address and port
210 :param self_twice_nat: 1 if translate external host address and port
211 whenever external host address equals
212 local address of internal host
213 :param out2in_only: if 1 rule is matching only out2in direction
214 :param tag: Opaque string tag
217 if local_port and external_port:
219 l_ip = socket.inet_pton(socket.AF_INET, local_ip)
220 e_ip = socket.inet_pton(socket.AF_INET, external_ip)
221 self.vapi.nat44_add_del_static_mapping(
224 external_sw_if_index,
236 def nat44_add_address(self, ip, is_add=1, vrf_id=0xFFFFFFFF, twice_nat=0):
238 Add/delete NAT44 address
240 :param ip: IP address
241 :param is_add: 1 if add, 0 if delete (Default add)
242 :param twice_nat: twice NAT address for extenal hosts
244 nat_addr = socket.inet_pton(socket.AF_INET, ip)
245 self.vapi.nat44_add_del_address_range(nat_addr, nat_addr, is_add,
249 def create_stream_in(self, in_if, out_if, dst_ip=None, ttl=64):
251 Create packet stream for inside network
253 :param in_if: Inside interface
254 :param out_if: Outside interface
255 :param dst_ip: Destination address
256 :param ttl: TTL of generated packets
259 dst_ip = out_if.remote_ip4
263 p = (Ether(dst=in_if.local_mac, src=in_if.remote_mac) /
264 IP(src=in_if.remote_ip4, dst=dst_ip, ttl=ttl) /
265 TCP(sport=self.tcp_port_in, dport=20))
269 p = (Ether(dst=in_if.local_mac, src=in_if.remote_mac) /
270 IP(src=in_if.remote_ip4, dst=dst_ip, ttl=ttl) /
271 UDP(sport=self.udp_port_in, dport=20))
275 p = (Ether(dst=in_if.local_mac, src=in_if.remote_mac) /
276 IP(src=in_if.remote_ip4, dst=dst_ip, ttl=ttl) /
277 ICMP(id=self.icmp_id_in, type='echo-request'))
282 def compose_ip6(self, ip4, pref, plen):
284 Compose IPv4-embedded IPv6 addresses
286 :param ip4: IPv4 address
287 :param pref: IPv6 prefix
288 :param plen: IPv6 prefix length
289 :returns: IPv4-embedded IPv6 addresses
291 pref_n = list(socket.inet_pton(socket.AF_INET6, pref))
292 ip4_n = list(socket.inet_pton(socket.AF_INET, ip4))
307 pref_n[10] = ip4_n[3]
311 pref_n[10] = ip4_n[2]
312 pref_n[11] = ip4_n[3]
315 pref_n[10] = ip4_n[1]
316 pref_n[11] = ip4_n[2]
317 pref_n[12] = ip4_n[3]
319 pref_n[12] = ip4_n[0]
320 pref_n[13] = ip4_n[1]
321 pref_n[14] = ip4_n[2]
322 pref_n[15] = ip4_n[3]
323 return socket.inet_ntop(socket.AF_INET6, ''.join(pref_n))
325 def extract_ip4(self, ip6, plen):
327 Extract IPv4 address embedded in IPv6 addresses
329 :param ip6: IPv6 address
330 :param plen: IPv6 prefix length
331 :returns: extracted IPv4 address
333 ip6_n = list(socket.inet_pton(socket.AF_INET6, ip6))
365 return socket.inet_ntop(socket.AF_INET, ''.join(ip4_n))
367 def create_stream_in_ip6(self, in_if, out_if, hlim=64, pref=None, plen=0):
369 Create IPv6 packet stream for inside network
371 :param in_if: Inside interface
372 :param out_if: Outside interface
373 :param ttl: Hop Limit of generated packets
374 :param pref: NAT64 prefix
375 :param plen: NAT64 prefix length
379 dst = ''.join(['64:ff9b::', out_if.remote_ip4])
381 dst = self.compose_ip6(out_if.remote_ip4, pref, plen)
384 p = (Ether(dst=in_if.local_mac, src=in_if.remote_mac) /
385 IPv6(src=in_if.remote_ip6, dst=dst, hlim=hlim) /
386 TCP(sport=self.tcp_port_in, dport=20))
390 p = (Ether(dst=in_if.local_mac, src=in_if.remote_mac) /
391 IPv6(src=in_if.remote_ip6, dst=dst, hlim=hlim) /
392 UDP(sport=self.udp_port_in, dport=20))
396 p = (Ether(dst=in_if.local_mac, src=in_if.remote_mac) /
397 IPv6(src=in_if.remote_ip6, dst=dst, hlim=hlim) /
398 ICMPv6EchoRequest(id=self.icmp_id_in))
403 def create_stream_out(self, out_if, dst_ip=None, ttl=64,
404 use_inside_ports=False):
406 Create packet stream for outside network
408 :param out_if: Outside interface
409 :param dst_ip: Destination IP address (Default use global NAT address)
410 :param ttl: TTL of generated packets
411 :param use_inside_ports: Use inside NAT ports as destination ports
412 instead of outside ports
415 dst_ip = self.nat_addr
416 if not use_inside_ports:
417 tcp_port = self.tcp_port_out
418 udp_port = self.udp_port_out
419 icmp_id = self.icmp_id_out
421 tcp_port = self.tcp_port_in
422 udp_port = self.udp_port_in
423 icmp_id = self.icmp_id_in
426 p = (Ether(dst=out_if.local_mac, src=out_if.remote_mac) /
427 IP(src=out_if.remote_ip4, dst=dst_ip, ttl=ttl) /
428 TCP(dport=tcp_port, sport=20))
432 p = (Ether(dst=out_if.local_mac, src=out_if.remote_mac) /
433 IP(src=out_if.remote_ip4, dst=dst_ip, ttl=ttl) /
434 UDP(dport=udp_port, sport=20))
438 p = (Ether(dst=out_if.local_mac, src=out_if.remote_mac) /
439 IP(src=out_if.remote_ip4, dst=dst_ip, ttl=ttl) /
440 ICMP(id=icmp_id, type='echo-reply'))
445 def create_stream_out_ip6(self, out_if, src_ip, dst_ip, hl=64):
447 Create packet stream for outside network
449 :param out_if: Outside interface
450 :param dst_ip: Destination IP address (Default use global NAT address)
451 :param hl: HL of generated packets
455 p = (Ether(dst=out_if.local_mac, src=out_if.remote_mac) /
456 IPv6(src=src_ip, dst=dst_ip, hlim=hl) /
457 TCP(dport=self.tcp_port_out, sport=20))
461 p = (Ether(dst=out_if.local_mac, src=out_if.remote_mac) /
462 IPv6(src=src_ip, dst=dst_ip, hlim=hl) /
463 UDP(dport=self.udp_port_out, sport=20))
467 p = (Ether(dst=out_if.local_mac, src=out_if.remote_mac) /
468 IPv6(src=src_ip, dst=dst_ip, hlim=hl) /
469 ICMPv6EchoReply(id=self.icmp_id_out))
474 def verify_capture_out(self, capture, nat_ip=None, same_port=False,
475 dst_ip=None, is_ip6=False):
477 Verify captured packets on outside network
479 :param capture: Captured packets
480 :param nat_ip: Translated IP address (Default use global NAT address)
481 :param same_port: Sorce port number is not translated (Default False)
482 :param dst_ip: Destination IP address (Default do not verify)
483 :param is_ip6: If L3 protocol is IPv6 (Default False)
487 ICMP46 = ICMPv6EchoRequest
492 nat_ip = self.nat_addr
493 for packet in capture:
496 self.assert_packet_checksums_valid(packet)
497 self.assertEqual(packet[IP46].src, nat_ip)
498 if dst_ip is not None:
499 self.assertEqual(packet[IP46].dst, dst_ip)
500 if packet.haslayer(TCP):
502 self.assertEqual(packet[TCP].sport, self.tcp_port_in)
505 packet[TCP].sport, self.tcp_port_in)
506 self.tcp_port_out = packet[TCP].sport
507 self.assert_packet_checksums_valid(packet)
508 elif packet.haslayer(UDP):
510 self.assertEqual(packet[UDP].sport, self.udp_port_in)
513 packet[UDP].sport, self.udp_port_in)
514 self.udp_port_out = packet[UDP].sport
517 self.assertEqual(packet[ICMP46].id, self.icmp_id_in)
519 self.assertNotEqual(packet[ICMP46].id, self.icmp_id_in)
520 self.icmp_id_out = packet[ICMP46].id
521 self.assert_packet_checksums_valid(packet)
523 self.logger.error(ppp("Unexpected or invalid packet "
524 "(outside network):", packet))
527 def verify_capture_out_ip6(self, capture, nat_ip, same_port=False,
530 Verify captured packets on outside network
532 :param capture: Captured packets
533 :param nat_ip: Translated IP address
534 :param same_port: Sorce port number is not translated (Default False)
535 :param dst_ip: Destination IP address (Default do not verify)
537 return self.verify_capture_out(capture, nat_ip, same_port, dst_ip,
540 def verify_capture_in(self, capture, in_if):
542 Verify captured packets on inside network
544 :param capture: Captured packets
545 :param in_if: Inside interface
547 for packet in capture:
549 self.assert_packet_checksums_valid(packet)
550 self.assertEqual(packet[IP].dst, in_if.remote_ip4)
551 if packet.haslayer(TCP):
552 self.assertEqual(packet[TCP].dport, self.tcp_port_in)
553 elif packet.haslayer(UDP):
554 self.assertEqual(packet[UDP].dport, self.udp_port_in)
556 self.assertEqual(packet[ICMP].id, self.icmp_id_in)
558 self.logger.error(ppp("Unexpected or invalid packet "
559 "(inside network):", packet))
562 def verify_capture_in_ip6(self, capture, src_ip, dst_ip):
564 Verify captured IPv6 packets on inside network
566 :param capture: Captured packets
567 :param src_ip: Source IP
568 :param dst_ip: Destination IP address
570 for packet in capture:
572 self.assertEqual(packet[IPv6].src, src_ip)
573 self.assertEqual(packet[IPv6].dst, dst_ip)
574 self.assert_packet_checksums_valid(packet)
575 if packet.haslayer(TCP):
576 self.assertEqual(packet[TCP].dport, self.tcp_port_in)
577 elif packet.haslayer(UDP):
578 self.assertEqual(packet[UDP].dport, self.udp_port_in)
580 self.assertEqual(packet[ICMPv6EchoReply].id,
583 self.logger.error(ppp("Unexpected or invalid packet "
584 "(inside network):", packet))
587 def verify_capture_no_translation(self, capture, ingress_if, egress_if):
589 Verify captured packet that don't have to be translated
591 :param capture: Captured packets
592 :param ingress_if: Ingress interface
593 :param egress_if: Egress interface
595 for packet in capture:
597 self.assertEqual(packet[IP].src, ingress_if.remote_ip4)
598 self.assertEqual(packet[IP].dst, egress_if.remote_ip4)
599 if packet.haslayer(TCP):
600 self.assertEqual(packet[TCP].sport, self.tcp_port_in)
601 elif packet.haslayer(UDP):
602 self.assertEqual(packet[UDP].sport, self.udp_port_in)
604 self.assertEqual(packet[ICMP].id, self.icmp_id_in)
606 self.logger.error(ppp("Unexpected or invalid packet "
607 "(inside network):", packet))
610 def verify_capture_out_with_icmp_errors(self, capture, src_ip=None,
613 Verify captured packets with ICMP errors on outside network
615 :param capture: Captured packets
616 :param src_ip: Translated IP address or IP address of VPP
617 (Default use global NAT address)
618 :param icmp_type: Type of error ICMP packet
619 we are expecting (Default 11)
622 src_ip = self.nat_addr
623 for packet in capture:
625 self.assertEqual(packet[IP].src, src_ip)
626 self.assertEqual(packet.haslayer(ICMP), 1)
628 self.assertEqual(icmp.type, icmp_type)
629 self.assertTrue(icmp.haslayer(IPerror))
630 inner_ip = icmp[IPerror]
631 if inner_ip.haslayer(TCPerror):
632 self.assertEqual(inner_ip[TCPerror].dport,
634 elif inner_ip.haslayer(UDPerror):
635 self.assertEqual(inner_ip[UDPerror].dport,
638 self.assertEqual(inner_ip[ICMPerror].id, self.icmp_id_out)
640 self.logger.error(ppp("Unexpected or invalid packet "
641 "(outside network):", packet))
644 def verify_capture_in_with_icmp_errors(self, capture, in_if, icmp_type=11):
646 Verify captured packets with ICMP errors on inside network
648 :param capture: Captured packets
649 :param in_if: Inside interface
650 :param icmp_type: Type of error ICMP packet
651 we are expecting (Default 11)
653 for packet in capture:
655 self.assertEqual(packet[IP].dst, in_if.remote_ip4)
656 self.assertEqual(packet.haslayer(ICMP), 1)
658 self.assertEqual(icmp.type, icmp_type)
659 self.assertTrue(icmp.haslayer(IPerror))
660 inner_ip = icmp[IPerror]
661 if inner_ip.haslayer(TCPerror):
662 self.assertEqual(inner_ip[TCPerror].sport,
664 elif inner_ip.haslayer(UDPerror):
665 self.assertEqual(inner_ip[UDPerror].sport,
668 self.assertEqual(inner_ip[ICMPerror].id, self.icmp_id_in)
670 self.logger.error(ppp("Unexpected or invalid packet "
671 "(inside network):", packet))
674 def create_stream_frag(self, src_if, dst, sport, dport, data,
675 proto=IP_PROTOS.tcp, echo_reply=False):
677 Create fragmented packet stream
679 :param src_if: Source interface
680 :param dst: Destination IPv4 address
681 :param sport: Source port
682 :param dport: Destination port
683 :param data: Payload data
684 :param proto: protocol (TCP, UDP, ICMP)
685 :param echo_reply: use echo_reply if protocol is ICMP
688 if proto == IP_PROTOS.tcp:
689 p = (IP(src=src_if.remote_ip4, dst=dst) /
690 TCP(sport=sport, dport=dport) /
692 p = p.__class__(str(p))
693 chksum = p['TCP'].chksum
694 proto_header = TCP(sport=sport, dport=dport, chksum=chksum)
695 elif proto == IP_PROTOS.udp:
696 proto_header = UDP(sport=sport, dport=dport)
697 elif proto == IP_PROTOS.icmp:
699 proto_header = ICMP(id=sport, type='echo-request')
701 proto_header = ICMP(id=sport, type='echo-reply')
703 raise Exception("Unsupported protocol")
704 id = random.randint(0, 65535)
706 if proto == IP_PROTOS.tcp:
709 raw = Raw(data[0:16])
710 p = (Ether(src=src_if.remote_mac, dst=src_if.local_mac) /
711 IP(src=src_if.remote_ip4, dst=dst, flags="MF", frag=0, id=id) /
715 if proto == IP_PROTOS.tcp:
716 raw = Raw(data[4:20])
718 raw = Raw(data[16:32])
719 p = (Ether(src=src_if.remote_mac, dst=src_if.local_mac) /
720 IP(src=src_if.remote_ip4, dst=dst, flags="MF", frag=3, id=id,
724 if proto == IP_PROTOS.tcp:
728 p = (Ether(src=src_if.remote_mac, dst=src_if.local_mac) /
729 IP(src=src_if.remote_ip4, dst=dst, frag=5, proto=proto,
735 def create_stream_frag_ip6(self, src_if, dst, sport, dport, data,
736 pref=None, plen=0, frag_size=128):
738 Create fragmented packet stream
740 :param src_if: Source interface
741 :param dst: Destination IPv4 address
742 :param sport: Source TCP port
743 :param dport: Destination TCP port
744 :param data: Payload data
745 :param pref: NAT64 prefix
746 :param plen: NAT64 prefix length
747 :param fragsize: size of fragments
751 dst_ip6 = ''.join(['64:ff9b::', dst])
753 dst_ip6 = self.compose_ip6(dst, pref, plen)
755 p = (Ether(dst=src_if.local_mac, src=src_if.remote_mac) /
756 IPv6(src=src_if.remote_ip6, dst=dst_ip6) /
757 IPv6ExtHdrFragment(id=random.randint(0, 65535)) /
758 TCP(sport=sport, dport=dport) /
761 return fragment6(p, frag_size)
763 def reass_frags_and_verify(self, frags, src, dst):
765 Reassemble and verify fragmented packet
767 :param frags: Captured fragments
768 :param src: Source IPv4 address to verify
769 :param dst: Destination IPv4 address to verify
771 :returns: Reassembled IPv4 packet
775 self.assertEqual(p[IP].src, src)
776 self.assertEqual(p[IP].dst, dst)
777 self.assert_ip_checksum_valid(p)
778 buffer.seek(p[IP].frag * 8)
779 buffer.write(bytes(p[IP].payload))
780 ip = IP(src=frags[0][IP].src, dst=frags[0][IP].dst,
781 proto=frags[0][IP].proto)
782 if ip.proto == IP_PROTOS.tcp:
783 p = (ip / TCP(buffer.getvalue()))
784 self.assert_tcp_checksum_valid(p)
785 elif ip.proto == IP_PROTOS.udp:
786 p = (ip / UDP(buffer.getvalue()[:8]) /
787 Raw(buffer.getvalue()[8:]))
788 elif ip.proto == IP_PROTOS.icmp:
789 p = (ip / ICMP(buffer.getvalue()))
792 def reass_frags_and_verify_ip6(self, frags, src, dst):
794 Reassemble and verify fragmented packet
796 :param frags: Captured fragments
797 :param src: Source IPv6 address to verify
798 :param dst: Destination IPv6 address to verify
800 :returns: Reassembled IPv6 packet
804 self.assertEqual(p[IPv6].src, src)
805 self.assertEqual(p[IPv6].dst, dst)
806 buffer.seek(p[IPv6ExtHdrFragment].offset * 8)
807 buffer.write(bytes(p[IPv6ExtHdrFragment].payload))
808 ip = IPv6(src=frags[0][IPv6].src, dst=frags[0][IPv6].dst,
809 nh=frags[0][IPv6ExtHdrFragment].nh)
810 if ip.nh == IP_PROTOS.tcp:
811 p = (ip / TCP(buffer.getvalue()))
812 elif ip.nh == IP_PROTOS.udp:
813 p = (ip / UDP(buffer.getvalue()))
814 self.assert_packet_checksums_valid(p)
817 def initiate_tcp_session(self, in_if, out_if):
819 Initiates TCP session
821 :param in_if: Inside interface
822 :param out_if: Outside interface
826 p = (Ether(src=in_if.remote_mac, dst=in_if.local_mac) /
827 IP(src=in_if.remote_ip4, dst=out_if.remote_ip4) /
828 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
831 self.pg_enable_capture(self.pg_interfaces)
833 capture = out_if.get_capture(1)
835 self.tcp_port_out = p[TCP].sport
837 # SYN + ACK packet out->in
838 p = (Ether(src=out_if.remote_mac, dst=out_if.local_mac) /
839 IP(src=out_if.remote_ip4, dst=self.nat_addr) /
840 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
843 self.pg_enable_capture(self.pg_interfaces)
848 p = (Ether(src=in_if.remote_mac, dst=in_if.local_mac) /
849 IP(src=in_if.remote_ip4, dst=out_if.remote_ip4) /
850 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
853 self.pg_enable_capture(self.pg_interfaces)
855 out_if.get_capture(1)
858 self.logger.error("TCP 3 way handshake failed")
861 def verify_ipfix_nat44_ses(self, data):
863 Verify IPFIX NAT44 session create/delete event
865 :param data: Decoded IPFIX data records
867 nat44_ses_create_num = 0
868 nat44_ses_delete_num = 0
869 self.assertEqual(6, len(data))
872 self.assertIn(ord(record[230]), [4, 5])
873 if ord(record[230]) == 4:
874 nat44_ses_create_num += 1
876 nat44_ses_delete_num += 1
878 self.assertEqual(self.pg0.remote_ip4n, record[8])
879 # postNATSourceIPv4Address
880 self.assertEqual(socket.inet_pton(socket.AF_INET, self.nat_addr),
883 self.assertEqual(struct.pack("!I", 0), record[234])
884 # protocolIdentifier/sourceTransportPort/postNAPTSourceTransportPort
885 if IP_PROTOS.icmp == ord(record[4]):
886 self.assertEqual(struct.pack("!H", self.icmp_id_in), record[7])
887 self.assertEqual(struct.pack("!H", self.icmp_id_out),
889 elif IP_PROTOS.tcp == ord(record[4]):
890 self.assertEqual(struct.pack("!H", self.tcp_port_in),
892 self.assertEqual(struct.pack("!H", self.tcp_port_out),
894 elif IP_PROTOS.udp == ord(record[4]):
895 self.assertEqual(struct.pack("!H", self.udp_port_in),
897 self.assertEqual(struct.pack("!H", self.udp_port_out),
900 self.fail("Invalid protocol")
901 self.assertEqual(3, nat44_ses_create_num)
902 self.assertEqual(3, nat44_ses_delete_num)
904 def verify_ipfix_addr_exhausted(self, data):
906 Verify IPFIX NAT addresses event
908 :param data: Decoded IPFIX data records
910 self.assertEqual(1, len(data))
913 self.assertEqual(ord(record[230]), 3)
915 self.assertEqual(struct.pack("!I", 0), record[283])
917 def verify_ipfix_max_sessions(self, data, limit):
919 Verify IPFIX maximum session entries exceeded event
921 :param data: Decoded IPFIX data records
922 :param limit: Number of maximum session entries that can be created.
924 self.assertEqual(1, len(data))
927 self.assertEqual(ord(record[230]), 13)
928 # natQuotaExceededEvent
929 self.assertEqual(struct.pack("I", 1), record[466])
931 self.assertEqual(struct.pack("I", limit), record[471])
933 def verify_ipfix_max_bibs(self, data, limit):
935 Verify IPFIX maximum BIB entries exceeded event
937 :param data: Decoded IPFIX data records
938 :param limit: Number of maximum BIB entries that can be created.
940 self.assertEqual(1, len(data))
943 self.assertEqual(ord(record[230]), 13)
944 # natQuotaExceededEvent
945 self.assertEqual(struct.pack("I", 2), record[466])
947 self.assertEqual(struct.pack("I", limit), record[472])
949 def verify_ipfix_max_fragments_ip6(self, data, limit, src_addr):
951 Verify IPFIX maximum IPv6 fragments pending reassembly exceeded event
953 :param data: Decoded IPFIX data records
954 :param limit: Number of maximum fragments pending reassembly
955 :param src_addr: IPv6 source address
957 self.assertEqual(1, len(data))
960 self.assertEqual(ord(record[230]), 13)
961 # natQuotaExceededEvent
962 self.assertEqual(struct.pack("I", 5), record[466])
963 # maxFragmentsPendingReassembly
964 self.assertEqual(struct.pack("I", limit), record[475])
966 self.assertEqual(src_addr, record[27])
968 def verify_ipfix_max_fragments_ip4(self, data, limit, src_addr):
970 Verify IPFIX maximum IPv4 fragments pending reassembly exceeded event
972 :param data: Decoded IPFIX data records
973 :param limit: Number of maximum fragments pending reassembly
974 :param src_addr: IPv4 source address
976 self.assertEqual(1, len(data))
979 self.assertEqual(ord(record[230]), 13)
980 # natQuotaExceededEvent
981 self.assertEqual(struct.pack("I", 5), record[466])
982 # maxFragmentsPendingReassembly
983 self.assertEqual(struct.pack("I", limit), record[475])
985 self.assertEqual(src_addr, record[8])
987 def verify_ipfix_bib(self, data, is_create, src_addr):
989 Verify IPFIX NAT64 BIB create and delete events
991 :param data: Decoded IPFIX data records
992 :param is_create: Create event if nonzero value otherwise delete event
993 :param src_addr: IPv6 source address
995 self.assertEqual(1, len(data))
999 self.assertEqual(ord(record[230]), 10)
1001 self.assertEqual(ord(record[230]), 11)
1003 self.assertEqual(src_addr, record[27])
1004 # postNATSourceIPv4Address
1005 self.assertEqual(self.nat_addr_n, record[225])
1006 # protocolIdentifier
1007 self.assertEqual(IP_PROTOS.tcp, ord(record[4]))
1009 self.assertEqual(struct.pack("!I", 0), record[234])
1010 # sourceTransportPort
1011 self.assertEqual(struct.pack("!H", self.tcp_port_in), record[7])
1012 # postNAPTSourceTransportPort
1013 self.assertEqual(struct.pack("!H", self.tcp_port_out), record[227])
1015 def verify_ipfix_nat64_ses(self, data, is_create, src_addr, dst_addr,
1018 Verify IPFIX NAT64 session create and delete events
1020 :param data: Decoded IPFIX data records
1021 :param is_create: Create event if nonzero value otherwise delete event
1022 :param src_addr: IPv6 source address
1023 :param dst_addr: IPv4 destination address
1024 :param dst_port: destination TCP port
1026 self.assertEqual(1, len(data))
1030 self.assertEqual(ord(record[230]), 6)
1032 self.assertEqual(ord(record[230]), 7)
1034 self.assertEqual(src_addr, record[27])
1035 # destinationIPv6Address
1036 self.assertEqual(socket.inet_pton(socket.AF_INET6,
1037 self.compose_ip6(dst_addr,
1041 # postNATSourceIPv4Address
1042 self.assertEqual(self.nat_addr_n, record[225])
1043 # postNATDestinationIPv4Address
1044 self.assertEqual(socket.inet_pton(socket.AF_INET, dst_addr),
1046 # protocolIdentifier
1047 self.assertEqual(IP_PROTOS.tcp, ord(record[4]))
1049 self.assertEqual(struct.pack("!I", 0), record[234])
1050 # sourceTransportPort
1051 self.assertEqual(struct.pack("!H", self.tcp_port_in), record[7])
1052 # postNAPTSourceTransportPort
1053 self.assertEqual(struct.pack("!H", self.tcp_port_out), record[227])
1054 # destinationTransportPort
1055 self.assertEqual(struct.pack("!H", dst_port), record[11])
1056 # postNAPTDestinationTransportPort
1057 self.assertEqual(struct.pack("!H", dst_port), record[228])
1059 def verify_no_nat44_user(self):
1060 """ Verify that there is no NAT44 user """
1061 users = self.vapi.nat44_user_dump()
1062 self.assertEqual(len(users), 0)
1063 users = self.statistics.get_counter('/nat44/total-users')
1064 self.assertEqual(users[0][0], 0)
1065 sessions = self.statistics.get_counter('/nat44/total-sessions')
1066 self.assertEqual(sessions[0][0], 0)
1068 def verify_ipfix_max_entries_per_user(self, data, limit, src_addr):
1070 Verify IPFIX maximum entries per user exceeded event
1072 :param data: Decoded IPFIX data records
1073 :param limit: Number of maximum entries per user
1074 :param src_addr: IPv4 source address
1076 self.assertEqual(1, len(data))
1079 self.assertEqual(ord(record[230]), 13)
1080 # natQuotaExceededEvent
1081 self.assertEqual(struct.pack("I", 3), record[466])
1083 self.assertEqual(struct.pack("I", limit), record[473])
1085 self.assertEqual(src_addr, record[8])
1087 def verify_syslog_apmap(self, data, is_add=True):
1088 message = data.decode('utf-8')
1090 message = SyslogMessage.parse(message)
1091 except ParseError as e:
1092 self.logger.error(e)
1095 self.assertEqual(message.severity, SyslogSeverity.info)
1096 self.assertEqual(message.appname, 'NAT')
1097 self.assertEqual(message.msgid, 'APMADD' if is_add else 'APMDEL')
1098 sd_params = message.sd.get('napmap')
1099 self.assertTrue(sd_params is not None)
1100 self.assertEqual(sd_params.get('IATYP'), 'IPv4')
1101 self.assertEqual(sd_params.get('ISADDR'), self.pg0.remote_ip4)
1102 self.assertEqual(sd_params.get('ISPORT'), "%d" % self.tcp_port_in)
1103 self.assertEqual(sd_params.get('XATYP'), 'IPv4')
1104 self.assertEqual(sd_params.get('XSADDR'), self.nat_addr)
1105 self.assertEqual(sd_params.get('XSPORT'), "%d" % self.tcp_port_out)
1106 self.assertEqual(sd_params.get('PROTO'), "%d" % IP_PROTOS.tcp)
1107 self.assertTrue(sd_params.get('SSUBIX') is not None)
1108 self.assertEqual(sd_params.get('SVLAN'), '0')
1110 def verify_syslog_sess(self, data, is_add=True, is_ip6=False):
1111 message = data.decode('utf-8')
1113 message = SyslogMessage.parse(message)
1114 except ParseError as e:
1115 self.logger.error(e)
1118 self.assertEqual(message.severity, SyslogSeverity.info)
1119 self.assertEqual(message.appname, 'NAT')
1120 self.assertEqual(message.msgid, 'SADD' if is_add else 'SDEL')
1121 sd_params = message.sd.get('nsess')
1122 self.assertTrue(sd_params is not None)
1124 self.assertEqual(sd_params.get('IATYP'), 'IPv6')
1125 self.assertEqual(sd_params.get('ISADDR'), self.pg0.remote_ip6)
1127 self.assertEqual(sd_params.get('IATYP'), 'IPv4')
1128 self.assertEqual(sd_params.get('ISADDR'), self.pg0.remote_ip4)
1129 self.assertTrue(sd_params.get('SSUBIX') is not None)
1130 self.assertEqual(sd_params.get('ISPORT'), "%d" % self.tcp_port_in)
1131 self.assertEqual(sd_params.get('XATYP'), 'IPv4')
1132 self.assertEqual(sd_params.get('XSADDR'), self.nat_addr)
1133 self.assertEqual(sd_params.get('XSPORT'), "%d" % self.tcp_port_out)
1134 self.assertEqual(sd_params.get('PROTO'), "%d" % IP_PROTOS.tcp)
1135 self.assertEqual(sd_params.get('SVLAN'), '0')
1136 self.assertEqual(sd_params.get('XDADDR'), self.pg1.remote_ip4)
1137 self.assertEqual(sd_params.get('XDPORT'),
1138 "%d" % self.tcp_external_port)
1140 def verify_mss_value(self, pkt, mss):
1142 Verify TCP MSS value
1147 if not pkt.haslayer(IP) or not pkt.haslayer(TCP):
1148 raise TypeError("Not a TCP/IP packet")
1150 for option in pkt[TCP].options:
1151 if option[0] == 'MSS':
1152 self.assertEqual(option[1], mss)
1153 self.assert_tcp_checksum_valid(pkt)
1156 def proto2layer(proto):
1157 if proto == IP_PROTOS.tcp:
1159 elif proto == IP_PROTOS.udp:
1161 elif proto == IP_PROTOS.icmp:
1164 raise Exception("Unsupported protocol")
1166 def frag_in_order(self, proto=IP_PROTOS.tcp, dont_translate=False):
1167 layer = self.proto2layer(proto)
1169 if proto == IP_PROTOS.tcp:
1170 data = "A" * 4 + "B" * 16 + "C" * 3
1172 data = "A" * 16 + "B" * 16 + "C" * 3
1173 self.port_in = random.randint(1025, 65535)
1175 reass = self.vapi.nat_reass_dump()
1176 reass_n_start = len(reass)
1179 pkts = self.create_stream_frag(self.pg0,
1180 self.pg1.remote_ip4,
1185 self.pg0.add_stream(pkts)
1186 self.pg_enable_capture(self.pg_interfaces)
1188 frags = self.pg1.get_capture(len(pkts))
1189 if not dont_translate:
1190 p = self.reass_frags_and_verify(frags,
1192 self.pg1.remote_ip4)
1194 p = self.reass_frags_and_verify(frags,
1195 self.pg0.remote_ip4,
1196 self.pg1.remote_ip4)
1197 if proto != IP_PROTOS.icmp:
1198 if not dont_translate:
1199 self.assertEqual(p[layer].dport, 20)
1200 self.assertNotEqual(p[layer].sport, self.port_in)
1202 self.assertEqual(p[layer].sport, self.port_in)
1204 if not dont_translate:
1205 self.assertNotEqual(p[layer].id, self.port_in)
1207 self.assertEqual(p[layer].id, self.port_in)
1208 self.assertEqual(data, p[Raw].load)
1211 if not dont_translate:
1212 dst_addr = self.nat_addr
1214 dst_addr = self.pg0.remote_ip4
1215 if proto != IP_PROTOS.icmp:
1217 dport = p[layer].sport
1221 pkts = self.create_stream_frag(self.pg1,
1228 self.pg1.add_stream(pkts)
1229 self.pg_enable_capture(self.pg_interfaces)
1231 frags = self.pg0.get_capture(len(pkts))
1232 p = self.reass_frags_and_verify(frags,
1233 self.pg1.remote_ip4,
1234 self.pg0.remote_ip4)
1235 if proto != IP_PROTOS.icmp:
1236 self.assertEqual(p[layer].sport, 20)
1237 self.assertEqual(p[layer].dport, self.port_in)
1239 self.assertEqual(p[layer].id, self.port_in)
1240 self.assertEqual(data, p[Raw].load)
1242 reass = self.vapi.nat_reass_dump()
1243 reass_n_end = len(reass)
1245 self.assertEqual(reass_n_end - reass_n_start, 2)
1247 def frag_in_order_in_plus_out(self, proto=IP_PROTOS.tcp):
1248 layer = self.proto2layer(proto)
1250 if proto == IP_PROTOS.tcp:
1251 data = "A" * 4 + "B" * 16 + "C" * 3
1253 data = "A" * 16 + "B" * 16 + "C" * 3
1254 self.port_in = random.randint(1025, 65535)
1257 reass = self.vapi.nat_reass_dump()
1258 reass_n_start = len(reass)
1261 pkts = self.create_stream_frag(self.pg0,
1262 self.server_out_addr,
1264 self.server_out_port,
1267 self.pg0.add_stream(pkts)
1268 self.pg_enable_capture(self.pg_interfaces)
1270 frags = self.pg1.get_capture(len(pkts))
1271 p = self.reass_frags_and_verify(frags,
1272 self.pg0.remote_ip4,
1273 self.server_in_addr)
1274 if proto != IP_PROTOS.icmp:
1275 self.assertEqual(p[layer].sport, self.port_in)
1276 self.assertEqual(p[layer].dport, self.server_in_port)
1278 self.assertEqual(p[layer].id, self.port_in)
1279 self.assertEqual(data, p[Raw].load)
1282 if proto != IP_PROTOS.icmp:
1283 pkts = self.create_stream_frag(self.pg1,
1284 self.pg0.remote_ip4,
1285 self.server_in_port,
1290 pkts = self.create_stream_frag(self.pg1,
1291 self.pg0.remote_ip4,
1297 self.pg1.add_stream(pkts)
1298 self.pg_enable_capture(self.pg_interfaces)
1300 frags = self.pg0.get_capture(len(pkts))
1301 p = self.reass_frags_and_verify(frags,
1302 self.server_out_addr,
1303 self.pg0.remote_ip4)
1304 if proto != IP_PROTOS.icmp:
1305 self.assertEqual(p[layer].sport, self.server_out_port)
1306 self.assertEqual(p[layer].dport, self.port_in)
1308 self.assertEqual(p[layer].id, self.port_in)
1309 self.assertEqual(data, p[Raw].load)
1311 reass = self.vapi.nat_reass_dump()
1312 reass_n_end = len(reass)
1314 self.assertEqual(reass_n_end - reass_n_start, 2)
1316 def reass_hairpinning(self, proto=IP_PROTOS.tcp):
1317 layer = self.proto2layer(proto)
1319 if proto == IP_PROTOS.tcp:
1320 data = "A" * 4 + "B" * 16 + "C" * 3
1322 data = "A" * 16 + "B" * 16 + "C" * 3
1324 # send packet from host to server
1325 pkts = self.create_stream_frag(self.pg0,
1328 self.server_out_port,
1331 self.pg0.add_stream(pkts)
1332 self.pg_enable_capture(self.pg_interfaces)
1334 frags = self.pg0.get_capture(len(pkts))
1335 p = self.reass_frags_and_verify(frags,
1338 if proto != IP_PROTOS.icmp:
1339 self.assertNotEqual(p[layer].sport, self.host_in_port)
1340 self.assertEqual(p[layer].dport, self.server_in_port)
1342 self.assertNotEqual(p[layer].id, self.host_in_port)
1343 self.assertEqual(data, p[Raw].load)
1345 def frag_out_of_order(self, proto=IP_PROTOS.tcp, dont_translate=False):
1346 layer = self.proto2layer(proto)
1348 if proto == IP_PROTOS.tcp:
1349 data = "A" * 4 + "B" * 16 + "C" * 3
1351 data = "A" * 16 + "B" * 16 + "C" * 3
1352 self.port_in = random.randint(1025, 65535)
1356 pkts = self.create_stream_frag(self.pg0,
1357 self.pg1.remote_ip4,
1363 self.pg0.add_stream(pkts)
1364 self.pg_enable_capture(self.pg_interfaces)
1366 frags = self.pg1.get_capture(len(pkts))
1367 if not dont_translate:
1368 p = self.reass_frags_and_verify(frags,
1370 self.pg1.remote_ip4)
1372 p = self.reass_frags_and_verify(frags,
1373 self.pg0.remote_ip4,
1374 self.pg1.remote_ip4)
1375 if proto != IP_PROTOS.icmp:
1376 if not dont_translate:
1377 self.assertEqual(p[layer].dport, 20)
1378 self.assertNotEqual(p[layer].sport, self.port_in)
1380 self.assertEqual(p[layer].sport, self.port_in)
1382 if not dont_translate:
1383 self.assertNotEqual(p[layer].id, self.port_in)
1385 self.assertEqual(p[layer].id, self.port_in)
1386 self.assertEqual(data, p[Raw].load)
1389 if not dont_translate:
1390 dst_addr = self.nat_addr
1392 dst_addr = self.pg0.remote_ip4
1393 if proto != IP_PROTOS.icmp:
1395 dport = p[layer].sport
1399 pkts = self.create_stream_frag(self.pg1,
1407 self.pg1.add_stream(pkts)
1408 self.pg_enable_capture(self.pg_interfaces)
1410 frags = self.pg0.get_capture(len(pkts))
1411 p = self.reass_frags_and_verify(frags,
1412 self.pg1.remote_ip4,
1413 self.pg0.remote_ip4)
1414 if proto != IP_PROTOS.icmp:
1415 self.assertEqual(p[layer].sport, 20)
1416 self.assertEqual(p[layer].dport, self.port_in)
1418 self.assertEqual(p[layer].id, self.port_in)
1419 self.assertEqual(data, p[Raw].load)
1421 def frag_out_of_order_in_plus_out(self, proto=IP_PROTOS.tcp):
1422 layer = self.proto2layer(proto)
1424 if proto == IP_PROTOS.tcp:
1425 data = "A" * 4 + "B" * 16 + "C" * 3
1427 data = "A" * 16 + "B" * 16 + "C" * 3
1428 self.port_in = random.randint(1025, 65535)
1432 pkts = self.create_stream_frag(self.pg0,
1433 self.server_out_addr,
1435 self.server_out_port,
1439 self.pg0.add_stream(pkts)
1440 self.pg_enable_capture(self.pg_interfaces)
1442 frags = self.pg1.get_capture(len(pkts))
1443 p = self.reass_frags_and_verify(frags,
1444 self.pg0.remote_ip4,
1445 self.server_in_addr)
1446 if proto != IP_PROTOS.icmp:
1447 self.assertEqual(p[layer].dport, self.server_in_port)
1448 self.assertEqual(p[layer].sport, self.port_in)
1449 self.assertEqual(p[layer].dport, self.server_in_port)
1451 self.assertEqual(p[layer].id, self.port_in)
1452 self.assertEqual(data, p[Raw].load)
1455 if proto != IP_PROTOS.icmp:
1456 pkts = self.create_stream_frag(self.pg1,
1457 self.pg0.remote_ip4,
1458 self.server_in_port,
1463 pkts = self.create_stream_frag(self.pg1,
1464 self.pg0.remote_ip4,
1471 self.pg1.add_stream(pkts)
1472 self.pg_enable_capture(self.pg_interfaces)
1474 frags = self.pg0.get_capture(len(pkts))
1475 p = self.reass_frags_and_verify(frags,
1476 self.server_out_addr,
1477 self.pg0.remote_ip4)
1478 if proto != IP_PROTOS.icmp:
1479 self.assertEqual(p[layer].sport, self.server_out_port)
1480 self.assertEqual(p[layer].dport, self.port_in)
1482 self.assertEqual(p[layer].id, self.port_in)
1483 self.assertEqual(data, p[Raw].load)
1486 class TestNAT44(MethodHolder):
1487 """ NAT44 Test Cases """
1490 def setUpClass(cls):
1491 super(TestNAT44, cls).setUpClass()
1492 cls.vapi.cli("set log class nat level debug")
1495 cls.tcp_port_in = 6303
1496 cls.tcp_port_out = 6303
1497 cls.udp_port_in = 6304
1498 cls.udp_port_out = 6304
1499 cls.icmp_id_in = 6305
1500 cls.icmp_id_out = 6305
1501 cls.nat_addr = '10.0.0.3'
1502 cls.nat_addr_n = socket.inet_pton(socket.AF_INET, cls.nat_addr)
1503 cls.ipfix_src_port = 4739
1504 cls.ipfix_domain_id = 1
1505 cls.tcp_external_port = 80
1506 cls.udp_external_port = 69
1508 cls.create_pg_interfaces(range(10))
1509 cls.interfaces = list(cls.pg_interfaces[0:4])
1511 for i in cls.interfaces:
1516 cls.pg0.generate_remote_hosts(3)
1517 cls.pg0.configure_ipv4_neighbors()
1519 cls.pg1.generate_remote_hosts(1)
1520 cls.pg1.configure_ipv4_neighbors()
1522 cls.overlapping_interfaces = list(list(cls.pg_interfaces[4:7]))
1523 cls.vapi.ip_table_add_del(is_add=1, table_id=10)
1524 cls.vapi.ip_table_add_del(is_add=1, table_id=20)
1526 cls.pg4._local_ip4 = "172.16.255.1"
1527 cls.pg4._local_ip4n = socket.inet_pton(socket.AF_INET, i.local_ip4)
1528 cls.pg4._remote_hosts[0]._ip4 = "172.16.255.2"
1529 cls.pg4.set_table_ip4(10)
1530 cls.pg5._local_ip4 = "172.17.255.3"
1531 cls.pg5._local_ip4n = socket.inet_pton(socket.AF_INET, i.local_ip4)
1532 cls.pg5._remote_hosts[0]._ip4 = "172.17.255.4"
1533 cls.pg5.set_table_ip4(10)
1534 cls.pg6._local_ip4 = "172.16.255.1"
1535 cls.pg6._local_ip4n = socket.inet_pton(socket.AF_INET, i.local_ip4)
1536 cls.pg6._remote_hosts[0]._ip4 = "172.16.255.2"
1537 cls.pg6.set_table_ip4(20)
1538 for i in cls.overlapping_interfaces:
1546 cls.pg9.generate_remote_hosts(2)
1547 cls.pg9.config_ip4()
1548 ip_addr_n = socket.inet_pton(socket.AF_INET, "10.0.0.1")
1549 cls.vapi.sw_interface_add_del_address(
1550 sw_if_index=cls.pg9.sw_if_index, address=ip_addr_n,
1553 cls.pg9.resolve_arp()
1554 cls.pg9._remote_hosts[1]._ip4 = cls.pg9._remote_hosts[0]._ip4
1555 cls.pg4._remote_ip4 = cls.pg9._remote_hosts[0]._ip4 = "10.0.0.2"
1556 cls.pg9.resolve_arp()
1559 super(TestNAT44, cls).tearDownClass()
1562 def test_dynamic(self):
1563 """ NAT44 dynamic translation test """
1564 self.nat44_add_address(self.nat_addr)
1565 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
1566 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
1570 tcpn = self.statistics.get_counter(
1571 '/err/nat44-in2out-slowpath/TCP packets')
1572 udpn = self.statistics.get_counter(
1573 '/err/nat44-in2out-slowpath/UDP packets')
1574 icmpn = self.statistics.get_counter(
1575 '/err/nat44-in2out-slowpath/ICMP packets')
1576 totaln = self.statistics.get_counter(
1577 '/err/nat44-in2out-slowpath/good in2out packets processed')
1579 pkts = self.create_stream_in(self.pg0, self.pg1)
1580 self.pg0.add_stream(pkts)
1581 self.pg_enable_capture(self.pg_interfaces)
1583 capture = self.pg1.get_capture(len(pkts))
1584 self.verify_capture_out(capture)
1586 err = self.statistics.get_counter(
1587 '/err/nat44-in2out-slowpath/TCP packets')
1588 self.assertEqual(err - tcpn, 1)
1589 err = self.statistics.get_counter(
1590 '/err/nat44-in2out-slowpath/UDP packets')
1591 self.assertEqual(err - udpn, 1)
1592 err = self.statistics.get_counter(
1593 '/err/nat44-in2out-slowpath/ICMP packets')
1594 self.assertEqual(err - icmpn, 1)
1595 err = self.statistics.get_counter(
1596 '/err/nat44-in2out-slowpath/good in2out packets processed')
1597 self.assertEqual(err - totaln, 3)
1600 tcpn = self.statistics.get_counter('/err/nat44-out2in/TCP packets')
1601 udpn = self.statistics.get_counter('/err/nat44-out2in/UDP packets')
1602 icmpn = self.statistics.get_counter('/err/nat44-out2in/ICMP packets')
1603 totaln = self.statistics.get_counter(
1604 '/err/nat44-out2in/good out2in packets processed')
1606 pkts = self.create_stream_out(self.pg1)
1607 self.pg1.add_stream(pkts)
1608 self.pg_enable_capture(self.pg_interfaces)
1610 capture = self.pg0.get_capture(len(pkts))
1611 self.verify_capture_in(capture, self.pg0)
1613 err = self.statistics.get_counter('/err/nat44-out2in/TCP packets')
1614 self.assertEqual(err - tcpn, 1)
1615 err = self.statistics.get_counter('/err/nat44-out2in/UDP packets')
1616 self.assertEqual(err - udpn, 1)
1617 err = self.statistics.get_counter('/err/nat44-out2in/ICMP packets')
1618 self.assertEqual(err - icmpn, 1)
1619 err = self.statistics.get_counter(
1620 '/err/nat44-out2in/good out2in packets processed')
1621 self.assertEqual(err - totaln, 3)
1623 users = self.statistics.get_counter('/nat44/total-users')
1624 self.assertEqual(users[0][0], 1)
1625 sessions = self.statistics.get_counter('/nat44/total-sessions')
1626 self.assertEqual(sessions[0][0], 3)
1628 def test_dynamic_icmp_errors_in2out_ttl_1(self):
1629 """ NAT44 handling of client packets with TTL=1 """
1631 self.nat44_add_address(self.nat_addr)
1632 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
1633 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
1636 # Client side - generate traffic
1637 pkts = self.create_stream_in(self.pg0, self.pg1, ttl=1)
1638 self.pg0.add_stream(pkts)
1639 self.pg_enable_capture(self.pg_interfaces)
1642 # Client side - verify ICMP type 11 packets
1643 capture = self.pg0.get_capture(len(pkts))
1644 self.verify_capture_in_with_icmp_errors(capture, self.pg0)
1646 def test_dynamic_icmp_errors_out2in_ttl_1(self):
1647 """ NAT44 handling of server packets with TTL=1 """
1649 self.nat44_add_address(self.nat_addr)
1650 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
1651 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
1654 # Client side - create sessions
1655 pkts = self.create_stream_in(self.pg0, self.pg1)
1656 self.pg0.add_stream(pkts)
1657 self.pg_enable_capture(self.pg_interfaces)
1660 # Server side - generate traffic
1661 capture = self.pg1.get_capture(len(pkts))
1662 self.verify_capture_out(capture)
1663 pkts = self.create_stream_out(self.pg1, ttl=1)
1664 self.pg1.add_stream(pkts)
1665 self.pg_enable_capture(self.pg_interfaces)
1668 # Server side - verify ICMP type 11 packets
1669 capture = self.pg1.get_capture(len(pkts))
1670 self.verify_capture_out_with_icmp_errors(capture,
1671 src_ip=self.pg1.local_ip4)
1673 def test_dynamic_icmp_errors_in2out_ttl_2(self):
1674 """ NAT44 handling of error responses to client packets with TTL=2 """
1676 self.nat44_add_address(self.nat_addr)
1677 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
1678 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
1681 # Client side - generate traffic
1682 pkts = self.create_stream_in(self.pg0, self.pg1, ttl=2)
1683 self.pg0.add_stream(pkts)
1684 self.pg_enable_capture(self.pg_interfaces)
1687 # Server side - simulate ICMP type 11 response
1688 capture = self.pg1.get_capture(len(pkts))
1689 pkts = [Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
1690 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
1691 ICMP(type=11) / packet[IP] for packet in capture]
1692 self.pg1.add_stream(pkts)
1693 self.pg_enable_capture(self.pg_interfaces)
1696 # Client side - verify ICMP type 11 packets
1697 capture = self.pg0.get_capture(len(pkts))
1698 self.verify_capture_in_with_icmp_errors(capture, self.pg0)
1700 def test_dynamic_icmp_errors_out2in_ttl_2(self):
1701 """ NAT44 handling of error responses to server packets with TTL=2 """
1703 self.nat44_add_address(self.nat_addr)
1704 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
1705 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
1708 # Client side - create sessions
1709 pkts = self.create_stream_in(self.pg0, self.pg1)
1710 self.pg0.add_stream(pkts)
1711 self.pg_enable_capture(self.pg_interfaces)
1714 # Server side - generate traffic
1715 capture = self.pg1.get_capture(len(pkts))
1716 self.verify_capture_out(capture)
1717 pkts = self.create_stream_out(self.pg1, ttl=2)
1718 self.pg1.add_stream(pkts)
1719 self.pg_enable_capture(self.pg_interfaces)
1722 # Client side - simulate ICMP type 11 response
1723 capture = self.pg0.get_capture(len(pkts))
1724 pkts = [Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
1725 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
1726 ICMP(type=11) / packet[IP] for packet in capture]
1727 self.pg0.add_stream(pkts)
1728 self.pg_enable_capture(self.pg_interfaces)
1731 # Server side - verify ICMP type 11 packets
1732 capture = self.pg1.get_capture(len(pkts))
1733 self.verify_capture_out_with_icmp_errors(capture)
1735 def test_ping_out_interface_from_outside(self):
1736 """ Ping NAT44 out interface from outside network """
1738 self.nat44_add_address(self.nat_addr)
1739 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
1740 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
1743 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
1744 IP(src=self.pg1.remote_ip4, dst=self.pg1.local_ip4) /
1745 ICMP(id=self.icmp_id_out, type='echo-request'))
1747 self.pg1.add_stream(pkts)
1748 self.pg_enable_capture(self.pg_interfaces)
1750 capture = self.pg1.get_capture(len(pkts))
1753 self.assertEqual(packet[IP].src, self.pg1.local_ip4)
1754 self.assertEqual(packet[IP].dst, self.pg1.remote_ip4)
1755 self.assertEqual(packet[ICMP].id, self.icmp_id_in)
1756 self.assertEqual(packet[ICMP].type, 0) # echo reply
1758 self.logger.error(ppp("Unexpected or invalid packet "
1759 "(outside network):", packet))
1762 def test_ping_internal_host_from_outside(self):
1763 """ Ping internal host from outside network """
1765 self.nat44_add_static_mapping(self.pg0.remote_ip4, self.nat_addr)
1766 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
1767 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
1771 pkt = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
1772 IP(src=self.pg1.remote_ip4, dst=self.nat_addr, ttl=64) /
1773 ICMP(id=self.icmp_id_out, type='echo-request'))
1774 self.pg1.add_stream(pkt)
1775 self.pg_enable_capture(self.pg_interfaces)
1777 capture = self.pg0.get_capture(1)
1778 self.verify_capture_in(capture, self.pg0)
1779 self.assert_equal(capture[0][IP].proto, IP_PROTOS.icmp)
1782 pkt = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
1783 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4, ttl=64) /
1784 ICMP(id=self.icmp_id_in, type='echo-reply'))
1785 self.pg0.add_stream(pkt)
1786 self.pg_enable_capture(self.pg_interfaces)
1788 capture = self.pg1.get_capture(1)
1789 self.verify_capture_out(capture, same_port=True)
1790 self.assert_equal(capture[0][IP].proto, IP_PROTOS.icmp)
1792 def test_forwarding(self):
1793 """ NAT44 forwarding test """
1795 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
1796 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
1798 self.vapi.nat44_forwarding_enable_disable(1)
1800 real_ip = self.pg0.remote_ip4n
1801 alias_ip = self.nat_addr_n
1802 self.vapi.nat44_add_del_static_mapping(local_ip=real_ip,
1803 external_ip=alias_ip)
1806 # static mapping match
1808 pkts = self.create_stream_out(self.pg1)
1809 self.pg1.add_stream(pkts)
1810 self.pg_enable_capture(self.pg_interfaces)
1812 capture = self.pg0.get_capture(len(pkts))
1813 self.verify_capture_in(capture, self.pg0)
1815 pkts = self.create_stream_in(self.pg0, self.pg1)
1816 self.pg0.add_stream(pkts)
1817 self.pg_enable_capture(self.pg_interfaces)
1819 capture = self.pg1.get_capture(len(pkts))
1820 self.verify_capture_out(capture, same_port=True)
1822 # no static mapping match
1824 host0 = self.pg0.remote_hosts[0]
1825 self.pg0.remote_hosts[0] = self.pg0.remote_hosts[1]
1827 pkts = self.create_stream_out(self.pg1,
1828 dst_ip=self.pg0.remote_ip4,
1829 use_inside_ports=True)
1830 self.pg1.add_stream(pkts)
1831 self.pg_enable_capture(self.pg_interfaces)
1833 capture = self.pg0.get_capture(len(pkts))
1834 self.verify_capture_in(capture, self.pg0)
1836 pkts = self.create_stream_in(self.pg0, self.pg1)
1837 self.pg0.add_stream(pkts)
1838 self.pg_enable_capture(self.pg_interfaces)
1840 capture = self.pg1.get_capture(len(pkts))
1841 self.verify_capture_out(capture, nat_ip=self.pg0.remote_ip4,
1844 self.pg0.remote_hosts[0] = host0
1847 self.vapi.nat44_forwarding_enable_disable(0)
1848 self.vapi.nat44_add_del_static_mapping(local_ip=real_ip,
1849 external_ip=alias_ip,
1852 def test_static_in(self):
1853 """ 1:1 NAT initialized from inside network """
1855 nat_ip = "10.0.0.10"
1856 self.tcp_port_out = 6303
1857 self.udp_port_out = 6304
1858 self.icmp_id_out = 6305
1860 self.nat44_add_static_mapping(self.pg0.remote_ip4, nat_ip)
1861 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
1862 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
1864 sm = self.vapi.nat44_static_mapping_dump()
1865 self.assertEqual(len(sm), 1)
1866 self.assertEqual((sm[0].tag).split('\0', 1)[0], '')
1867 self.assertEqual(sm[0].protocol, 0)
1868 self.assertEqual(sm[0].local_port, 0)
1869 self.assertEqual(sm[0].external_port, 0)
1872 pkts = self.create_stream_in(self.pg0, self.pg1)
1873 self.pg0.add_stream(pkts)
1874 self.pg_enable_capture(self.pg_interfaces)
1876 capture = self.pg1.get_capture(len(pkts))
1877 self.verify_capture_out(capture, nat_ip, True)
1880 pkts = self.create_stream_out(self.pg1, nat_ip)
1881 self.pg1.add_stream(pkts)
1882 self.pg_enable_capture(self.pg_interfaces)
1884 capture = self.pg0.get_capture(len(pkts))
1885 self.verify_capture_in(capture, self.pg0)
1887 def test_static_out(self):
1888 """ 1:1 NAT initialized from outside network """
1890 nat_ip = "10.0.0.20"
1891 self.tcp_port_out = 6303
1892 self.udp_port_out = 6304
1893 self.icmp_id_out = 6305
1896 self.nat44_add_static_mapping(self.pg0.remote_ip4, nat_ip, tag=tag)
1897 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
1898 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
1900 sm = self.vapi.nat44_static_mapping_dump()
1901 self.assertEqual(len(sm), 1)
1902 self.assertEqual((sm[0].tag).split('\0', 1)[0], tag)
1905 pkts = self.create_stream_out(self.pg1, nat_ip)
1906 self.pg1.add_stream(pkts)
1907 self.pg_enable_capture(self.pg_interfaces)
1909 capture = self.pg0.get_capture(len(pkts))
1910 self.verify_capture_in(capture, self.pg0)
1913 pkts = self.create_stream_in(self.pg0, self.pg1)
1914 self.pg0.add_stream(pkts)
1915 self.pg_enable_capture(self.pg_interfaces)
1917 capture = self.pg1.get_capture(len(pkts))
1918 self.verify_capture_out(capture, nat_ip, True)
1920 def test_static_with_port_in(self):
1921 """ 1:1 NAPT initialized from inside network """
1923 self.tcp_port_out = 3606
1924 self.udp_port_out = 3607
1925 self.icmp_id_out = 3608
1927 self.nat44_add_address(self.nat_addr)
1928 self.nat44_add_static_mapping(self.pg0.remote_ip4, self.nat_addr,
1929 self.tcp_port_in, self.tcp_port_out,
1930 proto=IP_PROTOS.tcp)
1931 self.nat44_add_static_mapping(self.pg0.remote_ip4, self.nat_addr,
1932 self.udp_port_in, self.udp_port_out,
1933 proto=IP_PROTOS.udp)
1934 self.nat44_add_static_mapping(self.pg0.remote_ip4, self.nat_addr,
1935 self.icmp_id_in, self.icmp_id_out,
1936 proto=IP_PROTOS.icmp)
1937 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
1938 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
1942 pkts = self.create_stream_in(self.pg0, self.pg1)
1943 self.pg0.add_stream(pkts)
1944 self.pg_enable_capture(self.pg_interfaces)
1946 capture = self.pg1.get_capture(len(pkts))
1947 self.verify_capture_out(capture)
1950 pkts = self.create_stream_out(self.pg1)
1951 self.pg1.add_stream(pkts)
1952 self.pg_enable_capture(self.pg_interfaces)
1954 capture = self.pg0.get_capture(len(pkts))
1955 self.verify_capture_in(capture, self.pg0)
1957 def test_static_with_port_out(self):
1958 """ 1:1 NAPT initialized from outside network """
1960 self.tcp_port_out = 30606
1961 self.udp_port_out = 30607
1962 self.icmp_id_out = 30608
1964 self.nat44_add_address(self.nat_addr)
1965 self.nat44_add_static_mapping(self.pg0.remote_ip4, self.nat_addr,
1966 self.tcp_port_in, self.tcp_port_out,
1967 proto=IP_PROTOS.tcp)
1968 self.nat44_add_static_mapping(self.pg0.remote_ip4, self.nat_addr,
1969 self.udp_port_in, self.udp_port_out,
1970 proto=IP_PROTOS.udp)
1971 self.nat44_add_static_mapping(self.pg0.remote_ip4, self.nat_addr,
1972 self.icmp_id_in, self.icmp_id_out,
1973 proto=IP_PROTOS.icmp)
1974 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
1975 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
1979 pkts = self.create_stream_out(self.pg1)
1980 self.pg1.add_stream(pkts)
1981 self.pg_enable_capture(self.pg_interfaces)
1983 capture = self.pg0.get_capture(len(pkts))
1984 self.verify_capture_in(capture, self.pg0)
1987 pkts = self.create_stream_in(self.pg0, self.pg1)
1988 self.pg0.add_stream(pkts)
1989 self.pg_enable_capture(self.pg_interfaces)
1991 capture = self.pg1.get_capture(len(pkts))
1992 self.verify_capture_out(capture)
1994 def test_static_vrf_aware(self):
1995 """ 1:1 NAT VRF awareness """
1997 nat_ip1 = "10.0.0.30"
1998 nat_ip2 = "10.0.0.40"
1999 self.tcp_port_out = 6303
2000 self.udp_port_out = 6304
2001 self.icmp_id_out = 6305
2003 self.nat44_add_static_mapping(self.pg4.remote_ip4, nat_ip1,
2005 self.nat44_add_static_mapping(self.pg0.remote_ip4, nat_ip2,
2007 self.vapi.nat44_interface_add_del_feature(self.pg3.sw_if_index,
2009 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
2010 self.vapi.nat44_interface_add_del_feature(self.pg4.sw_if_index)
2012 # inside interface VRF match NAT44 static mapping VRF
2013 pkts = self.create_stream_in(self.pg4, self.pg3)
2014 self.pg4.add_stream(pkts)
2015 self.pg_enable_capture(self.pg_interfaces)
2017 capture = self.pg3.get_capture(len(pkts))
2018 self.verify_capture_out(capture, nat_ip1, True)
2020 # inside interface VRF don't match NAT44 static mapping VRF (packets
2022 pkts = self.create_stream_in(self.pg0, self.pg3)
2023 self.pg0.add_stream(pkts)
2024 self.pg_enable_capture(self.pg_interfaces)
2026 self.pg3.assert_nothing_captured()
2028 def test_dynamic_to_static(self):
2029 """ Switch from dynamic translation to 1:1NAT """
2030 nat_ip = "10.0.0.10"
2031 self.tcp_port_out = 6303
2032 self.udp_port_out = 6304
2033 self.icmp_id_out = 6305
2035 self.nat44_add_address(self.nat_addr)
2036 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
2037 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
2041 pkts = self.create_stream_in(self.pg0, self.pg1)
2042 self.pg0.add_stream(pkts)
2043 self.pg_enable_capture(self.pg_interfaces)
2045 capture = self.pg1.get_capture(len(pkts))
2046 self.verify_capture_out(capture)
2049 self.nat44_add_static_mapping(self.pg0.remote_ip4, nat_ip)
2050 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4n, 0)
2051 self.assertEqual(len(sessions), 0)
2052 pkts = self.create_stream_in(self.pg0, self.pg1)
2053 self.pg0.add_stream(pkts)
2054 self.pg_enable_capture(self.pg_interfaces)
2056 capture = self.pg1.get_capture(len(pkts))
2057 self.verify_capture_out(capture, nat_ip, True)
2059 def test_identity_nat(self):
2060 """ Identity NAT """
2062 self.vapi.nat44_add_del_identity_mapping(ip=self.pg0.remote_ip4n)
2063 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
2064 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
2067 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
2068 IP(src=self.pg1.remote_ip4, dst=self.pg0.remote_ip4) /
2069 TCP(sport=12345, dport=56789))
2070 self.pg1.add_stream(p)
2071 self.pg_enable_capture(self.pg_interfaces)
2073 capture = self.pg0.get_capture(1)
2078 self.assertEqual(ip.dst, self.pg0.remote_ip4)
2079 self.assertEqual(ip.src, self.pg1.remote_ip4)
2080 self.assertEqual(tcp.dport, 56789)
2081 self.assertEqual(tcp.sport, 12345)
2082 self.assert_packet_checksums_valid(p)
2084 self.logger.error(ppp("Unexpected or invalid packet:", p))
2087 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4n, 0)
2088 self.assertEqual(len(sessions), 0)
2089 self.vapi.nat44_add_del_identity_mapping(ip=self.pg0.remote_ip4n,
2091 identity_mappings = self.vapi.nat44_identity_mapping_dump()
2092 self.assertEqual(len(identity_mappings), 2)
2094 def test_multiple_inside_interfaces(self):
2095 """ NAT44 multiple non-overlapping address space inside interfaces """
2097 self.nat44_add_address(self.nat_addr)
2098 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
2099 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index)
2100 self.vapi.nat44_interface_add_del_feature(self.pg3.sw_if_index,
2103 # between two NAT44 inside interfaces (no translation)
2104 pkts = self.create_stream_in(self.pg0, self.pg1)
2105 self.pg0.add_stream(pkts)
2106 self.pg_enable_capture(self.pg_interfaces)
2108 capture = self.pg1.get_capture(len(pkts))
2109 self.verify_capture_no_translation(capture, self.pg0, self.pg1)
2111 # from NAT44 inside to interface without NAT44 feature (no translation)
2112 pkts = self.create_stream_in(self.pg0, self.pg2)
2113 self.pg0.add_stream(pkts)
2114 self.pg_enable_capture(self.pg_interfaces)
2116 capture = self.pg2.get_capture(len(pkts))
2117 self.verify_capture_no_translation(capture, self.pg0, self.pg2)
2119 # in2out 1st interface
2120 pkts = self.create_stream_in(self.pg0, self.pg3)
2121 self.pg0.add_stream(pkts)
2122 self.pg_enable_capture(self.pg_interfaces)
2124 capture = self.pg3.get_capture(len(pkts))
2125 self.verify_capture_out(capture)
2127 # out2in 1st interface
2128 pkts = self.create_stream_out(self.pg3)
2129 self.pg3.add_stream(pkts)
2130 self.pg_enable_capture(self.pg_interfaces)
2132 capture = self.pg0.get_capture(len(pkts))
2133 self.verify_capture_in(capture, self.pg0)
2135 # in2out 2nd interface
2136 pkts = self.create_stream_in(self.pg1, self.pg3)
2137 self.pg1.add_stream(pkts)
2138 self.pg_enable_capture(self.pg_interfaces)
2140 capture = self.pg3.get_capture(len(pkts))
2141 self.verify_capture_out(capture)
2143 # out2in 2nd interface
2144 pkts = self.create_stream_out(self.pg3)
2145 self.pg3.add_stream(pkts)
2146 self.pg_enable_capture(self.pg_interfaces)
2148 capture = self.pg1.get_capture(len(pkts))
2149 self.verify_capture_in(capture, self.pg1)
2151 def test_inside_overlapping_interfaces(self):
2152 """ NAT44 multiple inside interfaces with overlapping address space """
2154 static_nat_ip = "10.0.0.10"
2155 self.nat44_add_address(self.nat_addr)
2156 self.vapi.nat44_interface_add_del_feature(self.pg3.sw_if_index,
2158 self.vapi.nat44_interface_add_del_feature(self.pg4.sw_if_index)
2159 self.vapi.nat44_interface_add_del_feature(self.pg5.sw_if_index)
2160 self.vapi.nat44_interface_add_del_feature(self.pg6.sw_if_index)
2161 self.nat44_add_static_mapping(self.pg6.remote_ip4, static_nat_ip,
2164 # between NAT44 inside interfaces with same VRF (no translation)
2165 pkts = self.create_stream_in(self.pg4, self.pg5)
2166 self.pg4.add_stream(pkts)
2167 self.pg_enable_capture(self.pg_interfaces)
2169 capture = self.pg5.get_capture(len(pkts))
2170 self.verify_capture_no_translation(capture, self.pg4, self.pg5)
2172 # between NAT44 inside interfaces with different VRF (hairpinning)
2173 p = (Ether(src=self.pg4.remote_mac, dst=self.pg4.local_mac) /
2174 IP(src=self.pg4.remote_ip4, dst=static_nat_ip) /
2175 TCP(sport=1234, dport=5678))
2176 self.pg4.add_stream(p)
2177 self.pg_enable_capture(self.pg_interfaces)
2179 capture = self.pg6.get_capture(1)
2184 self.assertEqual(ip.src, self.nat_addr)
2185 self.assertEqual(ip.dst, self.pg6.remote_ip4)
2186 self.assertNotEqual(tcp.sport, 1234)
2187 self.assertEqual(tcp.dport, 5678)
2189 self.logger.error(ppp("Unexpected or invalid packet:", p))
2192 # in2out 1st interface
2193 pkts = self.create_stream_in(self.pg4, self.pg3)
2194 self.pg4.add_stream(pkts)
2195 self.pg_enable_capture(self.pg_interfaces)
2197 capture = self.pg3.get_capture(len(pkts))
2198 self.verify_capture_out(capture)
2200 # out2in 1st interface
2201 pkts = self.create_stream_out(self.pg3)
2202 self.pg3.add_stream(pkts)
2203 self.pg_enable_capture(self.pg_interfaces)
2205 capture = self.pg4.get_capture(len(pkts))
2206 self.verify_capture_in(capture, self.pg4)
2208 # in2out 2nd interface
2209 pkts = self.create_stream_in(self.pg5, self.pg3)
2210 self.pg5.add_stream(pkts)
2211 self.pg_enable_capture(self.pg_interfaces)
2213 capture = self.pg3.get_capture(len(pkts))
2214 self.verify_capture_out(capture)
2216 # out2in 2nd interface
2217 pkts = self.create_stream_out(self.pg3)
2218 self.pg3.add_stream(pkts)
2219 self.pg_enable_capture(self.pg_interfaces)
2221 capture = self.pg5.get_capture(len(pkts))
2222 self.verify_capture_in(capture, self.pg5)
2225 addresses = self.vapi.nat44_address_dump()
2226 self.assertEqual(len(addresses), 1)
2227 sessions = self.vapi.nat44_user_session_dump(self.pg5.remote_ip4n, 10)
2228 self.assertEqual(len(sessions), 3)
2229 for session in sessions:
2230 self.assertFalse(session.is_static)
2231 self.assertEqual(session.inside_ip_address[0:4],
2232 self.pg5.remote_ip4n)
2233 self.assertEqual(session.outside_ip_address,
2234 addresses[0].ip_address)
2235 self.assertEqual(sessions[0].protocol, IP_PROTOS.tcp)
2236 self.assertEqual(sessions[1].protocol, IP_PROTOS.udp)
2237 self.assertEqual(sessions[2].protocol, IP_PROTOS.icmp)
2238 self.assertEqual(sessions[0].inside_port, self.tcp_port_in)
2239 self.assertEqual(sessions[1].inside_port, self.udp_port_in)
2240 self.assertEqual(sessions[2].inside_port, self.icmp_id_in)
2241 self.assertEqual(sessions[0].outside_port, self.tcp_port_out)
2242 self.assertEqual(sessions[1].outside_port, self.udp_port_out)
2243 self.assertEqual(sessions[2].outside_port, self.icmp_id_out)
2245 # in2out 3rd interface
2246 pkts = self.create_stream_in(self.pg6, self.pg3)
2247 self.pg6.add_stream(pkts)
2248 self.pg_enable_capture(self.pg_interfaces)
2250 capture = self.pg3.get_capture(len(pkts))
2251 self.verify_capture_out(capture, static_nat_ip, True)
2253 # out2in 3rd interface
2254 pkts = self.create_stream_out(self.pg3, static_nat_ip)
2255 self.pg3.add_stream(pkts)
2256 self.pg_enable_capture(self.pg_interfaces)
2258 capture = self.pg6.get_capture(len(pkts))
2259 self.verify_capture_in(capture, self.pg6)
2261 # general user and session dump verifications
2262 users = self.vapi.nat44_user_dump()
2263 self.assertGreaterEqual(len(users), 3)
2264 addresses = self.vapi.nat44_address_dump()
2265 self.assertEqual(len(addresses), 1)
2267 sessions = self.vapi.nat44_user_session_dump(user.ip_address,
2269 for session in sessions:
2270 self.assertEqual(user.ip_address, session.inside_ip_address)
2271 self.assertTrue(session.total_bytes > session.total_pkts > 0)
2272 self.assertTrue(session.protocol in
2273 [IP_PROTOS.tcp, IP_PROTOS.udp,
2275 self.assertFalse(session.ext_host_valid)
2278 sessions = self.vapi.nat44_user_session_dump(self.pg4.remote_ip4n, 10)
2279 self.assertGreaterEqual(len(sessions), 4)
2280 for session in sessions:
2281 self.assertFalse(session.is_static)
2282 self.assertEqual(session.inside_ip_address[0:4],
2283 self.pg4.remote_ip4n)
2284 self.assertEqual(session.outside_ip_address,
2285 addresses[0].ip_address)
2288 sessions = self.vapi.nat44_user_session_dump(self.pg6.remote_ip4n, 20)
2289 self.assertGreaterEqual(len(sessions), 3)
2290 for session in sessions:
2291 self.assertTrue(session.is_static)
2292 self.assertEqual(session.inside_ip_address[0:4],
2293 self.pg6.remote_ip4n)
2294 self.assertEqual(session.outside_ip_address,
2295 socket.inet_pton(socket.AF_INET, static_nat_ip))
2296 self.assertTrue(session.inside_port in
2297 [self.tcp_port_in, self.udp_port_in,
2300 def test_hairpinning(self):
2301 """ NAT44 hairpinning - 1:1 NAPT """
2303 host = self.pg0.remote_hosts[0]
2304 server = self.pg0.remote_hosts[1]
2307 server_in_port = 5678
2308 server_out_port = 8765
2310 self.nat44_add_address(self.nat_addr)
2311 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
2312 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
2314 # add static mapping for server
2315 self.nat44_add_static_mapping(server.ip4, self.nat_addr,
2316 server_in_port, server_out_port,
2317 proto=IP_PROTOS.tcp)
2319 # send packet from host to server
2320 p = (Ether(src=host.mac, dst=self.pg0.local_mac) /
2321 IP(src=host.ip4, dst=self.nat_addr) /
2322 TCP(sport=host_in_port, dport=server_out_port))
2323 self.pg0.add_stream(p)
2324 self.pg_enable_capture(self.pg_interfaces)
2326 capture = self.pg0.get_capture(1)
2331 self.assertEqual(ip.src, self.nat_addr)
2332 self.assertEqual(ip.dst, server.ip4)
2333 self.assertNotEqual(tcp.sport, host_in_port)
2334 self.assertEqual(tcp.dport, server_in_port)
2335 self.assert_packet_checksums_valid(p)
2336 host_out_port = tcp.sport
2338 self.logger.error(ppp("Unexpected or invalid packet:", p))
2341 # send reply from server to host
2342 p = (Ether(src=server.mac, dst=self.pg0.local_mac) /
2343 IP(src=server.ip4, dst=self.nat_addr) /
2344 TCP(sport=server_in_port, dport=host_out_port))
2345 self.pg0.add_stream(p)
2346 self.pg_enable_capture(self.pg_interfaces)
2348 capture = self.pg0.get_capture(1)
2353 self.assertEqual(ip.src, self.nat_addr)
2354 self.assertEqual(ip.dst, host.ip4)
2355 self.assertEqual(tcp.sport, server_out_port)
2356 self.assertEqual(tcp.dport, host_in_port)
2357 self.assert_packet_checksums_valid(p)
2359 self.logger.error(ppp("Unexpected or invalid packet:", p))
2362 def test_hairpinning2(self):
2363 """ NAT44 hairpinning - 1:1 NAT"""
2365 server1_nat_ip = "10.0.0.10"
2366 server2_nat_ip = "10.0.0.11"
2367 host = self.pg0.remote_hosts[0]
2368 server1 = self.pg0.remote_hosts[1]
2369 server2 = self.pg0.remote_hosts[2]
2370 server_tcp_port = 22
2371 server_udp_port = 20
2373 self.nat44_add_address(self.nat_addr)
2374 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
2375 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
2378 # add static mapping for servers
2379 self.nat44_add_static_mapping(server1.ip4, server1_nat_ip)
2380 self.nat44_add_static_mapping(server2.ip4, server2_nat_ip)
2384 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2385 IP(src=host.ip4, dst=server1_nat_ip) /
2386 TCP(sport=self.tcp_port_in, dport=server_tcp_port))
2388 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2389 IP(src=host.ip4, dst=server1_nat_ip) /
2390 UDP(sport=self.udp_port_in, dport=server_udp_port))
2392 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2393 IP(src=host.ip4, dst=server1_nat_ip) /
2394 ICMP(id=self.icmp_id_in, type='echo-request'))
2396 self.pg0.add_stream(pkts)
2397 self.pg_enable_capture(self.pg_interfaces)
2399 capture = self.pg0.get_capture(len(pkts))
2400 for packet in capture:
2402 self.assertEqual(packet[IP].src, self.nat_addr)
2403 self.assertEqual(packet[IP].dst, server1.ip4)
2404 if packet.haslayer(TCP):
2405 self.assertNotEqual(packet[TCP].sport, self.tcp_port_in)
2406 self.assertEqual(packet[TCP].dport, server_tcp_port)
2407 self.tcp_port_out = packet[TCP].sport
2408 self.assert_packet_checksums_valid(packet)
2409 elif packet.haslayer(UDP):
2410 self.assertNotEqual(packet[UDP].sport, self.udp_port_in)
2411 self.assertEqual(packet[UDP].dport, server_udp_port)
2412 self.udp_port_out = packet[UDP].sport
2414 self.assertNotEqual(packet[ICMP].id, self.icmp_id_in)
2415 self.icmp_id_out = packet[ICMP].id
2417 self.logger.error(ppp("Unexpected or invalid packet:", packet))
2422 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2423 IP(src=server1.ip4, dst=self.nat_addr) /
2424 TCP(sport=server_tcp_port, dport=self.tcp_port_out))
2426 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2427 IP(src=server1.ip4, dst=self.nat_addr) /
2428 UDP(sport=server_udp_port, dport=self.udp_port_out))
2430 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2431 IP(src=server1.ip4, dst=self.nat_addr) /
2432 ICMP(id=self.icmp_id_out, type='echo-reply'))
2434 self.pg0.add_stream(pkts)
2435 self.pg_enable_capture(self.pg_interfaces)
2437 capture = self.pg0.get_capture(len(pkts))
2438 for packet in capture:
2440 self.assertEqual(packet[IP].src, server1_nat_ip)
2441 self.assertEqual(packet[IP].dst, host.ip4)
2442 if packet.haslayer(TCP):
2443 self.assertEqual(packet[TCP].dport, self.tcp_port_in)
2444 self.assertEqual(packet[TCP].sport, server_tcp_port)
2445 self.assert_packet_checksums_valid(packet)
2446 elif packet.haslayer(UDP):
2447 self.assertEqual(packet[UDP].dport, self.udp_port_in)
2448 self.assertEqual(packet[UDP].sport, server_udp_port)
2450 self.assertEqual(packet[ICMP].id, self.icmp_id_in)
2452 self.logger.error(ppp("Unexpected or invalid packet:", packet))
2455 # server2 to server1
2457 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2458 IP(src=server2.ip4, dst=server1_nat_ip) /
2459 TCP(sport=self.tcp_port_in, dport=server_tcp_port))
2461 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2462 IP(src=server2.ip4, dst=server1_nat_ip) /
2463 UDP(sport=self.udp_port_in, dport=server_udp_port))
2465 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2466 IP(src=server2.ip4, dst=server1_nat_ip) /
2467 ICMP(id=self.icmp_id_in, type='echo-request'))
2469 self.pg0.add_stream(pkts)
2470 self.pg_enable_capture(self.pg_interfaces)
2472 capture = self.pg0.get_capture(len(pkts))
2473 for packet in capture:
2475 self.assertEqual(packet[IP].src, server2_nat_ip)
2476 self.assertEqual(packet[IP].dst, server1.ip4)
2477 if packet.haslayer(TCP):
2478 self.assertEqual(packet[TCP].sport, self.tcp_port_in)
2479 self.assertEqual(packet[TCP].dport, server_tcp_port)
2480 self.tcp_port_out = packet[TCP].sport
2481 self.assert_packet_checksums_valid(packet)
2482 elif packet.haslayer(UDP):
2483 self.assertEqual(packet[UDP].sport, self.udp_port_in)
2484 self.assertEqual(packet[UDP].dport, server_udp_port)
2485 self.udp_port_out = packet[UDP].sport
2487 self.assertEqual(packet[ICMP].id, self.icmp_id_in)
2488 self.icmp_id_out = packet[ICMP].id
2490 self.logger.error(ppp("Unexpected or invalid packet:", packet))
2493 # server1 to server2
2495 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2496 IP(src=server1.ip4, dst=server2_nat_ip) /
2497 TCP(sport=server_tcp_port, dport=self.tcp_port_out))
2499 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2500 IP(src=server1.ip4, dst=server2_nat_ip) /
2501 UDP(sport=server_udp_port, dport=self.udp_port_out))
2503 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2504 IP(src=server1.ip4, dst=server2_nat_ip) /
2505 ICMP(id=self.icmp_id_out, type='echo-reply'))
2507 self.pg0.add_stream(pkts)
2508 self.pg_enable_capture(self.pg_interfaces)
2510 capture = self.pg0.get_capture(len(pkts))
2511 for packet in capture:
2513 self.assertEqual(packet[IP].src, server1_nat_ip)
2514 self.assertEqual(packet[IP].dst, server2.ip4)
2515 if packet.haslayer(TCP):
2516 self.assertEqual(packet[TCP].dport, self.tcp_port_in)
2517 self.assertEqual(packet[TCP].sport, server_tcp_port)
2518 self.assert_packet_checksums_valid(packet)
2519 elif packet.haslayer(UDP):
2520 self.assertEqual(packet[UDP].dport, self.udp_port_in)
2521 self.assertEqual(packet[UDP].sport, server_udp_port)
2523 self.assertEqual(packet[ICMP].id, self.icmp_id_in)
2525 self.logger.error(ppp("Unexpected or invalid packet:", packet))
2528 def test_max_translations_per_user(self):
2529 """ MAX translations per user - recycle the least recently used """
2531 self.nat44_add_address(self.nat_addr)
2532 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
2533 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
2536 # get maximum number of translations per user
2537 nat44_config = self.vapi.nat_show_config()
2539 # send more than maximum number of translations per user packets
2540 pkts_num = nat44_config.max_translations_per_user + 5
2542 for port in range(0, pkts_num):
2543 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2544 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
2545 TCP(sport=1025 + port))
2547 self.pg0.add_stream(pkts)
2548 self.pg_enable_capture(self.pg_interfaces)
2551 # verify number of translated packet
2552 self.pg1.get_capture(pkts_num)
2554 users = self.vapi.nat44_user_dump()
2556 if user.ip_address == self.pg0.remote_ip4n:
2557 self.assertEqual(user.nsessions,
2558 nat44_config.max_translations_per_user)
2559 self.assertEqual(user.nstaticsessions, 0)
2562 self.nat44_add_static_mapping(self.pg0.remote_ip4, self.nat_addr,
2564 proto=IP_PROTOS.tcp)
2565 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2566 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
2567 TCP(sport=tcp_port))
2568 self.pg0.add_stream(p)
2569 self.pg_enable_capture(self.pg_interfaces)
2571 self.pg1.get_capture(1)
2572 users = self.vapi.nat44_user_dump()
2574 if user.ip_address == self.pg0.remote_ip4n:
2575 self.assertEqual(user.nsessions,
2576 nat44_config.max_translations_per_user - 1)
2577 self.assertEqual(user.nstaticsessions, 1)
2579 def test_interface_addr(self):
2580 """ Acquire NAT44 addresses from interface """
2581 self.vapi.nat44_add_del_interface_addr(self.pg7.sw_if_index)
2583 # no address in NAT pool
2584 adresses = self.vapi.nat44_address_dump()
2585 self.assertEqual(0, len(adresses))
2587 # configure interface address and check NAT address pool
2588 self.pg7.config_ip4()
2589 adresses = self.vapi.nat44_address_dump()
2590 self.assertEqual(1, len(adresses))
2591 self.assertEqual(adresses[0].ip_address[0:4], self.pg7.local_ip4n)
2593 # remove interface address and check NAT address pool
2594 self.pg7.unconfig_ip4()
2595 adresses = self.vapi.nat44_address_dump()
2596 self.assertEqual(0, len(adresses))
2598 def test_interface_addr_static_mapping(self):
2599 """ Static mapping with addresses from interface """
2602 self.vapi.nat44_add_del_interface_addr(self.pg7.sw_if_index)
2603 self.nat44_add_static_mapping(
2605 external_sw_if_index=self.pg7.sw_if_index,
2608 # static mappings with external interface
2609 static_mappings = self.vapi.nat44_static_mapping_dump()
2610 self.assertEqual(1, len(static_mappings))
2611 self.assertEqual(self.pg7.sw_if_index,
2612 static_mappings[0].external_sw_if_index)
2613 self.assertEqual((static_mappings[0].tag).split('\0', 1)[0], tag)
2615 # configure interface address and check static mappings
2616 self.pg7.config_ip4()
2617 static_mappings = self.vapi.nat44_static_mapping_dump()
2618 self.assertEqual(2, len(static_mappings))
2620 for sm in static_mappings:
2621 if sm.external_sw_if_index == 0xFFFFFFFF:
2622 self.assertEqual(sm.external_ip_address[0:4],
2623 self.pg7.local_ip4n)
2624 self.assertEqual((sm.tag).split('\0', 1)[0], tag)
2626 self.assertTrue(resolved)
2628 # remove interface address and check static mappings
2629 self.pg7.unconfig_ip4()
2630 static_mappings = self.vapi.nat44_static_mapping_dump()
2631 self.assertEqual(1, len(static_mappings))
2632 self.assertEqual(self.pg7.sw_if_index,
2633 static_mappings[0].external_sw_if_index)
2634 self.assertEqual((static_mappings[0].tag).split('\0', 1)[0], tag)
2636 # configure interface address again and check static mappings
2637 self.pg7.config_ip4()
2638 static_mappings = self.vapi.nat44_static_mapping_dump()
2639 self.assertEqual(2, len(static_mappings))
2641 for sm in static_mappings:
2642 if sm.external_sw_if_index == 0xFFFFFFFF:
2643 self.assertEqual(sm.external_ip_address[0:4],
2644 self.pg7.local_ip4n)
2645 self.assertEqual((sm.tag).split('\0', 1)[0], tag)
2647 self.assertTrue(resolved)
2649 # remove static mapping
2650 self.nat44_add_static_mapping(
2652 external_sw_if_index=self.pg7.sw_if_index,
2655 static_mappings = self.vapi.nat44_static_mapping_dump()
2656 self.assertEqual(0, len(static_mappings))
2658 def test_interface_addr_identity_nat(self):
2659 """ Identity NAT with addresses from interface """
2662 self.vapi.nat44_add_del_interface_addr(self.pg7.sw_if_index)
2663 self.vapi.nat44_add_del_identity_mapping(
2664 sw_if_index=self.pg7.sw_if_index,
2666 protocol=IP_PROTOS.tcp,
2669 # identity mappings with external interface
2670 identity_mappings = self.vapi.nat44_identity_mapping_dump()
2671 self.assertEqual(1, len(identity_mappings))
2672 self.assertEqual(self.pg7.sw_if_index,
2673 identity_mappings[0].sw_if_index)
2675 # configure interface address and check identity mappings
2676 self.pg7.config_ip4()
2677 identity_mappings = self.vapi.nat44_identity_mapping_dump()
2679 self.assertEqual(2, len(identity_mappings))
2680 for sm in identity_mappings:
2681 if sm.sw_if_index == 0xFFFFFFFF:
2682 self.assertEqual(identity_mappings[0].ip_address,
2683 self.pg7.local_ip4n)
2684 self.assertEqual(port, identity_mappings[0].port)
2685 self.assertEqual(IP_PROTOS.tcp, identity_mappings[0].protocol)
2687 self.assertTrue(resolved)
2689 # remove interface address and check identity mappings
2690 self.pg7.unconfig_ip4()
2691 identity_mappings = self.vapi.nat44_identity_mapping_dump()
2692 self.assertEqual(1, len(identity_mappings))
2693 self.assertEqual(self.pg7.sw_if_index,
2694 identity_mappings[0].sw_if_index)
2696 def test_ipfix_nat44_sess(self):
2697 """ IPFIX logging NAT44 session created/delted """
2698 self.ipfix_domain_id = 10
2699 self.ipfix_src_port = 20202
2700 colector_port = 30303
2701 bind_layers(UDP, IPFIX, dport=30303)
2702 self.nat44_add_address(self.nat_addr)
2703 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
2704 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
2706 self.vapi.set_ipfix_exporter(collector_address=self.pg3.remote_ip4n,
2707 src_address=self.pg3.local_ip4n,
2709 template_interval=10,
2710 collector_port=colector_port)
2711 self.vapi.nat_ipfix_enable_disable(domain_id=self.ipfix_domain_id,
2712 src_port=self.ipfix_src_port)
2714 pkts = self.create_stream_in(self.pg0, self.pg1)
2715 self.pg0.add_stream(pkts)
2716 self.pg_enable_capture(self.pg_interfaces)
2718 capture = self.pg1.get_capture(len(pkts))
2719 self.verify_capture_out(capture)
2720 self.nat44_add_address(self.nat_addr, is_add=0)
2721 self.vapi.cli("ipfix flush") # FIXME this should be an API call
2722 capture = self.pg3.get_capture(9)
2723 ipfix = IPFIXDecoder()
2724 # first load template
2726 self.assertTrue(p.haslayer(IPFIX))
2727 self.assertEqual(p[IP].src, self.pg3.local_ip4)
2728 self.assertEqual(p[IP].dst, self.pg3.remote_ip4)
2729 self.assertEqual(p[UDP].sport, self.ipfix_src_port)
2730 self.assertEqual(p[UDP].dport, colector_port)
2731 self.assertEqual(p[IPFIX].observationDomainID,
2732 self.ipfix_domain_id)
2733 if p.haslayer(Template):
2734 ipfix.add_template(p.getlayer(Template))
2735 # verify events in data set
2737 if p.haslayer(Data):
2738 data = ipfix.decode_data_set(p.getlayer(Set))
2739 self.verify_ipfix_nat44_ses(data)
2741 def test_ipfix_addr_exhausted(self):
2742 """ IPFIX logging NAT addresses exhausted """
2743 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
2744 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
2746 self.vapi.set_ipfix_exporter(collector_address=self.pg3.remote_ip4n,
2747 src_address=self.pg3.local_ip4n,
2749 template_interval=10)
2750 self.vapi.nat_ipfix_enable_disable(domain_id=self.ipfix_domain_id,
2751 src_port=self.ipfix_src_port)
2753 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
2754 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
2756 self.pg0.add_stream(p)
2757 self.pg_enable_capture(self.pg_interfaces)
2759 self.pg1.assert_nothing_captured()
2761 self.vapi.cli("ipfix flush") # FIXME this should be an API call
2762 capture = self.pg3.get_capture(9)
2763 ipfix = IPFIXDecoder()
2764 # first load template
2766 self.assertTrue(p.haslayer(IPFIX))
2767 self.assertEqual(p[IP].src, self.pg3.local_ip4)
2768 self.assertEqual(p[IP].dst, self.pg3.remote_ip4)
2769 self.assertEqual(p[UDP].sport, self.ipfix_src_port)
2770 self.assertEqual(p[UDP].dport, 4739)
2771 self.assertEqual(p[IPFIX].observationDomainID,
2772 self.ipfix_domain_id)
2773 if p.haslayer(Template):
2774 ipfix.add_template(p.getlayer(Template))
2775 # verify events in data set
2777 if p.haslayer(Data):
2778 data = ipfix.decode_data_set(p.getlayer(Set))
2779 self.verify_ipfix_addr_exhausted(data)
2781 @unittest.skipUnless(running_extended_tests, "part of extended tests")
2782 def test_ipfix_max_sessions(self):
2783 """ IPFIX logging maximum session entries exceeded """
2784 self.nat44_add_address(self.nat_addr)
2785 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
2786 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
2789 nat44_config = self.vapi.nat_show_config()
2790 max_sessions = 10 * nat44_config.translation_buckets
2793 for i in range(0, max_sessions):
2794 src = "10.10.%u.%u" % ((i & 0xFF00) >> 8, i & 0xFF)
2795 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2796 IP(src=src, dst=self.pg1.remote_ip4) /
2799 self.pg0.add_stream(pkts)
2800 self.pg_enable_capture(self.pg_interfaces)
2803 self.pg1.get_capture(max_sessions)
2804 self.vapi.set_ipfix_exporter(collector_address=self.pg3.remote_ip4n,
2805 src_address=self.pg3.local_ip4n,
2807 template_interval=10)
2808 self.vapi.nat_ipfix_enable_disable(domain_id=self.ipfix_domain_id,
2809 src_port=self.ipfix_src_port)
2811 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2812 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
2814 self.pg0.add_stream(p)
2815 self.pg_enable_capture(self.pg_interfaces)
2817 self.pg1.assert_nothing_captured()
2819 self.vapi.cli("ipfix flush") # FIXME this should be an API call
2820 capture = self.pg3.get_capture(9)
2821 ipfix = IPFIXDecoder()
2822 # first load template
2824 self.assertTrue(p.haslayer(IPFIX))
2825 self.assertEqual(p[IP].src, self.pg3.local_ip4)
2826 self.assertEqual(p[IP].dst, self.pg3.remote_ip4)
2827 self.assertEqual(p[UDP].sport, self.ipfix_src_port)
2828 self.assertEqual(p[UDP].dport, 4739)
2829 self.assertEqual(p[IPFIX].observationDomainID,
2830 self.ipfix_domain_id)
2831 if p.haslayer(Template):
2832 ipfix.add_template(p.getlayer(Template))
2833 # verify events in data set
2835 if p.haslayer(Data):
2836 data = ipfix.decode_data_set(p.getlayer(Set))
2837 self.verify_ipfix_max_sessions(data, max_sessions)
2839 def test_syslog_apmap(self):
2840 """ Test syslog address and port mapping creation and deletion """
2841 self.vapi.syslog_set_filter(SYSLOG_SEVERITY.INFO)
2842 self.vapi.syslog_set_sender(self.pg3.local_ip4n, self.pg3.remote_ip4n)
2843 self.nat44_add_address(self.nat_addr)
2844 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
2845 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
2848 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2849 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
2850 TCP(sport=self.tcp_port_in, dport=20))
2851 self.pg0.add_stream(p)
2852 self.pg_enable_capture(self.pg_interfaces)
2854 capture = self.pg1.get_capture(1)
2855 self.tcp_port_out = capture[0][TCP].sport
2856 capture = self.pg3.get_capture(1)
2857 self.verify_syslog_apmap(capture[0][Raw].load)
2859 self.pg_enable_capture(self.pg_interfaces)
2861 self.nat44_add_address(self.nat_addr, is_add=0)
2862 capture = self.pg3.get_capture(1)
2863 self.verify_syslog_apmap(capture[0][Raw].load, False)
2865 def test_pool_addr_fib(self):
2866 """ NAT44 add pool addresses to FIB """
2867 static_addr = '10.0.0.10'
2868 self.nat44_add_address(self.nat_addr)
2869 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
2870 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
2872 self.nat44_add_static_mapping(self.pg0.remote_ip4, static_addr)
2875 p = (Ether(src=self.pg1.remote_mac, dst='ff:ff:ff:ff:ff:ff') /
2876 ARP(op=ARP.who_has, pdst=self.nat_addr,
2877 psrc=self.pg1.remote_ip4, hwsrc=self.pg1.remote_mac))
2878 self.pg1.add_stream(p)
2879 self.pg_enable_capture(self.pg_interfaces)
2881 capture = self.pg1.get_capture(1)
2882 self.assertTrue(capture[0].haslayer(ARP))
2883 self.assertTrue(capture[0][ARP].op, ARP.is_at)
2886 p = (Ether(src=self.pg1.remote_mac, dst='ff:ff:ff:ff:ff:ff') /
2887 ARP(op=ARP.who_has, pdst=static_addr,
2888 psrc=self.pg1.remote_ip4, hwsrc=self.pg1.remote_mac))
2889 self.pg1.add_stream(p)
2890 self.pg_enable_capture(self.pg_interfaces)
2892 capture = self.pg1.get_capture(1)
2893 self.assertTrue(capture[0].haslayer(ARP))
2894 self.assertTrue(capture[0][ARP].op, ARP.is_at)
2896 # send ARP to non-NAT44 interface
2897 p = (Ether(src=self.pg2.remote_mac, dst='ff:ff:ff:ff:ff:ff') /
2898 ARP(op=ARP.who_has, pdst=self.nat_addr,
2899 psrc=self.pg2.remote_ip4, hwsrc=self.pg2.remote_mac))
2900 self.pg2.add_stream(p)
2901 self.pg_enable_capture(self.pg_interfaces)
2903 self.pg1.assert_nothing_captured()
2905 # remove addresses and verify
2906 self.nat44_add_address(self.nat_addr, is_add=0)
2907 self.nat44_add_static_mapping(self.pg0.remote_ip4, static_addr,
2910 p = (Ether(src=self.pg1.remote_mac, dst='ff:ff:ff:ff:ff:ff') /
2911 ARP(op=ARP.who_has, pdst=self.nat_addr,
2912 psrc=self.pg1.remote_ip4, hwsrc=self.pg1.remote_mac))
2913 self.pg1.add_stream(p)
2914 self.pg_enable_capture(self.pg_interfaces)
2916 self.pg1.assert_nothing_captured()
2918 p = (Ether(src=self.pg1.remote_mac, dst='ff:ff:ff:ff:ff:ff') /
2919 ARP(op=ARP.who_has, pdst=static_addr,
2920 psrc=self.pg1.remote_ip4, hwsrc=self.pg1.remote_mac))
2921 self.pg1.add_stream(p)
2922 self.pg_enable_capture(self.pg_interfaces)
2924 self.pg1.assert_nothing_captured()
2926 def test_vrf_mode(self):
2927 """ NAT44 tenant VRF aware address pool mode """
2931 nat_ip1 = "10.0.0.10"
2932 nat_ip2 = "10.0.0.11"
2934 self.pg0.unconfig_ip4()
2935 self.pg1.unconfig_ip4()
2936 self.vapi.ip_table_add_del(is_add=1, table_id=vrf_id1)
2937 self.vapi.ip_table_add_del(is_add=1, table_id=vrf_id2)
2938 self.pg0.set_table_ip4(vrf_id1)
2939 self.pg1.set_table_ip4(vrf_id2)
2940 self.pg0.config_ip4()
2941 self.pg1.config_ip4()
2942 self.pg0.resolve_arp()
2943 self.pg1.resolve_arp()
2945 self.nat44_add_address(nat_ip1, vrf_id=vrf_id1)
2946 self.nat44_add_address(nat_ip2, vrf_id=vrf_id2)
2947 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
2948 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index)
2949 self.vapi.nat44_interface_add_del_feature(self.pg2.sw_if_index,
2954 pkts = self.create_stream_in(self.pg0, self.pg2)
2955 self.pg0.add_stream(pkts)
2956 self.pg_enable_capture(self.pg_interfaces)
2958 capture = self.pg2.get_capture(len(pkts))
2959 self.verify_capture_out(capture, nat_ip1)
2962 pkts = self.create_stream_in(self.pg1, self.pg2)
2963 self.pg1.add_stream(pkts)
2964 self.pg_enable_capture(self.pg_interfaces)
2966 capture = self.pg2.get_capture(len(pkts))
2967 self.verify_capture_out(capture, nat_ip2)
2970 self.pg0.unconfig_ip4()
2971 self.pg1.unconfig_ip4()
2972 self.pg0.set_table_ip4(0)
2973 self.pg1.set_table_ip4(0)
2974 self.pg0.config_ip4()
2975 self.pg1.config_ip4()
2976 self.pg0.resolve_arp()
2977 self.pg1.resolve_arp()
2978 self.vapi.ip_table_add_del(is_add=0, table_id=vrf_id1)
2979 self.vapi.ip_table_add_del(is_add=0, table_id=vrf_id2)
2981 def test_vrf_feature_independent(self):
2982 """ NAT44 tenant VRF independent address pool mode """
2984 nat_ip1 = "10.0.0.10"
2985 nat_ip2 = "10.0.0.11"
2987 self.nat44_add_address(nat_ip1)
2988 self.nat44_add_address(nat_ip2, vrf_id=99)
2989 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
2990 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index)
2991 self.vapi.nat44_interface_add_del_feature(self.pg2.sw_if_index,
2995 pkts = self.create_stream_in(self.pg0, self.pg2)
2996 self.pg0.add_stream(pkts)
2997 self.pg_enable_capture(self.pg_interfaces)
2999 capture = self.pg2.get_capture(len(pkts))
3000 self.verify_capture_out(capture, nat_ip1)
3003 pkts = self.create_stream_in(self.pg1, self.pg2)
3004 self.pg1.add_stream(pkts)
3005 self.pg_enable_capture(self.pg_interfaces)
3007 capture = self.pg2.get_capture(len(pkts))
3008 self.verify_capture_out(capture, nat_ip1)
3010 def test_dynamic_ipless_interfaces(self):
3011 """ NAT44 interfaces without configured IP address """
3013 self.vapi.ip_neighbor_add_del(
3014 self.pg7.sw_if_index,
3015 self.pg7.remote_mac,
3016 self.pg7.remote_ip4,
3017 flags=(VppEnum.vl_api_ip_neighbor_flags_t.
3018 IP_API_NEIGHBOR_FLAG_STATIC))
3019 self.vapi.ip_neighbor_add_del(
3020 self.pg8.sw_if_index,
3021 self.pg8.remote_mac,
3022 self.pg8.remote_ip4,
3023 flags=(VppEnum.vl_api_ip_neighbor_flags_t.
3024 IP_API_NEIGHBOR_FLAG_STATIC))
3026 self.vapi.ip_add_del_route(dst_address=self.pg7.remote_ip4n,
3027 dst_address_length=32,
3028 next_hop_address=self.pg7.remote_ip4n,
3029 next_hop_sw_if_index=self.pg7.sw_if_index)
3030 self.vapi.ip_add_del_route(dst_address=self.pg8.remote_ip4n,
3031 dst_address_length=32,
3032 next_hop_address=self.pg8.remote_ip4n,
3033 next_hop_sw_if_index=self.pg8.sw_if_index)
3035 self.nat44_add_address(self.nat_addr)
3036 self.vapi.nat44_interface_add_del_feature(self.pg7.sw_if_index)
3037 self.vapi.nat44_interface_add_del_feature(self.pg8.sw_if_index,
3041 pkts = self.create_stream_in(self.pg7, self.pg8)
3042 self.pg7.add_stream(pkts)
3043 self.pg_enable_capture(self.pg_interfaces)
3045 capture = self.pg8.get_capture(len(pkts))
3046 self.verify_capture_out(capture)
3049 pkts = self.create_stream_out(self.pg8, self.nat_addr)
3050 self.pg8.add_stream(pkts)
3051 self.pg_enable_capture(self.pg_interfaces)
3053 capture = self.pg7.get_capture(len(pkts))
3054 self.verify_capture_in(capture, self.pg7)
3056 def test_static_ipless_interfaces(self):
3057 """ NAT44 interfaces without configured IP address - 1:1 NAT """
3059 self.vapi.ip_neighbor_add_del(
3060 self.pg7.sw_if_index,
3061 self.pg7.remote_mac,
3062 self.pg7.remote_ip4,
3063 flags=(VppEnum.vl_api_ip_neighbor_flags_t.
3064 IP_API_NEIGHBOR_FLAG_STATIC))
3065 self.vapi.ip_neighbor_add_del(
3066 self.pg8.sw_if_index,
3067 self.pg8.remote_mac,
3068 self.pg8.remote_ip4,
3069 flags=(VppEnum.vl_api_ip_neighbor_flags_t.
3070 IP_API_NEIGHBOR_FLAG_STATIC))
3072 self.vapi.ip_add_del_route(dst_address=self.pg7.remote_ip4n,
3073 dst_address_length=32,
3074 next_hop_address=self.pg7.remote_ip4n,
3075 next_hop_sw_if_index=self.pg7.sw_if_index)
3076 self.vapi.ip_add_del_route(dst_address=self.pg8.remote_ip4n,
3077 dst_address_length=32,
3078 next_hop_address=self.pg8.remote_ip4n,
3079 next_hop_sw_if_index=self.pg8.sw_if_index)
3081 self.nat44_add_static_mapping(self.pg7.remote_ip4, self.nat_addr)
3082 self.vapi.nat44_interface_add_del_feature(self.pg7.sw_if_index)
3083 self.vapi.nat44_interface_add_del_feature(self.pg8.sw_if_index,
3087 pkts = self.create_stream_out(self.pg8)
3088 self.pg8.add_stream(pkts)
3089 self.pg_enable_capture(self.pg_interfaces)
3091 capture = self.pg7.get_capture(len(pkts))
3092 self.verify_capture_in(capture, self.pg7)
3095 pkts = self.create_stream_in(self.pg7, self.pg8)
3096 self.pg7.add_stream(pkts)
3097 self.pg_enable_capture(self.pg_interfaces)
3099 capture = self.pg8.get_capture(len(pkts))
3100 self.verify_capture_out(capture, self.nat_addr, True)
3102 def test_static_with_port_ipless_interfaces(self):
3103 """ NAT44 interfaces without configured IP address - 1:1 NAPT """
3105 self.tcp_port_out = 30606
3106 self.udp_port_out = 30607
3107 self.icmp_id_out = 30608
3109 self.vapi.ip_neighbor_add_del(
3110 self.pg7.sw_if_index,
3111 self.pg7.remote_mac,
3112 self.pg7.remote_ip4,
3113 flags=(VppEnum.vl_api_ip_neighbor_flags_t.
3114 IP_API_NEIGHBOR_FLAG_STATIC))
3115 self.vapi.ip_neighbor_add_del(
3116 self.pg8.sw_if_index,
3117 self.pg8.remote_mac,
3118 self.pg8.remote_ip4,
3119 flags=(VppEnum.vl_api_ip_neighbor_flags_t.
3120 IP_API_NEIGHBOR_FLAG_STATIC))
3122 self.vapi.ip_add_del_route(dst_address=self.pg7.remote_ip4n,
3123 dst_address_length=32,
3124 next_hop_address=self.pg7.remote_ip4n,
3125 next_hop_sw_if_index=self.pg7.sw_if_index)
3126 self.vapi.ip_add_del_route(dst_address=self.pg8.remote_ip4n,
3127 dst_address_length=32,
3128 next_hop_address=self.pg8.remote_ip4n,
3129 next_hop_sw_if_index=self.pg8.sw_if_index)
3131 self.nat44_add_address(self.nat_addr)
3132 self.nat44_add_static_mapping(self.pg7.remote_ip4, self.nat_addr,
3133 self.tcp_port_in, self.tcp_port_out,
3134 proto=IP_PROTOS.tcp)
3135 self.nat44_add_static_mapping(self.pg7.remote_ip4, self.nat_addr,
3136 self.udp_port_in, self.udp_port_out,
3137 proto=IP_PROTOS.udp)
3138 self.nat44_add_static_mapping(self.pg7.remote_ip4, self.nat_addr,
3139 self.icmp_id_in, self.icmp_id_out,
3140 proto=IP_PROTOS.icmp)
3141 self.vapi.nat44_interface_add_del_feature(self.pg7.sw_if_index)
3142 self.vapi.nat44_interface_add_del_feature(self.pg8.sw_if_index,
3146 pkts = self.create_stream_out(self.pg8)
3147 self.pg8.add_stream(pkts)
3148 self.pg_enable_capture(self.pg_interfaces)
3150 capture = self.pg7.get_capture(len(pkts))
3151 self.verify_capture_in(capture, self.pg7)
3154 pkts = self.create_stream_in(self.pg7, self.pg8)
3155 self.pg7.add_stream(pkts)
3156 self.pg_enable_capture(self.pg_interfaces)
3158 capture = self.pg8.get_capture(len(pkts))
3159 self.verify_capture_out(capture)
3161 def test_static_unknown_proto(self):
3162 """ 1:1 NAT translate packet with unknown protocol """
3163 nat_ip = "10.0.0.10"
3164 self.nat44_add_static_mapping(self.pg0.remote_ip4, nat_ip)
3165 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
3166 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
3170 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
3171 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
3173 IP(src=self.pg2.remote_ip4, dst=self.pg3.remote_ip4) /
3174 TCP(sport=1234, dport=1234))
3175 self.pg0.add_stream(p)
3176 self.pg_enable_capture(self.pg_interfaces)
3178 p = self.pg1.get_capture(1)
3181 self.assertEqual(packet[IP].src, nat_ip)
3182 self.assertEqual(packet[IP].dst, self.pg1.remote_ip4)
3183 self.assertEqual(packet.haslayer(GRE), 1)
3184 self.assert_packet_checksums_valid(packet)
3186 self.logger.error(ppp("Unexpected or invalid packet:", packet))
3190 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
3191 IP(src=self.pg1.remote_ip4, dst=nat_ip) /
3193 IP(src=self.pg3.remote_ip4, dst=self.pg2.remote_ip4) /
3194 TCP(sport=1234, dport=1234))
3195 self.pg1.add_stream(p)
3196 self.pg_enable_capture(self.pg_interfaces)
3198 p = self.pg0.get_capture(1)
3201 self.assertEqual(packet[IP].src, self.pg1.remote_ip4)
3202 self.assertEqual(packet[IP].dst, self.pg0.remote_ip4)
3203 self.assertEqual(packet.haslayer(GRE), 1)
3204 self.assert_packet_checksums_valid(packet)
3206 self.logger.error(ppp("Unexpected or invalid packet:", packet))
3209 def test_hairpinning_static_unknown_proto(self):
3210 """ 1:1 NAT translate packet with unknown protocol - hairpinning """
3212 host = self.pg0.remote_hosts[0]
3213 server = self.pg0.remote_hosts[1]
3215 host_nat_ip = "10.0.0.10"
3216 server_nat_ip = "10.0.0.11"
3218 self.nat44_add_static_mapping(host.ip4, host_nat_ip)
3219 self.nat44_add_static_mapping(server.ip4, server_nat_ip)
3220 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
3221 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
3225 p = (Ether(dst=self.pg0.local_mac, src=host.mac) /
3226 IP(src=host.ip4, dst=server_nat_ip) /
3228 IP(src=self.pg2.remote_ip4, dst=self.pg3.remote_ip4) /
3229 TCP(sport=1234, dport=1234))
3230 self.pg0.add_stream(p)
3231 self.pg_enable_capture(self.pg_interfaces)
3233 p = self.pg0.get_capture(1)
3236 self.assertEqual(packet[IP].src, host_nat_ip)
3237 self.assertEqual(packet[IP].dst, server.ip4)
3238 self.assertEqual(packet.haslayer(GRE), 1)
3239 self.assert_packet_checksums_valid(packet)
3241 self.logger.error(ppp("Unexpected or invalid packet:", packet))
3245 p = (Ether(dst=self.pg0.local_mac, src=server.mac) /
3246 IP(src=server.ip4, dst=host_nat_ip) /
3248 IP(src=self.pg3.remote_ip4, dst=self.pg2.remote_ip4) /
3249 TCP(sport=1234, dport=1234))
3250 self.pg0.add_stream(p)
3251 self.pg_enable_capture(self.pg_interfaces)
3253 p = self.pg0.get_capture(1)
3256 self.assertEqual(packet[IP].src, server_nat_ip)
3257 self.assertEqual(packet[IP].dst, host.ip4)
3258 self.assertEqual(packet.haslayer(GRE), 1)
3259 self.assert_packet_checksums_valid(packet)
3261 self.logger.error(ppp("Unexpected or invalid packet:", packet))
3264 def test_output_feature(self):
3265 """ NAT44 interface output feature (in2out postrouting) """
3266 self.nat44_add_address(self.nat_addr)
3267 self.vapi.nat44_interface_add_del_output_feature(self.pg0.sw_if_index)
3268 self.vapi.nat44_interface_add_del_output_feature(self.pg1.sw_if_index)
3269 self.vapi.nat44_interface_add_del_output_feature(self.pg3.sw_if_index,
3273 pkts = self.create_stream_in(self.pg0, self.pg3)
3274 self.pg0.add_stream(pkts)
3275 self.pg_enable_capture(self.pg_interfaces)
3277 capture = self.pg3.get_capture(len(pkts))
3278 self.verify_capture_out(capture)
3281 pkts = self.create_stream_out(self.pg3)
3282 self.pg3.add_stream(pkts)
3283 self.pg_enable_capture(self.pg_interfaces)
3285 capture = self.pg0.get_capture(len(pkts))
3286 self.verify_capture_in(capture, self.pg0)
3288 # from non-NAT interface to NAT inside interface
3289 pkts = self.create_stream_in(self.pg2, self.pg0)
3290 self.pg2.add_stream(pkts)
3291 self.pg_enable_capture(self.pg_interfaces)
3293 capture = self.pg0.get_capture(len(pkts))
3294 self.verify_capture_no_translation(capture, self.pg2, self.pg0)
3296 def test_output_feature_vrf_aware(self):
3297 """ NAT44 interface output feature VRF aware (in2out postrouting) """
3298 nat_ip_vrf10 = "10.0.0.10"
3299 nat_ip_vrf20 = "10.0.0.20"
3301 self.vapi.ip_add_del_route(dst_address=self.pg3.remote_ip4n,
3302 dst_address_length=32,
3303 next_hop_address=self.pg3.remote_ip4n,
3304 next_hop_sw_if_index=self.pg3.sw_if_index,
3306 self.vapi.ip_add_del_route(dst_address=self.pg3.remote_ip4n,
3307 dst_address_length=32,
3308 next_hop_address=self.pg3.remote_ip4n,
3309 next_hop_sw_if_index=self.pg3.sw_if_index,
3312 self.nat44_add_address(nat_ip_vrf10, vrf_id=10)
3313 self.nat44_add_address(nat_ip_vrf20, vrf_id=20)
3314 self.vapi.nat44_interface_add_del_output_feature(self.pg4.sw_if_index)
3315 self.vapi.nat44_interface_add_del_output_feature(self.pg6.sw_if_index)
3316 self.vapi.nat44_interface_add_del_output_feature(self.pg3.sw_if_index,
3320 pkts = self.create_stream_in(self.pg4, self.pg3)
3321 self.pg4.add_stream(pkts)
3322 self.pg_enable_capture(self.pg_interfaces)
3324 capture = self.pg3.get_capture(len(pkts))
3325 self.verify_capture_out(capture, nat_ip=nat_ip_vrf10)
3328 pkts = self.create_stream_out(self.pg3, dst_ip=nat_ip_vrf10)
3329 self.pg3.add_stream(pkts)
3330 self.pg_enable_capture(self.pg_interfaces)
3332 capture = self.pg4.get_capture(len(pkts))
3333 self.verify_capture_in(capture, self.pg4)
3336 pkts = self.create_stream_in(self.pg6, self.pg3)
3337 self.pg6.add_stream(pkts)
3338 self.pg_enable_capture(self.pg_interfaces)
3340 capture = self.pg3.get_capture(len(pkts))
3341 self.verify_capture_out(capture, nat_ip=nat_ip_vrf20)
3344 pkts = self.create_stream_out(self.pg3, dst_ip=nat_ip_vrf20)
3345 self.pg3.add_stream(pkts)
3346 self.pg_enable_capture(self.pg_interfaces)
3348 capture = self.pg6.get_capture(len(pkts))
3349 self.verify_capture_in(capture, self.pg6)
3351 def test_output_feature_hairpinning(self):
3352 """ NAT44 interface output feature hairpinning (in2out postrouting) """
3353 host = self.pg0.remote_hosts[0]
3354 server = self.pg0.remote_hosts[1]
3357 server_in_port = 5678
3358 server_out_port = 8765
3360 self.nat44_add_address(self.nat_addr)
3361 self.vapi.nat44_interface_add_del_output_feature(self.pg0.sw_if_index)
3362 self.vapi.nat44_interface_add_del_output_feature(self.pg1.sw_if_index,
3365 # add static mapping for server
3366 self.nat44_add_static_mapping(server.ip4, self.nat_addr,
3367 server_in_port, server_out_port,
3368 proto=IP_PROTOS.tcp)
3370 # send packet from host to server
3371 p = (Ether(src=host.mac, dst=self.pg0.local_mac) /
3372 IP(src=host.ip4, dst=self.nat_addr) /
3373 TCP(sport=host_in_port, dport=server_out_port))
3374 self.pg0.add_stream(p)
3375 self.pg_enable_capture(self.pg_interfaces)
3377 capture = self.pg0.get_capture(1)
3382 self.assertEqual(ip.src, self.nat_addr)
3383 self.assertEqual(ip.dst, server.ip4)
3384 self.assertNotEqual(tcp.sport, host_in_port)
3385 self.assertEqual(tcp.dport, server_in_port)
3386 self.assert_packet_checksums_valid(p)
3387 host_out_port = tcp.sport
3389 self.logger.error(ppp("Unexpected or invalid packet:", p))
3392 # send reply from server to host
3393 p = (Ether(src=server.mac, dst=self.pg0.local_mac) /
3394 IP(src=server.ip4, dst=self.nat_addr) /
3395 TCP(sport=server_in_port, dport=host_out_port))
3396 self.pg0.add_stream(p)
3397 self.pg_enable_capture(self.pg_interfaces)
3399 capture = self.pg0.get_capture(1)
3404 self.assertEqual(ip.src, self.nat_addr)
3405 self.assertEqual(ip.dst, host.ip4)
3406 self.assertEqual(tcp.sport, server_out_port)
3407 self.assertEqual(tcp.dport, host_in_port)
3408 self.assert_packet_checksums_valid(p)
3410 self.logger.error(ppp("Unexpected or invalid packet:", p))
3413 def test_one_armed_nat44(self):
3414 """ One armed NAT44 """
3415 remote_host = self.pg9.remote_hosts[0]
3416 local_host = self.pg9.remote_hosts[1]
3419 self.nat44_add_address(self.nat_addr)
3420 self.vapi.nat44_interface_add_del_feature(self.pg9.sw_if_index)
3421 self.vapi.nat44_interface_add_del_feature(self.pg9.sw_if_index,
3425 p = (Ether(src=self.pg9.remote_mac, dst=self.pg9.local_mac) /
3426 IP(src=local_host.ip4, dst=remote_host.ip4) /
3427 TCP(sport=12345, dport=80))
3428 self.pg9.add_stream(p)
3429 self.pg_enable_capture(self.pg_interfaces)
3431 capture = self.pg9.get_capture(1)
3436 self.assertEqual(ip.src, self.nat_addr)
3437 self.assertEqual(ip.dst, remote_host.ip4)
3438 self.assertNotEqual(tcp.sport, 12345)
3439 external_port = tcp.sport
3440 self.assertEqual(tcp.dport, 80)
3441 self.assert_packet_checksums_valid(p)
3443 self.logger.error(ppp("Unexpected or invalid packet:", p))
3447 p = (Ether(src=self.pg9.remote_mac, dst=self.pg9.local_mac) /
3448 IP(src=remote_host.ip4, dst=self.nat_addr) /
3449 TCP(sport=80, dport=external_port))
3450 self.pg9.add_stream(p)
3451 self.pg_enable_capture(self.pg_interfaces)
3453 capture = self.pg9.get_capture(1)
3458 self.assertEqual(ip.src, remote_host.ip4)
3459 self.assertEqual(ip.dst, local_host.ip4)
3460 self.assertEqual(tcp.sport, 80)
3461 self.assertEqual(tcp.dport, 12345)
3462 self.assert_packet_checksums_valid(p)
3464 self.logger.error(ppp("Unexpected or invalid packet:", p))
3467 err = self.statistics.get_counter('/err/nat44-classify/next in2out')
3468 self.assertEqual(err, 1)
3469 err = self.statistics.get_counter('/err/nat44-classify/next out2in')
3470 self.assertEqual(err, 1)
3472 def test_del_session(self):
3473 """ Delete NAT44 session """
3474 self.nat44_add_address(self.nat_addr)
3475 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
3476 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
3479 pkts = self.create_stream_in(self.pg0, self.pg1)
3480 self.pg0.add_stream(pkts)
3481 self.pg_enable_capture(self.pg_interfaces)
3483 self.pg1.get_capture(len(pkts))
3485 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4n, 0)
3486 nsessions = len(sessions)
3488 self.vapi.nat44_del_session(sessions[0].inside_ip_address,
3489 sessions[0].inside_port,
3490 sessions[0].protocol)
3491 self.vapi.nat44_del_session(sessions[1].outside_ip_address,
3492 sessions[1].outside_port,
3493 sessions[1].protocol,
3496 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4n, 0)
3497 self.assertEqual(nsessions - len(sessions), 2)
3499 self.vapi.nat44_del_session(sessions[0].inside_ip_address,
3500 sessions[0].inside_port,
3501 sessions[0].protocol)
3503 self.verify_no_nat44_user()
3505 def test_set_get_reass(self):
3506 """ NAT44 set/get virtual fragmentation reassembly """
3507 reas_cfg1 = self.vapi.nat_get_reass()
3509 self.vapi.nat_set_reass(timeout=reas_cfg1.ip4_timeout + 5,
3510 max_reass=reas_cfg1.ip4_max_reass * 2,
3511 max_frag=reas_cfg1.ip4_max_frag * 2)
3513 reas_cfg2 = self.vapi.nat_get_reass()
3515 self.assertEqual(reas_cfg1.ip4_timeout + 5, reas_cfg2.ip4_timeout)
3516 self.assertEqual(reas_cfg1.ip4_max_reass * 2, reas_cfg2.ip4_max_reass)
3517 self.assertEqual(reas_cfg1.ip4_max_frag * 2, reas_cfg2.ip4_max_frag)
3519 self.vapi.nat_set_reass(drop_frag=1)
3520 self.assertTrue(self.vapi.nat_get_reass().ip4_drop_frag)
3522 def test_frag_in_order(self):
3523 """ NAT44 translate fragments arriving in order """
3525 self.nat44_add_address(self.nat_addr)
3526 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
3527 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
3530 self.frag_in_order(proto=IP_PROTOS.tcp)
3531 self.frag_in_order(proto=IP_PROTOS.udp)
3532 self.frag_in_order(proto=IP_PROTOS.icmp)
3534 def test_frag_forwarding(self):
3535 """ NAT44 forwarding fragment test """
3536 self.vapi.nat44_add_del_interface_addr(self.pg1.sw_if_index)
3537 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
3538 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
3540 self.vapi.nat44_forwarding_enable_disable(1)
3542 data = "A" * 16 + "B" * 16 + "C" * 3
3543 pkts = self.create_stream_frag(self.pg1,
3544 self.pg0.remote_ip4,
3548 proto=IP_PROTOS.udp)
3549 self.pg1.add_stream(pkts)
3550 self.pg_enable_capture(self.pg_interfaces)
3552 frags = self.pg0.get_capture(len(pkts))
3553 p = self.reass_frags_and_verify(frags,
3554 self.pg1.remote_ip4,
3555 self.pg0.remote_ip4)
3556 self.assertEqual(p[UDP].sport, 4789)
3557 self.assertEqual(p[UDP].dport, 4789)
3558 self.assertEqual(data, p[Raw].load)
3560 def test_reass_hairpinning(self):
3561 """ NAT44 fragments hairpinning """
3563 self.server = self.pg0.remote_hosts[1]
3564 self.host_in_port = random.randint(1025, 65535)
3565 self.server_in_port = random.randint(1025, 65535)
3566 self.server_out_port = random.randint(1025, 65535)
3568 self.nat44_add_address(self.nat_addr)
3569 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
3570 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
3572 # add static mapping for server
3573 self.nat44_add_static_mapping(self.server.ip4, self.nat_addr,
3574 self.server_in_port,
3575 self.server_out_port,
3576 proto=IP_PROTOS.tcp)
3577 self.nat44_add_static_mapping(self.server.ip4, self.nat_addr,
3578 self.server_in_port,
3579 self.server_out_port,
3580 proto=IP_PROTOS.udp)
3581 self.nat44_add_static_mapping(self.server.ip4, self.nat_addr)
3583 self.reass_hairpinning(proto=IP_PROTOS.tcp)
3584 self.reass_hairpinning(proto=IP_PROTOS.udp)
3585 self.reass_hairpinning(proto=IP_PROTOS.icmp)
3587 def test_frag_out_of_order(self):
3588 """ NAT44 translate fragments arriving out of order """
3590 self.nat44_add_address(self.nat_addr)
3591 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
3592 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
3595 self.frag_out_of_order(proto=IP_PROTOS.tcp)
3596 self.frag_out_of_order(proto=IP_PROTOS.udp)
3597 self.frag_out_of_order(proto=IP_PROTOS.icmp)
3599 def test_port_restricted(self):
3600 """ Port restricted NAT44 (MAP-E CE) """
3601 self.nat44_add_address(self.nat_addr)
3602 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
3603 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
3605 self.vapi.nat_set_addr_and_port_alloc_alg(alg=1,
3610 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
3611 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
3612 TCP(sport=4567, dport=22))
3613 self.pg0.add_stream(p)
3614 self.pg_enable_capture(self.pg_interfaces)
3616 capture = self.pg1.get_capture(1)
3621 self.assertEqual(ip.dst, self.pg1.remote_ip4)
3622 self.assertEqual(ip.src, self.nat_addr)
3623 self.assertEqual(tcp.dport, 22)
3624 self.assertNotEqual(tcp.sport, 4567)
3625 self.assertEqual((tcp.sport >> 6) & 63, 10)
3626 self.assert_packet_checksums_valid(p)
3628 self.logger.error(ppp("Unexpected or invalid packet:", p))
3631 def test_port_range(self):
3632 """ External address port range """
3633 self.nat44_add_address(self.nat_addr)
3634 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
3635 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
3637 self.vapi.nat_set_addr_and_port_alloc_alg(alg=2,
3642 for port in range(0, 5):
3643 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
3644 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
3645 TCP(sport=1125 + port))
3647 self.pg0.add_stream(pkts)
3648 self.pg_enable_capture(self.pg_interfaces)
3650 capture = self.pg1.get_capture(3)
3653 self.assertGreaterEqual(tcp.sport, 1025)
3654 self.assertLessEqual(tcp.sport, 1027)
3656 def test_ipfix_max_frags(self):
3657 """ IPFIX logging maximum fragments pending reassembly exceeded """
3658 self.nat44_add_address(self.nat_addr)
3659 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
3660 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
3662 self.vapi.nat_set_reass(max_frag=1)
3663 self.vapi.set_ipfix_exporter(collector_address=self.pg3.remote_ip4n,
3664 src_address=self.pg3.local_ip4n,
3666 template_interval=10)
3667 self.vapi.nat_ipfix_enable_disable(domain_id=self.ipfix_domain_id,
3668 src_port=self.ipfix_src_port)
3670 data = "A" * 4 + "B" * 16 + "C" * 3
3671 self.tcp_port_in = random.randint(1025, 65535)
3672 pkts = self.create_stream_frag(self.pg0,
3673 self.pg1.remote_ip4,
3678 self.pg0.add_stream(pkts)
3679 self.pg_enable_capture(self.pg_interfaces)
3681 self.pg1.assert_nothing_captured()
3683 self.vapi.cli("ipfix flush") # FIXME this should be an API call
3684 capture = self.pg3.get_capture(9)
3685 ipfix = IPFIXDecoder()
3686 # first load template
3688 self.assertTrue(p.haslayer(IPFIX))
3689 self.assertEqual(p[IP].src, self.pg3.local_ip4)
3690 self.assertEqual(p[IP].dst, self.pg3.remote_ip4)
3691 self.assertEqual(p[UDP].sport, self.ipfix_src_port)
3692 self.assertEqual(p[UDP].dport, 4739)
3693 self.assertEqual(p[IPFIX].observationDomainID,
3694 self.ipfix_domain_id)
3695 if p.haslayer(Template):
3696 ipfix.add_template(p.getlayer(Template))
3697 # verify events in data set
3699 if p.haslayer(Data):
3700 data = ipfix.decode_data_set(p.getlayer(Set))
3701 self.verify_ipfix_max_fragments_ip4(data, 1,
3702 self.pg0.remote_ip4n)
3704 def test_multiple_outside_vrf(self):
3705 """ Multiple outside VRF """
3709 self.pg1.unconfig_ip4()
3710 self.pg2.unconfig_ip4()
3711 self.vapi.ip_table_add_del(is_add=1, table_id=vrf_id1)
3712 self.vapi.ip_table_add_del(is_add=1, table_id=vrf_id2)
3713 self.pg1.set_table_ip4(vrf_id1)
3714 self.pg2.set_table_ip4(vrf_id2)
3715 self.pg1.config_ip4()
3716 self.pg2.config_ip4()
3717 self.pg1.resolve_arp()
3718 self.pg2.resolve_arp()
3720 self.nat44_add_address(self.nat_addr)
3721 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
3722 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
3724 self.vapi.nat44_interface_add_del_feature(self.pg2.sw_if_index,
3729 pkts = self.create_stream_in(self.pg0, self.pg1)
3730 self.pg0.add_stream(pkts)
3731 self.pg_enable_capture(self.pg_interfaces)
3733 capture = self.pg1.get_capture(len(pkts))
3734 self.verify_capture_out(capture, self.nat_addr)
3736 pkts = self.create_stream_out(self.pg1, self.nat_addr)
3737 self.pg1.add_stream(pkts)
3738 self.pg_enable_capture(self.pg_interfaces)
3740 capture = self.pg0.get_capture(len(pkts))
3741 self.verify_capture_in(capture, self.pg0)
3743 self.tcp_port_in = 60303
3744 self.udp_port_in = 60304
3745 self.icmp_id_in = 60305
3748 pkts = self.create_stream_in(self.pg0, self.pg2)
3749 self.pg0.add_stream(pkts)
3750 self.pg_enable_capture(self.pg_interfaces)
3752 capture = self.pg2.get_capture(len(pkts))
3753 self.verify_capture_out(capture, self.nat_addr)
3755 pkts = self.create_stream_out(self.pg2, self.nat_addr)
3756 self.pg2.add_stream(pkts)
3757 self.pg_enable_capture(self.pg_interfaces)
3759 capture = self.pg0.get_capture(len(pkts))
3760 self.verify_capture_in(capture, self.pg0)
3763 self.pg1.unconfig_ip4()
3764 self.pg2.unconfig_ip4()
3765 self.pg1.set_table_ip4(0)
3766 self.pg2.set_table_ip4(0)
3767 self.pg1.config_ip4()
3768 self.pg2.config_ip4()
3769 self.pg1.resolve_arp()
3770 self.pg2.resolve_arp()
3772 @unittest.skipUnless(running_extended_tests, "part of extended tests")
3773 def test_session_timeout(self):
3774 """ NAT44 session timeouts """
3775 self.nat44_add_address(self.nat_addr)
3776 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
3777 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
3779 self.vapi.nat_set_timeouts(udp=5)
3783 for i in range(0, max_sessions):
3784 src = "10.10.%u.%u" % ((i & 0xFF00) >> 8, i & 0xFF)
3785 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
3786 IP(src=src, dst=self.pg1.remote_ip4) /
3787 UDP(sport=1025, dport=53))
3789 self.pg0.add_stream(pkts)
3790 self.pg_enable_capture(self.pg_interfaces)
3792 self.pg1.get_capture(max_sessions)
3797 for i in range(0, max_sessions):
3798 src = "10.10.%u.%u" % ((i & 0xFF00) >> 8, i & 0xFF)
3799 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
3800 IP(src=src, dst=self.pg1.remote_ip4) /
3801 UDP(sport=1026, dport=53))
3803 self.pg0.add_stream(pkts)
3804 self.pg_enable_capture(self.pg_interfaces)
3806 self.pg1.get_capture(max_sessions)
3809 users = self.vapi.nat44_user_dump()
3811 nsessions = nsessions + user.nsessions
3812 self.assertLess(nsessions, 2 * max_sessions)
3814 def test_mss_clamping(self):
3815 """ TCP MSS clamping """
3816 self.nat44_add_address(self.nat_addr)
3817 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
3818 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
3821 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
3822 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
3823 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
3824 flags="S", options=[('MSS', 1400)]))
3826 self.vapi.nat_set_mss_clamping(enable=1, mss_value=1000)
3827 self.pg0.add_stream(p)
3828 self.pg_enable_capture(self.pg_interfaces)
3830 capture = self.pg1.get_capture(1)
3831 # Negotiated MSS value greater than configured - changed
3832 self.verify_mss_value(capture[0], 1000)
3834 self.vapi.nat_set_mss_clamping(enable=0)
3835 self.pg0.add_stream(p)
3836 self.pg_enable_capture(self.pg_interfaces)
3838 capture = self.pg1.get_capture(1)
3839 # MSS clamping disabled - negotiated MSS unchanged
3840 self.verify_mss_value(capture[0], 1400)
3842 self.vapi.nat_set_mss_clamping(enable=1, mss_value=1500)
3843 self.pg0.add_stream(p)
3844 self.pg_enable_capture(self.pg_interfaces)
3846 capture = self.pg1.get_capture(1)
3847 # Negotiated MSS value smaller than configured - unchanged
3848 self.verify_mss_value(capture[0], 1400)
3850 @unittest.skipUnless(running_extended_tests, "part of extended tests")
3851 def test_ha_send(self):
3852 """ Send HA session synchronization events (active) """
3853 self.nat44_add_address(self.nat_addr)
3854 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
3855 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
3857 self.vapi.nat_ha_set_listener(self.pg3.local_ip4, port=12345)
3858 self.vapi.nat_ha_set_failover(self.pg3.remote_ip4, port=12346)
3859 bind_layers(UDP, HANATStateSync, sport=12345)
3862 pkts = self.create_stream_in(self.pg0, self.pg1)
3863 self.pg0.add_stream(pkts)
3864 self.pg_enable_capture(self.pg_interfaces)
3866 capture = self.pg1.get_capture(len(pkts))
3867 self.verify_capture_out(capture)
3868 # active send HA events
3869 self.vapi.nat_ha_flush()
3870 stats = self.statistics.get_counter('/nat44/ha/add-event-send')
3871 self.assertEqual(stats[0][0], 3)
3872 capture = self.pg3.get_capture(1)
3874 self.assert_packet_checksums_valid(p)
3878 hanat = p[HANATStateSync]
3880 self.logger.error(ppp("Invalid packet:", p))
3883 self.assertEqual(ip.src, self.pg3.local_ip4)
3884 self.assertEqual(ip.dst, self.pg3.remote_ip4)
3885 self.assertEqual(udp.sport, 12345)
3886 self.assertEqual(udp.dport, 12346)
3887 self.assertEqual(hanat.version, 1)
3888 self.assertEqual(hanat.thread_index, 0)
3889 self.assertEqual(hanat.count, 3)
3890 seq = hanat.sequence_number
3891 for event in hanat.events:
3892 self.assertEqual(event.event_type, 1)
3893 self.assertEqual(event.in_addr, self.pg0.remote_ip4)
3894 self.assertEqual(event.out_addr, self.nat_addr)
3895 self.assertEqual(event.fib_index, 0)
3897 # ACK received events
3898 ack = (Ether(dst=self.pg3.local_mac, src=self.pg3.remote_mac) /
3899 IP(src=self.pg3.remote_ip4, dst=self.pg3.local_ip4) /
3900 UDP(sport=12346, dport=12345) /
3901 HANATStateSync(sequence_number=seq, flags='ACK'))
3902 self.pg3.add_stream(ack)
3904 stats = self.statistics.get_counter('/nat44/ha/ack-recv')
3905 self.assertEqual(stats[0][0], 1)
3907 # delete one session
3908 self.pg_enable_capture(self.pg_interfaces)
3909 self.vapi.nat44_del_session(self.pg0.remote_ip4n, self.tcp_port_in,
3911 self.vapi.nat_ha_flush()
3912 stats = self.statistics.get_counter('/nat44/ha/del-event-send')
3913 self.assertEqual(stats[0][0], 1)
3914 capture = self.pg3.get_capture(1)
3917 hanat = p[HANATStateSync]
3919 self.logger.error(ppp("Invalid packet:", p))
3922 self.assertGreater(hanat.sequence_number, seq)
3924 # do not send ACK, active retry send HA event again
3925 self.pg_enable_capture(self.pg_interfaces)
3927 stats = self.statistics.get_counter('/nat44/ha/retry-count')
3928 self.assertEqual(stats[0][0], 3)
3929 stats = self.statistics.get_counter('/nat44/ha/missed-count')
3930 self.assertEqual(stats[0][0], 1)
3931 capture = self.pg3.get_capture(3)
3932 for packet in capture:
3933 self.assertEqual(packet, p)
3935 # session counters refresh
3936 pkts = self.create_stream_out(self.pg1)
3937 self.pg1.add_stream(pkts)
3938 self.pg_enable_capture(self.pg_interfaces)
3940 self.pg0.get_capture(2)
3941 self.vapi.nat_ha_flush()
3942 stats = self.statistics.get_counter('/nat44/ha/refresh-event-send')
3943 self.assertEqual(stats[0][0], 2)
3944 capture = self.pg3.get_capture(1)
3946 self.assert_packet_checksums_valid(p)
3950 hanat = p[HANATStateSync]
3952 self.logger.error(ppp("Invalid packet:", p))
3955 self.assertEqual(ip.src, self.pg3.local_ip4)
3956 self.assertEqual(ip.dst, self.pg3.remote_ip4)
3957 self.assertEqual(udp.sport, 12345)
3958 self.assertEqual(udp.dport, 12346)
3959 self.assertEqual(hanat.version, 1)
3960 self.assertEqual(hanat.count, 2)
3961 seq = hanat.sequence_number
3962 for event in hanat.events:
3963 self.assertEqual(event.event_type, 3)
3964 self.assertEqual(event.out_addr, self.nat_addr)
3965 self.assertEqual(event.fib_index, 0)
3966 self.assertEqual(event.total_pkts, 2)
3967 self.assertGreater(event.total_bytes, 0)
3969 ack = (Ether(dst=self.pg3.local_mac, src=self.pg3.remote_mac) /
3970 IP(src=self.pg3.remote_ip4, dst=self.pg3.local_ip4) /
3971 UDP(sport=12346, dport=12345) /
3972 HANATStateSync(sequence_number=seq, flags='ACK'))
3973 self.pg3.add_stream(ack)
3975 stats = self.statistics.get_counter('/nat44/ha/ack-recv')
3976 self.assertEqual(stats[0][0], 2)
3978 def test_ha_recv(self):
3979 """ Receive HA session synchronization events (passive) """
3980 self.nat44_add_address(self.nat_addr)
3981 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
3982 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
3984 self.vapi.nat_ha_set_listener(self.pg3.local_ip4, port=12345)
3985 bind_layers(UDP, HANATStateSync, sport=12345)
3987 self.tcp_port_out = random.randint(1025, 65535)
3988 self.udp_port_out = random.randint(1025, 65535)
3990 # send HA session add events to failover/passive
3991 p = (Ether(dst=self.pg3.local_mac, src=self.pg3.remote_mac) /
3992 IP(src=self.pg3.remote_ip4, dst=self.pg3.local_ip4) /
3993 UDP(sport=12346, dport=12345) /
3994 HANATStateSync(sequence_number=1, events=[
3995 Event(event_type='add', protocol='tcp',
3996 in_addr=self.pg0.remote_ip4, out_addr=self.nat_addr,
3997 in_port=self.tcp_port_in, out_port=self.tcp_port_out,
3998 eh_addr=self.pg1.remote_ip4,
3999 ehn_addr=self.pg1.remote_ip4,
4000 eh_port=self.tcp_external_port,
4001 ehn_port=self.tcp_external_port, fib_index=0),
4002 Event(event_type='add', protocol='udp',
4003 in_addr=self.pg0.remote_ip4, out_addr=self.nat_addr,
4004 in_port=self.udp_port_in, out_port=self.udp_port_out,
4005 eh_addr=self.pg1.remote_ip4,
4006 ehn_addr=self.pg1.remote_ip4,
4007 eh_port=self.udp_external_port,
4008 ehn_port=self.udp_external_port, fib_index=0)]))
4010 self.pg3.add_stream(p)
4011 self.pg_enable_capture(self.pg_interfaces)
4014 capture = self.pg3.get_capture(1)
4017 hanat = p[HANATStateSync]
4019 self.logger.error(ppp("Invalid packet:", p))
4022 self.assertEqual(hanat.sequence_number, 1)
4023 self.assertEqual(hanat.flags, 'ACK')
4024 self.assertEqual(hanat.version, 1)
4025 self.assertEqual(hanat.thread_index, 0)
4026 stats = self.statistics.get_counter('/nat44/ha/ack-send')
4027 self.assertEqual(stats[0][0], 1)
4028 stats = self.statistics.get_counter('/nat44/ha/add-event-recv')
4029 self.assertEqual(stats[0][0], 2)
4030 users = self.statistics.get_counter('/nat44/total-users')
4031 self.assertEqual(users[0][0], 1)
4032 sessions = self.statistics.get_counter('/nat44/total-sessions')
4033 self.assertEqual(sessions[0][0], 2)
4034 users = self.vapi.nat44_user_dump()
4035 self.assertEqual(len(users), 1)
4036 self.assertEqual(users[0].ip_address, self.pg0.remote_ip4n)
4037 # there should be 2 sessions created by HA
4038 sessions = self.vapi.nat44_user_session_dump(users[0].ip_address,
4040 self.assertEqual(len(sessions), 2)
4041 for session in sessions:
4042 self.assertEqual(session.inside_ip_address, self.pg0.remote_ip4n)
4043 self.assertEqual(session.outside_ip_address, self.nat_addr_n)
4044 self.assertIn(session.inside_port,
4045 [self.tcp_port_in, self.udp_port_in])
4046 self.assertIn(session.outside_port,
4047 [self.tcp_port_out, self.udp_port_out])
4048 self.assertIn(session.protocol, [IP_PROTOS.tcp, IP_PROTOS.udp])
4050 # send HA session delete event to failover/passive
4051 p = (Ether(dst=self.pg3.local_mac, src=self.pg3.remote_mac) /
4052 IP(src=self.pg3.remote_ip4, dst=self.pg3.local_ip4) /
4053 UDP(sport=12346, dport=12345) /
4054 HANATStateSync(sequence_number=2, events=[
4055 Event(event_type='del', protocol='udp',
4056 in_addr=self.pg0.remote_ip4, out_addr=self.nat_addr,
4057 in_port=self.udp_port_in, out_port=self.udp_port_out,
4058 eh_addr=self.pg1.remote_ip4,
4059 ehn_addr=self.pg1.remote_ip4,
4060 eh_port=self.udp_external_port,
4061 ehn_port=self.udp_external_port, fib_index=0)]))
4063 self.pg3.add_stream(p)
4064 self.pg_enable_capture(self.pg_interfaces)
4067 capture = self.pg3.get_capture(1)
4070 hanat = p[HANATStateSync]
4072 self.logger.error(ppp("Invalid packet:", p))
4075 self.assertEqual(hanat.sequence_number, 2)
4076 self.assertEqual(hanat.flags, 'ACK')
4077 self.assertEqual(hanat.version, 1)
4078 users = self.vapi.nat44_user_dump()
4079 self.assertEqual(len(users), 1)
4080 self.assertEqual(users[0].ip_address, self.pg0.remote_ip4n)
4081 # now we should have only 1 session, 1 deleted by HA
4082 sessions = self.vapi.nat44_user_session_dump(users[0].ip_address,
4084 self.assertEqual(len(sessions), 1)
4085 stats = self.statistics.get_counter('/nat44/ha/del-event-recv')
4086 self.assertEqual(stats[0][0], 1)
4088 stats = self.statistics.get_counter('/err/nat-ha/pkts-processed')
4089 self.assertEqual(stats, 2)
4091 # send HA session refresh event to failover/passive
4092 p = (Ether(dst=self.pg3.local_mac, src=self.pg3.remote_mac) /
4093 IP(src=self.pg3.remote_ip4, dst=self.pg3.local_ip4) /
4094 UDP(sport=12346, dport=12345) /
4095 HANATStateSync(sequence_number=3, events=[
4096 Event(event_type='refresh', protocol='tcp',
4097 in_addr=self.pg0.remote_ip4, out_addr=self.nat_addr,
4098 in_port=self.tcp_port_in, out_port=self.tcp_port_out,
4099 eh_addr=self.pg1.remote_ip4,
4100 ehn_addr=self.pg1.remote_ip4,
4101 eh_port=self.tcp_external_port,
4102 ehn_port=self.tcp_external_port, fib_index=0,
4103 total_bytes=1024, total_pkts=2)]))
4104 self.pg3.add_stream(p)
4105 self.pg_enable_capture(self.pg_interfaces)
4108 capture = self.pg3.get_capture(1)
4111 hanat = p[HANATStateSync]
4113 self.logger.error(ppp("Invalid packet:", p))
4116 self.assertEqual(hanat.sequence_number, 3)
4117 self.assertEqual(hanat.flags, 'ACK')
4118 self.assertEqual(hanat.version, 1)
4119 users = self.vapi.nat44_user_dump()
4120 self.assertEqual(len(users), 1)
4121 self.assertEqual(users[0].ip_address, self.pg0.remote_ip4n)
4122 sessions = self.vapi.nat44_user_session_dump(users[0].ip_address,
4124 self.assertEqual(len(sessions), 1)
4125 session = sessions[0]
4126 self.assertEqual(session.total_bytes, 1024)
4127 self.assertEqual(session.total_pkts, 2)
4128 stats = self.statistics.get_counter('/nat44/ha/refresh-event-recv')
4129 self.assertEqual(stats[0][0], 1)
4131 stats = self.statistics.get_counter('/err/nat-ha/pkts-processed')
4132 self.assertEqual(stats, 3)
4134 # send packet to test session created by HA
4135 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
4136 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
4137 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out))
4138 self.pg1.add_stream(p)
4139 self.pg_enable_capture(self.pg_interfaces)
4141 capture = self.pg0.get_capture(1)
4147 self.logger.error(ppp("Invalid packet:", p))
4150 self.assertEqual(ip.src, self.pg1.remote_ip4)
4151 self.assertEqual(ip.dst, self.pg0.remote_ip4)
4152 self.assertEqual(tcp.sport, self.tcp_external_port)
4153 self.assertEqual(tcp.dport, self.tcp_port_in)
4156 super(TestNAT44, self).tearDown()
4157 if not self.vpp_dead:
4158 self.logger.info(self.vapi.cli("show nat44 addresses"))
4159 self.logger.info(self.vapi.cli("show nat44 interfaces"))
4160 self.logger.info(self.vapi.cli("show nat44 static mappings"))
4161 self.logger.info(self.vapi.cli("show nat44 interface address"))
4162 self.logger.info(self.vapi.cli("show nat44 sessions detail"))
4163 self.logger.info(self.vapi.cli("show nat virtual-reassembly"))
4164 self.logger.info(self.vapi.cli("show nat44 hash tables detail"))
4165 self.logger.info(self.vapi.cli("show nat timeouts"))
4167 self.vapi.cli("show nat addr-port-assignment-alg"))
4168 self.logger.info(self.vapi.cli("show nat ha"))
4170 self.vapi.cli("clear logging")
4173 class TestNAT44EndpointDependent(MethodHolder):
4174 """ Endpoint-Dependent mapping and filtering test cases """
4177 def setUpConstants(cls):
4178 super(TestNAT44EndpointDependent, cls).setUpConstants()
4179 cls.vpp_cmdline.extend(["nat", "{", "endpoint-dependent", "}"])
4182 def setUpClass(cls):
4183 super(TestNAT44EndpointDependent, cls).setUpClass()
4184 cls.vapi.cli("set log class nat level debug")
4186 cls.tcp_port_in = 6303
4187 cls.tcp_port_out = 6303
4188 cls.udp_port_in = 6304
4189 cls.udp_port_out = 6304
4190 cls.icmp_id_in = 6305
4191 cls.icmp_id_out = 6305
4192 cls.nat_addr = '10.0.0.3'
4193 cls.nat_addr_n = socket.inet_pton(socket.AF_INET, cls.nat_addr)
4194 cls.ipfix_src_port = 4739
4195 cls.ipfix_domain_id = 1
4196 cls.tcp_external_port = 80
4198 cls.create_pg_interfaces(range(7))
4199 cls.interfaces = list(cls.pg_interfaces[0:3])
4201 for i in cls.interfaces:
4206 cls.pg0.generate_remote_hosts(3)
4207 cls.pg0.configure_ipv4_neighbors()
4211 cls.pg4.generate_remote_hosts(2)
4212 cls.pg4.config_ip4()
4213 ip_addr_n = socket.inet_pton(socket.AF_INET, "10.0.0.1")
4214 cls.vapi.sw_interface_add_del_address(
4215 sw_if_index=cls.pg4.sw_if_index, address=ip_addr_n,
4218 cls.pg4.resolve_arp()
4219 cls.pg4._remote_hosts[1]._ip4 = cls.pg4._remote_hosts[0]._ip4
4220 cls.pg4.resolve_arp()
4222 zero_ip4n = socket.inet_pton(socket.AF_INET, "0.0.0.0")
4223 cls.vapi.ip_table_add_del(is_add=1, table_id=1)
4225 cls.pg5._local_ip4 = "10.1.1.1"
4226 cls.pg5._local_ip4n = socket.inet_pton(socket.AF_INET,
4228 cls.pg5._remote_hosts[0]._ip4 = "10.1.1.2"
4229 cls.pg5._remote_hosts[0]._ip4n = socket.inet_pton(
4230 socket.AF_INET, cls.pg5.remote_ip4)
4231 cls.pg5.set_table_ip4(1)
4232 cls.pg5.config_ip4()
4234 cls.vapi.ip_add_del_route(dst_address=cls.pg5.remote_ip4n,
4235 dst_address_length=32,
4237 next_hop_sw_if_index=cls.pg5.sw_if_index,
4238 next_hop_address=zero_ip4n)
4240 cls.pg6._local_ip4 = "10.1.2.1"
4241 cls.pg6._local_ip4n = socket.inet_pton(socket.AF_INET,
4243 cls.pg6._remote_hosts[0]._ip4 = "10.1.2.2"
4244 cls.pg6._remote_hosts[0]._ip4n = socket.inet_pton(
4245 socket.AF_INET, cls.pg6.remote_ip4)
4246 cls.pg6.set_table_ip4(1)
4247 cls.pg6.config_ip4()
4249 cls.vapi.ip_add_del_route(dst_address=cls.pg6.remote_ip4n,
4250 dst_address_length=32,
4252 next_hop_sw_if_index=cls.pg6.sw_if_index,
4253 next_hop_address=zero_ip4n)
4255 cls.vapi.ip_add_del_route(dst_address=cls.pg6.remote_ip4n,
4256 dst_address_length=16,
4257 next_hop_address=zero_ip4n,
4259 next_hop_table_id=1)
4260 cls.vapi.ip_add_del_route(dst_address=zero_ip4n,
4261 dst_address_length=0,
4262 next_hop_address=zero_ip4n,
4264 next_hop_table_id=0)
4265 cls.vapi.ip_add_del_route(dst_address=zero_ip4n,
4266 dst_address_length=0,
4268 next_hop_sw_if_index=cls.pg1.sw_if_index,
4269 next_hop_address=cls.pg1.local_ip4n)
4271 cls.pg5.resolve_arp()
4272 cls.pg6.resolve_arp()
4275 super(TestNAT44EndpointDependent, cls).tearDownClass()
4278 def test_frag_in_order(self):
4279 """ NAT44 translate fragments arriving in order """
4280 self.nat44_add_address(self.nat_addr)
4281 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
4282 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
4284 self.frag_in_order(proto=IP_PROTOS.tcp)
4285 self.frag_in_order(proto=IP_PROTOS.udp)
4286 self.frag_in_order(proto=IP_PROTOS.icmp)
4288 def test_frag_in_order_dont_translate(self):
4289 """ NAT44 don't translate fragments arriving in order """
4290 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
4291 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
4293 self.vapi.nat44_forwarding_enable_disable(enable=True)
4294 self.frag_in_order(proto=IP_PROTOS.tcp, dont_translate=True)
4296 def test_frag_out_of_order(self):
4297 """ NAT44 translate fragments arriving out of order """
4298 self.nat44_add_address(self.nat_addr)
4299 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
4300 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
4302 self.frag_out_of_order(proto=IP_PROTOS.tcp)
4303 self.frag_out_of_order(proto=IP_PROTOS.udp)
4304 self.frag_out_of_order(proto=IP_PROTOS.icmp)
4306 def test_frag_out_of_order_dont_translate(self):
4307 """ NAT44 don't translate fragments arriving out of order """
4308 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
4309 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
4311 self.vapi.nat44_forwarding_enable_disable(enable=True)
4312 self.frag_out_of_order(proto=IP_PROTOS.tcp, dont_translate=True)
4314 def test_frag_in_order_in_plus_out(self):
4315 """ in+out interface fragments in order """
4316 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
4317 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index,
4319 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index)
4320 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
4323 self.server = self.pg1.remote_hosts[0]
4325 self.server_in_addr = self.server.ip4
4326 self.server_out_addr = '11.11.11.11'
4327 self.server_in_port = random.randint(1025, 65535)
4328 self.server_out_port = random.randint(1025, 65535)
4330 self.nat44_add_address(self.server_out_addr)
4332 # add static mappings for server
4333 self.nat44_add_static_mapping(self.server_in_addr,
4334 self.server_out_addr,
4335 self.server_in_port,
4336 self.server_out_port,
4337 proto=IP_PROTOS.tcp)
4338 self.nat44_add_static_mapping(self.server_in_addr,
4339 self.server_out_addr,
4340 self.server_in_port,
4341 self.server_out_port,
4342 proto=IP_PROTOS.udp)
4343 self.nat44_add_static_mapping(self.server_in_addr,
4344 self.server_out_addr,
4345 proto=IP_PROTOS.icmp)
4347 self.vapi.nat_set_reass(timeout=10)
4349 self.frag_in_order_in_plus_out(proto=IP_PROTOS.tcp)
4350 self.frag_in_order_in_plus_out(proto=IP_PROTOS.udp)
4351 self.frag_in_order_in_plus_out(proto=IP_PROTOS.icmp)
4353 def test_frag_out_of_order_in_plus_out(self):
4354 """ in+out interface fragments out of order """
4355 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
4356 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index,
4358 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index)
4359 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
4362 self.server = self.pg1.remote_hosts[0]
4364 self.server_in_addr = self.server.ip4
4365 self.server_out_addr = '11.11.11.11'
4366 self.server_in_port = random.randint(1025, 65535)
4367 self.server_out_port = random.randint(1025, 65535)
4369 self.nat44_add_address(self.server_out_addr)
4371 # add static mappings for server
4372 self.nat44_add_static_mapping(self.server_in_addr,
4373 self.server_out_addr,
4374 self.server_in_port,
4375 self.server_out_port,
4376 proto=IP_PROTOS.tcp)
4377 self.nat44_add_static_mapping(self.server_in_addr,
4378 self.server_out_addr,
4379 self.server_in_port,
4380 self.server_out_port,
4381 proto=IP_PROTOS.udp)
4382 self.nat44_add_static_mapping(self.server_in_addr,
4383 self.server_out_addr,
4384 proto=IP_PROTOS.icmp)
4386 self.vapi.nat_set_reass(timeout=10)
4388 self.frag_out_of_order_in_plus_out(proto=IP_PROTOS.tcp)
4389 self.frag_out_of_order_in_plus_out(proto=IP_PROTOS.udp)
4390 self.frag_out_of_order_in_plus_out(proto=IP_PROTOS.icmp)
4392 def test_reass_hairpinning(self):
4393 """ NAT44 fragments hairpinning """
4394 self.server = self.pg0.remote_hosts[1]
4395 self.host_in_port = random.randint(1025, 65535)
4396 self.server_in_port = random.randint(1025, 65535)
4397 self.server_out_port = random.randint(1025, 65535)
4399 self.nat44_add_address(self.nat_addr)
4400 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
4401 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
4403 # add static mapping for server
4404 self.nat44_add_static_mapping(self.server.ip4, self.nat_addr,
4405 self.server_in_port,
4406 self.server_out_port,
4407 proto=IP_PROTOS.tcp)
4408 self.nat44_add_static_mapping(self.server.ip4, self.nat_addr,
4409 self.server_in_port,
4410 self.server_out_port,
4411 proto=IP_PROTOS.udp)
4412 self.nat44_add_static_mapping(self.server.ip4, self.nat_addr)
4414 self.reass_hairpinning(proto=IP_PROTOS.tcp)
4415 self.reass_hairpinning(proto=IP_PROTOS.udp)
4416 self.reass_hairpinning(proto=IP_PROTOS.icmp)
4418 def test_dynamic(self):
4419 """ NAT44 dynamic translation test """
4421 self.nat44_add_address(self.nat_addr)
4422 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
4423 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
4426 nat_config = self.vapi.nat_show_config()
4427 self.assertEqual(1, nat_config.endpoint_dependent)
4430 tcpn = self.statistics.get_counter(
4431 '/err/nat44-ed-in2out-slowpath/TCP packets')
4432 udpn = self.statistics.get_counter(
4433 '/err/nat44-ed-in2out-slowpath/UDP packets')
4434 icmpn = self.statistics.get_counter(
4435 '/err/nat44-ed-in2out-slowpath/ICMP packets')
4436 totaln = self.statistics.get_counter(
4437 '/err/nat44-ed-in2out-slowpath/good in2out packets processed')
4439 pkts = self.create_stream_in(self.pg0, self.pg1)
4440 self.pg0.add_stream(pkts)
4441 self.pg_enable_capture(self.pg_interfaces)
4443 capture = self.pg1.get_capture(len(pkts))
4444 self.verify_capture_out(capture)
4446 err = self.statistics.get_counter(
4447 '/err/nat44-ed-in2out-slowpath/TCP packets')
4448 self.assertEqual(err - tcpn, 1)
4449 err = self.statistics.get_counter(
4450 '/err/nat44-ed-in2out-slowpath/UDP packets')
4451 self.assertEqual(err - udpn, 1)
4452 err = self.statistics.get_counter(
4453 '/err/nat44-ed-in2out-slowpath/ICMP packets')
4454 self.assertEqual(err - icmpn, 1)
4455 err = self.statistics.get_counter(
4456 '/err/nat44-ed-in2out-slowpath/good in2out packets processed')
4457 self.assertEqual(err - totaln, 3)
4460 tcpn = self.statistics.get_counter('/err/nat44-ed-out2in/TCP packets')
4461 udpn = self.statistics.get_counter('/err/nat44-ed-out2in/UDP packets')
4462 icmpn = self.statistics.get_counter(
4463 '/err/nat44-ed-out2in-slowpath/ICMP packets')
4464 totaln = self.statistics.get_counter(
4465 '/err/nat44-ed-out2in/good out2in packets processed')
4467 pkts = self.create_stream_out(self.pg1)
4468 self.pg1.add_stream(pkts)
4469 self.pg_enable_capture(self.pg_interfaces)
4471 capture = self.pg0.get_capture(len(pkts))
4472 self.verify_capture_in(capture, self.pg0)
4474 err = self.statistics.get_counter('/err/nat44-ed-out2in/TCP packets')
4475 self.assertEqual(err - tcpn, 1)
4476 err = self.statistics.get_counter('/err/nat44-ed-out2in/UDP packets')
4477 self.assertEqual(err - udpn, 1)
4478 err = self.statistics.get_counter(
4479 '/err/nat44-ed-out2in-slowpath/ICMP packets')
4480 self.assertEqual(err - icmpn, 1)
4481 err = self.statistics.get_counter(
4482 '/err/nat44-ed-out2in/good out2in packets processed')
4483 self.assertEqual(err - totaln, 2)
4485 users = self.statistics.get_counter('/nat44/total-users')
4486 self.assertEqual(users[0][0], 1)
4487 sessions = self.statistics.get_counter('/nat44/total-sessions')
4488 self.assertEqual(sessions[0][0], 3)
4490 def test_forwarding(self):
4491 """ NAT44 forwarding test """
4493 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
4494 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
4496 self.vapi.nat44_forwarding_enable_disable(1)
4498 real_ip = self.pg0.remote_ip4n
4499 alias_ip = self.nat_addr_n
4500 self.vapi.nat44_add_del_static_mapping(local_ip=real_ip,
4501 external_ip=alias_ip)
4504 # in2out - static mapping match
4506 pkts = self.create_stream_out(self.pg1)
4507 self.pg1.add_stream(pkts)
4508 self.pg_enable_capture(self.pg_interfaces)
4510 capture = self.pg0.get_capture(len(pkts))
4511 self.verify_capture_in(capture, self.pg0)
4513 pkts = self.create_stream_in(self.pg0, self.pg1)
4514 self.pg0.add_stream(pkts)
4515 self.pg_enable_capture(self.pg_interfaces)
4517 capture = self.pg1.get_capture(len(pkts))
4518 self.verify_capture_out(capture, same_port=True)
4520 # in2out - no static mapping match
4522 host0 = self.pg0.remote_hosts[0]
4523 self.pg0.remote_hosts[0] = self.pg0.remote_hosts[1]
4525 pkts = self.create_stream_out(self.pg1,
4526 dst_ip=self.pg0.remote_ip4,
4527 use_inside_ports=True)
4528 self.pg1.add_stream(pkts)
4529 self.pg_enable_capture(self.pg_interfaces)
4531 capture = self.pg0.get_capture(len(pkts))
4532 self.verify_capture_in(capture, self.pg0)
4534 pkts = self.create_stream_in(self.pg0, self.pg1)
4535 self.pg0.add_stream(pkts)
4536 self.pg_enable_capture(self.pg_interfaces)
4538 capture = self.pg1.get_capture(len(pkts))
4539 self.verify_capture_out(capture, nat_ip=self.pg0.remote_ip4,
4542 self.pg0.remote_hosts[0] = host0
4544 user = self.pg0.remote_hosts[1]
4545 sessions = self.vapi.nat44_user_session_dump(user.ip4n, 0)
4546 self.assertEqual(len(sessions), 3)
4547 self.assertTrue(sessions[0].ext_host_valid)
4548 self.vapi.nat44_del_session(
4549 sessions[0].inside_ip_address,
4550 sessions[0].inside_port,
4551 sessions[0].protocol,
4552 ext_host_address=sessions[0].ext_host_address,
4553 ext_host_port=sessions[0].ext_host_port)
4554 sessions = self.vapi.nat44_user_session_dump(user.ip4n, 0)
4555 self.assertEqual(len(sessions), 2)
4558 self.vapi.nat44_forwarding_enable_disable(0)
4559 self.vapi.nat44_add_del_static_mapping(local_ip=real_ip,
4560 external_ip=alias_ip,
4563 def test_static_lb(self):
4564 """ NAT44 local service load balancing """
4565 external_addr_n = socket.inet_pton(socket.AF_INET, self.nat_addr)
4568 server1 = self.pg0.remote_hosts[0]
4569 server2 = self.pg0.remote_hosts[1]
4571 locals = [{'addr': server1.ip4n,
4575 {'addr': server2.ip4n,
4580 self.nat44_add_address(self.nat_addr)
4581 self.vapi.nat44_add_del_lb_static_mapping(external_addr_n,
4584 local_num=len(locals),
4586 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
4587 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
4590 # from client to service
4591 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
4592 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
4593 TCP(sport=12345, dport=external_port))
4594 self.pg1.add_stream(p)
4595 self.pg_enable_capture(self.pg_interfaces)
4597 capture = self.pg0.get_capture(1)
4603 self.assertIn(ip.dst, [server1.ip4, server2.ip4])
4604 if ip.dst == server1.ip4:
4608 self.assertEqual(tcp.dport, local_port)
4609 self.assert_packet_checksums_valid(p)
4611 self.logger.error(ppp("Unexpected or invalid packet:", p))
4614 # from service back to client
4615 p = (Ether(src=server.mac, dst=self.pg0.local_mac) /
4616 IP(src=server.ip4, dst=self.pg1.remote_ip4) /
4617 TCP(sport=local_port, dport=12345))
4618 self.pg0.add_stream(p)
4619 self.pg_enable_capture(self.pg_interfaces)
4621 capture = self.pg1.get_capture(1)
4626 self.assertEqual(ip.src, self.nat_addr)
4627 self.assertEqual(tcp.sport, external_port)
4628 self.assert_packet_checksums_valid(p)
4630 self.logger.error(ppp("Unexpected or invalid packet:", p))
4633 sessions = self.vapi.nat44_user_session_dump(server.ip4n, 0)
4634 self.assertEqual(len(sessions), 1)
4635 self.assertTrue(sessions[0].ext_host_valid)
4636 self.vapi.nat44_del_session(
4637 sessions[0].inside_ip_address,
4638 sessions[0].inside_port,
4639 sessions[0].protocol,
4640 ext_host_address=sessions[0].ext_host_address,
4641 ext_host_port=sessions[0].ext_host_port)
4642 sessions = self.vapi.nat44_user_session_dump(server.ip4n, 0)
4643 self.assertEqual(len(sessions), 0)
4645 @unittest.skipUnless(running_extended_tests, "part of extended tests")
4646 def test_static_lb_multi_clients(self):
4647 """ NAT44 local service load balancing - multiple clients"""
4649 external_addr_n = socket.inet_pton(socket.AF_INET, self.nat_addr)
4652 server1 = self.pg0.remote_hosts[0]
4653 server2 = self.pg0.remote_hosts[1]
4654 server3 = self.pg0.remote_hosts[2]
4656 locals = [{'addr': server1.ip4n,
4660 {'addr': server2.ip4n,
4665 self.nat44_add_address(self.nat_addr)
4666 self.vapi.nat44_add_del_lb_static_mapping(external_addr_n,
4669 local_num=len(locals),
4671 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
4672 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
4677 clients = ip4_range(self.pg1.remote_ip4, 10, 50)
4679 for client in clients:
4680 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
4681 IP(src=client, dst=self.nat_addr) /
4682 TCP(sport=12345, dport=external_port))
4684 self.pg1.add_stream(pkts)
4685 self.pg_enable_capture(self.pg_interfaces)
4687 capture = self.pg0.get_capture(len(pkts))
4689 if p[IP].dst == server1.ip4:
4693 self.assertGreater(server1_n, server2_n)
4696 self.vapi.nat44_lb_static_mapping_add_del_local(external_addr_n,
4705 clients = ip4_range(self.pg1.remote_ip4, 60, 110)
4707 for client in clients:
4708 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
4709 IP(src=client, dst=self.nat_addr) /
4710 TCP(sport=12346, dport=external_port))
4712 self.assertGreater(len(pkts), 0)
4713 self.pg1.add_stream(pkts)
4714 self.pg_enable_capture(self.pg_interfaces)
4716 capture = self.pg0.get_capture(len(pkts))
4718 if p[IP].dst == server1.ip4:
4720 elif p[IP].dst == server2.ip4:
4724 self.assertGreater(server1_n, 0)
4725 self.assertGreater(server2_n, 0)
4726 self.assertGreater(server3_n, 0)
4728 # remove one back-end
4729 self.vapi.nat44_lb_static_mapping_add_del_local(external_addr_n,
4739 self.pg1.add_stream(pkts)
4740 self.pg_enable_capture(self.pg_interfaces)
4742 capture = self.pg0.get_capture(len(pkts))
4744 if p[IP].dst == server1.ip4:
4746 elif p[IP].dst == server2.ip4:
4750 self.assertGreater(server1_n, 0)
4751 self.assertEqual(server2_n, 0)
4752 self.assertGreater(server3_n, 0)
4754 def test_static_lb_2(self):
4755 """ NAT44 local service load balancing (asymmetrical rule) """
4756 external_addr_n = socket.inet_pton(socket.AF_INET, self.nat_addr)
4759 server1 = self.pg0.remote_hosts[0]
4760 server2 = self.pg0.remote_hosts[1]
4762 locals = [{'addr': server1.ip4n,
4766 {'addr': server2.ip4n,
4771 self.vapi.nat44_forwarding_enable_disable(1)
4772 self.vapi.nat44_add_del_lb_static_mapping(external_addr_n,
4776 local_num=len(locals),
4778 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
4779 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
4782 # from client to service
4783 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
4784 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
4785 TCP(sport=12345, dport=external_port))
4786 self.pg1.add_stream(p)
4787 self.pg_enable_capture(self.pg_interfaces)
4789 capture = self.pg0.get_capture(1)
4795 self.assertIn(ip.dst, [server1.ip4, server2.ip4])
4796 if ip.dst == server1.ip4:
4800 self.assertEqual(tcp.dport, local_port)
4801 self.assert_packet_checksums_valid(p)
4803 self.logger.error(ppp("Unexpected or invalid packet:", p))
4806 # from service back to client
4807 p = (Ether(src=server.mac, dst=self.pg0.local_mac) /
4808 IP(src=server.ip4, dst=self.pg1.remote_ip4) /
4809 TCP(sport=local_port, dport=12345))
4810 self.pg0.add_stream(p)
4811 self.pg_enable_capture(self.pg_interfaces)
4813 capture = self.pg1.get_capture(1)
4818 self.assertEqual(ip.src, self.nat_addr)
4819 self.assertEqual(tcp.sport, external_port)
4820 self.assert_packet_checksums_valid(p)
4822 self.logger.error(ppp("Unexpected or invalid packet:", p))
4825 # from client to server (no translation)
4826 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
4827 IP(src=self.pg1.remote_ip4, dst=server1.ip4) /
4828 TCP(sport=12346, dport=local_port))
4829 self.pg1.add_stream(p)
4830 self.pg_enable_capture(self.pg_interfaces)
4832 capture = self.pg0.get_capture(1)
4838 self.assertEqual(ip.dst, server1.ip4)
4839 self.assertEqual(tcp.dport, local_port)
4840 self.assert_packet_checksums_valid(p)
4842 self.logger.error(ppp("Unexpected or invalid packet:", p))
4845 # from service back to client (no translation)
4846 p = (Ether(src=server1.mac, dst=self.pg0.local_mac) /
4847 IP(src=server1.ip4, dst=self.pg1.remote_ip4) /
4848 TCP(sport=local_port, dport=12346))
4849 self.pg0.add_stream(p)
4850 self.pg_enable_capture(self.pg_interfaces)
4852 capture = self.pg1.get_capture(1)
4857 self.assertEqual(ip.src, server1.ip4)
4858 self.assertEqual(tcp.sport, local_port)
4859 self.assert_packet_checksums_valid(p)
4861 self.logger.error(ppp("Unexpected or invalid packet:", p))
4864 def test_lb_affinity(self):
4865 """ NAT44 local service load balancing affinity """
4866 external_addr_n = socket.inet_pton(socket.AF_INET, self.nat_addr)
4869 server1 = self.pg0.remote_hosts[0]
4870 server2 = self.pg0.remote_hosts[1]
4872 locals = [{'addr': server1.ip4n,
4876 {'addr': server2.ip4n,
4881 self.nat44_add_address(self.nat_addr)
4882 self.vapi.nat44_add_del_lb_static_mapping(external_addr_n,
4886 local_num=len(locals),
4888 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
4889 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
4892 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
4893 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
4894 TCP(sport=1025, dport=external_port))
4895 self.pg1.add_stream(p)
4896 self.pg_enable_capture(self.pg_interfaces)
4898 capture = self.pg0.get_capture(1)
4899 backend = capture[0][IP].dst
4901 sessions = self.vapi.nat44_user_session_dump(
4902 socket.inet_pton(socket.AF_INET, backend), 0)
4903 self.assertEqual(len(sessions), 1)
4904 self.assertTrue(sessions[0].ext_host_valid)
4905 self.vapi.nat44_del_session(
4906 sessions[0].inside_ip_address,
4907 sessions[0].inside_port,
4908 sessions[0].protocol,
4909 ext_host_address=sessions[0].ext_host_address,
4910 ext_host_port=sessions[0].ext_host_port)
4913 for port in range(1030, 1100):
4914 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
4915 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
4916 TCP(sport=port, dport=external_port))
4918 self.pg1.add_stream(pkts)
4919 self.pg_enable_capture(self.pg_interfaces)
4921 capture = self.pg0.get_capture(len(pkts))
4923 self.assertEqual(p[IP].dst, backend)
4925 def test_unknown_proto(self):
4926 """ NAT44 translate packet with unknown protocol """
4927 self.nat44_add_address(self.nat_addr)
4928 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
4929 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
4933 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
4934 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
4935 TCP(sport=self.tcp_port_in, dport=20))
4936 self.pg0.add_stream(p)
4937 self.pg_enable_capture(self.pg_interfaces)
4939 p = self.pg1.get_capture(1)
4941 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
4942 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
4944 IP(src=self.pg2.remote_ip4, dst=self.pg2.remote_ip4) /
4945 TCP(sport=1234, dport=1234))
4946 self.pg0.add_stream(p)
4947 self.pg_enable_capture(self.pg_interfaces)
4949 p = self.pg1.get_capture(1)
4952 self.assertEqual(packet[IP].src, self.nat_addr)
4953 self.assertEqual(packet[IP].dst, self.pg1.remote_ip4)
4954 self.assertEqual(packet.haslayer(GRE), 1)
4955 self.assert_packet_checksums_valid(packet)
4957 self.logger.error(ppp("Unexpected or invalid packet:", packet))
4961 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
4962 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
4964 IP(src=self.pg2.remote_ip4, dst=self.pg2.remote_ip4) /
4965 TCP(sport=1234, dport=1234))
4966 self.pg1.add_stream(p)
4967 self.pg_enable_capture(self.pg_interfaces)
4969 p = self.pg0.get_capture(1)
4972 self.assertEqual(packet[IP].src, self.pg1.remote_ip4)
4973 self.assertEqual(packet[IP].dst, self.pg0.remote_ip4)
4974 self.assertEqual(packet.haslayer(GRE), 1)
4975 self.assert_packet_checksums_valid(packet)
4977 self.logger.error(ppp("Unexpected or invalid packet:", packet))
4980 def test_hairpinning_unknown_proto(self):
4981 """ NAT44 translate packet with unknown protocol - hairpinning """
4982 host = self.pg0.remote_hosts[0]
4983 server = self.pg0.remote_hosts[1]
4985 server_out_port = 8765
4986 server_nat_ip = "10.0.0.11"
4988 self.nat44_add_address(self.nat_addr)
4989 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
4990 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
4993 # add static mapping for server
4994 self.nat44_add_static_mapping(server.ip4, server_nat_ip)
4997 p = (Ether(src=host.mac, dst=self.pg0.local_mac) /
4998 IP(src=host.ip4, dst=server_nat_ip) /
4999 TCP(sport=host_in_port, dport=server_out_port))
5000 self.pg0.add_stream(p)
5001 self.pg_enable_capture(self.pg_interfaces)
5003 self.pg0.get_capture(1)
5005 p = (Ether(dst=self.pg0.local_mac, src=host.mac) /
5006 IP(src=host.ip4, dst=server_nat_ip) /
5008 IP(src=self.pg2.remote_ip4, dst=self.pg2.remote_ip4) /
5009 TCP(sport=1234, dport=1234))
5010 self.pg0.add_stream(p)
5011 self.pg_enable_capture(self.pg_interfaces)
5013 p = self.pg0.get_capture(1)
5016 self.assertEqual(packet[IP].src, self.nat_addr)
5017 self.assertEqual(packet[IP].dst, server.ip4)
5018 self.assertEqual(packet.haslayer(GRE), 1)
5019 self.assert_packet_checksums_valid(packet)
5021 self.logger.error(ppp("Unexpected or invalid packet:", packet))
5025 p = (Ether(dst=self.pg0.local_mac, src=server.mac) /
5026 IP(src=server.ip4, dst=self.nat_addr) /
5028 IP(src=self.pg2.remote_ip4, dst=self.pg2.remote_ip4) /
5029 TCP(sport=1234, dport=1234))
5030 self.pg0.add_stream(p)
5031 self.pg_enable_capture(self.pg_interfaces)
5033 p = self.pg0.get_capture(1)
5036 self.assertEqual(packet[IP].src, server_nat_ip)
5037 self.assertEqual(packet[IP].dst, host.ip4)
5038 self.assertEqual(packet.haslayer(GRE), 1)
5039 self.assert_packet_checksums_valid(packet)
5041 self.logger.error(ppp("Unexpected or invalid packet:", packet))
5044 def test_output_feature_and_service(self):
5045 """ NAT44 interface output feature and services """
5046 external_addr = '1.2.3.4'
5050 self.vapi.nat44_forwarding_enable_disable(1)
5051 self.nat44_add_address(self.nat_addr)
5052 self.vapi.nat44_add_del_identity_mapping(ip=self.pg1.remote_ip4n)
5053 self.nat44_add_static_mapping(self.pg0.remote_ip4, external_addr,
5054 local_port, external_port,
5055 proto=IP_PROTOS.tcp, out2in_only=1)
5056 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
5057 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index,
5059 self.vapi.nat44_interface_add_del_output_feature(self.pg1.sw_if_index,
5062 # from client to service
5063 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
5064 IP(src=self.pg1.remote_ip4, dst=external_addr) /
5065 TCP(sport=12345, dport=external_port))
5066 self.pg1.add_stream(p)
5067 self.pg_enable_capture(self.pg_interfaces)
5069 capture = self.pg0.get_capture(1)
5074 self.assertEqual(ip.dst, self.pg0.remote_ip4)
5075 self.assertEqual(tcp.dport, local_port)
5076 self.assert_packet_checksums_valid(p)
5078 self.logger.error(ppp("Unexpected or invalid packet:", p))
5081 # from service back to client
5082 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5083 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
5084 TCP(sport=local_port, dport=12345))
5085 self.pg0.add_stream(p)
5086 self.pg_enable_capture(self.pg_interfaces)
5088 capture = self.pg1.get_capture(1)
5093 self.assertEqual(ip.src, external_addr)
5094 self.assertEqual(tcp.sport, external_port)
5095 self.assert_packet_checksums_valid(p)
5097 self.logger.error(ppp("Unexpected or invalid packet:", p))
5100 # from local network host to external network
5101 pkts = self.create_stream_in(self.pg0, self.pg1)
5102 self.pg0.add_stream(pkts)
5103 self.pg_enable_capture(self.pg_interfaces)
5105 capture = self.pg1.get_capture(len(pkts))
5106 self.verify_capture_out(capture)
5107 pkts = self.create_stream_in(self.pg0, self.pg1)
5108 self.pg0.add_stream(pkts)
5109 self.pg_enable_capture(self.pg_interfaces)
5111 capture = self.pg1.get_capture(len(pkts))
5112 self.verify_capture_out(capture)
5114 # from external network back to local network host
5115 pkts = self.create_stream_out(self.pg1)
5116 self.pg1.add_stream(pkts)
5117 self.pg_enable_capture(self.pg_interfaces)
5119 capture = self.pg0.get_capture(len(pkts))
5120 self.verify_capture_in(capture, self.pg0)
5122 def test_output_feature_and_service2(self):
5123 """ NAT44 interface output feature and service host direct access """
5124 self.vapi.nat44_forwarding_enable_disable(1)
5125 self.nat44_add_address(self.nat_addr)
5126 self.vapi.nat44_interface_add_del_output_feature(self.pg1.sw_if_index,
5129 # session initiaded from service host - translate
5130 pkts = self.create_stream_in(self.pg0, self.pg1)
5131 self.pg0.add_stream(pkts)
5132 self.pg_enable_capture(self.pg_interfaces)
5134 capture = self.pg1.get_capture(len(pkts))
5135 self.verify_capture_out(capture)
5137 pkts = self.create_stream_out(self.pg1)
5138 self.pg1.add_stream(pkts)
5139 self.pg_enable_capture(self.pg_interfaces)
5141 capture = self.pg0.get_capture(len(pkts))
5142 self.verify_capture_in(capture, self.pg0)
5144 # session initiaded from remote host - do not translate
5145 self.tcp_port_in = 60303
5146 self.udp_port_in = 60304
5147 self.icmp_id_in = 60305
5148 pkts = self.create_stream_out(self.pg1,
5149 self.pg0.remote_ip4,
5150 use_inside_ports=True)
5151 self.pg1.add_stream(pkts)
5152 self.pg_enable_capture(self.pg_interfaces)
5154 capture = self.pg0.get_capture(len(pkts))
5155 self.verify_capture_in(capture, self.pg0)
5157 pkts = self.create_stream_in(self.pg0, self.pg1)
5158 self.pg0.add_stream(pkts)
5159 self.pg_enable_capture(self.pg_interfaces)
5161 capture = self.pg1.get_capture(len(pkts))
5162 self.verify_capture_out(capture, nat_ip=self.pg0.remote_ip4,
5165 def test_output_feature_and_service3(self):
5166 """ NAT44 interface output feature and DST NAT """
5167 external_addr = '1.2.3.4'
5171 self.vapi.nat44_forwarding_enable_disable(1)
5172 self.nat44_add_address(self.nat_addr)
5173 self.nat44_add_static_mapping(self.pg1.remote_ip4, external_addr,
5174 local_port, external_port,
5175 proto=IP_PROTOS.tcp, out2in_only=1)
5176 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
5177 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index,
5179 self.vapi.nat44_interface_add_del_output_feature(self.pg1.sw_if_index,
5182 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5183 IP(src=self.pg0.remote_ip4, dst=external_addr) /
5184 TCP(sport=12345, dport=external_port))
5185 self.pg0.add_stream(p)
5186 self.pg_enable_capture(self.pg_interfaces)
5188 capture = self.pg1.get_capture(1)
5193 self.assertEqual(ip.src, self.pg0.remote_ip4)
5194 self.assertEqual(tcp.sport, 12345)
5195 self.assertEqual(ip.dst, self.pg1.remote_ip4)
5196 self.assertEqual(tcp.dport, local_port)
5197 self.assert_packet_checksums_valid(p)
5199 self.logger.error(ppp("Unexpected or invalid packet:", p))
5202 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
5203 IP(src=self.pg1.remote_ip4, dst=self.pg0.remote_ip4) /
5204 TCP(sport=local_port, dport=12345))
5205 self.pg1.add_stream(p)
5206 self.pg_enable_capture(self.pg_interfaces)
5208 capture = self.pg0.get_capture(1)
5213 self.assertEqual(ip.src, external_addr)
5214 self.assertEqual(tcp.sport, external_port)
5215 self.assertEqual(ip.dst, self.pg0.remote_ip4)
5216 self.assertEqual(tcp.dport, 12345)
5217 self.assert_packet_checksums_valid(p)
5219 self.logger.error(ppp("Unexpected or invalid packet:", p))
5222 def test_next_src_nat(self):
5223 """ On way back forward packet to nat44-in2out node. """
5224 twice_nat_addr = '10.0.1.3'
5227 post_twice_nat_port = 0
5229 self.vapi.nat44_forwarding_enable_disable(1)
5230 self.nat44_add_address(twice_nat_addr, twice_nat=1)
5231 self.nat44_add_static_mapping(self.pg6.remote_ip4, self.pg1.remote_ip4,
5232 local_port, external_port,
5233 proto=IP_PROTOS.tcp, out2in_only=1,
5234 self_twice_nat=1, vrf_id=1)
5235 self.vapi.nat44_interface_add_del_feature(self.pg6.sw_if_index,
5238 p = (Ether(src=self.pg6.remote_mac, dst=self.pg6.local_mac) /
5239 IP(src=self.pg6.remote_ip4, dst=self.pg1.remote_ip4) /
5240 TCP(sport=12345, dport=external_port))
5241 self.pg6.add_stream(p)
5242 self.pg_enable_capture(self.pg_interfaces)
5244 capture = self.pg6.get_capture(1)
5249 self.assertEqual(ip.src, twice_nat_addr)
5250 self.assertNotEqual(tcp.sport, 12345)
5251 post_twice_nat_port = tcp.sport
5252 self.assertEqual(ip.dst, self.pg6.remote_ip4)
5253 self.assertEqual(tcp.dport, local_port)
5254 self.assert_packet_checksums_valid(p)
5256 self.logger.error(ppp("Unexpected or invalid packet:", p))
5259 p = (Ether(src=self.pg6.remote_mac, dst=self.pg6.local_mac) /
5260 IP(src=self.pg6.remote_ip4, dst=twice_nat_addr) /
5261 TCP(sport=local_port, dport=post_twice_nat_port))
5262 self.pg6.add_stream(p)
5263 self.pg_enable_capture(self.pg_interfaces)
5265 capture = self.pg6.get_capture(1)
5270 self.assertEqual(ip.src, self.pg1.remote_ip4)
5271 self.assertEqual(tcp.sport, external_port)
5272 self.assertEqual(ip.dst, self.pg6.remote_ip4)
5273 self.assertEqual(tcp.dport, 12345)
5274 self.assert_packet_checksums_valid(p)
5276 self.logger.error(ppp("Unexpected or invalid packet:", p))
5279 def twice_nat_common(self, self_twice_nat=False, same_pg=False, lb=False,
5281 twice_nat_addr = '10.0.1.3'
5289 port_in1 = port_in + 1
5290 port_in2 = port_in + 2
5295 server1 = self.pg0.remote_hosts[0]
5296 server2 = self.pg0.remote_hosts[1]
5308 eh_translate = ((not self_twice_nat) or (not lb and same_pg) or
5311 self.nat44_add_address(self.nat_addr)
5312 self.nat44_add_address(twice_nat_addr, twice_nat=1)
5314 self.nat44_add_static_mapping(pg0.remote_ip4, self.nat_addr,
5316 proto=IP_PROTOS.tcp,
5317 twice_nat=int(not self_twice_nat),
5318 self_twice_nat=int(self_twice_nat))
5320 locals = [{'addr': server1.ip4n,
5324 {'addr': server2.ip4n,
5328 out_addr_n = socket.inet_pton(socket.AF_INET, self.nat_addr)
5329 self.vapi.nat44_add_del_lb_static_mapping(out_addr_n,
5333 not self_twice_nat),
5336 local_num=len(locals),
5338 self.vapi.nat44_interface_add_del_feature(pg0.sw_if_index)
5339 self.vapi.nat44_interface_add_del_feature(pg1.sw_if_index,
5346 assert client_id is not None
5348 client = self.pg0.remote_hosts[0]
5349 elif client_id == 2:
5350 client = self.pg0.remote_hosts[1]
5352 client = pg1.remote_hosts[0]
5353 p = (Ether(src=pg1.remote_mac, dst=pg1.local_mac) /
5354 IP(src=client.ip4, dst=self.nat_addr) /
5355 TCP(sport=eh_port_out, dport=port_out))
5357 self.pg_enable_capture(self.pg_interfaces)
5359 capture = pg0.get_capture(1)
5365 if ip.dst == server1.ip4:
5371 self.assertEqual(ip.dst, server.ip4)
5373 self.assertIn(tcp.dport, [port_in1, port_in2])
5375 self.assertEqual(tcp.dport, port_in)
5377 self.assertEqual(ip.src, twice_nat_addr)
5378 self.assertNotEqual(tcp.sport, eh_port_out)
5380 self.assertEqual(ip.src, client.ip4)
5381 self.assertEqual(tcp.sport, eh_port_out)
5383 eh_port_in = tcp.sport
5384 saved_port_in = tcp.dport
5385 self.assert_packet_checksums_valid(p)
5387 self.logger.error(ppp("Unexpected or invalid packet:", p))
5390 p = (Ether(src=server.mac, dst=pg0.local_mac) /
5391 IP(src=server.ip4, dst=eh_addr_in) /
5392 TCP(sport=saved_port_in, dport=eh_port_in))
5394 self.pg_enable_capture(self.pg_interfaces)
5396 capture = pg1.get_capture(1)
5401 self.assertEqual(ip.dst, client.ip4)
5402 self.assertEqual(ip.src, self.nat_addr)
5403 self.assertEqual(tcp.dport, eh_port_out)
5404 self.assertEqual(tcp.sport, port_out)
5405 self.assert_packet_checksums_valid(p)
5407 self.logger.error(ppp("Unexpected or invalid packet:", p))
5411 sessions = self.vapi.nat44_user_session_dump(server.ip4n, 0)
5412 self.assertEqual(len(sessions), 1)
5413 self.assertTrue(sessions[0].ext_host_valid)
5414 self.assertTrue(sessions[0].is_twicenat)
5415 self.vapi.nat44_del_session(
5416 sessions[0].inside_ip_address,
5417 sessions[0].inside_port,
5418 sessions[0].protocol,
5419 ext_host_address=sessions[0].ext_host_nat_address,
5420 ext_host_port=sessions[0].ext_host_nat_port)
5421 sessions = self.vapi.nat44_user_session_dump(server.ip4n, 0)
5422 self.assertEqual(len(sessions), 0)
5424 def test_twice_nat(self):
5426 self.twice_nat_common()
5428 def test_self_twice_nat_positive(self):
5429 """ Self Twice NAT44 (positive test) """
5430 self.twice_nat_common(self_twice_nat=True, same_pg=True)
5432 def test_self_twice_nat_negative(self):
5433 """ Self Twice NAT44 (negative test) """
5434 self.twice_nat_common(self_twice_nat=True)
5436 def test_twice_nat_lb(self):
5437 """ Twice NAT44 local service load balancing """
5438 self.twice_nat_common(lb=True)
5440 def test_self_twice_nat_lb_positive(self):
5441 """ Self Twice NAT44 local service load balancing (positive test) """
5442 self.twice_nat_common(lb=True, self_twice_nat=True, same_pg=True,
5445 def test_self_twice_nat_lb_negative(self):
5446 """ Self Twice NAT44 local service load balancing (negative test) """
5447 self.twice_nat_common(lb=True, self_twice_nat=True, same_pg=True,
5450 def test_twice_nat_interface_addr(self):
5451 """ Acquire twice NAT44 addresses from interface """
5452 self.vapi.nat44_add_del_interface_addr(self.pg3.sw_if_index,
5455 # no address in NAT pool
5456 adresses = self.vapi.nat44_address_dump()
5457 self.assertEqual(0, len(adresses))
5459 # configure interface address and check NAT address pool
5460 self.pg3.config_ip4()
5461 adresses = self.vapi.nat44_address_dump()
5462 self.assertEqual(1, len(adresses))
5463 self.assertEqual(adresses[0].ip_address[0:4], self.pg3.local_ip4n)
5464 self.assertEqual(adresses[0].twice_nat, 1)
5466 # remove interface address and check NAT address pool
5467 self.pg3.unconfig_ip4()
5468 adresses = self.vapi.nat44_address_dump()
5469 self.assertEqual(0, len(adresses))
5471 def test_tcp_close(self):
5472 """ Close TCP session from inside network - output feature """
5473 self.vapi.nat44_forwarding_enable_disable(1)
5474 self.nat44_add_address(self.pg1.local_ip4)
5475 twice_nat_addr = '10.0.1.3'
5476 service_ip = '192.168.16.150'
5477 self.nat44_add_address(twice_nat_addr, twice_nat=1)
5478 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
5479 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index,
5481 self.vapi.nat44_interface_add_del_output_feature(self.pg1.sw_if_index,
5483 self.nat44_add_static_mapping(self.pg0.remote_ip4,
5487 proto=IP_PROTOS.tcp,
5490 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4n, 0)
5491 start_sessnum = len(sessions)
5493 # SYN packet out->in
5494 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
5495 IP(src=self.pg1.remote_ip4, dst=service_ip) /
5496 TCP(sport=33898, dport=80, flags="S"))
5497 self.pg1.add_stream(p)
5498 self.pg_enable_capture(self.pg_interfaces)
5500 capture = self.pg0.get_capture(1)
5502 tcp_port = p[TCP].sport
5504 # SYN + ACK packet in->out
5505 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5506 IP(src=self.pg0.remote_ip4, dst=twice_nat_addr) /
5507 TCP(sport=80, dport=tcp_port, flags="SA"))
5508 self.pg0.add_stream(p)
5509 self.pg_enable_capture(self.pg_interfaces)
5511 self.pg1.get_capture(1)
5513 # ACK packet out->in
5514 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
5515 IP(src=self.pg1.remote_ip4, dst=service_ip) /
5516 TCP(sport=33898, dport=80, flags="A"))
5517 self.pg1.add_stream(p)
5518 self.pg_enable_capture(self.pg_interfaces)
5520 self.pg0.get_capture(1)
5522 # FIN packet in -> out
5523 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5524 IP(src=self.pg0.remote_ip4, dst=twice_nat_addr) /
5525 TCP(sport=80, dport=tcp_port, flags="FA", seq=100, ack=300))
5526 self.pg0.add_stream(p)
5527 self.pg_enable_capture(self.pg_interfaces)
5529 self.pg1.get_capture(1)
5531 # FIN+ACK packet out -> in
5532 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
5533 IP(src=self.pg1.remote_ip4, dst=service_ip) /
5534 TCP(sport=33898, dport=80, flags="FA", seq=300, ack=101))
5535 self.pg1.add_stream(p)
5536 self.pg_enable_capture(self.pg_interfaces)
5538 self.pg0.get_capture(1)
5540 # ACK packet in -> out
5541 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5542 IP(src=self.pg0.remote_ip4, dst=twice_nat_addr) /
5543 TCP(sport=80, dport=tcp_port, flags="A", seq=101, ack=301))
5544 self.pg0.add_stream(p)
5545 self.pg_enable_capture(self.pg_interfaces)
5547 self.pg1.get_capture(1)
5549 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4n,
5551 self.assertEqual(len(sessions) - start_sessnum, 0)
5553 def test_tcp_session_close_in(self):
5554 """ Close TCP session from inside network """
5555 self.tcp_port_out = 10505
5556 self.nat44_add_address(self.nat_addr)
5557 self.nat44_add_static_mapping(self.pg0.remote_ip4,
5561 proto=IP_PROTOS.tcp,
5563 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
5564 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
5567 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4n, 0)
5568 start_sessnum = len(sessions)
5570 self.initiate_tcp_session(self.pg0, self.pg1)
5572 # FIN packet in -> out
5573 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5574 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
5575 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
5576 flags="FA", seq=100, ack=300))
5577 self.pg0.add_stream(p)
5578 self.pg_enable_capture(self.pg_interfaces)
5580 self.pg1.get_capture(1)
5584 # ACK packet out -> in
5585 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
5586 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
5587 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
5588 flags="A", seq=300, ack=101))
5591 # FIN packet out -> in
5592 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
5593 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
5594 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
5595 flags="FA", seq=300, ack=101))
5598 self.pg1.add_stream(pkts)
5599 self.pg_enable_capture(self.pg_interfaces)
5601 self.pg0.get_capture(2)
5603 # ACK packet in -> out
5604 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5605 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
5606 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
5607 flags="A", seq=101, ack=301))
5608 self.pg0.add_stream(p)
5609 self.pg_enable_capture(self.pg_interfaces)
5611 self.pg1.get_capture(1)
5613 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4n,
5615 self.assertEqual(len(sessions) - start_sessnum, 0)
5617 def test_tcp_session_close_out(self):
5618 """ Close TCP session from outside network """
5619 self.tcp_port_out = 10505
5620 self.nat44_add_address(self.nat_addr)
5621 self.nat44_add_static_mapping(self.pg0.remote_ip4,
5625 proto=IP_PROTOS.tcp,
5627 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
5628 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
5631 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4n, 0)
5632 start_sessnum = len(sessions)
5634 self.initiate_tcp_session(self.pg0, self.pg1)
5636 # FIN packet out -> in
5637 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
5638 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
5639 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
5640 flags="FA", seq=100, ack=300))
5641 self.pg1.add_stream(p)
5642 self.pg_enable_capture(self.pg_interfaces)
5644 self.pg0.get_capture(1)
5646 # FIN+ACK packet in -> out
5647 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5648 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
5649 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
5650 flags="FA", seq=300, ack=101))
5652 self.pg0.add_stream(p)
5653 self.pg_enable_capture(self.pg_interfaces)
5655 self.pg1.get_capture(1)
5657 # ACK packet out -> in
5658 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
5659 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
5660 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
5661 flags="A", seq=101, ack=301))
5662 self.pg1.add_stream(p)
5663 self.pg_enable_capture(self.pg_interfaces)
5665 self.pg0.get_capture(1)
5667 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4n,
5669 self.assertEqual(len(sessions) - start_sessnum, 0)
5671 def test_tcp_session_close_simultaneous(self):
5672 """ Close TCP session from inside network """
5673 self.tcp_port_out = 10505
5674 self.nat44_add_address(self.nat_addr)
5675 self.nat44_add_static_mapping(self.pg0.remote_ip4,
5679 proto=IP_PROTOS.tcp,
5681 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
5682 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
5685 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4n, 0)
5686 start_sessnum = len(sessions)
5688 self.initiate_tcp_session(self.pg0, self.pg1)
5690 # FIN packet in -> out
5691 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5692 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
5693 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
5694 flags="FA", seq=100, ack=300))
5695 self.pg0.add_stream(p)
5696 self.pg_enable_capture(self.pg_interfaces)
5698 self.pg1.get_capture(1)
5700 # FIN packet out -> in
5701 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
5702 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
5703 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
5704 flags="FA", seq=300, ack=100))
5705 self.pg1.add_stream(p)
5706 self.pg_enable_capture(self.pg_interfaces)
5708 self.pg0.get_capture(1)
5710 # ACK packet in -> out
5711 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5712 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
5713 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
5714 flags="A", seq=101, ack=301))
5715 self.pg0.add_stream(p)
5716 self.pg_enable_capture(self.pg_interfaces)
5718 self.pg1.get_capture(1)
5720 # ACK packet out -> in
5721 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
5722 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
5723 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
5724 flags="A", seq=301, ack=101))
5725 self.pg1.add_stream(p)
5726 self.pg_enable_capture(self.pg_interfaces)
5728 self.pg0.get_capture(1)
5730 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4n,
5732 self.assertEqual(len(sessions) - start_sessnum, 0)
5734 def test_one_armed_nat44_static(self):
5735 """ One armed NAT44 and 1:1 NAPT asymmetrical rule """
5736 remote_host = self.pg4.remote_hosts[0]
5737 local_host = self.pg4.remote_hosts[1]
5742 self.vapi.nat44_forwarding_enable_disable(1)
5743 self.nat44_add_address(self.nat_addr, twice_nat=1)
5744 self.nat44_add_static_mapping(local_host.ip4, self.nat_addr,
5745 local_port, external_port,
5746 proto=IP_PROTOS.tcp, out2in_only=1,
5748 self.vapi.nat44_interface_add_del_feature(self.pg4.sw_if_index)
5749 self.vapi.nat44_interface_add_del_feature(self.pg4.sw_if_index,
5752 # from client to service
5753 p = (Ether(src=self.pg4.remote_mac, dst=self.pg4.local_mac) /
5754 IP(src=remote_host.ip4, dst=self.nat_addr) /
5755 TCP(sport=12345, dport=external_port))
5756 self.pg4.add_stream(p)
5757 self.pg_enable_capture(self.pg_interfaces)
5759 capture = self.pg4.get_capture(1)
5764 self.assertEqual(ip.dst, local_host.ip4)
5765 self.assertEqual(ip.src, self.nat_addr)
5766 self.assertEqual(tcp.dport, local_port)
5767 self.assertNotEqual(tcp.sport, 12345)
5768 eh_port_in = tcp.sport
5769 self.assert_packet_checksums_valid(p)
5771 self.logger.error(ppp("Unexpected or invalid packet:", p))
5774 # from service back to client
5775 p = (Ether(src=self.pg4.remote_mac, dst=self.pg4.local_mac) /
5776 IP(src=local_host.ip4, dst=self.nat_addr) /
5777 TCP(sport=local_port, dport=eh_port_in))
5778 self.pg4.add_stream(p)
5779 self.pg_enable_capture(self.pg_interfaces)
5781 capture = self.pg4.get_capture(1)
5786 self.assertEqual(ip.src, self.nat_addr)
5787 self.assertEqual(ip.dst, remote_host.ip4)
5788 self.assertEqual(tcp.sport, external_port)
5789 self.assertEqual(tcp.dport, 12345)
5790 self.assert_packet_checksums_valid(p)
5792 self.logger.error(ppp("Unexpected or invalid packet:", p))
5795 def test_static_with_port_out2(self):
5796 """ 1:1 NAPT asymmetrical rule """
5801 self.vapi.nat44_forwarding_enable_disable(1)
5802 self.nat44_add_static_mapping(self.pg0.remote_ip4, self.nat_addr,
5803 local_port, external_port,
5804 proto=IP_PROTOS.tcp, out2in_only=1)
5805 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
5806 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
5809 # from client to service
5810 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
5811 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
5812 TCP(sport=12345, dport=external_port))
5813 self.pg1.add_stream(p)
5814 self.pg_enable_capture(self.pg_interfaces)
5816 capture = self.pg0.get_capture(1)
5821 self.assertEqual(ip.dst, self.pg0.remote_ip4)
5822 self.assertEqual(tcp.dport, local_port)
5823 self.assert_packet_checksums_valid(p)
5825 self.logger.error(ppp("Unexpected or invalid packet:", p))
5829 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
5830 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
5831 ICMP(type=11) / capture[0][IP])
5832 self.pg0.add_stream(p)
5833 self.pg_enable_capture(self.pg_interfaces)
5835 capture = self.pg1.get_capture(1)
5838 self.assertEqual(p[IP].src, self.nat_addr)
5840 self.assertEqual(inner.dst, self.nat_addr)
5841 self.assertEqual(inner[TCPerror].dport, external_port)
5843 self.logger.error(ppp("Unexpected or invalid packet:", p))
5846 # from service back to client
5847 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5848 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
5849 TCP(sport=local_port, dport=12345))
5850 self.pg0.add_stream(p)
5851 self.pg_enable_capture(self.pg_interfaces)
5853 capture = self.pg1.get_capture(1)
5858 self.assertEqual(ip.src, self.nat_addr)
5859 self.assertEqual(tcp.sport, external_port)
5860 self.assert_packet_checksums_valid(p)
5862 self.logger.error(ppp("Unexpected or invalid packet:", p))
5866 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
5867 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
5868 ICMP(type=11) / capture[0][IP])
5869 self.pg1.add_stream(p)
5870 self.pg_enable_capture(self.pg_interfaces)
5872 capture = self.pg0.get_capture(1)
5875 self.assertEqual(p[IP].dst, self.pg0.remote_ip4)
5877 self.assertEqual(inner.src, self.pg0.remote_ip4)
5878 self.assertEqual(inner[TCPerror].sport, local_port)
5880 self.logger.error(ppp("Unexpected or invalid packet:", p))
5883 # from client to server (no translation)
5884 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
5885 IP(src=self.pg1.remote_ip4, dst=self.pg0.remote_ip4) /
5886 TCP(sport=12346, dport=local_port))
5887 self.pg1.add_stream(p)
5888 self.pg_enable_capture(self.pg_interfaces)
5890 capture = self.pg0.get_capture(1)
5895 self.assertEqual(ip.dst, self.pg0.remote_ip4)
5896 self.assertEqual(tcp.dport, local_port)
5897 self.assert_packet_checksums_valid(p)
5899 self.logger.error(ppp("Unexpected or invalid packet:", p))
5902 # from service back to client (no translation)
5903 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5904 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
5905 TCP(sport=local_port, dport=12346))
5906 self.pg0.add_stream(p)
5907 self.pg_enable_capture(self.pg_interfaces)
5909 capture = self.pg1.get_capture(1)
5914 self.assertEqual(ip.src, self.pg0.remote_ip4)
5915 self.assertEqual(tcp.sport, local_port)
5916 self.assert_packet_checksums_valid(p)
5918 self.logger.error(ppp("Unexpected or invalid packet:", p))
5921 def test_output_feature(self):
5922 """ NAT44 interface output feature (in2out postrouting) """
5923 self.vapi.nat44_forwarding_enable_disable(1)
5924 self.nat44_add_address(self.nat_addr)
5925 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index,
5927 self.vapi.nat44_interface_add_del_output_feature(self.pg1.sw_if_index,
5931 pkts = self.create_stream_in(self.pg0, self.pg1)
5932 self.pg0.add_stream(pkts)
5933 self.pg_enable_capture(self.pg_interfaces)
5935 capture = self.pg1.get_capture(len(pkts))
5936 self.verify_capture_out(capture)
5939 pkts = self.create_stream_out(self.pg1)
5940 self.pg1.add_stream(pkts)
5941 self.pg_enable_capture(self.pg_interfaces)
5943 capture = self.pg0.get_capture(len(pkts))
5944 self.verify_capture_in(capture, self.pg0)
5946 def test_multiple_vrf(self):
5947 """ Multiple VRF setup """
5948 external_addr = '1.2.3.4'
5953 self.vapi.nat44_forwarding_enable_disable(1)
5954 self.nat44_add_address(self.nat_addr)
5955 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
5956 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index,
5958 self.vapi.nat44_interface_add_del_output_feature(self.pg1.sw_if_index,
5960 self.vapi.nat44_interface_add_del_feature(self.pg5.sw_if_index)
5961 self.vapi.nat44_interface_add_del_feature(self.pg5.sw_if_index,
5963 self.vapi.nat44_interface_add_del_feature(self.pg6.sw_if_index,
5965 self.nat44_add_static_mapping(self.pg5.remote_ip4, external_addr,
5966 local_port, external_port, vrf_id=1,
5967 proto=IP_PROTOS.tcp, out2in_only=1)
5968 self.nat44_add_static_mapping(
5969 self.pg0.remote_ip4, external_sw_if_index=self.pg0.sw_if_index,
5970 local_port=local_port, vrf_id=0, external_port=external_port,
5971 proto=IP_PROTOS.tcp, out2in_only=1)
5973 # from client to service (both VRF1)
5974 p = (Ether(src=self.pg6.remote_mac, dst=self.pg6.local_mac) /
5975 IP(src=self.pg6.remote_ip4, dst=external_addr) /
5976 TCP(sport=12345, dport=external_port))
5977 self.pg6.add_stream(p)
5978 self.pg_enable_capture(self.pg_interfaces)
5980 capture = self.pg5.get_capture(1)
5985 self.assertEqual(ip.dst, self.pg5.remote_ip4)
5986 self.assertEqual(tcp.dport, local_port)
5987 self.assert_packet_checksums_valid(p)
5989 self.logger.error(ppp("Unexpected or invalid packet:", p))
5992 # from service back to client (both VRF1)
5993 p = (Ether(src=self.pg5.remote_mac, dst=self.pg5.local_mac) /
5994 IP(src=self.pg5.remote_ip4, dst=self.pg6.remote_ip4) /
5995 TCP(sport=local_port, dport=12345))
5996 self.pg5.add_stream(p)
5997 self.pg_enable_capture(self.pg_interfaces)
5999 capture = self.pg6.get_capture(1)
6004 self.assertEqual(ip.src, external_addr)
6005 self.assertEqual(tcp.sport, external_port)
6006 self.assert_packet_checksums_valid(p)
6008 self.logger.error(ppp("Unexpected or invalid packet:", p))
6011 # dynamic NAT from VRF1 to VRF0 (output-feature)
6012 p = (Ether(src=self.pg5.remote_mac, dst=self.pg5.local_mac) /
6013 IP(src=self.pg5.remote_ip4, dst=self.pg1.remote_ip4) /
6014 TCP(sport=2345, dport=22))
6015 self.pg5.add_stream(p)
6016 self.pg_enable_capture(self.pg_interfaces)
6018 capture = self.pg1.get_capture(1)
6023 self.assertEqual(ip.src, self.nat_addr)
6024 self.assertNotEqual(tcp.sport, 2345)
6025 self.assert_packet_checksums_valid(p)
6028 self.logger.error(ppp("Unexpected or invalid packet:", p))
6031 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
6032 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
6033 TCP(sport=22, dport=port))
6034 self.pg1.add_stream(p)
6035 self.pg_enable_capture(self.pg_interfaces)
6037 capture = self.pg5.get_capture(1)
6042 self.assertEqual(ip.dst, self.pg5.remote_ip4)
6043 self.assertEqual(tcp.dport, 2345)
6044 self.assert_packet_checksums_valid(p)
6046 self.logger.error(ppp("Unexpected or invalid packet:", p))
6049 # from client VRF1 to service VRF0
6050 p = (Ether(src=self.pg6.remote_mac, dst=self.pg6.local_mac) /
6051 IP(src=self.pg6.remote_ip4, dst=self.pg0.local_ip4) /
6052 TCP(sport=12346, dport=external_port))
6053 self.pg6.add_stream(p)
6054 self.pg_enable_capture(self.pg_interfaces)
6056 capture = self.pg0.get_capture(1)
6061 self.assertEqual(ip.dst, self.pg0.remote_ip4)
6062 self.assertEqual(tcp.dport, local_port)
6063 self.assert_packet_checksums_valid(p)
6065 self.logger.error(ppp("Unexpected or invalid packet:", p))
6068 # from service VRF0 back to client VRF1
6069 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6070 IP(src=self.pg0.remote_ip4, dst=self.pg6.remote_ip4) /
6071 TCP(sport=local_port, dport=12346))
6072 self.pg0.add_stream(p)
6073 self.pg_enable_capture(self.pg_interfaces)
6075 capture = self.pg6.get_capture(1)
6080 self.assertEqual(ip.src, self.pg0.local_ip4)
6081 self.assertEqual(tcp.sport, external_port)
6082 self.assert_packet_checksums_valid(p)
6084 self.logger.error(ppp("Unexpected or invalid packet:", p))
6087 # from client VRF0 to service VRF1
6088 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6089 IP(src=self.pg0.remote_ip4, dst=external_addr) /
6090 TCP(sport=12347, dport=external_port))
6091 self.pg0.add_stream(p)
6092 self.pg_enable_capture(self.pg_interfaces)
6094 capture = self.pg5.get_capture(1)
6099 self.assertEqual(ip.dst, self.pg5.remote_ip4)
6100 self.assertEqual(tcp.dport, local_port)
6101 self.assert_packet_checksums_valid(p)
6103 self.logger.error(ppp("Unexpected or invalid packet:", p))
6106 # from service VRF1 back to client VRF0
6107 p = (Ether(src=self.pg5.remote_mac, dst=self.pg5.local_mac) /
6108 IP(src=self.pg5.remote_ip4, dst=self.pg0.remote_ip4) /
6109 TCP(sport=local_port, dport=12347))
6110 self.pg5.add_stream(p)
6111 self.pg_enable_capture(self.pg_interfaces)
6113 capture = self.pg0.get_capture(1)
6118 self.assertEqual(ip.src, external_addr)
6119 self.assertEqual(tcp.sport, external_port)
6120 self.assert_packet_checksums_valid(p)
6122 self.logger.error(ppp("Unexpected or invalid packet:", p))
6125 # from client to server (both VRF1, no translation)
6126 p = (Ether(src=self.pg6.remote_mac, dst=self.pg6.local_mac) /
6127 IP(src=self.pg6.remote_ip4, dst=self.pg5.remote_ip4) /
6128 TCP(sport=12348, dport=local_port))
6129 self.pg6.add_stream(p)
6130 self.pg_enable_capture(self.pg_interfaces)
6132 capture = self.pg5.get_capture(1)
6137 self.assertEqual(ip.dst, self.pg5.remote_ip4)
6138 self.assertEqual(tcp.dport, local_port)
6139 self.assert_packet_checksums_valid(p)
6141 self.logger.error(ppp("Unexpected or invalid packet:", p))
6144 # from server back to client (both VRF1, no translation)
6145 p = (Ether(src=self.pg5.remote_mac, dst=self.pg5.local_mac) /
6146 IP(src=self.pg5.remote_ip4, dst=self.pg6.remote_ip4) /
6147 TCP(sport=local_port, dport=12348))
6148 self.pg5.add_stream(p)
6149 self.pg_enable_capture(self.pg_interfaces)
6151 capture = self.pg6.get_capture(1)
6156 self.assertEqual(ip.src, self.pg5.remote_ip4)
6157 self.assertEqual(tcp.sport, local_port)
6158 self.assert_packet_checksums_valid(p)
6160 self.logger.error(ppp("Unexpected or invalid packet:", p))
6163 # from client VRF1 to server VRF0 (no translation)
6164 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6165 IP(src=self.pg0.remote_ip4, dst=self.pg6.remote_ip4) /
6166 TCP(sport=local_port, dport=12349))
6167 self.pg0.add_stream(p)
6168 self.pg_enable_capture(self.pg_interfaces)
6170 capture = self.pg6.get_capture(1)
6175 self.assertEqual(ip.src, self.pg0.remote_ip4)
6176 self.assertEqual(tcp.sport, local_port)
6177 self.assert_packet_checksums_valid(p)
6179 self.logger.error(ppp("Unexpected or invalid packet:", p))
6182 # from server VRF0 back to client VRF1 (no translation)
6183 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6184 IP(src=self.pg0.remote_ip4, dst=self.pg6.remote_ip4) /
6185 TCP(sport=local_port, dport=12349))
6186 self.pg0.add_stream(p)
6187 self.pg_enable_capture(self.pg_interfaces)
6189 capture = self.pg6.get_capture(1)
6194 self.assertEqual(ip.src, self.pg0.remote_ip4)
6195 self.assertEqual(tcp.sport, local_port)
6196 self.assert_packet_checksums_valid(p)
6198 self.logger.error(ppp("Unexpected or invalid packet:", p))
6201 # from client VRF0 to server VRF1 (no translation)
6202 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6203 IP(src=self.pg0.remote_ip4, dst=self.pg5.remote_ip4) /
6204 TCP(sport=12344, dport=local_port))
6205 self.pg0.add_stream(p)
6206 self.pg_enable_capture(self.pg_interfaces)
6208 capture = self.pg5.get_capture(1)
6213 self.assertEqual(ip.dst, self.pg5.remote_ip4)
6214 self.assertEqual(tcp.dport, local_port)
6215 self.assert_packet_checksums_valid(p)
6217 self.logger.error(ppp("Unexpected or invalid packet:", p))
6220 # from server VRF1 back to client VRF0 (no translation)
6221 p = (Ether(src=self.pg5.remote_mac, dst=self.pg5.local_mac) /
6222 IP(src=self.pg5.remote_ip4, dst=self.pg0.remote_ip4) /
6223 TCP(sport=local_port, dport=12344))
6224 self.pg5.add_stream(p)
6225 self.pg_enable_capture(self.pg_interfaces)
6227 capture = self.pg0.get_capture(1)
6232 self.assertEqual(ip.src, self.pg5.remote_ip4)
6233 self.assertEqual(tcp.sport, local_port)
6234 self.assert_packet_checksums_valid(p)
6236 self.logger.error(ppp("Unexpected or invalid packet:", p))
6239 @unittest.skipUnless(running_extended_tests, "part of extended tests")
6240 def test_session_timeout(self):
6241 """ NAT44 session timeouts """
6242 self.nat44_add_address(self.nat_addr)
6243 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
6244 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
6246 self.vapi.nat_set_timeouts(icmp=5)
6250 for i in range(0, max_sessions):
6251 src = "10.10.%u.%u" % ((i & 0xFF00) >> 8, i & 0xFF)
6252 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
6253 IP(src=src, dst=self.pg1.remote_ip4) /
6254 ICMP(id=1025, type='echo-request'))
6256 self.pg0.add_stream(pkts)
6257 self.pg_enable_capture(self.pg_interfaces)
6259 self.pg1.get_capture(max_sessions)
6264 for i in range(0, max_sessions):
6265 src = "10.11.%u.%u" % ((i & 0xFF00) >> 8, i & 0xFF)
6266 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
6267 IP(src=src, dst=self.pg1.remote_ip4) /
6268 ICMP(id=1026, type='echo-request'))
6270 self.pg0.add_stream(pkts)
6271 self.pg_enable_capture(self.pg_interfaces)
6273 self.pg1.get_capture(max_sessions)
6276 users = self.vapi.nat44_user_dump()
6278 nsessions = nsessions + user.nsessions
6279 self.assertLess(nsessions, 2 * max_sessions)
6281 @unittest.skipUnless(running_extended_tests, "part of extended tests")
6282 def test_session_rst_timeout(self):
6283 """ NAT44 session RST timeouts """
6284 self.nat44_add_address(self.nat_addr)
6285 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
6286 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
6288 self.vapi.nat_set_timeouts(tcp_transitory=5)
6290 self.initiate_tcp_session(self.pg0, self.pg1)
6291 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6292 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6293 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
6295 self.pg0.add_stream(p)
6296 self.pg_enable_capture(self.pg_interfaces)
6298 self.pg1.get_capture(1)
6302 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6303 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6304 TCP(sport=self.tcp_port_in + 1, dport=self.tcp_external_port + 1,
6306 self.pg0.add_stream(p)
6307 self.pg_enable_capture(self.pg_interfaces)
6309 self.pg1.get_capture(1)
6312 users = self.vapi.nat44_user_dump()
6313 self.assertEqual(len(users), 1)
6314 self.assertEqual(users[0].ip_address, self.pg0.remote_ip4n)
6315 self.assertEqual(users[0].nsessions, 1)
6317 @unittest.skipUnless(running_extended_tests, "part of extended tests")
6318 def test_session_limit_per_user(self):
6319 """ Maximum sessions per user limit """
6320 self.nat44_add_address(self.nat_addr)
6321 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
6322 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
6324 self.vapi.set_ipfix_exporter(collector_address=self.pg2.remote_ip4n,
6325 src_address=self.pg2.local_ip4n,
6327 template_interval=10)
6328 self.vapi.nat_set_timeouts(udp=5)
6330 # get maximum number of translations per user
6331 nat44_config = self.vapi.nat_show_config()
6334 for port in range(0, nat44_config.max_translations_per_user):
6335 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6336 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6337 UDP(sport=1025 + port, dport=1025 + port))
6340 self.pg0.add_stream(pkts)
6341 self.pg_enable_capture(self.pg_interfaces)
6343 capture = self.pg1.get_capture(len(pkts))
6345 self.vapi.nat_ipfix_enable_disable(domain_id=self.ipfix_domain_id,
6346 src_port=self.ipfix_src_port)
6348 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6349 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6350 UDP(sport=3001, dport=3002))
6351 self.pg0.add_stream(p)
6352 self.pg_enable_capture(self.pg_interfaces)
6354 capture = self.pg1.assert_nothing_captured()
6356 # verify IPFIX logging
6357 self.vapi.cli("ipfix flush") # FIXME this should be an API call
6359 capture = self.pg2.get_capture(10)
6360 ipfix = IPFIXDecoder()
6361 # first load template
6363 self.assertTrue(p.haslayer(IPFIX))
6364 if p.haslayer(Template):
6365 ipfix.add_template(p.getlayer(Template))
6366 # verify events in data set
6368 if p.haslayer(Data):
6369 data = ipfix.decode_data_set(p.getlayer(Set))
6370 self.verify_ipfix_max_entries_per_user(
6372 nat44_config.max_translations_per_user,
6373 self.pg0.remote_ip4n)
6376 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6377 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6378 UDP(sport=3001, dport=3002))
6379 self.pg0.add_stream(p)
6380 self.pg_enable_capture(self.pg_interfaces)
6382 self.pg1.get_capture(1)
6384 def test_syslog_sess(self):
6385 """ Test syslog session creation and deletion """
6386 self.vapi.syslog_set_filter(SYSLOG_SEVERITY.INFO)
6387 self.vapi.syslog_set_sender(self.pg2.local_ip4n, self.pg2.remote_ip4n)
6388 self.nat44_add_address(self.nat_addr)
6389 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
6390 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
6393 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
6394 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6395 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port))
6396 self.pg0.add_stream(p)
6397 self.pg_enable_capture(self.pg_interfaces)
6399 capture = self.pg1.get_capture(1)
6400 self.tcp_port_out = capture[0][TCP].sport
6401 capture = self.pg2.get_capture(1)
6402 self.verify_syslog_sess(capture[0][Raw].load)
6404 self.pg_enable_capture(self.pg_interfaces)
6406 self.nat44_add_address(self.nat_addr, is_add=0)
6407 capture = self.pg2.get_capture(1)
6408 self.verify_syslog_sess(capture[0][Raw].load, False)
6411 super(TestNAT44EndpointDependent, self).tearDown()
6412 if not self.vpp_dead:
6413 self.logger.info(self.vapi.cli("show nat44 addresses"))
6414 self.logger.info(self.vapi.cli("show nat44 interfaces"))
6415 self.logger.info(self.vapi.cli("show nat44 static mappings"))
6416 self.logger.info(self.vapi.cli("show nat44 interface address"))
6417 self.logger.info(self.vapi.cli("show nat44 sessions detail"))
6418 self.logger.info(self.vapi.cli("show nat44 hash tables detail"))
6419 self.logger.info(self.vapi.cli("show nat timeouts"))
6421 self.vapi.cli("clear logging")
6424 class TestNAT44Out2InDPO(MethodHolder):
6425 """ NAT44 Test Cases using out2in DPO """
6428 def setUpConstants(cls):
6429 super(TestNAT44Out2InDPO, cls).setUpConstants()
6430 cls.vpp_cmdline.extend(["nat", "{", "out2in dpo", "}"])
6433 def setUpClass(cls):
6434 super(TestNAT44Out2InDPO, cls).setUpClass()
6435 cls.vapi.cli("set log class nat level debug")
6438 cls.tcp_port_in = 6303
6439 cls.tcp_port_out = 6303
6440 cls.udp_port_in = 6304
6441 cls.udp_port_out = 6304
6442 cls.icmp_id_in = 6305
6443 cls.icmp_id_out = 6305
6444 cls.nat_addr = '10.0.0.3'
6445 cls.nat_addr_n = socket.inet_pton(socket.AF_INET, cls.nat_addr)
6446 cls.dst_ip4 = '192.168.70.1'
6448 cls.create_pg_interfaces(range(2))
6451 cls.pg0.config_ip4()
6452 cls.pg0.resolve_arp()
6455 cls.pg1.config_ip6()
6456 cls.pg1.resolve_ndp()
6458 cls.vapi.ip_add_del_route(is_ipv6=True, dst_address='\x00' * 16,
6459 dst_address_length=0,
6460 next_hop_address=cls.pg1.remote_ip6n,
6461 next_hop_sw_if_index=cls.pg1.sw_if_index)
6464 super(TestNAT44Out2InDPO, cls).tearDownClass()
6467 def configure_xlat(self):
6468 self.dst_ip6_pfx = '1:2:3::'
6469 self.dst_ip6_pfx_n = socket.inet_pton(socket.AF_INET6,
6471 self.dst_ip6_pfx_len = 96
6472 self.src_ip6_pfx = '4:5:6::'
6473 self.src_ip6_pfx_n = socket.inet_pton(socket.AF_INET6,
6475 self.src_ip6_pfx_len = 96
6476 self.vapi.map_add_domain(self.dst_ip6_pfx_n, self.dst_ip6_pfx_len,
6477 self.src_ip6_pfx_n, self.src_ip6_pfx_len,
6478 '\x00\x00\x00\x00', 0)
6480 @unittest.skip('Temporary disabled')
6481 def test_464xlat_ce(self):
6482 """ Test 464XLAT CE with NAT44 """
6484 nat_config = self.vapi.nat_show_config()
6485 self.assertEqual(1, nat_config.out2in_dpo)
6487 self.configure_xlat()
6489 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
6490 self.vapi.nat44_add_del_address_range(self.nat_addr_n, self.nat_addr_n)
6492 out_src_ip6 = self.compose_ip6(self.dst_ip4, self.dst_ip6_pfx,
6493 self.dst_ip6_pfx_len)
6494 out_dst_ip6 = self.compose_ip6(self.nat_addr, self.src_ip6_pfx,
6495 self.src_ip6_pfx_len)
6498 pkts = self.create_stream_in(self.pg0, self.pg1, self.dst_ip4)
6499 self.pg0.add_stream(pkts)
6500 self.pg_enable_capture(self.pg_interfaces)
6502 capture = self.pg1.get_capture(len(pkts))
6503 self.verify_capture_out_ip6(capture, nat_ip=out_dst_ip6,
6506 pkts = self.create_stream_out_ip6(self.pg1, out_src_ip6,
6508 self.pg1.add_stream(pkts)
6509 self.pg_enable_capture(self.pg_interfaces)
6511 capture = self.pg0.get_capture(len(pkts))
6512 self.verify_capture_in(capture, self.pg0)
6514 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index,
6516 self.vapi.nat44_add_del_address_range(self.nat_addr_n,
6517 self.nat_addr_n, is_add=0)
6519 @unittest.skip('Temporary disabled')
6520 def test_464xlat_ce_no_nat(self):
6521 """ Test 464XLAT CE without NAT44 """
6523 self.configure_xlat()
6525 out_src_ip6 = self.compose_ip6(self.dst_ip4, self.dst_ip6_pfx,
6526 self.dst_ip6_pfx_len)
6527 out_dst_ip6 = self.compose_ip6(self.pg0.remote_ip4, self.src_ip6_pfx,
6528 self.src_ip6_pfx_len)
6530 pkts = self.create_stream_in(self.pg0, self.pg1, self.dst_ip4)
6531 self.pg0.add_stream(pkts)
6532 self.pg_enable_capture(self.pg_interfaces)
6534 capture = self.pg1.get_capture(len(pkts))
6535 self.verify_capture_out_ip6(capture, dst_ip=out_src_ip6,
6536 nat_ip=out_dst_ip6, same_port=True)
6538 pkts = self.create_stream_out_ip6(self.pg1, out_src_ip6, out_dst_ip6)
6539 self.pg1.add_stream(pkts)
6540 self.pg_enable_capture(self.pg_interfaces)
6542 capture = self.pg0.get_capture(len(pkts))
6543 self.verify_capture_in(capture, self.pg0)
6546 class TestDeterministicNAT(MethodHolder):
6547 """ Deterministic NAT Test Cases """
6550 def setUpConstants(cls):
6551 super(TestDeterministicNAT, cls).setUpConstants()
6552 cls.vpp_cmdline.extend(["nat", "{", "deterministic", "}"])
6555 def setUpClass(cls):
6556 super(TestDeterministicNAT, cls).setUpClass()
6557 cls.vapi.cli("set log class nat level debug")
6560 cls.tcp_port_in = 6303
6561 cls.tcp_external_port = 6303
6562 cls.udp_port_in = 6304
6563 cls.udp_external_port = 6304
6564 cls.icmp_id_in = 6305
6565 cls.nat_addr = '10.0.0.3'
6567 cls.create_pg_interfaces(range(3))
6568 cls.interfaces = list(cls.pg_interfaces)
6570 for i in cls.interfaces:
6575 cls.pg0.generate_remote_hosts(2)
6576 cls.pg0.configure_ipv4_neighbors()
6579 super(TestDeterministicNAT, cls).tearDownClass()
6582 def create_stream_in(self, in_if, out_if, ttl=64):
6584 Create packet stream for inside network
6586 :param in_if: Inside interface
6587 :param out_if: Outside interface
6588 :param ttl: TTL of generated packets
6592 p = (Ether(dst=in_if.local_mac, src=in_if.remote_mac) /
6593 IP(src=in_if.remote_ip4, dst=out_if.remote_ip4, ttl=ttl) /
6594 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port))
6598 p = (Ether(dst=in_if.local_mac, src=in_if.remote_mac) /
6599 IP(src=in_if.remote_ip4, dst=out_if.remote_ip4, ttl=ttl) /
6600 UDP(sport=self.udp_port_in, dport=self.udp_external_port))
6604 p = (Ether(dst=in_if.local_mac, src=in_if.remote_mac) /
6605 IP(src=in_if.remote_ip4, dst=out_if.remote_ip4, ttl=ttl) /
6606 ICMP(id=self.icmp_id_in, type='echo-request'))
6611 def create_stream_out(self, out_if, dst_ip=None, ttl=64):
6613 Create packet stream for outside network
6615 :param out_if: Outside interface
6616 :param dst_ip: Destination IP address (Default use global NAT address)
6617 :param ttl: TTL of generated packets
6620 dst_ip = self.nat_addr
6623 p = (Ether(dst=out_if.local_mac, src=out_if.remote_mac) /
6624 IP(src=out_if.remote_ip4, dst=dst_ip, ttl=ttl) /
6625 TCP(dport=self.tcp_port_out, sport=self.tcp_external_port))
6629 p = (Ether(dst=out_if.local_mac, src=out_if.remote_mac) /
6630 IP(src=out_if.remote_ip4, dst=dst_ip, ttl=ttl) /
6631 UDP(dport=self.udp_port_out, sport=self.udp_external_port))
6635 p = (Ether(dst=out_if.local_mac, src=out_if.remote_mac) /
6636 IP(src=out_if.remote_ip4, dst=dst_ip, ttl=ttl) /
6637 ICMP(id=self.icmp_external_id, type='echo-reply'))
6642 def verify_capture_out(self, capture, nat_ip=None):
6644 Verify captured packets on outside network
6646 :param capture: Captured packets
6647 :param nat_ip: Translated IP address (Default use global NAT address)
6648 :param same_port: Sorce port number is not translated (Default False)
6651 nat_ip = self.nat_addr
6652 for packet in capture:
6654 self.assertEqual(packet[IP].src, nat_ip)
6655 if packet.haslayer(TCP):
6656 self.tcp_port_out = packet[TCP].sport
6657 elif packet.haslayer(UDP):
6658 self.udp_port_out = packet[UDP].sport
6660 self.icmp_external_id = packet[ICMP].id
6662 self.logger.error(ppp("Unexpected or invalid packet "
6663 "(outside network):", packet))
6666 def test_deterministic_mode(self):
6667 """ NAT plugin run deterministic mode """
6668 in_addr = '172.16.255.0'
6669 out_addr = '172.17.255.50'
6670 in_addr_t = '172.16.255.20'
6671 in_addr_n = socket.inet_aton(in_addr)
6672 out_addr_n = socket.inet_aton(out_addr)
6673 in_addr_t_n = socket.inet_aton(in_addr_t)
6677 nat_config = self.vapi.nat_show_config()
6678 self.assertEqual(1, nat_config.deterministic)
6680 self.vapi.nat_det_add_del_map(in_addr_n, in_plen, out_addr_n, out_plen)
6682 rep1 = self.vapi.nat_det_forward(in_addr_t_n)
6683 self.assertEqual(rep1.out_addr[:4], out_addr_n)
6684 rep2 = self.vapi.nat_det_reverse(out_addr_n, rep1.out_port_hi)
6685 self.assertEqual(rep2.in_addr[:4], in_addr_t_n)
6687 deterministic_mappings = self.vapi.nat_det_map_dump()
6688 self.assertEqual(len(deterministic_mappings), 1)
6689 dsm = deterministic_mappings[0]
6690 self.assertEqual(in_addr_n, dsm.in_addr[:4])
6691 self.assertEqual(in_plen, dsm.in_plen)
6692 self.assertEqual(out_addr_n, dsm.out_addr[:4])
6693 self.assertEqual(out_plen, dsm.out_plen)
6695 self.clear_nat_det()
6696 deterministic_mappings = self.vapi.nat_det_map_dump()
6697 self.assertEqual(len(deterministic_mappings), 0)
6699 def test_set_timeouts(self):
6700 """ Set deterministic NAT timeouts """
6701 timeouts_before = self.vapi.nat_get_timeouts()
6703 self.vapi.nat_set_timeouts(timeouts_before.udp + 10,
6704 timeouts_before.tcp_established + 10,
6705 timeouts_before.tcp_transitory + 10,
6706 timeouts_before.icmp + 10)
6708 timeouts_after = self.vapi.nat_get_timeouts()
6710 self.assertNotEqual(timeouts_before.udp, timeouts_after.udp)
6711 self.assertNotEqual(timeouts_before.icmp, timeouts_after.icmp)
6712 self.assertNotEqual(timeouts_before.tcp_established,
6713 timeouts_after.tcp_established)
6714 self.assertNotEqual(timeouts_before.tcp_transitory,
6715 timeouts_after.tcp_transitory)
6717 def test_det_in(self):
6718 """ Deterministic NAT translation test (TCP, UDP, ICMP) """
6720 nat_ip = "10.0.0.10"
6722 self.vapi.nat_det_add_del_map(self.pg0.remote_ip4n,
6724 socket.inet_aton(nat_ip),
6726 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
6727 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
6731 pkts = self.create_stream_in(self.pg0, self.pg1)
6732 self.pg0.add_stream(pkts)
6733 self.pg_enable_capture(self.pg_interfaces)
6735 capture = self.pg1.get_capture(len(pkts))
6736 self.verify_capture_out(capture, nat_ip)
6739 pkts = self.create_stream_out(self.pg1, nat_ip)
6740 self.pg1.add_stream(pkts)
6741 self.pg_enable_capture(self.pg_interfaces)
6743 capture = self.pg0.get_capture(len(pkts))
6744 self.verify_capture_in(capture, self.pg0)
6747 sessions = self.vapi.nat_det_session_dump(self.pg0.remote_ip4n)
6748 self.assertEqual(len(sessions), 3)
6752 self.assertEqual(s.ext_addr[:4], self.pg1.remote_ip4n)
6753 self.assertEqual(s.in_port, self.tcp_port_in)
6754 self.assertEqual(s.out_port, self.tcp_port_out)
6755 self.assertEqual(s.ext_port, self.tcp_external_port)
6759 self.assertEqual(s.ext_addr[:4], self.pg1.remote_ip4n)
6760 self.assertEqual(s.in_port, self.udp_port_in)
6761 self.assertEqual(s.out_port, self.udp_port_out)
6762 self.assertEqual(s.ext_port, self.udp_external_port)
6766 self.assertEqual(s.ext_addr[:4], self.pg1.remote_ip4n)
6767 self.assertEqual(s.in_port, self.icmp_id_in)
6768 self.assertEqual(s.out_port, self.icmp_external_id)
6770 def test_multiple_users(self):
6771 """ Deterministic NAT multiple users """
6773 nat_ip = "10.0.0.10"
6775 external_port = 6303
6777 host0 = self.pg0.remote_hosts[0]
6778 host1 = self.pg0.remote_hosts[1]
6780 self.vapi.nat_det_add_del_map(host0.ip4n,
6782 socket.inet_aton(nat_ip),
6784 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
6785 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
6789 p = (Ether(src=host0.mac, dst=self.pg0.local_mac) /
6790 IP(src=host0.ip4, dst=self.pg1.remote_ip4) /
6791 TCP(sport=port_in, dport=external_port))
6792 self.pg0.add_stream(p)
6793 self.pg_enable_capture(self.pg_interfaces)
6795 capture = self.pg1.get_capture(1)
6800 self.assertEqual(ip.src, nat_ip)
6801 self.assertEqual(ip.dst, self.pg1.remote_ip4)
6802 self.assertEqual(tcp.dport, external_port)
6803 port_out0 = tcp.sport
6805 self.logger.error(ppp("Unexpected or invalid packet:", p))
6809 p = (Ether(src=host1.mac, dst=self.pg0.local_mac) /
6810 IP(src=host1.ip4, dst=self.pg1.remote_ip4) /
6811 TCP(sport=port_in, dport=external_port))
6812 self.pg0.add_stream(p)
6813 self.pg_enable_capture(self.pg_interfaces)
6815 capture = self.pg1.get_capture(1)
6820 self.assertEqual(ip.src, nat_ip)
6821 self.assertEqual(ip.dst, self.pg1.remote_ip4)
6822 self.assertEqual(tcp.dport, external_port)
6823 port_out1 = tcp.sport
6825 self.logger.error(ppp("Unexpected or invalid packet:", p))
6828 dms = self.vapi.nat_det_map_dump()
6829 self.assertEqual(1, len(dms))
6830 self.assertEqual(2, dms[0].ses_num)
6833 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
6834 IP(src=self.pg1.remote_ip4, dst=nat_ip) /
6835 TCP(sport=external_port, dport=port_out0))
6836 self.pg1.add_stream(p)
6837 self.pg_enable_capture(self.pg_interfaces)
6839 capture = self.pg0.get_capture(1)
6844 self.assertEqual(ip.src, self.pg1.remote_ip4)
6845 self.assertEqual(ip.dst, host0.ip4)
6846 self.assertEqual(tcp.dport, port_in)
6847 self.assertEqual(tcp.sport, external_port)
6849 self.logger.error(ppp("Unexpected or invalid packet:", p))
6853 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
6854 IP(src=self.pg1.remote_ip4, dst=nat_ip) /
6855 TCP(sport=external_port, dport=port_out1))
6856 self.pg1.add_stream(p)
6857 self.pg_enable_capture(self.pg_interfaces)
6859 capture = self.pg0.get_capture(1)
6864 self.assertEqual(ip.src, self.pg1.remote_ip4)
6865 self.assertEqual(ip.dst, host1.ip4)
6866 self.assertEqual(tcp.dport, port_in)
6867 self.assertEqual(tcp.sport, external_port)
6869 self.logger.error(ppp("Unexpected or invalid packet", p))
6872 # session close api test
6873 self.vapi.nat_det_close_session_out(socket.inet_aton(nat_ip),
6875 self.pg1.remote_ip4n,
6877 dms = self.vapi.nat_det_map_dump()
6878 self.assertEqual(dms[0].ses_num, 1)
6880 self.vapi.nat_det_close_session_in(host0.ip4n,
6882 self.pg1.remote_ip4n,
6884 dms = self.vapi.nat_det_map_dump()
6885 self.assertEqual(dms[0].ses_num, 0)
6887 def test_tcp_session_close_detection_in(self):
6888 """ Deterministic NAT TCP session close from inside network """
6889 self.vapi.nat_det_add_del_map(self.pg0.remote_ip4n,
6891 socket.inet_aton(self.nat_addr),
6893 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
6894 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
6897 self.initiate_tcp_session(self.pg0, self.pg1)
6899 # close the session from inside
6901 # FIN packet in -> out
6902 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6903 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6904 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
6906 self.pg0.add_stream(p)
6907 self.pg_enable_capture(self.pg_interfaces)
6909 self.pg1.get_capture(1)
6913 # ACK packet out -> in
6914 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
6915 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
6916 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
6920 # FIN packet out -> in
6921 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
6922 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
6923 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
6927 self.pg1.add_stream(pkts)
6928 self.pg_enable_capture(self.pg_interfaces)
6930 self.pg0.get_capture(2)
6932 # ACK packet in -> out
6933 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6934 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6935 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
6937 self.pg0.add_stream(p)
6938 self.pg_enable_capture(self.pg_interfaces)
6940 self.pg1.get_capture(1)
6942 # Check if deterministic NAT44 closed the session
6943 dms = self.vapi.nat_det_map_dump()
6944 self.assertEqual(0, dms[0].ses_num)
6946 self.logger.error("TCP session termination failed")
6949 def test_tcp_session_close_detection_out(self):
6950 """ Deterministic NAT TCP session close from outside network """
6951 self.vapi.nat_det_add_del_map(self.pg0.remote_ip4n,
6953 socket.inet_aton(self.nat_addr),
6955 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
6956 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
6959 self.initiate_tcp_session(self.pg0, self.pg1)
6961 # close the session from outside
6963 # FIN packet out -> in
6964 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
6965 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
6966 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
6968 self.pg1.add_stream(p)
6969 self.pg_enable_capture(self.pg_interfaces)
6971 self.pg0.get_capture(1)
6975 # ACK packet in -> out
6976 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6977 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6978 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
6982 # ACK packet in -> out
6983 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6984 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6985 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
6989 self.pg0.add_stream(pkts)
6990 self.pg_enable_capture(self.pg_interfaces)
6992 self.pg1.get_capture(2)
6994 # ACK packet out -> in
6995 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
6996 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
6997 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
6999 self.pg1.add_stream(p)
7000 self.pg_enable_capture(self.pg_interfaces)
7002 self.pg0.get_capture(1)
7004 # Check if deterministic NAT44 closed the session
7005 dms = self.vapi.nat_det_map_dump()
7006 self.assertEqual(0, dms[0].ses_num)
7008 self.logger.error("TCP session termination failed")
7011 @unittest.skipUnless(running_extended_tests, "part of extended tests")
7012 def test_session_timeout(self):
7013 """ Deterministic NAT session timeouts """
7014 self.vapi.nat_det_add_del_map(self.pg0.remote_ip4n,
7016 socket.inet_aton(self.nat_addr),
7018 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
7019 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
7022 self.initiate_tcp_session(self.pg0, self.pg1)
7023 self.vapi.nat_set_timeouts(5, 5, 5, 5)
7024 pkts = self.create_stream_in(self.pg0, self.pg1)
7025 self.pg0.add_stream(pkts)
7026 self.pg_enable_capture(self.pg_interfaces)
7028 capture = self.pg1.get_capture(len(pkts))
7031 dms = self.vapi.nat_det_map_dump()
7032 self.assertEqual(0, dms[0].ses_num)
7034 @unittest.skipUnless(running_extended_tests, "part of extended tests")
7035 def test_session_limit_per_user(self):
7036 """ Deterministic NAT maximum sessions per user limit """
7037 self.vapi.nat_det_add_del_map(self.pg0.remote_ip4n,
7039 socket.inet_aton(self.nat_addr),
7041 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
7042 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
7044 self.vapi.set_ipfix_exporter(collector_address=self.pg2.remote_ip4n,
7045 src_address=self.pg2.local_ip4n,
7047 template_interval=10)
7048 self.vapi.nat_ipfix_enable_disable()
7051 for port in range(1025, 2025):
7052 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
7053 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
7054 UDP(sport=port, dport=port))
7057 self.pg0.add_stream(pkts)
7058 self.pg_enable_capture(self.pg_interfaces)
7060 capture = self.pg1.get_capture(len(pkts))
7062 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
7063 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
7064 UDP(sport=3001, dport=3002))
7065 self.pg0.add_stream(p)
7066 self.pg_enable_capture(self.pg_interfaces)
7068 capture = self.pg1.assert_nothing_captured()
7070 # verify ICMP error packet
7071 capture = self.pg0.get_capture(1)
7073 self.assertTrue(p.haslayer(ICMP))
7075 self.assertEqual(icmp.type, 3)
7076 self.assertEqual(icmp.code, 1)
7077 self.assertTrue(icmp.haslayer(IPerror))
7078 inner_ip = icmp[IPerror]
7079 self.assertEqual(inner_ip[UDPerror].sport, 3001)
7080 self.assertEqual(inner_ip[UDPerror].dport, 3002)
7082 dms = self.vapi.nat_det_map_dump()
7084 self.assertEqual(1000, dms[0].ses_num)
7086 # verify IPFIX logging
7087 self.vapi.cli("ipfix flush") # FIXME this should be an API call
7089 capture = self.pg2.get_capture(2)
7090 ipfix = IPFIXDecoder()
7091 # first load template
7093 self.assertTrue(p.haslayer(IPFIX))
7094 if p.haslayer(Template):
7095 ipfix.add_template(p.getlayer(Template))
7096 # verify events in data set
7098 if p.haslayer(Data):
7099 data = ipfix.decode_data_set(p.getlayer(Set))
7100 self.verify_ipfix_max_entries_per_user(data,
7102 self.pg0.remote_ip4n)
7104 def clear_nat_det(self):
7106 Clear deterministic NAT configuration.
7108 self.vapi.nat_ipfix_enable_disable(enable=0)
7109 self.vapi.nat_set_timeouts()
7110 deterministic_mappings = self.vapi.nat_det_map_dump()
7111 for dsm in deterministic_mappings:
7112 self.vapi.nat_det_add_del_map(dsm.in_addr,
7118 interfaces = self.vapi.nat44_interface_dump()
7119 for intf in interfaces:
7120 self.vapi.nat44_interface_add_del_feature(intf.sw_if_index,
7125 super(TestDeterministicNAT, self).tearDown()
7126 if not self.vpp_dead:
7127 self.logger.info(self.vapi.cli("show nat44 interfaces"))
7128 self.logger.info(self.vapi.cli("show nat timeouts"))
7130 self.vapi.cli("show nat44 deterministic mappings"))
7132 self.vapi.cli("show nat44 deterministic sessions"))
7133 self.clear_nat_det()
7136 class TestNAT64(MethodHolder):
7137 """ NAT64 Test Cases """
7140 def setUpConstants(cls):
7141 super(TestNAT64, cls).setUpConstants()
7142 cls.vpp_cmdline.extend(["nat", "{", "nat64 bib hash buckets 128",
7143 "nat64 st hash buckets 256", "}"])
7146 def setUpClass(cls):
7147 super(TestNAT64, cls).setUpClass()
7150 cls.tcp_port_in = 6303
7151 cls.tcp_port_out = 6303
7152 cls.udp_port_in = 6304
7153 cls.udp_port_out = 6304
7154 cls.icmp_id_in = 6305
7155 cls.icmp_id_out = 6305
7156 cls.tcp_external_port = 80
7157 cls.nat_addr = '10.0.0.3'
7158 cls.nat_addr_n = socket.inet_pton(socket.AF_INET, cls.nat_addr)
7160 cls.vrf1_nat_addr = '10.0.10.3'
7161 cls.vrf1_nat_addr_n = socket.inet_pton(socket.AF_INET,
7163 cls.ipfix_src_port = 4739
7164 cls.ipfix_domain_id = 1
7166 cls.create_pg_interfaces(range(6))
7167 cls.ip6_interfaces = list(cls.pg_interfaces[0:1])
7168 cls.ip6_interfaces.append(cls.pg_interfaces[2])
7169 cls.ip4_interfaces = list(cls.pg_interfaces[1:2])
7171 cls.vapi.ip_table_add_del(is_ipv6=1, is_add=1,
7172 table_id=cls.vrf1_id)
7174 cls.pg_interfaces[2].set_table_ip6(cls.vrf1_id)
7176 cls.pg0.generate_remote_hosts(2)
7178 for i in cls.ip6_interfaces:
7181 i.configure_ipv6_neighbors()
7183 for i in cls.ip4_interfaces:
7189 cls.pg3.config_ip4()
7190 cls.pg3.resolve_arp()
7191 cls.pg3.config_ip6()
7192 cls.pg3.configure_ipv6_neighbors()
7195 cls.pg5.config_ip6()
7198 super(TestNAT64, cls).tearDownClass()
7201 def test_nat64_inside_interface_handles_neighbor_advertisement(self):
7202 """ NAT64 inside interface handles Neighbor Advertisement """
7204 self.vapi.nat64_add_del_interface(self.pg5.sw_if_index)
7207 ping = (Ether(dst=self.pg5.local_mac, src=self.pg5.remote_mac) /
7208 IPv6(src=self.pg5.remote_ip6, dst=self.pg5.local_ip6) /
7209 ICMPv6EchoRequest())
7211 self.pg5.add_stream(pkts)
7212 self.pg_enable_capture(self.pg_interfaces)
7215 # Wait for Neighbor Solicitation
7216 capture = self.pg5.get_capture(len(pkts))
7219 self.assertEqual(packet[IPv6].src, self.pg5.local_ip6)
7220 self.assertEqual(packet.haslayer(ICMPv6ND_NS), 1)
7221 tgt = packet[ICMPv6ND_NS].tgt
7223 self.logger.error(ppp("Unexpected or invalid packet:", packet))
7226 # Send Neighbor Advertisement
7227 p = (Ether(dst=self.pg5.local_mac, src=self.pg5.remote_mac) /
7228 IPv6(src=self.pg5.remote_ip6, dst=self.pg5.local_ip6) /
7229 ICMPv6ND_NA(tgt=tgt) /
7230 ICMPv6NDOptDstLLAddr(lladdr=self.pg5.remote_mac))
7232 self.pg5.add_stream(pkts)
7233 self.pg_enable_capture(self.pg_interfaces)
7236 # Try to send ping again
7238 self.pg5.add_stream(pkts)
7239 self.pg_enable_capture(self.pg_interfaces)
7242 # Wait for ping reply
7243 capture = self.pg5.get_capture(len(pkts))
7246 self.assertEqual(packet[IPv6].src, self.pg5.local_ip6)
7247 self.assertEqual(packet[IPv6].dst, self.pg5.remote_ip6)
7248 self.assertEqual(packet.haslayer(ICMPv6EchoReply), 1)
7250 self.logger.error(ppp("Unexpected or invalid packet:", packet))
7253 def test_pool(self):
7254 """ Add/delete address to NAT64 pool """
7255 nat_addr = socket.inet_pton(socket.AF_INET, '1.2.3.4')
7257 self.vapi.nat64_add_del_pool_addr_range(nat_addr, nat_addr)
7259 addresses = self.vapi.nat64_pool_addr_dump()
7260 self.assertEqual(len(addresses), 1)
7261 self.assertEqual(addresses[0].address, nat_addr)
7263 self.vapi.nat64_add_del_pool_addr_range(nat_addr, nat_addr, is_add=0)
7265 addresses = self.vapi.nat64_pool_addr_dump()
7266 self.assertEqual(len(addresses), 0)
7268 def test_interface(self):
7269 """ Enable/disable NAT64 feature on the interface """
7270 self.vapi.nat64_add_del_interface(self.pg0.sw_if_index)
7271 self.vapi.nat64_add_del_interface(self.pg1.sw_if_index, is_inside=0)
7273 interfaces = self.vapi.nat64_interface_dump()
7274 self.assertEqual(len(interfaces), 2)
7277 for intf in interfaces:
7278 if intf.sw_if_index == self.pg0.sw_if_index:
7279 self.assertEqual(intf.is_inside, 1)
7281 elif intf.sw_if_index == self.pg1.sw_if_index:
7282 self.assertEqual(intf.is_inside, 0)
7284 self.assertTrue(pg0_found)
7285 self.assertTrue(pg1_found)
7287 features = self.vapi.cli("show interface features pg0")
7288 self.assertNotEqual(features.find('nat64-in2out'), -1)
7289 features = self.vapi.cli("show interface features pg1")
7290 self.assertNotEqual(features.find('nat64-out2in'), -1)
7292 self.vapi.nat64_add_del_interface(self.pg0.sw_if_index, is_add=0)
7293 self.vapi.nat64_add_del_interface(self.pg1.sw_if_index, is_add=0)
7295 interfaces = self.vapi.nat64_interface_dump()
7296 self.assertEqual(len(interfaces), 0)
7298 def test_static_bib(self):
7299 """ Add/delete static BIB entry """
7300 in_addr = socket.inet_pton(socket.AF_INET6,
7301 '2001:db8:85a3::8a2e:370:7334')
7302 out_addr = socket.inet_pton(socket.AF_INET, '10.1.1.3')
7305 proto = IP_PROTOS.tcp
7307 self.vapi.nat64_add_del_static_bib(in_addr,
7312 bib = self.vapi.nat64_bib_dump(IP_PROTOS.tcp)
7317 self.assertEqual(bibe.i_addr, in_addr)
7318 self.assertEqual(bibe.o_addr, out_addr)
7319 self.assertEqual(bibe.i_port, in_port)
7320 self.assertEqual(bibe.o_port, out_port)
7321 self.assertEqual(static_bib_num, 1)
7322 bibs = self.statistics.get_counter('/nat64/total-bibs')
7323 self.assertEqual(bibs[0][0], 1)
7325 self.vapi.nat64_add_del_static_bib(in_addr,
7331 bib = self.vapi.nat64_bib_dump(IP_PROTOS.tcp)
7336 self.assertEqual(static_bib_num, 0)
7337 bibs = self.statistics.get_counter('/nat64/total-bibs')
7338 self.assertEqual(bibs[0][0], 0)
7340 def test_set_timeouts(self):
7341 """ Set NAT64 timeouts """
7342 # verify default values
7343 timeouts = self.vapi.nat_get_timeouts()
7344 self.assertEqual(timeouts.udp, 300)
7345 self.assertEqual(timeouts.icmp, 60)
7346 self.assertEqual(timeouts.tcp_transitory, 240)
7347 self.assertEqual(timeouts.tcp_established, 7440)
7349 # set and verify custom values
7350 self.vapi.nat_set_timeouts(udp=200, icmp=30, tcp_transitory=250,
7351 tcp_established=7450)
7352 timeouts = self.vapi.nat_get_timeouts()
7353 self.assertEqual(timeouts.udp, 200)
7354 self.assertEqual(timeouts.icmp, 30)
7355 self.assertEqual(timeouts.tcp_transitory, 250)
7356 self.assertEqual(timeouts.tcp_established, 7450)
7358 def test_dynamic(self):
7359 """ NAT64 dynamic translation test """
7360 self.tcp_port_in = 6303
7361 self.udp_port_in = 6304
7362 self.icmp_id_in = 6305
7364 ses_num_start = self.nat64_get_ses_num()
7366 self.vapi.nat64_add_del_pool_addr_range(self.nat_addr_n,
7368 self.vapi.nat64_add_del_interface(self.pg0.sw_if_index)
7369 self.vapi.nat64_add_del_interface(self.pg1.sw_if_index, is_inside=0)
7372 tcpn = self.statistics.get_counter('/err/nat64-in2out/TCP packets')
7373 udpn = self.statistics.get_counter('/err/nat64-in2out/UDP packets')
7374 icmpn = self.statistics.get_counter('/err/nat64-in2out/ICMP packets')
7375 totaln = self.statistics.get_counter(
7376 '/err/nat64-in2out/good in2out packets processed')
7378 pkts = self.create_stream_in_ip6(self.pg0, self.pg1)
7379 self.pg0.add_stream(pkts)
7380 self.pg_enable_capture(self.pg_interfaces)
7382 capture = self.pg1.get_capture(len(pkts))
7383 self.verify_capture_out(capture, nat_ip=self.nat_addr,
7384 dst_ip=self.pg1.remote_ip4)
7386 err = self.statistics.get_counter('/err/nat64-in2out/TCP packets')
7387 self.assertEqual(err - tcpn, 1)
7388 err = self.statistics.get_counter('/err/nat64-in2out/UDP packets')
7389 self.assertEqual(err - udpn, 1)
7390 err = self.statistics.get_counter('/err/nat64-in2out/ICMP packets')
7391 self.assertEqual(err - icmpn, 1)
7392 err = self.statistics.get_counter(
7393 '/err/nat64-in2out/good in2out packets processed')
7394 self.assertEqual(err - totaln, 3)
7397 tcpn = self.statistics.get_counter('/err/nat64-out2in/TCP packets')
7398 udpn = self.statistics.get_counter('/err/nat64-out2in/UDP packets')
7399 icmpn = self.statistics.get_counter('/err/nat64-out2in/ICMP packets')
7400 totaln = self.statistics.get_counter(
7401 '/err/nat64-out2in/good out2in packets processed')
7403 pkts = self.create_stream_out(self.pg1, dst_ip=self.nat_addr)
7404 self.pg1.add_stream(pkts)
7405 self.pg_enable_capture(self.pg_interfaces)
7407 capture = self.pg0.get_capture(len(pkts))
7408 ip = IPv6(src=''.join(['64:ff9b::', self.pg1.remote_ip4]))
7409 self.verify_capture_in_ip6(capture, ip[IPv6].src, self.pg0.remote_ip6)
7411 err = self.statistics.get_counter('/err/nat64-out2in/TCP packets')
7412 self.assertEqual(err - tcpn, 1)
7413 err = self.statistics.get_counter('/err/nat64-out2in/UDP packets')
7414 self.assertEqual(err - udpn, 1)
7415 err = self.statistics.get_counter('/err/nat64-out2in/ICMP packets')
7416 self.assertEqual(err - icmpn, 1)
7417 err = self.statistics.get_counter(
7418 '/err/nat64-out2in/good out2in packets processed')
7419 self.assertEqual(err - totaln, 3)
7421 bibs = self.statistics.get_counter('/nat64/total-bibs')
7422 self.assertEqual(bibs[0][0], 3)
7423 sessions = self.statistics.get_counter('/nat64/total-sessions')
7424 self.assertEqual(sessions[0][0], 3)
7427 pkts = self.create_stream_in_ip6(self.pg0, self.pg1)
7428 self.pg0.add_stream(pkts)
7429 self.pg_enable_capture(self.pg_interfaces)
7431 capture = self.pg1.get_capture(len(pkts))
7432 self.verify_capture_out(capture, nat_ip=self.nat_addr,
7433 dst_ip=self.pg1.remote_ip4)
7436 pkts = self.create_stream_out(self.pg1, dst_ip=self.nat_addr)
7437 self.pg1.add_stream(pkts)
7438 self.pg_enable_capture(self.pg_interfaces)
7440 capture = self.pg0.get_capture(len(pkts))
7441 self.verify_capture_in_ip6(capture, ip[IPv6].src, self.pg0.remote_ip6)
7443 ses_num_end = self.nat64_get_ses_num()
7445 self.assertEqual(ses_num_end - ses_num_start, 3)
7447 # tenant with specific VRF
7448 self.vapi.nat64_add_del_pool_addr_range(self.vrf1_nat_addr_n,
7449 self.vrf1_nat_addr_n,
7450 vrf_id=self.vrf1_id)
7451 self.vapi.nat64_add_del_interface(self.pg2.sw_if_index)
7453 pkts = self.create_stream_in_ip6(self.pg2, self.pg1)
7454 self.pg2.add_stream(pkts)
7455 self.pg_enable_capture(self.pg_interfaces)
7457 capture = self.pg1.get_capture(len(pkts))
7458 self.verify_capture_out(capture, nat_ip=self.vrf1_nat_addr,
7459 dst_ip=self.pg1.remote_ip4)
7461 pkts = self.create_stream_out(self.pg1, dst_ip=self.vrf1_nat_addr)
7462 self.pg1.add_stream(pkts)
7463 self.pg_enable_capture(self.pg_interfaces)
7465 capture = self.pg2.get_capture(len(pkts))
7466 self.verify_capture_in_ip6(capture, ip[IPv6].src, self.pg2.remote_ip6)
7468 def test_static(self):
7469 """ NAT64 static translation test """
7470 self.tcp_port_in = 60303
7471 self.udp_port_in = 60304
7472 self.icmp_id_in = 60305
7473 self.tcp_port_out = 60303
7474 self.udp_port_out = 60304
7475 self.icmp_id_out = 60305
7477 ses_num_start = self.nat64_get_ses_num()
7479 self.vapi.nat64_add_del_pool_addr_range(self.nat_addr_n,
7481 self.vapi.nat64_add_del_interface(self.pg0.sw_if_index)
7482 self.vapi.nat64_add_del_interface(self.pg1.sw_if_index, is_inside=0)
7484 self.vapi.nat64_add_del_static_bib(self.pg0.remote_ip6n,
7489 self.vapi.nat64_add_del_static_bib(self.pg0.remote_ip6n,
7494 self.vapi.nat64_add_del_static_bib(self.pg0.remote_ip6n,
7501 pkts = self.create_stream_in_ip6(self.pg0, self.pg1)
7502 self.pg0.add_stream(pkts)
7503 self.pg_enable_capture(self.pg_interfaces)
7505 capture = self.pg1.get_capture(len(pkts))
7506 self.verify_capture_out(capture, nat_ip=self.nat_addr,
7507 dst_ip=self.pg1.remote_ip4, same_port=True)
7510 pkts = self.create_stream_out(self.pg1, dst_ip=self.nat_addr)
7511 self.pg1.add_stream(pkts)
7512 self.pg_enable_capture(self.pg_interfaces)
7514 capture = self.pg0.get_capture(len(pkts))
7515 ip = IPv6(src=''.join(['64:ff9b::', self.pg1.remote_ip4]))
7516 self.verify_capture_in_ip6(capture, ip[IPv6].src, self.pg0.remote_ip6)
7518 ses_num_end = self.nat64_get_ses_num()
7520 self.assertEqual(ses_num_end - ses_num_start, 3)
7522 @unittest.skipUnless(running_extended_tests, "part of extended tests")
7523 def test_session_timeout(self):
7524 """ NAT64 session timeout """
7525 self.icmp_id_in = 1234
7526 self.vapi.nat64_add_del_pool_addr_range(self.nat_addr_n,
7528 self.vapi.nat64_add_del_interface(self.pg0.sw_if_index)
7529 self.vapi.nat64_add_del_interface(self.pg1.sw_if_index, is_inside=0)
7530 self.vapi.nat_set_timeouts(icmp=5, tcp_transitory=5, tcp_established=5)
7532 pkts = self.create_stream_in_ip6(self.pg0, self.pg1)
7533 self.pg0.add_stream(pkts)
7534 self.pg_enable_capture(self.pg_interfaces)
7536 capture = self.pg1.get_capture(len(pkts))
7538 ses_num_before_timeout = self.nat64_get_ses_num()
7542 # ICMP and TCP session after timeout
7543 ses_num_after_timeout = self.nat64_get_ses_num()
7544 self.assertEqual(ses_num_before_timeout - ses_num_after_timeout, 2)
7546 def test_icmp_error(self):
7547 """ NAT64 ICMP Error message translation """
7548 self.tcp_port_in = 6303
7549 self.udp_port_in = 6304
7550 self.icmp_id_in = 6305
7552 self.vapi.nat64_add_del_pool_addr_range(self.nat_addr_n,
7554 self.vapi.nat64_add_del_interface(self.pg0.sw_if_index)
7555 self.vapi.nat64_add_del_interface(self.pg1.sw_if_index, is_inside=0)
7557 # send some packets to create sessions
7558 pkts = self.create_stream_in_ip6(self.pg0, self.pg1)
7559 self.pg0.add_stream(pkts)
7560 self.pg_enable_capture(self.pg_interfaces)
7562 capture_ip4 = self.pg1.get_capture(len(pkts))
7563 self.verify_capture_out(capture_ip4,
7564 nat_ip=self.nat_addr,
7565 dst_ip=self.pg1.remote_ip4)
7567 pkts = self.create_stream_out(self.pg1, dst_ip=self.nat_addr)
7568 self.pg1.add_stream(pkts)
7569 self.pg_enable_capture(self.pg_interfaces)
7571 capture_ip6 = self.pg0.get_capture(len(pkts))
7572 ip = IPv6(src=''.join(['64:ff9b::', self.pg1.remote_ip4]))
7573 self.verify_capture_in_ip6(capture_ip6, ip[IPv6].src,
7574 self.pg0.remote_ip6)
7577 pkts = [Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
7578 IPv6(src=self.pg0.remote_ip6, dst=ip[IPv6].src) /
7579 ICMPv6DestUnreach(code=1) /
7580 packet[IPv6] for packet in capture_ip6]
7581 self.pg0.add_stream(pkts)
7582 self.pg_enable_capture(self.pg_interfaces)
7584 capture = self.pg1.get_capture(len(pkts))
7585 for packet in capture:
7587 self.assertEqual(packet[IP].src, self.nat_addr)
7588 self.assertEqual(packet[IP].dst, self.pg1.remote_ip4)
7589 self.assertEqual(packet[ICMP].type, 3)
7590 self.assertEqual(packet[ICMP].code, 13)
7591 inner = packet[IPerror]
7592 self.assertEqual(inner.src, self.pg1.remote_ip4)
7593 self.assertEqual(inner.dst, self.nat_addr)
7594 self.assert_packet_checksums_valid(packet)
7595 if inner.haslayer(TCPerror):
7596 self.assertEqual(inner[TCPerror].dport, self.tcp_port_out)
7597 elif inner.haslayer(UDPerror):
7598 self.assertEqual(inner[UDPerror].dport, self.udp_port_out)
7600 self.assertEqual(inner[ICMPerror].id, self.icmp_id_out)
7602 self.logger.error(ppp("Unexpected or invalid packet:", packet))
7606 pkts = [Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
7607 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
7608 ICMP(type=3, code=13) /
7609 packet[IP] for packet in capture_ip4]
7610 self.pg1.add_stream(pkts)
7611 self.pg_enable_capture(self.pg_interfaces)
7613 capture = self.pg0.get_capture(len(pkts))
7614 for packet in capture:
7616 self.assertEqual(packet[IPv6].src, ip.src)
7617 self.assertEqual(packet[IPv6].dst, self.pg0.remote_ip6)
7618 icmp = packet[ICMPv6DestUnreach]
7619 self.assertEqual(icmp.code, 1)
7620 inner = icmp[IPerror6]
7621 self.assertEqual(inner.src, self.pg0.remote_ip6)
7622 self.assertEqual(inner.dst, ip.src)
7623 self.assert_icmpv6_checksum_valid(packet)
7624 if inner.haslayer(TCPerror):
7625 self.assertEqual(inner[TCPerror].sport, self.tcp_port_in)
7626 elif inner.haslayer(UDPerror):
7627 self.assertEqual(inner[UDPerror].sport, self.udp_port_in)
7629 self.assertEqual(inner[ICMPv6EchoRequest].id,
7632 self.logger.error(ppp("Unexpected or invalid packet:", packet))
7635 def test_hairpinning(self):
7636 """ NAT64 hairpinning """
7638 client = self.pg0.remote_hosts[0]
7639 server = self.pg0.remote_hosts[1]
7640 server_tcp_in_port = 22
7641 server_tcp_out_port = 4022
7642 server_udp_in_port = 23
7643 server_udp_out_port = 4023
7644 client_tcp_in_port = 1234
7645 client_udp_in_port = 1235
7646 client_tcp_out_port = 0
7647 client_udp_out_port = 0
7648 ip = IPv6(src=''.join(['64:ff9b::', self.nat_addr]))
7649 nat_addr_ip6 = ip.src
7651 self.vapi.nat64_add_del_pool_addr_range(self.nat_addr_n,
7653 self.vapi.nat64_add_del_interface(self.pg0.sw_if_index)
7654 self.vapi.nat64_add_del_interface(self.pg1.sw_if_index, is_inside=0)
7656 self.vapi.nat64_add_del_static_bib(server.ip6n,
7659 server_tcp_out_port,
7661 self.vapi.nat64_add_del_static_bib(server.ip6n,
7664 server_udp_out_port,
7669 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
7670 IPv6(src=client.ip6, dst=nat_addr_ip6) /
7671 TCP(sport=client_tcp_in_port, dport=server_tcp_out_port))
7673 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
7674 IPv6(src=client.ip6, dst=nat_addr_ip6) /
7675 UDP(sport=client_udp_in_port, dport=server_udp_out_port))
7677 self.pg0.add_stream(pkts)
7678 self.pg_enable_capture(self.pg_interfaces)
7680 capture = self.pg0.get_capture(len(pkts))
7681 for packet in capture:
7683 self.assertEqual(packet[IPv6].src, nat_addr_ip6)
7684 self.assertEqual(packet[IPv6].dst, server.ip6)
7685 self.assert_packet_checksums_valid(packet)
7686 if packet.haslayer(TCP):
7687 self.assertNotEqual(packet[TCP].sport, client_tcp_in_port)
7688 self.assertEqual(packet[TCP].dport, server_tcp_in_port)
7689 client_tcp_out_port = packet[TCP].sport
7691 self.assertNotEqual(packet[UDP].sport, client_udp_in_port)
7692 self.assertEqual(packet[UDP].dport, server_udp_in_port)
7693 client_udp_out_port = packet[UDP].sport
7695 self.logger.error(ppp("Unexpected or invalid packet:", packet))
7700 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
7701 IPv6(src=server.ip6, dst=nat_addr_ip6) /
7702 TCP(sport=server_tcp_in_port, dport=client_tcp_out_port))
7704 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
7705 IPv6(src=server.ip6, dst=nat_addr_ip6) /
7706 UDP(sport=server_udp_in_port, dport=client_udp_out_port))
7708 self.pg0.add_stream(pkts)
7709 self.pg_enable_capture(self.pg_interfaces)
7711 capture = self.pg0.get_capture(len(pkts))
7712 for packet in capture:
7714 self.assertEqual(packet[IPv6].src, nat_addr_ip6)
7715 self.assertEqual(packet[IPv6].dst, client.ip6)
7716 self.assert_packet_checksums_valid(packet)
7717 if packet.haslayer(TCP):
7718 self.assertEqual(packet[TCP].sport, server_tcp_out_port)
7719 self.assertEqual(packet[TCP].dport, client_tcp_in_port)
7721 self.assertEqual(packet[UDP].sport, server_udp_out_port)
7722 self.assertEqual(packet[UDP].dport, client_udp_in_port)
7724 self.logger.error(ppp("Unexpected or invalid packet:", packet))
7729 pkts = [Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
7730 IPv6(src=client.ip6, dst=nat_addr_ip6) /
7731 ICMPv6DestUnreach(code=1) /
7732 packet[IPv6] for packet in capture]
7733 self.pg0.add_stream(pkts)
7734 self.pg_enable_capture(self.pg_interfaces)
7736 capture = self.pg0.get_capture(len(pkts))
7737 for packet in capture:
7739 self.assertEqual(packet[IPv6].src, nat_addr_ip6)
7740 self.assertEqual(packet[IPv6].dst, server.ip6)
7741 icmp = packet[ICMPv6DestUnreach]
7742 self.assertEqual(icmp.code, 1)
7743 inner = icmp[IPerror6]
7744 self.assertEqual(inner.src, server.ip6)
7745 self.assertEqual(inner.dst, nat_addr_ip6)
7746 self.assert_packet_checksums_valid(packet)
7747 if inner.haslayer(TCPerror):
7748 self.assertEqual(inner[TCPerror].sport, server_tcp_in_port)
7749 self.assertEqual(inner[TCPerror].dport,
7750 client_tcp_out_port)
7752 self.assertEqual(inner[UDPerror].sport, server_udp_in_port)
7753 self.assertEqual(inner[UDPerror].dport,
7754 client_udp_out_port)
7756 self.logger.error(ppp("Unexpected or invalid packet:", packet))
7759 def test_prefix(self):
7760 """ NAT64 Network-Specific Prefix """
7762 self.vapi.nat64_add_del_pool_addr_range(self.nat_addr_n,
7764 self.vapi.nat64_add_del_interface(self.pg0.sw_if_index)
7765 self.vapi.nat64_add_del_interface(self.pg1.sw_if_index, is_inside=0)
7766 self.vapi.nat64_add_del_pool_addr_range(self.vrf1_nat_addr_n,
7767 self.vrf1_nat_addr_n,
7768 vrf_id=self.vrf1_id)
7769 self.vapi.nat64_add_del_interface(self.pg2.sw_if_index)
7772 global_pref64 = "2001:db8::"
7773 global_pref64_n = socket.inet_pton(socket.AF_INET6, global_pref64)
7774 global_pref64_len = 32
7775 self.vapi.nat64_add_del_prefix(global_pref64_n, global_pref64_len)
7777 prefix = self.vapi.nat64_prefix_dump()
7778 self.assertEqual(len(prefix), 1)
7779 self.assertEqual(prefix[0].prefix, global_pref64_n)
7780 self.assertEqual(prefix[0].prefix_len, global_pref64_len)
7781 self.assertEqual(prefix[0].vrf_id, 0)
7783 # Add tenant specific prefix
7784 vrf1_pref64 = "2001:db8:122:300::"
7785 vrf1_pref64_n = socket.inet_pton(socket.AF_INET6, vrf1_pref64)
7786 vrf1_pref64_len = 56
7787 self.vapi.nat64_add_del_prefix(vrf1_pref64_n,
7789 vrf_id=self.vrf1_id)
7790 prefix = self.vapi.nat64_prefix_dump()
7791 self.assertEqual(len(prefix), 2)
7794 pkts = self.create_stream_in_ip6(self.pg0,
7797 plen=global_pref64_len)
7798 self.pg0.add_stream(pkts)
7799 self.pg_enable_capture(self.pg_interfaces)
7801 capture = self.pg1.get_capture(len(pkts))
7802 self.verify_capture_out(capture, nat_ip=self.nat_addr,
7803 dst_ip=self.pg1.remote_ip4)
7805 pkts = self.create_stream_out(self.pg1, dst_ip=self.nat_addr)
7806 self.pg1.add_stream(pkts)
7807 self.pg_enable_capture(self.pg_interfaces)
7809 capture = self.pg0.get_capture(len(pkts))
7810 dst_ip = self.compose_ip6(self.pg1.remote_ip4,
7813 self.verify_capture_in_ip6(capture, dst_ip, self.pg0.remote_ip6)
7815 # Tenant specific prefix
7816 pkts = self.create_stream_in_ip6(self.pg2,
7819 plen=vrf1_pref64_len)
7820 self.pg2.add_stream(pkts)
7821 self.pg_enable_capture(self.pg_interfaces)
7823 capture = self.pg1.get_capture(len(pkts))
7824 self.verify_capture_out(capture, nat_ip=self.vrf1_nat_addr,
7825 dst_ip=self.pg1.remote_ip4)
7827 pkts = self.create_stream_out(self.pg1, dst_ip=self.vrf1_nat_addr)
7828 self.pg1.add_stream(pkts)
7829 self.pg_enable_capture(self.pg_interfaces)
7831 capture = self.pg2.get_capture(len(pkts))
7832 dst_ip = self.compose_ip6(self.pg1.remote_ip4,
7835 self.verify_capture_in_ip6(capture, dst_ip, self.pg2.remote_ip6)
7837 def test_unknown_proto(self):
7838 """ NAT64 translate packet with unknown protocol """
7840 self.vapi.nat64_add_del_pool_addr_range(self.nat_addr_n,
7842 self.vapi.nat64_add_del_interface(self.pg0.sw_if_index)
7843 self.vapi.nat64_add_del_interface(self.pg1.sw_if_index, is_inside=0)
7844 remote_ip6 = self.compose_ip6(self.pg1.remote_ip4, '64:ff9b::', 96)
7847 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
7848 IPv6(src=self.pg0.remote_ip6, dst=remote_ip6) /
7849 TCP(sport=self.tcp_port_in, dport=20))
7850 self.pg0.add_stream(p)
7851 self.pg_enable_capture(self.pg_interfaces)
7853 p = self.pg1.get_capture(1)
7855 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
7856 IPv6(src=self.pg0.remote_ip6, dst=remote_ip6, nh=47) /
7858 IP(src=self.pg2.local_ip4, dst=self.pg2.remote_ip4) /
7859 TCP(sport=1234, dport=1234))
7860 self.pg0.add_stream(p)
7861 self.pg_enable_capture(self.pg_interfaces)
7863 p = self.pg1.get_capture(1)
7866 self.assertEqual(packet[IP].src, self.nat_addr)
7867 self.assertEqual(packet[IP].dst, self.pg1.remote_ip4)
7868 self.assertEqual(packet.haslayer(GRE), 1)
7869 self.assert_packet_checksums_valid(packet)
7871 self.logger.error(ppp("Unexpected or invalid packet:", packet))
7875 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
7876 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
7878 IP(src=self.pg2.remote_ip4, dst=self.pg2.local_ip4) /
7879 TCP(sport=1234, dport=1234))
7880 self.pg1.add_stream(p)
7881 self.pg_enable_capture(self.pg_interfaces)
7883 p = self.pg0.get_capture(1)
7886 self.assertEqual(packet[IPv6].src, remote_ip6)
7887 self.assertEqual(packet[IPv6].dst, self.pg0.remote_ip6)
7888 self.assertEqual(packet[IPv6].nh, 47)
7890 self.logger.error(ppp("Unexpected or invalid packet:", packet))
7893 def test_hairpinning_unknown_proto(self):
7894 """ NAT64 translate packet with unknown protocol - hairpinning """
7896 client = self.pg0.remote_hosts[0]
7897 server = self.pg0.remote_hosts[1]
7898 server_tcp_in_port = 22
7899 server_tcp_out_port = 4022
7900 client_tcp_in_port = 1234
7901 client_tcp_out_port = 1235
7902 server_nat_ip = "10.0.0.100"
7903 client_nat_ip = "10.0.0.110"
7904 server_nat_ip_n = socket.inet_pton(socket.AF_INET, server_nat_ip)
7905 client_nat_ip_n = socket.inet_pton(socket.AF_INET, client_nat_ip)
7906 server_nat_ip6 = self.compose_ip6(server_nat_ip, '64:ff9b::', 96)
7907 client_nat_ip6 = self.compose_ip6(client_nat_ip, '64:ff9b::', 96)
7909 self.vapi.nat64_add_del_pool_addr_range(server_nat_ip_n,
7911 self.vapi.nat64_add_del_interface(self.pg0.sw_if_index)
7912 self.vapi.nat64_add_del_interface(self.pg1.sw_if_index, is_inside=0)
7914 self.vapi.nat64_add_del_static_bib(server.ip6n,
7917 server_tcp_out_port,
7920 self.vapi.nat64_add_del_static_bib(server.ip6n,
7926 self.vapi.nat64_add_del_static_bib(client.ip6n,
7929 client_tcp_out_port,
7933 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
7934 IPv6(src=client.ip6, dst=server_nat_ip6) /
7935 TCP(sport=client_tcp_in_port, dport=server_tcp_out_port))
7936 self.pg0.add_stream(p)
7937 self.pg_enable_capture(self.pg_interfaces)
7939 p = self.pg0.get_capture(1)
7941 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
7942 IPv6(src=client.ip6, dst=server_nat_ip6, nh=IP_PROTOS.gre) /
7944 IP(src=self.pg2.local_ip4, dst=self.pg2.remote_ip4) /
7945 TCP(sport=1234, dport=1234))
7946 self.pg0.add_stream(p)
7947 self.pg_enable_capture(self.pg_interfaces)
7949 p = self.pg0.get_capture(1)
7952 self.assertEqual(packet[IPv6].src, client_nat_ip6)
7953 self.assertEqual(packet[IPv6].dst, server.ip6)
7954 self.assertEqual(packet[IPv6].nh, IP_PROTOS.gre)
7956 self.logger.error(ppp("Unexpected or invalid packet:", packet))
7960 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
7961 IPv6(src=server.ip6, dst=client_nat_ip6, nh=IP_PROTOS.gre) /
7963 IP(src=self.pg2.remote_ip4, dst=self.pg2.local_ip4) /
7964 TCP(sport=1234, dport=1234))
7965 self.pg0.add_stream(p)
7966 self.pg_enable_capture(self.pg_interfaces)
7968 p = self.pg0.get_capture(1)
7971 self.assertEqual(packet[IPv6].src, server_nat_ip6)
7972 self.assertEqual(packet[IPv6].dst, client.ip6)
7973 self.assertEqual(packet[IPv6].nh, IP_PROTOS.gre)
7975 self.logger.error(ppp("Unexpected or invalid packet:", packet))
7978 def test_one_armed_nat64(self):
7979 """ One armed NAT64 """
7981 remote_host_ip6 = self.compose_ip6(self.pg3.remote_ip4,
7985 self.vapi.nat64_add_del_pool_addr_range(self.nat_addr_n,
7987 self.vapi.nat64_add_del_interface(self.pg3.sw_if_index)
7988 self.vapi.nat64_add_del_interface(self.pg3.sw_if_index, is_inside=0)
7991 p = (Ether(src=self.pg3.remote_mac, dst=self.pg3.local_mac) /
7992 IPv6(src=self.pg3.remote_ip6, dst=remote_host_ip6) /
7993 TCP(sport=12345, dport=80))
7994 self.pg3.add_stream(p)
7995 self.pg_enable_capture(self.pg_interfaces)
7997 capture = self.pg3.get_capture(1)
8002 self.assertEqual(ip.src, self.nat_addr)
8003 self.assertEqual(ip.dst, self.pg3.remote_ip4)
8004 self.assertNotEqual(tcp.sport, 12345)
8005 external_port = tcp.sport
8006 self.assertEqual(tcp.dport, 80)
8007 self.assert_packet_checksums_valid(p)
8009 self.logger.error(ppp("Unexpected or invalid packet:", p))
8013 p = (Ether(src=self.pg3.remote_mac, dst=self.pg3.local_mac) /
8014 IP(src=self.pg3.remote_ip4, dst=self.nat_addr) /
8015 TCP(sport=80, dport=external_port))
8016 self.pg3.add_stream(p)
8017 self.pg_enable_capture(self.pg_interfaces)
8019 capture = self.pg3.get_capture(1)
8024 self.assertEqual(ip.src, remote_host_ip6)
8025 self.assertEqual(ip.dst, self.pg3.remote_ip6)
8026 self.assertEqual(tcp.sport, 80)
8027 self.assertEqual(tcp.dport, 12345)
8028 self.assert_packet_checksums_valid(p)
8030 self.logger.error(ppp("Unexpected or invalid packet:", p))
8033 def test_frag_in_order(self):
8034 """ NAT64 translate fragments arriving in order """
8035 self.tcp_port_in = random.randint(1025, 65535)
8037 self.vapi.nat64_add_del_pool_addr_range(self.nat_addr_n,
8039 self.vapi.nat64_add_del_interface(self.pg0.sw_if_index)
8040 self.vapi.nat64_add_del_interface(self.pg1.sw_if_index, is_inside=0)
8042 reass = self.vapi.nat_reass_dump()
8043 reass_n_start = len(reass)
8047 pkts = self.create_stream_frag_ip6(self.pg0, self.pg1.remote_ip4,
8048 self.tcp_port_in, 20, data)
8049 self.pg0.add_stream(pkts)
8050 self.pg_enable_capture(self.pg_interfaces)
8052 frags = self.pg1.get_capture(len(pkts))
8053 p = self.reass_frags_and_verify(frags,
8055 self.pg1.remote_ip4)
8056 self.assertEqual(p[TCP].dport, 20)
8057 self.assertNotEqual(p[TCP].sport, self.tcp_port_in)
8058 self.tcp_port_out = p[TCP].sport
8059 self.assertEqual(data, p[Raw].load)
8062 data = "A" * 4 + "b" * 16 + "C" * 3
8063 pkts = self.create_stream_frag(self.pg1,
8068 self.pg1.add_stream(pkts)
8069 self.pg_enable_capture(self.pg_interfaces)
8071 frags = self.pg0.get_capture(len(pkts))
8072 src = self.compose_ip6(self.pg1.remote_ip4, '64:ff9b::', 96)
8073 p = self.reass_frags_and_verify_ip6(frags, src, self.pg0.remote_ip6)
8074 self.assertEqual(p[TCP].sport, 20)
8075 self.assertEqual(p[TCP].dport, self.tcp_port_in)
8076 self.assertEqual(data, p[Raw].load)
8078 reass = self.vapi.nat_reass_dump()
8079 reass_n_end = len(reass)
8081 self.assertEqual(reass_n_end - reass_n_start, 2)
8083 def test_reass_hairpinning(self):
8084 """ NAT64 fragments hairpinning """
8086 server = self.pg0.remote_hosts[1]
8087 server_in_port = random.randint(1025, 65535)
8088 server_out_port = random.randint(1025, 65535)
8089 client_in_port = random.randint(1025, 65535)
8090 ip = IPv6(src=''.join(['64:ff9b::', self.nat_addr]))
8091 nat_addr_ip6 = ip.src
8093 self.vapi.nat64_add_del_pool_addr_range(self.nat_addr_n,
8095 self.vapi.nat64_add_del_interface(self.pg0.sw_if_index)
8096 self.vapi.nat64_add_del_interface(self.pg1.sw_if_index, is_inside=0)
8098 # add static BIB entry for server
8099 self.vapi.nat64_add_del_static_bib(server.ip6n,
8105 # send packet from host to server
8106 pkts = self.create_stream_frag_ip6(self.pg0,
8111 self.pg0.add_stream(pkts)
8112 self.pg_enable_capture(self.pg_interfaces)
8114 frags = self.pg0.get_capture(len(pkts))
8115 p = self.reass_frags_and_verify_ip6(frags, nat_addr_ip6, server.ip6)
8116 self.assertNotEqual(p[TCP].sport, client_in_port)
8117 self.assertEqual(p[TCP].dport, server_in_port)
8118 self.assertEqual(data, p[Raw].load)
8120 def test_frag_out_of_order(self):
8121 """ NAT64 translate fragments arriving out of order """
8122 self.tcp_port_in = random.randint(1025, 65535)
8124 self.vapi.nat64_add_del_pool_addr_range(self.nat_addr_n,
8126 self.vapi.nat64_add_del_interface(self.pg0.sw_if_index)
8127 self.vapi.nat64_add_del_interface(self.pg1.sw_if_index, is_inside=0)
8131 pkts = self.create_stream_frag_ip6(self.pg0, self.pg1.remote_ip4,
8132 self.tcp_port_in, 20, data)
8134 self.pg0.add_stream(pkts)
8135 self.pg_enable_capture(self.pg_interfaces)
8137 frags = self.pg1.get_capture(len(pkts))
8138 p = self.reass_frags_and_verify(frags,
8140 self.pg1.remote_ip4)
8141 self.assertEqual(p[TCP].dport, 20)
8142 self.assertNotEqual(p[TCP].sport, self.tcp_port_in)
8143 self.tcp_port_out = p[TCP].sport
8144 self.assertEqual(data, p[Raw].load)
8147 data = "A" * 4 + "B" * 16 + "C" * 3
8148 pkts = self.create_stream_frag(self.pg1,
8154 self.pg1.add_stream(pkts)
8155 self.pg_enable_capture(self.pg_interfaces)
8157 frags = self.pg0.get_capture(len(pkts))
8158 src = self.compose_ip6(self.pg1.remote_ip4, '64:ff9b::', 96)
8159 p = self.reass_frags_and_verify_ip6(frags, src, self.pg0.remote_ip6)
8160 self.assertEqual(p[TCP].sport, 20)
8161 self.assertEqual(p[TCP].dport, self.tcp_port_in)
8162 self.assertEqual(data, p[Raw].load)
8164 def test_interface_addr(self):
8165 """ Acquire NAT64 pool addresses from interface """
8166 self.vapi.nat64_add_del_interface_addr(self.pg4.sw_if_index)
8168 # no address in NAT64 pool
8169 adresses = self.vapi.nat44_address_dump()
8170 self.assertEqual(0, len(adresses))
8172 # configure interface address and check NAT64 address pool
8173 self.pg4.config_ip4()
8174 addresses = self.vapi.nat64_pool_addr_dump()
8175 self.assertEqual(len(addresses), 1)
8176 self.assertEqual(addresses[0].address, self.pg4.local_ip4n)
8178 # remove interface address and check NAT64 address pool
8179 self.pg4.unconfig_ip4()
8180 addresses = self.vapi.nat64_pool_addr_dump()
8181 self.assertEqual(0, len(adresses))
8183 @unittest.skipUnless(running_extended_tests, "part of extended tests")
8184 def test_ipfix_max_bibs_sessions(self):
8185 """ IPFIX logging maximum session and BIB entries exceeded """
8188 remote_host_ip6 = self.compose_ip6(self.pg1.remote_ip4,
8192 self.vapi.nat64_add_del_pool_addr_range(self.nat_addr_n,
8194 self.vapi.nat64_add_del_interface(self.pg0.sw_if_index)
8195 self.vapi.nat64_add_del_interface(self.pg1.sw_if_index, is_inside=0)
8199 for i in range(0, max_bibs):
8200 src = "fd01:aa::%x" % (i)
8201 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
8202 IPv6(src=src, dst=remote_host_ip6) /
8203 TCP(sport=12345, dport=80))
8205 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
8206 IPv6(src=src, dst=remote_host_ip6) /
8207 TCP(sport=12345, dport=22))
8209 self.pg0.add_stream(pkts)
8210 self.pg_enable_capture(self.pg_interfaces)
8212 self.pg1.get_capture(max_sessions)
8214 self.vapi.set_ipfix_exporter(collector_address=self.pg3.remote_ip4n,
8215 src_address=self.pg3.local_ip4n,
8217 template_interval=10)
8218 self.vapi.nat_ipfix_enable_disable(domain_id=self.ipfix_domain_id,
8219 src_port=self.ipfix_src_port)
8221 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
8222 IPv6(src=src, dst=remote_host_ip6) /
8223 TCP(sport=12345, dport=25))
8224 self.pg0.add_stream(p)
8225 self.pg_enable_capture(self.pg_interfaces)
8227 self.pg1.assert_nothing_captured()
8229 self.vapi.cli("ipfix flush") # FIXME this should be an API call
8230 capture = self.pg3.get_capture(9)
8231 ipfix = IPFIXDecoder()
8232 # first load template
8234 self.assertTrue(p.haslayer(IPFIX))
8235 self.assertEqual(p[IP].src, self.pg3.local_ip4)
8236 self.assertEqual(p[IP].dst, self.pg3.remote_ip4)
8237 self.assertEqual(p[UDP].sport, self.ipfix_src_port)
8238 self.assertEqual(p[UDP].dport, 4739)
8239 self.assertEqual(p[IPFIX].observationDomainID,
8240 self.ipfix_domain_id)
8241 if p.haslayer(Template):
8242 ipfix.add_template(p.getlayer(Template))
8243 # verify events in data set
8245 if p.haslayer(Data):
8246 data = ipfix.decode_data_set(p.getlayer(Set))
8247 self.verify_ipfix_max_sessions(data, max_sessions)
8249 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
8250 IPv6(src=self.pg0.remote_ip6, dst=remote_host_ip6) /
8251 TCP(sport=12345, dport=80))
8252 self.pg0.add_stream(p)
8253 self.pg_enable_capture(self.pg_interfaces)
8255 self.pg1.assert_nothing_captured()
8257 self.vapi.cli("ipfix flush") # FIXME this should be an API call
8258 capture = self.pg3.get_capture(1)
8259 # verify events in data set
8261 self.assertTrue(p.haslayer(IPFIX))
8262 self.assertEqual(p[IP].src, self.pg3.local_ip4)
8263 self.assertEqual(p[IP].dst, self.pg3.remote_ip4)
8264 self.assertEqual(p[UDP].sport, self.ipfix_src_port)
8265 self.assertEqual(p[UDP].dport, 4739)
8266 self.assertEqual(p[IPFIX].observationDomainID,
8267 self.ipfix_domain_id)
8268 if p.haslayer(Data):
8269 data = ipfix.decode_data_set(p.getlayer(Set))
8270 self.verify_ipfix_max_bibs(data, max_bibs)
8272 def test_ipfix_max_frags(self):
8273 """ IPFIX logging maximum fragments pending reassembly exceeded """
8274 self.vapi.nat64_add_del_pool_addr_range(self.nat_addr_n,
8276 self.vapi.nat64_add_del_interface(self.pg0.sw_if_index)
8277 self.vapi.nat64_add_del_interface(self.pg1.sw_if_index, is_inside=0)
8278 self.vapi.nat_set_reass(max_frag=1, is_ip6=1)
8279 self.vapi.set_ipfix_exporter(collector_address=self.pg3.remote_ip4n,
8280 src_address=self.pg3.local_ip4n,
8282 template_interval=10)
8283 self.vapi.nat_ipfix_enable_disable(domain_id=self.ipfix_domain_id,
8284 src_port=self.ipfix_src_port)
8287 pkts = self.create_stream_frag_ip6(self.pg0, self.pg1.remote_ip4,
8288 self.tcp_port_in, 20, data)
8290 self.pg0.add_stream(pkts)
8291 self.pg_enable_capture(self.pg_interfaces)
8293 self.pg1.assert_nothing_captured()
8295 self.vapi.cli("ipfix flush") # FIXME this should be an API call
8296 capture = self.pg3.get_capture(9)
8297 ipfix = IPFIXDecoder()
8298 # first load template
8300 self.assertTrue(p.haslayer(IPFIX))
8301 self.assertEqual(p[IP].src, self.pg3.local_ip4)
8302 self.assertEqual(p[IP].dst, self.pg3.remote_ip4)
8303 self.assertEqual(p[UDP].sport, self.ipfix_src_port)
8304 self.assertEqual(p[UDP].dport, 4739)
8305 self.assertEqual(p[IPFIX].observationDomainID,
8306 self.ipfix_domain_id)
8307 if p.haslayer(Template):
8308 ipfix.add_template(p.getlayer(Template))
8309 # verify events in data set
8311 if p.haslayer(Data):
8312 data = ipfix.decode_data_set(p.getlayer(Set))
8313 self.verify_ipfix_max_fragments_ip6(data, 1,
8314 self.pg0.remote_ip6n)
8316 def test_ipfix_bib_ses(self):
8317 """ IPFIX logging NAT64 BIB/session create and delete events """
8318 self.tcp_port_in = random.randint(1025, 65535)
8319 remote_host_ip6 = self.compose_ip6(self.pg1.remote_ip4,
8323 self.vapi.nat64_add_del_pool_addr_range(self.nat_addr_n,
8325 self.vapi.nat64_add_del_interface(self.pg0.sw_if_index)
8326 self.vapi.nat64_add_del_interface(self.pg1.sw_if_index, is_inside=0)
8327 self.vapi.set_ipfix_exporter(collector_address=self.pg3.remote_ip4n,
8328 src_address=self.pg3.local_ip4n,
8330 template_interval=10)
8331 self.vapi.nat_ipfix_enable_disable(domain_id=self.ipfix_domain_id,
8332 src_port=self.ipfix_src_port)
8335 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
8336 IPv6(src=self.pg0.remote_ip6, dst=remote_host_ip6) /
8337 TCP(sport=self.tcp_port_in, dport=25))
8338 self.pg0.add_stream(p)
8339 self.pg_enable_capture(self.pg_interfaces)
8341 p = self.pg1.get_capture(1)
8342 self.tcp_port_out = p[0][TCP].sport
8343 self.vapi.cli("ipfix flush") # FIXME this should be an API call
8344 capture = self.pg3.get_capture(10)
8345 ipfix = IPFIXDecoder()
8346 # first load template
8348 self.assertTrue(p.haslayer(IPFIX))
8349 self.assertEqual(p[IP].src, self.pg3.local_ip4)
8350 self.assertEqual(p[IP].dst, self.pg3.remote_ip4)
8351 self.assertEqual(p[UDP].sport, self.ipfix_src_port)
8352 self.assertEqual(p[UDP].dport, 4739)
8353 self.assertEqual(p[IPFIX].observationDomainID,
8354 self.ipfix_domain_id)
8355 if p.haslayer(Template):
8356 ipfix.add_template(p.getlayer(Template))
8357 # verify events in data set
8359 if p.haslayer(Data):
8360 data = ipfix.decode_data_set(p.getlayer(Set))
8361 if ord(data[0][230]) == 10:
8362 self.verify_ipfix_bib(data, 1, self.pg0.remote_ip6n)
8363 elif ord(data[0][230]) == 6:
8364 self.verify_ipfix_nat64_ses(data,
8366 self.pg0.remote_ip6n,
8367 self.pg1.remote_ip4,
8370 self.logger.error(ppp("Unexpected or invalid packet: ", p))
8373 self.pg_enable_capture(self.pg_interfaces)
8374 self.vapi.nat64_add_del_pool_addr_range(self.nat_addr_n,
8377 self.vapi.cli("ipfix flush") # FIXME this should be an API call
8378 capture = self.pg3.get_capture(2)
8379 # verify events in data set
8381 self.assertTrue(p.haslayer(IPFIX))
8382 self.assertEqual(p[IP].src, self.pg3.local_ip4)
8383 self.assertEqual(p[IP].dst, self.pg3.remote_ip4)
8384 self.assertEqual(p[UDP].sport, self.ipfix_src_port)
8385 self.assertEqual(p[UDP].dport, 4739)
8386 self.assertEqual(p[IPFIX].observationDomainID,
8387 self.ipfix_domain_id)
8388 if p.haslayer(Data):
8389 data = ipfix.decode_data_set(p.getlayer(Set))
8390 if ord(data[0][230]) == 11:
8391 self.verify_ipfix_bib(data, 0, self.pg0.remote_ip6n)
8392 elif ord(data[0][230]) == 7:
8393 self.verify_ipfix_nat64_ses(data,
8395 self.pg0.remote_ip6n,
8396 self.pg1.remote_ip4,
8399 self.logger.error(ppp("Unexpected or invalid packet: ", p))
8401 def test_syslog_sess(self):
8402 """ Test syslog session creation and deletion """
8403 self.tcp_port_in = random.randint(1025, 65535)
8404 remote_host_ip6 = self.compose_ip6(self.pg1.remote_ip4,
8408 self.vapi.nat64_add_del_pool_addr_range(self.nat_addr_n,
8410 self.vapi.nat64_add_del_interface(self.pg0.sw_if_index)
8411 self.vapi.nat64_add_del_interface(self.pg1.sw_if_index, is_inside=0)
8412 self.vapi.syslog_set_filter(SYSLOG_SEVERITY.INFO)
8413 self.vapi.syslog_set_sender(self.pg3.local_ip4n, self.pg3.remote_ip4n)
8415 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
8416 IPv6(src=self.pg0.remote_ip6, dst=remote_host_ip6) /
8417 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port))
8418 self.pg0.add_stream(p)
8419 self.pg_enable_capture(self.pg_interfaces)
8421 p = self.pg1.get_capture(1)
8422 self.tcp_port_out = p[0][TCP].sport
8423 capture = self.pg3.get_capture(1)
8424 self.verify_syslog_sess(capture[0][Raw].load, is_ip6=True)
8426 self.pg_enable_capture(self.pg_interfaces)
8428 self.vapi.nat64_add_del_pool_addr_range(self.nat_addr_n,
8431 capture = self.pg3.get_capture(1)
8432 self.verify_syslog_sess(capture[0][Raw].load, False, True)
8434 def nat64_get_ses_num(self):
8436 Return number of active NAT64 sessions.
8438 st = self.vapi.nat64_st_dump()
8441 def clear_nat64(self):
8443 Clear NAT64 configuration.
8445 self.vapi.nat_ipfix_enable_disable(enable=0,
8446 src_port=self.ipfix_src_port,
8447 domain_id=self.ipfix_domain_id)
8448 self.ipfix_src_port = 4739
8449 self.ipfix_domain_id = 1
8451 self.vapi.syslog_set_filter(SYSLOG_SEVERITY.EMERG)
8453 self.vapi.nat_set_timeouts()
8455 interfaces = self.vapi.nat64_interface_dump()
8456 for intf in interfaces:
8457 if intf.is_inside > 1:
8458 self.vapi.nat64_add_del_interface(intf.sw_if_index,
8461 self.vapi.nat64_add_del_interface(intf.sw_if_index,
8465 bib = self.vapi.nat64_bib_dump(255)
8468 self.vapi.nat64_add_del_static_bib(bibe.i_addr,
8476 adresses = self.vapi.nat64_pool_addr_dump()
8477 for addr in adresses:
8478 self.vapi.nat64_add_del_pool_addr_range(addr.address,
8483 prefixes = self.vapi.nat64_prefix_dump()
8484 for prefix in prefixes:
8485 self.vapi.nat64_add_del_prefix(prefix.prefix,
8487 vrf_id=prefix.vrf_id,
8490 bibs = self.statistics.get_counter('/nat64/total-bibs')
8491 self.assertEqual(bibs[0][0], 0)
8492 sessions = self.statistics.get_counter('/nat64/total-sessions')
8493 self.assertEqual(sessions[0][0], 0)
8496 super(TestNAT64, self).tearDown()
8497 if not self.vpp_dead:
8498 self.logger.info(self.vapi.cli("show nat64 pool"))
8499 self.logger.info(self.vapi.cli("show nat64 interfaces"))
8500 self.logger.info(self.vapi.cli("show nat64 prefix"))
8501 self.logger.info(self.vapi.cli("show nat64 bib all"))
8502 self.logger.info(self.vapi.cli("show nat64 session table all"))
8503 self.logger.info(self.vapi.cli("show nat virtual-reassembly"))
8507 class TestDSlite(MethodHolder):
8508 """ DS-Lite Test Cases """
8511 def setUpClass(cls):
8512 super(TestDSlite, cls).setUpClass()
8515 cls.nat_addr = '10.0.0.3'
8516 cls.nat_addr_n = socket.inet_pton(socket.AF_INET, cls.nat_addr)
8518 cls.create_pg_interfaces(range(3))
8520 cls.pg0.config_ip4()
8521 cls.pg0.resolve_arp()
8523 cls.pg1.config_ip6()
8524 cls.pg1.generate_remote_hosts(2)
8525 cls.pg1.configure_ipv6_neighbors()
8527 cls.pg2.config_ip4()
8528 cls.pg2.resolve_arp()
8531 super(TestDSlite, cls).tearDownClass()
8534 def verify_syslog_apmadd(self, data, isaddr, isport, xsaddr, xsport,
8536 message = data.decode('utf-8')
8538 message = SyslogMessage.parse(message)
8539 except ParseError as e:
8540 self.logger.error(e)
8542 self.assertEqual(message.severity, SyslogSeverity.info)
8543 self.assertEqual(message.appname, 'NAT')
8544 self.assertEqual(message.msgid, 'APMADD')
8545 sd_params = message.sd.get('napmap')
8546 self.assertTrue(sd_params is not None)
8547 self.assertEqual(sd_params.get('IATYP'), 'IPv4')
8548 self.assertEqual(sd_params.get('ISADDR'), isaddr)
8549 self.assertEqual(sd_params.get('ISPORT'), "%d" % isport)
8550 self.assertEqual(sd_params.get('XATYP'), 'IPv4')
8551 self.assertEqual(sd_params.get('XSADDR'), xsaddr)
8552 self.assertEqual(sd_params.get('XSPORT'), "%d" % xsport)
8553 self.assertEqual(sd_params.get('PROTO'), "%d" % proto)
8554 self.assertTrue(sd_params.get('SSUBIX') is not None)
8555 self.assertEqual(sd_params.get('SV6ENC'), sv6enc)
8557 def test_dslite(self):
8558 """ Test DS-Lite """
8559 nat_config = self.vapi.nat_show_config()
8560 self.assertEqual(0, nat_config.dslite_ce)
8562 self.vapi.dslite_add_del_pool_addr_range(self.nat_addr_n,
8564 aftr_ip4 = '192.0.0.1'
8565 aftr_ip4_n = socket.inet_pton(socket.AF_INET, aftr_ip4)
8566 aftr_ip6 = '2001:db8:85a3::8a2e:370:1'
8567 aftr_ip6_n = socket.inet_pton(socket.AF_INET6, aftr_ip6)
8568 self.vapi.dslite_set_aftr_addr(aftr_ip6_n, aftr_ip4_n)
8569 self.vapi.syslog_set_sender(self.pg2.local_ip4n, self.pg2.remote_ip4n)
8572 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
8573 IPv6(dst=aftr_ip6, src=self.pg1.remote_hosts[0].ip6) /
8574 IP(dst=self.pg0.remote_ip4, src='192.168.1.1') /
8575 UDP(sport=20000, dport=10000))
8576 self.pg1.add_stream(p)
8577 self.pg_enable_capture(self.pg_interfaces)
8579 capture = self.pg0.get_capture(1)
8580 capture = capture[0]
8581 self.assertFalse(capture.haslayer(IPv6))
8582 self.assertEqual(capture[IP].src, self.nat_addr)
8583 self.assertEqual(capture[IP].dst, self.pg0.remote_ip4)
8584 self.assertNotEqual(capture[UDP].sport, 20000)
8585 self.assertEqual(capture[UDP].dport, 10000)
8586 self.assert_packet_checksums_valid(capture)
8587 out_port = capture[UDP].sport
8588 capture = self.pg2.get_capture(1)
8589 self.verify_syslog_apmadd(capture[0][Raw].load, '192.168.1.1',
8590 20000, self.nat_addr, out_port,
8591 self.pg1.remote_hosts[0].ip6, IP_PROTOS.udp)
8593 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
8594 IP(dst=self.nat_addr, src=self.pg0.remote_ip4) /
8595 UDP(sport=10000, dport=out_port))
8596 self.pg0.add_stream(p)
8597 self.pg_enable_capture(self.pg_interfaces)
8599 capture = self.pg1.get_capture(1)
8600 capture = capture[0]
8601 self.assertEqual(capture[IPv6].src, aftr_ip6)
8602 self.assertEqual(capture[IPv6].dst, self.pg1.remote_hosts[0].ip6)
8603 self.assertEqual(capture[IP].src, self.pg0.remote_ip4)
8604 self.assertEqual(capture[IP].dst, '192.168.1.1')
8605 self.assertEqual(capture[UDP].sport, 10000)
8606 self.assertEqual(capture[UDP].dport, 20000)
8607 self.assert_packet_checksums_valid(capture)
8610 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
8611 IPv6(dst=aftr_ip6, src=self.pg1.remote_hosts[1].ip6) /
8612 IP(dst=self.pg0.remote_ip4, src='192.168.1.1') /
8613 TCP(sport=20001, dport=10001))
8614 self.pg1.add_stream(p)
8615 self.pg_enable_capture(self.pg_interfaces)
8617 capture = self.pg0.get_capture(1)
8618 capture = capture[0]
8619 self.assertFalse(capture.haslayer(IPv6))
8620 self.assertEqual(capture[IP].src, self.nat_addr)
8621 self.assertEqual(capture[IP].dst, self.pg0.remote_ip4)
8622 self.assertNotEqual(capture[TCP].sport, 20001)
8623 self.assertEqual(capture[TCP].dport, 10001)
8624 self.assert_packet_checksums_valid(capture)
8625 out_port = capture[TCP].sport
8627 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
8628 IP(dst=self.nat_addr, src=self.pg0.remote_ip4) /
8629 TCP(sport=10001, dport=out_port))
8630 self.pg0.add_stream(p)
8631 self.pg_enable_capture(self.pg_interfaces)
8633 capture = self.pg1.get_capture(1)
8634 capture = capture[0]
8635 self.assertEqual(capture[IPv6].src, aftr_ip6)
8636 self.assertEqual(capture[IPv6].dst, self.pg1.remote_hosts[1].ip6)
8637 self.assertEqual(capture[IP].src, self.pg0.remote_ip4)
8638 self.assertEqual(capture[IP].dst, '192.168.1.1')
8639 self.assertEqual(capture[TCP].sport, 10001)
8640 self.assertEqual(capture[TCP].dport, 20001)
8641 self.assert_packet_checksums_valid(capture)
8644 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
8645 IPv6(dst=aftr_ip6, src=self.pg1.remote_hosts[1].ip6) /
8646 IP(dst=self.pg0.remote_ip4, src='192.168.1.1') /
8647 ICMP(id=4000, type='echo-request'))
8648 self.pg1.add_stream(p)
8649 self.pg_enable_capture(self.pg_interfaces)
8651 capture = self.pg0.get_capture(1)
8652 capture = capture[0]
8653 self.assertFalse(capture.haslayer(IPv6))
8654 self.assertEqual(capture[IP].src, self.nat_addr)
8655 self.assertEqual(capture[IP].dst, self.pg0.remote_ip4)
8656 self.assertNotEqual(capture[ICMP].id, 4000)
8657 self.assert_packet_checksums_valid(capture)
8658 out_id = capture[ICMP].id
8660 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
8661 IP(dst=self.nat_addr, src=self.pg0.remote_ip4) /
8662 ICMP(id=out_id, type='echo-reply'))
8663 self.pg0.add_stream(p)
8664 self.pg_enable_capture(self.pg_interfaces)
8666 capture = self.pg1.get_capture(1)
8667 capture = capture[0]
8668 self.assertEqual(capture[IPv6].src, aftr_ip6)
8669 self.assertEqual(capture[IPv6].dst, self.pg1.remote_hosts[1].ip6)
8670 self.assertEqual(capture[IP].src, self.pg0.remote_ip4)
8671 self.assertEqual(capture[IP].dst, '192.168.1.1')
8672 self.assertEqual(capture[ICMP].id, 4000)
8673 self.assert_packet_checksums_valid(capture)
8675 # ping DS-Lite AFTR tunnel endpoint address
8676 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
8677 IPv6(src=self.pg1.remote_hosts[1].ip6, dst=aftr_ip6) /
8678 ICMPv6EchoRequest())
8679 self.pg1.add_stream(p)
8680 self.pg_enable_capture(self.pg_interfaces)
8682 capture = self.pg1.get_capture(1)
8683 capture = capture[0]
8684 self.assertEqual(capture[IPv6].src, aftr_ip6)
8685 self.assertEqual(capture[IPv6].dst, self.pg1.remote_hosts[1].ip6)
8686 self.assertTrue(capture.haslayer(ICMPv6EchoReply))
8688 b4s = self.statistics.get_counter('/dslite/total-b4s')
8689 self.assertEqual(b4s[0][0], 2)
8690 sessions = self.statistics.get_counter('/dslite/total-sessions')
8691 self.assertEqual(sessions[0][0], 3)
8694 super(TestDSlite, self).tearDown()
8695 if not self.vpp_dead:
8696 self.logger.info(self.vapi.cli("show dslite pool"))
8698 self.vapi.cli("show dslite aftr-tunnel-endpoint-address"))
8699 self.logger.info(self.vapi.cli("show dslite sessions"))
8702 class TestDSliteCE(MethodHolder):
8703 """ DS-Lite CE Test Cases """
8706 def setUpConstants(cls):
8707 super(TestDSliteCE, cls).setUpConstants()
8708 cls.vpp_cmdline.extend(["nat", "{", "dslite ce", "}"])
8711 def setUpClass(cls):
8712 super(TestDSliteCE, cls).setUpClass()
8715 cls.create_pg_interfaces(range(2))
8717 cls.pg0.config_ip4()
8718 cls.pg0.resolve_arp()
8720 cls.pg1.config_ip6()
8721 cls.pg1.generate_remote_hosts(1)
8722 cls.pg1.configure_ipv6_neighbors()
8725 super(TestDSliteCE, cls).tearDownClass()
8728 def test_dslite_ce(self):
8729 """ Test DS-Lite CE """
8731 nat_config = self.vapi.nat_show_config()
8732 self.assertEqual(1, nat_config.dslite_ce)
8734 b4_ip4 = '192.0.0.2'
8735 b4_ip4_n = socket.inet_pton(socket.AF_INET, b4_ip4)
8736 b4_ip6 = '2001:db8:62aa::375e:f4c1:1'
8737 b4_ip6_n = socket.inet_pton(socket.AF_INET6, b4_ip6)
8738 self.vapi.dslite_set_b4_addr(b4_ip6_n, b4_ip4_n)
8740 aftr_ip4 = '192.0.0.1'
8741 aftr_ip4_n = socket.inet_pton(socket.AF_INET, aftr_ip4)
8742 aftr_ip6 = '2001:db8:85a3::8a2e:370:1'
8743 aftr_ip6_n = socket.inet_pton(socket.AF_INET6, aftr_ip6)
8744 self.vapi.dslite_set_aftr_addr(aftr_ip6_n, aftr_ip4_n)
8746 self.vapi.ip_add_del_route(dst_address=aftr_ip6_n,
8747 dst_address_length=128,
8748 next_hop_address=self.pg1.remote_ip6n,
8749 next_hop_sw_if_index=self.pg1.sw_if_index,
8753 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
8754 IP(dst=self.pg1.remote_ip4, src=self.pg0.remote_ip4) /
8755 UDP(sport=10000, dport=20000))
8756 self.pg0.add_stream(p)
8757 self.pg_enable_capture(self.pg_interfaces)
8759 capture = self.pg1.get_capture(1)
8760 capture = capture[0]
8761 self.assertEqual(capture[IPv6].src, b4_ip6)
8762 self.assertEqual(capture[IPv6].dst, aftr_ip6)
8763 self.assertEqual(capture[IP].src, self.pg0.remote_ip4)
8764 self.assertEqual(capture[IP].dst, self.pg1.remote_ip4)
8765 self.assertEqual(capture[UDP].sport, 10000)
8766 self.assertEqual(capture[UDP].dport, 20000)
8767 self.assert_packet_checksums_valid(capture)
8770 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
8771 IPv6(dst=b4_ip6, src=aftr_ip6) /
8772 IP(dst=self.pg0.remote_ip4, src=self.pg1.remote_ip4) /
8773 UDP(sport=20000, dport=10000))
8774 self.pg1.add_stream(p)
8775 self.pg_enable_capture(self.pg_interfaces)
8777 capture = self.pg0.get_capture(1)
8778 capture = capture[0]
8779 self.assertFalse(capture.haslayer(IPv6))
8780 self.assertEqual(capture[IP].src, self.pg1.remote_ip4)
8781 self.assertEqual(capture[IP].dst, self.pg0.remote_ip4)
8782 self.assertEqual(capture[UDP].sport, 20000)
8783 self.assertEqual(capture[UDP].dport, 10000)
8784 self.assert_packet_checksums_valid(capture)
8786 # ping DS-Lite B4 tunnel endpoint address
8787 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
8788 IPv6(src=self.pg1.remote_hosts[0].ip6, dst=b4_ip6) /
8789 ICMPv6EchoRequest())
8790 self.pg1.add_stream(p)
8791 self.pg_enable_capture(self.pg_interfaces)
8793 capture = self.pg1.get_capture(1)
8794 capture = capture[0]
8795 self.assertEqual(capture[IPv6].src, b4_ip6)
8796 self.assertEqual(capture[IPv6].dst, self.pg1.remote_hosts[0].ip6)
8797 self.assertTrue(capture.haslayer(ICMPv6EchoReply))
8800 super(TestDSliteCE, self).tearDown()
8801 if not self.vpp_dead:
8803 self.vapi.cli("show dslite aftr-tunnel-endpoint-address"))
8805 self.vapi.cli("show dslite b4-tunnel-endpoint-address"))
8808 class TestNAT66(MethodHolder):
8809 """ NAT66 Test Cases """
8812 def setUpClass(cls):
8813 super(TestNAT66, cls).setUpClass()
8816 cls.nat_addr = 'fd01:ff::2'
8817 cls.nat_addr_n = socket.inet_pton(socket.AF_INET6, cls.nat_addr)
8819 cls.create_pg_interfaces(range(2))
8820 cls.interfaces = list(cls.pg_interfaces)
8822 for i in cls.interfaces:
8825 i.configure_ipv6_neighbors()
8828 super(TestNAT66, cls).tearDownClass()
8831 def test_static(self):
8832 """ 1:1 NAT66 test """
8833 self.vapi.nat66_add_del_interface(self.pg0.sw_if_index)
8834 self.vapi.nat66_add_del_interface(self.pg1.sw_if_index, is_inside=0)
8835 self.vapi.nat66_add_del_static_mapping(self.pg0.remote_ip6n,
8840 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
8841 IPv6(src=self.pg0.remote_ip6, dst=self.pg1.remote_ip6) /
8844 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
8845 IPv6(src=self.pg0.remote_ip6, dst=self.pg1.remote_ip6) /
8848 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
8849 IPv6(src=self.pg0.remote_ip6, dst=self.pg1.remote_ip6) /
8850 ICMPv6EchoRequest())
8852 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
8853 IPv6(src=self.pg0.remote_ip6, dst=self.pg1.remote_ip6) /
8854 GRE() / IP() / TCP())
8856 self.pg0.add_stream(pkts)
8857 self.pg_enable_capture(self.pg_interfaces)
8859 capture = self.pg1.get_capture(len(pkts))
8860 for packet in capture:
8862 self.assertEqual(packet[IPv6].src, self.nat_addr)
8863 self.assertEqual(packet[IPv6].dst, self.pg1.remote_ip6)
8864 self.assert_packet_checksums_valid(packet)
8866 self.logger.error(ppp("Unexpected or invalid packet:", packet))
8871 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
8872 IPv6(src=self.pg1.remote_ip6, dst=self.nat_addr) /
8875 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
8876 IPv6(src=self.pg1.remote_ip6, dst=self.nat_addr) /
8879 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
8880 IPv6(src=self.pg1.remote_ip6, dst=self.nat_addr) /
8883 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
8884 IPv6(src=self.pg1.remote_ip6, dst=self.nat_addr) /
8885 GRE() / IP() / TCP())
8887 self.pg1.add_stream(pkts)
8888 self.pg_enable_capture(self.pg_interfaces)
8890 capture = self.pg0.get_capture(len(pkts))
8891 for packet in capture:
8893 self.assertEqual(packet[IPv6].src, self.pg1.remote_ip6)
8894 self.assertEqual(packet[IPv6].dst, self.pg0.remote_ip6)
8895 self.assert_packet_checksums_valid(packet)
8897 self.logger.error(ppp("Unexpected or invalid packet:", packet))
8900 sm = self.vapi.nat66_static_mapping_dump()
8901 self.assertEqual(len(sm), 1)
8902 self.assertEqual(sm[0].total_pkts, 8)
8904 def test_check_no_translate(self):
8905 """ NAT66 translate only when egress interface is outside interface """
8906 self.vapi.nat66_add_del_interface(self.pg0.sw_if_index)
8907 self.vapi.nat66_add_del_interface(self.pg1.sw_if_index)
8908 self.vapi.nat66_add_del_static_mapping(self.pg0.remote_ip6n,
8912 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
8913 IPv6(src=self.pg0.remote_ip6, dst=self.pg1.remote_ip6) /
8915 self.pg0.add_stream([p])
8916 self.pg_enable_capture(self.pg_interfaces)
8918 capture = self.pg1.get_capture(1)
8921 self.assertEqual(packet[IPv6].src, self.pg0.remote_ip6)
8922 self.assertEqual(packet[IPv6].dst, self.pg1.remote_ip6)
8924 self.logger.error(ppp("Unexpected or invalid packet:", packet))
8927 def clear_nat66(self):
8929 Clear NAT66 configuration.
8931 interfaces = self.vapi.nat66_interface_dump()
8932 for intf in interfaces:
8933 self.vapi.nat66_add_del_interface(intf.sw_if_index,
8937 static_mappings = self.vapi.nat66_static_mapping_dump()
8938 for sm in static_mappings:
8939 self.vapi.nat66_add_del_static_mapping(sm.local_ip_address,
8940 sm.external_ip_address,
8945 super(TestNAT66, self).tearDown()
8946 if not self.vpp_dead:
8947 self.logger.info(self.vapi.cli("show nat66 interfaces"))
8948 self.logger.info(self.vapi.cli("show nat66 static mappings"))
8952 if __name__ == '__main__':
8953 unittest.main(testRunner=VppTestRunner)