X-Git-Url: https://gerrit.fd.io/r/gitweb?a=blobdiff_plain;f=test%2Ftest_nat.py;h=695014fe587839e8d53a5c32e98c57fe0bb88182;hb=3f2dd30b0bf7cf3d82c720d5065178c1fa628c6b;hp=e3b44859f61dcade24f1cdea766a4654b3cce82a;hpb=f7ad5cbe819533523169e8a88876b94b9f38789c;p=vpp.git diff --git a/test/test_nat.py b/test/test_nat.py index e3b44859f61..695014fe587 100644 --- a/test/test_nat.py +++ b/test/test_nat.py @@ -1806,10 +1806,36 @@ class TestNAT44(MethodHolder): self.logger.error(ppp("Unexpected or invalid packet:", p)) raise - # multiple clients + @unittest.skipUnless(running_extended_tests(), "part of extended tests") + def test_static_lb_multi_clients(self): + """ NAT44 local service load balancing - multiple clients""" + + external_addr_n = socket.inet_pton(socket.AF_INET, self.nat_addr) + external_port = 80 + local_port = 8080 + server1 = self.pg0.remote_hosts[0] + server2 = self.pg0.remote_hosts[1] + + locals = [{'addr': server1.ip4n, + 'port': local_port, + 'probability': 90}, + {'addr': server2.ip4n, + 'port': local_port, + 'probability': 10}] + + self.nat44_add_address(self.nat_addr) + self.vapi.nat44_add_del_lb_static_mapping(external_addr_n, + external_port, + IP_PROTOS.tcp, + local_num=len(locals), + locals=locals) + self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index) + self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index, + is_inside=0) + server1_n = 0 server2_n = 0 - clients = ip4_range(self.pg1.remote_ip4, 10, 20) + clients = ip4_range(self.pg1.remote_ip4, 10, 50) pkts = [] for client in clients: p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) / @@ -3327,10 +3353,91 @@ class TestNAT44(MethodHolder): raise # from local network host to external network - ext_port = 0 + pkts = self.create_stream_in(self.pg0, self.pg1) + self.pg0.add_stream(pkts) + self.pg_enable_capture(self.pg_interfaces) + self.pg_start() + capture = self.pg1.get_capture(len(pkts)) + self.verify_capture_out(capture) + pkts = self.create_stream_in(self.pg0, self.pg1) + self.pg0.add_stream(pkts) + self.pg_enable_capture(self.pg_interfaces) + self.pg_start() + capture = self.pg1.get_capture(len(pkts)) + self.verify_capture_out(capture) + + # from external network back to local network host + pkts = self.create_stream_out(self.pg1) + self.pg1.add_stream(pkts) + self.pg_enable_capture(self.pg_interfaces) + self.pg_start() + capture = self.pg0.get_capture(len(pkts)) + self.verify_capture_in(capture, self.pg0) + + def test_output_feature_and_service2(self): + """ NAT44 interface output feature and service host direct access """ + self.vapi.nat44_forwarding_enable_disable(1) + self.nat44_add_address(self.nat_addr) + self.vapi.nat44_interface_add_del_output_feature(self.pg1.sw_if_index, + is_inside=0) + + # session initiaded from service host - translate + pkts = self.create_stream_in(self.pg0, self.pg1) + self.pg0.add_stream(pkts) + self.pg_enable_capture(self.pg_interfaces) + self.pg_start() + capture = self.pg1.get_capture(len(pkts)) + self.verify_capture_out(capture) + + pkts = self.create_stream_out(self.pg1) + self.pg1.add_stream(pkts) + self.pg_enable_capture(self.pg_interfaces) + self.pg_start() + capture = self.pg0.get_capture(len(pkts)) + self.verify_capture_in(capture, self.pg0) + + tcp_port_out = self.tcp_port_out + udp_port_out = self.udp_port_out + icmp_id_out = self.icmp_id_out + + # session initiaded from remote host - do not translate + pkts = self.create_stream_out(self.pg1, + self.pg0.remote_ip4, + use_inside_ports=True) + self.pg1.add_stream(pkts) + self.pg_enable_capture(self.pg_interfaces) + self.pg_start() + capture = self.pg0.get_capture(len(pkts)) + self.verify_capture_in(capture, self.pg0) + + pkts = self.create_stream_in(self.pg0, self.pg1) + self.pg0.add_stream(pkts) + self.pg_enable_capture(self.pg_interfaces) + self.pg_start() + capture = self.pg1.get_capture(len(pkts)) + self.verify_capture_out(capture, nat_ip=self.pg0.remote_ip4, + same_port=True) + + def test_output_feature_and_service3(self): + """ NAT44 interface output feature and DST NAT """ + external_addr = '1.2.3.4' + external_port = 80 + local_port = 8080 + + self.vapi.nat44_forwarding_enable_disable(1) + self.nat44_add_address(self.nat_addr) + self.nat44_add_static_mapping(self.pg1.remote_ip4, external_addr, + local_port, external_port, + proto=IP_PROTOS.tcp, out2in_only=1) + self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index) + self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index, + is_inside=0) + self.vapi.nat44_interface_add_del_output_feature(self.pg1.sw_if_index, + is_inside=0) + p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) / - IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) / - TCP(sport=23456, dport=34567)) + IP(src=self.pg0.remote_ip4, dst=external_addr) / + TCP(sport=12345, dport=external_port)) self.pg0.add_stream(p) self.pg_enable_capture(self.pg_interfaces) self.pg_start() @@ -3339,30 +3446,31 @@ class TestNAT44(MethodHolder): try: ip = p[IP] tcp = p[TCP] - self.assertEqual(ip.src, self.nat_addr) - self.assertNotEqual(tcp.sport, 23456) - ext_port = tcp.sport + self.assertEqual(ip.src, self.pg0.remote_ip4) + self.assertEqual(tcp.sport, 12345) + self.assertEqual(ip.dst, self.pg1.remote_ip4) + self.assertEqual(tcp.dport, local_port) self.check_tcp_checksum(p) self.check_ip_checksum(p) except: self.logger.error(ppp("Unexpected or invalid packet:", p)) raise - # from external network back to local network host p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) / - IP(src=self.pg1.remote_ip4, dst=self.nat_addr) / - TCP(sport=34567, dport=ext_port)) + IP(src=self.pg1.remote_ip4, dst=self.pg0.remote_ip4) / + TCP(sport=local_port, dport=12345)) self.pg1.add_stream(p) self.pg_enable_capture(self.pg_interfaces) self.pg_start() capture = self.pg0.get_capture(1) p = capture[0] - server = None try: ip = p[IP] tcp = p[TCP] + self.assertEqual(ip.src, external_addr) + self.assertEqual(tcp.sport, external_port) self.assertEqual(ip.dst, self.pg0.remote_ip4) - self.assertEqual(tcp.dport, 23456) + self.assertEqual(tcp.dport, 12345) self.check_tcp_checksum(p) self.check_ip_checksum(p) except: @@ -6185,5 +6293,136 @@ class TestDSliteCE(MethodHolder): self.logger.info( self.vapi.cli("show dslite b4-tunnel-endpoint-address")) + +class TestNAT66(MethodHolder): + """ NAT66 Test Cases """ + + @classmethod + def setUpClass(cls): + super(TestNAT66, cls).setUpClass() + + try: + cls.nat_addr = 'fd01:ff::2' + cls.nat_addr_n = socket.inet_pton(socket.AF_INET6, cls.nat_addr) + + cls.create_pg_interfaces(range(2)) + cls.interfaces = list(cls.pg_interfaces) + + for i in cls.interfaces: + i.admin_up() + i.config_ip6() + i.configure_ipv6_neighbors() + + except Exception: + super(TestNAT66, cls).tearDownClass() + raise + + def test_static(self): + """ 1:1 NAT66 test """ + self.vapi.nat66_add_del_interface(self.pg0.sw_if_index) + self.vapi.nat66_add_del_interface(self.pg1.sw_if_index, is_inside=0) + self.vapi.nat66_add_del_static_mapping(self.pg0.remote_ip6n, + self.nat_addr_n) + + # in2out + pkts = [] + p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) / + IPv6(src=self.pg0.remote_ip6, dst=self.pg1.remote_ip6) / + TCP()) + pkts.append(p) + p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) / + IPv6(src=self.pg0.remote_ip6, dst=self.pg1.remote_ip6) / + UDP()) + pkts.append(p) + p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) / + IPv6(src=self.pg0.remote_ip6, dst=self.pg1.remote_ip6) / + ICMPv6EchoRequest()) + pkts.append(p) + p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) / + IPv6(src=self.pg0.remote_ip6, dst=self.pg1.remote_ip6) / + GRE() / IP() / TCP()) + pkts.append(p) + self.pg0.add_stream(pkts) + self.pg_enable_capture(self.pg_interfaces) + self.pg_start() + capture = self.pg1.get_capture(len(pkts)) + for packet in capture: + try: + self.assertEqual(packet[IPv6].src, self.nat_addr) + self.assertEqual(packet[IPv6].dst, self.pg1.remote_ip6) + if packet.haslayer(TCP): + self.check_tcp_checksum(packet) + elif packet.haslayer(UDP): + self.check_udp_checksum(packet) + elif packet.haslayer(ICMPv6EchoRequest): + self.check_icmpv6_checksum(packet) + except: + self.logger.error(ppp("Unexpected or invalid packet:", packet)) + raise + + # out2in + pkts = [] + p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) / + IPv6(src=self.pg1.remote_ip6, dst=self.nat_addr) / + TCP()) + pkts.append(p) + p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) / + IPv6(src=self.pg1.remote_ip6, dst=self.nat_addr) / + UDP()) + pkts.append(p) + p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) / + IPv6(src=self.pg1.remote_ip6, dst=self.nat_addr) / + ICMPv6EchoReply()) + pkts.append(p) + p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) / + IPv6(src=self.pg1.remote_ip6, dst=self.nat_addr) / + GRE() / IP() / TCP()) + pkts.append(p) + self.pg1.add_stream(pkts) + self.pg_enable_capture(self.pg_interfaces) + self.pg_start() + capture = self.pg0.get_capture(len(pkts)) + for packet in capture: + try: + self.assertEqual(packet[IPv6].src, self.pg1.remote_ip6) + self.assertEqual(packet[IPv6].dst, self.pg0.remote_ip6) + if packet.haslayer(TCP): + self.check_tcp_checksum(packet) + elif packet.haslayer(UDP): + self.check_udp_checksum(packet) + elif packet.haslayer(ICMPv6EchoReply): + self.check_icmpv6_checksum(packet) + except: + self.logger.error(ppp("Unexpected or invalid packet:", packet)) + raise + + sm = self.vapi.nat66_static_mapping_dump() + self.assertEqual(len(sm), 1) + self.assertEqual(sm[0].total_pkts, 8) + + def clear_nat66(self): + """ + Clear NAT66 configuration. + """ + interfaces = self.vapi.nat66_interface_dump() + for intf in interfaces: + self.vapi.nat66_add_del_interface(intf.sw_if_index, + intf.is_inside, + is_add=0) + + static_mappings = self.vapi.nat66_static_mapping_dump() + for sm in static_mappings: + self.vapi.nat66_add_del_static_mapping(sm.local_ip_address, + sm.external_ip_address, + sm.vrf_id, + is_add=0) + + def tearDown(self): + super(TestNAT66, self).tearDown() + if not self.vpp_dead: + self.logger.info(self.vapi.cli("show nat66 interfaces")) + self.logger.info(self.vapi.cli("show nat66 static mappings")) + self.clear_nat66() + if __name__ == '__main__': unittest.main(testRunner=VppTestRunner)