aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNeale Ranns <nranns@cisco.com>2017-08-14 10:35:44 -0700
committerNeale Ranns <nranns@cisco.com>2018-05-15 13:07:00 +0000
commit744902e306c5a1f00bf13bbe344c6616cc816f0e (patch)
tree5a3290d07e5fb48045e63e3d4aa96224f924c959
parentd2d4c10ecd850b4c2fda6d258761026f9c595350 (diff)
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 <nranns@cisco.com>
-rw-r--r--src/vnet/ip/ip4_forward.c63
-rw-r--r--src/vnet/ip/ip6_forward.c44
-rw-r--r--test/test_classifier.py4
-rw-r--r--test/test_ip6.py6
4 files changed, 91 insertions, 26 deletions
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):