VPP-376: Refactor LISP dump API + VAT
[vpp.git] / vnet / vnet / lisp-cp / control.c
index 2fd1dce..16d7bfa 100644 (file)
@@ -235,7 +235,7 @@ dp_del_fwd_entry (lisp_cp_main_t * lcm, u32 src_map_index, u32 dst_map_index)
   u32 sw_if_index;
   a->is_add = 0;
   a->locator_pairs = fe->locator_pairs;
-  a->vni = gid_address_vni (&a->rmt_eid);
+  a->vni = gid_address_vni (&fe->deid);
   gid_address_copy (&a->rmt_eid, &fe->deid);
 
   vnet_lisp_gpe_add_del_fwd_entry (a, &sw_if_index);
@@ -445,6 +445,7 @@ vnet_lisp_map_cache_add_del (vnet_lisp_add_del_mapping_args_t * a,
       m->ttl = a->ttl;
       m->action = a->action;
       m->local = a->local;
+      m->is_static = a->is_static;
 
       map_index = m - lcm->mapping_pool;
       gid_dictionary_add_del (&lcm->mapping_index_by_gid, &a->eid, map_index,
@@ -767,11 +768,13 @@ compare_locators (lisp_cp_main_t * lcm, u32 * old_ls_indexes,
  * @param is_add add mapping if non-zero, delete otherwise
  * @param res_map_index the map-index that was created/updated/removed. It is
  *                      set to ~0 if no action is taken.
+ * @param is_static used for distinguishing between statically learned
+                    remote mappings and mappings obtained from MR
  * @return return code
  */
 int
 vnet_lisp_add_del_mapping (gid_address_t * eid, locator_t * rlocs, u8 action,
-                          u8 authoritative, u32 ttl, u8 is_add,
+                          u8 authoritative, u32 ttl, u8 is_add, u8 is_static,
                           u32 * res_map_index)
 {
   vnet_lisp_add_del_mapping_args_t _m_args, *m_args = &_m_args;
@@ -803,6 +806,15 @@ vnet_lisp_add_del_mapping (gid_address_t * eid, locator_t * rlocs, u8 action,
        * updated and be done */
       if (old_map && gid_address_cmp (&old_map->eid, eid) == 0)
        {
+         if (!is_static && (old_map->is_static || old_map->local))
+           {
+             /* do not overwrite local or static remote mappings */
+             clib_warning ("mapping %U rejected due to collision with local "
+                           "or static remote mapping!", format_gid_address,
+                           &eid);
+             return 0;
+           }
+
          locator_set_t *old_ls;
 
          /* update mapping attributes */
@@ -836,6 +848,7 @@ vnet_lisp_add_del_mapping (gid_address_t * eid, locator_t * rlocs, u8 action,
          m_args->is_add = 1;
          m_args->action = action;
          m_args->locator_set_index = ls_index;
+         m_args->is_static = is_static;
          vnet_lisp_map_cache_add_del (m_args, &dst_map_index);
 
          if (res_map_index)
@@ -1036,6 +1049,12 @@ lisp_add_del_remote_mapping_command_fn (vlib_main_t * vm,
       else if (unformat (line_input, "rloc %U", unformat_ip_address,
                         &gid_address_ip (&rloc.address)))
        {
+         /* since rloc is stored in ip prefix we need to set prefix length */
+         ip_prefix_t *pref = &gid_address_ippref (&rloc.address);
+
+         u8 version = gid_address_ip_version (&rloc.address);
+         ip_prefix_len (pref) = ip_address_max_len (version);
+
          vec_add1 (rlocs, rloc);
          curr_rloc = &rlocs[vec_len (rlocs) - 1];
        }
@@ -1084,7 +1103,8 @@ lisp_add_del_remote_mapping_command_fn (vlib_main_t * vm,
 
   /* add as static remote mapping, i.e., not authoritative and infinite
    * ttl */
-  rv = vnet_lisp_add_del_mapping (&eid, rlocs, action, 0, ~0, is_add, 0);
+  rv = vnet_lisp_add_del_mapping (&eid, rlocs, action, 0, ~0, is_add,
+                                 1 /* is_static */ , 0);
 
   if (rv)
     clib_warning ("failed to %s remote mapping!", is_add ? "add" : "delete");
@@ -1696,7 +1716,7 @@ vnet_lisp_add_del_locator (vnet_lisp_add_del_locator_set_args_t * a,
        vec_validate (lcm->locator_to_locator_sets, loc_index);
        ls_indexes = vec_elt_at_index (lcm->locator_to_locator_sets,
                                       loc_index);
-       vec_add1 (ls_indexes[0], ls_index);
+       vec_add1 (ls_indexes[0], p[0]);
       }
     }
   else
@@ -1991,12 +2011,42 @@ lisp_show_eid_table_map_command_fn (vlib_main_t * vm,
                                    vlib_cli_command_t * cmd)
 {
   hash_pair_t *p;
+  unformat_input_t _line_input, *line_input = &_line_input;
   lisp_cp_main_t *lcm = vnet_lisp_cp_get_main ();
+  uword *vni_table = 0;
+  u8 is_l2 = 0;
+
+  /* Get a line of input. */
+  if (!unformat_user (input, unformat_line_input, line_input))
+    return 0;
+
+  while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
+    {
+      if (unformat (line_input, "l2"))
+       {
+         vni_table = lcm->bd_id_by_vni;
+         is_l2 = 1;
+       }
+      else if (unformat (line_input, "l3"))
+       {
+         vni_table = lcm->table_id_by_vni;
+         is_l2 = 0;
+       }
+      else
+       return clib_error_return (0, "parse error: '%U'",
+                                 format_unformat_error, line_input);
+    }
 
-  vlib_cli_output (vm, "%=10s%=10s", "VNI", "VRF");
+  if (!vni_table)
+    {
+      vlib_cli_output (vm, "Error: expected l2|l3 param!\n");
+      return 0;
+    }
+
+  vlib_cli_output (vm, "%=10s%=10s", "VNI", is_l2 ? "BD" : "VRF");
 
   /* *INDENT-OFF* */
-  hash_foreach_pair (p, lcm->table_id_by_vni,
+  hash_foreach_pair (p, vni_table,
   ({
     vlib_cli_output (vm, "%=10d%=10d", p->key, p->value[0]);
   }));
@@ -2008,7 +2058,7 @@ lisp_show_eid_table_map_command_fn (vlib_main_t * vm,
 /* *INDENT-OFF* */
 VLIB_CLI_COMMAND (lisp_show_eid_table_map_command) = {
     .path = "show lisp eid-table map",
-    .short_help = "show lisp eid-table vni to vrf mappings",
+    .short_help = "show lisp eid-table l2|l3",
     .function = lisp_show_eid_table_map_command_fn,
 };
 /* *INDENT-ON* */
@@ -2169,7 +2219,7 @@ lisp_cp_show_locator_sets_command_fn (vlib_main_t * vm,
   u32 *locit;
   lisp_cp_main_t *lcm = vnet_lisp_cp_get_main ();
 
-  vlib_cli_output (vm, "%=20s%=16s%=16s%=16s", "Locator-set", "Locator",
+  vlib_cli_output (vm, "%s%=16s%=16s%=16s", "Locator-set", "Locator",
                   "Priority", "Weight");
 
   /* *INDENT-OFF* */
@@ -2179,11 +2229,11 @@ lisp_cp_show_locator_sets_command_fn (vlib_main_t * vm,
     int next_line = 0;
     if (lsit->local)
       {
-        msg = format (msg, "%=16v", lsit->name);
+        msg = format (msg, "%v", lsit->name);
       }
     else
       {
-        msg = format (msg, "%=16s", "remote");
+        msg = format (msg, "<%s-%d>", "remote", lsit - lcm->locator_set_pool);
       }
     vec_foreach (locit, lsit->locator_indices)
       {
@@ -3004,12 +3054,8 @@ lisp_cp_lookup (vlib_main_t * vm, vlib_node_runtime_t * node,
 
              memset (tr, 0, sizeof (*tr));
              gid_address_copy (&tr->dst_eid, &dst);
-             if (vec_len (lcm->map_resolvers) > 0)
-               {
-                 clib_memcpy (&tr->map_resolver_ip,
-                              vec_elt_at_index (lcm->map_resolvers, 0),
-                              sizeof (ip_address_t));
-               }
+             ip_address_copy (&tr->map_resolver_ip,
+                              &lcm->active_map_resolver);
            }
          gid_address_free (&dst);
          gid_address_free (&src);
@@ -3141,7 +3187,7 @@ process_map_reply (void *arg)
 
       /* insert/update mappings cache */
       vnet_lisp_add_del_mapping (&deid, locators, action, authoritative, ttl,
-                                1, &dst_map_index);
+                                1, 0 /* is_static */ , &dst_map_index);
 
       /* try to program forwarding only if mapping saved or updated */
       if ((u32) ~ 0 != dst_map_index)
@@ -3328,6 +3374,7 @@ lisp_cp_init (vlib_main_t * vm)
   lcm->vnet_main = vnet_get_main ();
   lcm->mreq_itr_rlocs = ~0;
   lcm->lisp_pitr = 0;
+  memset (&lcm->active_map_resolver, 0, sizeof (lcm->active_map_resolver));
 
   lcm->pending_map_request_lock =
     clib_mem_alloc_aligned (CLIB_CACHE_LINE_BYTES, CLIB_CACHE_LINE_BYTES);