ip: Protocol Independent IP Neighbors
[vpp.git] / src / plugins / gbp / gbp_endpoint.c
index 611e344..9ef0890 100644 (file)
 #include <plugins/gbp/gbp_policy_dpo.h>
 #include <plugins/gbp/gbp_vxlan.h>
 
-#include <vnet/ethernet/arp.h>
 #include <vnet/l2/l2_input.h>
 #include <vnet/l2/l2_output.h>
 #include <vnet/l2/feat_bitmap.h>
 #include <vnet/l2/l2_fib.h>
 #include <vnet/fib/fib_table.h>
-#include <vnet/ip/ip_neighbor.h>
+#include <vnet/ip-neighbor/ip_neighbor.h>
 #include <vnet/fib/fib_walk.h>
 #include <vnet/vxlan-gbp/vxlan_gbp.h>
 
@@ -41,9 +40,10 @@ static const char *gbp_endpoint_attr_names[] = GBP_ENDPOINT_ATTR_NAMES;
  */
 gbp_ep_db_t gbp_ep_db;
 
-fib_node_type_t gbp_endpoint_fib_type;
-
-vlib_log_class_t gbp_ep_logger;
+static fib_source_t gbp_fib_source_hi;
+static fib_source_t gbp_fib_source_low;
+static fib_node_type_t gbp_endpoint_fib_type;
+static vlib_log_class_t gbp_ep_logger;
 
 #define GBP_ENDPOINT_DBG(...)                           \
     vlib_log_debug (gbp_ep_logger, __VA_ARGS__);
@@ -207,12 +207,6 @@ gbp_endpoint_index (const gbp_endpoint_t * ge)
   return (ge - gbp_endpoint_pool);
 }
 
-static ip46_type_t
-ip46_address_get_type (const ip46_address_t * a)
-{
-  return (ip46_address_is_ip4 (a) ? IP46_TYPE_IP4 : IP46_TYPE_IP6);
-}
-
 static int
 gbp_endpoint_ip_is_equal (const fib_prefix_t * fp, const ip46_address_t * ip)
 {
@@ -588,10 +582,10 @@ gbb_endpoint_fwd_reset (gbp_endpoint_t * ge)
      */
     if (gbp_endpoint_is_remote (ge))
       {
-       fib_table_entry_special_remove (fib_index, pfx, FIB_SOURCE_PLUGIN_HI);
+       fib_table_entry_special_remove (fib_index, pfx, gbp_fib_source_hi);
       }
 
-    fib_table_entry_delete (fib_index, pfx, FIB_SOURCE_PLUGIN_LOW);
+    fib_table_entry_delete (fib_index, pfx, gbp_fib_source_low);
   }
   vec_foreach (ai, gef->gef_adjs)
   {
@@ -726,7 +720,7 @@ gbb_endpoint_fwd_recalc (gbp_endpoint_t * ge)
       }
 
     fib_table_entry_path_add (fib_index, pfx,
-                             FIB_SOURCE_PLUGIN_LOW,
+                             gbp_fib_source_low,
                              FIB_ENTRY_FLAG_NONE,
                              fib_proto_to_dpo (pfx->fp_proto),
                              &pfx->fp_addr, ip_sw_if_index,
@@ -759,7 +753,7 @@ gbb_endpoint_fwd_recalc (gbp_endpoint_t * ge)
                                        gg->gg_sclass, ~0, &policy_dpo);
 
            fib_table_entry_special_dpo_add (fib_index, pfx,
-                                            FIB_SOURCE_PLUGIN_HI,
+                                            gbp_fib_source_hi,
                                             FIB_ENTRY_FLAG_INTERPOSE,
                                             &policy_dpo);
            dpo_reset (&policy_dpo);
@@ -774,14 +768,11 @@ gbb_endpoint_fwd_recalc (gbp_endpoint_t * ge)
          {
            gbp_endpoint_add_itf (gbp_itf_get_sw_if_index (gef->gef_itf),
                                  gei);
-           if (FIB_PROTOCOL_IP4 == pfx->fp_proto)
-             send_ip4_garp_w_addr (vlib_get_main (),
-                                   &pfx->fp_addr.ip4,
-                                   gg->gg_uplink_sw_if_index);
-           else
-             send_ip6_na_w_addr (vlib_get_main (),
-                                 &pfx->fp_addr.ip6,
-                                 gg->gg_uplink_sw_if_index);
+           ip_neighbor_advertise (vlib_get_main (),
+                                  (FIB_PROTOCOL_IP4 == pfx->fp_proto ?
+                                   IP46_TYPE_IP4 :
+                                   IP46_TYPE_IP6),
+                                  &pfx->fp_addr, gg->gg_uplink_sw_if_index);
          }
       }
   }
@@ -1083,6 +1074,7 @@ gbp_endpoint_cli (vlib_main_t * vm,
   u32 sclass = SCLASS_INVALID;
   u32 handle = INDEX_INVALID;
   u32 sw_if_index = ~0;
+  u32 flags = GBP_ENDPOINT_FLAG_NONE;
   u8 add = 1;
   int rv;
 
@@ -1107,6 +1099,8 @@ gbp_endpoint_cli (vlib_main_t * vm,
        vec_add1 (ips, ip);
       else if (unformat (input, "mac %U", unformat_mac_address, &mac))
        ;
+      else if (unformat (input, "flags 0x%x", &flags))
+       ;
       else
        break;
     }
@@ -1122,9 +1116,7 @@ gbp_endpoint_cli (vlib_main_t * vm,
        gbp_endpoint_update_and_lock (GBP_ENDPOINT_SRC_CP,
                                      sw_if_index, ips, &mac,
                                      INDEX_INVALID, INDEX_INVALID,
-                                     sclass,
-                                     GBP_ENDPOINT_FLAG_NONE,
-                                     NULL, NULL, &handle);
+                                     sclass, flags, NULL, NULL, &handle);
 
       if (rv)
        return clib_error_return (0, "GBP Endpoint update returned %d", rv);
@@ -1148,13 +1140,13 @@ gbp_endpoint_cli (vlib_main_t * vm,
  * Configure a GBP Endpoint
  *
  * @cliexpar
- * @cliexstart{set gbp endpoint [del] <interface> epg <ID> ip <IP>}
+ * @cliexstart{gbp endpoint del <handle> | [add] <interface> sclass <SCLASS> ip <IP> mac <MAC> [flags <flags>]}
  * @cliexend
  ?*/
 /* *INDENT-OFF* */
 VLIB_CLI_COMMAND (gbp_endpoint_cli_node, static) = {
   .path = "gbp endpoint",
-  .short_help = "gbp endpoint [del] <interface> epg <ID> ip <IP> mac <MAC>",
+  .short_help = "gbp endpoint del <handle> | [add] <interface> sclass <SCLASS> ip <IP> mac <MAC> [flags <flags>]",
   .function = gbp_endpoint_cli,
 };
 /* *INDENT-ON* */
@@ -1266,8 +1258,8 @@ gbp_endpoint_show_one (index_t gei, void *ctx)
   return (WALK_CONTINUE);
 }
 
-static void
-gbp_endpoint_walk_ip_itf (const clib_bihash_kv_24_8_t * kvp, void *arg)
+static int
+gbp_endpoint_walk_ip_itf (clib_bihash_kv_24_8_t * kvp, void *arg)
 {
   ip46_address_t ip;
   vlib_main_t *vm;
@@ -1281,10 +1273,11 @@ gbp_endpoint_walk_ip_itf (const clib_bihash_kv_24_8_t * kvp, void *arg)
                   format_ip46_address, &ip, IP46_TYPE_ANY,
                   format_vnet_sw_if_index_name, vnet_get_main (),
                   sw_if_index, kvp->value);
+  return (BIHASH_WALK_CONTINUE);
 }
 
-static void
-gbp_endpoint_walk_mac_itf (const clib_bihash_kv_16_8_t * kvp, void *arg)
+static int
+gbp_endpoint_walk_mac_itf (clib_bihash_kv_16_8_t * kvp, void *arg)
 {
   mac_address_t mac;
   vlib_main_t *vm;
@@ -1298,6 +1291,7 @@ gbp_endpoint_walk_mac_itf (const clib_bihash_kv_16_8_t * kvp, void *arg)
                   format_mac_address_t, &mac,
                   format_vnet_sw_if_index_name, vnet_get_main (),
                   sw_if_index, kvp->value);
+  return (BIHASH_WALK_CONTINUE);
 }
 
 static clib_error_t *
@@ -1384,6 +1378,9 @@ gbp_endpoint_scan_l2 (vlib_main_t * vm)
   f64 last_start, start_time, delta_t;
   int i, j, k;
 
+  if (!gte_table->instantiated)
+    return;
+
   delta_t = 0;
   last_start = start_time = vlib_time_now (vm);
 
@@ -1436,6 +1433,9 @@ gbp_endpoint_scan_l3 (vlib_main_t * vm)
   f64 last_start, start_time, delta_t;
   int i, j, k;
 
+  if (!gte_table->instantiated)
+    return;
+
   delta_t = 0;
   last_start = start_time = vlib_time_now (vm);
 
@@ -1569,6 +1569,12 @@ gbp_endpoint_init (vlib_main_t * vm)
 
   gbp_ep_logger = vlib_log_register_class ("gbp", "ep");
   gbp_endpoint_fib_type = fib_node_register_new_type (&gbp_endpoint_vft);
+  gbp_fib_source_hi = fib_source_allocate ("gbp-endpoint-hi",
+                                          FIB_SOURCE_PRIORITY_HI,
+                                          FIB_SOURCE_BH_SIMPLE);
+  gbp_fib_source_low = fib_source_allocate ("gbp-endpoint-low",
+                                           FIB_SOURCE_PRIORITY_LOW,
+                                           FIB_SOURCE_BH_SIMPLE);
 
   return (NULL);
 }