No overlapping sub-nets on any interface in the same table/VRF (VPP-943) 57/8057/14
authorNeale Ranns <nranns@cisco.com>
Mon, 14 Aug 2017 17:35:44 +0000 (10:35 -0700)
committerNeale Ranns <nranns@cisco.com>
Tue, 15 May 2018 13:07:00 +0000 (13:07 +0000)
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>
src/vnet/ip/ip4_forward.c
src/vnet/ip/ip6_forward.c
test/test_classifier.py
test/test_ip6.py

index 28b6203..ce2d619 100644 (file)
@@ -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* */
 
index b53cdc4..c45b65f 100644 (file)
@@ -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);
 
index 1753fef..1e29aec 100644 (file)
@@ -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"))
index 884f793..21d8025 100644 (file)
@@ -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):