Remove unnumbered configuration on interface delete

Change-Id: Iae5532c3d53e208831f3b2782242d9e59d367087
Signed-off-by: Neale Ranns <nranns@cisco.com>
diff --git a/src/vnet/interface.c b/src/vnet/interface.c
index b197aa1..122ae06 100644
--- a/src/vnet/interface.c
+++ b/src/vnet/interface.c
@@ -1414,6 +1414,51 @@
     (vnm, hw_if_index, mac_address);
 }
 
+/* update the unnumbered state of an interface*/
+void
+vnet_sw_interface_update_unnumbered (u32 unnumbered_sw_if_index,
+				     u32 ip_sw_if_index, u8 enable)
+{
+  vnet_main_t *vnm = vnet_get_main ();
+  vnet_sw_interface_t *si;
+  u32 was_unnum;
+
+  si = vnet_get_sw_interface (vnm, unnumbered_sw_if_index);
+  was_unnum = (si->flags & VNET_SW_INTERFACE_FLAG_UNNUMBERED);
+
+  if (enable)
+    {
+      si->flags |= VNET_SW_INTERFACE_FLAG_UNNUMBERED;
+      si->unnumbered_sw_if_index = ip_sw_if_index;
+
+      ip4_main.lookup_main.if_address_pool_index_by_sw_if_index
+	[unnumbered_sw_if_index] =
+	ip4_main.
+	lookup_main.if_address_pool_index_by_sw_if_index[ip_sw_if_index];
+      ip6_main.
+	lookup_main.if_address_pool_index_by_sw_if_index
+	[unnumbered_sw_if_index] =
+	ip6_main.
+	lookup_main.if_address_pool_index_by_sw_if_index[ip_sw_if_index];
+    }
+  else
+    {
+      si->flags &= ~(VNET_SW_INTERFACE_FLAG_UNNUMBERED);
+      si->unnumbered_sw_if_index = (u32) ~ 0;
+
+      ip4_main.lookup_main.if_address_pool_index_by_sw_if_index
+	[unnumbered_sw_if_index] = ~0;
+      ip6_main.lookup_main.if_address_pool_index_by_sw_if_index
+	[unnumbered_sw_if_index] = ~0;
+    }
+
+  if (was_unnum != (si->flags & VNET_SW_INTERFACE_FLAG_UNNUMBERED))
+    {
+      ip4_sw_interface_enable_disable (unnumbered_sw_if_index, enable);
+      ip6_sw_interface_enable_disable (unnumbered_sw_if_index, enable);
+    }
+}
+
 vnet_l3_packet_type_t
 vnet_link_to_l3_proto (vnet_link_t link)
 {
diff --git a/src/vnet/interface_api.c b/src/vnet/interface_api.c
index fc7af1b..b22cadd 100644
--- a/src/vnet/interface_api.c
+++ b/src/vnet/interface_api.c
@@ -582,7 +582,6 @@
   vnet_main_t *vnm = vnet_get_main ();
   u32 sw_if_index = ntohl (mp->sw_if_index);
   u32 unnumbered_sw_if_index = ntohl (mp->unnumbered_sw_if_index);
-  u32 was_unnum;
 
   /*
    * The API message field names are backwards from
@@ -602,42 +601,8 @@
       goto done;
     }
 
-  vnet_sw_interface_t *si =
-    vnet_get_sw_interface (vnm, unnumbered_sw_if_index);
-  was_unnum = (si->flags & VNET_SW_INTERFACE_FLAG_UNNUMBERED);
-
-  if (mp->is_add)
-    {
-      si->flags |= VNET_SW_INTERFACE_FLAG_UNNUMBERED;
-      si->unnumbered_sw_if_index = sw_if_index;
-
-      ip4_main.lookup_main.if_address_pool_index_by_sw_if_index
-	[unnumbered_sw_if_index] =
-	ip4_main.
-	lookup_main.if_address_pool_index_by_sw_if_index[sw_if_index];
-      ip6_main.
-	lookup_main.if_address_pool_index_by_sw_if_index
-	[unnumbered_sw_if_index] =
-	ip6_main.
-	lookup_main.if_address_pool_index_by_sw_if_index[sw_if_index];
-    }
-  else
-    {
-      si->flags &= ~(VNET_SW_INTERFACE_FLAG_UNNUMBERED);
-      si->unnumbered_sw_if_index = (u32) ~ 0;
-
-      ip4_main.lookup_main.if_address_pool_index_by_sw_if_index
-	[unnumbered_sw_if_index] = ~0;
-      ip6_main.lookup_main.if_address_pool_index_by_sw_if_index
-	[unnumbered_sw_if_index] = ~0;
-    }
-
-  if (was_unnum != (si->flags & VNET_SW_INTERFACE_FLAG_UNNUMBERED))
-    {
-      ip4_sw_interface_enable_disable (unnumbered_sw_if_index, mp->is_add);
-      ip6_sw_interface_enable_disable (unnumbered_sw_if_index, mp->is_add);
-    }
-
+  vnet_sw_interface_update_unnumbered (unnumbered_sw_if_index,
+				       sw_if_index, mp->is_add);
 done:
   REPLY_MACRO (VL_API_SW_INTERFACE_SET_UNNUMBERED_REPLY);
 }
diff --git a/src/vnet/interface_cli.c b/src/vnet/interface_cli.c
index 8880d97..d151335 100644
--- a/src/vnet/interface_cli.c
+++ b/src/vnet/interface_cli.c
@@ -934,60 +934,32 @@
 		unformat_input_t * input, vlib_cli_command_t * cmd)
 {
   vnet_main_t *vnm = vnet_get_main ();
-  u32 unnumbered_sw_if_index;
-  u32 inherit_from_sw_if_index;
-  vnet_sw_interface_t *si;
-  int is_set = 0;
-  int is_del = 0;
-  u32 was_unnum;
+  u32 unnumbered_sw_if_index = ~0;
+  u32 inherit_from_sw_if_index = ~0;
+  int enable = 1;
 
   if (unformat (input, "%U use %U",
 		unformat_vnet_sw_interface, vnm, &unnumbered_sw_if_index,
 		unformat_vnet_sw_interface, vnm, &inherit_from_sw_if_index))
-    is_set = 1;
+    enable = 1;
   else if (unformat (input, "del %U",
 		     unformat_vnet_sw_interface, vnm,
 		     &unnumbered_sw_if_index))
-    is_del = 1;
+    enable = 0;
   else
     return clib_error_return (0, "parse error '%U'",
 			      format_unformat_error, input);
 
-  si = vnet_get_sw_interface (vnm, unnumbered_sw_if_index);
-  was_unnum = (si->flags & VNET_SW_INTERFACE_FLAG_UNNUMBERED);
+  if (~0 == unnumbered_sw_if_index)
+    return clib_error_return (0, "Specify the unnumbered interface");
+  if (enable && ~0 == inherit_from_sw_if_index)
+    return clib_error_return (0, "When enabling unnumberered specify the"
+			      " IP enabled interface that it uses");
 
-  if (is_del)
-    {
-      si->flags &= ~(VNET_SW_INTERFACE_FLAG_UNNUMBERED);
-      si->unnumbered_sw_if_index = (u32) ~ 0;
+  vnet_sw_interface_update_unnumbered (unnumbered_sw_if_index,
+				       inherit_from_sw_if_index, enable);
 
-      ip4_main.lookup_main.if_address_pool_index_by_sw_if_index
-	[unnumbered_sw_if_index] = ~0;
-      ip6_main.lookup_main.if_address_pool_index_by_sw_if_index
-	[unnumbered_sw_if_index] = ~0;
-    }
-  else if (is_set)
-    {
-      si->flags |= VNET_SW_INTERFACE_FLAG_UNNUMBERED;
-      si->unnumbered_sw_if_index = inherit_from_sw_if_index;
-
-      ip4_main.lookup_main.if_address_pool_index_by_sw_if_index
-	[unnumbered_sw_if_index] =
-	ip4_main.lookup_main.if_address_pool_index_by_sw_if_index
-	[inherit_from_sw_if_index];
-      ip6_main.lookup_main.if_address_pool_index_by_sw_if_index
-	[unnumbered_sw_if_index] =
-	ip6_main.lookup_main.if_address_pool_index_by_sw_if_index
-	[inherit_from_sw_if_index];
-    }
-
-  if (was_unnum != (si->flags & VNET_SW_INTERFACE_FLAG_UNNUMBERED))
-    {
-      ip4_sw_interface_enable_disable (unnumbered_sw_if_index, !is_del);
-      ip6_sw_interface_enable_disable (unnumbered_sw_if_index, !is_del);
-    }
-
-  return 0;
+  return (NULL);
 }
 
 /* *INDENT-OFF* */
diff --git a/src/vnet/interface_funcs.h b/src/vnet/interface_funcs.h
index 9c96027..3d045f8 100644
--- a/src/vnet/interface_funcs.h
+++ b/src/vnet/interface_funcs.h
@@ -295,6 +295,10 @@
 /* Set the MTU on the HW interface */
 void vnet_hw_interface_set_mtu (vnet_main_t * vnm, u32 hw_if_index, u32 mtu);
 
+/* update the unnumbered state of an interface */
+void vnet_sw_interface_update_unnumbered (u32 sw_if_index,
+					  u32 ip_sw_if_index, u8 enable);
+
 /* Formats sw/hw interface. */
 format_function_t format_vnet_hw_interface;
 format_function_t format_vnet_hw_interface_rx_mode;
diff --git a/src/vnet/ip/ip4_forward.c b/src/vnet/ip/ip4_forward.c
index 6b7eb9c..19babce 100644
--- a/src/vnet/ip/ip4_forward.c
+++ b/src/vnet/ip/ip4_forward.c
@@ -793,8 +793,9 @@
       ip4_address_t *address;
       vlib_main_t *vm = vlib_get_main ();
 
+      vnet_sw_interface_update_unnumbered (sw_if_index, ~0, 0);
       /* *INDENT-OFF* */
-      foreach_ip_interface_address (lm4, ia, sw_if_index, 1 /* honor unnumbered */,
+      foreach_ip_interface_address (lm4, ia, sw_if_index, 0,
       ({
         address = ip_interface_address_get_address (lm4, ia);
         ip4_add_del_interface_address(vm, sw_if_index, address, ia->address_length, 1);
diff --git a/src/vnet/ip/ip6_forward.c b/src/vnet/ip/ip6_forward.c
index eb7667b..3eb84e8 100644
--- a/src/vnet/ip/ip6_forward.c
+++ b/src/vnet/ip/ip6_forward.c
@@ -432,8 +432,9 @@
       vlib_main_t *vm = vlib_get_main ();
 
       ip6_neighbor_sw_interface_add_del (vnm, sw_if_index, 0 /* is_add */ );
+      vnet_sw_interface_update_unnumbered (sw_if_index, ~0, 0);
       /* *INDENT-OFF* */
-      foreach_ip_interface_address (lm6, ia, sw_if_index, 1 /* honor unnumbered */,
+      foreach_ip_interface_address (lm6, ia, sw_if_index, 0,
       ({
         address = ip_interface_address_get_address (lm6, ia);
         ip6_add_del_interface_address(vm, sw_if_index, address, ia->address_length, 1);