LISP Source/Dest control plane support, VPP-197 84/2884/9
authorFlorin Coras <fcoras@cisco.com>
Wed, 14 Sep 2016 14:01:38 +0000 (16:01 +0200)
committerDamjan Marion <dmarion.lists@gmail.com>
Tue, 27 Sep 2016 08:11:19 +0000 (08:11 +0000)
Change-Id: If88e4161e0944b657e6183b7b44348f7f46ba0a8
Signed-off-by: Florin Coras <fcoras@cisco.com>
Signed-off-by: Filip Tehlar <ftehlar@cisco.com>
vnet/vnet/lisp-cp/control.c
vnet/vnet/lisp-cp/control.h
vnet/vnet/lisp-cp/gid_dictionary.c
vnet/vnet/lisp-cp/gid_dictionary.h
vnet/vnet/lisp-cp/lisp_msg_serdes.c
vnet/vnet/lisp-cp/lisp_types.c
vnet/vnet/lisp-cp/lisp_types.h
vpp-api-test/vat/api_format.c
vpp/vpp-api/api.c
vpp/vpp-api/custom_dump.c
vpp/vpp-api/vpe.api

index 618acf2..2e89286 100644 (file)
@@ -29,6 +29,13 @@ typedef struct
   u8 smr_invoked;
 } map_request_args_t;
 
   u8 smr_invoked;
 } map_request_args_t;
 
+u8
+vnet_lisp_get_map_request_mode (void)
+{
+  lisp_cp_main_t *lcm = vnet_lisp_cp_get_main ();
+  return lcm->map_request_mode;
+}
+
 static int
 queue_map_request (gid_address_t * seid, gid_address_t * deid,
                   u8 smr_invoked, u8 is_resend);
 static int
 queue_map_request (gid_address_t * seid, gid_address_t * deid,
                   u8 smr_invoked, u8 is_resend);
@@ -346,6 +353,30 @@ get_locator_pairs (lisp_cp_main_t * lcm, mapping_t * lcl_map,
   return found;
 }
 
   return found;
 }
 
+static void
+gid_address_sd_to_flat (gid_address_t * dst, gid_address_t * src,
+                       fid_address_t * fid)
+{
+  ASSERT (GID_ADDR_SRC_DST == gid_address_type (src));
+
+  dst[0] = src[0];
+
+  switch (fid_addr_type (fid))
+    {
+    case FID_ADDR_IP_PREF:
+      gid_address_type (dst) = GID_ADDR_IP_PREFIX;
+      gid_address_ippref (dst) = fid_addr_ippref (fid);
+      break;
+    case FID_ADDR_MAC:
+      gid_address_type (dst) = GID_ADDR_MAC;
+      mac_copy (gid_address_mac (dst), fid_addr_mac (fid));
+      break;
+    default:
+      clib_warning ("Unsupported fid type %d!", fid_addr_type (fid));
+      break;
+    }
+}
+
 static void
 dp_add_fwd_entry (lisp_cp_main_t * lcm, u32 src_map_index, u32 dst_map_index)
 {
 static void
 dp_add_fwd_entry (lisp_cp_main_t * lcm, u32 src_map_index, u32 dst_map_index)
 {
@@ -369,11 +400,20 @@ dp_add_fwd_entry (lisp_cp_main_t * lcm, u32 src_map_index, u32 dst_map_index)
   /* insert data plane forwarding entry */
   a->is_add = 1;
 
   /* insert data plane forwarding entry */
   a->is_add = 1;
 
-  gid_address_copy (&a->rmt_eid, &dst_map->eid);
+  if (GID_ADDR_SRC_DST == gid_address_type (&dst_map->eid))
+    {
+      gid_address_sd_to_flat (&a->rmt_eid, &dst_map->eid,
+                             &gid_address_sd_dst (&dst_map->eid));
+      gid_address_sd_to_flat (&a->lcl_eid, &dst_map->eid,
+                             &gid_address_sd_src (&dst_map->eid));
+    }
+  else
+    gid_address_copy (&a->rmt_eid, &dst_map->eid);
+
   a->vni = gid_address_vni (&a->rmt_eid);
 
   /* get vrf or bd_index associated to vni */
   a->vni = gid_address_vni (&a->rmt_eid);
 
   /* get vrf or bd_index associated to vni */
-  type = gid_address_type (&dst_map->eid);
+  type = gid_address_type (&a->rmt_eid);
   if (GID_ADDR_IP_PREFIX == type)
     {
       dpid = hash_get (lcm->table_id_by_vni, a->vni);
   if (GID_ADDR_IP_PREFIX == type)
     {
       dpid = hash_get (lcm->table_id_by_vni, a->vni);
@@ -1256,6 +1296,104 @@ VLIB_CLI_COMMAND (lisp_add_del_adjacency_command) = {
 };
 /* *INDENT-ON* */
 
 };
 /* *INDENT-ON* */
 
+int
+vnet_lisp_set_map_request_mode (u8 mode)
+{
+  lisp_cp_main_t *lcm = vnet_lisp_cp_get_main ();
+
+  if (vnet_lisp_enable_disable_status () == 0)
+    {
+      clib_warning ("LISP is disabled!");
+      return VNET_API_ERROR_LISP_DISABLED;
+    }
+
+  if (mode >= _MR_MODE_MAX)
+    {
+      clib_warning ("Invalid LISP map request mode %d!", mode);
+      return VNET_API_ERROR_INVALID_ARGUMENT;
+    }
+
+  lcm->map_request_mode = mode;
+  return 0;
+}
+
+static clib_error_t *
+lisp_map_request_mode_command_fn (vlib_main_t * vm,
+                                 unformat_input_t * input,
+                                 vlib_cli_command_t * cmd)
+{
+  unformat_input_t _i, *i = &_i;
+  map_request_mode_t mr_mode = _MR_MODE_MAX;
+
+  /* Get a line of input. */
+  if (!unformat_user (input, unformat_line_input, i))
+    return 0;
+
+  while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
+    {
+      if (unformat (i, "dst-only"))
+       mr_mode = MR_MODE_DST_ONLY;
+      else if (unformat (i, "src-dst"))
+       mr_mode = MR_MODE_SRC_DST;
+      else
+       {
+         clib_warning ("parse error '%U'", format_unformat_error, i);
+         goto done;
+       }
+    }
+
+  if (_MR_MODE_MAX == mr_mode)
+    {
+      clib_warning ("No LISP map request mode entered!");
+      return 0;
+    }
+
+  vnet_lisp_set_map_request_mode (mr_mode);
+done:
+  return 0;
+}
+
+/* *INDENT-OFF* */
+VLIB_CLI_COMMAND (lisp_map_request_mode_command) = {
+    .path = "lisp map-request mode",
+    .short_help = "lisp map-request mode dst-only|src-dst",
+    .function = lisp_map_request_mode_command_fn,
+};
+/* *INDENT-ON* */
+
+static u8 *
+format_lisp_map_request_mode (u8 * s, va_list * args)
+{
+  u32 mode = va_arg (*args, u32);
+
+  switch (mode)
+    {
+    case 0:
+      return format (0, "dst-only");
+    case 1:
+      return format (0, "src-dst");
+    }
+  return 0;
+}
+
+static clib_error_t *
+lisp_show_map_request_mode_command_fn (vlib_main_t * vm,
+                                      unformat_input_t * input,
+                                      vlib_cli_command_t * cmd)
+{
+  vlib_cli_output (vm, "map-request mode: %U", format_lisp_map_request_mode,
+                  vnet_lisp_get_map_request_mode ());
+  return 0;
+}
+
+/* *INDENT-OFF* */
+VLIB_CLI_COMMAND (lisp_show_map_request_mode_command) = {
+    .path = "show lisp map-request mode",
+    .short_help = "show lisp map-request mode",
+    .function = lisp_show_map_request_mode_command_fn,
+};
+/* *INDENT-ON* */
+
 static clib_error_t *
 lisp_show_map_resolvers_command_fn (vlib_main_t * vm,
                                    unformat_input_t * input,
 static clib_error_t *
 lisp_show_map_resolvers_command_fn (vlib_main_t * vm,
                                    unformat_input_t * input,
@@ -2657,8 +2795,19 @@ build_encapsulated_map_request (lisp_cp_main_t * lcm,
   /* get rlocs */
   rlocs = build_itr_rloc_list (lcm, loc_set);
 
   /* get rlocs */
   rlocs = build_itr_rloc_list (lcm, loc_set);
 
-  /* put lisp msg */
-  lisp_msg_put_mreq (lcm, b, seid, deid, rlocs, is_smr_invoked, nonce_res);
+  if (MR_MODE_SRC_DST == lcm->map_request_mode)
+    {
+      gid_address_t sd;
+      memset (&sd, 0, sizeof (sd));
+      build_src_dst (&sd, seid, deid);
+      lisp_msg_put_mreq (lcm, b, seid, &sd, rlocs, is_smr_invoked, nonce_res);
+    }
+  else
+    {
+      /* put lisp msg */
+      lisp_msg_put_mreq (lcm, b, seid, deid, rlocs, is_smr_invoked,
+                        nonce_res);
+    }
 
   /* push ecm: udp-ip-lisp */
   lisp_msg_push_ecm (vm, b, LISP_CONTROL_PORT, LISP_CONTROL_PORT, seid, deid);
 
   /* push ecm: udp-ip-lisp */
   lisp_msg_push_ecm (vm, b, LISP_CONTROL_PORT, LISP_CONTROL_PORT, seid, deid);
@@ -3007,7 +3156,8 @@ lisp_cp_lookup_inline (vlib_main_t * vm,
 
          /* if we have remote mapping for destination already in map-chache
             add forwarding tunnel directly. If not send a map-request */
 
          /* if we have remote mapping for destination already in map-chache
             add forwarding tunnel directly. If not send a map-request */
-         di = gid_dictionary_lookup (&lcm->mapping_index_by_gid, &dst);
+         di = gid_dictionary_sd_lookup (&lcm->mapping_index_by_gid, &dst,
+                                        &src);
          if (~0 != di)
            {
              mapping_t *m = vec_elt_at_index (lcm->mapping_pool, di);
          if (~0 != di)
            {
              mapping_t *m = vec_elt_at_index (lcm->mapping_pool, di);
@@ -3408,6 +3558,7 @@ lisp_cp_init (vlib_main_t * vm)
   lcm->pending_map_request_lock[0] = 0;
   gid_dictionary_init (&lcm->mapping_index_by_gid);
   lcm->do_map_resolver_election = 1;
   lcm->pending_map_request_lock[0] = 0;
   gid_dictionary_init (&lcm->mapping_index_by_gid);
   lcm->do_map_resolver_election = 1;
+  lcm->map_request_mode = MR_MODE_DST_ONLY;
 
   /* default vrf mapped to vni 0 */
   hash_set (lcm->table_id_by_vni, 0, 0);
 
   /* default vrf mapped to vni 0 */
   hash_set (lcm->table_id_by_vni, 0, 0);
index 02efd04..1c8abfb 100644 (file)
@@ -63,6 +63,13 @@ typedef struct
   miss_packet_type_t type;
 } miss_packet_t;
 
   miss_packet_type_t type;
 } miss_packet_t;
 
+typedef enum
+{
+  MR_MODE_DST_ONLY = 0,
+  MR_MODE_SRC_DST,
+  _MR_MODE_MAX
+} map_request_mode_t;
+
 typedef struct
 {
   /* LISP feature status */
 typedef struct
 {
   /* LISP feature status */
@@ -138,6 +145,9 @@ typedef struct
   /* LISP PITR mode */
   u8 lisp_pitr;
 
   /* LISP PITR mode */
   u8 lisp_pitr;
 
+  /* map request mode */
+  u8 map_request_mode;
+
   /* commodity */
   ip4_main_t *im4;
   ip6_main_t *im6;
   /* commodity */
   ip4_main_t *im4;
   ip6_main_t *im6;
@@ -240,6 +250,8 @@ vnet_lisp_add_del_mreq_itr_rlocs (vnet_lisp_add_del_mreq_itr_rloc_args_t * a);
 int vnet_lisp_clear_all_remote_adjacencies (void);
 
 int vnet_lisp_eid_table_map (u32 vni, u32 vrf, u8 is_l2, u8 is_add);
 int vnet_lisp_clear_all_remote_adjacencies (void);
 
 int vnet_lisp_eid_table_map (u32 vni, u32 vrf, u8 is_l2, u8 is_add);
+int vnet_lisp_set_map_request_mode (u8 mode);
+u8 vnet_lisp_get_map_request_mode (void);
 
 static inline void
 lisp_pending_map_request_lock (lisp_cp_main_t * lcm)
 
 static inline void
 lisp_pending_map_request_lock (lisp_cp_main_t * lcm)
index fc95c88..a422b24 100644 (file)
 
 #include <vnet/lisp-cp/gid_dictionary.h>
 
 
 #include <vnet/lisp-cp/gid_dictionary.h>
 
+static void
+make_mac_sd_key (BVT (clib_bihash_kv) * kv, u32 vni, u8 src_mac[6],
+                u8 dst_mac[6])
+{
+  kv->key[0] = (u64) vni;
+  kv->key[1] = mac_to_u64 (dst_mac);
+  kv->key[2] = src_mac ? mac_to_u64 (src_mac) : (u64) 0;
+}
+
 static u32
 static u32
-mac_lookup (gid_dictionary_t * db, u32 vni, u8 * key)
+mac_sd_lookup (gid_mac_table_t * db, u32 vni, u8 * dst, u8 * src)
 {
   int rv;
   BVT (clib_bihash_kv) kv, value;
 
 {
   int rv;
   BVT (clib_bihash_kv) kv, value;
 
-  kv.key[0] = mac_to_u64 (key);
-  kv.key[1] = (u64) vni;
-  kv.key[2] = 0;
-
+  make_mac_sd_key (&kv, vni, src, dst);
   rv = BV (clib_bihash_search_inline_2) (&db->mac_lookup_table, &kv, &value);
   rv = BV (clib_bihash_search_inline_2) (&db->mac_lookup_table, &kv, &value);
-  if (rv == 0)
+
+  /* no match, try with src 0, catch all for dst */
+  if (rv != 0)
+    {
+      kv.key[2] = 0;
+      rv = BV (clib_bihash_search_inline_2) (&db->mac_lookup_table, &kv,
+                                            &value);
+      if (rv == 0)
+       return value.value;
+    }
+  else
     return value.value;
 
   return GID_LOOKUP_MISS;
 }
 
 static u32
     return value.value;
 
   return GID_LOOKUP_MISS;
 }
 
 static u32
-ip4_lookup (gid_dictionary_t * db, u32 vni, ip_prefix_t * key)
+ip4_lookup (gid_ip4_table_t * db, u32 vni, ip_prefix_t * key)
 {
   int i, len;
   int rv;
 {
   int i, len;
   int rv;
@@ -65,7 +81,7 @@ ip4_lookup (gid_dictionary_t * db, u32 vni, ip_prefix_t * key)
 }
 
 static u32
 }
 
 static u32
-ip6_lookup (gid_dictionary_t * db, u32 vni, ip_prefix_t * key)
+ip6_lookup (gid_ip6_table_t * db, u32 vni, ip_prefix_t * key)
 {
   int i, len;
   int rv;
 {
   int i, len;
   int rv;
@@ -96,35 +112,88 @@ ip6_lookup (gid_dictionary_t * db, u32 vni, ip_prefix_t * key)
 }
 
 static u32
 }
 
 static u32
-ip_lookup (gid_dictionary_t * db, u32 vni, ip_prefix_t * key)
+ip_sd_lookup (gid_dictionary_t * db, u32 vni, ip_prefix_t * dst,
+             ip_prefix_t * src)
 {
 {
-  /* XXX for now this only works with ip-prefixes, no lcafs */
-  switch (ip_prefix_version (key))
+  u32 sfi;
+  gid_ip4_table_t *sfib4;
+  gid_ip6_table_t *sfib6;
+
+  switch (ip_prefix_version (dst))
     {
     case IP4:
     {
     case IP4:
-      return ip4_lookup (db, vni, key);
+      sfi = ip4_lookup (&db->dst_ip4_table, vni, dst);
+      if (GID_LOOKUP_MISS != sfi)
+       sfib4 = pool_elt_at_index (db->src_ip4_table_pool, sfi);
+      else
+       return GID_LOOKUP_MISS;
+
+      if (!src)
+       {
+         ip_prefix_t sp;
+         memset (&sp, 0, sizeof (sp));
+         return ip4_lookup (sfib4, 0, &sp);
+       }
+      else
+       return ip4_lookup (sfib4, 0, src);
+
       break;
     case IP6:
       break;
     case IP6:
-      return ip6_lookup (db, vni, key);
+      sfi = ip6_lookup (&db->dst_ip6_table, vni, dst);
+      if (GID_LOOKUP_MISS != sfi)
+       sfib6 = pool_elt_at_index (db->src_ip6_table_pool, sfi);
+      else
+       return GID_LOOKUP_MISS;
+
+      if (!src)
+       {
+         ip_prefix_t sp;
+         memset (&sp, 0, sizeof (sp));
+         ip_prefix_version (&sp) = IP6;
+         return ip6_lookup (sfib6, 0, &sp);
+       }
+      else
+       return ip6_lookup (sfib6, 0, src);
+
       break;
     default:
       clib_warning ("address type %d not supported!",
       break;
     default:
       clib_warning ("address type %d not supported!",
-                   ip_prefix_version (key));
+                   ip_prefix_version (dst));
       break;
     }
       break;
     }
-  return ~0;
+  return GID_LOOKUP_MISS;
 }
 
 u32
 gid_dictionary_lookup (gid_dictionary_t * db, gid_address_t * key)
 {
 }
 
 u32
 gid_dictionary_lookup (gid_dictionary_t * db, gid_address_t * key)
 {
-  /* XXX for now this only works with ip-prefixes, no lcafs */
   switch (gid_address_type (key))
     {
     case GID_ADDR_IP_PREFIX:
   switch (gid_address_type (key))
     {
     case GID_ADDR_IP_PREFIX:
-      return ip_lookup (db, gid_address_vni (key), &gid_address_ippref (key));
+      return ip_sd_lookup (db, gid_address_vni (key),
+                          &gid_address_ippref (key), 0);
     case GID_ADDR_MAC:
     case GID_ADDR_MAC:
-      return mac_lookup (db, gid_address_vni (key), gid_address_mac (key));
+      return mac_sd_lookup (&db->sd_mac_table, gid_address_vni (key),
+                           gid_address_mac (key), 0);
+    case GID_ADDR_SRC_DST:
+      switch (gid_address_sd_dst_type (key))
+       {
+       case FID_ADDR_IP_PREF:
+         return ip_sd_lookup (db, gid_address_vni (key),
+                              &gid_address_sd_dst_ippref (key),
+                              &gid_address_sd_src_ippref (key));
+         break;
+       case FID_ADDR_MAC:
+         return mac_sd_lookup (&db->sd_mac_table, gid_address_vni (key),
+                               gid_address_sd_dst_mac (key),
+                               gid_address_sd_src_mac (key));
+         break;
+       default:
+         clib_warning ("Source/Dest address type %d not supported!",
+                       gid_address_sd_dst_type (key));
+         break;
+       }
+      break;
     default:
       clib_warning ("address type %d not supported!", gid_address_type (key));
       break;
     default:
       clib_warning ("address type %d not supported!", gid_address_type (key));
       break;
@@ -132,8 +201,28 @@ gid_dictionary_lookup (gid_dictionary_t * db, gid_address_t * key)
   return GID_LOOKUP_MISS;
 }
 
   return GID_LOOKUP_MISS;
 }
 
+u32
+gid_dictionary_sd_lookup (gid_dictionary_t * db, gid_address_t * dst,
+                         gid_address_t * src)
+{
+  switch (gid_address_type (dst))
+    {
+    case GID_ADDR_IP_PREFIX:
+      return ip_sd_lookup (db, gid_address_vni (dst),
+                          &gid_address_ippref (dst),
+                          &gid_address_ippref (src));
+    case GID_ADDR_MAC:
+      return mac_sd_lookup (&db->sd_mac_table, gid_address_vni (dst),
+                           gid_address_mac (dst), gid_address_mac (src));
+    default:
+      clib_warning ("address type %d not supported!", gid_address_type (dst));
+      break;
+    }
+  return GID_LOOKUP_MISS;
+}
+
 static void
 static void
-ip4_compute_prefix_lengths_in_search_order (gid_dictionary_t * db)
+ip4_compute_prefix_lengths_in_search_order (gid_ip4_table_t * db)
 {
   int i;
   vec_reset_length (db->ip4_prefix_lengths_in_search_order);
 {
   int i;
   vec_reset_length (db->ip4_prefix_lengths_in_search_order);
@@ -150,7 +239,7 @@ ip4_compute_prefix_lengths_in_search_order (gid_dictionary_t * db)
 }
 
 static u32
 }
 
 static u32
-add_del_ip4_key (gid_dictionary_t * db, u32 vni, ip_prefix_t * pref, u32 val,
+add_del_ip4_key (gid_ip4_table_t * db, u32 vni, ip_prefix_t * pref, u32 val,
                 u8 is_add)
 {
   BVT (clib_bihash_kv) kv, value;
                 u8 is_add)
 {
   BVT (clib_bihash_kv) kv, value;
@@ -202,7 +291,105 @@ add_del_ip4_key (gid_dictionary_t * db, u32 vni, ip_prefix_t * pref, u32 val,
 }
 
 static void
 }
 
 static void
-ip6_compute_prefix_lengths_in_search_order (gid_dictionary_t * db)
+ip4_lookup_init (gid_ip4_table_t * db)
+{
+  uword i;
+
+  memset (db->ip4_prefix_len_refcount, 0,
+         sizeof (db->ip4_prefix_len_refcount));
+
+  for (i = 0; i < ARRAY_LEN (db->ip4_fib_masks); i++)
+    {
+      u32 m;
+
+      if (i < 32)
+       m = pow2_mask (i) << (32 - i);
+      else
+       m = ~0;
+      db->ip4_fib_masks[i].as_u32 = clib_host_to_net_u32 (m);
+    }
+  if (db->ip4_lookup_table_nbuckets == 0)
+    db->ip4_lookup_table_nbuckets = IP4_LOOKUP_DEFAULT_HASH_NUM_BUCKETS;
+
+  db->ip4_lookup_table_nbuckets =
+    1 << max_log2 (db->ip4_lookup_table_nbuckets);
+
+  if (db->ip4_lookup_table_size == 0)
+    db->ip4_lookup_table_size = IP4_LOOKUP_DEFAULT_HASH_MEMORY_SIZE;
+
+  BV (clib_bihash_init) (&db->ip4_lookup_table, "ip4 lookup table",
+                        db->ip4_lookup_table_nbuckets,
+                        db->ip4_lookup_table_size);
+}
+
+static u32
+add_del_sd_ip4_key (gid_dictionary_t * db, u32 vni, ip_prefix_t * dst_pref,
+                   ip_prefix_t * src_pref, u32 val, u8 is_add)
+{
+  u32 sfi, old_val = ~0;
+  gid_ip4_table_t *sfib;
+
+  sfi = ip4_lookup (&db->dst_ip4_table, vni, dst_pref);
+
+  if (is_add)
+    {
+      if (GID_LOOKUP_MISS == sfi)
+       {
+         pool_get (db->src_ip4_table_pool, sfib);
+         ip4_lookup_init (sfib);
+         add_del_ip4_key (&db->dst_ip4_table, vni, dst_pref,
+                          sfib - db->src_ip4_table_pool, is_add);
+         if (src_pref)
+           add_del_ip4_key (sfib, 0 /* vni */ , src_pref, val, is_add);
+         else
+           {
+             ip_prefix_t sp;
+             memset (&sp, 0, sizeof (sp));
+             add_del_ip4_key (sfib, 0 /* vni */ , &sp, val, is_add);
+           }
+       }
+      else
+       {
+         ASSERT (!pool_is_free_index (db->src_ip4_table_pool, sfi));
+         sfib = pool_elt_at_index (db->src_ip4_table_pool, sfi);
+         if (src_pref)
+           {
+             old_val = ip4_lookup (sfib, 0, src_pref);
+             add_del_ip4_key (sfib, 0 /* vni */ , src_pref, val, is_add);
+           }
+         else
+           {
+             ip_prefix_t sp;
+             memset (&sp, 0, sizeof (sp));
+             old_val =
+               add_del_ip4_key (sfib, 0 /* vni */ , &sp, val, is_add);
+           }
+       }
+    }
+  else
+    {
+      if (GID_LOOKUP_MISS != sfi)
+       {
+         add_del_ip4_key (&db->dst_ip4_table, vni, dst_pref, 0, is_add);
+         sfib = pool_elt_at_index (db->src_ip4_table_pool, sfi);
+         if (src_pref)
+           old_val = add_del_ip4_key (sfib, 0, src_pref, 0, is_add);
+         else
+           {
+             ip_prefix_t sp;
+             memset (&sp, 0, sizeof (sp));
+             old_val = add_del_ip4_key (sfib, 0, &sp, 0, is_add);
+           }
+       }
+      else
+       clib_warning ("cannot delete dst mapping %U!", format_ip_prefix,
+                     dst_pref);
+    }
+  return old_val;
+}
+
+static void
+ip6_compute_prefix_lengths_in_search_order (gid_ip6_table_t * db)
 {
   int i;
   vec_reset_length (db->ip6_prefix_lengths_in_search_order);
 {
   int i;
   vec_reset_length (db->ip6_prefix_lengths_in_search_order);
@@ -218,7 +405,7 @@ ip6_compute_prefix_lengths_in_search_order (gid_dictionary_t * db)
 }
 
 static u32
 }
 
 static u32
-add_del_ip6_key (gid_dictionary_t * db, u32 vni, ip_prefix_t * pref, u32 val,
+add_del_ip6_key (gid_ip6_table_t * db, u32 vni, ip_prefix_t * pref, u32 val,
                 u8 is_add)
 {
   BVT (clib_bihash_kv) kv, value;
                 u8 is_add)
 {
   BVT (clib_bihash_kv) kv, value;
@@ -270,14 +457,13 @@ add_del_ip6_key (gid_dictionary_t * db, u32 vni, ip_prefix_t * pref, u32 val,
 }
 
 static u32
 }
 
 static u32
-add_del_mac (gid_dictionary_t * db, u32 vni, u8 * mac, u32 val, u8 is_add)
+add_del_mac (gid_mac_table_t * db, u32 vni, u8 * dst_mac, u8 * src_mac,
+            u32 val, u8 is_add)
 {
   BVT (clib_bihash_kv) kv, value;
   u32 old_val = ~0;
 
 {
   BVT (clib_bihash_kv) kv, value;
   u32 old_val = ~0;
 
-  kv.key[0] = ((u64 *) mac)[0];
-  kv.key[1] = (u64) vni;
-  kv.key[2] = 0;
+  make_mac_sd_key (&kv, vni, src_mac, dst_mac);
 
   if (BV (clib_bihash_search) (&db->mac_lookup_table, &kv, &value) == 0)
     old_val = value.value;
 
   if (BV (clib_bihash_search) (&db->mac_lookup_table, &kv, &value) == 0)
     old_val = value.value;
@@ -292,80 +478,8 @@ add_del_mac (gid_dictionary_t * db, u32 vni, u8 * mac, u32 val, u8 is_add)
   return old_val;
 }
 
   return old_val;
 }
 
-static u32
-add_del_ip (gid_dictionary_t * db, u32 vni, ip_prefix_t * key, u32 value,
-           u8 is_add)
-{
-  switch (ip_prefix_version (key))
-    {
-    case IP4:
-      return add_del_ip4_key (db, vni, key, value, is_add);
-      break;
-    case IP6:
-      return add_del_ip6_key (db, vni, key, value, is_add);
-      break;
-    default:
-      clib_warning ("address type %d not supported!",
-                   ip_prefix_version (key));
-      break;
-    }
-  return ~0;
-}
-
-u32
-gid_dictionary_add_del (gid_dictionary_t * db, gid_address_t * key, u32 value,
-                       u8 is_add)
-{
-  /* XXX for now this only works with ip-prefixes, no lcafs */
-  switch (gid_address_type (key))
-    {
-    case GID_ADDR_IP_PREFIX:
-      return add_del_ip (db, gid_address_vni (key), &gid_address_ippref (key),
-                        value, is_add);
-    case GID_ADDR_MAC:
-      return add_del_mac (db, gid_address_vni (key), gid_address_mac (key),
-                         value, is_add);
-    default:
-      clib_warning ("address type %d not supported!", gid_address_type (key));
-      break;
-    }
-  return ~0;
-}
-
-static void
-ip4_lookup_init (gid_dictionary_t * db)
-{
-  uword i;
-
-  memset (db->ip4_prefix_len_refcount, 0,
-         sizeof (db->ip4_prefix_len_refcount));
-
-  for (i = 0; i < ARRAY_LEN (db->ip4_fib_masks); i++)
-    {
-      u32 m;
-
-      if (i < 32)
-       m = pow2_mask (i) << (32 - i);
-      else
-       m = ~0;
-      db->ip4_fib_masks[i].as_u32 = clib_host_to_net_u32 (m);
-    }
-  if (db->ip4_lookup_table_nbuckets == 0)
-    db->ip4_lookup_table_nbuckets = IP4_LOOKUP_DEFAULT_HASH_NUM_BUCKETS;
-
-  db->ip4_lookup_table_nbuckets =
-    1 << max_log2 (db->ip4_lookup_table_nbuckets);
-
-  if (db->ip4_lookup_table_size == 0)
-    db->ip4_lookup_table_size = IP4_LOOKUP_DEFAULT_HASH_MEMORY_SIZE;
-
-  BV (clib_bihash_init) (&db->ip4_lookup_table, "ip4 lookup table",
-                        db->ip4_lookup_table_nbuckets,
-                        db->ip4_lookup_table_size);
-}
-
 static void
 static void
-ip6_lookup_init (gid_dictionary_t * db)
+ip6_lookup_init (gid_ip6_table_t * db)
 {
   uword i;
 
 {
   uword i;
 
@@ -401,8 +515,138 @@ ip6_lookup_init (gid_dictionary_t * db)
                         db->ip6_lookup_table_size);
 }
 
                         db->ip6_lookup_table_size);
 }
 
+static u32
+add_del_sd_ip6_key (gid_dictionary_t * db, u32 vni, ip_prefix_t * dst_pref,
+                   ip_prefix_t * src_pref, u32 val, u8 is_add)
+{
+  u32 sfi, old_val = ~0;
+  gid_ip6_table_t *sfib;
+
+  sfi = ip6_lookup (&db->dst_ip6_table, vni, dst_pref);
+
+  if (is_add)
+    {
+      if (GID_LOOKUP_MISS == sfi)
+       {
+         pool_get (db->src_ip6_table_pool, sfib);
+         ip6_lookup_init (sfib);
+         add_del_ip6_key (&db->dst_ip6_table, vni, dst_pref,
+                          sfib - db->src_ip6_table_pool, is_add);
+         if (src_pref)
+           add_del_ip6_key (sfib, 0 /* vni */ , src_pref, val, is_add);
+         else
+           {
+             ip_prefix_t sp;
+             memset (&sp, 0, sizeof (sp));
+             add_del_ip6_key (sfib, 0 /* vni */ , &sp, val, is_add);
+           }
+       }
+      else
+       {
+         ASSERT (!pool_is_free_index (db->src_ip6_table_pool, sfi));
+         sfib = pool_elt_at_index (db->src_ip6_table_pool, sfi);
+         if (src_pref)
+           {
+             old_val = ip6_lookup (sfib, 0, src_pref);
+             add_del_ip6_key (sfib, 0 /* vni */ , src_pref, val, is_add);
+           }
+         else
+           {
+             ip_prefix_t sp;
+             memset (&sp, 0, sizeof (sp));
+             old_val =
+               add_del_ip6_key (sfib, 0 /* vni */ , &sp, val, is_add);
+           }
+       }
+    }
+  else
+    {
+      if (GID_LOOKUP_MISS != sfi)
+       {
+         add_del_ip6_key (&db->dst_ip6_table, vni, dst_pref, 0, is_add);
+         sfib = pool_elt_at_index (db->src_ip6_table_pool, sfi);
+         if (src_pref)
+           old_val = add_del_ip6_key (sfib, 0, src_pref, 0, is_add);
+         else
+           {
+             ip_prefix_t sp;
+             memset (&sp, 0, sizeof (sp));
+             old_val = add_del_ip6_key (sfib, 0, &sp, 0, is_add);
+           }
+       }
+      else
+       clib_warning ("cannot delete dst mapping %U!", format_ip_prefix,
+                     dst_pref);
+    }
+  return old_val;
+}
+
+static u32
+add_del_ip (gid_dictionary_t * db, u32 vni, ip_prefix_t * dst_key,
+           ip_prefix_t * src_key, u32 value, u8 is_add)
+{
+  switch (ip_prefix_version (dst_key))
+    {
+    case IP4:
+      return add_del_sd_ip4_key (db, vni, dst_key, src_key, value, is_add);
+      break;
+    case IP6:
+      return add_del_sd_ip6_key (db, vni, dst_key, src_key, value, is_add);
+      break;
+    default:
+      clib_warning ("address type %d not supported!",
+                   ip_prefix_version (dst_key));
+      break;
+    }
+  return ~0;
+}
+
+static u32
+add_del_sd (gid_dictionary_t * db, u32 vni, source_dest_t * key, u32 value,
+           u8 is_add)
+{
+  switch (sd_dst_type (key))
+    {
+    case FID_ADDR_IP_PREF:
+      add_del_ip (db, vni, &sd_dst_ippref (key), &sd_src_ippref (key),
+                 value, is_add);
+
+    case FID_ADDR_MAC:
+      return add_del_mac (&db->sd_mac_table, vni, sd_dst_mac (key),
+                         sd_src_mac (key), value, is_add);
+
+    default:
+      clib_warning ("SD address type %d not supprted!", sd_dst_type (key));
+      break;
+    }
+
+  return ~0;
+}
+
+u32
+gid_dictionary_add_del (gid_dictionary_t * db, gid_address_t * key, u32 value,
+                       u8 is_add)
+{
+  switch (gid_address_type (key))
+    {
+    case GID_ADDR_IP_PREFIX:
+      return add_del_ip (db, gid_address_vni (key), &gid_address_ippref (key),
+                        0, value, is_add);
+    case GID_ADDR_MAC:
+      return add_del_mac (&db->sd_mac_table, gid_address_vni (key),
+                         gid_address_mac (key), 0, value, is_add);
+    case GID_ADDR_SRC_DST:
+      return add_del_sd (db, gid_address_vni (key), &gid_address_sd (key),
+                        value, is_add);
+    default:
+      clib_warning ("address type %d not supported!", gid_address_type (key));
+      break;
+    }
+  return ~0;
+}
+
 static void
 static void
-mac_lookup_init (gid_dictionary_t * db)
+mac_lookup_init (gid_mac_table_t * db)
 {
   if (db->mac_lookup_table_nbuckets == 0)
     db->mac_lookup_table_nbuckets = MAC_LOOKUP_DEFAULT_HASH_NUM_BUCKETS;
 {
   if (db->mac_lookup_table_nbuckets == 0)
     db->mac_lookup_table_nbuckets = MAC_LOOKUP_DEFAULT_HASH_NUM_BUCKETS;
@@ -421,9 +665,9 @@ mac_lookup_init (gid_dictionary_t * db)
 void
 gid_dictionary_init (gid_dictionary_t * db)
 {
 void
 gid_dictionary_init (gid_dictionary_t * db)
 {
-  ip4_lookup_init (db);
-  ip6_lookup_init (db);
-  mac_lookup_init (db);
+  ip4_lookup_init (&db->dst_ip4_table);
+  ip6_lookup_init (&db->dst_ip6_table);
+  mac_lookup_init (&db->sd_mac_table);
 }
 
 /*
 }
 
 /*
index d9a857f..6544cca 100644 (file)
@@ -48,8 +48,11 @@ typedef struct
   /* ip4 lookup table config parameters */
   u32 ip4_lookup_table_nbuckets;
   uword ip4_lookup_table_size;
   /* ip4 lookup table config parameters */
   u32 ip4_lookup_table_nbuckets;
   uword ip4_lookup_table_size;
+} gid_ip4_table_t;
 
 
-    BVT (clib_bihash) ip6_lookup_table;
+typedef struct
+{
+  BVT (clib_bihash) ip6_lookup_table;
 
   /* bitmap/vector of mask widths to search */
   uword *ip6_non_empty_dst_address_length_bitmap;
 
   /* bitmap/vector of mask widths to search */
   uword *ip6_non_empty_dst_address_length_bitmap;
@@ -60,12 +63,33 @@ typedef struct
   /* ip6 lookup table config parameters */
   u32 ip6_lookup_table_nbuckets;
   uword ip6_lookup_table_size;
   /* ip6 lookup table config parameters */
   u32 ip6_lookup_table_nbuckets;
   uword ip6_lookup_table_size;
+} gid_ip6_table_t;
 
 
-    BVT (clib_bihash) mac_lookup_table;
+typedef struct gid_mac_table
+{
+  BVT (clib_bihash) mac_lookup_table;
 
   /* mac lookup table config parameters */
   u32 mac_lookup_table_nbuckets;
   uword mac_lookup_table_size;
 
   /* mac lookup table config parameters */
   u32 mac_lookup_table_nbuckets;
   uword mac_lookup_table_size;
+} gid_mac_table_t;
+
+typedef struct
+{
+  /** destination IP LPM ip4 lookup table */
+  gid_ip4_table_t dst_ip4_table;
+
+  /** pool of source IP LPM ip4 lookup tables */
+  gid_ip4_table_t *src_ip4_table_pool;
+
+  /** destination IP LPM ip6 lookup table */
+  gid_ip6_table_t dst_ip6_table;
+
+  /** pool of source IP LPM ip6 lookup tables */
+  gid_ip6_table_t *src_ip6_table_pool;
+
+  /** flat source/dest mac lookup table */
+  gid_mac_table_t sd_mac_table;
 
 } gid_dictionary_t;
 
 
 } gid_dictionary_t;
 
@@ -74,6 +98,8 @@ gid_dictionary_add_del (gid_dictionary_t * db, gid_address_t * key, u32 value,
                        u8 is_add);
 
 u32 gid_dictionary_lookup (gid_dictionary_t * db, gid_address_t * key);
                        u8 is_add);
 
 u32 gid_dictionary_lookup (gid_dictionary_t * db, gid_address_t * key);
+u32 gid_dictionary_sd_lookup (gid_dictionary_t * db, gid_address_t * dst,
+                             gid_address_t * src);
 
 void gid_dictionary_init (gid_dictionary_t * db);
 
 
 void gid_dictionary_init (gid_dictionary_t * db);
 
index d170efd..de9a4f5 100644 (file)
@@ -233,7 +233,8 @@ lisp_msg_parse_mapping_record (vlib_buffer_t * b, gid_address_t * eid,
     return len;
 
   vlib_buffer_pull (b, len);
     return len;
 
   vlib_buffer_pull (b, len);
-  gid_address_ippref_len (eid) = MAP_REC_EID_PLEN (h);
+  if (GID_ADDR_IP_PREFIX == gid_address_type (eid))
+    gid_address_ippref_len (eid) = MAP_REC_EID_PLEN (h);
 
   for (i = 0; i < MAP_REC_LOC_COUNT (h); i++)
     {
 
   for (i = 0; i < MAP_REC_LOC_COUNT (h); i++)
     {
index a2edb48..1f527d6 100644 (file)
@@ -213,7 +213,7 @@ format_fid_address (u8 * s, va_list * args)
       return format (s, "%U", format_ip_prefix, &fid_addr_ippref (a));
 
     case FID_ADDR_MAC:
       return format (s, "%U", format_ip_prefix, &fid_addr_ippref (a));
 
     case FID_ADDR_MAC:
-      return format (s, "%U", format_ip_prefix, &fid_addr_mac (a));
+      return format (s, "%U", format_mac_address, &fid_addr_mac (a));
 
     default:
       clib_warning ("Can't format fid address type %d!", fid_addr_type (a));
 
     default:
       clib_warning ("Can't format fid address type %d!", fid_addr_type (a));
@@ -1302,6 +1302,12 @@ vni_cmp (void *a1, void *a2)
   return gid_address_cmp (vni_gid (v1), vni_gid (v2));
 }
 
   return gid_address_cmp (vni_gid (v1), vni_gid (v2));
 }
 
+static int
+mac_cmp (void *a1, void *a2)
+{
+  return memcmp (a1, a2, 6);
+}
+
 static int
 fid_addr_cmp (fid_address_t * a1, fid_address_t * a2)
 {
 static int
 fid_addr_cmp (fid_address_t * a1, fid_address_t * a2)
 {
@@ -1314,7 +1320,7 @@ fid_addr_cmp (fid_address_t * a1, fid_address_t * a2)
       return ip_prefix_cmp (&fid_addr_ippref (a1), &fid_addr_ippref (a2));
 
     case FID_ADDR_MAC:
       return ip_prefix_cmp (&fid_addr_ippref (a1), &fid_addr_ippref (a2));
 
     case FID_ADDR_MAC:
-      return memcmp (&fid_addr_mac (a1), &fid_addr_mac (a2), 6);
+      return mac_cmp (fid_addr_mac (a1), fid_addr_mac (a2));
 
     default:
       return -1;
 
     default:
       return -1;
@@ -1375,8 +1381,7 @@ gid_address_cmp (gid_address_t * a1, gid_address_t * a2)
        cmp = (*lcaf_cmp_fcts[lcaf_type (lcaf1)]) (lcaf1, lcaf2);
       break;
     case GID_ADDR_MAC:
        cmp = (*lcaf_cmp_fcts[lcaf_type (lcaf1)]) (lcaf1, lcaf2);
       break;
     case GID_ADDR_MAC:
-      cmp = memcmp (gid_address_mac (a1), gid_address_mac (a2),
-                   sizeof (gid_address_mac (a1)));
+      cmp = mac_cmp (gid_address_mac (a1), gid_address_mac (a2));
       break;
 
     case GID_ADDR_SRC_DST:
       break;
 
     case GID_ADDR_SRC_DST:
@@ -1448,6 +1453,37 @@ locator_free (locator_t * l)
     gid_address_free (&l->address);
 }
 
     gid_address_free (&l->address);
 }
 
+void
+build_src_dst (gid_address_t * sd, gid_address_t * src, gid_address_t * dst)
+{
+  memset (sd, 0, sizeof (*sd));
+  gid_address_type (sd) = GID_ADDR_SRC_DST;
+  gid_address_vni (sd) = gid_address_vni (dst);
+  gid_address_vni_mask (sd) = gid_address_vni_mask (dst);
+
+  switch (gid_address_type (dst))
+    {
+    case GID_ADDR_IP_PREFIX:
+      gid_address_sd_src_type (sd) = FID_ADDR_IP_PREF;
+      gid_address_sd_dst_type (sd) = FID_ADDR_IP_PREF;
+      ip_prefix_copy (&gid_address_sd_src_ippref (sd),
+                     &gid_address_ippref (src));
+      ip_prefix_copy (&gid_address_sd_dst_ippref (sd),
+                     &gid_address_ippref (dst));
+      break;
+    case GID_ADDR_MAC:
+      gid_address_sd_src_type (sd) = FID_ADDR_MAC;
+      gid_address_sd_dst_type (sd) = FID_ADDR_MAC;
+      mac_copy (gid_address_sd_src_mac (sd), gid_address_mac (src));
+      mac_copy (gid_address_sd_dst_mac (sd), gid_address_mac (dst));
+      break;
+    default:
+      clib_warning ("Unsupported gid type %d while conversion!",
+                   gid_address_type (dst));
+      break;
+    }
+}
+
 /*
  * fd.io coding-style-patch-verification: ON
  *
 /*
  * fd.io coding-style-patch-verification: ON
  *
index cd1d1b9..e6811f0 100644 (file)
@@ -126,6 +126,8 @@ typedef struct
 #define sd_dst_ippref(_a) fid_addr_ippref(&sd_dst(_a))
 #define sd_src_mac(_a) fid_addr_mac(&sd_src(_a))
 #define sd_dst_mac(_a) fid_addr_mac(&sd_dst(_a))
 #define sd_dst_ippref(_a) fid_addr_ippref(&sd_dst(_a))
 #define sd_src_mac(_a) fid_addr_mac(&sd_src(_a))
 #define sd_dst_mac(_a) fid_addr_mac(&sd_dst(_a))
+#define sd_src_type(_a) fid_addr_type(&sd_src(_a))
+#define sd_dst_type(_a) fid_addr_type(&sd_dst(_a))
 
 typedef struct
 {
 
 typedef struct
 {
@@ -224,6 +226,8 @@ void gid_address_ip_set (gid_address_t * dst, void *src, u8 version);
 #define gid_address_sd(_a) (_a)->sd
 #define gid_address_sd_src(_a) sd_src(&gid_address_sd(_a))
 #define gid_address_sd_dst(_a) sd_dst(&gid_address_sd(_a))
 #define gid_address_sd(_a) (_a)->sd
 #define gid_address_sd_src(_a) sd_src(&gid_address_sd(_a))
 #define gid_address_sd_dst(_a) sd_dst(&gid_address_sd(_a))
+#define gid_address_sd_src_type(_a) sd_src_type(&gid_address_sd(_a))
+#define gid_address_sd_dst_type(_a) sd_dst_type(&gid_address_sd(_a))
 
 /* 'sub'address functions */
 #define foreach_gid_address_type_fcns  \
 
 /* 'sub'address functions */
 #define foreach_gid_address_type_fcns  \
@@ -311,6 +315,9 @@ typedef struct locator_pair
   u8 weight;
 } locator_pair_t;
 
   u8 weight;
 } locator_pair_t;
 
+void
+build_src_dst (gid_address_t * sd, gid_address_t * src, gid_address_t * dst);
+
 #endif /* VNET_LISP_GPE_LISP_TYPES_H_ */
 
 /*
 #endif /* VNET_LISP_GPE_LISP_TYPES_H_ */
 
 /*
index 75e1fb2..27c80d9 100644 (file)
@@ -2711,6 +2711,62 @@ static void
   vam->result_ready = 1;
 }
 
   vam->result_ready = 1;
 }
 
+static u8 *
+format_lisp_map_request_mode (u8 * s, va_list * args)
+{
+  u32 mode = va_arg (*args, u32);
+
+  switch (mode)
+    {
+    case 0:
+      return format (0, "dst-only");
+    case 1:
+      return format (0, "src-dst");
+    }
+  return 0;
+}
+
+static void
+  vl_api_show_lisp_map_request_mode_reply_t_handler
+  (vl_api_show_lisp_map_request_mode_reply_t * mp)
+{
+  vat_main_t *vam = &vat_main;
+  i32 retval = ntohl (mp->retval);
+
+  if (0 <= retval)
+    {
+      u32 mode = mp->mode;
+      fformat (vam->ofp, "map_request_mode: %U\n",
+              format_lisp_map_request_mode, mode);
+    }
+
+  vam->retval = retval;
+  vam->result_ready = 1;
+}
+
+static void
+  vl_api_show_lisp_map_request_mode_reply_t_handler_json
+  (vl_api_show_lisp_map_request_mode_reply_t * mp)
+{
+  vat_main_t *vam = &vat_main;
+  vat_json_node_t node;
+  u8 *s = 0;
+  u32 mode;
+
+  mode = mp->mode;
+  s = format (0, "%U", format_lisp_map_request_mode, mode);
+  vec_add1 (s, 0);
+
+  vat_json_init_object (&node);
+  vat_json_object_add_string_copy (&node, "map_request_mode", s);
+  vat_json_print (vam->ofp, &node);
+  vat_json_free (&node);
+
+  vec_free (s);
+  vam->retval = ntohl (mp->retval);
+  vam->result_ready = 1;
+}
+
 static void
 vl_api_show_lisp_pitr_reply_t_handler (vl_api_show_lisp_pitr_reply_t * mp)
 {
 static void
 vl_api_show_lisp_pitr_reply_t_handler (vl_api_show_lisp_pitr_reply_t * mp)
 {
@@ -3407,6 +3463,7 @@ _(lisp_gpe_enable_disable_reply)                        \
 _(lisp_gpe_add_del_iface_reply)                         \
 _(lisp_enable_disable_reply)                            \
 _(lisp_pitr_set_locator_set_reply)                      \
 _(lisp_gpe_add_del_iface_reply)                         \
 _(lisp_enable_disable_reply)                            \
 _(lisp_pitr_set_locator_set_reply)                      \
+_(lisp_map_request_mode_reply)                          \
 _(lisp_add_del_map_request_itr_rlocs_reply)             \
 _(lisp_eid_table_add_del_map_reply)                     \
 _(vxlan_gpe_add_del_tunnel_reply)                       \
 _(lisp_add_del_map_request_itr_rlocs_reply)             \
 _(lisp_eid_table_add_del_map_reply)                     \
 _(vxlan_gpe_add_del_tunnel_reply)                       \
@@ -3599,6 +3656,7 @@ _(LISP_ADD_DEL_MAP_RESOLVER_REPLY, lisp_add_del_map_resolver_reply)     \
 _(LISP_GPE_ENABLE_DISABLE_REPLY, lisp_gpe_enable_disable_reply)         \
 _(LISP_ENABLE_DISABLE_REPLY, lisp_enable_disable_reply)                 \
 _(LISP_PITR_SET_LOCATOR_SET_REPLY, lisp_pitr_set_locator_set_reply)     \
 _(LISP_GPE_ENABLE_DISABLE_REPLY, lisp_gpe_enable_disable_reply)         \
 _(LISP_ENABLE_DISABLE_REPLY, lisp_enable_disable_reply)                 \
 _(LISP_PITR_SET_LOCATOR_SET_REPLY, lisp_pitr_set_locator_set_reply)     \
+_(LISP_MAP_REQUEST_MODE_REPLY, lisp_map_request_mode_reply)             \
 _(LISP_EID_TABLE_ADD_DEL_MAP_REPLY, lisp_eid_table_add_del_map_reply)   \
 _(LISP_GPE_ADD_DEL_IFACE_REPLY, lisp_gpe_add_del_iface_reply)           \
 _(LISP_LOCATOR_SET_DETAILS, lisp_locator_set_details)                   \
 _(LISP_EID_TABLE_ADD_DEL_MAP_REPLY, lisp_eid_table_add_del_map_reply)   \
 _(LISP_GPE_ADD_DEL_IFACE_REPLY, lisp_gpe_add_del_iface_reply)           \
 _(LISP_LOCATOR_SET_DETAILS, lisp_locator_set_details)                   \
@@ -3614,6 +3672,7 @@ _(LISP_ADD_DEL_MAP_REQUEST_ITR_RLOCS_REPLY,                             \
 _(LISP_GET_MAP_REQUEST_ITR_RLOCS_REPLY,                                 \
   lisp_get_map_request_itr_rlocs_reply)                                 \
 _(SHOW_LISP_PITR_REPLY, show_lisp_pitr_reply)                           \
 _(LISP_GET_MAP_REQUEST_ITR_RLOCS_REPLY,                                 \
   lisp_get_map_request_itr_rlocs_reply)                                 \
 _(SHOW_LISP_PITR_REPLY, show_lisp_pitr_reply)                           \
+_(SHOW_LISP_MAP_REQUEST_MODE_REPLY, show_lisp_map_request_mode_reply)   \
 _(AF_PACKET_CREATE_REPLY, af_packet_create_reply)                       \
 _(AF_PACKET_DELETE_REPLY, af_packet_delete_reply)                       \
 _(POLICER_ADD_DEL_REPLY, policer_add_del_reply)                         \
 _(AF_PACKET_CREATE_REPLY, af_packet_create_reply)                       \
 _(AF_PACKET_DELETE_REPLY, af_packet_delete_reply)                       \
 _(POLICER_ADD_DEL_REPLY, policer_add_del_reply)                         \
@@ -12380,6 +12439,59 @@ api_lisp_enable_disable (vat_main_t * vam)
   return 0;
 }
 
   return 0;
 }
 
+static int
+api_show_lisp_map_request_mode (vat_main_t * vam)
+{
+  f64 timeout = ~0;
+  vl_api_show_lisp_map_request_mode_t *mp;
+
+  M (SHOW_LISP_MAP_REQUEST_MODE, show_lisp_map_request_mode);
+
+  /* send */
+  S;
+
+  /* wait for reply */
+  W;
+
+  return 0;
+}
+
+static int
+api_lisp_map_request_mode (vat_main_t * vam)
+{
+  f64 timeout = ~0;
+  unformat_input_t *input = vam->input;
+  vl_api_lisp_map_request_mode_t *mp;
+  u8 mode = 0;
+
+  /* Parse args required to build the message */
+  while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
+    {
+      if (unformat (input, "dst-only"))
+       mode = 0;
+      else if (unformat (input, "src-dst"))
+       mode = 1;
+      else
+       {
+         errmsg ("parse error '%U'", format_unformat_error, input);
+         return -99;
+       }
+    }
+
+  M (LISP_MAP_REQUEST_MODE, lisp_map_request_mode);
+
+  mp->mode = mode;
+
+  /* send */
+  S;
+
+  /* wait for reply */
+  W;
+
+  /* notreached */
+  return 0;
+}
+
 /**
  * Enable/disable LISP proxy ITR.
  *
 /**
  * Enable/disable LISP proxy ITR.
  *
@@ -15398,6 +15510,7 @@ _(lisp_add_del_adjacency, "add|del vni <vni> deid <dest-eid> seid "     \
                           "<src-eid> rloc <locator> p <prio> w <weight>"\
                           "[rloc <loc> ... ] action <action>")          \
 _(lisp_pitr_set_locator_set, "locator-set <loc-set-name> | del")        \
                           "<src-eid> rloc <locator> p <prio> w <weight>"\
                           "[rloc <loc> ... ] action <action>")          \
 _(lisp_pitr_set_locator_set, "locator-set <loc-set-name> | del")        \
+_(lisp_map_request_mode, "src-dst|dst-only")                            \
 _(lisp_add_del_map_request_itr_rlocs, "<loc-set-name> [del]")           \
 _(lisp_eid_table_add_del_map, "[del] vni <vni> vrf <vrf>")              \
 _(lisp_locator_set_dump, "[local | remote]")                            \
 _(lisp_add_del_map_request_itr_rlocs, "<loc-set-name> [del]")           \
 _(lisp_eid_table_add_del_map, "[del] vni <vni> vrf <vrf>")              \
 _(lisp_locator_set_dump, "[local | remote]")                            \
@@ -15411,6 +15524,7 @@ _(lisp_map_resolver_dump, "")                                           \
 _(show_lisp_status, "")                                                 \
 _(lisp_get_map_request_itr_rlocs, "")                                   \
 _(show_lisp_pitr, "")                                                   \
 _(show_lisp_status, "")                                                 \
 _(lisp_get_map_request_itr_rlocs, "")                                   \
 _(show_lisp_pitr, "")                                                   \
+_(show_lisp_map_request_mode, "")                                       \
 _(af_packet_create, "name <host interface name> [hw_addr <mac>]")       \
 _(af_packet_delete, "name <host interface name>")                       \
 _(policer_add_del, "name <policer name> <params> [del]")                \
 _(af_packet_create, "name <host interface name> [hw_addr <mac>]")       \
 _(af_packet_delete, "name <host interface name>")                       \
 _(policer_add_del, "name <policer name> <params> [del]")                \
index 1a46eb9..3bdc80a 100644 (file)
@@ -364,6 +364,7 @@ _(LISP_GPE_ADD_DEL_IFACE, lisp_gpe_add_del_iface)                       \
 _(LISP_ADD_DEL_REMOTE_MAPPING, lisp_add_del_remote_mapping)             \
 _(LISP_ADD_DEL_ADJACENCY, lisp_add_del_adjacency)                       \
 _(LISP_PITR_SET_LOCATOR_SET, lisp_pitr_set_locator_set)                 \
 _(LISP_ADD_DEL_REMOTE_MAPPING, lisp_add_del_remote_mapping)             \
 _(LISP_ADD_DEL_ADJACENCY, lisp_add_del_adjacency)                       \
 _(LISP_PITR_SET_LOCATOR_SET, lisp_pitr_set_locator_set)                 \
+_(LISP_MAP_REQUEST_MODE, lisp_map_request_mode)                         \
 _(LISP_EID_TABLE_ADD_DEL_MAP, lisp_eid_table_add_del_map)               \
 _(LISP_LOCATOR_SET_DUMP, lisp_locator_set_dump)                         \
 _(LISP_LOCATOR_DUMP, lisp_locator_dump)                                 \
 _(LISP_EID_TABLE_ADD_DEL_MAP, lisp_eid_table_add_del_map)               \
 _(LISP_LOCATOR_SET_DUMP, lisp_locator_set_dump)                         \
 _(LISP_LOCATOR_DUMP, lisp_locator_dump)                                 \
@@ -377,6 +378,7 @@ _(LISP_ADD_DEL_MAP_REQUEST_ITR_RLOCS,                                   \
   lisp_add_del_map_request_itr_rlocs)                                   \
 _(LISP_GET_MAP_REQUEST_ITR_RLOCS, lisp_get_map_request_itr_rlocs)       \
 _(SHOW_LISP_PITR, show_lisp_pitr)                                       \
   lisp_add_del_map_request_itr_rlocs)                                   \
 _(LISP_GET_MAP_REQUEST_ITR_RLOCS, lisp_get_map_request_itr_rlocs)       \
 _(SHOW_LISP_PITR, show_lisp_pitr)                                       \
+_(SHOW_LISP_MAP_REQUEST_MODE, show_lisp_map_request_mode)               \
 _(SR_MULTICAST_MAP_ADD_DEL, sr_multicast_map_add_del)                   \
 _(AF_PACKET_CREATE, af_packet_create)                                   \
 _(AF_PACKET_DELETE, af_packet_delete)                                   \
 _(SR_MULTICAST_MAP_ADD_DEL, sr_multicast_map_add_del)                   \
 _(AF_PACKET_CREATE, af_packet_create)                                   \
 _(AF_PACKET_DELETE, af_packet_delete)                                   \
@@ -5239,6 +5241,32 @@ vl_api_lisp_gpe_add_del_iface_t_handler (vl_api_lisp_gpe_add_del_iface_t * mp)
   REPLY_MACRO (VL_API_LISP_GPE_ADD_DEL_IFACE_REPLY);
 }
 
   REPLY_MACRO (VL_API_LISP_GPE_ADD_DEL_IFACE_REPLY);
 }
 
+static void
+  vl_api_show_lisp_map_request_mode_t_handler
+  (vl_api_show_lisp_map_request_mode_t * mp)
+{
+  int rv = 0;
+  vl_api_show_lisp_map_request_mode_reply_t *rmp;
+
+  /* *INDENT-OFF* */
+  REPLY_MACRO2(VL_API_SHOW_LISP_MAP_REQUEST_MODE_REPLY,
+  ({
+    rmp->mode = vnet_lisp_get_map_request_mode ();
+  }));
+  /* *INDENT-ON* */
+}
+
+static void
+vl_api_lisp_map_request_mode_t_handler (vl_api_lisp_map_request_mode_t * mp)
+{
+  vl_api_lisp_map_request_mode_reply_t *rmp;
+  int rv = 0;
+
+  rv = vnet_lisp_set_map_request_mode (mp->mode);
+
+  REPLY_MACRO (VL_API_LISP_MAP_REQUEST_MODE_REPLY);
+}
+
 static void
 vl_api_lisp_pitr_set_locator_set_t_handler (vl_api_lisp_pitr_set_locator_set_t
                                            * mp)
 static void
 vl_api_lisp_pitr_set_locator_set_t_handler (vl_api_lisp_pitr_set_locator_set_t
                                            * mp)
index 98598ce..37360b8 100644 (file)
@@ -2600,6 +2600,27 @@ static void *vl_api_lisp_locator_dump_t_print
   FINISH;
 }
 
   FINISH;
 }
 
+static void *vl_api_lisp_map_request_mode_t_print
+  (vl_api_lisp_map_request_mode_t * mp, void *handle)
+{
+  u8 *s;
+
+  s = format (0, "SCRIPT: lisp_map_request_mode ");
+
+  switch (mp->mode)
+    {
+    case 0:
+      s = format (s, "dst-only");
+      break;
+    case 1:
+      s = format (s, "src-dst");
+    default:
+      break;
+    }
+
+  FINISH;
+}
+
 static void *vl_api_lisp_eid_table_dump_t_print
   (vl_api_lisp_eid_table_dump_t * mp, void *handle)
 {
 static void *vl_api_lisp_eid_table_dump_t_print
   (vl_api_lisp_eid_table_dump_t * mp, void *handle)
 {
@@ -2680,6 +2701,7 @@ static void *vl_api_ipsec_gre_tunnel_dump_t_print
 #define foreach_custom_print_no_arg_function                            \
 _(lisp_eid_table_vni_dump)                                              \
 _(lisp_map_resolver_dump)                                               \
 #define foreach_custom_print_no_arg_function                            \
 _(lisp_eid_table_vni_dump)                                              \
 _(lisp_map_resolver_dump)                                               \
+_(show_lisp_map_request_mode)                                           \
 _(lisp_gpe_tunnel_dump)
 
 #define _(f)                                                            \
 _(lisp_gpe_tunnel_dump)
 
 #define _(f)                                                            \
@@ -2812,6 +2834,8 @@ _(LISP_ENABLE_DISABLE, lisp_enable_disable)                             \
 _(LISP_GPE_ENABLE_DISABLE, lisp_gpe_enable_disable)                     \
 _(LISP_GPE_ADD_DEL_IFACE, lisp_gpe_add_del_iface)                       \
 _(LISP_PITR_SET_LOCATOR_SET, lisp_pitr_set_locator_set)                 \
 _(LISP_GPE_ENABLE_DISABLE, lisp_gpe_enable_disable)                     \
 _(LISP_GPE_ADD_DEL_IFACE, lisp_gpe_add_del_iface)                       \
 _(LISP_PITR_SET_LOCATOR_SET, lisp_pitr_set_locator_set)                 \
+_(LISP_MAP_REQUEST_MODE, lisp_map_request_mode)                         \
+_(SHOW_LISP_MAP_REQUEST_MODE, show_lisp_map_request_mode)               \
 _(LISP_ADD_DEL_REMOTE_MAPPING, lisp_add_del_remote_mapping)             \
 _(LISP_ADD_DEL_ADJACENCY, lisp_add_del_adjacency)                       \
 _(LISP_ADD_DEL_MAP_REQUEST_ITR_RLOCS,                                   \
 _(LISP_ADD_DEL_REMOTE_MAPPING, lisp_add_del_remote_mapping)             \
 _(LISP_ADD_DEL_ADJACENCY, lisp_add_del_adjacency)                       \
 _(LISP_ADD_DEL_MAP_REQUEST_ITR_RLOCS,                                   \
index 5c75986..33793b0 100644 (file)
@@ -2621,6 +2621,53 @@ define lisp_pitr_set_locator_set_reply
   i32 retval;
 };
 
   i32 retval;
 };
 
+/** \brief set LISP map-request mode. Based on configuration VPP will send
+      src/dest or just normal destination map requests.
+    @param client_index - opaque cookie to identify the sender
+    @param context - sender context, to match reply w/ request
+    @param mode - new map-request mode. Supported values are:
+      0 - destination only
+      1 - source/destaination
+*/
+define lisp_map_request_mode
+{
+  u32 client_index;
+  u32 context;
+  u8 mode;
+};
+
+/** \brief Reply for lisp_map_request_mode
+    @param context - returned sender context, to match reply w/ request
+    @param retval - return code
+*/
+define lisp_map_request_mode_reply
+{
+  u32 context;
+  i32 retval;
+};
+
+/** \brief Request for LISP map-request mode
+    @param client_index - opaque cookie to identify the sender
+    @param context - sender context, to match reply w/ request
+*/
+define show_lisp_map_request_mode
+{
+  u32 client_index;
+  u32 context;
+};
+
+/** \brief Reply for show_lisp_map_request_mode
+    @param context - returned sender context, to match reply w/ request
+    @param retval - return code
+    @param mode - map-request mode
+*/
+define show_lisp_map_request_mode_reply
+{
+  u32 context;
+  i32 retval;
+  u8 mode;
+};
+
 /** \brief add or delete remote static mapping
     @param client_index - opaque cookie to identify the sender
     @param context - sender context, to match reply w/ request
 /** \brief add or delete remote static mapping
     @param client_index - opaque cookie to identify the sender
     @param context - sender context, to match reply w/ request