Propagate duplicate IF addr add/del error up to API. 19/8619/2
authorJon Loeliger <jdl@netgate.com>
Thu, 28 Sep 2017 18:54:16 +0000 (13:54 -0500)
committerNeale Ranns <nranns@cisco.com>
Tue, 3 Oct 2017 10:15:53 +0000 (10:15 +0000)
Identify and complain when the same IP prefix is assigned
to two different SW interfaces:

    vpp# set int ip address TenGigabitEthernet6/0/0 1.2.3.4/32
    vpp# set int ip address TenGigabitEthernet6/0/1 1.2.3.4/32
    set interface ip address: Prefix 1.2.3.4/32 already found on
interface TenGigabitEthernet6/0/0

Change-Id: I1aee1b6a7ddd00d3109a53d8e1b6ce97bf45e372
Signed-off-by: Jon Loeliger <jdl@netgate.com>
src/vnet/api_errno.h
src/vnet/interface_api.c
src/vnet/ip/lookup.c [changed mode: 0755->0644]

index c0deb1d..22cfaee 100644 (file)
@@ -115,7 +115,8 @@ _(BD_ID_EXCEED_MAX, -122, "Bridge domain ID exceed 16M limit")              \
 _(SUBIF_DOESNT_EXIST, -123, "Subinterface doesn't exist")               \
 _(L2_MACS_EVENT_CLINET_PRESENT, -124, "Client already exist for L2 MACs events") \
 _(INVALID_QUEUE, -125, "Invalid queue")                                \
-_(UNSUPPORTED, -126, "Unsupported")
+_(UNSUPPORTED, -126, "Unsupported")                                    \
+_(DUPLICATE_IF_ADDRESS, -127, "Address already present on another interface")
 
 typedef enum
 {
index 0731ab3..93551e4 100644 (file)
@@ -281,27 +281,38 @@ static void
   (vl_api_sw_interface_add_del_address_t * mp)
 {
   vlib_main_t *vm = vlib_get_main ();
+  vnet_main_t *vnm = vnet_get_main ();
   vl_api_sw_interface_add_del_address_reply_t *rmp;
   int rv = 0;
   u32 is_del;
+  clib_error_t *error = 0;
 
   VALIDATE_SW_IF_INDEX (mp);
 
   is_del = mp->is_add == 0;
+  vnm->api_errno = 0;
 
   if (mp->del_all)
     ip_del_all_interface_addresses (vm, ntohl (mp->sw_if_index));
   else if (mp->is_ipv6)
-    ip6_add_del_interface_address (vm, ntohl (mp->sw_if_index),
-                                  (void *) mp->address,
-                                  mp->address_length, is_del);
+    error = ip6_add_del_interface_address (vm, ntohl (mp->sw_if_index),
+                                          (void *) mp->address,
+                                          mp->address_length, is_del);
   else
-    ip4_add_del_interface_address (vm, ntohl (mp->sw_if_index),
-                                  (void *) mp->address,
-                                  mp->address_length, is_del);
+    error = ip4_add_del_interface_address (vm, ntohl (mp->sw_if_index),
+                                          (void *) mp->address,
+                                          mp->address_length, is_del);
+
+  if (error)
+    {
+      rv = vnm->api_errno;
+      clib_error_report (error);
+      goto done;
+    }
 
   BAD_SW_IF_INDEX_LABEL;
 
+done:
   REPLY_MACRO (VL_API_SW_INTERFACE_ADD_DEL_ADDRESS_REPLY);
 }
 
old mode 100755 (executable)
new mode 100644 (file)
index d9922f4..856c494
@@ -165,11 +165,21 @@ ip_interface_address_add_del (ip_lookup_main_t * lm,
     }
   else
     {
+      if (sw_if_index != a->sw_if_index)
+       {
+         if (result_if_address_index)
+           *result_if_address_index = ~0;
+         vnm->api_errno = VNET_API_ERROR_DUPLICATE_IF_ADDRESS;
+         return clib_error_create
+           ("Prefix %U already found on interface %U",
+            lm->format_address_and_length, addr_fib, address_length,
+            format_vnet_sw_if_index_name, vnm, a->sw_if_index);
+       }
+
       if (result_if_address_index)
        *result_if_address_index = a - lm->if_address_pool;
     }
 
-
   return /* no error */ 0;
 }