From: Neale Ranns Date: Mon, 14 Aug 2017 17:35:44 +0000 (-0700) Subject: No overlapping sub-nets on any interface in the same table/VRF (VPP-943) X-Git-Tag: v18.07-rc1~338 X-Git-Url: https://gerrit.fd.io/r/gitweb?a=commitdiff_plain;h=refs%2Fchanges%2F57%2F8057%2F14;p=vpp.git No overlapping sub-nets on any interface in the same table/VRF (VPP-943) DBGvpp# set int ip addr loop0 10.10.10.10/24 DBGvpp# set int ip addr loop0 10.10.10.11/24 set interface ip address: failed to add 10.10.10.11/24 which conflicts with 10.10.10.10/24 for interface loop0 Change-Id: Iba63ffafbd36b6146ce86adb78139da9d55b40ba Signed-off-by: Neale Ranns --- diff --git a/src/vnet/ip/ip4_forward.c b/src/vnet/ip/ip4_forward.c index 28b6203c0fb..ce2d619941c 100644 --- a/src/vnet/ip/ip4_forward.c +++ b/src/vnet/ip/ip4_forward.c @@ -545,7 +545,7 @@ ip4_add_del_interface_address_internal (vlib_main_t * vm, vec_elt (im->fib_index_by_sw_if_index, sw_if_index)); vec_add1 (addr_fib, ip4_af); - /* FIXME-LATER + /* * there is no support for adj-fib handling in the presence of overlapping * subnets on interfaces. Easy fix - disallow overlapping subnets, like * most routers do. @@ -554,31 +554,44 @@ ip4_add_del_interface_address_internal (vlib_main_t * vm, if (!is_del) { /* When adding an address check that it does not conflict - with an existing address. */ + with an existing address on any interface in this table. */ ip_interface_address_t *ia; - foreach_ip_interface_address - (&im->lookup_main, ia, sw_if_index, - 0 /* honor unnumbered */ , - ({ - ip4_address_t * x = - ip_interface_address_get_address - (&im->lookup_main, ia); - if (ip4_destination_matches_route - (im, address, x, ia->address_length) || - ip4_destination_matches_route (im, - x, - address, - address_length)) - return - clib_error_create - ("failed to add %U which conflicts with %U for interface %U", - format_ip4_address_and_length, address, - address_length, - format_ip4_address_and_length, x, - ia->address_length, - format_vnet_sw_if_index_name, vnm, - sw_if_index); - })); + vnet_sw_interface_t *sif; + + pool_foreach(sif, vnm->interface_main.sw_interfaces, + ({ + if (im->fib_index_by_sw_if_index[sw_if_index] == + im->fib_index_by_sw_if_index[sif->sw_if_index]) + { + foreach_ip_interface_address + (&im->lookup_main, ia, sif->sw_if_index, + 0 /* honor unnumbered */ , + ({ + ip4_address_t * x = + ip_interface_address_get_address + (&im->lookup_main, ia); + if (ip4_destination_matches_route + (im, address, x, ia->address_length) || + ip4_destination_matches_route (im, + x, + address, + address_length)) + { + vnm->api_errno = VNET_API_ERROR_DUPLICATE_IF_ADDRESS; + + return + clib_error_create + ("failed to add %U which conflicts with %U for interface %U", + format_ip4_address_and_length, address, + address_length, + format_ip4_address_and_length, x, + ia->address_length, + format_vnet_sw_if_index_name, vnm, + sif->sw_if_index); + } + })); + } + })); } /* *INDENT-ON* */ diff --git a/src/vnet/ip/ip6_forward.c b/src/vnet/ip/ip6_forward.c index b53cdc47346..c45b65fd22d 100644 --- a/src/vnet/ip/ip6_forward.c +++ b/src/vnet/ip/ip6_forward.c @@ -215,6 +215,50 @@ ip6_add_del_interface_address (vlib_main_t * vm, vec_elt (im->fib_index_by_sw_if_index, sw_if_index)); vec_add1 (addr_fib, ip6_af); + /* *INDENT-OFF* */ + if (!is_del) + { + /* When adding an address check that it does not conflict + with an existing address on any interface in this table. */ + ip_interface_address_t *ia; + vnet_sw_interface_t *sif; + + pool_foreach(sif, vnm->interface_main.sw_interfaces, + ({ + if (im->fib_index_by_sw_if_index[sw_if_index] == + im->fib_index_by_sw_if_index[sif->sw_if_index]) + { + foreach_ip_interface_address + (&im->lookup_main, ia, sif->sw_if_index, + 0 /* honor unnumbered */ , + ({ + ip6_address_t * x = + ip_interface_address_get_address + (&im->lookup_main, ia); + if (ip6_destination_matches_route + (im, address, x, ia->address_length) || + ip6_destination_matches_route (im, + x, + address, + address_length)) + { + vnm->api_errno = VNET_API_ERROR_DUPLICATE_IF_ADDRESS; + return + clib_error_create + ("failed to add %U which conflicts with %U for interface %U", + format_ip6_address_and_length, address, + address_length, + format_ip6_address_and_length, x, + ia->address_length, + format_vnet_sw_if_index_name, vnm, + sif->sw_if_index); + } + })); + } + })); + } + /* *INDENT-ON* */ + { uword elts_before = pool_elts (lm->if_address_pool); diff --git a/test/test_classifier.py b/test/test_classifier.py index 1753feff66a..1e29aec6b00 100644 --- a/test/test_classifier.py +++ b/test/test_classifier.py @@ -60,6 +60,10 @@ class TestClassifier(VppTestCase): def tearDown(self): """Run standard test teardown and acl related log.""" + for intf in self.interfaces: + intf.unconfig_ip4() + intf.admin_down() + super(TestClassifier, self).tearDown() if not self.vpp_dead: self.logger.info(self.vapi.cli("show classify table verbose")) diff --git a/test/test_ip6.py b/test/test_ip6.py index 884f793680d..21d8025d583 100644 --- a/test/test_ip6.py +++ b/test/test_ip6.py @@ -212,10 +212,11 @@ class TestIPv6(TestIPv6ND): def tearDown(self): """Run standard test teardown and log ``show ip6 neighbors``.""" - for i in self.sub_interfaces: + for i in self.interfaces: i.unconfig_ip6() i.ip6_disable() i.admin_down() + for i in self.sub_interfaces: i.remove_vpp_config() super(TestIPv6, self).tearDown() @@ -918,6 +919,9 @@ class TestIPv6RD(TestIPv6ND): i.config_ip6() def tearDown(self): + for i in self.interfaces: + i.unconfig_ip6() + i.admin_down() super(TestIPv6RD, self).tearDown() def test_rd_send_router_solicitation(self):