misc: minimize dependencies on udp.h
[vpp.git] / src / vnet / vxlan-gpe / vxlan_gpe.c
index a7eaba6..979d98c 100644 (file)
 #include <vnet/ip/format.h>
 #include <vnet/fib/fib_entry.h>
 #include <vnet/fib/fib_table.h>
+#include <vnet/fib/fib_entry_track.h>
 #include <vnet/mfib/mfib_table.h>
 #include <vnet/adj/adj_mcast.h>
 #include <vnet/interface.h>
+#include <vnet/udp/udp_local.h>
 #include <vlib/vlib.h>
 
 /**
@@ -383,35 +385,6 @@ vxlan6_gpe_rewrite (vxlan_gpe_tunnel_t * t, u32 extension_size,
   return (0);
 }
 
-static uword
-vtep_addr_ref (ip46_address_t * ip)
-{
-  uword *vtep = ip46_address_is_ip4 (ip) ?
-    hash_get (vxlan_gpe_main.vtep4, ip->ip4.as_u32) :
-    hash_get_mem (vxlan_gpe_main.vtep6, &ip->ip6);
-  if (vtep)
-    return ++(*vtep);
-  ip46_address_is_ip4 (ip) ?
-    hash_set (vxlan_gpe_main.vtep4, ip->ip4.as_u32, 1) :
-    hash_set_mem_alloc (&vxlan_gpe_main.vtep6, &ip->ip6, 1);
-  return 1;
-}
-
-static uword
-vtep_addr_unref (ip46_address_t * ip)
-{
-  uword *vtep = ip46_address_is_ip4 (ip) ?
-    hash_get (vxlan_gpe_main.vtep4, ip->ip4.as_u32) :
-    hash_get_mem (vxlan_gpe_main.vtep6, &ip->ip6);
-  ASSERT (vtep);
-  if (--(*vtep) != 0)
-    return *vtep;
-  ip46_address_is_ip4 (ip) ?
-    hash_unset (vxlan_gpe_main.vtep4, ip->ip4.as_u32) :
-    hash_unset_mem_free (&vxlan_gpe_main.vtep6, &ip->ip6);
-  return 0;
-}
-
 /* *INDENT-OFF* */
 typedef CLIB_PACKED(union {
   struct {
@@ -427,7 +400,7 @@ mcast_shared_get (ip46_address_t * ip)
 {
   ASSERT (ip46_address_is_multicast (ip));
   uword *p = hash_get_mem (vxlan_gpe_main.mcast_shared, ip);
-  ASSERT (p);
+  ALWAYS_ASSERT (p);
   return (mcast_shared_t)
   {
   .as_u64 = *p};
@@ -619,13 +592,12 @@ int vnet_vxlan_gpe_add_del_tunnel
           * when the forwarding for the entry updates, and the tunnel can
           * re-stack accordingly
           */
-         vtep_addr_ref (&t->local);
-         t->fib_entry_index = fib_table_entry_special_add
-           (t->encap_fib_index, &tun_remote_pfx, FIB_SOURCE_RR,
-            FIB_ENTRY_FLAG_NONE);
-         t->sibling_index = fib_entry_child_add
-           (t->fib_entry_index, FIB_NODE_TYPE_VXLAN_GPE_TUNNEL,
-            t - ngm->tunnels);
+         vtep_addr_ref (&ngm->vtep_table, t->encap_fib_index, &t->local);
+         t->fib_entry_index = fib_entry_track (t->encap_fib_index,
+                                               &tun_remote_pfx,
+                                               FIB_NODE_TYPE_VXLAN_GPE_TUNNEL,
+                                               t - ngm->tunnels,
+                                               &t->sibling_index);
          vxlan_gpe_tunnel_restack_dpo (t);
        }
       else
@@ -637,7 +609,8 @@ int vnet_vxlan_gpe_add_del_tunnel
           */
          fib_protocol_t fp = fib_ip_proto (is_ip6);
 
-         if (vtep_addr_ref (&t->remote) == 1)
+         if (vtep_addr_ref (&ngm->vtep_table,
+                            t->encap_fib_index, &t->remote) == 1)
            {
              fib_node_index_t mfei;
              adj_index_t ai;
@@ -646,8 +619,9 @@ int vnet_vxlan_gpe_add_del_tunnel
                .frp_addr = zero_addr,
                .frp_sw_if_index = 0xffffffff,
                .frp_fib_index = ~0,
-               .frp_weight = 0,
+               .frp_weight = 1,
                .frp_flags = FIB_ROUTE_PATH_LOCAL,
+               .frp_mitf_flags = MFIB_ITF_FLAG_FORWARD,
              };
              const mfib_prefix_t mpfx = {
                .fp_proto = fp,
@@ -662,16 +636,15 @@ int vnet_vxlan_gpe_add_del_tunnel
               */
              mfib_table_entry_path_update (t->encap_fib_index,
                                            &mpfx,
-                                           MFIB_SOURCE_VXLAN_GPE,
-                                           &path, MFIB_ITF_FLAG_FORWARD);
+                                           MFIB_SOURCE_VXLAN_GPE, &path);
 
              path.frp_sw_if_index = a->mcast_sw_if_index;
              path.frp_flags = FIB_ROUTE_PATH_FLAG_NONE;
+             path.frp_mitf_flags = MFIB_ITF_FLAG_ACCEPT;
              mfei = mfib_table_entry_path_update (t->encap_fib_index,
                                                   &mpfx,
                                                   MFIB_SOURCE_VXLAN_GPE,
-                                                  &path,
-                                                  MFIB_ITF_FLAG_ACCEPT);
+                                                  &path);
 
              /*
               * Create the mcast adjacency to send traffic to the group
@@ -726,11 +699,11 @@ int vnet_vxlan_gpe_add_del_tunnel
 
       if (!ip46_address_is_multicast (&t->remote))
        {
-         vtep_addr_unref (&t->local);
-         fib_entry_child_remove (t->fib_entry_index, t->sibling_index);
-         fib_table_entry_delete_index (t->fib_entry_index, FIB_SOURCE_RR);
+         vtep_addr_unref (&ngm->vtep_table, t->encap_fib_index, &t->local);
+         fib_entry_untrack (t->fib_entry_index, t->sibling_index);
        }
-      else if (vtep_addr_unref (&t->remote) == 0)
+      else if (vtep_addr_unref (&ngm->vtep_table,
+                               t->encap_fib_index, &t->remote) == 0)
        {
          mcast_shared_remove (&t->remote);
        }
@@ -743,6 +716,17 @@ int vnet_vxlan_gpe_add_del_tunnel
   if (sw_if_indexp)
     *sw_if_indexp = sw_if_index;
 
+  if (a->is_add)
+    {
+      /* register udp ports */
+      if (!is_ip6 && !udp_is_valid_dst_port (UDP_DST_PORT_VXLAN_GPE, 1))
+       udp_register_dst_port (ngm->vlib_main, UDP_DST_PORT_VXLAN_GPE,
+                              vxlan4_gpe_input_node.index, 1 /* is_ip4 */ );
+      if (is_ip6 && !udp_is_valid_dst_port (UDP_DST_PORT_VXLAN6_GPE, 0))
+       udp_register_dst_port (ngm->vlib_main, UDP_DST_PORT_VXLAN6_GPE,
+                              vxlan6_gpe_input_node.index, 0 /* is_ip4 */ );
+    }
+
   return 0;
 }
 
@@ -976,9 +960,9 @@ done:
  *
  * @cliexpar
  * Example of how to create a VXLAN-GPE Tunnel:
- * @cliexcmd{create vxlan-gpe tunnel local 10.0.3.1 local 10.0.3.3 vni 13 encap-vrf-id 7}
- * Example of how to delete a VXLAN Tunnel:
- * @cliexcmd{create vxlan tunnel src 10.0.3.1 remote 10.0.3.3 vni 13 del}
+ * @cliexcmd{create vxlan-gpe tunnel local 10.0.3.1 remote 10.0.3.3 vni 13 encap-vrf-id 7}
+ * Example of how to delete a VXLAN-GPE Tunnel:
+ * @cliexcmd{create vxlan-gpe tunnel local 10.0.3.1 remote 10.0.3.3 vni 13 del}
  ?*/
 /* *INDENT-OFF* */
 VLIB_CLI_COMMAND (create_vxlan_gpe_tunnel_command, static) = {
@@ -1205,7 +1189,7 @@ set_ip6_vxlan_gpe_bypass (vlib_main_t * vm,
 VLIB_CLI_COMMAND (set_interface_ip6_vxlan_gpe_bypass_command, static) = {
   .path = "set interface ip6 vxlan-gpe-bypass",
   .function = set_ip6_vxlan_gpe_bypass,
-  .short_help = "set interface ip vxlan-gpe-bypass <interface> [del]",
+  .short_help = "set interface ip6 vxlan-gpe-bypass <interface> [del]",
 };
 /* *INDENT-ON* */
 
@@ -1251,12 +1235,7 @@ vxlan_gpe_init (vlib_main_t * vm)
   ngm->mcast_shared = hash_create_mem (0,
                                       sizeof (ip46_address_t),
                                       sizeof (mcast_shared_t));
-  ngm->vtep6 = hash_create_mem (0, sizeof (ip6_address_t), sizeof (uword));
-
-  udp_register_dst_port (vm, UDP_DST_PORT_VXLAN_GPE,
-                        vxlan4_gpe_input_node.index, 1 /* is_ip4 */ );
-  udp_register_dst_port (vm, UDP_DST_PORT_VXLAN6_GPE,
-                        vxlan6_gpe_input_node.index, 0 /* is_ip4 */ );
+  ngm->vtep_table = vtep_table_create ();
 
   /* Register the list of standard decap protocols supported */
   vxlan_gpe_register_decap_protocol (VXLAN_GPE_PROTOCOL_IP4,