fib: fix crash when create vxlan/vxlan-gpe/geneve/gtpu tunnel.
[vpp.git] / src / vnet / vxlan / vxlan.c
index 484b7c2..1871e5d 100644 (file)
@@ -52,6 +52,14 @@ vxlan_eth_flag_change (vnet_main_t *vnm, vnet_hw_interface_t *hi, u32 flags)
   return 0;
 }
 
+static clib_error_t *
+vxlan_eth_set_max_frame_size (vnet_main_t *vnm, vnet_hw_interface_t *hw,
+                             u32 frame_size)
+{
+  /* nothing for now */
+  return 0;
+}
+
 static u8 *
 format_decap_next (u8 * s, va_list * args)
 {
@@ -82,8 +90,6 @@ format_vxlan_tunnel (u8 * s, va_list * args)
   if (PREDICT_FALSE (t->decap_next_index != VXLAN_INPUT_NEXT_L2_INPUT))
     s = format (s, "decap-next-%U ", format_decap_next, t->decap_next_index);
 
-  s = format (s, "l3 %u ", t->is_l3);
-
   if (PREDICT_FALSE (ip46_address_is_multicast (&t->dst)))
     s = format (s, "mcast-sw-if-idx %d ", t->mcast_sw_if_index);
 
@@ -247,8 +253,7 @@ const static fib_node_vft_t vxlan_vft = {
   _ (src)                                                                     \
   _ (dst)                                                                     \
   _ (src_port)                                                                \
-  _ (dst_port)                                                                \
-  _ (is_l3)
+  _ (dst_port)
 
 static void
 vxlan_rewrite (vxlan_tunnel_t * t, bool is_ip6)
@@ -451,12 +456,13 @@ int vnet_vxlan_add_del_tunnel
       t->user_instance = user_instance; /* name */
       t->flow_index = ~0;
 
-      if (a->is_l3 == 0)
+      if (a->is_l3)
        t->hw_if_index =
          vnet_register_interface (vnm, vxlan_device_class.index, dev_instance,
                                   vxlan_hw_class.index, dev_instance);
       else
        {
+         vnet_eth_interface_registration_t eir = {};
          f64 now = vlib_time_now (vm);
          u32 rnd;
          rnd = (u32) (now * 1e6);
@@ -464,15 +470,13 @@ int vnet_vxlan_add_del_tunnel
          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))
-           {
-             hash_unset (vxm->instance_used, t->user_instance);
 
-             pool_put (vxm->tunnels, t);
-             return VNET_API_ERROR_SYSCALL_ERROR_2;
-           }
+         eir.dev_class_index = vxlan_device_class.index;
+         eir.dev_instance = dev_instance;
+         eir.address = hw_addr;
+         eir.cb.flag_change = vxlan_eth_flag_change;
+         eir.cb.set_max_frame_size = vxlan_eth_set_max_frame_size;
+         t->hw_if_index = vnet_eth_register_interface (vnm, &eir);
        }
 
       vnet_hw_interface_t *hi = vnet_get_hw_interface (vnm, t->hw_if_index);
@@ -506,7 +510,7 @@ int vnet_vxlan_add_del_tunnel
 
       if (add_failed)
        {
-         if (a->is_l3 == 0)
+         if (a->is_l3)
            vnet_delete_hw_interface (vnm, t->hw_if_index);
          else
            ethernet_delete_interface (vnm, t->hw_if_index);
@@ -533,7 +537,8 @@ int vnet_vxlan_add_del_tunnel
       fib_prefix_t tun_dst_pfx;
       vnet_flood_class_t flood_class = VNET_FLOOD_CLASS_TUNNEL_NORMAL;
 
-      fib_prefix_from_ip46_addr (&t->dst, &tun_dst_pfx);
+      fib_protocol_t fp = fib_ip_proto (is_ip6);
+      fib_prefix_from_ip46_addr (fp, &t->dst, &tun_dst_pfx);
       if (!ip46_address_is_multicast (&t->dst))
        {
          /* Unicast tunnel -
@@ -557,8 +562,6 @@ int vnet_vxlan_add_del_tunnel
           * with different VNIs, create the output fib adjacency only if
           * it does not already exist
           */
-         fib_protocol_t fp = fib_ip_proto (is_ip6);
-
          if (vtep_addr_ref (&vxm->vtep_table,
                             t->encap_fib_index, &t->dst) == 1)
            {
@@ -659,7 +662,8 @@ int vnet_vxlan_add_del_tunnel
          mcast_shared_remove (&t->dst);
        }
 
-      if (t->is_l3 == 0)
+      vnet_hw_interface_t *hw = vnet_get_hw_interface (vnm, t->hw_if_index);
+      if (hw->dev_class_index == vxlan_device_class.index)
        vnet_delete_hw_interface (vnm, t->hw_if_index);
       else
        ethernet_delete_interface (vnm, t->hw_if_index);
@@ -846,6 +850,7 @@ vxlan_add_del_tunnel_command_fn (vlib_main_t * vm,
 
   vnet_vxlan_add_del_tunnel_args_t a = { .is_add = is_add,
                                         .is_ip6 = ipv6_set,
+                                        .is_l3 = is_l3,
                                         .instance = instance,
 #define _(x) .x = x,
                                         foreach_copy_field