vxlan: fix SEGV reported in VPP-1962 06/30806/10
authorEd Warnicke <hagbard@gmail.com>
Mon, 18 Jan 2021 17:56:22 +0000 (11:56 -0600)
committerFlorin Coras <florin.coras@gmail.com>
Wed, 20 Jan 2021 17:53:01 +0000 (17:53 +0000)
Type: fix

Replace vnet_register_interface with ethernet_register_interface

Fixes https://jira.fd.io/browse/VPP-1962

Signed-off-by: Ed Warnicke <hagbard@gmail.com>
Change-Id: I5f578fc416605429fe1e2b510ad49eb754451d40
Signed-off-by: Ed Warnicke <hagbard@gmail.com>
src/vnet/vxlan/vxlan.c

index 71d03f6..300aae4 100644 (file)
 
 vxlan_main_t vxlan_main;
 
+static u32
+vxlan_eth_flag_change (vnet_main_t *vnm, vnet_hw_interface_t *hi, u32 flags)
+{
+  /* nothing for now */
+  return 0;
+}
+
 static u8 *
 format_decap_next (u8 * s, va_list * args)
 {
@@ -355,6 +362,8 @@ int vnet_vxlan_add_del_tunnel
   vxlan4_tunnel_key_t key4;
   vxlan6_tunnel_key_t key6;
   u32 is_ip6 = a->is_ip6;
+  vlib_main_t *vm = vlib_get_main ();
+  u8 hw_addr[6];
 
   int not_found;
   if (!is_ip6)
@@ -421,15 +430,30 @@ int vnet_vxlan_add_del_tunnel
          pool_put (vxm->tunnels, t);
          return VNET_API_ERROR_INSTANCE_IN_USE;
        }
+
+      f64 now = vlib_time_now (vm);
+      u32 rnd;
+      rnd = (u32) (now * 1e6);
+      rnd = random_u32 (&rnd);
+
+      memcpy (hw_addr + 2, &rnd, sizeof (rnd));
+      hw_addr[0] = 2;
+      hw_addr[1] = 0xfe;
+
+      if (ethernet_register_interface (vnm, vxlan_device_class.index,
+                                      dev_instance, hw_addr, &t->hw_if_index,
+                                      vxlan_eth_flag_change))
+       {
+         pool_put (vxm->tunnels, t);
+         return VNET_API_ERROR_SYSCALL_ERROR_2;
+       }
+
       hash_set (vxm->instance_used, user_instance, 1);
 
       t->dev_instance = dev_instance;  /* actual */
       t->user_instance = user_instance;        /* name */
       t->flow_index = ~0;
 
-      t->hw_if_index = vnet_register_interface
-       (vnm, vxlan_device_class.index, dev_instance,
-        vxlan_hw_class.index, dev_instance);
       vnet_hw_interface_t *hi = vnet_get_hw_interface (vnm, t->hw_if_index);
 
       /* Set vxlan tunnel output node */
@@ -461,7 +485,7 @@ int vnet_vxlan_add_del_tunnel
 
       if (add_failed)
        {
-         vnet_delete_hw_interface (vnm, t->hw_if_index);
+         ethernet_delete_interface (vnm, t->hw_if_index);
          hash_unset (vxm->instance_used, t->user_instance);
          pool_put (vxm->tunnels, t);
          return VNET_API_ERROR_INVALID_REGISTRATION;
@@ -610,7 +634,7 @@ int vnet_vxlan_add_del_tunnel
          mcast_shared_remove (&t->dst);
        }
 
-      vnet_delete_hw_interface (vnm, t->hw_if_index);
+      ethernet_delete_interface (vnm, t->hw_if_index);
       hash_unset (vxm->instance_used, t->user_instance);
 
       fib_node_deinit (&t->node);