interface: handle error during admin-up correctly
[vpp.git] / src / vnet / interface.c
index 44ea52a..ab12da5 100644 (file)
@@ -462,9 +462,6 @@ vnet_sw_interface_set_flags_helper (vnet_main_t * vnm, u32 sw_if_index,
              goto done;
            }
 
-         /* save the si admin up flag */
-         old_flags = si->flags;
-
          /* update si admin up flag in advance if we are going admin down */
          if (!(flags & VNET_SW_INTERFACE_FLAG_ADMIN_UP))
            si->flags &= ~VNET_SW_INTERFACE_FLAG_ADMIN_UP;
@@ -1113,8 +1110,7 @@ vnet_delete_hw_interface (vnet_main_t * vnm, u32 hw_if_index)
   hash_unset_mem (im->hw_interface_by_name, hw->name);
   vec_free (hw->name);
   vec_free (hw->hw_address);
-  vec_free (hw->input_node_thread_index_by_queue);
-  vec_free (hw->rx_queue_indices);
+  vec_free (hw->output_node_thread_runtimes);
   pool_put (im->hw_interfaces, hw);
 }
 
@@ -1334,6 +1330,29 @@ vnet_sw_interface_is_nbma (vnet_main_t * vnm, u32 sw_if_index)
   return (hc->flags & VNET_HW_INTERFACE_CLASS_FLAG_NBMA);
 }
 
+clib_error_t *
+vnet_sw_interface_supports_addressing (vnet_main_t *vnm, u32 sw_if_index)
+{
+  if (sw_if_index == 0)
+    {
+      return clib_error_create (
+       "local0 interface doesn't support IP addressing");
+    }
+
+  if (vnet_sw_interface_is_sub (vnm, sw_if_index))
+    {
+      vnet_sw_interface_t *si;
+      si = vnet_get_sw_interface_or_null (vnm, sw_if_index);
+      if (si && si->type == VNET_SW_INTERFACE_TYPE_SUB &&
+         si->sub.eth.flags.exact_match == 0)
+       {
+         return clib_error_create (
+           "sub-interface without exact-match doesn't support IP addressing");
+       }
+    }
+  return NULL;
+}
+
 clib_error_t *
 vnet_interface_init (vlib_main_t * vm)
 {
@@ -1610,20 +1629,48 @@ vnet_hw_interface_change_mac_address (vnet_main_t * vnm, u32 hw_if_index,
     (vnm, hw_if_index, mac_address);
 }
 
+static int
+vnet_sw_interface_check_table_same (u32 unnumbered_sw_if_index,
+                                   u32 ip_sw_if_index)
+{
+  if (ip4_main.fib_index_by_sw_if_index[unnumbered_sw_if_index] !=
+      ip4_main.fib_index_by_sw_if_index[ip_sw_if_index])
+    return VNET_API_ERROR_UNEXPECTED_INTF_STATE;
+
+  if (ip4_main.mfib_index_by_sw_if_index[unnumbered_sw_if_index] !=
+      ip4_main.mfib_index_by_sw_if_index[ip_sw_if_index])
+    return VNET_API_ERROR_UNEXPECTED_INTF_STATE;
+
+  if (ip6_main.fib_index_by_sw_if_index[unnumbered_sw_if_index] !=
+      ip6_main.fib_index_by_sw_if_index[ip_sw_if_index])
+    return VNET_API_ERROR_UNEXPECTED_INTF_STATE;
+
+  if (ip6_main.mfib_index_by_sw_if_index[unnumbered_sw_if_index] !=
+      ip6_main.mfib_index_by_sw_if_index[ip_sw_if_index])
+    return VNET_API_ERROR_UNEXPECTED_INTF_STATE;
+
+  return 0;
+}
+
 /* update the unnumbered state of an interface*/
-void
+int
 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;
+  int rv = 0;
 
   si = vnet_get_sw_interface (vnm, unnumbered_sw_if_index);
   was_unnum = (si->flags & VNET_SW_INTERFACE_FLAG_UNNUMBERED);
 
   if (enable)
     {
+      rv = vnet_sw_interface_check_table_same (unnumbered_sw_if_index,
+                                              ip_sw_if_index);
+      if (rv != 0)
+       return rv;
       si->flags |= VNET_SW_INTERFACE_FLAG_UNNUMBERED;
       si->unnumbered_sw_if_index = ip_sw_if_index;
 
@@ -1660,6 +1707,8 @@ vnet_sw_interface_update_unnumbered (u32 unnumbered_sw_if_index,
       ip4_sw_interface_enable_disable (unnumbered_sw_if_index, enable);
       ip6_sw_interface_enable_disable (unnumbered_sw_if_index, enable);
     }
+
+  return 0;
 }
 
 vnet_l3_packet_type_t