FD.io VPP  v16.06
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 <vnet/lisp-cp/control.h>
17 #include <vnet/lisp-cp/packets.h>
19 #include <vnet/lisp-gpe/lisp_gpe.h>
20 
21 static void
22 add_fwd_entry (lisp_cp_main_t* lcm, u32 src_map_index, u32 dst_map_index);
23 
24 static void
25 del_fwd_entry (lisp_cp_main_t * lcm, u32 src_map_index, u32 dst_map_index);
26 
27 static u8
28 compare_locators (lisp_cp_main_t *lcm, u32 * old_ls_indexes,
29  locator_t * new_locators);
30 
31 /* Stores mapping in map-cache. It does NOT program data plane forwarding for
32  * remote/learned mappings. */
33 int
35  u32 * map_index_result)
36 {
38  u32 mi, * map_indexp, map_index, i;
39  mapping_t * m;
40  u32 ** eid_indexes;
41 
43  if (a->is_add)
44  {
45  /* TODO check if overwriting and take appropriate actions */
46  if (mi != GID_LOOKUP_MISS)
47  {
48  clib_warning("eid %U found in the eid-table", format_ip_address,
49  &a->deid);
50  return VNET_API_ERROR_VALUE_EXIST;
51  }
52 
53  pool_get(lcm->mapping_pool, m);
54  m->eid = a->deid;
56  m->ttl = a->ttl;
57  m->local = a->local;
58 
59  map_index = m - lcm->mapping_pool;
60  gid_dictionary_add_del (&lcm->mapping_index_by_gid, &a->deid, map_index,
61  1);
62 
64  {
65  clib_warning("Locator set with index %d doesn't exist",
67  return VNET_API_ERROR_INVALID_VALUE;
68  }
69 
70  /* add eid to list of eids supported by locator-set */
72  eid_indexes = vec_elt_at_index(lcm->locator_set_to_eids,
74  vec_add1(eid_indexes[0], map_index);
75 
76  if (a->local)
77  {
78  /* mark as local */
79  vec_add1(lcm->local_mappings_indexes, map_index);
80  }
81  map_index_result[0] = map_index;
82  }
83  else
84  {
85  if (mi == GID_LOOKUP_MISS)
86  {
87  clib_warning("eid %U not found in the eid-table", format_ip_address,
88  &a->deid);
89  return VNET_API_ERROR_INVALID_VALUE;
90  }
91 
92  /* clear locator-set to eids binding */
93  eid_indexes = vec_elt_at_index(lcm->locator_set_to_eids,
95  for (i = 0; i < vec_len(eid_indexes[0]); i++)
96  {
97  map_indexp = vec_elt_at_index(eid_indexes[0], i);
98  if (map_indexp[0] == mi)
99  break;
100  }
101  vec_del1(eid_indexes[0], i);
102 
103  /* remove local mark if needed */
104  m = pool_elt_at_index(lcm->mapping_pool, mi);
105  if (m->local)
106  {
107  u32 k, * lm_indexp;
108  for (k = 0; k < vec_len(lcm->local_mappings_indexes); k++)
109  {
110  lm_indexp = vec_elt_at_index(lcm->local_mappings_indexes, k);
111  if (lm_indexp[0] == mi)
112  break;
113  }
115  }
116  else
117  {
118  /* remove tunnel ??? */
119  }
120 
121  /* remove mapping from dictionary */
123  pool_put_index (lcm->mapping_pool, mi);
124  }
125 
126  return 0;
127 }
128 
129 /* Stores mapping in map-cache and programs data plane for local mappings. */
130 int
132  u32 * map_index_result)
133 {
134  uword * table_id, * refc;
135  u32 rv, vni;
136  vnet_lisp_gpe_add_del_iface_args_t _ai, *ai = &_ai;
138 
139  vni = gid_address_vni(&a->deid);
140 
141  /* store/remove mapping from map-cache */
142  rv = vnet_lisp_add_del_mapping (a, map_index_result);
143  if (rv)
144  return rv;
145 
146  table_id = hash_get(lcm->table_id_by_vni, vni);
147 
148  if (!table_id)
149  {
150  clib_warning ("vni %d not associated to a vrf!", vni);
151  return VNET_API_ERROR_INVALID_VALUE;
152  }
153 
154  refc = hash_get(lcm->dp_if_refcount_by_vni, vni);
155 
156  /* enable/disable data-plane interface */
157  if (a->is_add)
158  {
159  /* create interface or update refcount */
160  if (!refc)
161  {
162  ai->is_add = 1;
163  ai->vni = vni;
164  ai->table_id = table_id[0];
166 
167  /* counts the number of eids in a vni that use the interface */
168  hash_set(lcm->dp_if_refcount_by_vni, vni, 1);
169  }
170  else
171  {
172  refc[0]++;
173  }
174  }
175  else
176  {
177  /* since this is a remove for an existing eid, the iface should exist */
178  ASSERT(refc != 0);
179  refc[0]--;
180 
181  /* remove iface if needed */
182  if (refc[0] == 0)
183  {
184  ai->is_add = 0;
185  ai->vni = vni;
186  ai->table_id = table_id[0];
188  }
189  }
190 
191  return rv;
192 }
193 
194 static clib_error_t *
196  vlib_cli_command_t * cmd)
197 {
199  unformat_input_t _line_input, * line_input = &_line_input;
200  u8 is_add = 1;
201  gid_address_t eid;
202  ip_prefix_t * prefp = &gid_address_ippref(&eid);
203  gid_address_t * eids = 0;
204  clib_error_t * error = 0;
205  u8 * locator_set_name;
206  u32 locator_set_index = 0, map_index = 0;
207  uword * p;
209 
211 
212  /* Get a line of input. */
213  if (! unformat_user (input, unformat_line_input, line_input))
214  return 0;
215 
216  while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
217  {
218  if (unformat (line_input, "add"))
219  is_add = 1;
220  else if (unformat (line_input, "del"))
221  is_add = 0;
222  else if (unformat (line_input, "eid %U", unformat_ip_prefix, prefp))
223  {
224  vec_add1(eids, eid);
225  }
226  else if (unformat (line_input, "locator-set %_%v%_", &locator_set_name))
227  {
228  p = hash_get_mem(lcm->locator_set_index_by_name, locator_set_name);
229  if (!p)
230  {
231  error = clib_error_return(0, "locator-set %s doesn't exist",
232  locator_set_name);
233  goto done;
234  }
235  locator_set_index = p[0];
236  }
237  else
238  {
239  error = unformat_parse_error(line_input);
240  goto done;
241  }
242  }
243 
244  /* XXX treat batch configuration */
245  a->deid = eid;
246  a->is_add = is_add;
247  a->locator_set_index = locator_set_index;
248  a->local = 1;
249 
250  vnet_lisp_add_del_local_mapping (a, &map_index);
251  done:
252  vec_free(eids);
253  return error;
254 }
255 
256 VLIB_CLI_COMMAND (lisp_add_del_local_eid_command) = {
257  .path = "lisp eid-table",
258  .short_help = "lisp eid-table add/del eid <eid> locator-set <locator-set>",
260 };
261 
262 /**
263  * Adds/removes/updates static remote mapping.
264  *
265  * This function also modifies forwarding entries if needed.
266  *
267  * @param deid destination EID
268  * @param seid source EID
269  * @param rlocs vector of remote locators
270  * @param action action for negative map-reply
271  * @param is_add add mapping if non-zero, delete otherwise
272  * @return return code
273  */
274 int
276  ip_address_t * rlocs, u8 action, u8 is_add)
277 {
278  vnet_lisp_add_del_mapping_args_t _dm_args, * dm_args = &_dm_args;
279  vnet_lisp_add_del_mapping_args_t _sm_args, * sm_args = &_sm_args;
280  vnet_lisp_add_del_locator_set_args_t _ls, * ls = &_ls;
282  u32 mi, ls_index = 0, dst_map_index, src_map_index;
283  locator_t loc;
284  ip_address_t * dl;
285  int rc = -1;
286 
287  memset (sm_args, 0, sizeof (sm_args[0]));
288  memset (dm_args, 0, sizeof (dm_args[0]));
289  memset (ls, 0, sizeof (ls[0]));
290 
291  /* prepare remote locator set */
292  vec_foreach (dl, rlocs)
293  {
294  memset (&loc, 0, sizeof (loc));
295  gid_address_ip (&loc.address) = dl[0];
296  vec_add1 (ls->locators, loc);
297  }
298  src_map_index = gid_dictionary_lookup (&lcm->mapping_index_by_gid, seid);
299 
300  mi = gid_dictionary_lookup (&lcm->mapping_index_by_gid, deid);
301  /* new mapping */
302  if ((u32)~0 == mi)
303  {
304  if ((u32)~0 == src_map_index)
305  {
306  clib_warning ("seid %U not found!", format_gid_address, seid);
307  goto done;
308  }
309 
310  if (!is_add)
311  {
312  clib_warning ("deid %U marked for removal but not "
313  "found!", format_gid_address, deid);
314  goto done;
315  }
316 
317  ls->is_add = 1;
318  ls->index = ~0;
319  vnet_lisp_add_del_locator_set (ls, &ls_index);
320 
321  /* add mapping */
322  gid_address_copy (&dm_args->deid, deid);
323  dm_args->is_add = 1;
324  dm_args->action = action;
325  dm_args->locator_set_index = ls_index;
326  vnet_lisp_add_del_mapping (dm_args, &dst_map_index);
327 
328  /* add fwd tunnel */
329  add_fwd_entry (lcm, src_map_index, dst_map_index);
330  }
331  else
332  {
333  /* delete mapping */
334  if (!is_add)
335  {
336  /* delete forwarding entry */
337  del_fwd_entry (lcm, 0, mi);
338  dm_args->is_add = 0;
339  gid_address_copy (&dm_args->deid, deid);
340  mapping_t * map = pool_elt_at_index (lcm->mapping_pool, mi);
341  dm_args->locator_set_index = map->locator_set_index;
342 
343  /* delete mapping associated to fwd entry */
344  vnet_lisp_add_del_mapping (dm_args, 0);
345 
346  ls->is_add = 0;
347  ls->index = map->locator_set_index;
348  /* delete locator set */
350  }
351  /* update existing locator set */
352  else
353  {
354  if ((u32)~0 == src_map_index)
355  {
356  clib_warning ("seid %U not found!", format_gid_address, seid);
357  goto done;
358  }
359 
360  mapping_t * old_map;
361  locator_set_t * old_ls;
362  old_map = pool_elt_at_index (lcm->mapping_pool, mi);
363 
364  /* update mapping attributes */
365  old_map->action = action;
366 
367  old_ls = pool_elt_at_index(lcm->locator_set_pool,
368  old_map->locator_set_index);
369  if (compare_locators (lcm, old_ls->locator_indices,
370  ls->locators))
371  {
372  /* set locator-set index to overwrite */
373  ls->is_add = 1;
374  ls->index = old_map->locator_set_index;
376  add_fwd_entry (lcm, src_map_index, mi);
377  }
378  }
379  }
380  /* success */
381  rc = 0;
382 done:
383  vec_free (ls->locators);
384  return rc;
385 }
386 
387 /**
388  * Handler for add/del remote mapping CLI.
389  *
390  * @param vm vlib context
391  * @param input input from user
392  * @param cmd cmd
393  * @return pointer to clib error structure
394  */
395 static clib_error_t *
397  unformat_input_t * input,
398  vlib_cli_command_t * cmd)
399 {
400  clib_error_t * error = 0;
401  unformat_input_t _line_input, * line_input = &_line_input;
402  u8 is_add = 1;
403  ip_address_t rloc, * rlocs = 0;
404  ip_prefix_t * deid_ippref, * seid_ippref;
405  gid_address_t seid, deid;
406  u8 deid_set = 0, seid_set = 0;
407  u32 vni, action = ~0;
408 
409  /* Get a line of input. */
410  if (! unformat_user (input, unformat_line_input, line_input))
411  return 0;
412 
413  memset (&deid, 0, sizeof (deid));
414  memset (&seid, 0, sizeof (seid));
415 
416  seid_ippref = &gid_address_ippref(&seid);
417  deid_ippref = &gid_address_ippref(&deid);
418 
421 
422  while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
423  {
424  if (unformat (line_input, "del"))
425  is_add = 0;
426  if (unformat (line_input, "add"))
427  ;
428  else if (unformat (line_input, "deid %U",
429  unformat_ip_prefix, deid_ippref))
430  {
431  deid_set = 1;
432  }
433  else if (unformat (line_input, "vni %u", &vni))
434  {
435  gid_address_set_vni (&seid, vni);
436  gid_address_set_vni (&deid, vni);
437  }
438  else if (unformat (line_input, "seid %U",
439  unformat_ip_prefix, seid_ippref))
440  seid_set = 1;
441  else if (unformat (line_input, "rloc %U", unformat_ip_address, &rloc))
442  vec_add1 (rlocs, rloc);
443  else if (unformat (line_input, "action %d", &action))
444  ;
445  else
446  {
447  clib_warning ("parse error");
448  goto done;
449  }
450  }
451 
452  if (is_add && (!deid_set || !seid_set))
453  {
454  clib_warning ("missing paramete(s)!");
455  goto done;
456  }
457 
458  if (!is_add && !deid_set)
459  {
460  clib_warning ("missing deid!");
461  goto done;
462  }
463 
464  if (is_add
465  && (ip_prefix_version (deid_ippref)
466  != ip_prefix_version (seid_ippref)))
467  {
468  clib_warning ("source and destination EIDs are not"
469  " in the same IP family!");
470  goto done;
471  }
472 
473  if (is_add && (~0 == action)
474  && 0 == vec_len (rlocs))
475  {
476  clib_warning ("no action set for negative map-reply!");
477  goto done;
478  }
479 
480  int rv = vnet_lisp_add_del_remote_mapping (&deid, &seid, rlocs,
481  action, is_add);
482  if (rv)
483  clib_warning ("failed to %s remote mapping!",
484  is_add ? "add" : "delete");
485 
486 done:
487  unformat_free (line_input);
488  return error;
489 }
490 
491 VLIB_CLI_COMMAND (lisp_add_del_remote_mapping_command) = {
492  .path = "lisp remote-mapping",
493  .short_help = "lisp remote-mapping add|del vni <vni> deid <dest-eid> "
494  "seid <src-eid> rloc <dst-locator> [rloc <dst-locator> ... ]",
496 };
497 
498 static clib_error_t *
500  unformat_input_t * input,
501  vlib_cli_command_t * cmd)
502 {
504  mapping_t * mapit;
505 
506  vlib_cli_output (vm, "%=20s%=16s", "EID", "Locator");
507  pool_foreach (mapit, lcm->mapping_pool,
508  ({
509  u8 * msg = 0;
510  locator_set_t * ls = pool_elt_at_index (lcm->locator_set_pool,
511  mapit->locator_set_index);
512  vlib_cli_output (vm, "%-16U%16v", format_gid_address, &mapit->eid,
513  ls->name);
514  vec_free (msg);
515  }));
516 
517  return 0;
518 }
519 
520 VLIB_CLI_COMMAND (lisp_cp_show_local_eid_table_command) = {
521  .path = "show lisp eid-table",
522  .short_help = "Shows local EID table",
524 };
525 
526 /* cleans locator to locator-set data and removes locators not part of
527  * any locator-set */
528 static void
530 {
531  u32 i, j, *loc_indexp, *ls_indexp, **ls_indexes;
533  for (i = 0; i < vec_len(ls->locator_indices); i++)
534  {
535  loc_indexp = vec_elt_at_index(ls->locator_indices, i);
536  ls_indexes = vec_elt_at_index(lcm->locator_to_locator_sets,
537  loc_indexp[0]);
538  for (j = 0; j < vec_len(ls_indexes[0]); j++)
539  {
540  ls_indexp = vec_elt_at_index(ls_indexes[0], j);
541  if (ls_indexp[0] == lsi)
542  break;
543  }
544 
545  /* delete index for removed locator-set*/
546  vec_del1(ls_indexes[0], j);
547 
548  /* delete locator if it's part of no locator-set */
549  if (vec_len (ls_indexes[0]) == 0)
550  pool_put_index(lcm->locator_pool, loc_indexp[0]);
551  }
552 }
553 
554 static inline
556  uword * p)
557 {
559 
560  ASSERT(a != NULL);
561  ASSERT(p != NULL);
562 
563  /* find locator-set */
564  if (a->local)
565  {
567  }
568  else
569  {
570  *p = a->index;
571  }
572 
573  return p;
574 }
575 
576 static inline
578  locator_t * loc)
579 {
580  locator_t * itloc;
581  u32 * locit;
582 
583  ASSERT(ls != NULL);
584  ASSERT(loc != NULL);
585 
586  vec_foreach(locit, ls->locator_indices)
587  {
588  itloc = pool_elt_at_index(lcm->locator_pool, locit[0]);
589  if (itloc->sw_if_index == loc->sw_if_index ||
590  !gid_address_cmp(&itloc->address, &loc->address))
591  {
592  clib_warning("Duplicate locator");
593  return VNET_API_ERROR_VALUE_EXIST;
594  }
595  }
596 
597  return 0;
598 }
599 
600 static inline
602  u32 ls_index, u32 loc_id)
603 {
605  u32 ** ls_indexes = NULL;
606 
607  ASSERT(ls != NULL);
608  ASSERT(locit != NULL);
609 
610  ls_indexes = vec_elt_at_index(lcm->locator_to_locator_sets,
611  locit[0]);
612  pool_put_index(lcm->locator_pool, locit[0]);
613  vec_del1(ls->locator_indices, loc_id);
614  vec_del1(ls_indexes[0], ls_index);
615 }
616 
617 int
619  locator_set_t * ls, u32 * ls_result)
620 {
622  locator_t * loc = NULL, *itloc = NULL;
623  uword _p = (u32)~0, * p = &_p;
624  u32 loc_index = ~0, ls_index = ~0, * locit = NULL, ** ls_indexes = NULL;
625  u32 loc_id = ~0;
626  int ret = 0;
627 
628  ASSERT(a != NULL);
629 
630  p = get_locator_set_index(a, p);
631  if (!p)
632  {
633  clib_warning("locator-set %v doesn't exist", a->name);
634  return VNET_API_ERROR_INVALID_ARGUMENT;
635  }
636 
637  if (ls == 0)
638  {
639  ls = pool_elt_at_index(lcm->locator_set_pool, p[0]);
640  if (!ls)
641  {
642  clib_warning("locator-set %d to be overwritten doesn't exist!",
643  p[0]);
644  return VNET_API_ERROR_INVALID_ARGUMENT;
645  }
646  }
647 
648  if (a->is_add)
649  {
650 
651  if (ls_result)
652  ls_result[0] = p[0];
653 
654  /* allocate locators */
655  vec_foreach (itloc, a->locators)
656  {
657  ret = is_locator_in_locator_set(lcm, ls, itloc);
658  if (0 != ret)
659  {
660  return ret;
661  }
662 
663  pool_get(lcm->locator_pool, loc);
664  loc[0] = itloc[0];
665  loc_index = loc - lcm->locator_pool;
666 
667  vec_add1(ls->locator_indices, loc_index);
668 
669  vec_validate (lcm->locator_to_locator_sets, loc_index);
670  ls_indexes = vec_elt_at_index(lcm->locator_to_locator_sets,
671  loc_index);
672  vec_add1(ls_indexes[0], ls_index);
673  }
674  }
675  else
676  {
677  ls_index = p[0];
678 
679  itloc = a->locators;
680  loc_id = 0;
681  vec_foreach (locit, ls->locator_indices)
682  {
683  loc = pool_elt_at_index(lcm->locator_pool, locit[0]);
684 
685  if (loc->local && loc->sw_if_index == itloc->sw_if_index)
686  {
688  ls_index, loc_id);
689  }
690  if (0 == loc->local &&
691  !gid_address_cmp(&loc->address, &itloc->address))
692  {
694  ls_index, loc_id);
695  }
696 
697  loc_id++;
698  }
699  }
700 
701  return 0;
702 }
703 
704 int
706  u32 * ls_result)
707 {
709  locator_set_t * ls;
710  uword _p = (u32)~0, * p = &_p;
711  u32 ls_index;
712  u32 ** eid_indexes;
713  int ret = 0;
714 
715  if (a->is_add)
716  {
717  p = get_locator_set_index(a, p);
718 
719  /* overwrite */
720  if (p && p[0] != (u32)~0)
721  {
722  ls = pool_elt_at_index(lcm->locator_set_pool, p[0]);
723  if (!ls)
724  {
725  clib_warning("locator-set %d to be overwritten doesn't exist!",
726  p[0]);
727  return -1;
728  }
729 
730  /* clean locator to locator-set vectors and remove locators if
731  * they're not part of another locator-set */
732  clean_locator_to_locator_set (lcm, p[0]);
733 
734  /* remove locator indices from locator set */
736 
737  ls_index = p[0];
738 
739  if (ls_result)
740  ls_result[0] = p[0];
741  }
742  /* new locator-set */
743  else
744  {
745  pool_get(lcm->locator_set_pool, ls);
746  memset(ls, 0, sizeof(*ls));
747  ls_index = ls - lcm->locator_set_pool;
748 
749  if (a->local)
750  {
751  ls->name = vec_dup(a->name);
752 
753  if (!lcm->locator_set_index_by_name)
755  /* size */0, sizeof(ls->name[0]), sizeof(uword));
756  hash_set_mem(lcm->locator_set_index_by_name, ls->name, ls_index);
757 
758  /* mark as local locator-set */
759  vec_add1(lcm->local_locator_set_indexes, ls_index);
760  }
761  ls->local = a->local;
762  if (ls_result)
763  ls_result[0] = ls_index;
764  }
765 
766  ret = vnet_lisp_add_del_locator(a, ls, NULL);
767  if (0 != ret)
768  {
769  return ret;
770  }
771  }
772  else
773  {
774  p = get_locator_set_index(a, p);
775  if (!p)
776  {
777  clib_warning("locator-set %v doesn't exists", a->name);
778  return -1;
779  }
780 
781  ls = pool_elt_at_index(lcm->locator_set_pool, p[0]);
782  if (!ls)
783  {
784  clib_warning("locator-set with index %d doesn't exists", p[0]);
785  return -1;
786  }
787 
788  if (vec_len(lcm->locator_set_to_eids) != 0)
789  {
790  eid_indexes = vec_elt_at_index(lcm->locator_set_to_eids, p[0]);
791  if (vec_len(eid_indexes[0]) != 0)
792  {
793  clib_warning ("Can't delete a locator that supports a mapping!");
794  return -1;
795  }
796  }
797 
798  /* clean locator to locator-sets data */
799  clean_locator_to_locator_set (lcm, p[0]);
800 
801  if (ls->local)
802  {
803  u32 it, lsi;
804 
806  {
807  lsi = vec_elt(lcm->local_locator_set_indexes, it);
808  if (lsi == p[0])
809  {
811  break;
812  }
813  }
815  }
816  vec_free(ls->name);
818  pool_put(lcm->locator_set_pool, ls);
819  }
820  return 0;
821 }
822 
823 clib_error_t *
825 {
826  vnet_lisp_gpe_add_del_iface_args_t _ai, * ai= &_ai;
827  uword * table_id, * refc;
828  u32 i;
829  clib_error_t * error = 0;
832 
833  a->is_en = is_enabled;
834  error = vnet_lisp_gpe_enable_disable (a);
835  if (error)
836  {
837  return clib_error_return (0, "failed to %s data-plane!",
838  a->is_en ? "enable" : "disable");
839  }
840 
841  if (is_enabled)
842  {
843  /* enable all ifaces */
844  for (i = 0; i < vec_len (lcm->local_mappings_indexes); i++)
845  {
846  mapping_t * m = vec_elt_at_index (lcm->mapping_pool, i);
847  ai->is_add = 1;
848  ai->vni = gid_address_vni (&m->eid);
849 
850  refc = hash_get (lcm->dp_if_refcount_by_vni, ai->vni);
851  if (!refc)
852  {
853  table_id = hash_get (lcm->table_id_by_vni, ai->vni);
854  if (table_id)
855  {
856  ai->table_id = table_id[0];
857  /* enables interface and adds defaults */
859  }
860  else
861  return clib_error_return (0, "no table_id found for vni %u!",
862  ai->vni);
863 
864  hash_set (lcm->dp_if_refcount_by_vni, ai->vni, 1);
865  }
866  else
867  {
868  refc[0]++;
869  }
870  }
871  }
872  else
873  {
874  /* clear refcount table */
877  pool_free (lcm->fwd_entry_pool);
878  }
879 
880  /* update global flag */
881  lcm->is_enabled = is_enabled;
882 
883  return 0;
884 }
885 
886 static clib_error_t *
888  vlib_cli_command_t * cmd)
889 {
890  unformat_input_t _line_input, * line_input = &_line_input;
891  u8 is_enabled = 0;
892  u8 is_set = 0;
893 
894  /* Get a line of input. */
895  if (! unformat_user (input, unformat_line_input, line_input))
896  return 0;
897 
898  while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
899  {
900  if (unformat (line_input, "enable"))
901  {
902  is_set = 1;
903  is_enabled = 1;
904  }
905  else if (unformat (line_input, "disable"))
906  is_set = 1;
907  else
908  {
909  return clib_error_return (0, "parse error: '%U'",
910  format_unformat_error, line_input);
911  }
912  }
913 
914  if (!is_set)
915  return clib_error_return (0, "state not set");
916 
917  return vnet_lisp_enable_disable (is_enabled);
918 }
919 
920 VLIB_CLI_COMMAND (lisp_cp_enable_disable_command) = {
921  .path = "lisp",
922  .short_help = "lisp [enable|disable]",
923  .function = lisp_enable_disable_command_fn,
924 };
925 
926 u8
928 {
930  return lcm->is_enabled;
931 }
932 
933 static u8 *
934 format_lisp_status (u8 * s, va_list * args)
935 {
937  return format (s, "%s", lcm->is_enabled ? "enabled" : "disabled");
938 }
939 
940 static clib_error_t *
942  vlib_cli_command_t * cmd)
943 {
944  u8 * msg = 0;
945  msg = format (msg, "feature: %U\ngpe: %U\n",
947  vlib_cli_output (vm, "%v", msg);
948  vec_free (msg);
949  return 0;
950 }
951 
952 VLIB_CLI_COMMAND (lisp_show_status_command) = {
953  .path = "show lisp status",
954  .short_help = "show lisp status",
955  .function = lisp_show_status_command_fn,
956 };
957 static clib_error_t *
959  vlib_cli_command_t * cmd)
960 {
962  vnet_main_t * vnm = lgm->vnet_main;
963  unformat_input_t _line_input, * line_input = &_line_input;
964  u8 is_add = 1;
965  clib_error_t * error = 0;
966  u8 * locator_set_name = 0;
967  locator_t locator, * locators = 0;
969  u32 ls_index = 0;
970 
971  memset(&locator, 0, sizeof(locator));
972  memset(a, 0, sizeof(a[0]));
973 
974  /* Get a line of input. */
975  if (! unformat_user (input, unformat_line_input, line_input))
976  return 0;
977 
978  while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
979  {
980  if (unformat (line_input, "add %_%v%_", &locator_set_name))
981  is_add = 1;
982  else if (unformat (line_input, "del %_%v%_", &locator_set_name))
983  is_add = 0;
984  else if (unformat (line_input, "iface %U p %d w %d",
986  &locator.priority, &locator.weight))
987  {
988  locator.local = 1;
989  vec_add1(locators, locator);
990  }
991  else
992  {
993  error = unformat_parse_error(line_input);
994  goto done;
995  }
996  }
997 
998  a->name = locator_set_name;
999  a->locators = locators;
1000  a->is_add = is_add;
1001  a->local = 1;
1002 
1003  vnet_lisp_add_del_locator_set(a, &ls_index);
1004 
1005  done:
1006  vec_free(locators);
1007  vec_free(locator_set_name);
1008  return error;
1009 }
1010 
1011 VLIB_CLI_COMMAND (lisp_cp_add_del_locator_set_command) = {
1012  .path = "lisp locator-set",
1013  .short_help = "lisp locator-set add/del <name> iface <iface-name> "
1014  "p <priority> w <weight>",
1016 };
1017 
1018 static clib_error_t *
1020  unformat_input_t * input,
1021  vlib_cli_command_t * cmd)
1022 {
1023  locator_set_t * lsit;
1024  locator_t * loc;
1025  u32 * locit;
1027 
1028  vlib_cli_output (vm, "%=20s%=16s%=16s%=16s", "Locator-set", "Locator",
1029  "Priority", "Weight");
1030  pool_foreach (lsit, lcm->locator_set_pool,
1031  ({
1032  u8 * msg = 0;
1033  msg = format (msg, "%-16v", lsit->name);
1034  vec_foreach (locit, lsit->locator_indices)
1035  {
1036  loc = pool_elt_at_index (lcm->locator_pool, locit[0]);
1037  if (loc->local)
1038  msg = format (msg, "%16d%16d%16d", loc->sw_if_index, loc->priority,
1039  loc->weight);
1040  else
1041  msg = format (msg, "%16U%16d%16d", format_gid_address, &loc->address,
1042  loc->priority, loc->weight);
1043  }
1044  vlib_cli_output (vm, "%v", msg);
1045  vec_free (msg);
1046  }));
1047  return 0;
1048 }
1049 
1050 VLIB_CLI_COMMAND (lisp_cp_show_locator_sets_command) = {
1051  .path = "show lisp locator-set",
1052  .short_help = "Shows locator-sets",
1054 };
1055 
1056 int
1058 {
1060  ip_address_t * addr;
1061  u32 i;
1062 
1063  if (a->is_add)
1064  {
1065  vec_foreach(addr, lcm->map_resolvers)
1066  {
1067  if (!ip_address_cmp (addr, &a->address))
1068  {
1069  clib_warning("map-resolver %U already exists!", format_ip_address,
1070  &a->address);
1071  return -1;
1072  }
1073  }
1074  vec_add1(lcm->map_resolvers, a->address);
1075  }
1076  else
1077  {
1078  for (i = 0; i < vec_len(lcm->map_resolvers); i++)
1079  {
1080  addr = vec_elt_at_index(lcm->map_resolvers, i);
1081  if (!ip_address_cmp (addr, &a->address))
1082  {
1083  vec_delete(lcm->map_resolvers, 1, i);
1084  break;
1085  }
1086  }
1087  }
1088  return 0;
1089 }
1090 
1091 static clib_error_t *
1093  unformat_input_t * input,
1094  vlib_cli_command_t * cmd)
1095 {
1096  unformat_input_t _line_input, * line_input = &_line_input;
1097  u8 is_add = 1;
1098  ip_address_t ip_addr;
1099  clib_error_t * error = 0;
1101 
1102  /* Get a line of input. */
1103  if (! unformat_user (input, unformat_line_input, line_input))
1104  return 0;
1105 
1106  while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
1107  {
1108  if (unformat (line_input, "add"))
1109  is_add = 1;
1110  else if (unformat (line_input, "del"))
1111  is_add = 0;
1112  else if (unformat (line_input, "%U", unformat_ip_address, &ip_addr))
1113  ;
1114  else
1115  {
1116  error = unformat_parse_error(line_input);
1117  goto done;
1118  }
1119  }
1120  a->is_add = is_add;
1121  a->address = ip_addr;
1123 
1124  done:
1125  return error;
1126 }
1127 
1128 VLIB_CLI_COMMAND (lisp_add_del_map_resolver_command) = {
1129  .path = "lisp map-resolver",
1130  .short_help = "lisp map-resolver add/del <ip_address>",
1132 };
1133 
1134 /* Statistics (not really errors) */
1135 #define foreach_lisp_cp_lookup_error \
1136 _(DROP, "drop") \
1137 _(MAP_REQUESTS_SENT, "map-request sent")
1138 
1139 static char * lisp_cp_lookup_error_strings[] = {
1140 #define _(sym,string) string,
1142 #undef _
1143 };
1144 
1145 typedef enum
1146 {
1147 #define _(sym,str) LISP_CP_LOOKUP_ERROR_##sym,
1149 #undef _
1152 
1153 typedef enum
1154 {
1160 
1161 typedef struct
1162 {
1164  ip_address_t map_resolver_ip;
1166 
1167 u8 *
1168 format_lisp_cp_lookup_trace (u8 * s, va_list * args)
1169 {
1170  CLIB_UNUSED (vlib_main_t * vm) = va_arg (*args, vlib_main_t *);
1171  CLIB_UNUSED (vlib_node_t * node) = va_arg (*args, vlib_node_t *);
1172  lisp_cp_lookup_trace_t * t = va_arg (*args, lisp_cp_lookup_trace_t *);
1173 
1174  s = format (s, "LISP-CP-LOOKUP: map-resolver: %U destination eid %U",
1176  &t->dst_eid);
1177  return s;
1178 }
1179 
1180 static u32
1182  ip_address_t * dst)
1183 {
1184  if (ip_addr_version (dst) == IP4)
1185  return ip4_fib_lookup_with_table (lcm->im4, fib_index, &ip_addr_v4(dst),
1186  0);
1187  else
1188  return ip6_fib_lookup_with_table (lcm->im6, fib_index, &ip_addr_v6(dst));
1189 }
1190 
1191 void
1192 get_mr_and_local_iface_ip (lisp_cp_main_t *lcm, ip_address_t * mr_ip,
1193  ip_address_t * sloc)
1194 {
1195  u32 adj_index;
1196  ip_adjacency_t * adj;
1197  ip_interface_address_t * ia = 0;
1198  ip_lookup_main_t * lm;
1199  ip4_address_t * l4 = 0;
1200  ip6_address_t * l6 = 0;
1201  ip_address_t * mrit;
1202 
1203  if (vec_len(lcm->map_resolvers) == 0)
1204  {
1205  clib_warning("No map-resolver configured");
1206  return;
1207  }
1208 
1209  /* find the first mr ip we have a route to and the ip of the
1210  * iface that has a route to it */
1211  vec_foreach(mrit, lcm->map_resolvers)
1212  {
1213  lm = ip_addr_version (mrit) == IP4 ?
1214  &lcm->im4->lookup_main : &lcm->im6->lookup_main;
1215 
1216  adj_index = ip_fib_lookup_with_table (lcm, 0, mrit);
1217  adj = ip_get_adjacency (lm, adj_index);
1218 
1219  if (adj == 0)
1220  continue;
1221 
1223  {
1225  if (ip_addr_version(mrit) == IP4)
1226  {
1227  l4 = ip_interface_address_get_address (lm, ia);
1228  }
1229  else
1230  {
1231  l6 = ip_interface_address_get_address (lm, ia);
1232  }
1233  }
1234  else if (adj->lookup_next_index == IP_LOOKUP_NEXT_REWRITE)
1235  {
1236  /* find sw_if_index in rewrite header */
1237  u32 sw_if_index = adj->rewrite_header.sw_if_index;
1238 
1239  /* find suitable address */
1240  if (ip_addr_version(mrit) == IP4)
1241  {
1242  /* find the first ip address */
1244  sw_if_index, 1 /* unnumbered */,
1245  ({
1246  l4 = ip_interface_address_get_address (&lcm->im4->lookup_main,
1247  ia);
1248  break;
1249  }));
1250  }
1251  else
1252  {
1253  /* find the first ip address */
1255  sw_if_index, 1 /* unnumbered */,
1256  ({
1257  l6 = ip_interface_address_get_address (&lcm->im6->lookup_main,
1258  ia);
1259  break;
1260  }));
1261  }
1262  }
1263 
1264  if (l4)
1265  {
1266  ip_addr_v4(sloc).as_u32 = l4->as_u32;
1267  ip_addr_version(sloc) = IP4;
1268  ip_address_copy(mr_ip, mrit);
1269  return;
1270  }
1271  else if (l6)
1272  {
1273  clib_memcpy (&ip_addr_v6(sloc), l6, sizeof(*l6));
1274  ip_addr_version(sloc) = IP6;
1275  ip_address_copy(mr_ip, mrit);
1276  return;
1277  }
1278  }
1279 
1280  clib_warning("Can't find map-resolver and local interface ip!");
1281  return;
1282 }
1283 
1284 static gid_address_t *
1286 {
1287  ip4_address_t * l4;
1288  ip6_address_t * l6;
1289  u32 i;
1290  locator_t * loc;
1291  u32 * loc_indexp;
1292  ip_interface_address_t * ia = 0;
1293  gid_address_t gid_data, * gid = &gid_data;
1294  gid_address_t * rlocs = 0;
1295  ip_prefix_t * ippref = &gid_address_ippref (gid);
1296  ip_address_t * rloc = &ip_prefix_addr (ippref);
1297 
1299  for (i = 0; i < vec_len(loc_set->locator_indices); i++)
1300  {
1301  loc_indexp = vec_elt_at_index(loc_set->locator_indices, i);
1302  loc = pool_elt_at_index (lcm->locator_pool, loc_indexp[0]);
1303 
1304  ip_addr_version(rloc) = IP4;
1305  /* Add ipv4 locators first TODO sort them */
1307  loc->sw_if_index, 1 /* unnumbered */,
1308  ({
1309  l4 = ip_interface_address_get_address (&lcm->im4->lookup_main, ia);
1310  ip_addr_v4 (rloc) = l4[0];
1311  ip_prefix_len (ippref) = 32;
1312  vec_add1 (rlocs, gid[0]);
1313  }));
1314 
1315  ip_addr_version(rloc) = IP6;
1316  /* Add ipv6 locators */
1318  loc->sw_if_index, 1 /* unnumbered */,
1319  ({
1320  l6 = ip_interface_address_get_address (&lcm->im6->lookup_main, ia);
1321  ip_addr_v6 (rloc) = l6[0];
1322  ip_prefix_len (ippref) = 128;
1323  vec_add1 (rlocs, gid[0]);
1324  }));
1325  }
1326  return rlocs;
1327 }
1328 
1329 static vlib_buffer_t *
1331  gid_address_t * seid, gid_address_t * deid,
1332  locator_set_t * loc_set, ip_address_t * mr_ip,
1333  ip_address_t * sloc, u8 is_smr_invoked,
1334  u64 *nonce_res, u32 * bi_res)
1335 {
1336  vlib_buffer_t * b;
1337  u32 bi;
1338  gid_address_t * rlocs = 0;
1339 
1340  if (vlib_buffer_alloc (vm, &bi, 1) != 1)
1341  {
1342  clib_warning ("Can't allocate buffer for Map-Request!");
1343  return 0;
1344  }
1345 
1346  b = vlib_get_buffer (vm, bi);
1347 
1348  /* leave some space for the encap headers */
1350 
1351  /* get rlocs */
1352  rlocs = build_itr_rloc_list (lcm, loc_set);
1353 
1354  /* put lisp msg */
1355  lisp_msg_put_mreq (lcm, b, seid, deid, rlocs, is_smr_invoked, nonce_res);
1356 
1357  /* push ecm: udp-ip-lisp */
1359 
1360  /* push outer ip header */
1362  mr_ip);
1363 
1364  bi_res[0] = bi;
1365 
1366  if (rlocs)
1367  vec_free(rlocs);
1368  return b;
1369 }
1370 
1371 static void
1373  gid_address_t * seid, gid_address_t * deid,
1374  u8 is_smr_invoked)
1375 {
1376  u32 next_index, bi = 0, * to_next, map_index;
1377  vlib_buffer_t * b;
1378  vlib_frame_t * f;
1379  u64 nonce = 0;
1380  locator_set_t * loc_set;
1381  mapping_t * map;
1382  pending_map_request_t * pmr;
1383  ip_address_t mr_ip, sloc;
1384 
1385  /* get locator-set for seid */
1386  map_index = gid_dictionary_lookup (&lcm->mapping_index_by_gid, seid);
1387  if (map_index == ~0)
1388  {
1389  clib_warning("No local mapping found in eid-table for %U!",
1390  format_gid_address, seid);
1391  return;
1392  }
1393 
1394  map = pool_elt_at_index (lcm->mapping_pool, map_index);
1395 
1396  if (!map->local)
1397  {
1398  clib_warning("Mapping found for src eid %U is not marked as local!",
1399  format_gid_address, seid);
1400  return;
1401  }
1402  loc_set = pool_elt_at_index (lcm->locator_set_pool, map->locator_set_index);
1403 
1404  /* get local iface ip to use in map-request XXX fib 0 for now*/
1405  get_mr_and_local_iface_ip (lcm, &mr_ip, &sloc);
1406 
1407  /* build the encapsulated map request */
1408  b = build_encapsulated_map_request (vm, lcm, seid, deid, loc_set, &mr_ip,
1409  &sloc, is_smr_invoked, &nonce, &bi);
1410 
1411  if (!b)
1412  return;
1413 
1414  /* set fib index and lookup node */
1415  vnet_buffer(b)->sw_if_index[VLIB_TX] = ~0;
1416  next_index = (ip_addr_version(&mr_ip) == IP4) ?
1417  ip4_lookup_node.index : ip6_lookup_node.index;
1418 
1419  f = vlib_get_frame_to_node (vm, next_index);
1420 
1421  /* Enqueue the packet */
1422  to_next = vlib_frame_vector_args (f);
1423  to_next[0] = bi;
1424  f->n_vectors = 1;
1425  vlib_put_frame_to_node (vm, next_index, f);
1426 
1427  /* add map-request to pending requests table */
1429  gid_address_copy (&pmr->src, seid);
1430  gid_address_copy (&pmr->dst, deid);
1431  pmr->src_mapping_index = map_index;
1433  pmr - lcm->pending_map_requests_pool);
1434 }
1435 
1436 static void
1437 get_src_and_dst (void *hdr, ip_address_t * src, ip_address_t *dst)
1438 {
1439  ip4_header_t * ip4 = hdr;
1440  ip6_header_t * ip6;
1441 
1442  if ((ip4->ip_version_and_header_length & 0xF0) == 0x40)
1443  {
1444  ip_addr_v4(src).as_u32 = ip4->src_address.as_u32;
1445  ip_addr_version(src) = IP4;
1446  ip_addr_v4(dst).as_u32 = ip4->dst_address.as_u32;
1447  ip_addr_version(dst) = IP4;
1448  }
1449  else
1450  {
1451  ip6 = hdr;
1452  clib_memcpy (&ip_addr_v6(src), &ip6->src_address, sizeof(ip6->src_address));
1453  ip_addr_version(src) = IP6;
1454  clib_memcpy (&ip_addr_v6(dst), &ip6->dst_address, sizeof(ip6->dst_address));
1455  ip_addr_version(dst) = IP6;
1456  }
1457 }
1458 
1459 static uword
1461  vlib_frame_t * from_frame)
1462 {
1463  u32 * from, * to_next_drop, di, si;
1465  u32 pkts_mapped = 0;
1466  uword n_left_from, n_left_to_next_drop;
1467 
1468  from = vlib_frame_vector_args (from_frame);
1469  n_left_from = from_frame->n_vectors;
1470 
1471  while (n_left_from > 0)
1472  {
1474  to_next_drop, n_left_to_next_drop);
1475 
1476  while (n_left_from > 0 && n_left_to_next_drop > 0)
1477  {
1478  u32 pi0;
1479  vlib_buffer_t * p0;
1480  ip4_header_t * ip0;
1481  gid_address_t src, dst;
1482  ip_prefix_t * spref, * dpref;
1483 
1485  spref = &gid_address_ippref(&src);
1487  dpref = &gid_address_ippref(&dst);
1488 
1489  pi0 = from[0];
1490  from += 1;
1491  n_left_from -= 1;
1492  to_next_drop[0] = pi0;
1493  to_next_drop += 1;
1494  n_left_to_next_drop -= 1;
1495 
1496  p0 = vlib_get_buffer (vm, pi0);
1497  p0->error = node->errors[LISP_CP_LOOKUP_ERROR_DROP];
1498 
1499  /* src/dst eid pair */
1500  ip0 = vlib_buffer_get_current (p0);
1501  get_src_and_dst (ip0, &ip_prefix_addr(spref), &ip_prefix_addr(dpref));
1504 
1505  /* if we have remote mapping for destination already in map-chache
1506  add forwarding tunnel directly. If not send a map-request */
1507  di = gid_dictionary_lookup (&lcm->mapping_index_by_gid, &dst);
1508  if (~0 != di)
1509  {
1510  si = gid_dictionary_lookup (&lcm->mapping_index_by_gid, &src);
1511  if (~0 != si)
1512  {
1513  add_fwd_entry (lcm, si, di);
1514  }
1515  }
1516  else
1517  {
1518  /* send map-request */
1519  send_encapsulated_map_request (vm, lcm, &src, &dst, 0);
1520  pkts_mapped++;
1521  }
1522 
1524  {
1525  lisp_cp_lookup_trace_t *tr = vlib_add_trace (vm, node, p0,
1526  sizeof(*tr));
1527 
1528  memset(tr, 0, sizeof(*tr));
1529  gid_address_copy (&tr->dst_eid, &dst);
1530  if (vec_len(lcm->map_resolvers) > 0)
1531  {
1534  sizeof(ip_address_t));
1535  }
1536  }
1537  }
1538 
1539  vlib_put_next_frame (vm, node, LISP_CP_LOOKUP_NEXT_DROP, n_left_to_next_drop);
1540  }
1542  LISP_CP_LOOKUP_ERROR_MAP_REQUESTS_SENT,
1543  pkts_mapped);
1544  return from_frame->n_vectors;
1545 }
1546 
1548  .function = lisp_cp_lookup,
1549  .name = "lisp-cp-lookup",
1550  .vector_size = sizeof (u32),
1551  .format_trace = format_lisp_cp_lookup_trace,
1553 
1554  .n_errors = LISP_CP_LOOKUP_N_ERROR,
1555  .error_strings = lisp_cp_lookup_error_strings,
1556 
1557  .n_next_nodes = LISP_CP_LOOKUP_N_NEXT,
1558 
1559  .next_nodes = {
1560  [LISP_CP_LOOKUP_NEXT_DROP] = "error-drop",
1561  [LISP_CP_LOOKUP_NEXT_IP4_LOOKUP] = "ip4-lookup",
1562  [LISP_CP_LOOKUP_NEXT_IP6_LOOKUP] = "ip6-lookup",
1563  },
1564 };
1565 
1566 /* lisp_cp_input statistics */
1567 #define foreach_lisp_cp_input_error \
1568 _(DROP, "drop") \
1569 _(MAP_REPLIES_RECEIVED, "map-replies received")
1570 
1571 static char * lisp_cp_input_error_strings[] = {
1572 #define _(sym,string) string,
1574 #undef _
1575 };
1576 
1577 typedef enum
1578 {
1579 #define _(sym,str) LISP_CP_INPUT_ERROR_##sym,
1581 #undef _
1584 
1585 typedef enum
1586 {
1590 
1591 typedef struct
1592 {
1596 
1597 u8 *
1598 format_lisp_cp_input_trace (u8 * s, va_list * args)
1599 {
1600  CLIB_UNUSED (vlib_main_t * vm) = va_arg (*args, vlib_main_t *);
1601  CLIB_UNUSED (vlib_node_t * node) = va_arg (*args, vlib_node_t *);
1602  CLIB_UNUSED(lisp_cp_input_trace_t * t) = va_arg (*args, lisp_cp_input_trace_t *);
1603 
1604  s = format (s, "LISP-CP-INPUT: TODO");
1605  return s;
1606 }
1607 
1610  u8 loop)
1611 {
1612  vnet_main_t *vnm = vnet_get_main ();
1613  vnet_sw_interface_t * swif = vnet_get_sw_interface (vnm, sw_if_index);
1614  if (loop && swif->flags & VNET_SW_INTERFACE_FLAG_UNNUMBERED)
1615  sw_if_index = swif->unnumbered_sw_if_index;
1616  u32 ia =
1617  (vec_len((lm)->if_address_pool_index_by_sw_if_index) > (sw_if_index)) ?
1618  vec_elt((lm)->if_address_pool_index_by_sw_if_index, (sw_if_index)) :
1619  (u32) ~0;
1620  return pool_elt_at_index((lm)->if_address_pool, ia);
1621 }
1622 
1623 void *
1625  u8 loop)
1626 {
1628  lm, sw_if_index, loop);
1629  return ip_interface_address_get_address (lm, ia);
1630 }
1631 
1632 static void
1633 del_fwd_entry (lisp_cp_main_t * lcm, u32 src_map_index,
1634  u32 dst_map_index)
1635 {
1637  fwd_entry_t * fe = 0;
1638  uword * feip = 0;
1639  memset(a, 0, sizeof(*a));
1640 
1641  feip = hash_get(lcm->fwd_entry_by_mapping_index, dst_map_index);
1642  if (!feip)
1643  return;
1644 
1645  fe = pool_elt_at_index(lcm->fwd_entry_pool, feip[0]);
1646 
1647  /* delete dp fwd entry */
1648  u32 sw_if_index;
1649  a->is_add = 0;
1650  a->dlocator = fe->dst_loc;
1651  a->slocator = fe->src_loc;
1652  a->vni = gid_address_vni(&a->deid);
1653  gid_address_copy(&a->deid, &fe->deid);
1654 
1655  vnet_lisp_gpe_add_del_fwd_entry (a, &sw_if_index);
1656 
1657  /* delete entry in fwd table */
1658  hash_unset(lcm->fwd_entry_by_mapping_index, dst_map_index);
1659  pool_put(lcm->fwd_entry_pool, fe);
1660 }
1661 
1662 static void
1663 add_fwd_entry (lisp_cp_main_t* lcm, u32 src_map_index, u32 dst_map_index)
1664 {
1665  mapping_t * src_map, * dst_map;
1666  locator_set_t * dst_ls, * src_ls;
1667  u32 i, minp = ~0, sw_if_index;
1668  locator_t * dl = 0;
1669  uword * feip = 0, * tidp;
1670  fwd_entry_t* fe;
1672 
1673  memset (a, 0, sizeof(*a));
1674 
1675  /* remove entry if it already exists */
1676  feip = hash_get (lcm->fwd_entry_by_mapping_index, dst_map_index);
1677  if (feip)
1678  del_fwd_entry (lcm, src_map_index, dst_map_index);
1679 
1680  src_map = pool_elt_at_index (lcm->mapping_pool, src_map_index);
1681  dst_map = pool_elt_at_index (lcm->mapping_pool, dst_map_index);
1682 
1683  gid_address_copy (&a->deid, &dst_map->eid);
1684  a->vni = gid_address_vni(&a->deid);
1685 
1686  tidp = hash_get(lcm->table_id_by_vni, a->vni);
1687  if (!tidp)
1688  {
1689  clib_warning("vni %d not associated to a vrf!", a->vni);
1690  return;
1691  }
1692  a->table_id = tidp[0];
1693 
1694  /* XXX simple forwarding policy: first lowest (value) priority locator */
1695  dst_ls = pool_elt_at_index (lcm->locator_set_pool,
1696  dst_map->locator_set_index);
1697  for (i = 0; i < vec_len (dst_ls->locator_indices); i++)
1698  {
1699  u32 li = vec_elt (dst_ls->locator_indices, i);
1700  locator_t * l = pool_elt_at_index (lcm->locator_pool, li);
1701  if (l->priority < minp && gid_address_type(&l->address)
1702  == GID_ADDR_IP_PREFIX)
1703  {
1704  minp = l->priority;
1705  dl = l;
1706  }
1707  }
1708  if (dl)
1709  {
1710  src_ls = pool_elt_at_index(lcm->locator_set_pool,
1711  src_map->locator_set_index);
1712  for (i = 0; i < vec_len(src_ls->locator_indices); i++)
1713  {
1714  u32 li = vec_elt (src_ls->locator_indices, i);
1715  locator_t * sl = pool_elt_at_index (lcm->locator_pool, li);
1716 
1717  if (ip_addr_version(&gid_address_ip(&dl->address)) == IP4)
1718  {
1719  ip4_address_t * l4;
1721  sl->sw_if_index,
1722  1 /* unnumbered */);
1723  ip_addr_v4(&a->slocator) = *l4;
1724  ip_addr_version(&a->slocator) = IP4;
1725  }
1726  else
1727  {
1728  ip6_address_t * l6;
1730  sl->sw_if_index,
1731  1 /* unnumbered */);
1732  ip_addr_v6(&a->slocator) = *l6;
1733  ip_addr_version(&a->slocator) = IP6;
1734  }
1735  }
1736  }
1737 
1738  /* insert data plane forwarding entry */
1739  a->is_add = 1;
1740  if (dl)
1741  a->dlocator = gid_address_ip(&dl->address);
1742  else
1743  {
1744  a->is_negative = 1;
1745  a->action = dst_map->action;
1746  }
1747 
1748  /* TODO remove */
1750  a->decap_next_index = (ipver == IP4) ?
1751  LISP_GPE_INPUT_NEXT_IP4_INPUT : LISP_GPE_INPUT_NEXT_IP6_INPUT;
1752 
1753  vnet_lisp_gpe_add_del_fwd_entry (a, &sw_if_index);
1754 
1755  /* add tunnel to fwd entry table XXX check return value from DP insertion */
1756  pool_get (lcm->fwd_entry_pool, fe);
1757  fe->dst_loc = a->dlocator;
1758  fe->src_loc = a->slocator;
1759  gid_address_copy (&fe->deid, &a->deid);
1760  hash_set (lcm->fwd_entry_by_mapping_index, dst_map_index,
1761  fe - lcm->fwd_entry_pool);
1762 }
1763 
1764 /* return 0 if the two locator sets are identical 1 otherwise */
1765 static u8
1766 compare_locators (lisp_cp_main_t *lcm, u32 * old_ls_indexes,
1767  locator_t * new_locators)
1768 {
1769  u32 i, old_li;
1770  locator_t * old_loc, * new_loc;
1771 
1772  if (vec_len (old_ls_indexes) != vec_len(new_locators))
1773  return 1;
1774 
1775  for (i = 0; i < vec_len(new_locators); i++)
1776  {
1777  old_li = vec_elt(old_ls_indexes, i);
1778  old_loc = pool_elt_at_index(lcm->locator_pool, old_li);
1779 
1780  new_loc = vec_elt_at_index(new_locators, i);
1781 
1782  if (locator_cmp (old_loc, new_loc))
1783  return 1;
1784  }
1785  return 0;
1786 }
1787 
1788 void
1790 {
1791  locator_t * loc;
1792  u32 len = 0, i, ls_index = 0;
1793  void * h;
1794  vnet_lisp_add_del_locator_set_args_t _ls_arg, * ls_arg = &_ls_arg;
1795  vnet_lisp_add_del_mapping_args_t _m_args, * m_args = &_m_args;
1796  pending_map_request_t * pmr;
1797  locator_t probed;
1798  map_reply_hdr_t * mrep_hdr;
1799  u64 nonce;
1800  u32 dst_map_index, mi;
1801  uword * pmr_index;
1802 
1803  mrep_hdr = vlib_buffer_get_current (b);
1804 
1805  /* Check pending requests table and nonce */
1806  nonce = MREP_NONCE(mrep_hdr);
1807  pmr_index = hash_get(lcm->pending_map_requests_by_nonce, nonce);
1808  if (!pmr_index)
1809  {
1810  clib_warning("No pending map-request entry with nonce %lu!", nonce);
1811  return;
1812  }
1813  pmr = pool_elt_at_index(lcm->pending_map_requests_pool, pmr_index[0]);
1814 
1815  vlib_buffer_pull (b, sizeof(*mrep_hdr));
1816 
1817  for (i = 0; i < MREP_REC_COUNT(mrep_hdr); i++)
1818  {
1819  memset (ls_arg, 0, sizeof(*ls_arg));
1820  memset (m_args, 0, sizeof(*m_args));
1821 
1822  h = vlib_buffer_get_current (b);
1823  m_args->ttl = clib_net_to_host_u32 (MAP_REC_TTL(h));
1824  m_args->action = MAP_REC_ACTION(h);
1825  m_args->authoritative = MAP_REC_AUTH(h);
1826 
1827  len = lisp_msg_parse_mapping_record (b, &m_args->deid, &ls_arg->locators,
1828  &probed);
1829  if (len == ~0)
1830  {
1831  clib_warning ("Failed to parse mapping record!");
1832  vec_foreach (loc, ls_arg->locators)
1833  {
1834  locator_free (loc);
1835  }
1836  vec_free(ls_arg->locators);
1837  return;
1838  }
1839 
1840  mi = gid_dictionary_lookup (&lcm->mapping_index_by_gid, &m_args->deid);
1841 
1842  /* if mapping already exists, decide if locators (and forwarding) should
1843  * be updated and be done */
1844  if (mi != ~0)
1845  {
1846  mapping_t * old_map;
1847  locator_set_t * old_ls;
1848  old_map = pool_elt_at_index(lcm->mapping_pool, mi);
1849 
1850  /* update mapping attributes */
1851  old_map->action = m_args->action;
1852  old_map->authoritative = m_args->authoritative;
1853  old_map->ttl = m_args->ttl;
1854 
1855  old_ls = pool_elt_at_index(lcm->locator_set_pool,
1856  old_map->locator_set_index);
1857  /* if the two locators are not equal, update them and forwarding
1858  * otherwise there's nothing to be done */
1859  if (compare_locators (lcm, old_ls->locator_indices, ls_arg->locators))
1860  {
1861  /* set locator-set index to overwrite */
1862  ls_arg->is_add = 1;
1863  ls_arg->index = old_map->locator_set_index;
1864  vnet_lisp_add_del_locator_set (ls_arg, 0);
1865  add_fwd_entry (lcm, pmr->src_mapping_index, mi);
1866  }
1867  }
1868  /* new mapping */
1869  else
1870  {
1871  /* add locator-set */
1872  ls_arg->is_add = 1;
1873  ls_arg->index = ~0;
1874  vnet_lisp_add_del_locator_set (ls_arg, &ls_index);
1875 
1876  /* add mapping */
1877  m_args->is_add = 1;
1878  m_args->locator_set_index = ls_index;
1879  vnet_lisp_add_del_mapping (m_args, &dst_map_index);
1880 
1881  /* add forwarding tunnel */
1882  add_fwd_entry (lcm, pmr->src_mapping_index, dst_map_index);
1883  }
1884  vec_free(ls_arg->locators);
1885  }
1886 
1887  /* remove pending map request entry */
1890 }
1891 
1892 void
1894 {
1895  map_request_hdr_t * mreq_hdr;
1896  gid_address_t src, dst;
1897 // u64 nonce;
1898  u32 i, len = 0;
1899  gid_address_t * itr_rlocs = 0, * rloc;
1900 
1901  mreq_hdr = vlib_buffer_get_current (b);
1902  vlib_buffer_pull (b, sizeof(*mreq_hdr));
1903 
1904 // nonce = MREQ_NONCE(mreq_hdr);
1905 
1906  if (!MREQ_SMR(mreq_hdr)) {
1907  clib_warning("Only SMR Map-Requests supported for now!");
1908  return;
1909  }
1910 
1911  /* parse src eid */
1912  len = lisp_msg_parse_addr (b, &src);
1913  if (len == ~0)
1914  return;
1915 
1916  /* for now we don't do anything with the itr's rlocs */
1917  len = lisp_msg_parse_itr_rlocs (b, &itr_rlocs, MREQ_ITR_RLOC_COUNT(mreq_hdr) + 1);
1918  if (len == ~0)
1919  return;
1920 
1921  /* TODO: RLOCs are currently unused, so free them for now */
1922  vec_foreach (rloc, itr_rlocs)
1923  {
1924  gid_address_free (rloc);
1925  }
1926 
1927  /* parse eid records and send SMR-invoked map-requests */
1928  for (i = 0; i < MREQ_REC_COUNT(mreq_hdr); i++)
1929  {
1930  memset(&dst, 0, sizeof(dst));
1931  len = lisp_msg_parse_eid_rec (b, &dst);
1932  if (len == ~0)
1933  {
1934  clib_warning("Can't parse map-request EID-record");
1935  return;
1936  }
1937  /* send SMR-invoked map-requests */
1938  send_encapsulated_map_request (vm, lcm, &dst, &src, /* invoked */ 1);
1939  }
1940 }
1941 
1942 static uword
1944  vlib_frame_t * from_frame)
1945 {
1946  u32 n_left_from, * from, * to_next_drop;
1949 
1950  from = vlib_frame_vector_args (from_frame);
1951  n_left_from = from_frame->n_vectors;
1952 
1953 
1954  while (n_left_from > 0)
1955  {
1956  u32 n_left_to_next_drop;
1957 
1959  to_next_drop, n_left_to_next_drop);
1960  while (n_left_from > 0 && n_left_to_next_drop > 0)
1961  {
1962  u32 bi0;
1963  vlib_buffer_t * b0;
1964 
1965  bi0 = from[0];
1966  from += 1;
1967  n_left_from -= 1;
1968  to_next_drop[0] = bi0;
1969  to_next_drop += 1;
1970  n_left_to_next_drop -= 1;
1971 
1972  b0 = vlib_get_buffer (vm, bi0);
1973 
1975  switch (type)
1976  {
1977  case LISP_MAP_REPLY:
1978  process_map_reply (lcm, b0);
1979  break;
1980  case LISP_MAP_REQUEST:
1981  process_map_request(vm, lcm, b0);
1982  break;
1983  default:
1984  clib_warning("Unsupported LISP message type %d", type);
1985  break;
1986  }
1987 
1988  b0->error = node->errors[LISP_CP_INPUT_ERROR_DROP];
1989 
1991  {
1992 
1993  }
1994  }
1995 
1996  vlib_put_next_frame (vm, node, LISP_CP_INPUT_NEXT_DROP, n_left_to_next_drop);
1997  }
1998  return from_frame->n_vectors;
1999 }
2000 
2002  .function = lisp_cp_input,
2003  .name = "lisp-cp-input",
2004  .vector_size = sizeof (u32),
2005  .format_trace = format_lisp_cp_input_trace,
2007 
2008  .n_errors = LISP_CP_INPUT_N_ERROR,
2009  .error_strings = lisp_cp_input_error_strings,
2010 
2011  .n_next_nodes = LISP_CP_INPUT_N_NEXT,
2012 
2013  .next_nodes = {
2014  [LISP_CP_INPUT_NEXT_DROP] = "error-drop",
2015  },
2016 };
2017 
2018 clib_error_t *
2020 {
2022  clib_error_t * error = 0;
2023 
2024  if ((error = vlib_call_init_function (vm, lisp_gpe_init)))
2025  return error;
2026 
2027  lcm->im4 = &ip4_main;
2028  lcm->im6 = &ip6_main;
2029  lcm->vlib_main = vm;
2030  lcm->vnet_main = vnet_get_main();
2031 
2033 
2034  /* default vrf mapped to vni 0 */
2035  hash_set(lcm->table_id_by_vni, 0, 0);
2036 
2037  udp_register_dst_port (vm, UDP_DST_PORT_lisp_cp,
2038  lisp_cp_input_node.index, 1 /* is_ip4 */);
2039  udp_register_dst_port (vm, UDP_DST_PORT_lisp_cp6,
2040  lisp_cp_input_node.index, 0 /* is_ip4 */);
2041 
2042  return 0;
2043 }
2044 
#define vec_validate(V, I)
Make sure vector is long enough for given index (no header, unspecified alignment) ...
Definition: vec.h:394
#define MREQ_SMR(h_)
void vlib_put_next_frame(vlib_main_t *vm, vlib_node_runtime_t *r, u32 next_index, u32 n_vectors_left)
Definition: main.c:459
#define foreach_ip_interface_address(lm, a, sw_if_index, loop, body)
Definition: lookup.h:534
#define VNET_SW_INTERFACE_FLAG_UNNUMBERED
Definition: interface.h:380
#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:1943
#define vec_foreach_index(var, v)
Iterate over vector indices.
#define MREP_REC_COUNT(h_)
#define hash_set(h, key, value)
Definition: hash.h:237
sll srl srl sll sra u16x4 i
Definition: vector_sse2.h:267
#define gid_address_type(_a)
Definition: lisp_types.h:161
uword * dp_if_refcount_by_vni
Definition: control.h:101
#define CLIB_UNUSED(x)
Definition: clib.h:79
uword unformat(unformat_input_t *i, char *fmt,...)
Definition: unformat.c:942
#define hash_unset(h, key)
Definition: hash.h:243
a
Definition: bitmap.h:393
lisp_cp_lookup_next_t
Definition: control.c:1153
ip4_address_t src_address
Definition: ip4_packet.h:138
bad routing header type(not 4)") sr_error (NO_MORE_SEGMENTS
ip_interface_address_t * if_address_pool
Definition: lookup.h:388
#define MAP_REC_TTL(h)
gid_address_t dst_eid
Definition: control.c:1593
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:222
#define MREQ_REC_COUNT(h_)
ip_lookup_next_t lookup_next_index
Definition: lookup.h:163
int vnet_lisp_gpe_add_del_fwd_entry(vnet_lisp_gpe_add_del_fwd_entry_args_t *a, u32 *hw_if_indexp)
Definition: lisp_gpe.c:214
uword * table_id_by_vni
Definition: control.h:98
always_inline void unformat_free(unformat_input_t *i)
Definition: format.h:160
#define UNFORMAT_END_OF_INPUT
Definition: format.h:142
clib_error_t * vnet_lisp_gpe_enable_disable(vnet_lisp_gpe_enable_disable_args_t *a)
Definition: lisp_gpe.c:444
#define NULL
Definition: clib.h:55
#define foreach_lisp_cp_input_error
Definition: control.c:1567
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:941
u32 * local_mappings_indexes
Definition: control.h:79
locator_t * locator_pool
Definition: control.h:64
#define ip_prefix_len(_a)
Definition: lisp_types.h:55
uword unformat_ip_address(unformat_input_t *input, va_list *args)
Definition: lisp_types.c:123
#define vec_add1(V, E)
Add 1 element to end of vector (unspecified alignment).
Definition: vec.h:480
Definition: control.h:30
lisp_cp_input_next_t
Definition: control.c:1585
gid_address_t deid
Definition: lisp_gpe.h:213
#define hash_set_mem(h, key, value)
Definition: hash.h:257
static char * lisp_cp_input_error_strings[]
Definition: control.c:1571
ip_lookup_main_t lookup_main
Definition: ip4.h:129
unformat_function_t unformat_vnet_sw_interface
vlib_error_t * errors
Definition: node.h:378
#define pool_get(P, E)
Definition: pool.h:186
static uword lisp_cp_lookup(vlib_main_t *vm, vlib_node_runtime_t *node, vlib_frame_t *from_frame)
Definition: control.c:1460
ip_address_t dlocator
Definition: lisp_gpe.h:217
ip6_address_t src_address
Definition: ip6_packet.h:293
#define ip_prefix_version(_a)
Definition: lisp_types.h:54
always_inline void * vlib_buffer_get_current(vlib_buffer_t *b)
Get pointer to current data to process.
Definition: buffer.h:184
void gid_dictionary_init(gid_dictionary_t *db)
ip_address_t * map_resolvers
Definition: control.h:95
static void clean_locator_to_locator_set(lisp_cp_main_t *lcm, u32 lsi)
Definition: control.c:529
always_inline void * ip_interface_address_get_address(ip_lookup_main_t *lm, ip_interface_address_t *a)
Definition: lookup.h:513
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:1019
vlib_node_registration_t ip4_lookup_node
(constructor) VLIB_REGISTER_NODE (ip4_lookup_node)
Definition: ip4_forward.c:1360
always_inline uword unformat_check_input(unformat_input_t *i)
Definition: format.h:168
static clib_error_t * lisp_show_local_eid_table_command_fn(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
Definition: control.c:499
u32 ** locator_to_locator_sets
Definition: control.h:70
vlib_main_t * vlib_main
Definition: control.h:106
vnet_main_t * vnet_get_main(void)
Definition: misc.c:45
vlib_node_registration_t lisp_cp_lookup_node
(constructor) VLIB_REGISTER_NODE (lisp_cp_lookup_node)
Definition: control.c:1547
void process_map_reply(lisp_cp_main_t *lcm, vlib_buffer_t *b)
Definition: control.c:1789
#define pool_foreach(VAR, POOL, BODY)
Definition: pool.h:328
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:195
#define VLIB_INIT_FUNCTION(x)
Definition: init.h:109
ip4_address_t dst_address
Definition: ip4_packet.h:138
u8 is_add
Definition: lisp_gpe.h:205
void di(unformat_input_t *i)
Definition: unformat.c:150
#define vec_elt_at_index(v, i)
Get vector value at index i checking that i is in bounds.
u32 ip4_fib_lookup_with_table(ip4_main_t *im, u32 fib_index, ip4_address_t *dst, u32 disable_default_route)
Definition: ip4_forward.c:50
u32 * fwd_entry_by_mapping_index
Definition: control.h:83
#define clib_warning(format, args...)
Definition: error.h:59
unsigned long u64
Definition: types.h:89
uword unformat_user(unformat_input_t *input, unformat_function_t *func,...)
Definition: unformat.c:953
void vnet_lisp_gpe_add_del_iface(vnet_lisp_gpe_add_del_iface_args_t *a, u32 *hw_if_indexp)
Definition: interface.c:484
#define ip_addr_v4(_a)
Definition: lisp_types.h:49
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)
#define vlib_call_init_function(vm, x)
Definition: init.h:159
static vlib_buffer_t * build_encapsulated_map_request(vlib_main_t *vm, 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:1330
always_inline void * vlib_frame_vector_args(vlib_frame_t *f)
Definition: node_funcs.h:202
Definition: lisp_gpe.h:203
gid_address_t src
Definition: control.h:25
#define ip_addr_version(_a)
Definition: lisp_types.h:51
ip6_main_t * im6
Definition: control.h:105
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:887
u32 gid_dictionary_lookup(gid_dictionary_t *db, gid_address_t *key)
#define hash_get(h, key)
Definition: hash.h:231
#define pool_elt_at_index(p, i)
Definition: pool.h:346
#define hash_unset_mem(h, key)
Definition: hash.h:263
lisp_cp_lookup_error_t
Definition: control.c:1145
u32 table_id
Definition: lisp_gpe.h:229
u32 gid_dictionary_add_del(gid_dictionary_t *db, gid_address_t *key, u32 value, u8 is_add)
#define MAP_REC_AUTH(h)
int vnet_lisp_add_del_local_mapping(vnet_lisp_add_del_mapping_args_t *a, u32 *map_index_result)
Definition: control.c:131
u32 lisp_msg_parse_addr(vlib_buffer_t *b, gid_address_t *eid)
vlib_node_registration_t lisp_cp_input_node
(constructor) VLIB_REGISTER_NODE (lisp_cp_input_node)
Definition: control.c:2001
#define hash_free(h)
Definition: hash.h:269
void gid_address_free(gid_address_t *a)
Definition: lisp_types.c:392
#define pool_put(P, E)
Definition: pool.h:200
#define vec_dup(V)
Return copy of vector (no header, no alignment)
Definition: vec.h:332
u8 authoritative
Definition: lisp_types.h:225
#define unformat_parse_error(input)
Definition: format.h:265
u32 * local_locator_set_indexes
Definition: control.h:80
#define PREDICT_FALSE(x)
Definition: clib.h:97
#define vec_del1(v, i)
Delete the element at index I.
Definition: vec.h:763
u8 * format_gid_address(u8 *s, va_list *args)
Definition: lisp_types.c:151
always_inline void vlib_node_increment_counter(vlib_main_t *vm, u32 node_index, u32 counter_index, u64 increment)
Definition: node_funcs.h:970
static void del_fwd_entry(lisp_cp_main_t *lcm, u32 src_map_index, u32 dst_map_index)
Definition: control.c:1633
static u8 compare_locators(lisp_cp_main_t *lcm, u32 *old_ls_indexes, locator_t *new_locators)
Definition: control.c:1766
static void send_encapsulated_map_request(vlib_main_t *vm, lisp_cp_main_t *lcm, gid_address_t *seid, gid_address_t *deid, u8 is_smr_invoked)
Definition: control.c:1372
clib_error_t * vnet_lisp_enable_disable(u8 is_enabled)
Definition: control.c:824
#define foreach_lisp_cp_lookup_error
Definition: control.c:1135
void vlib_put_frame_to_node(vlib_main_t *vm, u32 to_node_index, vlib_frame_t *f)
Definition: main.c:191
#define MAX_LISP_MSG_ENCAP_LEN
#define vlib_get_next_frame(vm, node, next_index, vectors, n_vectors_left)
Definition: node_funcs.h:265
void * ip_interface_get_first_ip_addres(ip_lookup_main_t *lm, u32 sw_if_index, u8 loop)
Definition: control.c:1624
void vlib_cli_output(vlib_main_t *vm, char *fmt,...)
Definition: cli.c:538
ip_address_t map_resolver_ip
Definition: control.c:1164
u32 decap_next_index
Definition: lisp_gpe.h:223
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:1092
vlib_error_t error
Error code for buffers to be enqueued to error handler.
Definition: buffer.h:129
#define ip_addr_v6(_a)
Definition: lisp_types.h:50
static void remove_locator_from_locator_set(locator_set_t *ls, u32 *locit, u32 ls_index, u32 loc_id)
Definition: control.c:601
#define gid_address_ippref(_a)
Definition: lisp_types.h:162
u8 is_negative
Definition: lisp_gpe.h:208
static int is_locator_in_locator_set(lisp_cp_main_t *lcm, locator_set_t *ls, locator_t *loc)
Definition: control.c:577
#define pool_free(p)
Definition: pool.h:248
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:192
clib_error_t * lisp_cp_init(vlib_main_t *vm)
Definition: control.c:2019
u32 vni
Definition: lisp_gpe.h:226
int vnet_lisp_add_del_remote_mapping(gid_address_t *deid, gid_address_t *seid, ip_address_t *rlocs, u8 action, u8 is_add)
Adds/removes/updates static remote mapping.
Definition: control.c:275
uword * pending_map_requests_by_nonce
Definition: control.h:89
u16 n_vectors
Definition: node.h:307
u8 * format_lisp_cp_input_trace(u8 *s, va_list *args)
Definition: control.c:1598
#define MAP_REC_ACTION(h)
int gid_address_cmp(gid_address_t *a1, gid_address_t *a2)
Definition: lisp_types.c:730
#define vec_free(V)
Free vector&#39;s memory (no header).
Definition: vec.h:298
vnet_main_t * vnet_main
Definition: lisp_gpe.h:156
u32 lisp_msg_parse_mapping_record(vlib_buffer_t *b, gid_address_t *eid, locator_t **locs, locator_t *probed_)
gid_address_t deid
Definition: control.h:33
u32 locator_set_index
Definition: lisp_types.h:221
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:63
u32 locator_cmp(locator_t *l1, locator_t *l2)
Definition: lisp_types.c:799
u32 ip6_fib_lookup_with_table(ip6_main_t *im, u32 fib_index, ip6_address_t *dst)
Definition: ip6_forward.c:61
#define pool_is_free_index(P, I)
Definition: pool.h:197
ip4_address_t map_resolver_ip
Definition: control.c:1594
lisp_gpe_main_t lisp_gpe_main
Definition: lisp_gpe.c:18
always_inline lisp_cp_main_t * vnet_lisp_cp_get_main()
Definition: control.h:168
#define VLIB_CLI_COMMAND(x,...)
Definition: cli.h:150
u8 vnet_lisp_enable_disable_status(void)
Definition: control.c:927
vlib_node_registration_t ip6_lookup_node
(constructor) VLIB_REGISTER_NODE (ip6_lookup_node)
Definition: ip6_forward.c:1267
struct _gid_address_t gid_address_t
u8 * format_vnet_lisp_gpe_status(u8 *s, va_list *args)
Definition: lisp_gpe.c:581
#define pool_put_index(p, i)
Definition: pool.h:214
static void get_src_and_dst(void *hdr, ip_address_t *src, ip_address_t *dst)
Definition: control.c:1437
#define ASSERT(truth)
unsigned int u32
Definition: types.h:88
void get_mr_and_local_iface_ip(lisp_cp_main_t *lcm, ip_address_t *mr_ip, ip_address_t *sloc)
Definition: control.c:1192
u8 * format_ip_address(u8 *s, va_list *args)
Definition: lisp_types.c:103
#define GID_LOOKUP_MISS
u8 * format_unformat_error(u8 *s, va_list *va)
Definition: unformat.c:87
#define vnet_buffer(b)
Definition: buffer.h:300
ip6_main_t ip6_main
Definition: ip6_forward.c:2490
ip_lookup_main_t lookup_main
Definition: ip6.h:135
#define vec_delete(V, N, M)
Delete N elements starting at element M.
Definition: vec.h:743
clib_error_t * lisp_gpe_init(vlib_main_t *vm)
Definition: lisp_gpe.c:550
u8 * format(u8 *s, char *fmt,...)
Definition: format.c:405
gid_dictionary_t mapping_index_by_gid
Definition: control.h:58
ip_interface_address_t * ip_interface_get_first_interface_address(ip_lookup_main_t *lm, u32 sw_if_index, u8 loop)
Definition: control.c:1609
always_inline void * vlib_buffer_make_headroom(vlib_buffer_t *b, u8 size)
Definition: packets.h:59
locator_set_t * locator_set_pool
Definition: control.h:67
always_inline void * vlib_buffer_pull(vlib_buffer_t *b, u8 size)
Definition: packets.h:67
ip_address_t slocator
Definition: lisp_gpe.h:216
u32 ** locator_set_to_eids
Definition: control.h:76
#define LISP_CONTROL_PORT
u32 vlib_buffer_alloc(vlib_main_t *vm, u32 *buffers, u32 n_buffers)
Allocate buffers into supplied array.
Definition: buffer.c:770
uword unformat_ip_prefix(unformat_input_t *input, va_list *args)
Definition: lisp_types.c:143
fwd_entry_t * fwd_entry_pool
Definition: control.h:86
#define VLIB_BUFFER_IS_TRACED
Definition: buffer.h:91
always_inline ip_adjacency_t * ip_get_adjacency(ip_lookup_main_t *lm, u32 adj_index)
Definition: lookup.h:423
u64 uword
Definition: types.h:112
#define vec_elt(v, i)
Get vector value at index i.
pending_map_request_t * pending_map_requests_pool
Definition: control.h:92
int vnet_lisp_add_del_locator_set(vnet_lisp_add_del_locator_set_args_t *a, u32 *ls_result)
Definition: control.c:705
#define gid_address_ip(_a)
Definition: lisp_types.h:164
Definition: defs.h:46
negative_fwd_actions_e action
Definition: lisp_gpe.h:209
#define gid_address_vni(_a)
Definition: lisp_types.h:166
#define hash_create_vec(elts, key_bytes, value_bytes)
Definition: hash.h:601
ip_address_t src_loc
Definition: control.h:34
static uword * get_locator_set_index(vnet_lisp_add_del_locator_set_args_t *a, uword *p)
Definition: control.c:555
void locator_free(locator_t *l)
Definition: lisp_types.c:817
#define vec_len(v)
Number of elements in vector (rvalue-only, NULL tolerant)
static char * lisp_cp_lookup_error_strings[]
Definition: control.c:1139
unsigned char u8
Definition: types.h:56
always_inline vnet_sw_interface_t * vnet_get_sw_interface(vnet_main_t *vnm, u32 sw_if_index)
int ip_address_cmp(ip_address_t *ip1, ip_address_t *ip2)
Definition: lisp_types.c:403
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:618
mapping_t * mapping_pool
Definition: control.h:61
u8 ip_address_max_len(u8 version)
Definition: lisp_types.c:264
uword * locator_set_index_by_name
Definition: control.h:73
static gid_address_t * build_itr_rloc_list(lisp_cp_main_t *lcm, locator_set_t *loc_set)
Definition: control.c:1285
void gid_address_copy(gid_address_t *dst, gid_address_t *src)
Definition: lisp_types.c:656
Definition: lisp_types.h:24
gid_address_t eid
Definition: lisp_types.h:218
always_inline 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
gid_address_t address
Definition: lisp_types.h:193
#define hash_get_mem(h, key)
Definition: hash.h:251
u32 lisp_msg_parse_eid_rec(vlib_buffer_t *b, gid_address_t *eid)
gid_address_t dst
Definition: control.h:26
#define VLIB_REGISTER_NODE(x,...)
Definition: node.h:140
int vnet_lisp_add_del_map_resolver(vnet_lisp_add_del_map_resolver_args_t *a)
Definition: control.c:1057
ip4_main_t ip4_main
Definition: ip4_forward.c:1394
void process_map_request(vlib_main_t *vm, lisp_cp_main_t *lcm, vlib_buffer_t *b)
Definition: control.c:1893
#define gid_address_set_vni(_a, _val)
Definition: lisp_types.h:169
u32 if_address_index
Definition: lookup.h:155
ip_address_t dst_loc
Definition: control.h:35
#define vec_foreach(var, vec)
Vector iterator.
vhost_vring_addr_t addr
Definition: vhost-user.h:78
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:374
gid_address_t dst_eid
Definition: control.c:1163
#define clib_error_return(e, args...)
Definition: error.h:112
u8 ip_version_and_header_length
Definition: ip4_packet.h:108
struct _unformat_input_t unformat_input_t
#define MREP_NONCE(h_)
vlib_frame_t * vlib_get_frame_to_node(vlib_main_t *vm, u32 to_node_index)
Definition: main.c:184
Definition: lisp_types.h:25
always_inline lisp_msg_type_e lisp_msg_type(void *b)
u32 flags
buffer flags: VLIB_BUFFER_IS_TRACED: trace this buffer.
Definition: buffer.h:84
unformat_function_t unformat_line_input
Definition: format.h:279
static u8 * format_lisp_status(u8 *s, va_list *args)
Definition: control.c:934
always_inline vlib_buffer_t * vlib_get_buffer(vlib_main_t *vm, u32 buffer_index)
Translate buffer index into buffer pointer.
Definition: buffer_funcs.h:69
static u32 ip_fib_lookup_with_table(lisp_cp_main_t *lcm, u32 fib_index, ip_address_t *dst)
Definition: control.c:1181
int vnet_lisp_add_del_mapping(vnet_lisp_add_del_mapping_args_t *a, u32 *map_index_result)
Definition: control.c:34
u32 * locator_indices
Definition: lisp_types.h:212
vnet_main_t * vnet_main
Definition: control.h:107
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:958
u8 * format_lisp_cp_lookup_trace(u8 *s, va_list *args)
Definition: control.c:1168
ip4_main_t * im4
Definition: control.h:104
void ip_address_copy(ip_address_t *dst, ip_address_t *src)
Definition: lisp_types.c:419
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:396
#define ip_prefix_addr(_a)
Definition: lisp_types.h:53
ip6_address_t dst_address
Definition: ip6_packet.h:293
lisp_cp_input_error_t
Definition: control.c:1577
static void add_fwd_entry(lisp_cp_main_t *lcm, u32 src_map_index, u32 dst_map_index)
Definition: control.c:1663