From cbe25aab3be72154f2c706c39eeba6a77f34450f Mon Sep 17 00:00:00 2001 From: Neale Ranns Date: Mon, 30 Sep 2019 10:53:31 +0000 Subject: ip: Protocol Independent IP Neighbors Type: feature - ip-neighbour: generic neighbour handling; APIs, DBs, event handling, aging - arp: ARP protocol implementation - ip6-nd; IPv6 neighbor discovery implementation; separate ND, MLD, RA - ip6-link; manage link-local addresses - l2-arp-term; events separated from IP neighbours, since they are not the same. vnet retains just enough education to perform ND/ARP packet construction. arp and ip6-nd to be moved to plugins soon. Change-Id: I88dedd0006b299344f4c7024a0aa5baa6b9a8bbe Signed-off-by: Neale Ranns --- test/test_bond.py | 6 +- test/test_container.py | 3 +- test/test_ip4.py | 2 +- test/test_ip4_irb.py | 4 +- test/test_ip4_vrf_multi_instance.py | 6 +- test/test_ip6.py | 55 ++++++--- test/test_ip_ecmp.py | 2 +- test/test_l2bd_arp_term.py | 16 +-- test/test_mpls.py | 2 +- test/test_neighbor.py | 224 +++++++++++++++++++++++++++++++++++- test/test_ping.py | 5 +- test/test_punt.py | 1 - test/test_sixrd.py | 1 + test/test_srmpls.py | 1 - test/test_udp.py | 1 - test/vpp_neighbor.py | 7 +- test/vpp_papi_provider.py | 22 +--- 17 files changed, 289 insertions(+), 69 deletions(-) (limited to 'test') diff --git a/test/test_bond.py b/test/test_bond.py index 29ad33d7a4e..5ef865f26d4 100644 --- a/test/test_bond.py +++ b/test/test_bond.py @@ -81,7 +81,7 @@ class TestBondInterface(VppTestCase): self.logger.info(self.vapi.cli("show interface")) self.logger.info(self.vapi.cli("show interface address")) - self.logger.info(self.vapi.cli("show ip arp")) + self.logger.info(self.vapi.cli("show ip neighbors")) # enslave pg0 and pg1 to BondEthernet0 self.logger.info("bond enslave interface pg0 to BondEthernet0") @@ -116,9 +116,9 @@ class TestBondInterface(VppTestCase): # set up the static arp entries pointing to the BondEthernet0 interface # so that it does not try to resolve the ip address self.logger.info(self.vapi.cli( - "set ip arp static BondEthernet0 10.10.10.12 abcd.abcd.0002")) + "set ip neighbor static BondEthernet0 10.10.10.12 abcd.abcd.0002")) self.logger.info(self.vapi.cli( - "set ip arp static BondEthernet0 10.10.10.11 abcd.abcd.0004")) + "set ip neighbor static BondEthernet0 10.10.10.11 abcd.abcd.0004")) # clear the interface counters self.logger.info(self.vapi.cli("clear interfaces")) diff --git a/test/test_container.py b/test/test_container.py index 68a7dacbb37..474805333c5 100644 --- a/test/test_container.py +++ b/test/test_container.py @@ -47,8 +47,7 @@ class ContainerIntegrationTestCase(VppTestCase): super(ContainerIntegrationTestCase, self).tearDown() def show_commands_at_teardown(self): - self.logger.info(self.vapi.cli("show ip arp")) - self.logger.info(self.vapi.cli("show ip6 neighbors")) + self.logger.info(self.vapi.cli("show ip neighbors")) def run_basic_conn_test(self, af, acl_side): """ Basic connectivity test """ diff --git a/test/test_ip4.py b/test/test_ip4.py index 705b15154e8..46a8306815b 100644 --- a/test/test_ip4.py +++ b/test/test_ip4.py @@ -89,7 +89,7 @@ class TestIPv4(VppTestCase): super(TestIPv4, self).tearDown() def show_commands_at_teardown(self): - self.logger.info(self.vapi.cli("show ip arp")) + self.logger.info(self.vapi.cli("show ip4 neighbors")) # info(self.vapi.cli("show ip fib")) # many entries def modify_packet(self, src_if, packet_size, pkt): diff --git a/test/test_ip4_irb.py b/test/test_ip4_irb.py index 20181b0a32b..de5231c7dca 100644 --- a/test/test_ip4_irb.py +++ b/test/test_ip4_irb.py @@ -96,7 +96,7 @@ class TestIpIrb(VppTestCase): def tearDown(self): """Run standard test teardown and log ``show l2patch``, ``show l2fib verbose``,``show bridge-domain detail``, - ``show ip arp``. + ``show ip neighbors``. """ super(TestIpIrb, self).tearDown() @@ -105,7 +105,7 @@ class TestIpIrb(VppTestCase): self.logger.info(self.vapi.cli("show l2fib verbose")) self.logger.info(self.vapi.cli("show bridge-domain %s detail" % self.bd_id)) - self.logger.info(self.vapi.cli("show ip arp")) + self.logger.info(self.vapi.cli("show ip neighbors")) def create_stream(self, src_ip_if, dst_ip_if, packet_sizes): pkts = [] diff --git a/test/test_ip4_vrf_multi_instance.py b/test/test_ip4_vrf_multi_instance.py index 474ab70dc71..79e5ef72aa0 100644 --- a/test/test_ip4_vrf_multi_instance.py +++ b/test/test_ip4_vrf_multi_instance.py @@ -167,7 +167,7 @@ class TestIp4VrfMultiInst(VppTestCase): def show_commands_at_teardown(self): self.logger.info(self.vapi.ppcli("show ip fib")) - self.logger.info(self.vapi.ppcli("show ip arp")) + self.logger.info(self.vapi.ppcli("show ip4 neighbors")) def create_vrf_and_assign_interfaces(self, count, start=1): """ @@ -202,7 +202,7 @@ class TestIp4VrfMultiInst(VppTestCase): pg_if.config_ip4() pg_if.configure_ipv4_neighbors() self.logger.debug(self.vapi.ppcli("show ip fib")) - self.logger.debug(self.vapi.ppcli("show ip arp")) + self.logger.debug(self.vapi.ppcli("show ip4 neighbors")) def reset_vrf_and_remove_from_vrf_list(self, vrf_id): """ @@ -224,7 +224,7 @@ class TestIp4VrfMultiInst(VppTestCase): self.pg_not_in_vrf.append(pg_if) self.logger.info("IPv4 VRF ID %d reset finished" % vrf_id) self.logger.debug(self.vapi.ppcli("show ip fib")) - self.logger.debug(self.vapi.ppcli("show ip arp")) + self.logger.debug(self.vapi.ppcli("show ip neighbors")) self.vapi.ip_table_add_del(is_add=0, table={'table_id': vrf_id}) def create_stream(self, src_if, packet_sizes): diff --git a/test/test_ip6.py b/test/test_ip6.py index 205bea65863..f5904d9a3bd 100644 --- a/test/test_ip6.py +++ b/test/test_ip6.py @@ -137,6 +137,7 @@ class TestIPv6ND(VppTestCase): def send_and_expect_ns(self, tx_intf, rx_intf, pkts, tgt_ip, filter_out_fn=is_ipv6_misc): + self.vapi.cli("clear trace") tx_intf.add_stream(pkts) self.pg_enable_capture(self.pg_interfaces) self.pg_start() @@ -221,7 +222,6 @@ class TestIPv6(TestIPv6ND): """Run standard test teardown and log ``show ip6 neighbors``.""" for i in self.interfaces: i.unconfig_ip6() - i.ip6_disable() i.admin_down() for i in self.sub_interfaces: i.remove_vpp_config() @@ -577,9 +577,12 @@ class TestIPv6(TestIPv6ND): self.pg0.remote_ip6, self.pg1.remote_hosts[1].ip6) - def validate_ra(self, intf, rx, dst_ip=None, mtu=9000, pi_opt=None): + def validate_ra(self, intf, rx, dst_ip=None, src_ip=None, + mtu=9000, pi_opt=None): if not dst_ip: dst_ip = intf.remote_ip6 + if not src_ip: + src_ip = mk_ll_addr(intf.local_mac) # unicasted packets must come to the unicast mac self.assertEqual(rx[Ether].dst, intf.remote_mac) @@ -594,8 +597,7 @@ class TestIPv6(TestIPv6ND): # and come from the router's link local self.assertTrue(in6_islladdr(rx[IPv6].src)) - self.assertEqual(in6_ptop(rx[IPv6].src), - in6_ptop(mk_ll_addr(intf.local_mac))) + self.assertEqual(in6_ptop(rx[IPv6].src), in6_ptop(src_ip)) # it should contain the links MTU ra = rx[ICMPv6ND_RA] @@ -634,7 +636,9 @@ class TestIPv6(TestIPv6ND): def send_and_expect_ra(self, intf, pkts, remark, dst_ip=None, filter_out_fn=is_ipv6_misc, - opt=None): + opt=None, + src_ip=None): + self.vapi.cli("clear trace") intf.add_stream(pkts) self.pg_enable_capture(self.pg_interfaces) self.pg_start() @@ -642,7 +646,7 @@ class TestIPv6(TestIPv6ND): self.assertEqual(len(rx), 1) rx = rx[0] - self.validate_ra(intf, rx, dst_ip, pi_opt=opt) + self.validate_ra(intf, rx, dst_ip, src_ip=src_ip, pi_opt=opt) def test_rs(self): """ IPv6 Router Solicitation Exceptions @@ -665,8 +669,7 @@ class TestIPv6(TestIPv6ND): # - expect an RA in return # p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) / - IPv6( - dst=self.pg0.local_ip6, src=self.pg0.remote_ip6) / + IPv6(dst=self.pg0.local_ip6, src=self.pg0.remote_ip6) / ICMPv6ND_RS()) pkts = [p] self.send_and_expect_ra(self.pg0, pkts, "Genuine RS") @@ -924,10 +927,18 @@ class TestIPv6(TestIPv6ND): self.pg1.local_ip6_prefix_len), is_no=1) + # + # change the link's link local, so we know that works too. + # + self.vapi.sw_interface_ip6_set_link_local_address( + sw_if_index=self.pg0.sw_if_index, + ip="fe80::88") + self.pg0.ip6_ra_config(send_unicast=1) self.send_and_expect_ra(self.pg0, p, "RA with Prefix reverted to defaults", - dst_ip=ll) + dst_ip=ll, + src_ip="fe80::88") # # Reset the periodic advertisements back to default values @@ -1034,7 +1045,6 @@ class TestICMPv6Echo(VppTestCase): super(TestICMPv6Echo, self).tearDown() for i in self.pg_interfaces: i.unconfig_ip6() - i.ip6_disable() i.admin_down() def test_icmpv6_echo(self): @@ -1158,7 +1168,7 @@ class TestIPv6RD(TestIPv6ND): def test_rd_receive_router_advertisement(self): """ Verify events triggered by received RA packets """ - self.vapi.want_ip6_ra_events() + self.vapi.want_ip6_ra_events(enable=1) prefix_info_1 = ICMPv6NDOptPrefixInfo( prefix="1::2", @@ -1264,6 +1274,17 @@ class TestIPv6RDControlPlane(TestIPv6ND): list.append(str(entry.route.prefix.network_address)) return list + def wait_for_no_default_route(self, n_tries=50, s_time=1): + while (n_tries): + fib = self.vapi.ip_route_dump(0, True) + default_routes = self.get_default_routes(fib) + if 0 is len(default_routes): + return True + n_tries = n_tries - 1 + self.sleep(s_time) + + return False + def test_all(self): """ Test handling of SLAAC addresses and default routes """ @@ -1363,9 +1384,7 @@ class TestIPv6RDControlPlane(TestIPv6ND): self.sleep_on_vpp_time(1) # check that default route is deleted - fib = self.vapi.ip_route_dump(0, True) - default_routes = self.get_default_routes(fib) - self.assertEqual(len(default_routes), 0) + self.assertTrue(self.wait_for_no_default_route()) # check FIB still contains the SLAAC address addresses = set(self.get_interface_addresses(fib, self.pg0)) @@ -1442,7 +1461,7 @@ class IPv6NDProxyTest(TestIPv6ND): # Add proxy support for the host # self.vapi.ip6nd_proxy_add_del( - ip=inet_pton(AF_INET6, self.pg0._remote_hosts[2].ip6), + is_add=1, ip=inet_pton(AF_INET6, self.pg0._remote_hosts[2].ip6), sw_if_index=self.pg1.sw_if_index) # @@ -1509,7 +1528,7 @@ class IPv6NDProxyTest(TestIPv6ND): lladdr=self.pg0._remote_hosts[2].mac)) self.vapi.ip6nd_proxy_add_del( - ip=inet_pton(AF_INET6, self.pg0._remote_hosts[3].ip6), + is_add=1, 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, @@ -1550,10 +1569,10 @@ class IPv6NDProxyTest(TestIPv6ND): # 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) + sw_if_index=self.pg1.sw_if_index, is_add=0) 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) + sw_if_index=self.pg2.sw_if_index, is_add=0) self.assertFalse(find_nbr(self, self.pg2.sw_if_index, diff --git a/test/test_ip_ecmp.py b/test/test_ip_ecmp.py index cc93ab731d3..1d3e872e45e 100644 --- a/test/test_ip_ecmp.py +++ b/test/test_ip_ecmp.py @@ -75,7 +75,7 @@ class TestECMP(VppTestCase): super(TestECMP, self).tearDown() def show_commands_at_teardown(self): - self.logger.info(self.vapi.ppcli("show ip arp")) + self.logger.info(self.vapi.ppcli("show ip4 neighbors")) self.logger.info(self.vapi.ppcli("show ip6 neighbors")) def get_ip_address(self, ip_addr_start, ip_prefix_len): diff --git a/test/test_l2bd_arp_term.py b/test/test_l2bd_arp_term.py index 975c324896b..c64d5d4f01c 100644 --- a/test/test_l2bd_arp_term.py +++ b/test/test_l2bd_arp_term.py @@ -391,7 +391,7 @@ class TestL2bdArpTerm(VppTestCase): def test_l2bd_arp_term_09(self): """ L2BD arp term - send garps, verify arp event reports """ - self.vapi.want_ip4_arp_events() + self.vapi.want_l2_arp_term_events(enable=1) self.bd_add_del(1, is_add=1) self.set_bd_flags(1, arp_term=True, flood=False, uu_flood=False, learn=False) @@ -403,7 +403,7 @@ class TestL2bdArpTerm(VppTestCase): self.pg_enable_capture(self.pg_interfaces) self.pg_start() - evs = [self.vapi.wait_for_event(1, "ip4_arp_event") + evs = [self.vapi.wait_for_event(1, "l2_arp_term_event") for i in range(len(hosts))] ev_hosts = self.arp_event_hosts(evs) self.assertEqual(len(ev_hosts ^ hosts), 0) @@ -421,7 +421,7 @@ class TestL2bdArpTerm(VppTestCase): self.pg_enable_capture(self.pg_interfaces) self.pg_start() - evs = [self.vapi.wait_for_event(1, "ip4_arp_event") + evs = [self.vapi.wait_for_event(1, "l2_arp_term_event") for i in range(len(hosts))] ev_hosts = self.arp_event_hosts(evs) self.assertEqual(len(ev_hosts ^ hosts), 0) @@ -429,7 +429,7 @@ class TestL2bdArpTerm(VppTestCase): def test_l2bd_arp_term_11(self): """ L2BD arp term - disable ip4 arp events,send garps, verify no events """ - self.vapi.want_ip4_arp_events(enable_disable=0) + self.vapi.want_l2_arp_term_events(enable=0) macs = self.mac_list(range(90, 95)) hosts = self.ip4_hosts(5, 1, macs) @@ -445,7 +445,7 @@ class TestL2bdArpTerm(VppTestCase): def test_l2bd_arp_term_12(self): """ L2BD ND term - send NS packets verify reports """ - self.vapi.want_ip6_nd_events(ip="::") + self.vapi.want_l2_arp_term_events(enable=1) dst_host = self.ip6_host(50, 50, "00:00:11:22:33:44") self.bd_add_del(1, is_add=1) self.set_bd_flags(1, arp_term=True, flood=False, @@ -457,7 +457,7 @@ class TestL2bdArpTerm(VppTestCase): self.pg_enable_capture(self.pg_interfaces) self.pg_start() - evs = [self.vapi.wait_for_event(2, "ip6_nd_event") + evs = [self.vapi.wait_for_event(2, "l2_arp_term_event") for i in range(len(hosts))] ev_hosts = self.nd_event_hosts(evs) self.assertEqual(len(ev_hosts ^ hosts), 0) @@ -473,7 +473,7 @@ class TestL2bdArpTerm(VppTestCase): self.pg_enable_capture(self.pg_interfaces) self.pg_start() - evs = [self.vapi.wait_for_event(2, "ip6_nd_event") + evs = [self.vapi.wait_for_event(2, "l2_arp_term_event") for i in range(len(hosts))] ev_hosts = self.nd_event_hosts(evs) self.assertEqual(len(ev_hosts ^ hosts), 0) @@ -481,7 +481,7 @@ class TestL2bdArpTerm(VppTestCase): def test_l2bd_arp_term_14(self): """ L2BD ND term - disable ip4 arp events,send ns, verify no events """ - self.vapi.want_ip6_nd_events(enable_disable=0, ip="::") + self.vapi.want_l2_arp_term_events(enable=0) dst_host = self.ip6_host(50, 50, "00:00:11:22:33:44") macs = self.mac_list(range(10, 15)) hosts = self.ip6_hosts(5, 1, macs) diff --git a/test/test_mpls.py b/test/test_mpls.py index 32868c69157..6c493ef277f 100644 --- a/test/test_mpls.py +++ b/test/test_mpls.py @@ -108,7 +108,6 @@ class TestMPLS(VppTestCase): for i in self.pg_interfaces: i.unconfig_ip4() i.unconfig_ip6() - i.ip6_disable() i.set_table_ip4(0) i.set_table_ip6(0) i.disable_mpls() @@ -2045,6 +2044,7 @@ class TestMPLSPIC(VppTestCase): # # put the connected routes back # + print(self.vapi.cli("sh log")) self.pg2.admin_up() self.pg2.config_ip6() self.pg2.resolve_ndp() diff --git a/test/test_neighbor.py b/test/test_neighbor.py index 0b7ffff8bc3..a415e965ea3 100644 --- a/test/test_neighbor.py +++ b/test/test_neighbor.py @@ -1,6 +1,7 @@ #!/usr/bin/env python3 import unittest +import os from socket import AF_INET, AF_INET6, inet_pton from framework import VppTestCase, VppTestRunner @@ -155,6 +156,24 @@ class ARPTestCase(VppTestCase): # self.pg1.generate_remote_hosts(11) + # + # watch for: + # - all neighbour events + # - all neighbor events on pg1 + # - neighbor events for host[1] on pg1 + # + self.vapi.want_ip_neighbor_events(enable=1, + pid=os.getpid()) + self.vapi.want_ip_neighbor_events(enable=1, + pid=os.getpid(), + sw_if_index=self.pg1.sw_if_index) + self.vapi.want_ip_neighbor_events(enable=1, + pid=os.getpid(), + sw_if_index=self.pg1.sw_if_index, + ip=self.pg1.remote_hosts[1].ip4) + + self.logger.info(self.vapi.cli("sh ip neighbor-watcher")) + # # Send IP traffic to one of these unresolved hosts. # expect the generation of an ARP request @@ -183,6 +202,14 @@ class ARPTestCase(VppTestCase): self.pg1.remote_hosts[1].mac, self.pg1.remote_hosts[1].ip4) dyn_arp.add_vpp_config() + self.assertTrue(dyn_arp.query_vpp_config()) + + # this matches all of the listnerers + es = [self.vapi.wait_for_event(1, "ip_neighbor_event") + for i in range(3)] + for e in es: + self.assertEqual(str(e.neighbor.ip_address), + self.pg1.remote_hosts[1].ip4) # # now we expect IP traffic forwarded @@ -214,6 +241,11 @@ class ARPTestCase(VppTestCase): self.pg1.remote_hosts[2].ip4, is_static=1) static_arp.add_vpp_config() + es = [self.vapi.wait_for_event(1, "ip_neighbor_event") + for i in range(2)] + for e in es: + self.assertEqual(str(e.neighbor.ip_address), + self.pg1.remote_hosts[2].ip4) static_p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) / IP(src=self.pg0.remote_ip4, @@ -233,6 +265,19 @@ class ARPTestCase(VppTestCase): self.pg0.remote_ip4, self.pg1._remote_hosts[2].ip4) + # + # remove all the listeners + # + self.vapi.want_ip_neighbor_events(enable=0, + pid=os.getpid()) + self.vapi.want_ip_neighbor_events(enable=0, + pid=os.getpid(), + sw_if_index=self.pg1.sw_if_index) + self.vapi.want_ip_neighbor_events(enable=0, + pid=os.getpid(), + sw_if_index=self.pg1.sw_if_index, + ip=self.pg1.remote_hosts[1].ip4) + # # flap the link. dynamic ARPs get flush, statics don't # @@ -260,6 +305,8 @@ class ARPTestCase(VppTestCase): self.pg1.local_ip4, self.pg1._remote_hosts[1].ip4) + self.assertFalse(dyn_arp.query_vpp_config()) + self.assertTrue(static_arp.query_vpp_config()) # # Send an ARP request from one of the so-far unlearned remote hosts # @@ -684,7 +731,6 @@ class ARPTestCase(VppTestCase): # # cleanup # - dyn_arp.remove_vpp_config() static_arp.remove_vpp_config() self.pg2.unset_unnumbered(self.pg1.sw_if_index) @@ -1160,6 +1206,7 @@ class ARPTestCase(VppTestCase): # clean-up # self.pg2.unconfig_ip4() + static_arp.remove_vpp_config() self.pg2.set_table_ip4(0) def test_arp_incomplete(self): @@ -1541,5 +1588,180 @@ class NeighborStatsTestCase(VppTestCase): self.assertEqual(NUM_PKTS+16, nd1.get_stats()['packets']) +class NeighborAgeTestCase(VppTestCase): + """ ARP/ND Aging """ + + @classmethod + def setUpClass(cls): + super(NeighborAgeTestCase, cls).setUpClass() + + @classmethod + def tearDownClass(cls): + super(NeighborAgeTestCase, cls).tearDownClass() + + def setUp(self): + super(NeighborAgeTestCase, self).setUp() + + self.create_pg_interfaces(range(1)) + + # pg0 configured with ip4 and 6 addresses used for input + # pg1 configured with ip4 and 6 addresses used for output + # pg2 is unnumbered to pg0 + for i in self.pg_interfaces: + i.admin_up() + i.config_ip4() + i.config_ip6() + i.resolve_arp() + i.resolve_ndp() + + def tearDown(self): + super(NeighborAgeTestCase, self).tearDown() + + for i in self.pg_interfaces: + i.unconfig_ip4() + i.unconfig_ip6() + i.admin_down() + + def wait_for_no_nbr(self, intf, address, + n_tries=50, s_time=1): + while (n_tries): + if not find_nbr(self, intf, address): + return True + n_tries = n_tries - 1 + self.sleep(s_time) + + return False + + def verify_arp_req(self, rx, smac, sip, dip): + ether = rx[Ether] + self.assertEqual(ether.dst, "ff:ff:ff:ff:ff:ff") + self.assertEqual(ether.src, smac) + + arp = rx[ARP] + self.assertEqual(arp.hwtype, 1) + self.assertEqual(arp.ptype, 0x800) + self.assertEqual(arp.hwlen, 6) + self.assertEqual(arp.plen, 4) + self.assertEqual(arp.op, arp_opts["who-has"]) + self.assertEqual(arp.hwsrc, smac) + self.assertEqual(arp.hwdst, "00:00:00:00:00:00") + self.assertEqual(arp.psrc, sip) + self.assertEqual(arp.pdst, dip) + + def test_age(self): + """ Aging/Recycle """ + + self.vapi.cli("set logging unthrottle 0") + self.vapi.cli("set logging size %d" % 0xffff) + + self.pg0.generate_remote_hosts(201) + + vaf = VppEnum.vl_api_address_family_t + + # + # start listening on all interfaces + # + self.pg_enable_capture(self.pg_interfaces) + + # + # Set the neighbor configuration: + # limi = 200 + # age = 2 seconds + # recycle = false + # + self.vapi.ip_neighbor_config(af=vaf.ADDRESS_IP4, + max_number=200, + max_age=0, + recycle=False) + + self.vapi.cli("sh ip neighbor-config") + + # add the 198 neighbours that should pass (-1 for one created in setup) + for ii in range(200): + VppNeighbor(self, + self.pg0.sw_if_index, + self.pg0.remote_hosts[ii].mac, + self.pg0.remote_hosts[ii].ip4).add_vpp_config() + + # one more neighbor over the limit should fail + with self.vapi.assert_negative_api_retval(): + VppNeighbor(self, + self.pg0.sw_if_index, + self.pg0.remote_hosts[200].mac, + self.pg0.remote_hosts[200].ip4).add_vpp_config() + + # + # change the config to allow recycling the old neighbors + # + self.vapi.ip_neighbor_config(af=vaf.ADDRESS_IP4, + max_number=200, + max_age=0, + recycle=True) + + # now new additions are allowed + VppNeighbor(self, + self.pg0.sw_if_index, + self.pg0.remote_hosts[200].mac, + self.pg0.remote_hosts[200].ip4).add_vpp_config() + + # add the first neighbor we configured has been re-used + self.assertFalse(find_nbr(self, + self.pg0.sw_if_index, + self.pg0.remote_hosts[0].ip4)) + self.assertTrue(find_nbr(self, + self.pg0.sw_if_index, + self.pg0.remote_hosts[200].ip4)) + + # + # change the config to age old neighbors + # + self.vapi.ip_neighbor_config(af=vaf.ADDRESS_IP4, + max_number=200, + max_age=2, + recycle=True) + + self.vapi.cli("sh ip4 neighbor-sorted") + + # + # expect probes from all these ARP entries as they age + # 3 probes for each neighbor 3*200 = 600 + rxs = self.pg0.get_capture(600, timeout=8) + + for ii in range(3): + for jj in range(200): + rx = rxs[ii*200 + jj] + # rx.show() + + # + # 3 probes sent then 1 more second to see if a reply comes, before + # they age out + # + for jj in range(1, 201): + self.wait_for_no_nbr(self.pg0.sw_if_index, + self.pg0.remote_hosts[jj].ip4) + + self.assertFalse(self.vapi.ip_neighbor_dump(sw_if_index=0xffffffff, + af=vaf.ADDRESS_IP4)) + + # + # load up some neighbours again, then disable the aging + # they should still be there in 10 seconds time + # + for ii in range(10): + VppNeighbor(self, + self.pg0.sw_if_index, + self.pg0.remote_hosts[ii].mac, + self.pg0.remote_hosts[ii].ip4).add_vpp_config() + self.vapi.ip_neighbor_config(af=vaf.ADDRESS_IP4, + max_number=200, + max_age=0, + recycle=False) + + self.sleep(10) + self.assertTrue(find_nbr(self, + self.pg0.sw_if_index, + self.pg0.remote_hosts[0].ip4)) + + if __name__ == '__main__': unittest.main(testRunner=VppTestRunner) diff --git a/test/test_ping.py b/test/test_ping.py index 7e5c92f63c6..87cb45c3211 100644 --- a/test/test_ping.py +++ b/test/test_ping.py @@ -51,7 +51,7 @@ class TestPing(VppTestCase): try: self.pg_enable_capture(self.pg_interfaces) self.pg_start() - self.logger.info(self.vapi.cli("show ip arp")) + self.logger.info(self.vapi.cli("show ip4 neighbors")) self.logger.info(self.vapi.cli("show ip6 neighbors")) remote_ip4 = self.pg1.remote_ip4 @@ -87,8 +87,7 @@ class TestPing(VppTestCase): try: self.pg_enable_capture(self.pg_interfaces) self.pg_start() - self.logger.info(self.vapi.cli("show ip arp")) - self.logger.info(self.vapi.cli("show ip6 neighbors")) + self.logger.info(self.vapi.cli("show ip neighbors")) remote_ip4 = self.pg1.remote_ip4 ping_cmd = "ping " + remote_ip4 + " interval 0.01 burst 3" diff --git a/test/test_punt.py b/test/test_punt.py index c0c63507977..9627e542c2c 100644 --- a/test/test_punt.py +++ b/test/test_punt.py @@ -1057,7 +1057,6 @@ class TestPunt(VppTestCase): for i in self.pg_interfaces: i.unconfig_ip4() i.unconfig_ip6() - i.ip6_disable() i.admin_down() super(TestPunt, self).tearDown() diff --git a/test/test_sixrd.py b/test/test_sixrd.py index cb2f6799461..24ff74b8d1c 100644 --- a/test/test_sixrd.py +++ b/test/test_sixrd.py @@ -56,6 +56,7 @@ class Test6RD(VppTestCase): i.unconfig_ip6() i.set_table_ip4(0) i.set_table_ip6(0) + i.admin_down() super(Test6RD, self).tearDown() def validate_6in4(self, rx, expected): diff --git a/test/test_srmpls.py b/test/test_srmpls.py index cb47328a7c9..b9abeaeffec 100644 --- a/test/test_srmpls.py +++ b/test/test_srmpls.py @@ -84,7 +84,6 @@ class TestSRMPLS(VppTestCase): for i in self.pg_interfaces: i.unconfig_ip4() i.unconfig_ip6() - i.ip6_disable() i.disable_mpls() i.admin_down() super(TestSRMPLS, self).tearDown() diff --git a/test/test_udp.py b/test/test_udp.py index b22ed44e791..af64f8ae704 100644 --- a/test/test_udp.py +++ b/test/test_udp.py @@ -60,7 +60,6 @@ class TestUdpEncap(VppTestCase): for i in self.pg_interfaces: i.unconfig_ip4() i.unconfig_ip6() - i.ip6_disable() i.set_table_ip4(0) i.set_table_ip6(0) i.admin_down() diff --git a/test/vpp_neighbor.py b/test/vpp_neighbor.py index f906c2a5af3..6172d8f871d 100644 --- a/test/vpp_neighbor.py +++ b/test/vpp_neighbor.py @@ -16,8 +16,11 @@ except NameError: def find_nbr(test, sw_if_index, nbr_addr, is_static=0, mac=None): ip_addr = ip_address(text_type(nbr_addr)) e = VppEnum.vl_api_ip_neighbor_flags_t - nbrs = test.vapi.ip_neighbor_dump(sw_if_index, - is_ipv6=(6 == ip_addr.version)) + if 6 == ip_addr.version: + af = VppEnum.vl_api_address_family_t.ADDRESS_IP6 + else: + af = VppEnum.vl_api_address_family_t.ADDRESS_IP4 + nbrs = test.vapi.ip_neighbor_dump(sw_if_index=sw_if_index, af=af) for n in nbrs: if ip_addr == n.neighbor.ip_address and \ diff --git a/test/vpp_papi_provider.py b/test/vpp_papi_provider.py index 309fc3f5c58..964b68c1761 100644 --- a/test/vpp_papi_provider.py +++ b/test/vpp_papi_provider.py @@ -127,9 +127,6 @@ defaultmapping = { 'want_bfd_events': {'enable_disable': 1, }, 'want_igmp_events': {'enable': 1, }, 'want_interface_events': {'enable_disable': 1, }, - 'want_ip4_arp_events': {'enable_disable': 1, 'ip': '0.0.0.0', }, - 'want_ip6_nd_events': {'enable_disable': 1, 'ip': '::', }, - 'want_ip6_ra_events': {'enable_disable': 1, }, 'want_l2_macs_events': {'enable_disable': 1, }, } @@ -364,23 +361,6 @@ class VppPapiProvider(object): """ return cli + "\n" + self.cli(cli) - def want_ip4_arp_events(self, enable_disable=1, ip="0.0.0.0"): - return self.api(self.papi.want_ip4_arp_events, - {'enable_disable': enable_disable, - 'ip': ip, - 'pid': os.getpid(), }) - - def want_ip6_nd_events(self, enable_disable=1, ip="::"): - return self.api(self.papi.want_ip6_nd_events, - {'enable_disable': enable_disable, - 'ip': ip, - 'pid': os.getpid(), }) - - def want_ip6_ra_events(self, enable_disable=1): - return self.api(self.papi.want_ip6_ra_events, - {'enable_disable': enable_disable, - 'pid': os.getpid(), }) - def ip6nd_send_router_solicitation(self, sw_if_index, irt=1, mrt=120, mrc=0, mrd=0): return self.api(self.papi.ip6nd_send_router_solicitation, @@ -521,7 +501,7 @@ class VppPapiProvider(object): return self.api( self.papi.proxy_arp_intfc_enable_disable, {'sw_if_index': sw_if_index, - 'enable_disable': is_enable + 'enable': is_enable } ) -- cgit 1.2.3-korg