X-Git-Url: https://gerrit.fd.io/r/gitweb?a=blobdiff_plain;f=test%2Ftest_ip6.py;h=6cfb04be14266748080e684a08f7fcae2ed7d55e;hb=a5b2eec0535f9025319a752891d77ff9948ae0df;hp=849e9f73a410e2bc928b8b588fa195fae0415639;hpb=978aa643ca32ab220be940290039eb11e068bb73;p=vpp.git diff --git a/test/test_ip6.py b/test/test_ip6.py index 849e9f73a41..6cfb04be142 100644 --- a/test/test_ip6.py +++ b/test/test_ip6.py @@ -1,38 +1,40 @@ #!/usr/bin/env python -import unittest import socket +import unittest -from framework import VppTestCase, VppTestRunner -from util import ppp, ip6_normalize -from vpp_sub_interface import VppSubInterface, VppDot1QSubint -from vpp_pg_interface import is_ipv6_misc -from vpp_ip import DpoProto -from vpp_ip_route import VppIpRoute, VppRoutePath, find_route, VppIpMRoute, \ - VppMRoutePath, MRouteItfFlags, MRouteEntryFlags, VppMplsIpBind, \ - VppMplsRoute, VppMplsTable, VppIpTable, VppIpAddress -from vpp_neighbor import find_nbr, VppNeighbor - -from scapy.packet import Raw -from scapy.layers.l2 import Ether, Dot1Q +from parameterized import parameterized +import scapy.compat import scapy.layers.inet6 as inet6 +from scapy.contrib.mpls import MPLS from scapy.layers.inet6 import IPv6, ICMPv6ND_NS, ICMPv6ND_RS, \ - ICMPv6ND_RA, getmacbyip6, ICMPv6MRD_Solicitation, \ - ICMPv6NDOptMTU, ICMPv6NDOptSrcLLAddr, ICMPv6NDOptPrefixInfo, \ + ICMPv6ND_RA, ICMPv6NDOptMTU, ICMPv6NDOptSrcLLAddr, ICMPv6NDOptPrefixInfo, \ ICMPv6ND_NA, ICMPv6NDOptDstLLAddr, ICMPv6DestUnreach, icmp6types, \ ICMPv6TimeExceeded, ICMPv6EchoRequest, ICMPv6EchoReply -from scapy.utils6 import in6_getnsma, in6_getnsmac, in6_ptop, in6_islladdr, \ - in6_mactoifaceid, in6_ismaddr +from scapy.layers.l2 import Ether, Dot1Q +from scapy.packet import Raw from scapy.utils import inet_pton, inet_ntop -from scapy.contrib.mpls import MPLS +from scapy.utils6 import in6_getnsma, in6_getnsmac, in6_ptop, in6_islladdr, \ + in6_mactoifaceid +from six import moves -AF_INET6 = socket.AF_INET6 +from framework import VppTestCase, VppTestRunner +from util import ppp, ip6_normalize, mk_ll_addr +from vpp_ip import DpoProto +from vpp_ip_route import VppIpRoute, VppRoutePath, find_route, VppIpMRoute, \ + VppMRoutePath, MRouteItfFlags, MRouteEntryFlags, VppMplsIpBind, \ + VppMplsRoute, VppMplsTable, VppIpTable +from vpp_neighbor import find_nbr, VppNeighbor +from vpp_pg_interface import is_ipv6_misc +from vpp_sub_interface import VppSubInterface, VppDot1QSubint +from ipaddress import IPv6Network, IPv4Network +AF_INET6 = socket.AF_INET6 -def mk_ll_addr(mac): - euid = in6_mactoifaceid(mac) - addr = "fe80::" + euid - return addr +try: + text_type = unicode +except NameError: + text_type = str class TestIPv6ND(VppTestCase): @@ -244,8 +246,10 @@ class TestIPv6(TestIPv6ND): for i in self.interfaces: next_hop_address = i.local_ip6n for j in range(count / n_int): - self.vapi.ip_add_del_route( - dest_addr, dest_addr_len, next_hop_address, is_ipv6=1) + self.vapi.ip_add_del_route(dst_address=dest_addr, + dst_address_length=dest_addr_len, + next_hop_address=next_hop_address, + is_ipv6=1) counter += 1 if counter / count * 100 > percent: self.logger.info("Configure %d FIB entries .. %d%% done" % @@ -284,11 +288,12 @@ class TestIPv6(TestIPv6ND): inet6.UDP(sport=1234, dport=1234)) pkts = [self.modify_packet(src_if, i, pkt_tmpl) - for i in xrange(self.pg_if_packet_sizes[0], - self.pg_if_packet_sizes[1], 10)] + for i in moves.range(self.pg_if_packet_sizes[0], + self.pg_if_packet_sizes[1], 10)] pkts_b = [self.modify_packet(src_if, i, pkt_tmpl) - for i in xrange(self.pg_if_packet_sizes[1] + hdr_ext, - self.pg_if_packet_sizes[2] + hdr_ext, 50)] + for i in moves.range(self.pg_if_packet_sizes[1] + hdr_ext, + self.pg_if_packet_sizes[2] + hdr_ext, + 50)] pkts.extend(pkts_b) return pkts @@ -316,7 +321,7 @@ class TestIPv6(TestIPv6ND): try: ip = packet[IPv6] udp = packet[inet6.UDP] - payload_info = self.payload_to_info(str(packet[Raw])) + payload_info = self.payload_to_info(packet[Raw]) packet_index = payload_info.index self.assertEqual(payload_info.dst, dst_sw_if_index) self.logger.debug( @@ -443,7 +448,6 @@ class TestIPv6(TestIPv6ND): self.pg0.sw_if_index, self.pg0.remote_hosts[2].mac, self.pg0.remote_hosts[2].ip6, - af=AF_INET6, is_no_fib_entry=1) nd_entry.add_vpp_config() @@ -452,8 +456,7 @@ class TestIPv6(TestIPv6ND): # self.assertTrue(find_nbr(self, self.pg0.sw_if_index, - self.pg0._remote_hosts[2].ip6, - inet=AF_INET6)) + self.pg0._remote_hosts[2].ip6)) self.assertFalse(find_route(self, self.pg0._remote_hosts[2].ip6, 128, @@ -481,8 +484,7 @@ class TestIPv6(TestIPv6ND): # self.assertTrue(find_nbr(self, self.pg0.sw_if_index, - self.pg0._remote_hosts[2].ip6_ll, - inet=AF_INET6)) + self.pg0._remote_hosts[2].ip6_ll)) self.assertFalse(find_route(self, self.pg0._remote_hosts[2].ip6_ll, 128, @@ -509,8 +511,7 @@ class TestIPv6(TestIPv6ND): # self.assertTrue(find_nbr(self, self.pg0.sw_if_index, - self.pg0._remote_hosts[3].ip6_ll, - inet=AF_INET6)) + self.pg0._remote_hosts[3].ip6_ll)) self.assertFalse(find_route(self, self.pg0._remote_hosts[3].ip6_ll, 128, @@ -530,14 +531,12 @@ class TestIPv6(TestIPv6ND): ns_pg1 = VppNeighbor(self, self.pg1.sw_if_index, self.pg1.remote_hosts[1].mac, - self.pg1.remote_hosts[1].ip6, - af=AF_INET6) + self.pg1.remote_hosts[1].ip6) ns_pg1.add_vpp_config() ns_pg2 = VppNeighbor(self, self.pg2.sw_if_index, self.pg2.remote_mac, - self.pg1.remote_hosts[1].ip6, - af=AF_INET6) + self.pg1.remote_hosts[1].ip6) ns_pg2.add_vpp_config() # @@ -753,7 +752,7 @@ class TestIPv6(TestIPv6ND): # # Configure The RA to announce the links prefix # - self.pg0.ip6_ra_prefix(self.pg0.local_ip6n, + self.pg0.ip6_ra_prefix(self.pg0.local_ip6, self.pg0.local_ip6_prefix_len) # @@ -779,7 +778,7 @@ class TestIPv6(TestIPv6ND): # Change the prefix info to not off-link # L-flag is clear # - self.pg0.ip6_ra_prefix(self.pg0.local_ip6n, + self.pg0.ip6_ra_prefix(self.pg0.local_ip6, self.pg0.local_ip6_prefix_len, off_link=1) @@ -799,7 +798,7 @@ class TestIPv6(TestIPv6ND): # Change the prefix info to not off-link, no-autoconfig # L and A flag are clear in the advert # - self.pg0.ip6_ra_prefix(self.pg0.local_ip6n, + self.pg0.ip6_ra_prefix(self.pg0.local_ip6, self.pg0.local_ip6_prefix_len, off_link=1, no_autoconfig=1) @@ -820,7 +819,7 @@ class TestIPv6(TestIPv6ND): # Change the flag settings back to the defaults # L and A flag are set in the advert # - self.pg0.ip6_ra_prefix(self.pg0.local_ip6n, + self.pg0.ip6_ra_prefix(self.pg0.local_ip6, self.pg0.local_ip6_prefix_len) opt = ICMPv6NDOptPrefixInfo( @@ -839,7 +838,7 @@ class TestIPv6(TestIPv6ND): # Change the prefix info to not off-link, no-autoconfig # L and A flag are clear in the advert # - self.pg0.ip6_ra_prefix(self.pg0.local_ip6n, + self.pg0.ip6_ra_prefix(self.pg0.local_ip6, self.pg0.local_ip6_prefix_len, off_link=1, no_autoconfig=1) @@ -860,7 +859,7 @@ class TestIPv6(TestIPv6ND): # Use the reset to defults option to revert to defaults # L and A flag are clear in the advert # - self.pg0.ip6_ra_prefix(self.pg0.local_ip6n, + self.pg0.ip6_ra_prefix(self.pg0.local_ip6, self.pg0.local_ip6_prefix_len, use_default=1) @@ -879,7 +878,7 @@ class TestIPv6(TestIPv6ND): # # Advertise Another prefix. With no L-flag/A-flag # - self.pg0.ip6_ra_prefix(self.pg1.local_ip6n, + self.pg0.ip6_ra_prefix(self.pg1.local_ip6, self.pg1.local_ip6_prefix_len, off_link=1, no_autoconfig=1) @@ -909,7 +908,7 @@ class TestIPv6(TestIPv6ND): # Remove the first refix-info - expect the second is still in the # advert # - self.pg0.ip6_ra_prefix(self.pg0.local_ip6n, + self.pg0.ip6_ra_prefix(self.pg0.local_ip6, self.pg0.local_ip6_prefix_len, is_no=1) @@ -928,7 +927,7 @@ class TestIPv6(TestIPv6ND): # # Remove the second prefix-info - expect no prefix-info i nthe adverts # - self.pg0.ip6_ra_prefix(self.pg1.local_ip6n, + self.pg0.ip6_ra_prefix(self.pg1.local_ip6, self.pg1.local_ip6_prefix_len, is_no=1) @@ -975,7 +974,7 @@ class TestICMPv6Echo(VppTestCase): icmpv6_id = 0xb icmpv6_seq = 5 - icmpv6_data = '\x0a' * 18 + icmpv6_data = b'\x0a' * 18 p_echo_request = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) / IPv6(src=self.pg0.remote_ip6, @@ -1062,11 +1061,13 @@ class TestIPv6RD(TestIPv6ND): self.pg1.local_mac) def verify_prefix_info(self, reported_prefix, prefix_option): - prefix = socket.inet_pton(socket.AF_INET6, - prefix_option.getfieldval("prefix")) - self.assert_equal(reported_prefix.dst_address, prefix) - self.assert_equal(reported_prefix.dst_address_length, - prefix_option.getfieldval("prefixlen")) + prefix = IPv6Network( + text_type(prefix_option.getfieldval("prefix") + + "/" + + text_type(prefix_option.getfieldval("prefixlen"))), + strict=False) + self.assert_equal(reported_prefix.prefix.network_address, + prefix.network_address) L = prefix_option.getfieldval("L") A = prefix_option.getfieldval("A") option_flags = (L << 7) | (A << 6) @@ -1347,9 +1348,9 @@ class IPv6NDProxyTest(TestIPv6ND): # # Add proxy support for the host # - self.vapi.ip6_nd_proxy( - inet_pton(AF_INET6, self.pg0._remote_hosts[2].ip6), - self.pg1.sw_if_index) + self.vapi.ip6nd_proxy_add_del( + ip=inet_pton(AF_INET6, self.pg0._remote_hosts[2].ip6), + sw_if_index=self.pg1.sw_if_index) # # try that NS again. this time we expect an NA back @@ -1364,8 +1365,7 @@ class IPv6NDProxyTest(TestIPv6ND): # self.assertTrue(find_nbr(self, self.pg1.sw_if_index, - self.pg0._remote_hosts[2].ip6, - inet=AF_INET6)) + self.pg0._remote_hosts[2].ip6)) # # ... and we can route traffic to it @@ -1415,9 +1415,9 @@ class IPv6NDProxyTest(TestIPv6ND): ICMPv6NDOptSrcLLAddr( lladdr=self.pg0._remote_hosts[2].mac)) - self.vapi.ip6_nd_proxy( - inet_pton(AF_INET6, self.pg0._remote_hosts[3].ip6), - self.pg2.sw_if_index) + self.vapi.ip6nd_proxy_add_del( + ip=inet_pton(AF_INET6, self.pg0._remote_hosts[3].ip6), + sw_if_index=self.pg2.sw_if_index) self.send_and_expect_na(self.pg2, ns_pg2, "NS to proxy entry other interface", @@ -1426,8 +1426,7 @@ class IPv6NDProxyTest(TestIPv6ND): self.assertTrue(find_nbr(self, self.pg2.sw_if_index, - self.pg0._remote_hosts[3].ip6, - inet=AF_INET6)) + self.pg0._remote_hosts[3].ip6)) # # hosts can communicate. pg2->pg1 @@ -1456,23 +1455,19 @@ class IPv6NDProxyTest(TestIPv6ND): # # remove the proxy configs # - self.vapi.ip6_nd_proxy( - inet_pton(AF_INET6, self.pg0._remote_hosts[2].ip6), - self.pg1.sw_if_index, - is_del=1) - self.vapi.ip6_nd_proxy( - inet_pton(AF_INET6, self.pg0._remote_hosts[3].ip6), - self.pg2.sw_if_index, - is_del=1) + self.vapi.ip6nd_proxy_add_del( + ip=inet_pton(AF_INET6, self.pg0._remote_hosts[2].ip6), + sw_if_index=self.pg1.sw_if_index, is_del=1) + self.vapi.ip6nd_proxy_add_del( + ip=inet_pton(AF_INET6, self.pg0._remote_hosts[3].ip6), + sw_if_index=self.pg2.sw_if_index, is_del=1) self.assertFalse(find_nbr(self, self.pg2.sw_if_index, - self.pg0._remote_hosts[3].ip6, - inet=AF_INET6)) + self.pg0._remote_hosts[3].ip6)) self.assertFalse(find_nbr(self, self.pg1.sw_if_index, - self.pg0._remote_hosts[2].ip6, - inet=AF_INET6)) + self.pg0._remote_hosts[2].ip6)) # # no longer proxy-ing... @@ -1675,20 +1670,20 @@ class TestIP6LoadBalance(VppTestCase): i.disable_mpls() super(TestIP6LoadBalance, self).tearDown() - def send_and_expect_load_balancing(self, input, pkts, outputs): + def pg_send(self, input, pkts): self.vapi.cli("clear trace") input.add_stream(pkts) self.pg_enable_capture(self.pg_interfaces) self.pg_start() + + def send_and_expect_load_balancing(self, input, pkts, outputs): + self.pg_send(input, pkts) for oo in outputs: rx = oo._get_capture(1) self.assertNotEqual(0, len(rx)) def send_and_expect_one_itf(self, input, pkts, itf): - self.vapi.cli("clear trace") - input.add_stream(pkts) - self.pg_enable_capture(self.pg_interfaces) - self.pg_start() + self.pg_send(input, pkts) rx = itf.get_capture(len(pkts)) def test_ip6_load_balance(self): @@ -1811,7 +1806,8 @@ class TestIP6LoadBalance(VppTestCase): # - now only the stream with differing source address will # load-balance # - self.vapi.set_ip_flow_hash(0, is_ip6=1, src=1, dst=1, sport=0, dport=0) + self.vapi.set_ip_flow_hash(vrf_id=0, src=1, dst=1, sport=0, dport=0, + is_ipv6=1) self.send_and_expect_load_balancing(self.pg0, src_ip_pkts, [self.pg1, self.pg2]) @@ -1822,7 +1818,8 @@ class TestIP6LoadBalance(VppTestCase): # # change the flow hash config back to defaults # - self.vapi.set_ip_flow_hash(0, is_ip6=1, src=1, dst=1, sport=1, dport=1) + self.vapi.set_ip_flow_hash(vrf_id=0, src=1, dst=1, sport=1, dport=1, + is_ipv6=1) # # Recursive prefixes @@ -1948,7 +1945,7 @@ class TestIP6Punt(VppTestCase): # # Configure a punt redirect via pg1. # - nh_addr = VppIpAddress(self.pg1.remote_ip6).encode() + nh_addr = self.pg1.remote_ip6 self.vapi.ip_punt_redirect(self.pg0.sw_if_index, self.pg1.sw_if_index, nh_addr) @@ -1958,7 +1955,7 @@ class TestIP6Punt(VppTestCase): # # add a policer # - policer = self.vapi.policer_add_del("ip6-punt", 400, 0, 10, 0, + policer = self.vapi.policer_add_del(b"ip6-punt", 400, 0, 10, 0, rate_type=1) self.vapi.ip_punt_police(policer.policer_index, is_ip6=1) @@ -1976,10 +1973,10 @@ class TestIP6Punt(VppTestCase): self.assertLess(len(rx), len(pkts)) # - # remove the poilcer. back to full rx + # remove the policer. back to full rx # self.vapi.ip_punt_police(policer.policer_index, is_add=0, is_ip6=1) - self.vapi.policer_add_del("ip6-punt", 400, 0, 10, 0, + self.vapi.policer_add_del(b"ip6-punt", 400, 0, 10, 0, rate_type=1, is_add=0) self.send_and_expect(self.pg0, pkts, self.pg1) @@ -2012,7 +2009,7 @@ class TestIP6Punt(VppTestCase): # # Configure a punt redirects # - nh_addr = VppIpAddress(self.pg3.remote_ip6).encode() + nh_addr = self.pg3.remote_ip6 self.vapi.ip_punt_redirect(self.pg0.sw_if_index, self.pg3.sw_if_index, nh_addr) @@ -2021,7 +2018,7 @@ class TestIP6Punt(VppTestCase): nh_addr) self.vapi.ip_punt_redirect(self.pg2.sw_if_index, self.pg3.sw_if_index, - VppIpAddress('0::0').encode()) + '0::0') # # Dump pg0 punt redirects @@ -2038,8 +2035,8 @@ class TestIP6Punt(VppTestCase): self.assertEqual(len(punts), 3) for p in punts: self.assertEqual(p.punt.tx_sw_if_index, self.pg3.sw_if_index) - self.assertNotEqual(punts[1].punt.nh.un.ip6, self.pg3.remote_ip6) - self.assertEqual(punts[2].punt.nh.un.ip6.address, '\x00'*16) + self.assertNotEqual(punts[1].punt.nh, self.pg3.remote_ip6) + self.assertEqual(str(punts[2].punt.nh), '::') class TestIPDeag(VppTestCase): @@ -2162,7 +2159,7 @@ class TestIPDeag(VppTestCase): class TestIP6Input(VppTestCase): - """ IPv6 Input Exceptions """ + """ IPv6 Input Exception Test Cases """ def setUp(self): super(TestIP6Input, self).setUp() @@ -2180,25 +2177,10 @@ class TestIP6Input(VppTestCase): i.unconfig_ip6() i.admin_down() - def test_ip_input(self): - """ IP6 Input Exceptions """ - - # - # bad version - this is dropped - # - p_version = (Ether(src=self.pg0.remote_mac, - dst=self.pg0.local_mac) / - IPv6(src=self.pg0.remote_ip6, - dst=self.pg1.remote_ip6, - version=3) / - inet6.UDP(sport=1234, dport=1234) / - Raw('\xa5' * 100)) - - self.send_and_assert_no_replies(self.pg0, p_version * 65, - "funky version") - + def test_ip_input_icmp_reply(self): + """ IP6 Input Exception - Return ICMP (3,0) """ # - # hop limit - IMCP replies + # hop limit - ICMP replies # p_version = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) / @@ -2211,9 +2193,45 @@ class TestIP6Input(VppTestCase): rx = self.send_and_expect(self.pg0, p_version * 65, self.pg0) rx = rx[0] icmp = rx[ICMPv6TimeExceeded] - self.assertEqual(icmp.type, 3) + # 0: "hop limit exceeded in transit", - self.assertEqual(icmp.code, 0) + self.assertEqual((icmp.type, icmp.code), (3, 0)) + + icmpv6_data = '\x0a' * 18 + all_0s = "::" + all_1s = "FFFF:FFFF:FFFF:FFFF:FFFF:FFFF:FFFF:FFFF" + + @parameterized.expand([ + # Name, src, dst, l4proto, msg, timeout + ("src='iface', dst='iface'", None, None, + inet6.UDP(sport=1234, dport=1234), "funky version", None), + ("src='All 0's', dst='iface'", all_0s, None, + ICMPv6EchoRequest(id=0xb, seq=5, data=icmpv6_data), None, 0.1), + ("src='iface', dst='All 0's'", None, all_0s, + ICMPv6EchoRequest(id=0xb, seq=5, data=icmpv6_data), None, 0.1), + ("src='All 1's', dst='iface'", all_1s, None, + ICMPv6EchoRequest(id=0xb, seq=5, data=icmpv6_data), None, 0.1), + ("src='iface', dst='All 1's'", None, all_1s, + ICMPv6EchoRequest(id=0xb, seq=5, data=icmpv6_data), None, 0.1), + ("src='All 1's', dst='All 1's'", all_1s, all_1s, + ICMPv6EchoRequest(id=0xb, seq=5, data=icmpv6_data), None, 0.1), + + ]) + def test_ip_input_no_replies(self, name, src, dst, l4, msg, timeout): + + self._testMethodDoc = 'IPv6 Input Exception - %s' % name + + p_version = (Ether(src=self.pg0.remote_mac, + dst=self.pg0.local_mac) / + IPv6(src=src or self.pg0.remote_ip6, + dst=dst or self.pg1.remote_ip6, + version=3) / + l4 / + Raw('\xa5' * 100)) + + self.send_and_assert_no_replies(self.pg0, p_version * 65, + remark=msg or "", + timeout=timeout) if __name__ == '__main__':