Revert "Allow interface types to override glean adjacency behaivour"
[vpp.git] / src / vnet / interface.c
index 82eccc1..7516aec 100644 (file)
@@ -122,6 +122,22 @@ unserialize_vnet_sw_interface_set_flags (serialize_main_t * m, va_list * va)
      /* helper_flags no redistribution */ 0);
 }
 
+void
+vnet_hw_interface_set_mtu (vnet_main_t * vnm, u32 hw_if_index, u32 mtu)
+{
+  vnet_hw_interface_t *hi = vnet_get_hw_interface (vnm, hw_if_index);
+
+  if (hi->max_packet_bytes != mtu)
+    {
+      u16 l3_pad = hi->max_packet_bytes - hi->max_l3_packet_bytes[VLIB_TX];
+      hi->max_packet_bytes = mtu;
+      hi->max_l3_packet_bytes[VLIB_TX] =
+       hi->max_l3_packet_bytes[VLIB_RX] = mtu - l3_pad;
+      ethernet_set_flags (vnm, hw_if_index, ETHERNET_INTERFACE_FLAG_MTU);
+      adj_mtu_update (hw_if_index);
+    }
+}
+
 static void
 unserialize_vnet_hw_interface_set_flags (serialize_main_t * m, va_list * va)
 {
@@ -704,6 +720,7 @@ vnet_register_interface (vnet_main_t * vnm,
   char *tx_node_name, *output_node_name;
 
   pool_get (im->hw_interfaces, hw);
+  memset (hw, 0, sizeof (*hw));
 
   hw_index = hw - im->hw_interfaces;
   hw->hw_if_index = hw_index;
@@ -745,6 +762,9 @@ vnet_register_interface (vnet_main_t * vnm,
   hw->max_l3_packet_bytes[VLIB_RX] = ~0;
   hw->max_l3_packet_bytes[VLIB_TX] = ~0;
 
+  if (dev_class->tx_function == 0)
+    goto no_output_nodes;      /* No output/tx nodes to create */
+
   tx_node_name = (char *) format (0, "%v-tx", hw->name);
   output_node_name = (char *) format (0, "%v-output", hw->name);
 
@@ -881,6 +901,7 @@ vnet_register_interface (vnet_main_t * vnm,
   setup_output_node (vm, hw->output_node_index, hw_class);
   setup_tx_node (vm, hw->tx_node_index, dev_class);
 
+no_output_nodes:
   /* Call all up/down callbacks with zero flags when interface is created. */
   vnet_sw_interface_set_flags_helper (vnm, hw->sw_if_index, /* flags */ 0,
                                      VNET_INTERFACE_SET_FLAGS_HELPER_IS_CREATE);
@@ -896,7 +917,8 @@ vnet_delete_hw_interface (vnet_main_t * vnm, u32 hw_if_index)
   vnet_interface_main_t *im = &vnm->interface_main;
   vnet_hw_interface_t *hw = vnet_get_hw_interface (vnm, hw_if_index);
   vlib_main_t *vm = vnm->vlib_main;
-
+  vnet_device_class_t *dev_class = vnet_get_device_class (vnm,
+                                                         hw->dev_class_index);
   /* If it is up, mark it down. */
   if (hw->flags != 0)
     vnet_hw_interface_set_flags (vnm, hw_if_index, /* flags */ 0);
@@ -904,41 +926,50 @@ vnet_delete_hw_interface (vnet_main_t * vnm, u32 hw_if_index)
   /* Call delete callbacks. */
   call_hw_interface_add_del_callbacks (vnm, hw_if_index, /* is_create */ 0);
 
-  /* Delete software interface corresponding to hardware interface. */
-  vnet_delete_sw_interface (vnm, hw->sw_if_index);
-
   /* Delete any sub-interfaces. */
   {
     u32 id, sw_if_index;
     /* *INDENT-OFF* */
-    hash_foreach (id, sw_if_index, hw->sub_interface_sw_if_index_by_id, ({
+    hash_foreach (id, sw_if_index, hw->sub_interface_sw_if_index_by_id,
+    ({
+      vnet_sw_interface_t *si = vnet_get_sw_interface (vnm, sw_if_index);
+      u64 sup_and_sub_key =
+       ((u64) (si->sup_sw_if_index) << 32) | (u64) si->sub.id;
+      hash_unset_mem_free (&im->sw_if_index_by_sup_and_sub, &sup_and_sub_key);
       vnet_delete_sw_interface (vnm, sw_if_index);
     }));
+    hash_free (hw->sub_interface_sw_if_index_by_id);
     /* *INDENT-ON* */
   }
 
-  {
-    vnet_hw_interface_nodes_t *dn;
+  /* Delete software interface corresponding to hardware interface. */
+  vnet_delete_sw_interface (vnm, hw->sw_if_index);
 
-    /* *INDENT-OFF* */
-    foreach_vlib_main ({
-      vnet_interface_output_runtime_t *rt =
-        vlib_node_get_runtime_data (this_vlib_main, hw->output_node_index);
-
-      /* Mark node runtime as deleted so output node (if called)
-       * will drop packets. */
-      rt->is_deleted = 1;
-    });
-    /* *INDENT-ON* */
+  if (dev_class->tx_function)
+    {
+      /* Put output/tx nodes into recycle pool */
+      vnet_hw_interface_nodes_t *dn;
 
-    vlib_node_rename (vm, hw->output_node_index,
-                     "interface-%d-output-deleted", hw_if_index);
-    vlib_node_rename (vm, hw->tx_node_index, "interface-%d-tx-deleted",
-                     hw_if_index);
-    vec_add2 (im->deleted_hw_interface_nodes, dn, 1);
-    dn->tx_node_index = hw->tx_node_index;
-    dn->output_node_index = hw->output_node_index;
-  }
+      /* *INDENT-OFF* */
+      foreach_vlib_main
+       ({
+         vnet_interface_output_runtime_t *rt =
+           vlib_node_get_runtime_data (this_vlib_main, hw->output_node_index);
+
+         /* Mark node runtime as deleted so output node (if called)
+          * will drop packets. */
+         rt->is_deleted = 1;
+       });
+      /* *INDENT-ON* */
+
+      vlib_node_rename (vm, hw->output_node_index,
+                       "interface-%d-output-deleted", hw_if_index);
+      vlib_node_rename (vm, hw->tx_node_index, "interface-%d-tx-deleted",
+                       hw_if_index);
+      vec_add2 (im->deleted_hw_interface_nodes, dn, 1);
+      dn->tx_node_index = hw->tx_node_index;
+      dn->output_node_index = hw->output_node_index;
+    }
 
   hash_unset_mem (im->hw_interface_by_name, hw->name);
   vec_free (hw->name);