VPP-393: Subinterface is still used after deletion
[vpp.git] / vnet / vnet / interface.c
index 941ab17..b57c1e8 100644 (file)
@@ -623,6 +623,16 @@ vnet_delete_sw_interface (vnet_main_t * vnm, u32 sw_if_index)
   vnet_sw_interface_t *sw =
     pool_elt_at_index (im->sw_interfaces, sw_if_index);
 
+  /* Make sure the interface is in L3 mode (removed from L2 BD or XConnect) */
+  vlib_main_t *vm = vlib_get_main ();
+  l2_input_config_t *config;
+  config = vec_elt_at_index (l2input_main.configs, sw_if_index);
+  if (config->xconnect)
+    set_int_l2_mode (vm, vnm, MODE_L3, config->output_sw_if_index, 0, 0, 0,
+                    0);
+  if (config->xconnect || config->bridge)
+    set_int_l2_mode (vm, vnm, MODE_L3, sw_if_index, 0, 0, 0, 0);
+
   /* Bring down interface in case it is up. */
   if (sw->flags != 0)
     vnet_sw_interface_set_flags (vnm, sw_if_index, /* flags */ 0);
@@ -721,6 +731,8 @@ vnet_register_interface (vnet_main_t * vnm,
     {
       vnet_hw_interface_nodes_t *hn;
       vnet_interface_output_runtime_t *rt;
+      vlib_node_t *node;
+      vlib_node_runtime_t *nrt;
 
       hn = vec_end (im->deleted_hw_interface_nodes) - 1;
 
@@ -742,6 +754,22 @@ vnet_register_interface (vnet_main_t * vnm,
       rt->sw_if_index = hw->sw_if_index;
       rt->dev_instance = hw->dev_instance;
 
+      /* The new class may differ from the old one.
+       * Functions have to be updated. */
+      node = vlib_get_node (vm, hw->output_node_index);
+      node->function = dev_class->no_flatten_output_chains ?
+       vnet_interface_output_node_no_flatten_multiarch_select () :
+       vnet_interface_output_node_multiarch_select ();
+      node->format_trace = format_vnet_interface_output_trace;
+      nrt = vlib_node_get_runtime (vm, hw->output_node_index);
+      nrt->function = node->function;
+
+      node = vlib_get_node (vm, hw->tx_node_index);
+      node->function = dev_class->tx_function;
+      node->format_trace = dev_class->format_tx_trace;
+      nrt = vlib_node_get_runtime (vm, hw->tx_node_index);
+      nrt->function = node->function;
+
       vlib_worker_thread_node_runtime_update ();
       _vec_len (im->deleted_hw_interface_nodes) -= 1;
     }
@@ -1272,8 +1300,11 @@ vnet_hw_interface_change_mac_address_helper (vnet_main_t * vnm,
          ethernet_interface_t *ei =
            pool_elt_at_index (em->interfaces, hi->hw_instance);
 
-         clib_memcpy (hi->hw_address, (u8 *) & mac_address,
-                      sizeof (hi->hw_address));
+         vec_validate (hi->hw_address,
+                       STRUCT_SIZE_OF (ethernet_header_t, src_address) - 1);
+         clib_memcpy (hi->hw_address, &mac_address,
+                      vec_len (hi->hw_address));
+
          clib_memcpy (ei->address, (u8 *) & mac_address,
                       sizeof (ei->address));
          ethernet_arp_change_mac (vnm, hw_if_index);