FD.io VPP  v16.12-rc0-308-g931be3a
Vector Packet Processing
control.c
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2016 Cisco and/or its affiliates.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at:
6  *
7  * http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include <vlibmemory/api.h>
17 #include <vnet/lisp-cp/control.h>
18 #include <vnet/lisp-cp/packets.h>
20 #include <vnet/lisp-gpe/lisp_gpe.h>
23 #include <vnet/fib/fib_entry.h>
24 #include <vnet/fib/fib_table.h>
25 
26 typedef struct
27 {
33 
34 u8
36 {
38  return lcm->map_request_mode;
39 }
40 
41 static int
43  u8 smr_invoked, u8 is_resend);
44 
47  u32 sw_if_index, u8 loop)
48 {
49  vnet_main_t *vnm = vnet_get_main ();
50  vnet_sw_interface_t *swif = vnet_get_sw_interface (vnm, sw_if_index);
51  if (loop && swif->flags & VNET_SW_INTERFACE_FLAG_UNNUMBERED)
52  sw_if_index = swif->unnumbered_sw_if_index;
53  u32 ia =
54  (vec_len ((lm)->if_address_pool_index_by_sw_if_index) > (sw_if_index)) ?
55  vec_elt ((lm)->if_address_pool_index_by_sw_if_index, (sw_if_index)) :
56  (u32) ~ 0;
57  return pool_elt_at_index ((lm)->if_address_pool, ia);
58 }
59 
60 void *
62  u8 version)
63 {
65 
66  ia = ip_interface_get_first_interface_address (lm, sw_if_index, 1);
67  if (!ia)
68  return 0;
69  return ip_interface_address_get_address (lm, ia);
70 }
71 
72 int
74  u8 version, ip_address_t * result)
75 {
76  ip_lookup_main_t *lm;
77  void *addr;
78 
79  lm = (version == IP4) ? &lcm->im4->lookup_main : &lcm->im6->lookup_main;
80  addr = ip_interface_get_first_address (lm, sw_if_index, version);
81  if (!addr)
82  return 0;
83 
84  ip_address_set (result, addr, version);
85  return 1;
86 }
87 
88 /**
89  * convert from a LISP address to a FIB prefix
90  */
91 void
92 ip_address_to_fib_prefix (const ip_address_t * addr, fib_prefix_t * prefix)
93 {
94  if (addr->version == IP4)
95  {
96  prefix->fp_len = 32;
97  prefix->fp_proto = FIB_PROTOCOL_IP4;
98  memset (&prefix->fp_addr.pad, 0, sizeof (prefix->fp_addr.pad));
99  memcpy (&prefix->fp_addr.ip4, &addr->ip, sizeof (prefix->fp_addr.ip4));
100  }
101  else
102  {
103  prefix->fp_len = 128;
104  prefix->fp_proto = FIB_PROTOCOL_IP6;
105  memcpy (&prefix->fp_addr.ip6, &addr->ip, sizeof (prefix->fp_addr.ip6));
106  }
107 }
108 
109 /**
110  * convert from a LISP to a FIB prefix
111  */
112 void
113 ip_prefix_to_fib_prefix (const ip_prefix_t * ip_prefix,
114  fib_prefix_t * fib_prefix)
115 {
116  ip_address_to_fib_prefix (&ip_prefix->addr, fib_prefix);
117  fib_prefix->fp_len = ip_prefix->len;
118 }
119 
120 /**
121  * Find the sw_if_index of the interface that would be used to egress towards
122  * dst.
123  */
124 u32
126 {
127  fib_node_index_t fei;
128  fib_prefix_t prefix;
129 
130  ip_address_to_fib_prefix (dst, &prefix);
131 
132  fei = fib_table_lookup (0, &prefix);
133 
134  return (fib_entry_get_resolving_interface (fei));
135 }
136 
137 /**
138  * Find first IP of the interface that would be used to egress towards dst.
139  * Returns 1 if the address is found 0 otherwise.
140  */
141 int
143  ip_address_t * result)
144 {
145  u32 si;
146  ip_lookup_main_t *lm;
147  void *addr = 0;
148  u8 ipver;
149 
150  ASSERT (result != 0);
151 
152  ipver = ip_addr_version (dst);
153 
154  lm = (ipver == IP4) ? &lcm->im4->lookup_main : &lcm->im6->lookup_main;
155  si = ip_fib_get_egress_iface_for_dst (lcm, dst);
156 
157  if ((u32) ~ 0 == si)
158  return 0;
159 
160  /* find the first ip address */
161  addr = ip_interface_get_first_address (lm, si, ipver);
162  if (0 == addr)
163  return 0;
164 
165  ip_address_set (result, addr, ipver);
166  return 1;
167 }
168 
169 static int
170 dp_add_del_iface (lisp_cp_main_t * lcm, u32 vni, u8 is_l2, u8 is_add)
171 {
172  uword *dp_table;
173 
174  if (!is_l2)
175  {
176  dp_table = hash_get (lcm->table_id_by_vni, vni);
177 
178  if (!dp_table)
179  {
180  clib_warning ("vni %d not associated to a vrf!", vni);
181  return VNET_API_ERROR_INVALID_VALUE;
182  }
183  }
184  else
185  {
186  dp_table = hash_get (lcm->bd_id_by_vni, vni);
187  if (!dp_table)
188  {
189  clib_warning ("vni %d not associated to a bridge domain!", vni);
190  return VNET_API_ERROR_INVALID_VALUE;
191  }
192  }
193 
194  /* enable/disable data-plane interface */
195  if (is_add)
196  {
197  if (is_l2)
198  lisp_gpe_tenant_l2_iface_add_or_lock (vni, dp_table[0]);
199  else
200  lisp_gpe_tenant_l3_iface_add_or_lock (vni, dp_table[0]);
201  }
202  else
203  {
204  if (is_l2)
206  else
208  }
209 
210  return 0;
211 }
212 
213 static void
214 dp_del_fwd_entry (lisp_cp_main_t * lcm, u32 src_map_index, u32 dst_map_index)
215 {
217  fwd_entry_t *fe = 0;
218  uword *feip = 0;
219  memset (a, 0, sizeof (*a));
220 
221  feip = hash_get (lcm->fwd_entry_by_mapping_index, dst_map_index);
222  if (!feip)
223  return;
224 
225  fe = pool_elt_at_index (lcm->fwd_entry_pool, feip[0]);
226 
227  /* delete dp fwd entry */
228  u32 sw_if_index;
229  a->is_add = 0;
230  a->locator_pairs = fe->locator_pairs;
231  a->vni = gid_address_vni (&fe->reid);
232  gid_address_copy (&a->rmt_eid, &fe->reid);
233  if (fe->is_src_dst)
234  gid_address_copy (&a->lcl_eid, &fe->leid);
235 
236  vnet_lisp_gpe_add_del_fwd_entry (a, &sw_if_index);
237 
238  /* delete entry in fwd table */
239  hash_unset (lcm->fwd_entry_by_mapping_index, dst_map_index);
240  vec_free (fe->locator_pairs);
241  pool_put (lcm->fwd_entry_pool, fe);
242 }
243 
244 /**
245  * Finds first remote locator with best (lowest) priority that has a local
246  * peer locator with an underlying route to it.
247  *
248  */
249 static u32
251  mapping_t * rmt_map, locator_pair_t ** locator_pairs)
252 {
253  u32 i, limitp = 0, li, found = 0, esi;
254  locator_set_t *rmt_ls, *lcl_ls;
255  ip_address_t _lcl_addr, *lcl_addr = &_lcl_addr;
256  locator_t *lp, *rmt = 0;
257  uword *checked = 0;
258  locator_pair_t pair;
259 
260  rmt_ls =
262  lcl_ls =
264 
265  if (!rmt_ls || vec_len (rmt_ls->locator_indices) == 0)
266  return 0;
267 
268  while (1)
269  {
270  rmt = 0;
271 
272  /* find unvisited remote locator with best priority */
273  for (i = 0; i < vec_len (rmt_ls->locator_indices); i++)
274  {
275  if (0 != hash_get (checked, i))
276  continue;
277 
278  li = vec_elt (rmt_ls->locator_indices, i);
279  lp = pool_elt_at_index (lcm->locator_pool, li);
280 
281  /* we don't support non-IP locators for now */
283  continue;
284 
285  if ((found && lp->priority == limitp)
286  || (!found && lp->priority >= limitp))
287  {
288  rmt = lp;
289 
290  /* don't search for locators with lower priority and don't
291  * check this locator again*/
292  limitp = lp->priority;
293  hash_set (checked, i, 1);
294  break;
295  }
296  }
297  /* check if a local locator with a route to remote locator exists */
298  if (rmt != 0)
299  {
300  /* find egress sw_if_index for rmt locator */
301  esi =
303  &gid_address_ip (&rmt->address));
304  if ((u32) ~ 0 == esi)
305  continue;
306 
307  for (i = 0; i < vec_len (lcl_ls->locator_indices); i++)
308  {
309  li = vec_elt (lcl_ls->locator_indices, i);
310  locator_t *sl = pool_elt_at_index (lcm->locator_pool, li);
311 
312  /* found local locator with the needed sw_if_index */
313  if (sl->sw_if_index == esi)
314  {
315  /* and it has an address */
316  if (0 == ip_interface_get_first_ip_address (lcm,
317  sl->sw_if_index,
319  (&rmt->address),
320  lcl_addr))
321  continue;
322 
323  memset (&pair, 0, sizeof (pair));
324  ip_address_copy (&pair.rmt_loc,
325  &gid_address_ip (&rmt->address));
326  ip_address_copy (&pair.lcl_loc, lcl_addr);
327  pair.weight = rmt->weight;
328  vec_add1 (locator_pairs[0], pair);
329  found = 1;
330  }
331  }
332  }
333  else
334  break;
335  }
336 
337  hash_free (checked);
338  return found;
339 }
340 
341 static void
343  fid_address_t * fid)
344 {
346 
347  dst[0] = src[0];
348 
349  switch (fid_addr_type (fid))
350  {
351  case FID_ADDR_IP_PREF:
353  gid_address_ippref (dst) = fid_addr_ippref (fid);
354  break;
355  case FID_ADDR_MAC:
357  mac_copy (gid_address_mac (dst), fid_addr_mac (fid));
358  break;
359  default:
360  clib_warning ("Unsupported fid type %d!", fid_addr_type (fid));
361  break;
362  }
363 }
364 
365 static void
366 dp_add_fwd_entry (lisp_cp_main_t * lcm, u32 src_map_index, u32 dst_map_index)
367 {
369  mapping_t *src_map, *dst_map;
370  u32 sw_if_index;
371  uword *feip = 0, *dpid;
372  fwd_entry_t *fe;
373  u8 type, is_src_dst = 0;
374 
375  memset (a, 0, sizeof (*a));
376 
377  /* remove entry if it already exists */
378  feip = hash_get (lcm->fwd_entry_by_mapping_index, dst_map_index);
379  if (feip)
380  dp_del_fwd_entry (lcm, src_map_index, dst_map_index);
381 
382  if (lcm->lisp_pitr)
383  src_map = pool_elt_at_index (lcm->mapping_pool, lcm->pitr_map_index);
384  else
385  src_map = pool_elt_at_index (lcm->mapping_pool, src_map_index);
386  dst_map = pool_elt_at_index (lcm->mapping_pool, dst_map_index);
387 
388  /* insert data plane forwarding entry */
389  a->is_add = 1;
390 
391  if (MR_MODE_SRC_DST == lcm->map_request_mode)
392  {
393  if (GID_ADDR_SRC_DST == gid_address_type (&dst_map->eid))
394  {
395  gid_address_sd_to_flat (&a->rmt_eid, &dst_map->eid,
396  &gid_address_sd_dst (&dst_map->eid));
397  gid_address_sd_to_flat (&a->lcl_eid, &dst_map->eid,
398  &gid_address_sd_src (&dst_map->eid));
399  }
400  else
401  {
402  gid_address_copy (&a->rmt_eid, &dst_map->eid);
403  gid_address_copy (&a->lcl_eid, &src_map->eid);
404  }
405  is_src_dst = 1;
406  }
407  else
408  gid_address_copy (&a->rmt_eid, &dst_map->eid);
409 
410  a->vni = gid_address_vni (&a->rmt_eid);
411 
412  /* get vrf or bd_index associated to vni */
413  type = gid_address_type (&a->rmt_eid);
414  if (GID_ADDR_IP_PREFIX == type)
415  {
416  dpid = hash_get (lcm->table_id_by_vni, a->vni);
417  if (!dpid)
418  {
419  clib_warning ("vni %d not associated to a vrf!", a->vni);
420  return;
421  }
422  a->table_id = dpid[0];
423  }
424  else if (GID_ADDR_MAC == type)
425  {
426  dpid = hash_get (lcm->bd_id_by_vni, a->vni);
427  if (!dpid)
428  {
429  clib_warning ("vni %d not associated to a bridge domain !", a->vni);
430  return;
431  }
432  a->bd_id = dpid[0];
433  }
434 
435  /* find best locator pair that 1) verifies LISP policy 2) are connected */
436  if (0 == get_locator_pairs (lcm, src_map, dst_map, &a->locator_pairs))
437  {
438  /* negative entry */
439  a->is_negative = 1;
440  a->action = dst_map->action;
441  }
442 
443  /* TODO remove */
445  a->decap_next_index = (ipver == IP4) ?
446  LISP_GPE_INPUT_NEXT_IP4_INPUT : LISP_GPE_INPUT_NEXT_IP6_INPUT;
447 
448  vnet_lisp_gpe_add_del_fwd_entry (a, &sw_if_index);
449 
450  /* add tunnel to fwd entry table XXX check return value from DP insertion */
451  pool_get (lcm->fwd_entry_pool, fe);
452  fe->locator_pairs = a->locator_pairs;
453  gid_address_copy (&fe->reid, &a->rmt_eid);
454  gid_address_copy (&fe->leid, &src_map->eid);
455  fe->is_src_dst = is_src_dst;
456  hash_set (lcm->fwd_entry_by_mapping_index, dst_map_index,
457  fe - lcm->fwd_entry_pool);
458 }
459 
460 /**
461  * Returns vector of adjacencies.
462  *
463  * The caller must free the vector returned by this function.
464  *
465  * @param vni virtual network identifier
466  * @return vector of adjacencies
467  */
470 {
472  fwd_entry_t *fwd;
473  lisp_adjacency_t *adjs = 0, adj;
474 
475  /* *INDENT-OFF* */
476  pool_foreach(fwd, lcm->fwd_entry_pool,
477  ({
478  if (gid_address_vni (&fwd->reid) != vni)
479  continue;
480 
481  gid_address_copy (&adj.reid, &fwd->reid);
482  gid_address_copy (&adj.leid, &fwd->leid);
483  vec_add1 (adjs, adj);
484  }));
485  /* *INDENT-ON* */
486 
487  return adjs;
488 }
489 
490 static clib_error_t *
492  unformat_input_t * input,
493  vlib_cli_command_t * cmd)
494 {
495  lisp_adjacency_t *adjs, *adj;
496  vlib_cli_output (vm, "%s %40s\n", "leid", "reid");
497  unformat_input_t _line_input, *line_input = &_line_input;
498  u32 vni = ~0;
499 
500  /* Get a line of input. */
501  if (!unformat_user (input, unformat_line_input, line_input))
502  return 0;
503 
504  while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
505  {
506  if (unformat (line_input, "vni %d", &vni))
507  ;
508  else
509  {
510  vlib_cli_output (vm, "parse error: '%U'",
511  format_unformat_error, line_input);
512  return 0;
513  }
514  }
515 
516  if (~0 == vni)
517  {
518  vlib_cli_output (vm, "error: no vni specified!");
519  return 0;
520  }
521 
523 
524  vec_foreach (adj, adjs)
525  {
526  vlib_cli_output (vm, "%U %40U\n", format_gid_address, &adj->leid,
527  format_gid_address, &adj->reid);
528  }
529  vec_free (adjs);
530 
531  return 0;
532 }
533 
534 /* *INDENT-OFF* */
535 VLIB_CLI_COMMAND (lisp_show_adjacencies_command) = {
536  .path = "show lisp adjacencies",
537  .short_help = "show lisp adjacencies",
539 };
540 /* *INDENT-ON* */
541 
542 /**
543  * Add/remove mapping to/from map-cache. Overwriting not allowed.
544  */
545 int
547  u32 * map_index_result)
548 {
550  u32 mi, *map_indexp, map_index, i;
551  mapping_t *m, *old_map;
552  u32 **eid_indexes;
553 
555  old_map = mi != ~0 ? pool_elt_at_index (lcm->mapping_pool, mi) : 0;
556  if (a->is_add)
557  {
558  /* TODO check if overwriting and take appropriate actions */
559  if (mi != GID_LOOKUP_MISS && !gid_address_cmp (&old_map->eid, &a->eid))
560  {
561  clib_warning ("eid %U found in the eid-table", format_gid_address,
562  &a->eid);
563  return VNET_API_ERROR_VALUE_EXIST;
564  }
565 
566  pool_get (lcm->mapping_pool, m);
567  gid_address_copy (&m->eid, &a->eid);
569  m->ttl = a->ttl;
570  m->action = a->action;
571  m->local = a->local;
572  m->is_static = a->is_static;
573 
574  map_index = m - lcm->mapping_pool;
575  gid_dictionary_add_del (&lcm->mapping_index_by_gid, &a->eid, map_index,
576  1);
577 
579  {
580  clib_warning ("Locator set with index %d doesn't exist",
581  a->locator_set_index);
582  return VNET_API_ERROR_INVALID_VALUE;
583  }
584 
585  /* add eid to list of eids supported by locator-set */
587  eid_indexes = vec_elt_at_index (lcm->locator_set_to_eids,
588  a->locator_set_index);
589  vec_add1 (eid_indexes[0], map_index);
590 
591  if (a->local)
592  {
593  /* mark as local */
594  vec_add1 (lcm->local_mappings_indexes, map_index);
595  }
596  map_index_result[0] = map_index;
597  }
598  else
599  {
600  if (mi == GID_LOOKUP_MISS)
601  {
602  clib_warning ("eid %U not found in the eid-table",
603  format_gid_address, &a->eid);
604  return VNET_API_ERROR_INVALID_VALUE;
605  }
606 
607  /* clear locator-set to eids binding */
608  eid_indexes = vec_elt_at_index (lcm->locator_set_to_eids,
609  a->locator_set_index);
610  for (i = 0; i < vec_len (eid_indexes[0]); i++)
611  {
612  map_indexp = vec_elt_at_index (eid_indexes[0], i);
613  if (map_indexp[0] == mi)
614  break;
615  }
616  vec_del1 (eid_indexes[0], i);
617 
618  /* remove local mark if needed */
619  m = pool_elt_at_index (lcm->mapping_pool, mi);
620  if (m->local)
621  {
622  u32 k, *lm_indexp;
623  for (k = 0; k < vec_len (lcm->local_mappings_indexes); k++)
624  {
625  lm_indexp = vec_elt_at_index (lcm->local_mappings_indexes, k);
626  if (lm_indexp[0] == mi)
627  break;
628  }
630  }
631 
632  /* remove mapping from dictionary */
634  gid_address_free (&m->eid);
635  pool_put_index (lcm->mapping_pool, mi);
636  }
637 
638  return 0;
639 }
640 
641 /**
642  * Add/update/delete mapping to/in/from map-cache.
643  */
644 int
646  u32 * map_index_result)
647 {
648  uword *dp_table = 0;
649  u32 vni;
650  u8 type;
651 
653 
655  {
656  clib_warning ("LISP is disabled!");
657  return VNET_API_ERROR_LISP_DISABLED;
658  }
659 
660  vni = gid_address_vni (&a->eid);
661  type = gid_address_type (&a->eid);
662  if (GID_ADDR_IP_PREFIX == type)
663  dp_table = hash_get (lcm->table_id_by_vni, vni);
664  else if (GID_ADDR_MAC == type)
665  dp_table = hash_get (lcm->bd_id_by_vni, vni);
666 
667  if (!dp_table)
668  {
669  clib_warning ("vni %d not associated to a %s!", vni,
670  GID_ADDR_IP_PREFIX == type ? "vrf" : "bd");
671  return VNET_API_ERROR_INVALID_VALUE;
672  }
673 
674  /* store/remove mapping from map-cache */
675  return vnet_lisp_map_cache_add_del (a, map_index_result);
676 }
677 
678 static clib_error_t *
680  vlib_cli_command_t * cmd)
681 {
683  unformat_input_t _line_input, *line_input = &_line_input;
684  u8 is_add = 1;
685  gid_address_t eid;
686  gid_address_t *eids = 0;
687  clib_error_t *error = 0;
688  u8 *locator_set_name = 0;
689  u32 locator_set_index = 0, map_index = 0;
690  uword *p;
692  int rv = 0;
693  u32 vni = 0;
694 
695  memset (&eid, 0, sizeof (eid));
696  memset (a, 0, sizeof (*a));
697 
698  /* Get a line of input. */
699  if (!unformat_user (input, unformat_line_input, line_input))
700  return 0;
701 
702  while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
703  {
704  if (unformat (line_input, "add"))
705  is_add = 1;
706  else if (unformat (line_input, "del"))
707  is_add = 0;
708  else if (unformat (line_input, "eid %U", unformat_gid_address, &eid))
709  ;
710  else if (unformat (line_input, "vni %d", &vni))
711  gid_address_vni (&eid) = vni;
712  else if (unformat (line_input, "locator-set %_%v%_", &locator_set_name))
713  {
714  p = hash_get_mem (lcm->locator_set_index_by_name, locator_set_name);
715  if (!p)
716  {
717  error = clib_error_return (0, "locator-set %s doesn't exist",
718  locator_set_name);
719  goto done;
720  }
721  locator_set_index = p[0];
722  }
723  else
724  {
725  error = unformat_parse_error (line_input);
726  goto done;
727  }
728  }
729  /* XXX treat batch configuration */
730 
731  if (GID_ADDR_SRC_DST == gid_address_type (&eid))
732  {
733  error =
734  clib_error_return (0, "src/dst is not supported for local EIDs!");
735  goto done;
736  }
737 
738  gid_address_copy (&a->eid, &eid);
739  a->is_add = is_add;
740  a->locator_set_index = locator_set_index;
741  a->local = 1;
742 
743  rv = vnet_lisp_add_del_local_mapping (a, &map_index);
744  if (0 != rv)
745  {
746  error = clib_error_return (0, "failed to %s local mapping!",
747  is_add ? "add" : "delete");
748  }
749 done:
750  vec_free (eids);
751  if (locator_set_name)
752  vec_free (locator_set_name);
753  gid_address_free (&a->eid);
754  return error;
755 }
756 
757 /* *INDENT-OFF* */
758 VLIB_CLI_COMMAND (lisp_add_del_local_eid_command) = {
759  .path = "lisp eid-table",
760  .short_help = "lisp eid-table add/del [vni <vni>] eid <eid> "
761  "locator-set <locator-set>",
763 };
764 /* *INDENT-ON* */
765 
766 int
767 vnet_lisp_eid_table_map (u32 vni, u32 dp_id, u8 is_l2, u8 is_add)
768 {
770  uword *dp_idp, *vnip, **dp_table_by_vni, **vni_by_dp_table;
771 
773  {
774  clib_warning ("LISP is disabled!");
775  return -1;
776  }
777 
778  dp_table_by_vni = is_l2 ? &lcm->bd_id_by_vni : &lcm->table_id_by_vni;
779  vni_by_dp_table = is_l2 ? &lcm->vni_by_bd_id : &lcm->vni_by_table_id;
780 
781  if (!is_l2 && (vni == 0 || dp_id == 0))
782  {
783  clib_warning ("can't add/del default vni-vrf mapping!");
784  return -1;
785  }
786 
787  dp_idp = hash_get (dp_table_by_vni[0], vni);
788  vnip = hash_get (vni_by_dp_table[0], dp_id);
789 
790  if (is_add)
791  {
792  if (dp_idp || vnip)
793  {
794  clib_warning ("vni %d or vrf %d already used in vrf/vni "
795  "mapping!", vni, dp_id);
796  return -1;
797  }
798  hash_set (dp_table_by_vni[0], vni, dp_id);
799  hash_set (vni_by_dp_table[0], dp_id, vni);
800 
801  /* create dp iface */
802  dp_add_del_iface (lcm, vni, is_l2, 1);
803  }
804  else
805  {
806  if (!dp_idp || !vnip)
807  {
808  clib_warning ("vni %d or vrf %d not used in any vrf/vni! "
809  "mapping!", vni, dp_id);
810  return -1;
811  }
812  hash_unset (dp_table_by_vni[0], vni);
813  hash_unset (vni_by_dp_table[0], dp_id);
814 
815  /* remove dp iface */
816  dp_add_del_iface (lcm, vni, is_l2, 0);
817  }
818  return 0;
819 
820 }
821 
822 static clib_error_t *
824  unformat_input_t * input,
825  vlib_cli_command_t * cmd)
826 {
827  u8 is_add = 1, is_l2 = 0;
828  u32 vni = 0, dp_id = 0;
829  unformat_input_t _line_input, *line_input = &_line_input;
830 
831  /* Get a line of input. */
832  if (!unformat_user (input, unformat_line_input, line_input))
833  return 0;
834 
835  while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
836  {
837  if (unformat (line_input, "del"))
838  is_add = 0;
839  else if (unformat (line_input, "vni %d", &vni))
840  ;
841  else if (unformat (line_input, "vrf %d", &dp_id))
842  ;
843  else if (unformat (line_input, "bd %d", &dp_id))
844  is_l2 = 1;
845  else
846  {
847  return unformat_parse_error (line_input);
848  }
849  }
850  vnet_lisp_eid_table_map (vni, dp_id, is_l2, is_add);
851  return 0;
852 }
853 
854 /* *INDENT-OFF* */
855 VLIB_CLI_COMMAND (lisp_eid_table_map_command) = {
856  .path = "lisp eid-table map",
857  .short_help = "lisp eid-table map [del] vni <vni> vrf <vrf> | bd <bdi>",
858  .function = lisp_eid_table_map_command_fn,
859 };
860 /* *INDENT-ON* */
861 
862 /* return 0 if the two locator sets are identical 1 otherwise */
863 static u8
864 compare_locators (lisp_cp_main_t * lcm, u32 * old_ls_indexes,
865  locator_t * new_locators)
866 {
867  u32 i, old_li;
868  locator_t *old_loc, *new_loc;
869 
870  if (vec_len (old_ls_indexes) != vec_len (new_locators))
871  return 1;
872 
873  for (i = 0; i < vec_len (new_locators); i++)
874  {
875  old_li = vec_elt (old_ls_indexes, i);
876  old_loc = pool_elt_at_index (lcm->locator_pool, old_li);
877 
878  new_loc = vec_elt_at_index (new_locators, i);
879 
880  if (locator_cmp (old_loc, new_loc))
881  return 1;
882  }
883  return 0;
884 }
885 
886 typedef struct
887 {
889  void *lcm;
892 
893 /**
894  * Callback invoked when a sub-prefix is found
895  */
896 static void
898 {
899  u8 delete = 0;
900  remove_mapping_args_t *a = arg;
901  lisp_cp_main_t *lcm = a->lcm;
902  mapping_t *m;
903  locator_set_t *ls;
904 
905  m = pool_elt_at_index (lcm->mapping_pool, mi);
906  if (!m)
907  return;
908 
910 
911  if (a->is_negative)
912  {
913  if (0 != vec_len (ls->locator_indices))
914  delete = 1;
915  }
916  else
917  {
918  if (0 == vec_len (ls->locator_indices))
919  delete = 1;
920  }
921 
922  if (delete)
924 }
925 
926 /**
927  * This function searches map cache and looks for IP prefixes that are subset
928  * of the provided one. If such prefix is found depending on 'is_negative'
929  * it does follows:
930  *
931  * 1) if is_negative is true and found prefix points to positive mapping,
932  * then the mapping is removed
933  * 2) if is_negative is false and found prefix points to negative mapping,
934  * then the mapping is removed
935  */
936 static void
938  u8 is_negative)
939 {
940  gid_address_t *e;
942  memset (&a, 0, sizeof (a));
943 
944  /* do this only in src/dst mode ... */
945  if (MR_MODE_SRC_DST != lcm->map_request_mode)
946  return;
947 
948  /* ... and only for IP prefix */
951  return;
952 
953  a.is_negative = is_negative;
954  a.lcm = lcm;
955 
958 
960  vnet_lisp_add_del_mapping (e, 0, 0, 0, 0, 0 /* is add */ , 0, 0);
961 
963 }
964 
965 /**
966  * Adds/removes/updates mapping. Does not program forwarding.
967  *
968  * @param eid end-host identifier
969  * @param rlocs vector of remote locators
970  * @param action action for negative map-reply
971  * @param is_add add mapping if non-zero, delete otherwise
972  * @param res_map_index the map-index that was created/updated/removed. It is
973  * set to ~0 if no action is taken.
974  * @param is_static used for distinguishing between statically learned
975  remote mappings and mappings obtained from MR
976  * @return return code
977  */
978 int
980  u8 authoritative, u32 ttl, u8 is_add, u8 is_static,
981  u32 * res_map_index)
982 {
983  vnet_lisp_add_del_mapping_args_t _m_args, *m_args = &_m_args;
984  vnet_lisp_add_del_locator_set_args_t _ls_args, *ls_args = &_ls_args;
986  u32 mi, ls_index = 0, dst_map_index;
987  mapping_t *old_map;
988 
990  {
991  clib_warning ("LISP is disabled!");
992  return VNET_API_ERROR_LISP_DISABLED;
993  }
994 
995  if (res_map_index)
996  res_map_index[0] = ~0;
997 
998  memset (m_args, 0, sizeof (m_args[0]));
999  memset (ls_args, 0, sizeof (ls_args[0]));
1000 
1001  ls_args->locators = rlocs;
1002 
1003  mi = gid_dictionary_lookup (&lcm->mapping_index_by_gid, eid);
1004  old_map = ((u32) ~ 0 != mi) ? pool_elt_at_index (lcm->mapping_pool, mi) : 0;
1005 
1006  if (is_add)
1007  {
1008  /* overwrite: if mapping already exists, decide if locators should be
1009  * updated and be done */
1010  if (old_map && gid_address_cmp (&old_map->eid, eid) == 0)
1011  {
1012  if (!is_static && (old_map->is_static || old_map->local))
1013  {
1014  /* do not overwrite local or static remote mappings */
1015  clib_warning ("mapping %U rejected due to collision with local "
1016  "or static remote mapping!", format_gid_address,
1017  eid);
1018  return 0;
1019  }
1020 
1021  locator_set_t *old_ls;
1022 
1023  /* update mapping attributes */
1024  old_map->action = action;
1025  old_map->authoritative = authoritative;
1026  old_map->ttl = ttl;
1027 
1028  old_ls = pool_elt_at_index (lcm->locator_set_pool,
1029  old_map->locator_set_index);
1030  if (compare_locators (lcm, old_ls->locator_indices,
1031  ls_args->locators))
1032  {
1033  /* set locator-set index to overwrite */
1034  ls_args->is_add = 1;
1035  ls_args->index = old_map->locator_set_index;
1036  vnet_lisp_add_del_locator_set (ls_args, 0);
1037  if (res_map_index)
1038  res_map_index[0] = mi;
1039  }
1040  }
1041  /* new mapping */
1042  else
1043  {
1044  remove_overlapping_sub_prefixes (lcm, eid, 0 == ls_args->locators);
1045 
1046  ls_args->is_add = 1;
1047  ls_args->index = ~0;
1048 
1049  vnet_lisp_add_del_locator_set (ls_args, &ls_index);
1050 
1051  /* add mapping */
1052  gid_address_copy (&m_args->eid, eid);
1053  m_args->is_add = 1;
1054  m_args->action = action;
1055  m_args->locator_set_index = ls_index;
1056  m_args->is_static = is_static;
1057  vnet_lisp_map_cache_add_del (m_args, &dst_map_index);
1058 
1059  if (res_map_index)
1060  res_map_index[0] = dst_map_index;
1061  }
1062  }
1063  else
1064  {
1065  if (old_map == 0 || gid_address_cmp (&old_map->eid, eid) != 0)
1066  {
1067  clib_warning ("cannot delete mapping for eid %U",
1068  format_gid_address, eid);
1069  return -1;
1070  }
1071 
1072  m_args->is_add = 0;
1073  gid_address_copy (&m_args->eid, eid);
1074  m_args->locator_set_index = old_map->locator_set_index;
1075 
1076  /* delete mapping associated from map-cache */
1077  vnet_lisp_map_cache_add_del (m_args, 0);
1078 
1079  ls_args->is_add = 0;
1080  ls_args->index = old_map->locator_set_index;
1081  /* delete locator set */
1082  vnet_lisp_add_del_locator_set (ls_args, 0);
1083 
1084  /* return old mapping index */
1085  if (res_map_index)
1086  res_map_index[0] = mi;
1087  }
1088 
1089  /* success */
1090  return 0;
1091 }
1092 
1093 int
1095 {
1096  int rv = 0;
1097  u32 mi, *map_indices = 0, *map_indexp;
1099  vnet_lisp_add_del_mapping_args_t _dm_args, *dm_args = &_dm_args;
1100  vnet_lisp_add_del_locator_set_args_t _ls, *ls = &_ls;
1101 
1102  /* *INDENT-OFF* */
1103  pool_foreach_index (mi, lcm->mapping_pool,
1104  ({
1105  vec_add1 (map_indices, mi);
1106  }));
1107  /* *INDENT-ON* */
1108 
1109  vec_foreach (map_indexp, map_indices)
1110  {
1111  mapping_t *map = pool_elt_at_index (lcm->mapping_pool, map_indexp[0]);
1112  if (!map->local)
1113  {
1114  dp_del_fwd_entry (lcm, 0, map_indexp[0]);
1115 
1116  dm_args->is_add = 0;
1117  gid_address_copy (&dm_args->eid, &map->eid);
1118  dm_args->locator_set_index = map->locator_set_index;
1119 
1120  /* delete mapping associated to fwd entry */
1121  vnet_lisp_map_cache_add_del (dm_args, 0);
1122 
1123  ls->is_add = 0;
1124  ls->local = 0;
1125  ls->index = map->locator_set_index;
1126  /* delete locator set */
1127  rv = vnet_lisp_add_del_locator_set (ls, 0);
1128  if (rv != 0)
1129  goto cleanup;
1130  }
1131  }
1132 
1133 cleanup:
1134  if (map_indices)
1135  vec_free (map_indices);
1136  return rv;
1137 }
1138 
1139 /**
1140  * Adds adjacency or removes forwarding entry associated to remote mapping.
1141  * Note that adjacencies are not stored, they only result in forwarding entries
1142  * being created.
1143  */
1144 int
1146  gid_address_t * remote_eid, u8 is_add)
1147 {
1148  u32 local_mi, remote_mi = ~0;
1149 
1150  if (vnet_lisp_enable_disable_status () == 0)
1151  {
1152  clib_warning ("LISP is disabled!");
1153  return VNET_API_ERROR_LISP_DISABLED;
1154  }
1155 
1157  remote_eid, local_eid);
1158  if (GID_LOOKUP_MISS == remote_mi)
1159  {
1160  clib_warning ("Remote eid %U not found. Cannot add adjacency!",
1161  format_gid_address, remote_eid);
1162 
1163  return -1;
1164  }
1165 
1166  if (is_add)
1167  {
1168  /* TODO 1) check if src/dst 2) once we have src/dst working, use it in
1169  * delete*/
1170 
1171  /* check if source eid has an associated mapping. If pitr mode is on,
1172  * just use the pitr's mapping */
1173  local_mi = lcm->lisp_pitr ? lcm->pitr_map_index :
1174  gid_dictionary_lookup (&lcm->mapping_index_by_gid, local_eid);
1175 
1176 
1177  if (GID_LOOKUP_MISS == local_mi)
1178  {
1179  clib_warning ("Local eid %U not found. Cannot add adjacency!",
1180  format_gid_address, local_eid);
1181 
1182  return -1;
1183  }
1184 
1185  /* update forwarding */
1186  dp_add_fwd_entry (lcm, local_mi, remote_mi);
1187  }
1188  else
1189  dp_del_fwd_entry (lcm, 0, remote_mi);
1190 
1191  return 0;
1192 }
1193 
1194 int
1196 {
1198  return lisp_add_del_adjacency (lcm, &a->leid, &a->reid, a->is_add);
1199 }
1200 
1201 /**
1202  * Handler for add/del remote mapping CLI.
1203  *
1204  * @param vm vlib context
1205  * @param input input from user
1206  * @param cmd cmd
1207  * @return pointer to clib error structure
1208  */
1209 static clib_error_t *
1211  unformat_input_t * input,
1212  vlib_cli_command_t * cmd)
1213 {
1214  clib_error_t *error = 0;
1215  unformat_input_t _line_input, *line_input = &_line_input;
1216  u8 is_add = 1, del_all = 0;
1217  locator_t rloc, *rlocs = 0, *curr_rloc = 0;
1218  gid_address_t eid;
1219  u8 eid_set = 0;
1220  u32 vni, action = ~0, p, w;
1221  int rv;
1222 
1223  /* Get a line of input. */
1224  if (!unformat_user (input, unformat_line_input, line_input))
1225  return 0;
1226 
1227  memset (&eid, 0, sizeof (eid));
1228  memset (&rloc, 0, sizeof (rloc));
1229 
1230  while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
1231  {
1232  if (unformat (line_input, "del-all"))
1233  del_all = 1;
1234  else if (unformat (line_input, "del"))
1235  is_add = 0;
1236  else if (unformat (line_input, "add"))
1237  ;
1238  else if (unformat (line_input, "eid %U", unformat_gid_address, &eid))
1239  eid_set = 1;
1240  else if (unformat (line_input, "vni %u", &vni))
1241  {
1242  gid_address_vni (&eid) = vni;
1243  }
1244  else if (unformat (line_input, "p %d w %d", &p, &w))
1245  {
1246  if (!curr_rloc)
1247  {
1248  clib_warning
1249  ("No RLOC configured for setting priority/weight!");
1250  goto done;
1251  }
1252  curr_rloc->priority = p;
1253  curr_rloc->weight = w;
1254  }
1255  else if (unformat (line_input, "rloc %U", unformat_ip_address,
1256  &gid_address_ip (&rloc.address)))
1257  {
1258  /* since rloc is stored in ip prefix we need to set prefix length */
1259  ip_prefix_t *pref = &gid_address_ippref (&rloc.address);
1260 
1261  u8 version = gid_address_ip_version (&rloc.address);
1262  ip_prefix_len (pref) = ip_address_max_len (version);
1263 
1264  vec_add1 (rlocs, rloc);
1265  curr_rloc = &rlocs[vec_len (rlocs) - 1];
1266  }
1267  else if (unformat (line_input, "action %U",
1269  ;
1270  else
1271  {
1272  clib_warning ("parse error");
1273  goto done;
1274  }
1275  }
1276 
1277  if (!eid_set)
1278  {
1279  clib_warning ("missing eid!");
1280  goto done;
1281  }
1282 
1283  if (!del_all)
1284  {
1285  if (is_add && (~0 == action) && 0 == vec_len (rlocs))
1286  {
1287  clib_warning ("no action set for negative map-reply!");
1288  goto done;
1289  }
1290  }
1291  else
1292  {
1294  goto done;
1295  }
1296 
1297  /* TODO build src/dst with seid */
1298 
1299  /* if it's a delete, clean forwarding */
1300  if (!is_add)
1301  {
1303  rv = lisp_add_del_adjacency (lcm, 0, &eid, /* is_add */ 0);
1304  if (rv)
1305  {
1306  goto done;
1307  }
1308  }
1309 
1310  /* add as static remote mapping, i.e., not authoritative and infinite
1311  * ttl */
1312  rv = vnet_lisp_add_del_mapping (&eid, rlocs, action, 0, ~0, is_add,
1313  1 /* is_static */ , 0);
1314 
1315  if (rv)
1316  clib_warning ("failed to %s remote mapping!", is_add ? "add" : "delete");
1317 
1318 done:
1319  vec_free (rlocs);
1320  unformat_free (line_input);
1321  return error;
1322 }
1323 
1324 VLIB_CLI_COMMAND (lisp_add_del_remote_mapping_command) =
1325 {
1326 .path = "lisp remote-mapping",.short_help =
1327  "lisp remote-mapping add|del [del-all] vni <vni> "
1328  "eid <est-eid> [action <no-action|natively-forward|"
1329  "send-map-request|drop>] rloc <dst-locator> p <prio> w <weight> "
1330  "[rloc <dst-locator> ... ]",.function =
1332 
1333 /**
1334  * Handler for add/del adjacency CLI.
1335  */
1336 static clib_error_t *
1338  vlib_cli_command_t * cmd)
1339 {
1340  clib_error_t *error = 0;
1341  unformat_input_t _line_input, *line_input = &_line_input;
1343  u8 is_add = 1;
1344  ip_prefix_t *reid_ippref, *leid_ippref;
1345  gid_address_t leid, reid;
1346  u8 *dmac = gid_address_mac (&reid);
1347  u8 *smac = gid_address_mac (&leid);
1348  u8 reid_set = 0, leid_set = 0;
1349  u32 vni;
1350  int rv;
1351 
1352  /* Get a line of input. */
1353  if (!unformat_user (input, unformat_line_input, line_input))
1354  return 0;
1355 
1356  memset (&reid, 0, sizeof (reid));
1357  memset (&leid, 0, sizeof (leid));
1358 
1359  leid_ippref = &gid_address_ippref (&leid);
1360  reid_ippref = &gid_address_ippref (&reid);
1361 
1362  while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
1363  {
1364  if (unformat (line_input, "del"))
1365  is_add = 0;
1366  else if (unformat (line_input, "add"))
1367  ;
1368  else if (unformat (line_input, "reid %U",
1369  unformat_ip_prefix, reid_ippref))
1370  {
1372  reid_set = 1;
1373  }
1374  else if (unformat (line_input, "reid %U", unformat_mac_address, dmac))
1375  {
1376  gid_address_type (&reid) = GID_ADDR_MAC;
1377  reid_set = 1;
1378  }
1379  else if (unformat (line_input, "vni %u", &vni))
1380  {
1381  gid_address_vni (&leid) = vni;
1382  gid_address_vni (&reid) = vni;
1383  }
1384  else if (unformat (line_input, "leid %U",
1385  unformat_ip_prefix, leid_ippref))
1386  {
1388  leid_set = 1;
1389  }
1390  else if (unformat (line_input, "leid %U", unformat_mac_address, smac))
1391  {
1392  gid_address_type (&leid) = GID_ADDR_MAC;
1393  leid_set = 1;
1394  }
1395  else
1396  {
1397  clib_warning ("parse error");
1398  goto done;
1399  }
1400  }
1401 
1402  if (!reid_set || !leid_set)
1403  {
1404  clib_warning ("missing remote or local eid!");
1405  goto done;
1406  }
1407 
1408  if ((gid_address_type (&leid) != gid_address_type (&reid))
1409  || (gid_address_type (&reid) == GID_ADDR_IP_PREFIX
1410  && ip_prefix_version (reid_ippref)
1411  != ip_prefix_version (leid_ippref)))
1412  {
1413  clib_warning ("remote and local EIDs are of different types!");
1414  return error;
1415  }
1416 
1417  memset (a, 0, sizeof (a[0]));
1418  gid_address_copy (&a->leid, &leid);
1419  gid_address_copy (&a->reid, &reid);
1420 
1421  a->is_add = is_add;
1422  rv = vnet_lisp_add_del_adjacency (a);
1423 
1424  if (rv)
1425  clib_warning ("failed to %s adjacency!", is_add ? "add" : "delete");
1426 
1427 done:
1428  unformat_free (line_input);
1429  return error;
1430 }
1431 
1432 /* *INDENT-OFF* */
1433 VLIB_CLI_COMMAND (lisp_add_del_adjacency_command) = {
1434  .path = "lisp adjacency",
1435  .short_help = "lisp adjacency add|del vni <vni> reid <remote-eid> "
1436  "leid <local-eid>",
1438 };
1439 /* *INDENT-ON* */
1440 
1441 int
1443 {
1445 
1446  if (vnet_lisp_enable_disable_status () == 0)
1447  {
1448  clib_warning ("LISP is disabled!");
1449  return VNET_API_ERROR_LISP_DISABLED;
1450  }
1451 
1452  if (mode >= _MR_MODE_MAX)
1453  {
1454  clib_warning ("Invalid LISP map request mode %d!", mode);
1455  return VNET_API_ERROR_INVALID_ARGUMENT;
1456  }
1457 
1458  lcm->map_request_mode = mode;
1459  return 0;
1460 }
1461 
1462 static clib_error_t *
1464  unformat_input_t * input,
1465  vlib_cli_command_t * cmd)
1466 {
1467  unformat_input_t _i, *i = &_i;
1468  map_request_mode_t mr_mode = _MR_MODE_MAX;
1469 
1470  /* Get a line of input. */
1471  if (!unformat_user (input, unformat_line_input, i))
1472  return 0;
1473 
1475  {
1476  if (unformat (i, "dst-only"))
1477  mr_mode = MR_MODE_DST_ONLY;
1478  else if (unformat (i, "src-dst"))
1479  mr_mode = MR_MODE_SRC_DST;
1480  else
1481  {
1482  clib_warning ("parse error '%U'", format_unformat_error, i);
1483  goto done;
1484  }
1485  }
1486 
1487  if (_MR_MODE_MAX == mr_mode)
1488  {
1489  clib_warning ("No LISP map request mode entered!");
1490  return 0;
1491  }
1492 
1494 done:
1495  return 0;
1496 }
1497 
1498 /* *INDENT-OFF* */
1499 VLIB_CLI_COMMAND (lisp_map_request_mode_command) = {
1500  .path = "lisp map-request mode",
1501  .short_help = "lisp map-request mode dst-only|src-dst",
1503 };
1504 /* *INDENT-ON* */
1505 
1506 static u8 *
1507 format_lisp_map_request_mode (u8 * s, va_list * args)
1508 {
1509  u32 mode = va_arg (*args, u32);
1510 
1511  switch (mode)
1512  {
1513  case 0:
1514  return format (0, "dst-only");
1515  case 1:
1516  return format (0, "src-dst");
1517  }
1518  return 0;
1519 }
1520 
1521 static clib_error_t *
1523  unformat_input_t * input,
1524  vlib_cli_command_t * cmd)
1525 {
1526  vlib_cli_output (vm, "map-request mode: %U", format_lisp_map_request_mode,
1528  return 0;
1529 }
1530 
1531 /* *INDENT-OFF* */
1532 VLIB_CLI_COMMAND (lisp_show_map_request_mode_command) = {
1533  .path = "show lisp map-request mode",
1534  .short_help = "show lisp map-request mode",
1536 };
1537 /* *INDENT-ON* */
1538 
1539 static clib_error_t *
1541  unformat_input_t * input,
1542  vlib_cli_command_t * cmd)
1543 {
1544  map_resolver_t *mr;
1546 
1547  vec_foreach (mr, lcm->map_resolvers)
1548  {
1549  vlib_cli_output (vm, "%U", format_ip_address, &mr->address);
1550  }
1551  return 0;
1552 }
1553 
1554 /* *INDENT-OFF* */
1555 VLIB_CLI_COMMAND (lisp_show_map_resolvers_command) = {
1556  .path = "show lisp map-resolvers",
1557  .short_help = "show lisp map-resolvers",
1559 };
1560 /* *INDENT-ON* */
1561 
1562 int
1563 vnet_lisp_pitr_set_locator_set (u8 * locator_set_name, u8 is_add)
1564 {
1566  u32 locator_set_index = ~0;
1567  mapping_t *m;
1568  uword *p;
1569 
1570  if (vnet_lisp_enable_disable_status () == 0)
1571  {
1572  clib_warning ("LISP is disabled!");
1573  return VNET_API_ERROR_LISP_DISABLED;
1574  }
1575 
1576  p = hash_get_mem (lcm->locator_set_index_by_name, locator_set_name);
1577  if (!p)
1578  {
1579  clib_warning ("locator-set %v doesn't exist", locator_set_name);
1580  return -1;
1581  }
1582  locator_set_index = p[0];
1583 
1584  if (is_add)
1585  {
1586  pool_get (lcm->mapping_pool, m);
1587  m->locator_set_index = locator_set_index;
1588  m->local = 1;
1589  lcm->pitr_map_index = m - lcm->mapping_pool;
1590 
1591  /* enable pitr mode */
1592  lcm->lisp_pitr = 1;
1593  }
1594  else
1595  {
1596  /* remove pitr mapping */
1598 
1599  /* disable pitr mode */
1600  lcm->lisp_pitr = 0;
1601  }
1602  return 0;
1603 }
1604 
1605 static clib_error_t *
1607  unformat_input_t * input,
1608  vlib_cli_command_t * cmd)
1609 {
1610  u8 locator_name_set = 0;
1611  u8 *locator_set_name = 0;
1612  u8 is_add = 1;
1613  unformat_input_t _line_input, *line_input = &_line_input;
1614  clib_error_t *error = 0;
1615  int rv = 0;
1616 
1617  /* Get a line of input. */
1618  if (!unformat_user (input, unformat_line_input, line_input))
1619  return 0;
1620 
1621  while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
1622  {
1623  if (unformat (line_input, "ls %_%v%_", &locator_set_name))
1624  locator_name_set = 1;
1625  else if (unformat (line_input, "disable"))
1626  is_add = 0;
1627  else
1628  return clib_error_return (0, "parse error");
1629  }
1630 
1631  if (!locator_name_set)
1632  {
1633  clib_warning ("No locator set specified!");
1634  goto done;
1635  }
1636  rv = vnet_lisp_pitr_set_locator_set (locator_set_name, is_add);
1637  if (0 != rv)
1638  {
1639  error = clib_error_return (0, "failed to %s pitr!",
1640  is_add ? "add" : "delete");
1641  }
1642 
1643 done:
1644  if (locator_set_name)
1645  vec_free (locator_set_name);
1646  return error;
1647 }
1648 
1649 /* *INDENT-OFF* */
1650 VLIB_CLI_COMMAND (lisp_pitr_set_locator_set_command) = {
1651  .path = "lisp pitr",
1652  .short_help = "lisp pitr [disable] ls <locator-set-name>",
1654 };
1655 /* *INDENT-ON* */
1656 
1657 static clib_error_t *
1659  unformat_input_t * input, vlib_cli_command_t * cmd)
1660 {
1662  mapping_t *m;
1663  locator_set_t *ls;
1664  u8 *tmp_str = 0;
1665 
1666  vlib_cli_output (vm, "%=20s%=16s",
1667  "pitr", lcm->lisp_pitr ? "locator-set" : "");
1668 
1669  if (!lcm->lisp_pitr)
1670  {
1671  vlib_cli_output (vm, "%=20s", "disable");
1672  return 0;
1673  }
1674 
1675  if (~0 == lcm->pitr_map_index)
1676  {
1677  tmp_str = format (0, "N/A");
1678  }
1679  else
1680  {
1682  if (~0 != m->locator_set_index)
1683  {
1684  ls =
1686  tmp_str = format (0, "%s", ls->name);
1687  }
1688  else
1689  {
1690  tmp_str = format (0, "N/A");
1691  }
1692  }
1693  vec_add1 (tmp_str, 0);
1694 
1695  vlib_cli_output (vm, "%=20s%=16s", "enable", tmp_str);
1696 
1697  vec_free (tmp_str);
1698 
1699  return 0;
1700 }
1701 
1702 /* *INDENT-OFF* */
1703 VLIB_CLI_COMMAND (lisp_show_pitr_command) = {
1704  .path = "show lisp pitr",
1705  .short_help = "Show pitr",
1706  .function = lisp_show_pitr_command_fn,
1707 };
1708 /* *INDENT-ON* */
1709 
1710 static u8 *
1711 format_eid_entry (u8 * s, va_list * args)
1712 {
1713  vnet_main_t *vnm = va_arg (*args, vnet_main_t *);
1714  lisp_cp_main_t *lcm = va_arg (*args, lisp_cp_main_t *);
1715  mapping_t *mapit = va_arg (*args, mapping_t *);
1716  locator_set_t *ls = va_arg (*args, locator_set_t *);
1717  gid_address_t *gid = &mapit->eid;
1718  u32 ttl = mapit->ttl;
1719  u8 aut = mapit->authoritative;
1720  u32 *loc_index;
1721  u8 first_line = 1;
1722  u8 *loc;
1723 
1724  u8 *type = ls->local ? format (0, "local(%s)", ls->name)
1725  : format (0, "remote");
1726 
1727  if (vec_len (ls->locator_indices) == 0)
1728  {
1729  s = format (s, "%-35U%-30s%-20u%-u", format_gid_address, gid,
1730  type, ttl, aut);
1731  }
1732  else
1733  {
1734  vec_foreach (loc_index, ls->locator_indices)
1735  {
1736  locator_t *l = pool_elt_at_index (lcm->locator_pool, loc_index[0]);
1737  if (l->local)
1738  loc = format (0, "%U", format_vnet_sw_if_index_name, vnm,
1739  l->sw_if_index);
1740  else
1741  loc = format (0, "%U", format_ip_address,
1742  &gid_address_ip (&l->address));
1743 
1744  if (first_line)
1745  {
1746  s = format (s, "%-35U%-20s%-30v%-20u%-u\n", format_gid_address,
1747  gid, type, loc, ttl, aut);
1748  first_line = 0;
1749  }
1750  else
1751  s = format (s, "%55s%v\n", "", loc);
1752  }
1753  }
1754  return s;
1755 }
1756 
1757 static clib_error_t *
1759  unformat_input_t * input,
1760  vlib_cli_command_t * cmd)
1761 {
1763  mapping_t *mapit;
1764  unformat_input_t _line_input, *line_input = &_line_input;
1765  u32 mi;
1766  gid_address_t eid;
1767  u8 print_all = 1;
1768  u8 filter = 0;
1769 
1770  memset (&eid, 0, sizeof (eid));
1771 
1772  /* Get a line of input. */
1773  if (!unformat_user (input, unformat_line_input, line_input))
1774  return 0;
1775 
1776  while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
1777  {
1778  if (unformat (line_input, "eid %U", unformat_gid_address, &eid))
1779  print_all = 0;
1780  else if (unformat (line_input, "local"))
1781  filter = 1;
1782  else if (unformat (line_input, "remote"))
1783  filter = 2;
1784  else
1785  return clib_error_return (0, "parse error: '%U'",
1786  format_unformat_error, line_input);
1787  }
1788 
1789  vlib_cli_output (vm, "%-35s%-20s%-30s%-20s%-s",
1790  "EID", "type", "locators", "ttl", "autoritative");
1791 
1792  if (print_all)
1793  {
1794  /* *INDENT-OFF* */
1795  pool_foreach (mapit, lcm->mapping_pool,
1796  ({
1797  locator_set_t * ls = pool_elt_at_index (lcm->locator_set_pool,
1798  mapit->locator_set_index);
1799  if (filter && !((1 == filter && ls->local) ||
1800  (2 == filter && !ls->local)))
1801  {
1802  continue;
1803  }
1804  vlib_cli_output (vm, "%U", format_eid_entry, lcm->vnet_main,
1805  lcm, mapit, ls);
1806  }));
1807  /* *INDENT-ON* */
1808  }
1809  else
1810  {
1811  mi = gid_dictionary_lookup (&lcm->mapping_index_by_gid, &eid);
1812  if ((u32) ~ 0 == mi)
1813  return 0;
1814 
1815  mapit = pool_elt_at_index (lcm->mapping_pool, mi);
1816  locator_set_t *ls = pool_elt_at_index (lcm->locator_set_pool,
1817  mapit->locator_set_index);
1818 
1819  if (filter && !((1 == filter && ls->local) ||
1820  (2 == filter && !ls->local)))
1821  {
1822  return 0;
1823  }
1824 
1825  vlib_cli_output (vm, "%U,", format_eid_entry, lcm->vnet_main,
1826  lcm, mapit, ls);
1827  }
1828 
1829  return 0;
1830 }
1831 
1832 /* *INDENT-OFF* */
1833 VLIB_CLI_COMMAND (lisp_cp_show_eid_table_command) = {
1834  .path = "show lisp eid-table",
1835  .short_help = "Shows EID table",
1836  .function = lisp_show_eid_table_command_fn,
1837 };
1838 /* *INDENT-ON* */
1839 
1840 /* cleans locator to locator-set data and removes locators not part of
1841  * any locator-set */
1842 static void
1844 {
1845  u32 i, j, *loc_indexp, *ls_indexp, **ls_indexes, *to_be_deleted = 0;
1847  for (i = 0; i < vec_len (ls->locator_indices); i++)
1848  {
1849  loc_indexp = vec_elt_at_index (ls->locator_indices, i);
1850  ls_indexes = vec_elt_at_index (lcm->locator_to_locator_sets,
1851  loc_indexp[0]);
1852  for (j = 0; j < vec_len (ls_indexes[0]); j++)
1853  {
1854  ls_indexp = vec_elt_at_index (ls_indexes[0], j);
1855  if (ls_indexp[0] == lsi)
1856  break;
1857  }
1858 
1859  /* delete index for removed locator-set */
1860  vec_del1 (ls_indexes[0], j);
1861 
1862  /* delete locator if it's part of no locator-set */
1863  if (vec_len (ls_indexes[0]) == 0)
1864  {
1865  pool_put_index (lcm->locator_pool, loc_indexp[0]);
1866  vec_add1 (to_be_deleted, i);
1867  }
1868  }
1869 
1870  if (to_be_deleted)
1871  {
1872  for (i = 0; i < vec_len (to_be_deleted); i++)
1873  {
1874  loc_indexp = vec_elt_at_index (to_be_deleted, i);
1875  vec_del1 (ls->locator_indices, loc_indexp[0]);
1876  }
1877  vec_free (to_be_deleted);
1878  }
1879 }
1880 
1881 static inline uword *
1883 {
1885 
1886  ASSERT (a != NULL);
1887  ASSERT (p != NULL);
1888 
1889  /* find locator-set */
1890  if (a->local)
1891  {
1893  }
1894  else
1895  {
1896  *p = a->index;
1897  }
1898 
1899  return p;
1900 }
1901 
1902 static inline int
1904  locator_t * loc)
1905 {
1906  locator_t *itloc;
1907  u32 *locit;
1908 
1909  ASSERT (ls != NULL);
1910  ASSERT (loc != NULL);
1911 
1912  vec_foreach (locit, ls->locator_indices)
1913  {
1914  itloc = pool_elt_at_index (lcm->locator_pool, locit[0]);
1915  if ((ls->local && itloc->sw_if_index == loc->sw_if_index) ||
1916  (!ls->local && !gid_address_cmp (&itloc->address, &loc->address)))
1917  {
1918  clib_warning ("Duplicate locator");
1919  return VNET_API_ERROR_VALUE_EXIST;
1920  }
1921  }
1922 
1923  return 0;
1924 }
1925 
1926 static inline void
1928  u32 ls_index, u32 loc_id)
1929 {
1931  u32 **ls_indexes = NULL;
1932 
1933  ASSERT (ls != NULL);
1934  ASSERT (locit != NULL);
1935 
1936  ls_indexes = vec_elt_at_index (lcm->locator_to_locator_sets, locit[0]);
1937  pool_put_index (lcm->locator_pool, locit[0]);
1938  vec_del1 (ls->locator_indices, loc_id);
1939  vec_del1 (ls_indexes[0], ls_index);
1940 }
1941 
1942 int
1944  locator_set_t * ls, u32 * ls_result)
1945 {
1947  locator_t *loc = NULL, *itloc = NULL;
1948  uword _p = (u32) ~ 0, *p = &_p;
1949  u32 loc_index = ~0, ls_index = ~0, *locit = NULL, **ls_indexes = NULL;
1950  u32 loc_id = ~0;
1951  int ret = 0;
1952 
1953  ASSERT (a != NULL);
1954 
1955  if (vnet_lisp_enable_disable_status () == 0)
1956  {
1957  clib_warning ("LISP is disabled!");
1958  return VNET_API_ERROR_LISP_DISABLED;
1959  }
1960 
1961  p = get_locator_set_index (a, p);
1962  if (!p)
1963  {
1964  clib_warning ("locator-set %v doesn't exist", a->name);
1965  return VNET_API_ERROR_INVALID_ARGUMENT;
1966  }
1967 
1968  if (ls == 0)
1969  {
1970  ls = pool_elt_at_index (lcm->locator_set_pool, p[0]);
1971  if (!ls)
1972  {
1973  clib_warning ("locator-set %d to be overwritten doesn't exist!",
1974  p[0]);
1975  return VNET_API_ERROR_INVALID_ARGUMENT;
1976  }
1977  }
1978 
1979  if (a->is_add)
1980  {
1981  if (ls_result)
1982  ls_result[0] = p[0];
1983 
1984  /* allocate locators */
1985  vec_foreach (itloc, a->locators)
1986  {
1987  ret = is_locator_in_locator_set (lcm, ls, itloc);
1988  if (0 != ret)
1989  {
1990  return ret;
1991  }
1992 
1993  pool_get (lcm->locator_pool, loc);
1994  loc[0] = itloc[0];
1995  loc_index = loc - lcm->locator_pool;
1996 
1997  vec_add1 (ls->locator_indices, loc_index);
1998 
1999  vec_validate (lcm->locator_to_locator_sets, loc_index);
2000  ls_indexes = vec_elt_at_index (lcm->locator_to_locator_sets,
2001  loc_index);
2002  vec_add1 (ls_indexes[0], p[0]);
2003  }
2004  }
2005  else
2006  {
2007  ls_index = p[0];
2008 
2009  itloc = a->locators;
2010  loc_id = 0;
2011  vec_foreach (locit, ls->locator_indices)
2012  {
2013  loc = pool_elt_at_index (lcm->locator_pool, locit[0]);
2014 
2015  if (loc->local && loc->sw_if_index == itloc->sw_if_index)
2016  {
2017  remove_locator_from_locator_set (ls, locit, ls_index, loc_id);
2018  }
2019  if (0 == loc->local &&
2020  !gid_address_cmp (&loc->address, &itloc->address))
2021  {
2022  remove_locator_from_locator_set (ls, locit, ls_index, loc_id);
2023  }
2024 
2025  loc_id++;
2026  }
2027  }
2028 
2029  return 0;
2030 }
2031 
2032 int
2034  u32 * ls_result)
2035 {
2037  locator_set_t *ls;
2038  uword _p = (u32) ~ 0, *p = &_p;
2039  u32 ls_index;
2040  u32 **eid_indexes;
2041  int ret = 0;
2042 
2043  if (vnet_lisp_enable_disable_status () == 0)
2044  {
2045  clib_warning ("LISP is disabled!");
2046  return VNET_API_ERROR_LISP_DISABLED;
2047  }
2048 
2049  if (a->is_add)
2050  {
2051  p = get_locator_set_index (a, p);
2052 
2053  /* overwrite */
2054  if (p && p[0] != (u32) ~ 0)
2055  {
2056  ls = pool_elt_at_index (lcm->locator_set_pool, p[0]);
2057  if (!ls)
2058  {
2059  clib_warning ("locator-set %d to be overwritten doesn't exist!",
2060  p[0]);
2061  return -1;
2062  }
2063 
2064  /* clean locator to locator-set vectors and remove locators if
2065  * they're not part of another locator-set */
2066  clean_locator_to_locator_set (lcm, p[0]);
2067 
2068  /* remove locator indices from locator set */
2069  vec_free (ls->locator_indices);
2070 
2071  ls_index = p[0];
2072 
2073  if (ls_result)
2074  ls_result[0] = p[0];
2075  }
2076  /* new locator-set */
2077  else
2078  {
2079  pool_get (lcm->locator_set_pool, ls);
2080  memset (ls, 0, sizeof (*ls));
2081  ls_index = ls - lcm->locator_set_pool;
2082 
2083  if (a->local)
2084  {
2085  ls->name = vec_dup (a->name);
2086 
2087  if (!lcm->locator_set_index_by_name)
2089  /* size */
2090  0,
2091  sizeof
2092  (ls->name
2093  [0]),
2094  sizeof
2095  (uword));
2097  ls_index);
2098 
2099  /* mark as local locator-set */
2100  vec_add1 (lcm->local_locator_set_indexes, ls_index);
2101  }
2102  ls->local = a->local;
2103  if (ls_result)
2104  ls_result[0] = ls_index;
2105  }
2106 
2107  ret = vnet_lisp_add_del_locator (a, ls, NULL);
2108  if (0 != ret)
2109  {
2110  return ret;
2111  }
2112  }
2113  else
2114  {
2115  p = get_locator_set_index (a, p);
2116  if (!p)
2117  {
2118  clib_warning ("locator-set %v doesn't exists", a->name);
2119  return -1;
2120  }
2121 
2122  ls = pool_elt_at_index (lcm->locator_set_pool, p[0]);
2123  if (!ls)
2124  {
2125  clib_warning ("locator-set with index %d doesn't exists", p[0]);
2126  return -1;
2127  }
2128 
2129  if (lcm->mreq_itr_rlocs == p[0])
2130  {
2131  clib_warning ("Can't delete the locator-set used to constrain "
2132  "the itr-rlocs in map-requests!");
2133  return -1;
2134  }
2135 
2136  if (vec_len (lcm->locator_set_to_eids) != 0)
2137  {
2138  eid_indexes = vec_elt_at_index (lcm->locator_set_to_eids, p[0]);
2139  if (vec_len (eid_indexes[0]) != 0)
2140  {
2141  clib_warning
2142  ("Can't delete a locator that supports a mapping!");
2143  return -1;
2144  }
2145  }
2146 
2147  /* clean locator to locator-sets data */
2148  clean_locator_to_locator_set (lcm, p[0]);
2149 
2150  if (ls->local)
2151  {
2152  u32 it, lsi;
2153 
2155  {
2156  lsi = vec_elt (lcm->local_locator_set_indexes, it);
2157  if (lsi == p[0])
2158  {
2160  break;
2161  }
2162  }
2164  }
2165  vec_free (ls->name);
2166  vec_free (ls->locator_indices);
2167  pool_put (lcm->locator_set_pool, ls);
2168  }
2169  return 0;
2170 }
2171 
2172 clib_error_t *
2174 {
2175  u32 vni, dp_table;
2176  clib_error_t *error = 0;
2179 
2180  a->is_en = is_enable;
2181  error = vnet_lisp_gpe_enable_disable (a);
2182  if (error)
2183  {
2184  return clib_error_return (0, "failed to %s data-plane!",
2185  a->is_en ? "enable" : "disable");
2186  }
2187 
2188  if (is_enable)
2189  {
2190  /* enable all l2 and l3 ifaces */
2191 
2192  /* *INDENT-OFF* */
2193  hash_foreach(vni, dp_table, lcm->table_id_by_vni, ({
2194  dp_add_del_iface(lcm, vni, 0, 1);
2195  }));
2196  hash_foreach(vni, dp_table, lcm->bd_id_by_vni, ({
2197  dp_add_del_iface(lcm, vni, /* is_l2 */ 1, 1);
2198  }));
2199  /* *INDENT-ON* */
2200  }
2201  else
2202  {
2203  /* clear interface table */
2205  pool_free (lcm->fwd_entry_pool);
2206  }
2207 
2208  /* update global flag */
2209  lcm->is_enabled = is_enable;
2210 
2211  return 0;
2212 }
2213 
2214 static clib_error_t *
2216  vlib_cli_command_t * cmd)
2217 {
2218  unformat_input_t _line_input, *line_input = &_line_input;
2219  u8 is_enabled = 0;
2220  u8 is_set = 0;
2221 
2222  /* Get a line of input. */
2223  if (!unformat_user (input, unformat_line_input, line_input))
2224  return 0;
2225 
2226  while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
2227  {
2228  if (unformat (line_input, "enable"))
2229  {
2230  is_set = 1;
2231  is_enabled = 1;
2232  }
2233  else if (unformat (line_input, "disable"))
2234  is_set = 1;
2235  else
2236  {
2237  return clib_error_return (0, "parse error: '%U'",
2238  format_unformat_error, line_input);
2239  }
2240  }
2241 
2242  if (!is_set)
2243  return clib_error_return (0, "state not set");
2244 
2245  return vnet_lisp_enable_disable (is_enabled);
2246 }
2247 
2248 /* *INDENT-OFF* */
2249 VLIB_CLI_COMMAND (lisp_cp_enable_disable_command) = {
2250  .path = "lisp",
2251  .short_help = "lisp [enable|disable]",
2252  .function = lisp_enable_disable_command_fn,
2253 };
2254 /* *INDENT-ON* */
2255 
2256 u8
2258 {
2260  return lcm->is_enabled;
2261 }
2262 
2263 static u8 *
2264 format_lisp_status (u8 * s, va_list * args)
2265 {
2267  return format (s, "%s", lcm->is_enabled ? "enabled" : "disabled");
2268 }
2269 
2270 static clib_error_t *
2272  vlib_cli_command_t * cmd)
2273 {
2274  u8 *msg = 0;
2275  msg = format (msg, "feature: %U\ngpe: %U\n",
2277  vlib_cli_output (vm, "%v", msg);
2278  vec_free (msg);
2279  return 0;
2280 }
2281 
2282 /* *INDENT-OFF* */
2283 VLIB_CLI_COMMAND (lisp_show_status_command) = {
2284  .path = "show lisp status",
2285  .short_help = "show lisp status",
2286  .function = lisp_show_status_command_fn,
2287 };
2288 /* *INDENT-ON* */
2289 
2290 static clib_error_t *
2292  unformat_input_t * input,
2293  vlib_cli_command_t * cmd)
2294 {
2295  hash_pair_t *p;
2296  unformat_input_t _line_input, *line_input = &_line_input;
2298  uword *vni_table = 0;
2299  u8 is_l2 = 0;
2300 
2301  /* Get a line of input. */
2302  if (!unformat_user (input, unformat_line_input, line_input))
2303  return 0;
2304 
2305  while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
2306  {
2307  if (unformat (line_input, "l2"))
2308  {
2309  vni_table = lcm->bd_id_by_vni;
2310  is_l2 = 1;
2311  }
2312  else if (unformat (line_input, "l3"))
2313  {
2314  vni_table = lcm->table_id_by_vni;
2315  is_l2 = 0;
2316  }
2317  else
2318  return clib_error_return (0, "parse error: '%U'",
2319  format_unformat_error, line_input);
2320  }
2321 
2322  if (!vni_table)
2323  {
2324  vlib_cli_output (vm, "Error: expected l2|l3 param!\n");
2325  return 0;
2326  }
2327 
2328  vlib_cli_output (vm, "%=10s%=10s", "VNI", is_l2 ? "BD" : "VRF");
2329 
2330  /* *INDENT-OFF* */
2331  hash_foreach_pair (p, vni_table,
2332  ({
2333  vlib_cli_output (vm, "%=10d%=10d", p->key, p->value[0]);
2334  }));
2335  /* *INDENT-ON* */
2336 
2337  return 0;
2338 }
2339 
2340 /* *INDENT-OFF* */
2341 VLIB_CLI_COMMAND (lisp_show_eid_table_map_command) = {
2342  .path = "show lisp eid-table map",
2343  .short_help = "show lisp eid-table l2|l3",
2345 };
2346 /* *INDENT-ON* */
2347 
2348 static clib_error_t *
2350  unformat_input_t * input,
2351  vlib_cli_command_t * cmd)
2352 {
2354  vnet_main_t *vnm = lgm->vnet_main;
2355  unformat_input_t _line_input, *line_input = &_line_input;
2356  u8 is_add = 1;
2357  clib_error_t *error = 0;
2358  u8 *locator_set_name = 0;
2359  locator_t locator, *locators = 0;
2361  u32 ls_index = 0;
2362  int rv = 0;
2363 
2364  memset (&locator, 0, sizeof (locator));
2365  memset (a, 0, sizeof (a[0]));
2366 
2367  /* Get a line of input. */
2368  if (!unformat_user (input, unformat_line_input, line_input))
2369  return 0;
2370 
2371  while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
2372  {
2373  if (unformat (line_input, "add %_%v%_", &locator_set_name))
2374  is_add = 1;
2375  else if (unformat (line_input, "del %_%v%_", &locator_set_name))
2376  is_add = 0;
2377  else if (unformat (line_input, "iface %U p %d w %d",
2379  &locator.sw_if_index, &locator.priority,
2380  &locator.weight))
2381  {
2382  locator.local = 1;
2383  vec_add1 (locators, locator);
2384  }
2385  else
2386  {
2387  error = unformat_parse_error (line_input);
2388  goto done;
2389  }
2390  }
2391 
2392  a->name = locator_set_name;
2393  a->locators = locators;
2394  a->is_add = is_add;
2395  a->local = 1;
2396 
2397  rv = vnet_lisp_add_del_locator_set (a, &ls_index);
2398  if (0 != rv)
2399  {
2400  error = clib_error_return (0, "failed to %s locator-set!",
2401  is_add ? "add" : "delete");
2402  }
2403 
2404 done:
2405  vec_free (locators);
2406  if (locator_set_name)
2407  vec_free (locator_set_name);
2408  return error;
2409 }
2410 
2411 /* *INDENT-OFF* */
2412 VLIB_CLI_COMMAND (lisp_cp_add_del_locator_set_command) = {
2413  .path = "lisp locator-set",
2414  .short_help = "lisp locator-set add/del <name> [iface <iface-name> "
2415  "p <priority> w <weight>]",
2417 };
2418 /* *INDENT-ON* */
2419 
2420 static clib_error_t *
2422  unformat_input_t * input,
2423  vlib_cli_command_t * cmd)
2424 {
2426  vnet_main_t *vnm = lgm->vnet_main;
2427  unformat_input_t _line_input, *line_input = &_line_input;
2428  u8 is_add = 1;
2429  clib_error_t *error = 0;
2430  u8 *locator_set_name = 0;
2431  u8 locator_set_name_set = 0;
2432  locator_t locator, *locators = 0;
2434  u32 ls_index = 0;
2435 
2436  memset (&locator, 0, sizeof (locator));
2437  memset (a, 0, sizeof (a[0]));
2438 
2439  /* Get a line of input. */
2440  if (!unformat_user (input, unformat_line_input, line_input))
2441  return 0;
2442 
2443  while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
2444  {
2445  if (unformat (line_input, "add"))
2446  is_add = 1;
2447  else if (unformat (line_input, "del"))
2448  is_add = 0;
2449  else if (unformat (line_input, "locator-set %_%v%_", &locator_set_name))
2450  locator_set_name_set = 1;
2451  else if (unformat (line_input, "iface %U p %d w %d",
2453  &locator.sw_if_index, &locator.priority,
2454  &locator.weight))
2455  {
2456  locator.local = 1;
2457  vec_add1 (locators, locator);
2458  }
2459  else
2460  {
2461  error = unformat_parse_error (line_input);
2462  goto done;
2463  }
2464  }
2465 
2466  if (!locator_set_name_set)
2467  {
2468  error = clib_error_return (0, "locator_set name not set!");
2469  goto done;
2470  }
2471 
2472  a->name = locator_set_name;
2473  a->locators = locators;
2474  a->is_add = is_add;
2475  a->local = 1;
2476 
2477  vnet_lisp_add_del_locator (a, 0, &ls_index);
2478 
2479 done:
2480  vec_free (locators);
2481  vec_free (locator_set_name);
2482  return error;
2483 }
2484 
2485 /* *INDENT-OFF* */
2486 VLIB_CLI_COMMAND (lisp_cp_add_del_locator_in_set_command) = {
2487  .path = "lisp locator",
2488  .short_help = "lisp locator add/del locator-set <name> iface <iface-name> "
2489  "p <priority> w <weight>",
2491 };
2492 /* *INDENT-ON* */
2493 
2494 static clib_error_t *
2496  unformat_input_t * input,
2497  vlib_cli_command_t * cmd)
2498 {
2499  locator_set_t *lsit;
2500  locator_t *loc;
2501  u32 *locit;
2503 
2504  vlib_cli_output (vm, "%s%=16s%=16s%=16s", "Locator-set", "Locator",
2505  "Priority", "Weight");
2506 
2507  /* *INDENT-OFF* */
2508  pool_foreach (lsit, lcm->locator_set_pool,
2509  ({
2510  u8 * msg = 0;
2511  int next_line = 0;
2512  if (lsit->local)
2513  {
2514  msg = format (msg, "%v", lsit->name);
2515  }
2516  else
2517  {
2518  msg = format (msg, "<%s-%d>", "remote", lsit - lcm->locator_set_pool);
2519  }
2520  vec_foreach (locit, lsit->locator_indices)
2521  {
2522  if (next_line)
2523  {
2524  msg = format (msg, "%16s", " ");
2525  }
2526  loc = pool_elt_at_index (lcm->locator_pool, locit[0]);
2527  if (loc->local)
2528  msg = format (msg, "%16d%16d%16d\n", loc->sw_if_index, loc->priority,
2529  loc->weight);
2530  else
2531  msg = format (msg, "%16U%16d%16d\n", format_ip_address,
2532  &gid_address_ip(&loc->address), loc->priority,
2533  loc->weight);
2534  next_line = 1;
2535  }
2536  vlib_cli_output (vm, "%v", msg);
2537  vec_free (msg);
2538  }));
2539  /* *INDENT-ON* */
2540  return 0;
2541 }
2542 
2543 /* *INDENT-OFF* */
2544 VLIB_CLI_COMMAND (lisp_cp_show_locator_sets_command) = {
2545  .path = "show lisp locator-set",
2546  .short_help = "Shows locator-sets",
2548 };
2549 /* *INDENT-ON* */
2550 
2551 static map_resolver_t *
2552 get_map_resolver (ip_address_t * a)
2553 {
2555  map_resolver_t *mr;
2556 
2557  vec_foreach (mr, lcm->map_resolvers)
2558  {
2559  if (!ip_address_cmp (&mr->address, a))
2560  {
2561  return mr;
2562  }
2563  }
2564  return 0;
2565 }
2566 
2567 int
2569 {
2571  u32 i;
2572  map_resolver_t _mr, *mr = &_mr;
2573 
2574  if (vnet_lisp_enable_disable_status () == 0)
2575  {
2576  clib_warning ("LISP is disabled!");
2577  return VNET_API_ERROR_LISP_DISABLED;
2578  }
2579 
2580  if (a->is_add)
2581  {
2582 
2583  if (get_map_resolver (&a->address))
2584  {
2585  clib_warning ("map-resolver %U already exists!", format_ip_address,
2586  &a->address);
2587  return -1;
2588  }
2589 
2590  memset (mr, 0, sizeof (*mr));
2591  ip_address_copy (&mr->address, &a->address);
2592  vec_add1 (lcm->map_resolvers, *mr);
2593 
2594  if (vec_len (lcm->map_resolvers) == 1)
2595  lcm->do_map_resolver_election = 1;
2596  }
2597  else
2598  {
2599  for (i = 0; i < vec_len (lcm->map_resolvers); i++)
2600  {
2601  mr = vec_elt_at_index (lcm->map_resolvers, i);
2602  if (!ip_address_cmp (&mr->address, &a->address))
2603  {
2604  if (!ip_address_cmp (&mr->address, &lcm->active_map_resolver))
2605  lcm->do_map_resolver_election = 1;
2606 
2607  vec_del1 (lcm->map_resolvers, i);
2608  break;
2609  }
2610  }
2611  }
2612  return 0;
2613 }
2614 
2615 static clib_error_t *
2617  unformat_input_t * input,
2618  vlib_cli_command_t * cmd)
2619 {
2620  unformat_input_t _line_input, *line_input = &_line_input;
2621  u8 is_add = 1, addr_set = 0;
2622  ip_address_t ip_addr;
2623  clib_error_t *error = 0;
2624  int rv = 0;
2626 
2627  /* Get a line of input. */
2628  if (!unformat_user (input, unformat_line_input, line_input))
2629  return 0;
2630 
2631  while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
2632  {
2633  if (unformat (line_input, "add"))
2634  is_add = 1;
2635  else if (unformat (line_input, "del"))
2636  is_add = 0;
2637  else if (unformat (line_input, "%U", unformat_ip_address, &ip_addr))
2638  addr_set = 1;
2639  else
2640  {
2641  error = unformat_parse_error (line_input);
2642  goto done;
2643  }
2644  }
2645 
2646  if (!addr_set)
2647  {
2648  error = clib_error_return (0, "Map-resolver address must be set!");
2649  goto done;
2650  }
2651 
2652  a->is_add = is_add;
2653  a->address = ip_addr;
2655  if (0 != rv)
2656  {
2657  error = clib_error_return (0, "failed to %s map-resolver!",
2658  is_add ? "add" : "delete");
2659  }
2660 
2661 done:
2662  return error;
2663 }
2664 
2665 /* *INDENT-OFF* */
2666 VLIB_CLI_COMMAND (lisp_add_del_map_resolver_command) = {
2667  .path = "lisp map-resolver",
2668  .short_help = "lisp map-resolver add/del <ip_address>",
2670 };
2671 /* *INDENT-ON* */
2672 
2673 int
2675 {
2677  uword *p = 0;
2678 
2679  if (vnet_lisp_enable_disable_status () == 0)
2680  {
2681  clib_warning ("LISP is disabled!");
2682  return VNET_API_ERROR_LISP_DISABLED;
2683  }
2684 
2685  if (a->is_add)
2686  {
2688  if (!p)
2689  {
2690  clib_warning ("locator-set %v doesn't exist", a->locator_set_name);
2691  return VNET_API_ERROR_INVALID_ARGUMENT;
2692  }
2693 
2694  lcm->mreq_itr_rlocs = p[0];
2695  }
2696  else
2697  {
2698  lcm->mreq_itr_rlocs = ~0;
2699  }
2700 
2701  return 0;
2702 }
2703 
2704 static clib_error_t *
2706  unformat_input_t * input,
2707  vlib_cli_command_t * cmd)
2708 {
2709  unformat_input_t _line_input, *line_input = &_line_input;
2710  u8 is_add = 1;
2711  u8 *locator_set_name = 0;
2712  clib_error_t *error = 0;
2713  int rv = 0;
2715 
2716  /* Get a line of input. */
2717  if (!unformat_user (input, unformat_line_input, line_input))
2718  return 0;
2719 
2720  while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
2721  {
2722  if (unformat (line_input, "del"))
2723  is_add = 0;
2724  else if (unformat (line_input, "add %_%v%_", &locator_set_name))
2725  is_add = 1;
2726  else
2727  {
2728  error = unformat_parse_error (line_input);
2729  goto done;
2730  }
2731  }
2732 
2733  a->is_add = is_add;
2734  a->locator_set_name = locator_set_name;
2736  if (0 != rv)
2737  {
2738  error = clib_error_return (0, "failed to %s map-request itr-rlocs!",
2739  is_add ? "add" : "delete");
2740  }
2741 
2742  vec_free (locator_set_name);
2743 
2744 done:
2745  return error;
2746 
2747 }
2748 
2749 /* *INDENT-OFF* */
2750 VLIB_CLI_COMMAND (lisp_add_del_map_request_command) = {
2751  .path = "lisp map-request itr-rlocs",
2752  .short_help = "lisp map-request itr-rlocs add/del <locator_set_name>",
2754 };
2755 /* *INDENT-ON* */
2756 
2757 static clib_error_t *
2759  unformat_input_t * input,
2760  vlib_cli_command_t * cmd)
2761 {
2763  locator_set_t *loc_set;
2764 
2765  vlib_cli_output (vm, "%=20s", "itr-rlocs");
2766 
2767  if (~0 == lcm->mreq_itr_rlocs)
2768  {
2769  return 0;
2770  }
2771 
2772  loc_set = pool_elt_at_index (lcm->locator_set_pool, lcm->mreq_itr_rlocs);
2773 
2774  vlib_cli_output (vm, "%=20s", loc_set->name);
2775 
2776  return 0;
2777 }
2778 
2779 /* *INDENT-OFF* */
2780 VLIB_CLI_COMMAND (lisp_show_map_request_command) = {
2781  .path = "show lisp map-request itr-rlocs",
2782  .short_help = "Shows map-request itr-rlocs",
2784 };
2785 /* *INDENT-ON* */
2786 
2787 /* Statistics (not really errors) */
2788 #define foreach_lisp_cp_lookup_error \
2789 _(DROP, "drop") \
2790 _(MAP_REQUESTS_SENT, "map-request sent")
2791 
2793 #define _(sym,string) string,
2795 #undef _
2796 };
2797 
2798 typedef enum
2799 {
2800 #define _(sym,str) LISP_CP_LOOKUP_ERROR_##sym,
2802 #undef _
2805 
2806 typedef enum
2807 {
2811 
2812 typedef struct
2813 {
2815  ip_address_t map_resolver_ip;
2817 
2818 u8 *
2819 format_lisp_cp_lookup_trace (u8 * s, va_list * args)
2820 {
2821  CLIB_UNUSED (vlib_main_t * vm) = va_arg (*args, vlib_main_t *);
2822  CLIB_UNUSED (vlib_node_t * node) = va_arg (*args, vlib_node_t *);
2823  lisp_cp_lookup_trace_t *t = va_arg (*args, lisp_cp_lookup_trace_t *);
2824 
2825  s = format (s, "LISP-CP-LOOKUP: map-resolver: %U destination eid %U",
2827  &t->dst_eid);
2828  return s;
2829 }
2830 
2831 int
2832 get_mr_and_local_iface_ip (lisp_cp_main_t * lcm, ip_address_t * mr_ip,
2833  ip_address_t * sloc)
2834 {
2835  map_resolver_t *mrit;
2836  ip_address_t *a;
2837 
2838  if (vec_len (lcm->map_resolvers) == 0)
2839  {
2840  clib_warning ("No map-resolver configured");
2841  return 0;
2842  }
2843 
2844  /* find the first mr ip we have a route to and the ip of the
2845  * iface that has a route to it */
2846  vec_foreach (mrit, lcm->map_resolvers)
2847  {
2848  a = &mrit->address;
2849  if (0 != ip_fib_get_first_egress_ip_for_dst (lcm, a, sloc))
2850  {
2851  ip_address_copy (mr_ip, a);
2852 
2853  /* also update globals */
2854  return 1;
2855  }
2856  }
2857 
2858  clib_warning ("Can't find map-resolver and local interface ip!");
2859  return 0;
2860 }
2861 
2862 static gid_address_t *
2864 {
2865  void *addr;
2866  u32 i;
2867  locator_t *loc;
2868  u32 *loc_indexp;
2869  ip_interface_address_t *ia = 0;
2870  gid_address_t gid_data, *gid = &gid_data;
2871  gid_address_t *rlocs = 0;
2872  ip_prefix_t *ippref = &gid_address_ippref (gid);
2873  ip_address_t *rloc = &ip_prefix_addr (ippref);
2874 
2875  memset (gid, 0, sizeof (gid[0]));
2877  for (i = 0; i < vec_len (loc_set->locator_indices); i++)
2878  {
2879  loc_indexp = vec_elt_at_index (loc_set->locator_indices, i);
2880  loc = pool_elt_at_index (lcm->locator_pool, loc_indexp[0]);
2881 
2882  /* Add ipv4 locators first TODO sort them */
2883 
2884  /* *INDENT-OFF* */
2886  loc->sw_if_index, 1 /* unnumbered */,
2887  ({
2888  addr = ip_interface_address_get_address (&lcm->im4->lookup_main, ia);
2889  ip_address_set (rloc, addr, IP4);
2890  ip_prefix_len (ippref) = 32;
2891  ip_prefix_normalize (ippref);
2892  vec_add1 (rlocs, gid[0]);
2893  }));
2894 
2895  /* Add ipv6 locators */
2897  loc->sw_if_index, 1 /* unnumbered */,
2898  ({
2899  addr = ip_interface_address_get_address (&lcm->im6->lookup_main, ia);
2900  ip_address_set (rloc, addr, IP6);
2901  ip_prefix_len (ippref) = 128;
2902  ip_prefix_normalize (ippref);
2903  vec_add1 (rlocs, gid[0]);
2904  }));
2905  /* *INDENT-ON* */
2906 
2907  }
2908  return rlocs;
2909 }
2910 
2911 static vlib_buffer_t *
2913  gid_address_t * seid, gid_address_t * deid,
2914  locator_set_t * loc_set, ip_address_t * mr_ip,
2915  ip_address_t * sloc, u8 is_smr_invoked,
2916  u64 * nonce_res, u32 * bi_res)
2917 {
2918  vlib_buffer_t *b;
2919  u32 bi;
2920  gid_address_t *rlocs = 0;
2921  vlib_main_t *vm = lcm->vlib_main;
2922 
2923  if (vlib_buffer_alloc (vm, &bi, 1) != 1)
2924  {
2925  clib_warning ("Can't allocate buffer for Map-Request!");
2926  return 0;
2927  }
2928 
2929  b = vlib_get_buffer (vm, bi);
2930 
2931  /* leave some space for the encap headers */
2933 
2934  /* get rlocs */
2935  rlocs = build_itr_rloc_list (lcm, loc_set);
2936 
2937  if (MR_MODE_SRC_DST == lcm->map_request_mode
2938  && GID_ADDR_SRC_DST != gid_address_type (deid))
2939  {
2940  gid_address_t sd;
2941  memset (&sd, 0, sizeof (sd));
2942  build_src_dst (&sd, seid, deid);
2943  lisp_msg_put_mreq (lcm, b, seid, &sd, rlocs, is_smr_invoked, nonce_res);
2944  }
2945  else
2946  {
2947  /* put lisp msg */
2948  lisp_msg_put_mreq (lcm, b, seid, deid, rlocs, is_smr_invoked,
2949  nonce_res);
2950  }
2951 
2952  /* push ecm: udp-ip-lisp */
2954 
2955  /* push outer ip header */
2957  mr_ip);
2958 
2959  bi_res[0] = bi;
2960 
2961  vec_free (rlocs);
2962  return b;
2963 }
2964 
2965 static void
2967 {
2969  r->retries_num = 0;
2970 }
2971 
2972 static int
2974 {
2975  map_resolver_t *mr;
2976 
2977  vec_foreach (mr, lcm->map_resolvers)
2978  {
2979  if (!mr->is_down)
2980  {
2982  lcm->do_map_resolver_election = 0;
2983  return 1;
2984  }
2985  }
2986  return 0;
2987 }
2988 
2989 #define send_encapsulated_map_request(lcm, seid, deid, smr) \
2990  _send_encapsulated_map_request(lcm, seid, deid, smr, 0)
2991 
2992 #define resend_encapsulated_map_request(lcm, seid, deid, smr) \
2993  _send_encapsulated_map_request(lcm, seid, deid, smr, 1)
2994 
2995 static int
2996 _send_encapsulated_map_request (lisp_cp_main_t * lcm,
2997  gid_address_t * seid, gid_address_t * deid,
2998  u8 is_smr_invoked, u8 is_resend)
2999 {
3000  map_resolver_t *mr;
3001  u32 next_index, bi = 0, *to_next, map_index;
3002  vlib_buffer_t *b;
3003  vlib_frame_t *f;
3004  u64 nonce = 0;
3005  locator_set_t *loc_set;
3006  mapping_t *map;
3007  pending_map_request_t *pmr, *duplicate_pmr = 0;
3008  ip_address_t sloc;
3009  u32 ls_index;
3010 
3012 
3013  /* if there is already a pending request remember it */
3014 
3015  /* *INDENT-OFF* */
3017  ({
3018  if (!gid_address_cmp (&pmr->src, seid)
3019  && !gid_address_cmp (&pmr->dst, deid))
3020  {
3021  duplicate_pmr = pmr;
3022  break;
3023  }
3024  }));
3025  /* *INDENT-ON* */
3026 
3027  if (!is_resend && duplicate_pmr)
3028  {
3029  /* don't send the request if there is a pending map request already */
3030  return 0;
3031  }
3032 
3033  /* get locator-set for seid */
3034  if (!lcm->lisp_pitr)
3035  {
3036  map_index = gid_dictionary_lookup (&lcm->mapping_index_by_gid, seid);
3037  if (map_index == ~0)
3038  {
3039  clib_warning ("No local mapping found in eid-table for %U!",
3040  format_gid_address, seid);
3041  return -1;
3042  }
3043 
3044  map = pool_elt_at_index (lcm->mapping_pool, map_index);
3045 
3046  if (!map->local)
3047  {
3048  clib_warning
3049  ("Mapping found for src eid %U is not marked as local!",
3050  format_gid_address, seid);
3051  return -1;
3052  }
3053  ls_index = map->locator_set_index;
3054  }
3055  else
3056  {
3057  map_index = lcm->pitr_map_index;
3058  map = pool_elt_at_index (lcm->mapping_pool, lcm->pitr_map_index);
3059  ls_index = map->locator_set_index;
3060  }
3061 
3062  /* overwrite locator set if map-request itr-rlocs configured */
3063  if (~0 != lcm->mreq_itr_rlocs)
3064  {
3065  ls_index = lcm->mreq_itr_rlocs;
3066  }
3067 
3068  loc_set = pool_elt_at_index (lcm->locator_set_pool, ls_index);
3069 
3070  while (lcm->do_map_resolver_election
3072  &lcm->active_map_resolver,
3073  &sloc)))
3074  {
3075  if (0 == elect_map_resolver (lcm))
3076  /* all Mrs are down */
3077  {
3078  if (duplicate_pmr)
3079  duplicate_pmr->to_be_removed = 1;
3080 
3081  /* restart MR checking by marking all of them up */
3082  vec_foreach (mr, lcm->map_resolvers) mr->is_down = 0;
3083 
3084  return -1;
3085  }
3086  }
3087 
3088  /* build the encapsulated map request */
3089  b = build_encapsulated_map_request (lcm, seid, deid, loc_set,
3090  &lcm->active_map_resolver,
3091  &sloc, is_smr_invoked, &nonce, &bi);
3092 
3093  if (!b)
3094  return -1;
3095 
3096  /* set fib index to default and lookup node */
3097  vnet_buffer (b)->sw_if_index[VLIB_TX] = 0;
3098  next_index = (ip_addr_version (&lcm->active_map_resolver) == IP4) ?
3099  ip4_lookup_node.index : ip6_lookup_node.index;
3100 
3101  f = vlib_get_frame_to_node (lcm->vlib_main, next_index);
3102 
3103  /* Enqueue the packet */
3104  to_next = vlib_frame_vector_args (f);
3105  to_next[0] = bi;
3106  f->n_vectors = 1;
3107  vlib_put_frame_to_node (lcm->vlib_main, next_index, f);
3108 
3109  if (duplicate_pmr)
3110  /* if there is a pending request already update it */
3111  {
3112  if (clib_fifo_elts (duplicate_pmr->nonces) >= PENDING_MREQ_QUEUE_LEN)
3113  {
3114  /* remove the oldest nonce */
3115  u64 CLIB_UNUSED (tmp), *nonce_del;
3116  nonce_del = clib_fifo_head (duplicate_pmr->nonces);
3117  hash_unset (lcm->pending_map_requests_by_nonce, nonce_del[0]);
3118  clib_fifo_sub1 (duplicate_pmr->nonces, tmp);
3119  }
3120 
3121  clib_fifo_add1 (duplicate_pmr->nonces, nonce);
3122  hash_set (lcm->pending_map_requests_by_nonce, nonce,
3123  duplicate_pmr - lcm->pending_map_requests_pool);
3124  }
3125  else
3126  {
3127  /* add map-request to pending requests table */
3128  pool_get (lcm->pending_map_requests_pool, pmr);
3129  memset (pmr, 0, sizeof (*pmr));
3130  gid_address_copy (&pmr->src, seid);
3131  gid_address_copy (&pmr->dst, deid);
3132  clib_fifo_add1 (pmr->nonces, nonce);
3133  pmr->is_smr_invoked = is_smr_invoked;
3135  hash_set (lcm->pending_map_requests_by_nonce, nonce,
3136  pmr - lcm->pending_map_requests_pool);
3137  }
3138 
3139  return 0;
3140 }
3141 
3142 static void
3143 get_src_and_dst_ip (void *hdr, ip_address_t * src, ip_address_t * dst)
3144 {
3145  ip4_header_t *ip4 = hdr;
3146  ip6_header_t *ip6;
3147 
3148  if ((ip4->ip_version_and_header_length & 0xF0) == 0x40)
3149  {
3150  ip_address_set (src, &ip4->src_address, IP4);
3151  ip_address_set (dst, &ip4->dst_address, IP4);
3152  }
3153  else
3154  {
3155  ip6 = hdr;
3156  ip_address_set (src, &ip6->src_address, IP6);
3157  ip_address_set (dst, &ip6->dst_address, IP6);
3158  }
3159 }
3160 
3161 static u32
3163  u8 version)
3164 {
3165  uword *vnip;
3166  u32 vni = ~0, table_id = ~0;
3167 
3168  table_id = fib_table_get_table_id_for_sw_if_index ((version ==
3169  IP4 ? FIB_PROTOCOL_IP4 :
3171  vnet_buffer
3172  (b)->sw_if_index
3173  [VLIB_RX]);
3174 
3175  vnip = hash_get (lcm->vni_by_table_id, table_id);
3176  if (vnip)
3177  vni = vnip[0];
3178  else
3179  clib_warning ("vrf %d is not mapped to any vni!", table_id);
3180 
3181  return vni;
3182 }
3183 
3186 {
3187  uword *vnip;
3188  u32 vni = ~0;
3189  u32 sw_if_index0;
3190 
3191  l2input_main_t *l2im = &l2input_main;
3192  l2_input_config_t *config;
3193  l2_bridge_domain_t *bd_config;
3194 
3195  sw_if_index0 = vnet_buffer (b)->sw_if_index[VLIB_RX];
3196  config = vec_elt_at_index (l2im->configs, sw_if_index0);
3197  bd_config = vec_elt_at_index (l2im->bd_configs, config->bd_index);
3198 
3199  vnip = hash_get (lcm->vni_by_bd_id, bd_config->bd_id);
3200  if (vnip)
3201  vni = vnip[0];
3202  else
3203  clib_warning ("bridge domain %d is not mapped to any vni!",
3204  config->bd_index);
3205 
3206  return vni;
3207 }
3208 
3209 always_inline void
3211  gid_address_t * src, gid_address_t * dst)
3212 {
3213  u32 vni = 0;
3214  u16 type;
3215 
3216  memset (src, 0, sizeof (*src));
3217  memset (dst, 0, sizeof (*dst));
3218  type = vnet_buffer (b)->lisp.overlay_afi;
3219 
3220  if (LISP_AFI_IP == type || LISP_AFI_IP6 == type)
3221  {
3222  ip4_header_t *ip;
3223  u8 version, preflen;
3224 
3227 
3228  ip = vlib_buffer_get_current (b);
3229  get_src_and_dst_ip (ip, &gid_address_ip (src), &gid_address_ip (dst));
3230 
3231  version = gid_address_ip_version (src);
3232  preflen = ip_address_max_len (version);
3233  gid_address_ippref_len (src) = preflen;
3234  gid_address_ippref_len (dst) = preflen;
3235 
3236  vni = lisp_get_vni_from_buffer_ip (lcm, b, version);
3237  gid_address_vni (dst) = vni;
3238  gid_address_vni (src) = vni;
3239  }
3240  else if (LISP_AFI_MAC == type)
3241  {
3242  ethernet_header_t *eh;
3243 
3244  eh = vlib_buffer_get_current (b);
3245 
3248  mac_copy (&gid_address_mac (src), eh->src_address);
3249  mac_copy (&gid_address_mac (dst), eh->dst_address);
3250 
3251  /* get vni */
3252  vni = lisp_get_vni_from_buffer_eth (lcm, b);
3253 
3254  gid_address_vni (dst) = vni;
3255  gid_address_vni (src) = vni;
3256  }
3257 }
3258 
3259 static uword
3261  vlib_node_runtime_t * node,
3262  vlib_frame_t * from_frame, int overlay)
3263 {
3264  u32 *from, *to_next_drop, di, si;
3266  u32 pkts_mapped = 0;
3267  uword n_left_from, n_left_to_next_drop;
3268 
3269  from = vlib_frame_vector_args (from_frame);
3270  n_left_from = from_frame->n_vectors;
3271 
3272  while (n_left_from > 0)
3273  {
3275  to_next_drop, n_left_to_next_drop);
3276 
3277  while (n_left_from > 0 && n_left_to_next_drop > 0)
3278  {
3279  u32 pi0;
3280  vlib_buffer_t *b0;
3281  gid_address_t src, dst;
3282 
3283  pi0 = from[0];
3284  from += 1;
3285  n_left_from -= 1;
3286  to_next_drop[0] = pi0;
3287  to_next_drop += 1;
3288  n_left_to_next_drop -= 1;
3289 
3290  b0 = vlib_get_buffer (vm, pi0);
3291  b0->error = node->errors[LISP_CP_LOOKUP_ERROR_DROP];
3292  vnet_buffer (b0)->lisp.overlay_afi = overlay;
3293 
3294  /* src/dst eid pair */
3295  get_src_and_dst_eids_from_buffer (lcm, b0, &src, &dst);
3296 
3297  /* if we have remote mapping for destination already in map-chache
3298  add forwarding tunnel directly. If not send a map-request */
3300  &src);
3301  if (~0 != di)
3302  {
3303  mapping_t *m = vec_elt_at_index (lcm->mapping_pool, di);
3304  /* send a map-request also in case of negative mapping entry
3305  with corresponding action */
3306  if (m->action == LISP_SEND_MAP_REQUEST)
3307  {
3308  /* send map-request */
3309  queue_map_request (&src, &dst, 0 /* smr_invoked */ ,
3310  0 /* is_resend */ );
3311  pkts_mapped++;
3312  }
3313  else
3314  {
3316  &src);
3317  if (~0 != si)
3318  {
3319  dp_add_fwd_entry (lcm, si, di);
3320  }
3321  }
3322  }
3323  else
3324  {
3325  /* send map-request */
3326  queue_map_request (&src, &dst, 0 /* smr_invoked */ ,
3327  0 /* is_resend */ );
3328  pkts_mapped++;
3329  }
3330 
3332  {
3333  lisp_cp_lookup_trace_t *tr = vlib_add_trace (vm, node, b0,
3334  sizeof (*tr));
3335 
3336  memset (tr, 0, sizeof (*tr));
3337  gid_address_copy (&tr->dst_eid, &dst);
3339  &lcm->active_map_resolver);
3340  }
3341  gid_address_free (&dst);
3342  gid_address_free (&src);
3343  }
3344 
3346  n_left_to_next_drop);
3347  }
3349  LISP_CP_LOOKUP_ERROR_MAP_REQUESTS_SENT,
3350  pkts_mapped);
3351  return from_frame->n_vectors;
3352 }
3353 
3354 static uword
3356  vlib_node_runtime_t * node, vlib_frame_t * from_frame)
3357 {
3358  return (lisp_cp_lookup_inline (vm, node, from_frame, LISP_AFI_IP));
3359 }
3360 
3361 static uword
3363  vlib_node_runtime_t * node, vlib_frame_t * from_frame)
3364 {
3365  return (lisp_cp_lookup_inline (vm, node, from_frame, LISP_AFI_IP6));
3366 }
3367 
3368 static uword
3370  vlib_node_runtime_t * node, vlib_frame_t * from_frame)
3371 {
3372  return (lisp_cp_lookup_inline (vm, node, from_frame, LISP_AFI_MAC));
3373 }
3374 
3375 /* *INDENT-OFF* */
3377  .function = lisp_cp_lookup_ip4,
3378  .name = "lisp-cp-lookup-ip4",
3379  .vector_size = sizeof (u32),
3380  .format_trace = format_lisp_cp_lookup_trace,
3382 
3383  .n_errors = LISP_CP_LOOKUP_N_ERROR,
3384  .error_strings = lisp_cp_lookup_error_strings,
3385 
3386  .n_next_nodes = LISP_CP_LOOKUP_N_NEXT,
3387 
3388  .next_nodes = {
3389  [LISP_CP_LOOKUP_NEXT_DROP] = "error-drop",
3390  },
3391 };
3392 /* *INDENT-ON* */
3393 
3394 /* *INDENT-OFF* */
3396  .function = lisp_cp_lookup_ip6,
3397  .name = "lisp-cp-lookup-ip6",
3398  .vector_size = sizeof (u32),
3399  .format_trace = format_lisp_cp_lookup_trace,
3401 
3402  .n_errors = LISP_CP_LOOKUP_N_ERROR,
3403  .error_strings = lisp_cp_lookup_error_strings,
3404 
3405  .n_next_nodes = LISP_CP_LOOKUP_N_NEXT,
3406 
3407  .next_nodes = {
3408  [LISP_CP_LOOKUP_NEXT_DROP] = "error-drop",
3409  },
3410 };
3411 /* *INDENT-ON* */
3412 
3413 /* *INDENT-OFF* */
3415  .function = lisp_cp_lookup_l2,
3416  .name = "lisp-cp-lookup-l2",
3417  .vector_size = sizeof (u32),
3418  .format_trace = format_lisp_cp_lookup_trace,
3420 
3421  .n_errors = LISP_CP_LOOKUP_N_ERROR,
3422  .error_strings = lisp_cp_lookup_error_strings,
3423 
3424  .n_next_nodes = LISP_CP_LOOKUP_N_NEXT,
3425 
3426  .next_nodes = {
3427  [LISP_CP_LOOKUP_NEXT_DROP] = "error-drop",
3428  },
3429 };
3430 /* *INDENT-ON* */
3431 
3432 /* lisp_cp_input statistics */
3433 #define foreach_lisp_cp_input_error \
3434 _(DROP, "drop") \
3435 _(MAP_REPLIES_RECEIVED, "map-replies received")
3436 
3438 #define _(sym,string) string,
3440 #undef _
3441 };
3442 
3443 typedef enum
3444 {
3445 #define _(sym,str) LISP_CP_INPUT_ERROR_##sym,
3447 #undef _
3450 
3451 typedef enum
3452 {
3456 
3457 typedef struct
3458 {
3462 
3463 u8 *
3464 format_lisp_cp_input_trace (u8 * s, va_list * args)
3465 {
3466  CLIB_UNUSED (vlib_main_t * vm) = va_arg (*args, vlib_main_t *);
3467  CLIB_UNUSED (vlib_node_t * node) = va_arg (*args, vlib_node_t *);
3469  va_arg (*args, lisp_cp_input_trace_t *);
3470 
3471  s = format (s, "LISP-CP-INPUT: TODO");
3472  return s;
3473 }
3474 
3475 void *
3477 {
3479  vlib_buffer_t *b = arg;
3480  u32 len = 0, i, ttl, dst_map_index = 0;
3481  void *h;
3482  pending_map_request_t *pmr;
3483  locator_t probed;
3484  map_reply_hdr_t *mrep_hdr;
3485  u64 nonce, *noncep;
3486  gid_address_t deid;
3487  uword *pmr_index;
3488  u8 authoritative, action;
3489  locator_t *locators = 0, *loc;
3490 
3491  mrep_hdr = vlib_buffer_get_current (b);
3492 
3494 
3495  /* Check pending requests table and nonce */
3496  nonce = MREP_NONCE (mrep_hdr);
3497  pmr_index = hash_get (lcm->pending_map_requests_by_nonce, nonce);
3498  if (!pmr_index)
3499  {
3500  clib_warning ("No pending map-request entry with nonce %lu!", nonce);
3501  goto done;
3502  }
3503  pmr = pool_elt_at_index (lcm->pending_map_requests_pool, pmr_index[0]);
3504 
3505  vlib_buffer_pull (b, sizeof (*mrep_hdr));
3506 
3507  for (i = 0; i < MREP_REC_COUNT (mrep_hdr); i++)
3508  {
3509  h = vlib_buffer_get_current (b);
3510  ttl = clib_net_to_host_u32 (MAP_REC_TTL (h));
3511  action = MAP_REC_ACTION (h);
3512  authoritative = MAP_REC_AUTH (h);
3513 
3514  len = lisp_msg_parse_mapping_record (b, &deid, &locators, &probed);
3515  if (len == ~0)
3516  {
3517  clib_warning ("Failed to parse mapping record!");
3518  vec_foreach (loc, locators)
3519  {
3520  locator_free (loc);
3521  }
3522  vec_free (locators);
3523  goto done;
3524  }
3525 
3526  /* insert/update mappings cache */
3527  vnet_lisp_add_del_mapping (&deid, locators, action, authoritative, ttl,
3528  1, 0 /* is_static */ , &dst_map_index);
3529 
3530  /* try to program forwarding only if mapping saved or updated */
3531  if ((u32) ~ 0 != dst_map_index)
3532  lisp_add_del_adjacency (lcm, &pmr->src, &deid, 1);
3533 
3534  vec_free (locators);
3535  }
3536 
3537  /* remove pending map request entry */
3538 
3539  /* *INDENT-OFF* */
3540  clib_fifo_foreach (noncep, pmr->nonces, ({
3541  hash_unset(lcm->pending_map_requests_by_nonce, noncep[0]);
3542  }));
3543  /* *INDENT-ON* */
3544 
3545  clib_fifo_free (pmr->nonces);
3546  pool_put (lcm->pending_map_requests_pool, pmr);
3547 
3548 done:
3550  return 0;
3551 }
3552 
3553 void
3555  vlib_buffer_t * b)
3556 {
3557  map_request_hdr_t *mreq_hdr;
3558  gid_address_t src, dst;
3559 // u64 nonce;
3560  u32 i, len = 0;
3561  gid_address_t *itr_rlocs = 0, *rloc;
3562 
3563  mreq_hdr = vlib_buffer_get_current (b);
3564  vlib_buffer_pull (b, sizeof (*mreq_hdr));
3565 
3566 // nonce = MREQ_NONCE(mreq_hdr);
3567 
3568  if (!MREQ_SMR (mreq_hdr))
3569  {
3570  clib_warning ("Only SMR Map-Requests supported for now!");
3571  return;
3572  }
3573 
3574  /* parse src eid */
3575  len = lisp_msg_parse_addr (b, &src);
3576  if (len == ~0)
3577  return;
3578 
3579  /* for now we don't do anything with the itr's rlocs */
3580  len =
3581  lisp_msg_parse_itr_rlocs (b, &itr_rlocs,
3582  MREQ_ITR_RLOC_COUNT (mreq_hdr) + 1);
3583  if (len == ~0)
3584  return;
3585 
3586  /* TODO: RLOCs are currently unused, so free them for now */
3587  vec_foreach (rloc, itr_rlocs)
3588  {
3589  gid_address_free (rloc);
3590  }
3591 
3592  /* parse eid records and send SMR-invoked map-requests */
3593  for (i = 0; i < MREQ_REC_COUNT (mreq_hdr); i++)
3594  {
3595  memset (&dst, 0, sizeof (dst));
3596  len = lisp_msg_parse_eid_rec (b, &dst);
3597  if (len == ~0)
3598  {
3599  clib_warning ("Can't parse map-request EID-record");
3600  return;
3601  }
3602  /* send SMR-invoked map-requests */
3603  queue_map_request (&dst, &src, 1 /* invoked */ , 0 /* resend */ );
3604  }
3605 }
3606 
3607 static void
3609 {
3610  vlib_buffer_t *a = clib_mem_alloc (sizeof (a[0]) + b->current_length);
3611 
3612  clib_memcpy (a->data, b->data + b->current_data, b->current_length);
3614  a->current_data = 0;
3615 
3616  vl_api_rpc_call_main_thread (process_map_reply, (u8 *) a, sizeof (a[0])
3617  + a->current_length);
3618  clib_mem_free (a);
3619 }
3620 
3621 static uword
3623  vlib_frame_t * from_frame)
3624 {
3625  u32 n_left_from, *from, *to_next_drop;
3628 
3629  from = vlib_frame_vector_args (from_frame);
3630  n_left_from = from_frame->n_vectors;
3631 
3632 
3633  while (n_left_from > 0)
3634  {
3635  u32 n_left_to_next_drop;
3636 
3638  to_next_drop, n_left_to_next_drop);
3639  while (n_left_from > 0 && n_left_to_next_drop > 0)
3640  {
3641  u32 bi0;
3642  vlib_buffer_t *b0;
3643 
3644  bi0 = from[0];
3645  from += 1;
3646  n_left_from -= 1;
3647  to_next_drop[0] = bi0;
3648  to_next_drop += 1;
3649  n_left_to_next_drop -= 1;
3650 
3651  b0 = vlib_get_buffer (vm, bi0);
3652 
3653  type = lisp_msg_type (vlib_buffer_get_current (b0));
3654  switch (type)
3655  {
3656  case LISP_MAP_REPLY:
3657  queue_map_reply (b0);
3658  break;
3659  case LISP_MAP_REQUEST:
3660  process_map_request (vm, lcm, b0);
3661  break;
3662  default:
3663  clib_warning ("Unsupported LISP message type %d", type);
3664  break;
3665  }
3666 
3667  b0->error = node->errors[LISP_CP_INPUT_ERROR_DROP];
3668 
3670  {
3671 
3672  }
3673  }
3674 
3676  n_left_to_next_drop);
3677  }
3678  return from_frame->n_vectors;
3679 }
3680 
3681 /* *INDENT-OFF* */
3683  .function = lisp_cp_input,
3684  .name = "lisp-cp-input",
3685  .vector_size = sizeof (u32),
3686  .format_trace = format_lisp_cp_input_trace,
3688 
3689  .n_errors = LISP_CP_INPUT_N_ERROR,
3690  .error_strings = lisp_cp_input_error_strings,
3691 
3692  .n_next_nodes = LISP_CP_INPUT_N_NEXT,
3693 
3694  .next_nodes = {
3695  [LISP_CP_INPUT_NEXT_DROP] = "error-drop",
3696  },
3697 };
3698 /* *INDENT-ON* */
3699 
3700 clib_error_t *
3702 {
3704  clib_error_t *error = 0;
3705 
3706  if ((error = vlib_call_init_function (vm, lisp_gpe_init)))
3707  return error;
3708 
3709  lcm->im4 = &ip4_main;
3710  lcm->im6 = &ip6_main;
3711  lcm->vlib_main = vm;
3712  lcm->vnet_main = vnet_get_main ();
3713  lcm->mreq_itr_rlocs = ~0;
3714  lcm->lisp_pitr = 0;
3715  memset (&lcm->active_map_resolver, 0, sizeof (lcm->active_map_resolver));
3716 
3719 
3720  lcm->pending_map_request_lock[0] = 0;
3722  lcm->do_map_resolver_election = 1;
3724 
3725  /* default vrf mapped to vni 0 */
3726  hash_set (lcm->table_id_by_vni, 0, 0);
3727  hash_set (lcm->vni_by_table_id, 0, 0);
3728 
3729  udp_register_dst_port (vm, UDP_DST_PORT_lisp_cp,
3730  lisp_cp_input_node.index, 1 /* is_ip4 */ );
3731  udp_register_dst_port (vm, UDP_DST_PORT_lisp_cp6,
3732  lisp_cp_input_node.index, 0 /* is_ip4 */ );
3733 
3734  return 0;
3735 }
3736 
3737 static void *
3739 {
3740  map_request_args_t *a = arg;
3742 
3743  if (a->is_resend)
3744  /* if resending, we already have the lock */
3746  else
3747  {
3748  /* get lock before sending map-request */
3750  send_encapsulated_map_request (lcm, &a->seid, &a->deid, a->smr_invoked);
3752  }
3753 
3754 
3755  return 0;
3756 }
3757 
3758 static int
3760  u8 smr_invoked, u8 is_resend)
3761 {
3763 
3764  a.is_resend = is_resend;
3765  gid_address_copy (&a.seid, seid);
3766  gid_address_copy (&a.deid, deid);
3767  a.smr_invoked = smr_invoked;
3768 
3770  (u8 *) & a, sizeof (a));
3771  return 0;
3772 }
3773 
3774 /**
3775  * Take an action with a pending map request depending on expiration time
3776  * and re-try counters.
3777  */
3778 static void
3780 {
3782  map_resolver_t *mr;
3783 
3784  if (r->time_to_expire - dt < 0)
3785  /* it's time to decide what to do with this pending request */
3786  {
3787  if (r->retries_num >= NUMBER_OF_RETRIES)
3788  /* too many retries -> assume current map resolver is not available */
3789  {
3791  if (!mr)
3792  {
3793  clib_warning ("Map resolver %U not found - probably deleted "
3794  "by the user recently.", format_ip_address,
3795  &lcm->active_map_resolver);
3796  }
3797  else
3798  {
3799  clib_warning ("map resolver %U is unreachable, ignoring",
3801 
3802  /* mark current map resolver unavailable so it won't be
3803  * selected next time */
3804  mr->is_down = 1;
3805  mr->last_update = vlib_time_now (lcm->vlib_main);
3806  }
3807 
3809  elect_map_resolver (lcm);
3810 
3811  /* try to find a next eligible map resolver and re-send */
3812  queue_map_request (&r->src, &r->dst, r->is_smr_invoked,
3813  1 /* resend */ );
3814  }
3815  else
3816  {
3817  /* try again */
3818  queue_map_request (&r->src, &r->dst, r->is_smr_invoked,
3819  1 /* resend */ );
3820  r->retries_num++;
3822  }
3823  }
3824  else
3825  r->time_to_expire -= dt;
3826 }
3827 
3828 static void
3830 {
3831  u64 *nonce;
3832  pending_map_request_t *pmr;
3833  u32 *to_be_removed = 0, *pmr_index;
3834 
3836 
3837  /* *INDENT-OFF* */
3839  ({
3840  if (pmr->to_be_removed)
3841  {
3842  clib_fifo_foreach (nonce, pmr->nonces, ({
3843  hash_unset (lcm->pending_map_requests_by_nonce, nonce[0]);
3844  }));
3845 
3846  vec_add1 (to_be_removed, pmr - lcm->pending_map_requests_pool);
3847  }
3848  }));
3849  /* *INDENT-ON* */
3850 
3851  vec_foreach (pmr_index, to_be_removed)
3852  pool_put_index (lcm->pending_map_requests_by_nonce, pmr_index[0]);
3853 
3854  vec_free (to_be_removed);
3855 }
3856 
3857 static uword
3860 {
3861  f64 period = 2.0;
3862  pending_map_request_t *pmr;
3864 
3865  while (1)
3866  {
3868 
3869  /* currently no signals are expected - just wait for clock */
3870  (void) vlib_process_get_events (vm, 0);
3871 
3873 
3874  /* *INDENT-OFF* */
3876  ({
3877  if (!pmr->to_be_removed)
3878  update_pending_request (pmr, period);
3879  }));
3880  /* *INDENT-ON* */
3881 
3883 
3885  }
3886 
3887  /* unreachable */
3888  return 0;
3889 }
3890 
3891 /* *INDENT-OFF* */
3893  .function = send_map_resolver_service,
3894  .type = VLIB_NODE_TYPE_PROCESS,
3895  .name = "lisp-retry-service",
3896  .process_log2_n_stack_bytes = 16,
3897 };
3898 /* *INDENT-ON* */
3899 
3901 
3902 /*
3903  * fd.io coding-style-patch-verification: ON
3904  *
3905  * Local Variables:
3906  * eval: (c-set-style "gnu")
3907  * End:
3908  */
void lisp_gpe_tenant_l2_iface_unlock(u32 vni)
Release the lock held on the tenant&#39;s L3 interface.
#define vec_validate(V, I)
Make sure vector is long enough for given index (no header, unspecified alignment) ...
Definition: vec.h:396
#define MREQ_SMR(h_)
static clib_error_t * lisp_show_map_resolvers_command_fn(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
Definition: control.c:1540
void vlib_put_next_frame(vlib_main_t *vm, vlib_node_runtime_t *r, u32 next_index, u32 n_vectors_left)
Release pointer to next frame vector data.
Definition: main.c:457
#define foreach_ip_interface_address(lm, a, sw_if_index, loop, body)
Definition: lookup.h:434
fib_protocol_t fp_proto
protocol type
Definition: fib_types.h:158
#define VNET_SW_INTERFACE_FLAG_UNNUMBERED
Definition: interface.h:497
#define MREQ_ITR_RLOC_COUNT(h_)
static uword lisp_cp_input(vlib_main_t *vm, vlib_node_runtime_t *node, vlib_frame_t *from_frame)
Definition: control.c:3622
#define gid_address_ip_version(_a)
Definition: lisp_types.h:219
#define vec_foreach_index(var, v)
Iterate over vector indices.
u32 pitr_map_index
Definition: control.h:149
#define MREP_REC_COUNT(h_)
#define hash_set(h, key, value)
Definition: hash.h:254
l2_input_config_t * configs
Definition: l2_input.h:66
gid_address_t leid
Definition: control.h:48
sll srl srl sll sra u16x4 i
Definition: vector_sse2.h:343
#define clib_fifo_head(v)
Definition: fifo.h:254
static clib_error_t * lisp_map_request_mode_command_fn(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
Definition: control.c:1463
#define gid_address_type(_a)
Definition: lisp_types.h:215
#define CLIB_UNUSED(x)
Definition: clib.h:79
uword unformat(unformat_input_t *i, char *fmt,...)
Definition: unformat.c:966
vlib_node_registration_t lisp_cp_lookup_ip4_node
(constructor) VLIB_REGISTER_NODE (lisp_cp_lookup_ip4_node)
Definition: control.c:3376
static clib_error_t * lisp_pitr_set_locator_set_command_fn(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
Definition: control.c:1606
static f64 vlib_process_wait_for_event_or_clock(vlib_main_t *vm, f64 dt)
Suspend a cooperative multi-tasking thread Waits for an event, or for the indicated number of seconds...
Definition: node_funcs.h:684
#define hash_unset(h, key)
Definition: hash.h:260
a
Definition: bitmap.h:516
gid_address_t deid
Definition: control.c:30
lisp_cp_lookup_next_t
Definition: control.c:2806
ip4_address_t src_address
Definition: ip4_packet.h:138
static uword clib_fifo_elts(void *v)
Definition: fifo.h:66
ip_address_t active_map_resolver
Definition: control.h:130
bad routing header type(not 4)") sr_error (NO_MORE_SEGMENTS
#define MAP_REC_TTL(h)
gid_address_t dst_eid
Definition: control.c:3459
void * pkt_push_udp_and_ip(vlib_main_t *vm, vlib_buffer_t *b, u16 sp, u16 dp, ip_address_t *sip, ip_address_t *dip)
Definition: packets.c:226
void ip_prefix_to_fib_prefix(const ip_prefix_t *ip_prefix, fib_prefix_t *fib_prefix)
convert from a LISP to a FIB prefix
Definition: control.c:113
#define MREQ_REC_COUNT(h_)
static vlib_buffer_t * build_encapsulated_map_request(lisp_cp_main_t *lcm, gid_address_t *seid, gid_address_t *deid, locator_set_t *loc_set, ip_address_t *mr_ip, ip_address_t *sloc, u8 is_smr_invoked, u64 *nonce_res, u32 *bi_res)
Definition: control.c:2912
static u8 * format_lisp_map_request_mode(u8 *s, va_list *args)
Definition: control.c:1507
locator_pair_t * locator_pairs
Definition: control.h:43
uword * table_id_by_vni
Definition: control.h:138
void lisp_gpe_tenant_l3_iface_unlock(u32 vni)
Release the lock held on the tenant&#39;s L3 interface.
#define UNFORMAT_END_OF_INPUT
Definition: format.h:143
static clib_error_t * lisp_show_adjacencies_command_fn(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
Definition: control.c:491
clib_error_t * vnet_lisp_gpe_enable_disable(vnet_lisp_gpe_enable_disable_args_t *a)
Enable/disable LISP-GPE.
Definition: lisp_gpe.c:183
#define NULL
Definition: clib.h:55
#define foreach_lisp_cp_input_error
Definition: control.c:3433
static clib_error_t * lisp_show_status_command_fn(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
Definition: control.c:2271
u32 * local_mappings_indexes
Definition: control.h:107
static f64 vlib_time_now(vlib_main_t *vm)
Definition: main.h:182
locator_t * locator_pool
Definition: control.h:92
#define PENDING_MREQ_QUEUE_LEN
Definition: control.h:25
u8 src_address[6]
Definition: packet.h:54
LISP-GPE global state.
Definition: lisp_gpe.h:89
u8 vnet_lisp_get_map_request_mode(void)
Definition: control.c:35
static int elect_map_resolver(lisp_cp_main_t *lcm)
Definition: control.c:2973
#define ip_prefix_len(_a)
Definition: lisp_types.h:60
void ip_address_to_fib_prefix(const ip_address_t *addr, fib_prefix_t *prefix)
convert from a LISP address to a FIB prefix
Definition: control.c:92
uword unformat_ip_address(unformat_input_t *input, va_list *args)
Definition: lisp_types.c:147
#define vec_add1(V, E)
Add 1 element to end of vector (unspecified alignment).
Definition: vec.h:482
Definition: control.h:38
LISP-GPE definitions.
lisp_cp_input_next_t
Definition: control.c:3451
u32 ip_fib_get_egress_iface_for_dst(lisp_cp_main_t *lcm, ip_address_t *dst)
Find the sw_if_index of the interface that would be used to egress towards dst.
Definition: control.c:125
#define hash_set_mem(h, key, value)
Definition: hash.h:274
static char * lisp_cp_input_error_strings[]
Definition: control.c:3437
ip_lookup_main_t lookup_main
Definition: ip4.h:96
static vnet_sw_interface_t * vnet_get_sw_interface(vnet_main_t *vnm, u32 sw_if_index)
unformat_function_t unformat_vnet_sw_interface
static void remove_dead_pending_map_requests(lisp_cp_main_t *lcm)
Definition: control.c:3829
void ip_address_copy(ip_address_t *dst, const ip_address_t *src)
Definition: lisp_types.c:699
void ip_address_set(ip_address_t *dst, const void *src, u8 version)
Definition: lisp_types.c:721
vlib_error_t * errors
Definition: node.h:419
uword * vni_by_table_id
Definition: control.h:139
#define pool_get(P, E)
Allocate an object E from a pool P (unspecified alignment).
Definition: pool.h:200
static clib_error_t * lisp_add_del_locator_in_set_command_fn(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
Definition: control.c:2421
ip6_address_t src_address
Definition: ip6_packet.h:300
#define ip_prefix_version(_a)
Definition: lisp_types.h:59
format_function_t format_vnet_sw_if_index_name
#define fid_addr_mac(_a)
Definition: lisp_types.h:113
void gid_dictionary_init(gid_dictionary_t *db)
int vnet_lisp_set_map_request_mode(u8 mode)
Definition: control.c:1442
static clib_error_t * lisp_eid_table_map_command_fn(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
Definition: control.c:823
static void clean_locator_to_locator_set(lisp_cp_main_t *lcm, u32 lsi)
Definition: control.c:1843
int vnet_lisp_add_del_adjacency(vnet_lisp_add_del_adjacency_args_t *a)
Definition: control.c:1195
uword value[0]
Definition: hash.h:164
#define NUMBER_OF_RETRIES
Definition: control.h:23
static clib_error_t * lisp_cp_show_locator_sets_command_fn(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
Definition: control.c:2495
map_resolver_t * map_resolvers
Definition: control.h:124
vlib_node_registration_t ip4_lookup_node
(constructor) VLIB_REGISTER_NODE (ip4_lookup_node)
Definition: ip4_forward.c:485
uword unformat_negative_mapping_action(unformat_input_t *input, va_list *args)
Definition: lisp_types.c:308
static void reset_pending_mr_counters(pending_map_request_t *r)
Definition: control.c:2966
u32 ** locator_to_locator_sets
Definition: control.h:98
vlib_main_t * vlib_main
Definition: control.h:160
vnet_main_t * vnet_get_main(void)
Definition: misc.c:46
i16 current_data
signed offset in data[], pre_data[] that we are currently processing.
Definition: buffer.h:78
#define pool_foreach(VAR, POOL, BODY)
Iterate through pool.
Definition: pool.h:348
static clib_error_t * lisp_add_del_local_eid_command_fn(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
Definition: control.c:679
static void queue_map_reply(vlib_buffer_t *b)
Definition: control.c:3608
#define VLIB_INIT_FUNCTION(x)
Definition: init.h:111
static uword vlib_process_get_events(vlib_main_t *vm, uword **data_vector)
Return the first event type which has occurred and a vector of per-event data of that type...
Definition: node_funcs.h:527
#define always_inline
Definition: clib.h:84
int ip_fib_get_first_egress_ip_for_dst(lisp_cp_main_t *lcm, ip_address_t *dst, ip_address_t *result)
Find first IP of the interface that would be used to egress towards dst.
Definition: control.c:142
static void * vlib_buffer_get_current(vlib_buffer_t *b)
Get pointer to current data to process.
Definition: buffer.h:190
u16 bd_id
bridge domain id
Definition: lisp_gpe.h:216
gid_address_t * eids_to_be_deleted
Definition: control.c:890
ip4_address_t dst_address
Definition: ip4_packet.h:138
u8 dst_address[6]
Definition: packet.h:53
u8 is_add
Definition: lisp_gpe.h:180
#define hash_foreach(key_var, value_var, h, body)
Definition: hash.h:418
void di(unformat_input_t *i)
Definition: unformat.c:163
volatile u32 * pending_map_request_lock
Definition: control.h:121
#define gid_address_sd_src(_a)
Definition: lisp_types.h:229
#define vec_elt_at_index(v, i)
Get vector value at index i checking that i is in bounds.
Aggregrate type for a prefix.
Definition: fib_types.h:149
u32 * fwd_entry_by_mapping_index
Definition: control.h:111
void vl_api_rpc_call_main_thread(void *fp, u8 *data, u32 data_length)
Definition: memory_vlib.c:1364
static void unformat_free(unformat_input_t *i)
Definition: format.h:161
#define clib_warning(format, args...)
Definition: error.h:59
unsigned long u64
Definition: types.h:89
int vnet_lisp_eid_table_map(u32 vni, u32 dp_id, u8 is_l2, u8 is_add)
Definition: control.c:767
static u32 get_locator_pairs(lisp_cp_main_t *lcm, mapping_t *lcl_map, mapping_t *rmt_map, locator_pair_t **locator_pairs)
Finds first remote locator with best (lowest) priority that has a local peer locator with an underlyi...
Definition: control.c:250
uword unformat_user(unformat_input_t *input, unformat_function_t *func,...)
Definition: unformat.c:977
uword * bd_id_by_vni
Definition: control.h:142
int vlib_main(vlib_main_t *volatile vm, unformat_input_t *input)
Definition: main.c:1573
u32 lisp_gpe_tenant_l2_iface_add_or_lock(u32 vni, u32 bd_id)
Add/create and lock a new or find and lock the existing L2 interface for the tenant.
void * lisp_msg_put_mreq(lisp_cp_main_t *lcm, vlib_buffer_t *b, gid_address_t *seid, gid_address_t *deid, gid_address_t *rlocs, u8 is_smr_invoked, u64 *nonce)
static lisp_cp_main_t * vnet_lisp_cp_get_main()
Definition: control.h:174
u16 fp_len
The mask length.
Definition: fib_types.h:153
#define vlib_call_init_function(vm, x)
Definition: init.h:161
static void * send_map_request_thread_fn(void *arg)
Definition: control.c:3738
uword * vni_by_bd_id
Definition: control.h:143
fib_node_index_t fib_table_lookup(u32 fib_index, const fib_prefix_t *prefix)
Perfom a longest prefix match in the non-forwarding table.
Definition: fib_table.c:66
Definition: lisp_gpe.h:178
gid_address_t src
Definition: control.h:29
#define ip_addr_version(_a)
Definition: lisp_types.h:43
ip6_main_t * im6
Definition: control.h:159
static void update_pending_request(pending_map_request_t *r, f64 dt)
Take an action with a pending map request depending on expiration time and re-try counters...
Definition: control.c:3779
clib_error_t * vnet_lisp_enable_disable(u8 is_enable)
Definition: control.c:2173
static clib_error_t * lisp_enable_disable_command_fn(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
Definition: control.c:2215
vlib_node_registration_t lisp_cp_lookup_ip6_node
(constructor) VLIB_REGISTER_NODE (lisp_cp_lookup_ip6_node)
Definition: control.c:3395
u32 gid_dictionary_lookup(gid_dictionary_t *db, gid_address_t *key)
#define hash_get(h, key)
Definition: hash.h:248
u8 is_src_dst
Definition: control.h:42
int vnet_lisp_pitr_set_locator_set(u8 *locator_set_name, u8 is_add)
Definition: control.c:1563
#define pool_elt_at_index(p, i)
Returns pointer to element at given index.
Definition: pool.h:369
#define hash_unset_mem(h, key)
Definition: hash.h:280
lisp_cp_lookup_error_t
Definition: control.c:2798
u8 do_map_resolver_election
Definition: control.h:132
#define clib_fifo_sub1(f, e)
Definition: fifo.h:224
u32 table_id
table (vrf) id
Definition: lisp_gpe.h:213
u16 current_length
Nbytes between current data and the end of this buffer.
Definition: buffer.h:82
ip46_address_t fp_addr
The address type is not deriveable from the fp_addr member.
Definition: fib_types.h:172
void gid_dict_foreach_subprefix(gid_dictionary_t *db, gid_address_t *eid, foreach_subprefix_match_cb_t cb, void *arg)
u32 gid_dictionary_add_del(gid_dictionary_t *db, gid_address_t *key, u32 value, u8 is_add)
#define gid_address_mac(_a)
Definition: lisp_types.h:221
int get_mr_and_local_iface_ip(lisp_cp_main_t *lcm, ip_address_t *mr_ip, ip_address_t *sloc)
Definition: control.c:2832
int vnet_lisp_map_cache_add_del(vnet_lisp_add_del_mapping_args_t *a, u32 *map_index_result)
Add/remove mapping to/from map-cache.
Definition: control.c:546
#define MAP_REC_AUTH(h)
int vnet_lisp_add_del_local_mapping(vnet_lisp_add_del_mapping_args_t *a, u32 *map_index_result)
Add/update/delete mapping to/in/from map-cache.
Definition: control.c:645
u32 lisp_msg_parse_addr(vlib_buffer_t *b, gid_address_t *eid)
static vlib_node_registration_t lisp_retry_service_node
(constructor) VLIB_REGISTER_NODE (lisp_retry_service_node)
Definition: control.c:3892
vlib_node_registration_t lisp_cp_input_node
(constructor) VLIB_REGISTER_NODE (lisp_cp_input_node)
Definition: control.c:3682
#define hash_free(h)
Definition: hash.h:286
void gid_address_free(gid_address_t *a)
Definition: lisp_types.c:671
vlib_node_registration_t lisp_cp_lookup_l2_node
(constructor) VLIB_REGISTER_NODE (lisp_cp_lookup_l2_node)
Definition: control.c:3414
#define pool_put(P, E)
Free an object E in pool P.
Definition: pool.h:214
#define gid_address_sd_dst_type(_a)
Definition: lisp_types.h:232
#define vec_dup(V)
Return copy of vector (no header, no alignment)
Definition: vec.h:334
u8 authoritative
Definition: lisp_types.h:299
#define unformat_parse_error(input)
Definition: format.h:267
u32 * local_locator_set_indexes
Definition: control.h:108
#define PREDICT_FALSE(x)
Definition: clib.h:97
uword unformat_gid_address(unformat_input_t *input, va_list *args)
Definition: lisp_types.c:273
gid_address_t reid
Definition: control.h:41
#define vec_del1(v, i)
Delete the element at index I.
Definition: vec.h:765
u8 * format_gid_address(u8 *s, va_list *args)
Definition: lisp_types.c:226
static uword lisp_cp_lookup_ip4(vlib_main_t *vm, vlib_node_runtime_t *node, vlib_frame_t *from_frame)
Definition: control.c:3355
ip_address_t lcl_loc
Definition: lisp_types.h:313
u8 map_request_mode
Definition: control.h:155
static u8 compare_locators(lisp_cp_main_t *lcm, u32 *old_ls_indexes, locator_t *new_locators)
Definition: control.c:864
#define foreach_lisp_cp_lookup_error
Definition: control.c:2788
void vlib_put_frame_to_node(vlib_main_t *vm, u32 to_node_index, vlib_frame_t *f)
Definition: main.c:194
#define MAX_LISP_MSG_ENCAP_LEN
#define vlib_get_next_frame(vm, node, next_index, vectors, n_vectors_left)
Get pointer to next frame vector data by (vlib_node_runtime_t, next_index).
Definition: node_funcs.h:350
void vlib_cli_output(vlib_main_t *vm, char *fmt,...)
Definition: cli.c:575
ip_address_t map_resolver_ip
Definition: control.c:2815
int vnet_lisp_add_del_mapping(gid_address_t *eid, locator_t *rlocs, u8 action, u8 authoritative, u32 ttl, u8 is_add, u8 is_static, u32 *res_map_index)
Adds/removes/updates mapping.
Definition: control.c:979
#define clib_fifo_foreach(v, f, body)
Definition: fifo.h:279
u32 decap_next_index
Definition: lisp_gpe.h:204
static clib_error_t * lisp_add_del_map_resolver_command_fn(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
Definition: control.c:2616
vlib_error_t error
Error code for buffers to be enqueued to error handler.
Definition: buffer.h:121
static int queue_map_request(gid_address_t *seid, gid_address_t *deid, u8 smr_invoked, u8 is_resend)
Definition: control.c:3759
static void vlib_node_increment_counter(vlib_main_t *vm, u32 node_index, u32 counter_index, u64 increment)
Definition: node_funcs.h:1113
static void remove_locator_from_locator_set(locator_set_t *ls, u32 *locit, u32 ls_index, u32 loc_id)
Definition: control.c:1927
static clib_error_t * lisp_show_eid_table_map_command_fn(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
Definition: control.c:2291
#define gid_address_ippref(_a)
Definition: lisp_types.h:216
static void * vlib_buffer_pull(vlib_buffer_t *b, u8 size)
Definition: packets.h:64
lisp_adjacency_t * vnet_lisp_adjacencies_get_by_vni(u32 vni)
Returns vector of adjacencies.
Definition: control.c:469
u32 fib_entry_get_resolving_interface(fib_node_index_t entry_index)
Definition: fib_entry.c:1354
u8 is_negative
type of mapping
Definition: lisp_gpe.h:183
static int is_locator_in_locator_set(lisp_cp_main_t *lcm, locator_set_t *ls, locator_t *loc)
Definition: control.c:1903
#define pool_free(p)
Free a pool.
Definition: pool.h:263
u32 lisp_msg_parse_itr_rlocs(vlib_buffer_t *b, gid_address_t **rlocs, u8 rloc_count)
u32 sw_if_index
Definition: lisp_types.h:266
clib_error_t * lisp_cp_init(vlib_main_t *vm)
Definition: control.c:3701
static clib_error_t * lisp_add_del_mreq_itr_rlocs_command_fn(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
Definition: control.c:2705
static void * vlib_buffer_make_headroom(vlib_buffer_t *b, u8 size)
Definition: packets.h:56
u32 vni
VNI/tenant id in HOST byte order.
Definition: lisp_gpe.h:207
static uword lisp_cp_lookup_l2(vlib_main_t *vm, vlib_node_runtime_t *node, vlib_frame_t *from_frame)
Definition: control.c:3369
uword * pending_map_requests_by_nonce
Definition: control.h:117
static void dp_add_fwd_entry(lisp_cp_main_t *lcm, u32 src_map_index, u32 dst_map_index)
Definition: control.c:366
int vnet_lisp_add_del_mreq_itr_rlocs(vnet_lisp_add_del_mreq_itr_rloc_args_t *a)
Definition: control.c:2674
u16 n_vectors
Definition: node.h:344
int lisp_add_del_adjacency(lisp_cp_main_t *lcm, gid_address_t *local_eid, gid_address_t *remote_eid, u8 is_add)
Adds adjacency or removes forwarding entry associated to remote mapping.
Definition: control.c:1145
u8 * format_lisp_cp_input_trace(u8 *s, va_list *args)
Definition: control.c:3464
#define MAP_REC_ACTION(h)
int gid_address_cmp(gid_address_t *a1, gid_address_t *a2)
Definition: lisp_types.c:1382
static void lisp_pending_map_request_lock(lisp_cp_main_t *lcm)
Definition: control.h:264
#define vec_free(V)
Free vector&#39;s memory (no header).
Definition: vec.h:300
#define gid_address_ippref_len(_a)
Definition: lisp_types.h:217
vnet_main_t * vnet_main
Definition: lisp_gpe.h:124
u32 lisp_msg_parse_mapping_record(vlib_buffer_t *b, gid_address_t *eid, locator_t **locs, locator_t *probed_)
static void remove_mapping_if_needed(u32 mi, void *arg)
Callback invoked when a sub-prefix is found.
Definition: control.c:897
static void lisp_pending_map_request_unlock(lisp_cp_main_t *lcm)
Definition: control.h:272
u32 locator_set_index
Definition: lisp_types.h:295
void * lisp_msg_push_ecm(vlib_main_t *vm, vlib_buffer_t *b, int lp, int rp, gid_address_t *la, gid_address_t *ra)
#define clib_memcpy(a, b, c)
Definition: string.h:64
u32 locator_cmp(locator_t *l1, locator_t *l2)
Definition: lisp_types.c:1462
static map_resolver_t * get_map_resolver(ip_address_t *a)
Definition: control.c:2552
u32 fib_node_index_t
A typedef of a node index.
Definition: fib_types.h:28
#define pool_is_free_index(P, I)
Use free bitmap to query whether given index is free.
Definition: pool.h:211
ip4_address_t map_resolver_ip
Definition: control.c:3460
lisp_gpe_main_t lisp_gpe_main
LISP-GPE global state.
Definition: lisp_gpe.c:27
void * ip_interface_get_first_address(ip_lookup_main_t *lm, u32 sw_if_index, u8 version)
Definition: control.c:61
#define fid_addr_ippref(_a)
Definition: lisp_types.h:112
#define VLIB_CLI_COMMAND(x,...)
Definition: cli.h:154
int vnet_lisp_gpe_add_del_fwd_entry(vnet_lisp_gpe_add_del_fwd_entry_args_t *a, u32 *hw_if_indexp)
Forwarding entry create/remove dispatcher.
u8 vnet_lisp_enable_disable_status(void)
Definition: control.c:2257
vlib_node_registration_t ip6_lookup_node
(constructor) VLIB_REGISTER_NODE (ip6_lookup_node)
Definition: ip6_forward.c:768
static uword send_map_resolver_service(vlib_main_t *vm, vlib_node_runtime_t *rt, vlib_frame_t *f)
Definition: control.c:3858
struct _gid_address_t gid_address_t
u32 fib_table_get_table_id_for_sw_if_index(fib_protocol_t proto, u32 sw_if_index)
Get the Table-ID of the FIB bound to the interface.
Definition: fib_table.c:920
uword unformat_mac_address(unformat_input_t *input, va_list *args)
Definition: lisp_types.c:190
u8 * format_vnet_lisp_gpe_status(u8 *s, va_list *args)
Format LISP-GPE status.
Definition: lisp_gpe.c:282
#define pool_put_index(p, i)
Free pool element with given index.
Definition: pool.h:228
int ip_interface_get_first_ip_address(lisp_cp_main_t *lcm, u32 sw_if_index, u8 version, ip_address_t *result)
Definition: control.c:73
#define ASSERT(truth)
#define fid_addr_type(_a)
Definition: lisp_types.h:114
static lisp_msg_type_e lisp_msg_type(void *b)
unsigned int u32
Definition: types.h:88
u8 * format_ip_address(u8 *s, va_list *args)
Definition: lisp_types.c:127
#define GID_LOOKUP_MISS
u8 * format_unformat_error(u8 *s, va_list *va)
Definition: unformat.c:91
#define vnet_buffer(b)
Definition: buffer.h:333
int vnet_lisp_clear_all_remote_adjacencies(void)
Definition: control.c:1094
ip6_main_t ip6_main
Definition: ip6_forward.c:2655
ip_lookup_main_t lookup_main
Definition: ip6.h:132
#define gid_address_sd_dst(_a)
Definition: lisp_types.h:230
gid_address_t seid
Definition: control.c:29
static void get_src_and_dst_ip(void *hdr, ip_address_t *src, ip_address_t *dst)
Definition: control.c:3143
clib_error_t * lisp_gpe_init(vlib_main_t *vm)
LISP-GPE init function.
Definition: lisp_gpe.c:291
ip_address_t address
Definition: control.h:62
gid_dictionary_t mapping_index_by_gid
Definition: control.h:86
ip_interface_address_t * ip_interface_get_first_interface_address(ip_lookup_main_t *lm, u32 sw_if_index, u8 loop)
Definition: control.c:46
u32 gid_dictionary_sd_lookup(gid_dictionary_t *db, gid_address_t *dst, gid_address_t *src)
static u32 lisp_get_vni_from_buffer_ip(lisp_cp_main_t *lcm, vlib_buffer_t *b, u8 version)
Definition: control.c:3162
locator_set_t * locator_set_pool
Definition: control.h:95
static void clib_mem_free(void *p)
Definition: mem.h:176
static clib_error_t * lisp_show_map_request_mode_command_fn(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
Definition: control.c:1522
static clib_error_t * lisp_show_mreq_itr_rlocs_command_fn(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
Definition: control.c:2758
u8 is_static
Definition: lisp_types.h:303
static void gid_address_sd_to_flat(gid_address_t *dst, gid_address_t *src, fid_address_t *fid)
Definition: control.c:342
u32 ** locator_set_to_eids
Definition: control.h:104
#define LISP_CONTROL_PORT
static u8 * format_eid_entry(u8 *s, va_list *args)
Definition: control.c:1711
u32 vlib_buffer_alloc(vlib_main_t *vm, u32 *buffers, u32 n_buffers)
Allocate buffers into supplied array.
Definition: dpdk_buffer.c:643
gid_address_t rmt_eid
remote eid
Definition: lisp_gpe.h:192
uword unformat_ip_prefix(unformat_input_t *input, va_list *args)
Definition: lisp_types.c:170
static clib_error_t * lisp_add_del_adjacency_command_fn(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
Handler for add/del adjacency CLI.
Definition: control.c:1337
#define clib_fifo_free(f)
Definition: fifo.h:257
static void * clib_mem_alloc(uword size)
Definition: mem.h:109
fwd_entry_t * fwd_entry_pool
Definition: control.h:114
#define VLIB_BUFFER_IS_TRACED
Definition: buffer.h:95
u64 uword
Definition: types.h:112
static void * vlib_add_trace(vlib_main_t *vm, vlib_node_runtime_t *r, vlib_buffer_t *b, u32 n_data_bytes)
Definition: trace_funcs.h:55
#define vec_elt(v, i)
Get vector value at index i.
pending_map_request_t * pending_map_requests_pool
Definition: control.h:120
int vnet_lisp_add_del_locator_set(vnet_lisp_add_del_locator_set_args_t *a, u32 *ls_result)
Definition: control.c:2033
#define gid_address_ip(_a)
Definition: lisp_types.h:218
Definition: defs.h:47
negative_fwd_actions_e action
action for negative mappings
Definition: lisp_gpe.h:186
#define clib_fifo_add1(f, e)
Definition: fifo.h:192
unsigned short u16
Definition: types.h:57
l2input_main_t l2input_main
Definition: l2_input.c:87
#define gid_address_vni(_a)
Definition: lisp_types.h:222
#define hash_create_vec(elts, key_bytes, value_bytes)
Definition: hash.h:644
static u32 lisp_get_vni_from_buffer_eth(lisp_cp_main_t *lcm, vlib_buffer_t *b)
Definition: control.c:3185
map_request_mode_t
Definition: control.h:73
static uword * get_locator_set_index(vnet_lisp_add_del_locator_set_args_t *a, uword *p)
Definition: control.c:1882
void locator_free(locator_t *l)
Definition: lisp_types.c:1480
static void remove_overlapping_sub_prefixes(lisp_cp_main_t *lcm, gid_address_t *eid, u8 is_negative)
This function searches map cache and looks for IP prefixes that are subset of the provided one...
Definition: control.c:937
#define vec_len(v)
Number of elements in vector (rvalue-only, NULL tolerant)
double f64
Definition: types.h:142
static char * lisp_cp_lookup_error_strings[]
Definition: control.c:2792
unsigned char u8
Definition: types.h:56
static int dp_add_del_iface(lisp_cp_main_t *lcm, u32 vni, u8 is_l2, u8 is_add)
Definition: control.c:170
#define hash_foreach_pair(p, v, body)
Iterate over hash pairs.
Definition: hash.h:349
static void dp_del_fwd_entry(lisp_cp_main_t *lcm, u32 src_map_index, u32 dst_map_index)
Definition: control.c:214
static void * vlib_frame_vector_args(vlib_frame_t *f)
Get pointer to frame vector data.
Definition: node_funcs.h:253
int vnet_lisp_add_del_locator(vnet_lisp_add_del_locator_set_args_t *a, locator_set_t *ls, u32 *ls_result)
Definition: control.c:1943
f64 last_update
Definition: control.h:61
locator_pair_t * locator_pairs
vector of locator pairs
Definition: lisp_gpe.h:195
mapping_t * mapping_pool
Definition: control.h:89
static clib_error_t * lisp_show_eid_table_command_fn(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
Definition: control.c:1758
u8 ip_address_max_len(u8 version)
Definition: lisp_types.c:448
uword * locator_set_index_by_name
Definition: control.h:101
static gid_address_t * build_itr_rloc_list(lisp_cp_main_t *lcm, locator_set_t *loc_set)
Definition: control.c:2863
l2_bridge_domain_t * bd_configs
Definition: l2_input.h:69
void gid_address_copy(gid_address_t *dst, gid_address_t *src)
Definition: lisp_types.c:1244
Definition: lisp_types.h:24
gid_address_t eid
Definition: lisp_types.h:292
gid_address_t reid
Definition: control.h:49
gid_address_t address
Definition: lisp_types.h:267
#define hash_get_mem(h, key)
Definition: hash.h:268
void mac_copy(void *dst, void *src)
Definition: lisp_types.c:864
static void get_src_and_dst_eids_from_buffer(lisp_cp_main_t *lcm, vlib_buffer_t *b, gid_address_t *src, gid_address_t *dst)
Definition: control.c:3210
u32 lisp_msg_parse_eid_rec(vlib_buffer_t *b, gid_address_t *eid)
static clib_error_t * lisp_show_pitr_command_fn(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
Definition: control.c:1658
static void * clib_mem_alloc_aligned(uword size, uword align)
Definition: mem.h:117
static uword unformat_check_input(unformat_input_t *i)
Definition: format.h:169
gid_address_t dst
Definition: control.h:30
#define VLIB_REGISTER_NODE(x,...)
Definition: node.h:143
u8 * format(u8 *s, const char *fmt,...)
Definition: format.c:418
int vnet_lisp_add_del_map_resolver(vnet_lisp_add_del_map_resolver_args_t *a)
Definition: control.c:2568
ip4_main_t ip4_main
Global ip4 main structure.
Definition: ip4_forward.c:1060
void process_map_request(vlib_main_t *vm, lisp_cp_main_t *lcm, vlib_buffer_t *b)
Definition: control.c:3554
ip_address_t rmt_loc
Definition: lisp_types.h:314
u8 data[0]
Packet data.
Definition: buffer.h:154
#define vec_foreach(var, vec)
Vector iterator.
void * process_map_reply(void *arg)
Definition: control.c:3476
vhost_vring_addr_t addr
Definition: vhost-user.h:81
void udp_register_dst_port(vlib_main_t *vm, udp_dst_port_t dst_port, u32 node_index, u8 is_ip4)
Definition: udp_local.c:458
gid_address_t dst_eid
Definition: control.c:2814
#define clib_error_return(e, args...)
Definition: error.h:111
u8 ip_version_and_header_length
Definition: ip4_packet.h:108
struct _unformat_input_t unformat_input_t
static void * ip_interface_address_get_address(ip_lookup_main_t *lm, ip_interface_address_t *a)
Definition: lookup.h:431
#define MREP_NONCE(h_)
#define pool_foreach_index(i, v, body)
Iterate pool by index.
Definition: pool.h:390
vlib_frame_t * vlib_get_frame_to_node(vlib_main_t *vm, u32 to_node_index)
Definition: main.c:185
Definition: lisp_types.h:25
#define CLIB_CACHE_LINE_BYTES
Definition: cache.h:67
u32 flags
buffer flags: VLIB_BUFFER_IS_TRACED: trace this buffer.
Definition: buffer.h:85
void build_src_dst(gid_address_t *sd, gid_address_t *src, gid_address_t *dst)
Definition: lisp_types.c:1487
static uword lisp_cp_lookup_ip6(vlib_main_t *vm, vlib_node_runtime_t *node, vlib_frame_t *from_frame)
Definition: control.c:3362
gid_address_t lcl_eid
local eid
Definition: lisp_gpe.h:189
unformat_function_t unformat_line_input
Definition: format.h:281
static u8 * format_lisp_status(u8 *s, va_list *args)
Definition: control.c:2264
u32 mreq_itr_rlocs
Definition: control.h:135
u32 lisp_gpe_tenant_l3_iface_add_or_lock(u32 vni, u32 table_id)
Add/create and lock a new or find and lock the existing L3 interface for the tenant.
static vlib_buffer_t * vlib_get_buffer(vlib_main_t *vm, u32 buffer_index)
Translate buffer index into buffer pointer.
Definition: buffer_funcs.h:69
u32 * locator_indices
Definition: lisp_types.h:286
#define send_encapsulated_map_request(lcm, seid, deid, smr)
Definition: control.c:2989
vnet_main_t * vnet_main
Definition: control.h:161
uword key
Definition: hash.h:161
static clib_error_t * lisp_add_del_locator_set_command_fn(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
Definition: control.c:2349
LISP-GPE definitions.
u8 * format_lisp_cp_lookup_trace(u8 *s, va_list *args)
Definition: control.c:2819
ip4_main_t * im4
Definition: control.h:158
gid_address_t leid
Definition: control.h:40
Definition: defs.h:46
lisp_msg_type_e
static clib_error_t * lisp_add_del_remote_mapping_command_fn(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
Handler for add/del remote mapping CLI.
Definition: control.c:1210
#define ip_prefix_addr(_a)
Definition: lisp_types.h:58
ip6_address_t dst_address
Definition: ip6_packet.h:300
#define resend_encapsulated_map_request(lcm, seid, deid, smr)
Definition: control.c:2992
#define PENDING_MREQ_EXPIRATION_TIME
Definition: control.h:24
lisp_cp_input_error_t
Definition: control.c:3443
static uword lisp_cp_lookup_inline(vlib_main_t *vm, vlib_node_runtime_t *node, vlib_frame_t *from_frame, int overlay)
Definition: control.c:3260
int ip_address_cmp(const ip_address_t *ip1, const ip_address_t *ip2)
Definition: lisp_types.c:682