FD.io VPP  v20.09-64-g4f7b92f0a
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>
23 #include <vnet/fib/fib_entry.h>
24 #include <vnet/fib/fib_table.h>
26 #include <vnet/ethernet/packet.h>
27 
28 #include <openssl/evp.h>
29 #include <vnet/crypto/crypto.h>
30 
31 #define MAX_VALUE_U24 0xffffff
32 
33 /* mapping timer control constants (in seconds) */
34 #define TIME_UNTIL_REFETCH_OR_DELETE 20
35 #define MAPPING_TIMEOUT (((m->ttl) * 60) - TIME_UNTIL_REFETCH_OR_DELETE)
36 
38 
39 u8 *format_lisp_cp_input_trace (u8 * s, va_list * args);
40 static void *send_map_request_thread_fn (void *arg);
41 
42 typedef enum
43 {
47 
48 typedef struct
49 {
55 
56 u8
58 {
60  return lcm->map_request_mode;
61 }
62 
63 static u16
65 {
66  switch (key_id)
67  {
68  case HMAC_SHA_1_96:
69  return SHA1_AUTH_DATA_LEN;
70  case HMAC_SHA_256_128:
71  return SHA256_AUTH_DATA_LEN;
72  default:
73  clib_warning ("unsupported key type: %d!", key_id);
74  return (u16) ~ 0;
75  }
76  return (u16) ~ 0;
77 }
78 
79 static int
81  u8 smr_invoked, u8 is_resend);
82 
85  u32 sw_if_index, u8 loop)
86 {
87  vnet_main_t *vnm = vnet_get_main ();
88  vnet_sw_interface_t *swif = vnet_get_sw_interface (vnm, sw_if_index);
89  if (loop && swif->flags & VNET_SW_INTERFACE_FLAG_UNNUMBERED)
90  sw_if_index = swif->unnumbered_sw_if_index;
91  u32 ia =
92  (vec_len ((lm)->if_address_pool_index_by_sw_if_index) > (sw_if_index)) ?
93  vec_elt ((lm)->if_address_pool_index_by_sw_if_index, (sw_if_index)) :
94  (u32) ~ 0;
95  return pool_elt_at_index ((lm)->if_address_pool, ia);
96 }
97 
98 void *
100  u8 version)
101 {
103 
104  ia = ip_interface_get_first_interface_address (lm, sw_if_index, 1);
105  if (!ia)
106  return 0;
107  return ip_interface_address_get_address (lm, ia);
108 }
109 
110 int
112  u8 version, ip_address_t * result)
113 {
114  ip_lookup_main_t *lm;
115  void *addr;
116 
117  lm = (version == AF_IP4) ? &lcm->im4->lookup_main : &lcm->im6->lookup_main;
118  addr = ip_interface_get_first_address (lm, sw_if_index, version);
119  if (!addr)
120  return 0;
121 
122  ip_address_set (result, addr, version);
123  return 1;
124 }
125 
126 /**
127  * Find the sw_if_index of the interface that would be used to egress towards
128  * dst.
129  */
130 u32
132 {
133  fib_node_index_t fei;
135 
136  ip_address_to_fib_prefix (dst, &prefix);
137 
138  fei = fib_table_lookup (0, &prefix);
139 
140  return (fib_entry_get_resolving_interface (fei));
141 }
142 
143 /**
144  * Find first IP of the interface that would be used to egress towards dst.
145  * Returns 1 if the address is found 0 otherwise.
146  */
147 int
149  ip_address_t * result)
150 {
151  u32 si;
152  ip_lookup_main_t *lm;
153  void *addr = 0;
154  u8 ipver;
155 
156  ASSERT (result != 0);
157 
158  ipver = ip_addr_version (dst);
159 
160  lm = (ipver == AF_IP4) ? &lcm->im4->lookup_main : &lcm->im6->lookup_main;
161  si = ip_fib_get_egress_iface_for_dst (lcm, dst);
162 
163  if ((u32) ~ 0 == si)
164  return 0;
165 
166  /* find the first ip address */
167  addr = ip_interface_get_first_address (lm, si, ipver);
168  if (0 == addr)
169  return 0;
170 
171  ip_address_set (result, addr, ipver);
172  return 1;
173 }
174 
175 static int
176 dp_add_del_iface (lisp_cp_main_t * lcm, u32 vni, u8 is_l2, u8 is_add,
177  u8 with_default_route)
178 {
179  uword *dp_table;
180 
181  if (!is_l2)
182  {
183  dp_table = hash_get (lcm->table_id_by_vni, vni);
184 
185  if (!dp_table)
186  {
187  clib_warning ("vni %d not associated to a vrf!", vni);
188  return VNET_API_ERROR_INVALID_VALUE;
189  }
190  }
191  else
192  {
193  dp_table = hash_get (lcm->bd_id_by_vni, vni);
194  if (!dp_table)
195  {
196  clib_warning ("vni %d not associated to a bridge domain!", vni);
197  return VNET_API_ERROR_INVALID_VALUE;
198  }
199  }
200 
201  /* enable/disable data-plane interface */
202  if (is_add)
203  {
204  if (is_l2)
205  lisp_gpe_tenant_l2_iface_add_or_lock (vni, dp_table[0]);
206  else
207  lisp_gpe_tenant_l3_iface_add_or_lock (vni, dp_table[0],
208  with_default_route);
209  }
210  else
211  {
212  if (is_l2)
214  else
216  }
217 
218  return 0;
219 }
220 
221 static void
222 dp_del_fwd_entry (lisp_cp_main_t * lcm, u32 dst_map_index)
223 {
225  fwd_entry_t *fe = 0;
226  uword *feip = 0;
227  clib_memset (a, 0, sizeof (*a));
228 
229  feip = hash_get (lcm->fwd_entry_by_mapping_index, dst_map_index);
230  if (!feip)
231  return;
232 
233  fe = pool_elt_at_index (lcm->fwd_entry_pool, feip[0]);
234 
235  /* delete dp fwd entry */
237  a->is_add = 0;
238  a->locator_pairs = fe->locator_pairs;
239  a->vni = gid_address_vni (&fe->reid);
240  gid_address_copy (&a->rmt_eid, &fe->reid);
241  if (fe->is_src_dst)
242  gid_address_copy (&a->lcl_eid, &fe->leid);
243 
244  vnet_lisp_gpe_del_fwd_counters (a, feip[0]);
245  vnet_lisp_gpe_add_del_fwd_entry (a, &sw_if_index);
246 
247  /* delete entry in fwd table */
248  hash_unset (lcm->fwd_entry_by_mapping_index, dst_map_index);
249  vec_free (fe->locator_pairs);
250  pool_put (lcm->fwd_entry_pool, fe);
251 }
252 
253 /**
254  * Finds first remote locator with best (lowest) priority that has a local
255  * peer locator with an underlying route to it.
256  *
257  */
258 static u32
260  mapping_t * rmt_map, locator_pair_t ** locator_pairs)
261 {
262  u32 i, limitp = 0, li, found = 0, esi;
263  locator_set_t *rmt_ls, *lcl_ls;
264  ip_address_t _lcl_addr, *lcl_addr = &_lcl_addr;
265  locator_t *lp, *rmt = 0;
266  uword *checked = 0;
267  locator_pair_t pair;
268 
269  rmt_ls =
271  lcl_ls =
273 
274  if (!rmt_ls || vec_len (rmt_ls->locator_indices) == 0)
275  return 0;
276 
277  while (1)
278  {
279  rmt = 0;
280 
281  /* find unvisited remote locator with best priority */
282  for (i = 0; i < vec_len (rmt_ls->locator_indices); i++)
283  {
284  if (0 != hash_get (checked, i))
285  continue;
286 
287  li = vec_elt (rmt_ls->locator_indices, i);
288  lp = pool_elt_at_index (lcm->locator_pool, li);
289 
290  /* we don't support non-IP locators for now */
292  continue;
293 
294  if ((found && lp->priority == limitp)
295  || (!found && lp->priority >= limitp))
296  {
297  rmt = lp;
298 
299  /* don't search for locators with lower priority and don't
300  * check this locator again*/
301  limitp = lp->priority;
302  hash_set (checked, i, 1);
303  break;
304  }
305  }
306  /* check if a local locator with a route to remote locator exists */
307  if (rmt != 0)
308  {
309  /* find egress sw_if_index for rmt locator */
310  esi =
312  &gid_address_ip (&rmt->address));
313  if ((u32) ~ 0 == esi)
314  continue;
315 
316  for (i = 0; i < vec_len (lcl_ls->locator_indices); i++)
317  {
318  li = vec_elt (lcl_ls->locator_indices, i);
319  locator_t *sl = pool_elt_at_index (lcm->locator_pool, li);
320 
321  /* found local locator with the needed sw_if_index */
322  if (sl->sw_if_index == esi)
323  {
324  /* and it has an address */
325  if (0 == ip_interface_get_first_ip_address (lcm,
326  sl->sw_if_index,
328  (&rmt->address),
329  lcl_addr))
330  continue;
331 
332  clib_memset (&pair, 0, sizeof (pair));
333  ip_address_copy (&pair.rmt_loc,
334  &gid_address_ip (&rmt->address));
335  ip_address_copy (&pair.lcl_loc, lcl_addr);
336  pair.weight = rmt->weight;
337  pair.priority = rmt->priority;
338  vec_add1 (locator_pairs[0], pair);
339  found = 1;
340  }
341  }
342  }
343  else
344  break;
345  }
346 
347  hash_free (checked);
348  return found;
349 }
350 
351 static void
353  fid_address_t * fid)
354 {
356 
357  dst[0] = src[0];
358 
359  switch (fid_addr_type (fid))
360  {
361  case FID_ADDR_IP_PREF:
363  gid_address_ippref (dst) = fid_addr_ippref (fid);
364  break;
365  case FID_ADDR_MAC:
367  mac_copy (gid_address_mac (dst), fid_addr_mac (fid));
368  break;
369  default:
370  clib_warning ("Unsupported fid type %d!", fid_addr_type (fid));
371  break;
372  }
373 }
374 
375 u8
377 {
379  return lcm->map_registering;
380 }
381 
382 u8
384 {
386  return lcm->rloc_probing;
387 }
388 
389 static void
390 dp_add_fwd_entry (lisp_cp_main_t * lcm, u32 src_map_index, u32 dst_map_index)
391 {
393  gid_address_t *rmt_eid, *lcl_eid;
394  mapping_t *lcl_map, *rmt_map;
395  u32 sw_if_index, **rmts, rmts_idx;
396  uword *feip = 0, *dpid, *rmts_stored_idxp = 0;
397  fwd_entry_t *fe;
398  u8 type, is_src_dst = 0;
399  int rv;
400 
401  clib_memset (a, 0, sizeof (*a));
402 
403  /* remove entry if it already exists */
404  feip = hash_get (lcm->fwd_entry_by_mapping_index, dst_map_index);
405  if (feip)
406  dp_del_fwd_entry (lcm, dst_map_index);
407 
408  /*
409  * Determine local mapping and eid
410  */
411  if (lcm->flags & LISP_FLAG_PITR_MODE)
412  {
413  if (lcm->pitr_map_index != ~0)
414  lcl_map = pool_elt_at_index (lcm->mapping_pool, lcm->pitr_map_index);
415  else
416  {
417  clib_warning ("no PITR mapping configured!");
418  return;
419  }
420  }
421  else
422  lcl_map = pool_elt_at_index (lcm->mapping_pool, src_map_index);
423  lcl_eid = &lcl_map->eid;
424 
425  /*
426  * Determine remote mapping and eid
427  */
428  rmt_map = pool_elt_at_index (lcm->mapping_pool, dst_map_index);
429  rmt_eid = &rmt_map->eid;
430 
431  /*
432  * Build and insert data plane forwarding entry
433  */
434  a->is_add = 1;
435 
436  if (MR_MODE_SRC_DST == lcm->map_request_mode)
437  {
438  if (GID_ADDR_SRC_DST == gid_address_type (rmt_eid))
439  {
440  gid_address_sd_to_flat (&a->rmt_eid, rmt_eid,
441  &gid_address_sd_dst (rmt_eid));
442  gid_address_sd_to_flat (&a->lcl_eid, rmt_eid,
443  &gid_address_sd_src (rmt_eid));
444  }
445  else
446  {
447  gid_address_copy (&a->rmt_eid, rmt_eid);
448  gid_address_copy (&a->lcl_eid, lcl_eid);
449  }
450  is_src_dst = 1;
451  }
452  else
453  gid_address_copy (&a->rmt_eid, rmt_eid);
454 
455  a->vni = gid_address_vni (&a->rmt_eid);
456  a->is_src_dst = is_src_dst;
457 
458  /* get vrf or bd_index associated to vni */
459  type = gid_address_type (&a->rmt_eid);
460  if (GID_ADDR_IP_PREFIX == type)
461  {
462  dpid = hash_get (lcm->table_id_by_vni, a->vni);
463  if (!dpid)
464  {
465  clib_warning ("vni %d not associated to a vrf!", a->vni);
466  return;
467  }
468  a->table_id = dpid[0];
469  }
470  else if (GID_ADDR_MAC == type)
471  {
472  dpid = hash_get (lcm->bd_id_by_vni, a->vni);
473  if (!dpid)
474  {
475  clib_warning ("vni %d not associated to a bridge domain !", a->vni);
476  return;
477  }
478  a->bd_id = dpid[0];
479  }
480 
481  /* find best locator pair that 1) verifies LISP policy 2) are connected */
482  rv = get_locator_pairs (lcm, lcl_map, rmt_map, &a->locator_pairs);
483 
484  /* Either rmt mapping is negative or we can't find underlay path.
485  * Try again with petr if configured */
486  if (rv == 0 && (lcm->flags & LISP_FLAG_USE_PETR))
487  {
488  rmt_map = lisp_get_petr_mapping (lcm);
489  rv = get_locator_pairs (lcm, lcl_map, rmt_map, &a->locator_pairs);
490  }
491 
492  /* negative entry */
493  if (rv == 0)
494  {
495  a->is_negative = 1;
496  a->action = rmt_map->action;
497  }
498 
499  rv = vnet_lisp_gpe_add_del_fwd_entry (a, &sw_if_index);
500  if (rv)
501  {
502  if (a->locator_pairs)
503  vec_free (a->locator_pairs);
504  return;
505  }
506 
507  /* add tunnel to fwd entry table */
508  pool_get (lcm->fwd_entry_pool, fe);
510 
511  fe->locator_pairs = a->locator_pairs;
512  gid_address_copy (&fe->reid, &a->rmt_eid);
513 
514  if (is_src_dst)
515  gid_address_copy (&fe->leid, &a->lcl_eid);
516  else
517  gid_address_copy (&fe->leid, lcl_eid);
518 
519  fe->is_src_dst = is_src_dst;
520  hash_set (lcm->fwd_entry_by_mapping_index, dst_map_index,
521  fe - lcm->fwd_entry_pool);
522 
523  /* Add rmt mapping to the vector of adjacent mappings to lcl mapping */
524  rmts_stored_idxp =
525  hash_get (lcm->lcl_to_rmt_adjs_by_lcl_idx, src_map_index);
526  if (!rmts_stored_idxp)
527  {
528  pool_get (lcm->lcl_to_rmt_adjacencies, rmts);
529  clib_memset (rmts, 0, sizeof (*rmts));
530  rmts_idx = rmts - lcm->lcl_to_rmt_adjacencies;
531  hash_set (lcm->lcl_to_rmt_adjs_by_lcl_idx, src_map_index, rmts_idx);
532  }
533  else
534  {
535  rmts_idx = (u32) (*rmts_stored_idxp);
536  rmts = pool_elt_at_index (lcm->lcl_to_rmt_adjacencies, rmts_idx);
537  }
538  vec_add1 (rmts[0], dst_map_index);
539 }
540 
541 typedef struct
542 {
546 
547 static void *
549 {
550  fwd_entry_mt_arg_t *a = arg;
552  dp_add_fwd_entry (lcm, a->si, a->di);
553  return 0;
554 }
555 
556 static int
558 {
560 
561  clib_memset (&a, 0, sizeof (a));
562  a.si = si;
563  a.di = di;
564 
566  (u8 *) & a, sizeof (a));
567  return 0;
568 }
569 
570 /**
571  * Returns vector of adjacencies.
572  *
573  * The caller must free the vector returned by this function.
574  *
575  * @param vni virtual network identifier
576  * @return vector of adjacencies
577  */
580 {
582  fwd_entry_t *fwd;
583  lisp_adjacency_t *adjs = 0, adj;
584 
585  /* *INDENT-OFF* */
586  pool_foreach(fwd, lcm->fwd_entry_pool,
587  ({
588  if (gid_address_vni (&fwd->reid) != vni)
589  continue;
590 
591  gid_address_copy (&adj.reid, &fwd->reid);
592  gid_address_copy (&adj.leid, &fwd->leid);
593  vec_add1 (adjs, adj);
594  }));
595  /* *INDENT-ON* */
596 
597  return adjs;
598 }
599 
600 static lisp_msmr_t *
602 {
604  lisp_msmr_t *m;
605 
606  vec_foreach (m, lcm->map_servers)
607  {
608  if (!ip_address_cmp (&m->address, a))
609  {
610  return m;
611  }
612  }
613  return 0;
614 }
615 
616 static lisp_msmr_t *
618 {
620  lisp_msmr_t *m;
621 
622  vec_foreach (m, lcm->map_resolvers)
623  {
624  if (!ip_address_cmp (&m->address, a))
625  {
626  return m;
627  }
628  }
629  return 0;
630 }
631 
632 int
634 {
635  u32 i;
637  lisp_msmr_t _ms, *ms = &_ms;
638 
640  {
641  clib_warning ("LISP is disabled!");
642  return VNET_API_ERROR_LISP_DISABLED;
643  }
644 
645  if (is_add)
646  {
647  if (get_map_server (addr))
648  {
649  clib_warning ("map-server %U already exists!", format_ip_address,
650  addr);
651  return -1;
652  }
653 
654  clib_memset (ms, 0, sizeof (*ms));
655  ip_address_copy (&ms->address, addr);
656  vec_add1 (lcm->map_servers, ms[0]);
657 
658  if (vec_len (lcm->map_servers) == 1)
659  lcm->do_map_server_election = 1;
660  }
661  else
662  {
663  for (i = 0; i < vec_len (lcm->map_servers); i++)
664  {
665  ms = vec_elt_at_index (lcm->map_servers, i);
666  if (!ip_address_cmp (&ms->address, addr))
667  {
668  if (!ip_address_cmp (&ms->address, &lcm->active_map_server))
669  lcm->do_map_server_election = 1;
670 
671  vec_del1 (lcm->map_servers, i);
672  break;
673  }
674  }
675  }
676 
677  return 0;
678 }
679 
680 /**
681  * Add/remove mapping to/from map-cache. Overwriting not allowed.
682  */
683 int
685  u32 * map_index_result)
686 {
688  u32 mi, *map_indexp, map_index, i;
689  u32 **rmts = 0, *remote_idxp, rmts_itr, remote_idx;
690  uword *rmts_idxp;
691  mapping_t *m, *old_map;
692  u32 **eid_indexes;
693 
694  if (gid_address_type (&a->eid) == GID_ADDR_NSH)
695  {
696  if (gid_address_vni (&a->eid) != 0)
697  {
698  clib_warning ("Supported only default VNI for NSH!");
699  return VNET_API_ERROR_INVALID_ARGUMENT;
700  }
702  {
703  clib_warning ("SPI is greater than 24bit!");
704  return VNET_API_ERROR_INVALID_ARGUMENT;
705  }
706  }
707 
709  old_map = mi != ~0 ? pool_elt_at_index (lcm->mapping_pool, mi) : 0;
710  if (a->is_add)
711  {
712  /* TODO check if overwriting and take appropriate actions */
713  if (mi != GID_LOOKUP_MISS && !gid_address_cmp (&old_map->eid, &a->eid))
714  {
715  clib_warning ("eid %U found in the eid-table", format_gid_address,
716  &a->eid);
717  return VNET_API_ERROR_VALUE_EXIST;
718  }
719 
720  pool_get (lcm->mapping_pool, m);
721  gid_address_copy (&m->eid, &a->eid);
723  m->ttl = a->ttl;
724  m->action = a->action;
725  m->local = a->local;
726  m->is_static = a->is_static;
727  m->key = vec_dup (a->key);
728  m->key_id = a->key_id;
730 
731  map_index = m - lcm->mapping_pool;
732  gid_dictionary_add_del (&lcm->mapping_index_by_gid, &a->eid, map_index,
733  1);
734 
736  {
737  clib_warning ("Locator set with index %d doesn't exist",
738  a->locator_set_index);
739  return VNET_API_ERROR_INVALID_VALUE;
740  }
741 
742  /* add eid to list of eids supported by locator-set */
744  eid_indexes = vec_elt_at_index (lcm->locator_set_to_eids,
745  a->locator_set_index);
746  vec_add1 (eid_indexes[0], map_index);
747 
748  if (a->local)
749  {
750  /* mark as local */
751  vec_add1 (lcm->local_mappings_indexes, map_index);
752  }
753  map_index_result[0] = map_index;
754  }
755  else
756  {
757  if (mi == GID_LOOKUP_MISS)
758  {
759  clib_warning ("eid %U not found in the eid-table",
760  format_gid_address, &a->eid);
761  return VNET_API_ERROR_INVALID_VALUE;
762  }
763 
764  /* clear locator-set to eids binding */
765  eid_indexes = vec_elt_at_index (lcm->locator_set_to_eids,
766  a->locator_set_index);
767  for (i = 0; i < vec_len (eid_indexes[0]); i++)
768  {
769  map_indexp = vec_elt_at_index (eid_indexes[0], i);
770  if (map_indexp[0] == mi)
771  break;
772  }
773  vec_del1 (eid_indexes[0], i);
774 
775  /* remove local mark if needed */
776  m = pool_elt_at_index (lcm->mapping_pool, mi);
777  if (m->local)
778  {
779  /* Remove adjacencies associated with the local mapping */
780  rmts_idxp = hash_get (lcm->lcl_to_rmt_adjs_by_lcl_idx, mi);
781  if (rmts_idxp)
782  {
783  rmts =
784  pool_elt_at_index (lcm->lcl_to_rmt_adjacencies, rmts_idxp[0]);
785  vec_foreach (remote_idxp, rmts[0])
786  {
787  dp_del_fwd_entry (lcm, remote_idxp[0]);
788  }
789  vec_free (rmts[0]);
790  pool_put (lcm->lcl_to_rmt_adjacencies, rmts);
792  }
793 
794  u32 k, *lm_indexp;
795  for (k = 0; k < vec_len (lcm->local_mappings_indexes); k++)
796  {
797  lm_indexp = vec_elt_at_index (lcm->local_mappings_indexes, k);
798  if (lm_indexp[0] == mi)
799  break;
800  }
802  }
803  else
804  {
805  /* Remove remote (if present) from the vectors of lcl-to-rmts
806  * TODO: Address this in a more efficient way.
807  */
808  /* *INDENT-OFF* */
810  ({
811  vec_foreach_index (rmts_itr, rmts[0])
812  {
813  remote_idx = vec_elt (rmts[0], rmts_itr);
814  if (mi == remote_idx)
815  {
816  vec_del1 (rmts[0], rmts_itr);
817  break;
818  }
819  }
820  }));
821  /* *INDENT-ON* */
822  }
823 
824  /* remove mapping from dictionary */
826  gid_address_free (&m->eid);
827  pool_put_index (lcm->mapping_pool, mi);
828  }
829 
830  return 0;
831 }
832 
833 /**
834  * Add/update/delete mapping to/in/from map-cache.
835  */
836 int
838  u32 * map_index_result)
839 {
840  uword *dp_table = 0;
841  u32 vni;
842  u8 type;
843 
845 
847  {
848  clib_warning ("LISP is disabled!");
849  return VNET_API_ERROR_LISP_DISABLED;
850  }
851 
852  vni = gid_address_vni (&a->eid);
853  type = gid_address_type (&a->eid);
854  if (GID_ADDR_IP_PREFIX == type)
855  dp_table = hash_get (lcm->table_id_by_vni, vni);
856  else if (GID_ADDR_MAC == type)
857  dp_table = hash_get (lcm->bd_id_by_vni, vni);
858 
859  if (!dp_table && GID_ADDR_NSH != type)
860  {
861  clib_warning ("vni %d not associated to a %s!", vni,
862  GID_ADDR_IP_PREFIX == type ? "vrf" : "bd");
863  return VNET_API_ERROR_INVALID_VALUE;
864  }
865 
866  /* store/remove mapping from map-cache */
867  return vnet_lisp_map_cache_add_del (a, map_index_result);
868 }
869 
870 static int
871 add_l2_arp_bd (BVT (clib_bihash_kv) * kvp, void *arg)
872 {
873  u32 **ht = arg;
874  u32 version = (u32) kvp->key[0];
875  if (AF_IP6 == version)
876  return (BIHASH_WALK_CONTINUE);
877 
878  u32 bd = (u32) (kvp->key[0] >> 32);
879  hash_set (ht[0], bd, 0);
880  return (BIHASH_WALK_CONTINUE);
881 }
882 
883 u32 *
885 {
887  u32 *bds = 0;
888 
890  add_l2_arp_bd, &bds);
891  return bds;
892 }
893 
894 static int
895 add_ndp_bd (BVT (clib_bihash_kv) * kvp, void *arg)
896 {
897  u32 **ht = arg;
898  u32 version = (u32) kvp->key[0];
899  if (AF_IP4 == version)
900  return (BIHASH_WALK_CONTINUE);
901 
902  u32 bd = (u32) (kvp->key[0] >> 32);
903  hash_set (ht[0], bd, 0);
904  return (BIHASH_WALK_CONTINUE);
905 }
906 
907 u32 *
909 {
911  u32 *bds = 0;
912 
914  add_ndp_bd, &bds);
915  return bds;
916 }
917 
918 typedef struct
919 {
920  void *vector;
923 
924 static int
925 add_l2_arp_entry (BVT (clib_bihash_kv) * kvp, void *arg)
926 {
928  lisp_api_l2_arp_entry_t **vector = a->vector, e;
929 
930  u32 version = (u32) kvp->key[0];
931  if (AF_IP6 == version)
932  return (BIHASH_WALK_CONTINUE);
933 
934  u32 bd = (u32) (kvp->key[0] >> 32);
935 
936  if (bd == a->bd)
937  {
938  mac_copy (e.mac, (void *) &kvp->value);
939  e.ip4 = (u32) kvp->key[1];
940  vec_add1 (vector[0], e);
941  }
942  return (BIHASH_WALK_CONTINUE);
943 }
944 
947 {
951 
952  a.vector = &entries;
953  a.bd = bd;
954 
956  add_l2_arp_entry, &a);
957  return entries;
958 }
959 
960 static int
961 add_ndp_entry (BVT (clib_bihash_kv) * kvp, void *arg)
962 {
964  lisp_api_ndp_entry_t **vector = a->vector, e;
965 
966  u32 version = (u32) kvp->key[0];
967  if (AF_IP4 == version)
968  return (BIHASH_WALK_CONTINUE);
969 
970  u32 bd = (u32) (kvp->key[0] >> 32);
971 
972  if (bd == a->bd)
973  {
974  mac_copy (e.mac, (void *) &kvp->value);
975  clib_memcpy (e.ip6, &kvp->key[1], 16);
976  vec_add1 (vector[0], e);
977  }
978  return (BIHASH_WALK_CONTINUE);
979 }
980 
983 {
987 
988  a.vector = &entries;
989  a.bd = bd;
990 
992  add_ndp_entry, &a);
993  return entries;
994 }
995 
996 int
998 {
1000  {
1001  clib_warning ("LISP is disabled!");
1002  return VNET_API_ERROR_LISP_DISABLED;
1003  }
1004 
1006  int rc = 0;
1007 
1008  u64 res = gid_dictionary_lookup (&lcm->mapping_index_by_gid, key);
1009  if (is_add)
1010  {
1011  if (res != GID_LOOKUP_MISS_L2)
1012  {
1013  clib_warning ("Entry %U exists in DB!", format_gid_address, key);
1014  return VNET_API_ERROR_ENTRY_ALREADY_EXISTS;
1015  }
1016  u64 val = mac_to_u64 (mac);
1018  1 /* is_add */ );
1019  }
1020  else
1021  {
1022  if (res == GID_LOOKUP_MISS_L2)
1023  {
1024  clib_warning ("ONE entry %U not found - cannot delete!",
1025  format_gid_address, key);
1026  return -1;
1027  }
1029  0 /* is_add */ );
1030  }
1031 
1032  return rc;
1033 }
1034 
1035 int
1036 vnet_lisp_eid_table_map (u32 vni, u32 dp_id, u8 is_l2, u8 is_add)
1037 {
1039  uword *dp_idp, *vnip, **dp_table_by_vni, **vni_by_dp_table;
1040 
1041  if (vnet_lisp_enable_disable_status () == 0)
1042  {
1043  clib_warning ("LISP is disabled!");
1044  return VNET_API_ERROR_LISP_DISABLED;
1045  }
1046 
1047  dp_table_by_vni = is_l2 ? &lcm->bd_id_by_vni : &lcm->table_id_by_vni;
1048  vni_by_dp_table = is_l2 ? &lcm->vni_by_bd_id : &lcm->vni_by_table_id;
1049 
1050  if (!is_l2 && (vni == 0 || dp_id == 0))
1051  {
1052  clib_warning ("can't add/del default vni-vrf mapping!");
1053  return -1;
1054  }
1055 
1056  dp_idp = hash_get (dp_table_by_vni[0], vni);
1057  vnip = hash_get (vni_by_dp_table[0], dp_id);
1058 
1059  if (is_add)
1060  {
1061  if (dp_idp || vnip)
1062  {
1063  clib_warning ("vni %d or vrf %d already used in vrf/vni "
1064  "mapping!", vni, dp_id);
1065  return -1;
1066  }
1067  hash_set (dp_table_by_vni[0], vni, dp_id);
1068  hash_set (vni_by_dp_table[0], dp_id, vni);
1069 
1070  /* create dp iface */
1071  dp_add_del_iface (lcm, vni, is_l2, 1 /* is_add */ ,
1072  1 /* with_default_route */ );
1073  }
1074  else
1075  {
1076  if (!dp_idp || !vnip)
1077  {
1078  clib_warning ("vni %d or vrf %d not used in any vrf/vni! "
1079  "mapping!", vni, dp_id);
1080  return -1;
1081  }
1082  /* remove dp iface */
1083  dp_add_del_iface (lcm, vni, is_l2, 0 /* is_add */ , 0 /* unused */ );
1084 
1085  hash_unset (dp_table_by_vni[0], vni);
1086  hash_unset (vni_by_dp_table[0], dp_id);
1087  }
1088  return 0;
1089 
1090 }
1091 
1092 /* return 0 if the two locator sets are identical 1 otherwise */
1093 static u8
1094 compare_locators (lisp_cp_main_t * lcm, u32 * old_ls_indexes,
1095  locator_t * new_locators)
1096 {
1097  u32 i, old_li;
1098  locator_t *old_loc, *new_loc;
1099 
1100  if (vec_len (old_ls_indexes) != vec_len (new_locators))
1101  return 1;
1102 
1103  for (i = 0; i < vec_len (new_locators); i++)
1104  {
1105  old_li = vec_elt (old_ls_indexes, i);
1106  old_loc = pool_elt_at_index (lcm->locator_pool, old_li);
1107 
1108  new_loc = vec_elt_at_index (new_locators, i);
1109 
1110  if (locator_cmp (old_loc, new_loc))
1111  return 1;
1112  }
1113  return 0;
1114 }
1115 
1116 typedef struct
1117 {
1119  void *lcm;
1122 
1123 /**
1124  * Callback invoked when a sub-prefix is found
1125  */
1126 static void
1128 {
1129  u8 delete = 0;
1130  remove_mapping_args_t *a = arg;
1131  lisp_cp_main_t *lcm = a->lcm;
1132  mapping_t *m;
1133  locator_set_t *ls;
1134 
1135  m = pool_elt_at_index (lcm->mapping_pool, mi);
1136  if (!m)
1137  return;
1138 
1140 
1141  if (a->is_negative)
1142  {
1143  if (0 != vec_len (ls->locator_indices))
1144  delete = 1;
1145  }
1146  else
1147  {
1148  if (0 == vec_len (ls->locator_indices))
1149  delete = 1;
1150  }
1151 
1152  if (delete)
1153  vec_add1 (a->eids_to_be_deleted, m->eid);
1154 }
1155 
1156 /**
1157  * This function searches map cache and looks for IP prefixes that are subset
1158  * of the provided one. If such prefix is found depending on 'is_negative'
1159  * it does follows:
1160  *
1161  * 1) if is_negative is true and found prefix points to positive mapping,
1162  * then the mapping is removed
1163  * 2) if is_negative is false and found prefix points to negative mapping,
1164  * then the mapping is removed
1165  */
1166 static void
1168  u8 is_negative)
1169 {
1170  gid_address_t *e;
1172 
1173  clib_memset (&a, 0, sizeof (a));
1174 
1175  /* do this only in src/dst mode ... */
1176  if (MR_MODE_SRC_DST != lcm->map_request_mode)
1177  return;
1178 
1179  /* ... and only for IP prefix */
1180  if (GID_ADDR_SRC_DST != gid_address_type (eid)
1182  return;
1183 
1184  a.is_negative = is_negative;
1185  a.lcm = lcm;
1186 
1189 
1191  {
1192  vnet_lisp_add_del_adjacency_args_t _adj_args, *adj_args = &_adj_args;
1193 
1194  clib_memset (adj_args, 0, sizeof (adj_args[0]));
1195  gid_address_copy (&adj_args->reid, e);
1196  adj_args->is_add = 0;
1197  if (vnet_lisp_add_del_adjacency (adj_args))
1198  clib_warning ("failed to del adjacency!");
1199 
1200  vnet_lisp_del_mapping (e, NULL);
1201  }
1202 
1204 }
1205 
1206 static int
1208 {
1209  fib_node_index_t fei;
1212 
1213  ip_address_to_fib_prefix (addr, &prefix);
1214 
1215  fei = fib_table_lookup (0, &prefix);
1216  flags = fib_entry_get_flags (fei);
1217  return (FIB_ENTRY_FLAG_LOCAL & flags);
1218 }
1219 
1220 /**
1221  * Adds/updates mapping. Does not program forwarding.
1222  *
1223  * @param a parameters of the new mapping
1224  * @param rlocs vector of remote locators
1225  * @param res_map_index index of the newly created mapping
1226  * @param locators_changed indicator if locators were updated in the mapping
1227  * @return return code
1228  */
1229 int
1231  locator_t * rlocs,
1232  u32 * res_map_index, u8 * is_updated)
1233 {
1234  vnet_lisp_add_del_locator_set_args_t _ls_args, *ls_args = &_ls_args;
1236  u32 mi, ls_index = 0, dst_map_index;
1237  mapping_t *old_map;
1238  locator_t *loc;
1239 
1240  if (vnet_lisp_enable_disable_status () == 0)
1241  {
1242  clib_warning ("LISP is disabled!");
1243  return VNET_API_ERROR_LISP_DISABLED;
1244  }
1245 
1246  if (res_map_index)
1247  res_map_index[0] = ~0;
1248  if (is_updated)
1249  is_updated[0] = 0;
1250 
1251  clib_memset (ls_args, 0, sizeof (ls_args[0]));
1252 
1253  ls_args->locators = rlocs;
1255  old_map = ((u32) ~ 0 != mi) ? pool_elt_at_index (lcm->mapping_pool, mi) : 0;
1256 
1257  /* check if none of the locators match locally configured address */
1258  vec_foreach (loc, rlocs)
1259  {
1260  ip_prefix_t *p = &gid_address_ippref (&loc->address);
1261  if (is_local_ip (lcm, &ip_prefix_addr (p)))
1262  {
1263  clib_warning ("RLOC %U matches a local address!",
1264  format_gid_address, &loc->address);
1265  return VNET_API_ERROR_LISP_RLOC_LOCAL;
1266  }
1267  }
1268 
1269  /* overwrite: if mapping already exists, decide if locators should be
1270  * updated and be done */
1271  if (old_map && gid_address_cmp (&old_map->eid, &a->eid) == 0)
1272  {
1273  if (!a->is_static && (old_map->is_static || old_map->local))
1274  {
1275  /* do not overwrite local or static remote mappings */
1276  clib_warning ("mapping %U rejected due to collision with local "
1277  "or static remote mapping!", format_gid_address,
1278  &a->eid);
1279  return 0;
1280  }
1281 
1282  locator_set_t *old_ls;
1283 
1284  /* update mapping attributes */
1285  old_map->action = a->action;
1286  if (old_map->action != a->action && NULL != is_updated)
1287  is_updated[0] = 1;
1288 
1289  old_map->authoritative = a->authoritative;
1290  old_map->ttl = a->ttl;
1291 
1292  old_ls = pool_elt_at_index (lcm->locator_set_pool,
1293  old_map->locator_set_index);
1294  if (compare_locators (lcm, old_ls->locator_indices, ls_args->locators))
1295  {
1296  /* set locator-set index to overwrite */
1297  ls_args->is_add = 1;
1298  ls_args->index = old_map->locator_set_index;
1299  vnet_lisp_add_del_locator_set (ls_args, 0);
1300  if (is_updated)
1301  is_updated[0] = 1;
1302  }
1303  if (res_map_index)
1304  res_map_index[0] = mi;
1305  }
1306  /* new mapping */
1307  else
1308  {
1309  if (is_updated)
1310  is_updated[0] = 1;
1311  remove_overlapping_sub_prefixes (lcm, &a->eid, 0 == ls_args->locators);
1312 
1313  ls_args->is_add = 1;
1314  ls_args->index = ~0;
1315 
1316  vnet_lisp_add_del_locator_set (ls_args, &ls_index);
1317 
1318  /* add mapping */
1319  a->is_add = 1;
1320  a->locator_set_index = ls_index;
1321  vnet_lisp_map_cache_add_del (a, &dst_map_index);
1322 
1323  if (res_map_index)
1324  res_map_index[0] = dst_map_index;
1325  }
1326 
1327  /* success */
1328  return 0;
1329 }
1330 
1331 /**
1332  * Removes a mapping. Does not program forwarding.
1333  *
1334  * @param eid end-host identifier
1335  * @param res_map_index index of the removed mapping
1336  * @return return code
1337  */
1338 int
1340 {
1342  vnet_lisp_add_del_mapping_args_t _m_args, *m_args = &_m_args;
1343  vnet_lisp_add_del_locator_set_args_t _ls_args, *ls_args = &_ls_args;
1344  mapping_t *old_map;
1345  u32 mi;
1346 
1347  clib_memset (ls_args, 0, sizeof (ls_args[0]));
1348  clib_memset (m_args, 0, sizeof (m_args[0]));
1349  if (res_map_index)
1350  res_map_index[0] = ~0;
1351 
1352  mi = gid_dictionary_lookup (&lcm->mapping_index_by_gid, eid);
1353  old_map = ((u32) ~ 0 != mi) ? pool_elt_at_index (lcm->mapping_pool, mi) : 0;
1354 
1355  if (old_map == 0 || gid_address_cmp (&old_map->eid, eid) != 0)
1356  {
1357  clib_warning ("cannot delete mapping for eid %U",
1358  format_gid_address, eid);
1359  return -1;
1360  }
1361 
1362  m_args->is_add = 0;
1363  gid_address_copy (&m_args->eid, eid);
1364  m_args->locator_set_index = old_map->locator_set_index;
1365 
1366  ls_args->is_add = 0;
1367  ls_args->index = old_map->locator_set_index;
1368 
1369  /* delete timer associated to the mapping if any */
1370  if (old_map->timer_set)
1371  TW (tw_timer_stop) (&lcm->wheel, old_map->timer_handle);
1372 
1373  /* delete locator set */
1374  vnet_lisp_add_del_locator_set (ls_args, 0);
1375 
1376  /* delete mapping associated from map-cache */
1377  vnet_lisp_map_cache_add_del (m_args, 0);
1378 
1379  /* return old mapping index */
1380  if (res_map_index)
1381  res_map_index[0] = mi;
1382 
1383  /* success */
1384  return 0;
1385 }
1386 
1387 int
1389 {
1390  int rv = 0;
1391  u32 mi, *map_indices = 0, *map_indexp;
1393  vnet_lisp_add_del_mapping_args_t _dm_args, *dm_args = &_dm_args;
1394  vnet_lisp_add_del_locator_set_args_t _ls, *ls = &_ls;
1395 
1396  /* *INDENT-OFF* */
1397  pool_foreach_index (mi, lcm->mapping_pool,
1398  ({
1399  vec_add1 (map_indices, mi);
1400  }));
1401  /* *INDENT-ON* */
1402 
1403  vec_foreach (map_indexp, map_indices)
1404  {
1405  mapping_t *map = pool_elt_at_index (lcm->mapping_pool, map_indexp[0]);
1406  if (!map->local)
1407  {
1408  dp_del_fwd_entry (lcm, map_indexp[0]);
1409 
1410  dm_args->is_add = 0;
1411  gid_address_copy (&dm_args->eid, &map->eid);
1412  dm_args->locator_set_index = map->locator_set_index;
1413 
1414  /* delete mapping associated to fwd entry */
1415  vnet_lisp_map_cache_add_del (dm_args, 0);
1416 
1417  ls->is_add = 0;
1418  ls->local = 0;
1419  ls->index = map->locator_set_index;
1420  /* delete locator set */
1421  rv = vnet_lisp_add_del_locator_set (ls, 0);
1422  if (rv != 0)
1423  goto cleanup;
1424  }
1425  }
1426 
1427 cleanup:
1428  if (map_indices)
1429  vec_free (map_indices);
1430  return rv;
1431 }
1432 
1433 /**
1434  * Adds adjacency or removes forwarding entry associated to remote mapping.
1435  * Note that adjacencies are not stored, they only result in forwarding entries
1436  * being created.
1437  */
1438 int
1440 {
1442  u32 local_mi, remote_mi = ~0;
1443 
1444  if (vnet_lisp_enable_disable_status () == 0)
1445  {
1446  clib_warning ("LISP is disabled!");
1447  return VNET_API_ERROR_LISP_DISABLED;
1448  }
1449 
1451  &a->reid, &a->leid);
1452  if (GID_LOOKUP_MISS == remote_mi)
1453  {
1454  clib_warning ("Remote eid %U not found. Cannot add adjacency!",
1455  format_gid_address, &a->reid);
1456 
1457  return -1;
1458  }
1459 
1460  if (a->is_add)
1461  {
1462  /* check if source eid has an associated mapping. If pitr mode is on,
1463  * just use the pitr's mapping */
1464  if (lcm->flags & LISP_FLAG_PITR_MODE)
1465  {
1466  if (lcm->pitr_map_index != ~0)
1467  {
1468  local_mi = lcm->pitr_map_index;
1469  }
1470  else
1471  {
1472  /* PITR mode is on, but no mapping is configured */
1473  return -1;
1474  }
1475  }
1476  else
1477  {
1478  if (gid_address_type (&a->reid) == GID_ADDR_NSH)
1479  {
1480  if (lcm->nsh_map_index == ~0)
1481  local_mi = GID_LOOKUP_MISS;
1482  else
1483  local_mi = lcm->nsh_map_index;
1484  }
1485  else
1486  {
1487  local_mi = gid_dictionary_lookup (&lcm->mapping_index_by_gid,
1488  &a->leid);
1489  }
1490  }
1491 
1492  if (GID_LOOKUP_MISS == local_mi)
1493  {
1494  clib_warning ("Local eid %U not found. Cannot add adjacency!",
1495  format_gid_address, &a->leid);
1496 
1497  return -1;
1498  }
1499 
1500  /* update forwarding */
1501  dp_add_fwd_entry (lcm, local_mi, remote_mi);
1502  }
1503  else
1504  dp_del_fwd_entry (lcm, remote_mi);
1505 
1506  return 0;
1507 }
1508 
1509 int
1511 {
1513 
1514  if (vnet_lisp_enable_disable_status () == 0)
1515  {
1516  clib_warning ("LISP is disabled!");
1517  return VNET_API_ERROR_LISP_DISABLED;
1518  }
1519 
1520  if (mode >= _MR_MODE_MAX)
1521  {
1522  clib_warning ("Invalid LISP map request mode %d!", mode);
1523  return VNET_API_ERROR_INVALID_ARGUMENT;
1524  }
1525 
1526  lcm->map_request_mode = mode;
1527  return 0;
1528 }
1529 
1530 int
1531 vnet_lisp_nsh_set_locator_set (u8 * locator_set_name, u8 is_add)
1532 {
1535  u32 locator_set_index = ~0;
1536  mapping_t *m;
1537  uword *p;
1538 
1539  if (vnet_lisp_enable_disable_status () == 0)
1540  {
1541  clib_warning ("LISP is disabled!");
1542  return VNET_API_ERROR_LISP_DISABLED;
1543  }
1544 
1545  if (is_add)
1546  {
1547  if (lcm->nsh_map_index == (u32) ~ 0)
1548  {
1549  p = hash_get_mem (lcm->locator_set_index_by_name, locator_set_name);
1550  if (!p)
1551  {
1552  clib_warning ("locator-set %v doesn't exist", locator_set_name);
1553  return -1;
1554  }
1555  locator_set_index = p[0];
1556 
1557  pool_get (lcm->mapping_pool, m);
1558  clib_memset (m, 0, sizeof *m);
1559  m->locator_set_index = locator_set_index;
1560  m->local = 1;
1561  m->nsh_set = 1;
1562  lcm->nsh_map_index = m - lcm->mapping_pool;
1563 
1564  if (~0 == vnet_lisp_gpe_add_nsh_iface (lgm))
1565  return -1;
1566  }
1567  }
1568  else
1569  {
1570  if (lcm->nsh_map_index != (u32) ~ 0)
1571  {
1572  /* remove NSH mapping */
1574  lcm->nsh_map_index = ~0;
1576  }
1577  }
1578  return 0;
1579 }
1580 
1581 int
1582 vnet_lisp_pitr_set_locator_set (u8 * locator_set_name, u8 is_add)
1583 {
1585  u32 locator_set_index = ~0;
1586  mapping_t *m;
1587  uword *p;
1588 
1589  if (vnet_lisp_enable_disable_status () == 0)
1590  {
1591  clib_warning ("LISP is disabled!");
1592  return VNET_API_ERROR_LISP_DISABLED;
1593  }
1594 
1595  p = hash_get_mem (lcm->locator_set_index_by_name, locator_set_name);
1596  if (!p)
1597  {
1598  clib_warning ("locator-set %v doesn't exist", locator_set_name);
1599  return -1;
1600  }
1601  locator_set_index = p[0];
1602 
1603  if (is_add)
1604  {
1605  pool_get (lcm->mapping_pool, m);
1606  m->locator_set_index = locator_set_index;
1607  m->local = 1;
1608  m->pitr_set = 1;
1609  lcm->pitr_map_index = m - lcm->mapping_pool;
1610  }
1611  else
1612  {
1613  /* remove pitr mapping */
1615  lcm->pitr_map_index = ~0;
1616  }
1617  return 0;
1618 }
1619 
1620 int
1622 {
1624  if (0 == value)
1625  {
1626  return VNET_API_ERROR_INVALID_ARGUMENT;
1627  }
1628 
1630  return 0;
1631 }
1632 
1633 u32
1635 {
1637  return lcm->max_expired_map_registers;
1638 }
1639 
1640 /**
1641  * Configure Proxy-ETR
1642  *
1643  * @param ip PETR's IP address
1644  * @param is_add Flag that indicates if this is an addition or removal
1645  *
1646  * return 0 on success
1647  */
1648 int
1650 {
1652  u32 ls_index = ~0;
1653  mapping_t *m;
1654  vnet_lisp_add_del_locator_set_args_t _ls_args, *ls_args = &_ls_args;
1655  locator_t loc;
1656 
1657  if (vnet_lisp_enable_disable_status () == 0)
1658  {
1659  clib_warning ("LISP is disabled!");
1660  return VNET_API_ERROR_LISP_DISABLED;
1661  }
1662 
1663  clib_memset (ls_args, 0, sizeof (*ls_args));
1664 
1665  if (is_add)
1666  {
1667  /* Create placeholder petr locator-set */
1668  clib_memset (&loc, 0, sizeof (loc));
1669  gid_address_from_ip (&loc.address, ip);
1670  loc.priority = 1;
1671  loc.state = loc.weight = 1;
1672  loc.local = 0;
1673 
1674  ls_args->is_add = 1;
1675  ls_args->index = ~0;
1676  vec_add1 (ls_args->locators, loc);
1677  vnet_lisp_add_del_locator_set (ls_args, &ls_index);
1678 
1679  /* Add petr mapping */
1680  pool_get (lcm->mapping_pool, m);
1681  m->locator_set_index = ls_index;
1682  lcm->petr_map_index = m - lcm->mapping_pool;
1683 
1684  /* Enable use-petr */
1685  lcm->flags |= LISP_FLAG_USE_PETR;
1686  }
1687  else
1688  {
1690 
1691  /* Remove petr locator */
1692  ls_args->is_add = 0;
1693  ls_args->index = m->locator_set_index;
1694  vnet_lisp_add_del_locator_set (ls_args, 0);
1695 
1696  /* Remove petr mapping */
1698 
1699  /* Disable use-petr */
1700  lcm->flags &= ~LISP_FLAG_USE_PETR;
1701  lcm->petr_map_index = ~0;
1702  }
1703  return 0;
1704 }
1705 
1706 /* cleans locator to locator-set data and removes locators not part of
1707  * any locator-set */
1708 static void
1710 {
1711  u32 i, j, *loc_indexp, *ls_indexp, **ls_indexes, *to_be_deleted = 0;
1713  for (i = 0; i < vec_len (ls->locator_indices); i++)
1714  {
1715  loc_indexp = vec_elt_at_index (ls->locator_indices, i);
1716  ls_indexes = vec_elt_at_index (lcm->locator_to_locator_sets,
1717  loc_indexp[0]);
1718  for (j = 0; j < vec_len (ls_indexes[0]); j++)
1719  {
1720  ls_indexp = vec_elt_at_index (ls_indexes[0], j);
1721  if (ls_indexp[0] == lsi)
1722  break;
1723  }
1724 
1725  /* delete index for removed locator-set */
1726  vec_del1 (ls_indexes[0], j);
1727 
1728  /* delete locator if it's part of no locator-set */
1729  if (vec_len (ls_indexes[0]) == 0)
1730  {
1731  pool_put_index (lcm->locator_pool, loc_indexp[0]);
1732  vec_add1 (to_be_deleted, i);
1733  }
1734  }
1735 
1736  if (to_be_deleted)
1737  {
1738  for (i = 0; i < vec_len (to_be_deleted); i++)
1739  {
1740  loc_indexp = vec_elt_at_index (to_be_deleted, i);
1741  vec_del1 (ls->locator_indices, loc_indexp[0]);
1742  }
1743  vec_free (to_be_deleted);
1744  }
1745 }
1746 
1747 static inline uword *
1749 {
1751 
1752  ASSERT (a != NULL);
1753  ASSERT (p != NULL);
1754 
1755  /* find locator-set */
1756  if (a->local)
1757  {
1758  ASSERT (a->name);
1760  }
1761  else
1762  {
1763  *p = a->index;
1764  }
1765 
1766  return p;
1767 }
1768 
1769 static inline int
1771  locator_t * loc)
1772 {
1773  locator_t *itloc;
1774  u32 *locit;
1775 
1776  ASSERT (ls != NULL);
1777  ASSERT (loc != NULL);
1778 
1779  vec_foreach (locit, ls->locator_indices)
1780  {
1781  itloc = pool_elt_at_index (lcm->locator_pool, locit[0]);
1782  if ((ls->local && itloc->sw_if_index == loc->sw_if_index) ||
1783  (!ls->local && !gid_address_cmp (&itloc->address, &loc->address)))
1784  {
1785  clib_warning ("Duplicate locator");
1786  return VNET_API_ERROR_VALUE_EXIST;
1787  }
1788  }
1789 
1790  return 0;
1791 }
1792 
1793 static void
1795  u32 mapping_index, u8 remove_only)
1796 {
1797  fwd_entry_t *fwd;
1798  mapping_t *map;
1799  uword *fei = 0, *rmts_idxp = 0;
1800  u32 **rmts = 0, *remote_idxp = 0, *rmts_copy = 0;
1802  clib_memset (a, 0, sizeof (*a));
1803 
1804  map = pool_elt_at_index (lcm->mapping_pool, mapping_index);
1805 
1806  if (map->local)
1807  {
1808  rmts_idxp = hash_get (lcm->lcl_to_rmt_adjs_by_lcl_idx, mapping_index);
1809  if (rmts_idxp)
1810  {
1811  rmts =
1812  pool_elt_at_index (lcm->lcl_to_rmt_adjacencies, rmts_idxp[0]);
1813  rmts_copy = vec_dup (rmts[0]);
1814 
1815  vec_foreach (remote_idxp, rmts_copy)
1816  {
1817  fei = hash_get (lcm->fwd_entry_by_mapping_index, remote_idxp[0]);
1818  if (!fei)
1819  continue;
1820 
1821  fwd = pool_elt_at_index (lcm->fwd_entry_pool, fei[0]);
1822  a->is_add = 0;
1823  gid_address_copy (&a->leid, &fwd->leid);
1824  gid_address_copy (&a->reid, &fwd->reid);
1826 
1827  if (!remove_only)
1828  {
1829  a->is_add = 1;
1831  }
1832  }
1833  vec_free (rmts_copy);
1834  }
1835  }
1836  else
1837  {
1838  fei = hash_get (lcm->fwd_entry_by_mapping_index, mapping_index);
1839  if (!fei)
1840  return;
1841 
1842  fwd = pool_elt_at_index (lcm->fwd_entry_pool, fei[0]);
1843  a->is_add = 0;
1844  gid_address_copy (&a->leid, &fwd->leid);
1845  gid_address_copy (&a->reid, &fwd->reid);
1847 
1848  if (!remove_only)
1849  {
1850  a->is_add = 1;
1852  }
1853  }
1854 }
1855 
1856 static void
1858  u32 ls_index, u8 remove_only)
1859 {
1860  u32 i, *map_indexp;
1861  u32 **eid_indexes;
1862 
1863  if (vec_len (lcm->locator_set_to_eids) <= ls_index)
1864  return;
1865 
1866  eid_indexes = vec_elt_at_index (lcm->locator_set_to_eids, ls_index);
1867 
1868  for (i = 0; i < vec_len (eid_indexes[0]); i++)
1869  {
1870  map_indexp = vec_elt_at_index (eid_indexes[0], i);
1871  update_adjacencies_by_map_index (lcm, map_indexp[0], remove_only);
1872  }
1873 }
1874 
1875 static inline void
1877  u32 ls_index, u32 loc_id)
1878 {
1880  u32 **ls_indexes = NULL;
1881 
1882  ASSERT (ls != NULL);
1883  ASSERT (locit != NULL);
1884 
1885  ls_indexes = vec_elt_at_index (lcm->locator_to_locator_sets, locit[0]);
1886  pool_put_index (lcm->locator_pool, locit[0]);
1887  vec_del1 (ls->locator_indices, loc_id);
1888  vec_del1 (ls_indexes[0], ls_index);
1889 }
1890 
1891 int
1893  locator_set_t * ls, u32 * ls_result)
1894 {
1896  locator_t *loc = NULL, *itloc = NULL;
1897  uword _p = (u32) ~ 0, *p = &_p;
1898  u32 loc_index = ~0, ls_index = ~0, *locit = NULL, **ls_indexes = NULL;
1899  u32 loc_id = ~0;
1900  int ret = 0;
1901 
1902  ASSERT (a != NULL);
1903 
1904  if (vnet_lisp_enable_disable_status () == 0)
1905  {
1906  clib_warning ("LISP is disabled!");
1907  return VNET_API_ERROR_LISP_DISABLED;
1908  }
1909 
1910  p = get_locator_set_index (a, p);
1911  if (!p)
1912  {
1913  clib_warning ("locator-set %v doesn't exist", a->name);
1914  return VNET_API_ERROR_INVALID_ARGUMENT;
1915  }
1916 
1917  if (ls == 0)
1918  {
1919  ls = pool_elt_at_index (lcm->locator_set_pool, p[0]);
1920  if (!ls)
1921  {
1922  clib_warning ("locator-set %d to be overwritten doesn't exist!",
1923  p[0]);
1924  return VNET_API_ERROR_INVALID_ARGUMENT;
1925  }
1926  }
1927 
1928  if (a->is_add)
1929  {
1930  if (ls_result)
1931  ls_result[0] = p[0];
1932 
1933  /* allocate locators */
1934  vec_foreach (itloc, a->locators)
1935  {
1936  ret = is_locator_in_locator_set (lcm, ls, itloc);
1937  if (0 != ret)
1938  {
1939  return ret;
1940  }
1941 
1942  pool_get (lcm->locator_pool, loc);
1943  loc[0] = itloc[0];
1944  loc_index = loc - lcm->locator_pool;
1945 
1946  vec_add1 (ls->locator_indices, loc_index);
1947 
1948  vec_validate (lcm->locator_to_locator_sets, loc_index);
1949  ls_indexes = vec_elt_at_index (lcm->locator_to_locator_sets,
1950  loc_index);
1951  vec_add1 (ls_indexes[0], p[0]);
1952  }
1953  }
1954  else
1955  {
1956  ls_index = p[0];
1957  u8 removed;
1958 
1959  vec_foreach (itloc, a->locators)
1960  {
1961  removed = 0;
1962  loc_id = 0;
1963  vec_foreach (locit, ls->locator_indices)
1964  {
1965  loc = pool_elt_at_index (lcm->locator_pool, locit[0]);
1966 
1967  if (loc->local && loc->sw_if_index == itloc->sw_if_index)
1968  {
1969  removed = 1;
1970  remove_locator_from_locator_set (ls, locit, ls_index, loc_id);
1971  }
1972  else if (0 == loc->local &&
1973  !gid_address_cmp (&loc->address, &itloc->address))
1974  {
1975  removed = 1;
1976  remove_locator_from_locator_set (ls, locit, ls_index, loc_id);
1977  }
1978 
1979  if (removed)
1980  {
1981  /* update fwd entries using this locator in DP */
1982  update_fwd_entries_by_locator_set (lcm, ls_index,
1983  vec_len (ls->locator_indices)
1984  == 0);
1985  }
1986 
1987  loc_id++;
1988  }
1989  }
1990  }
1991 
1992  return 0;
1993 }
1994 
1995 int
1997  u32 * ls_result)
1998 {
2000  locator_set_t *ls;
2001  uword _p = (u32) ~ 0, *p = &_p;
2002  u32 ls_index;
2003  u32 **eid_indexes;
2004  int ret = 0;
2005 
2006  if (vnet_lisp_enable_disable_status () == 0)
2007  {
2008  clib_warning ("LISP is disabled!");
2009  return VNET_API_ERROR_LISP_DISABLED;
2010  }
2011 
2012  if (a->is_add)
2013  {
2014  p = get_locator_set_index (a, p);
2015 
2016  /* overwrite */
2017  if (p && p[0] != (u32) ~ 0)
2018  {
2019  ls = pool_elt_at_index (lcm->locator_set_pool, p[0]);
2020  if (!ls)
2021  {
2022  clib_warning ("locator-set %d to be overwritten doesn't exist!",
2023  p[0]);
2024  return -1;
2025  }
2026 
2027  /* clean locator to locator-set vectors and remove locators if
2028  * they're not part of another locator-set */
2029  clean_locator_to_locator_set (lcm, p[0]);
2030 
2031  /* remove locator indices from locator set */
2032  vec_free (ls->locator_indices);
2033 
2034  ls_index = p[0];
2035 
2036  if (ls_result)
2037  ls_result[0] = p[0];
2038  }
2039  /* new locator-set */
2040  else
2041  {
2042  pool_get (lcm->locator_set_pool, ls);
2043  clib_memset (ls, 0, sizeof (*ls));
2044  ls_index = ls - lcm->locator_set_pool;
2045 
2046  if (a->local)
2047  {
2048  ls->name = vec_dup (a->name);
2049 
2050  if (!lcm->locator_set_index_by_name)
2052  hash_create_vec ( /* size */ 0, sizeof (ls->name[0]),
2053  sizeof (uword));
2055  ls_index);
2056 
2057  /* mark as local locator-set */
2058  vec_add1 (lcm->local_locator_set_indexes, ls_index);
2059  }
2060  ls->local = a->local;
2061  if (ls_result)
2062  ls_result[0] = ls_index;
2063  }
2064 
2065  ret = vnet_lisp_add_del_locator (a, ls, NULL);
2066  if (0 != ret)
2067  {
2068  return ret;
2069  }
2070  }
2071  else
2072  {
2073  p = get_locator_set_index (a, p);
2074  if (!p)
2075  {
2076  clib_warning ("locator-set %v doesn't exists", a->name);
2077  return -1;
2078  }
2079 
2080  ls = pool_elt_at_index (lcm->locator_set_pool, p[0]);
2081  if (!ls)
2082  {
2083  clib_warning ("locator-set with index %d doesn't exists", p[0]);
2084  return -1;
2085  }
2086 
2087  if (lcm->mreq_itr_rlocs == p[0])
2088  {
2089  clib_warning ("Can't delete the locator-set used to constrain "
2090  "the itr-rlocs in map-requests!");
2091  return -1;
2092  }
2093 
2094  if (vec_len (lcm->locator_set_to_eids) != 0)
2095  {
2096  eid_indexes = vec_elt_at_index (lcm->locator_set_to_eids, p[0]);
2097  if (vec_len (eid_indexes[0]) != 0)
2098  {
2099  clib_warning
2100  ("Can't delete a locator that supports a mapping!");
2101  return -1;
2102  }
2103  }
2104 
2105  /* clean locator to locator-sets data */
2106  clean_locator_to_locator_set (lcm, p[0]);
2107 
2108  if (ls->local)
2109  {
2110  u32 it, lsi;
2111 
2113  {
2114  lsi = vec_elt (lcm->local_locator_set_indexes, it);
2115  if (lsi == p[0])
2116  {
2118  break;
2119  }
2120  }
2122  }
2123  vec_free (ls->name);
2124  vec_free (ls->locator_indices);
2125  pool_put (lcm->locator_set_pool, ls);
2126  }
2127  return 0;
2128 }
2129 
2130 int
2132 {
2134 
2135  lcm->rloc_probing = is_enable;
2136  return 0;
2137 }
2138 
2139 int
2141 {
2143 
2144  lcm->map_registering = is_enable;
2145  return 0;
2146 }
2147 
2148 static void
2150 {
2151  udp_register_dst_port (vm, UDP_DST_PORT_lisp_cp,
2152  lisp_cp_input_node.index, 1 /* is_ip4 */ );
2153  udp_register_dst_port (vm, UDP_DST_PORT_lisp_cp6,
2154  lisp_cp_input_node.index, 0 /* is_ip4 */ );
2155 }
2156 
2157 static void
2159 {
2160  udp_unregister_dst_port (vm, UDP_DST_PORT_lisp_cp, 0 /* is_ip4 */ );
2161  udp_unregister_dst_port (vm, UDP_DST_PORT_lisp_cp6, 1 /* is_ip4 */ );
2162 }
2163 
2164 /**
2165  * lisp_cp_enable_l2_l3_ifaces
2166  *
2167  * Enable all l2 and l3 ifaces
2168  */
2169 static void
2170 lisp_cp_enable_l2_l3_ifaces (lisp_cp_main_t * lcm, u8 with_default_route)
2171 {
2172  u32 vni, dp_table;
2173 
2174  /* *INDENT-OFF* */
2175  hash_foreach(vni, dp_table, lcm->table_id_by_vni, ({
2176  dp_add_del_iface(lcm, vni, /* is_l2 */ 0, /* is_add */1,
2177  with_default_route);
2178  }));
2179  hash_foreach(vni, dp_table, lcm->bd_id_by_vni, ({
2180  dp_add_del_iface(lcm, vni, /* is_l2 */ 1, 1,
2181  with_default_route);
2182  }));
2183  /* *INDENT-ON* */
2184 }
2185 
2186 static void
2188 {
2189  u32 **rmts;
2190 
2191  /* clear interface table */
2193  pool_free (lcm->fwd_entry_pool);
2194  /* Clear state tracking rmt-lcl fwd entries */
2195  /* *INDENT-OFF* */
2197  {
2198  vec_free(rmts[0]);
2199  });
2200  /* *INDENT-ON* */
2203 }
2204 
2205 clib_error_t *
2207 {
2208  clib_error_t *error = 0;
2211 
2212  a->is_en = is_enable;
2213  error = vnet_lisp_gpe_enable_disable (a);
2214  if (error)
2215  {
2216  return clib_error_return (0, "failed to %s data-plane!",
2217  a->is_en ? "enable" : "disable");
2218  }
2219 
2220  /* decide what to do based on mode */
2221 
2222  if (lcm->flags & LISP_FLAG_XTR_MODE)
2223  {
2224  if (is_enable)
2225  {
2227  lisp_cp_enable_l2_l3_ifaces (lcm, 1 /* with_default_route */ );
2228  }
2229  else
2230  {
2233  }
2234  }
2235 
2236  if (lcm->flags & LISP_FLAG_PETR_MODE)
2237  {
2238  /* if in xTR mode, the LISP ports were already (un)registered above */
2239  if (!(lcm->flags & LISP_FLAG_XTR_MODE))
2240  {
2241  if (is_enable)
2243  else
2245  }
2246  }
2247 
2248  if (lcm->flags & LISP_FLAG_PITR_MODE)
2249  {
2250  if (is_enable)
2251  {
2252  /* install interfaces, but no default routes */
2253  lisp_cp_enable_l2_l3_ifaces (lcm, 0 /* with_default_route */ );
2254  }
2255  else
2256  {
2258  }
2259  }
2260 
2261  if (is_enable)
2263 
2264  /* update global flag */
2265  lcm->is_enabled = is_enable;
2266 
2267  return 0;
2268 }
2269 
2270 u8
2272 {
2274  return lcm->is_enabled;
2275 }
2276 
2277 int
2279 {
2281  u32 i;
2282  lisp_msmr_t _mr, *mr = &_mr;
2283 
2284  if (vnet_lisp_enable_disable_status () == 0)
2285  {
2286  clib_warning ("LISP is disabled!");
2287  return VNET_API_ERROR_LISP_DISABLED;
2288  }
2289 
2290  if (a->is_add)
2291  {
2292 
2293  if (get_map_resolver (&a->address))
2294  {
2295  clib_warning ("map-resolver %U already exists!", format_ip_address,
2296  &a->address);
2297  return -1;
2298  }
2299 
2300  clib_memset (mr, 0, sizeof (*mr));
2301  ip_address_copy (&mr->address, &a->address);
2302  vec_add1 (lcm->map_resolvers, *mr);
2303 
2304  if (vec_len (lcm->map_resolvers) == 1)
2305  lcm->do_map_resolver_election = 1;
2306  }
2307  else
2308  {
2309  for (i = 0; i < vec_len (lcm->map_resolvers); i++)
2310  {
2311  mr = vec_elt_at_index (lcm->map_resolvers, i);
2312  if (!ip_address_cmp (&mr->address, &a->address))
2313  {
2314  if (!ip_address_cmp (&mr->address, &lcm->active_map_resolver))
2315  lcm->do_map_resolver_election = 1;
2316 
2317  vec_del1 (lcm->map_resolvers, i);
2318  break;
2319  }
2320  }
2321  }
2322  return 0;
2323 }
2324 
2325 int
2327 {
2329  lcm->map_register_ttl = ttl;
2330  return 0;
2331 }
2332 
2333 u32
2335 {
2337  return lcm->map_register_ttl;
2338 }
2339 
2340 int
2342 {
2344  uword *p = 0;
2345 
2346  if (vnet_lisp_enable_disable_status () == 0)
2347  {
2348  clib_warning ("LISP is disabled!");
2349  return VNET_API_ERROR_LISP_DISABLED;
2350  }
2351 
2352  if (a->is_add)
2353  {
2355  if (!p)
2356  {
2357  clib_warning ("locator-set %v doesn't exist", a->locator_set_name);
2358  return VNET_API_ERROR_INVALID_ARGUMENT;
2359  }
2360 
2361  lcm->mreq_itr_rlocs = p[0];
2362  }
2363  else
2364  {
2365  lcm->mreq_itr_rlocs = ~0;
2366  }
2367 
2368  return 0;
2369 }
2370 
2371 /* Statistics (not really errors) */
2372 #define foreach_lisp_cp_lookup_error \
2373 _(DROP, "drop") \
2374 _(MAP_REQUESTS_SENT, "map-request sent") \
2375 _(ARP_REPLY_TX, "ARP replies sent") \
2376 _(NDP_NEIGHBOR_ADVERTISEMENT_TX, \
2377  "neighbor advertisement sent")
2378 
2380 #define _(sym,string) string,
2382 #undef _
2383 };
2384 
2385 typedef enum
2386 {
2387 #define _(sym,str) LISP_CP_LOOKUP_ERROR_##sym,
2389 #undef _
2392 
2393 typedef enum
2394 {
2399 
2400 typedef struct
2401 {
2405 
2406 u8 *
2407 format_lisp_cp_lookup_trace (u8 * s, va_list * args)
2408 {
2409  CLIB_UNUSED (vlib_main_t * vm) = va_arg (*args, vlib_main_t *);
2410  CLIB_UNUSED (vlib_node_t * node) = va_arg (*args, vlib_node_t *);
2411  lisp_cp_lookup_trace_t *t = va_arg (*args, lisp_cp_lookup_trace_t *);
2412 
2413  s = format (s, "LISP-CP-LOOKUP: map-resolver: %U destination eid %U",
2415  &t->dst_eid);
2416  return s;
2417 }
2418 
2419 int
2421  ip_address_t * sloc)
2422 {
2423  lisp_msmr_t *mrit;
2424  ip_address_t *a;
2425 
2426  if (vec_len (lcm->map_resolvers) == 0)
2427  {
2428  clib_warning ("No map-resolver configured");
2429  return 0;
2430  }
2431 
2432  /* find the first mr ip we have a route to and the ip of the
2433  * iface that has a route to it */
2434  vec_foreach (mrit, lcm->map_resolvers)
2435  {
2436  a = &mrit->address;
2437  if (0 != ip_fib_get_first_egress_ip_for_dst (lcm, a, sloc))
2438  {
2439  ip_address_copy (mr_ip, a);
2440 
2441  /* also update globals */
2442  return 1;
2443  }
2444  }
2445 
2446  clib_warning ("Can't find map-resolver and local interface ip!");
2447  return 0;
2448 }
2449 
2450 static gid_address_t *
2452 {
2453  void *addr;
2454  u32 i;
2455  locator_t *loc;
2456  u32 *loc_indexp;
2457  ip_interface_address_t *ia = 0;
2458  gid_address_t gid_data, *gid = &gid_data;
2459  gid_address_t *rlocs = 0;
2460  ip_prefix_t *ippref = &gid_address_ippref (gid);
2461  ip_address_t *rloc = &ip_prefix_addr (ippref);
2462 
2463  clib_memset (gid, 0, sizeof (gid[0]));
2465  for (i = 0; i < vec_len (loc_set->locator_indices); i++)
2466  {
2467  loc_indexp = vec_elt_at_index (loc_set->locator_indices, i);
2468  loc = pool_elt_at_index (lcm->locator_pool, loc_indexp[0]);
2469 
2470  /* Add ipv4 locators first TODO sort them */
2471 
2472  /* *INDENT-OFF* */
2474  loc->sw_if_index, 1 /* unnumbered */,
2475  ({
2476  addr = ip_interface_address_get_address (&lcm->im4->lookup_main, ia);
2477  ip_address_set (rloc, addr, AF_IP4);
2478  ip_prefix_len (ippref) = 32;
2479  ip_prefix_normalize (ippref);
2480  vec_add1 (rlocs, gid[0]);
2481  }));
2482 
2483  /* Add ipv6 locators */
2485  loc->sw_if_index, 1 /* unnumbered */,
2486  ({
2487  addr = ip_interface_address_get_address (&lcm->im6->lookup_main, ia);
2488  ip_address_set (rloc, addr, AF_IP6);
2489  ip_prefix_len (ippref) = 128;
2490  ip_prefix_normalize (ippref);
2491  vec_add1 (rlocs, gid[0]);
2492  }));
2493  /* *INDENT-ON* */
2494 
2495  }
2496  return rlocs;
2497 }
2498 
2499 static vlib_buffer_t *
2501  ip_address_t * sloc, ip_address_t * rloc,
2502  gid_address_t * itr_rlocs, u64 * nonce_res, u32 * bi_res)
2503 {
2504  vlib_buffer_t *b;
2505  u32 bi;
2506  vlib_main_t *vm = lcm->vlib_main;
2507 
2508  if (vlib_buffer_alloc (vm, &bi, 1) != 1)
2509  {
2510  clib_warning ("Can't allocate buffer for Map-Request!");
2511  return 0;
2512  }
2513 
2514  b = vlib_get_buffer (vm, bi);
2515 
2516  /* leave some space for the encap headers */
2518 
2519  /* put lisp msg */
2520  lisp_msg_put_mreq (lcm, b, NULL, deid, itr_rlocs, 0 /* smr invoked */ ,
2521  1 /* rloc probe */ , nonce_res);
2522 
2523  /* push outer ip header */
2525  rloc, 1);
2526 
2527  bi_res[0] = bi;
2528 
2529  return b;
2530 }
2531 
2532 static vlib_buffer_t *
2534  gid_address_t * seid, gid_address_t * deid,
2535  locator_set_t * loc_set, ip_address_t * mr_ip,
2536  ip_address_t * sloc, u8 is_smr_invoked,
2537  u64 * nonce_res, u32 * bi_res)
2538 {
2539  vlib_buffer_t *b;
2540  u32 bi;
2541  gid_address_t *rlocs = 0;
2542  vlib_main_t *vm = lcm->vlib_main;
2543 
2544  if (vlib_buffer_alloc (vm, &bi, 1) != 1)
2545  {
2546  clib_warning ("Can't allocate buffer for Map-Request!");
2547  return 0;
2548  }
2549 
2550  b = vlib_get_buffer (vm, bi);
2551  b->flags = 0;
2552 
2553  /* leave some space for the encap headers */
2555 
2556  /* get rlocs */
2557  rlocs = build_itr_rloc_list (lcm, loc_set);
2558 
2559  if (MR_MODE_SRC_DST == lcm->map_request_mode
2560  && GID_ADDR_SRC_DST != gid_address_type (deid))
2561  {
2562  gid_address_t sd;
2563  clib_memset (&sd, 0, sizeof (sd));
2564  build_src_dst (&sd, seid, deid);
2565  lisp_msg_put_mreq (lcm, b, seid, &sd, rlocs, is_smr_invoked,
2566  0 /* rloc probe */ , nonce_res);
2567  }
2568  else
2569  {
2570  /* put lisp msg */
2571  lisp_msg_put_mreq (lcm, b, seid, deid, rlocs, is_smr_invoked,
2572  0 /* rloc probe */ , nonce_res);
2573  }
2574 
2575  /* push ecm: udp-ip-lisp */
2577 
2578  /* push outer ip header */
2580  mr_ip, 1);
2581 
2582  bi_res[0] = bi;
2583 
2584  vec_free (rlocs);
2585  return b;
2586 }
2587 
2588 static void
2590 {
2592  r->retries_num = 0;
2593 }
2594 
2595 #define foreach_msmr \
2596  _(server) \
2597  _(resolver)
2598 
2599 #define _(name) \
2600 static int \
2601 elect_map_ ## name (lisp_cp_main_t * lcm) \
2602 { \
2603  lisp_msmr_t *mr; \
2604  vec_foreach (mr, lcm->map_ ## name ## s) \
2605  { \
2606  if (!mr->is_down) \
2607  { \
2608  ip_address_copy (&lcm->active_map_ ##name, &mr->address); \
2609  lcm->do_map_ ## name ## _election = 0; \
2610  return 1; \
2611  } \
2612  } \
2613  return 0; \
2614 }
2616 #undef _
2617  static void
2619 {
2620  mapping_t *map;
2621  vec_foreach (map, maps) vec_free (map->locators);
2622 
2623  vec_free (maps);
2624 }
2625 
2626 static void
2627 add_locators (lisp_cp_main_t * lcm, mapping_t * m, u32 locator_set_index,
2628  ip_address_t * probed_loc)
2629 {
2630  u32 *li;
2631  locator_t *loc, new;
2632  ip_interface_address_t *ia = 0;
2633  void *addr;
2634  ip_address_t *new_ip = &gid_address_ip (&new.address);
2635 
2636  m->locators = 0;
2638  locator_set_index);
2639  vec_foreach (li, ls->locator_indices)
2640  {
2641  loc = pool_elt_at_index (lcm->locator_pool, li[0]);
2642  new = loc[0];
2643  if (loc->local)
2644  {
2645  /* *INDENT-OFF* */
2647  loc->sw_if_index, 1 /* unnumbered */,
2648  ({
2649  addr = ip_interface_address_get_address (&lcm->im4->lookup_main,
2650  ia);
2651  ip_address_set (new_ip, addr, AF_IP4);
2652  }));
2653 
2654  /* Add ipv6 locators */
2656  loc->sw_if_index, 1 /* unnumbered */,
2657  ({
2658  addr = ip_interface_address_get_address (&lcm->im6->lookup_main,
2659  ia);
2660  ip_address_set (new_ip, addr, AF_IP6);
2661  }));
2662  /* *INDENT-ON* */
2663 
2664  if (probed_loc && ip_address_cmp (probed_loc, new_ip) == 0)
2665  new.probed = 1;
2666  }
2667  vec_add1 (m->locators, new);
2668  }
2669 }
2670 
2671 static mapping_t *
2673 {
2674  mapping_t *recs = 0, rec, *m;
2675 
2676  /* *INDENT-OFF* */
2677  pool_foreach(m, lcm->mapping_pool,
2678  {
2679  /* for now build only local mappings */
2680  if (!m->local)
2681  continue;
2682 
2683  rec = m[0];
2684  add_locators (lcm, &rec, m->locator_set_index, NULL);
2685  vec_add1 (recs, rec);
2686  });
2687  /* *INDENT-ON* */
2688 
2689  return recs;
2690 }
2691 
2692 static vnet_crypto_alg_t
2694 {
2695  switch (key_id)
2696  {
2697  case HMAC_SHA_1_96:
2698  return VNET_CRYPTO_ALG_HMAC_SHA1;
2699  case HMAC_SHA_256_128:
2700  return VNET_CRYPTO_ALG_HMAC_SHA256;
2701  default:
2702  clib_warning ("unsupported encryption key type: %d!", key_id);
2703  break;
2704  }
2705  return VNET_CRYPTO_ALG_NONE;
2706 }
2707 
2708 static vnet_crypto_op_id_t
2710 {
2711  switch (key_id)
2712  {
2713  case HMAC_SHA_1_96:
2714  return VNET_CRYPTO_OP_SHA1_HMAC;
2715  case HMAC_SHA_256_128:
2716  return VNET_CRYPTO_OP_SHA256_HMAC;
2717  default:
2718  clib_warning ("unsupported encryption key type: %d!", key_id);
2719  break;
2720  }
2721  return VNET_CRYPTO_OP_NONE;
2722 }
2723 
2724 static int
2726  lisp_key_type_t key_id, u8 * key,
2727  u16 auth_data_len, u32 msg_len)
2728 {
2730  MREG_KEY_ID (map_reg_hdr) = clib_host_to_net_u16 (key_id);
2731  MREG_AUTH_DATA_LEN (map_reg_hdr) = clib_host_to_net_u16 (auth_data_len);
2732  vnet_crypto_op_t _op, *op = &_op;
2734 
2736  op->len = msg_len;
2737  op->digest = MREG_DATA (map_reg_hdr);
2738  op->src = (u8 *) map_reg_hdr;
2739  op->digest_len = 0;
2740  op->iv = 0;
2741 
2742  ki = vnet_crypto_key_add (lcm->vlib_main,
2743  lisp_key_type_to_crypto_alg (key_id), key,
2744  vec_len (key));
2745 
2746  op->key_index = ki;
2747 
2748  vnet_crypto_process_ops (lcm->vlib_main, op, 1);
2749  vnet_crypto_key_del (lcm->vlib_main, ki);
2750 
2751  return 0;
2752 }
2753 
2754 static vlib_buffer_t *
2756  ip_address_t * ms_ip, u64 * nonce_res, u8 want_map_notif,
2757  mapping_t * records, lisp_key_type_t key_id, u8 * key,
2758  u32 * bi_res)
2759 {
2760  void *map_reg_hdr;
2761  vlib_buffer_t *b;
2762  u32 bi, auth_data_len = 0, msg_len = 0;
2763  vlib_main_t *vm = lcm->vlib_main;
2764 
2765  if (vlib_buffer_alloc (vm, &bi, 1) != 1)
2766  {
2767  clib_warning ("Can't allocate buffer for Map-Register!");
2768  return 0;
2769  }
2770 
2771  b = vlib_get_buffer (vm, bi);
2772 
2773  /* leave some space for the encap headers */
2775 
2776  auth_data_len = auth_data_len_by_key_id (key_id);
2777  map_reg_hdr = lisp_msg_put_map_register (b, records, want_map_notif,
2778  auth_data_len, nonce_res,
2779  &msg_len);
2780 
2781  update_map_register_auth_data (map_reg_hdr, key_id, key, auth_data_len,
2782  msg_len);
2783 
2784  /* push outer ip header */
2786  ms_ip, 1);
2787 
2788  bi_res[0] = bi;
2789  return b;
2790 }
2791 
2792 #define _(name) \
2793 static int \
2794 get_egress_map_ ##name## _ip (lisp_cp_main_t * lcm, ip_address_t * ip) \
2795 { \
2796  lisp_msmr_t *mr; \
2797  while (lcm->do_map_ ## name ## _election \
2798  | (0 == ip_fib_get_first_egress_ip_for_dst \
2799  (lcm, &lcm->active_map_ ##name, ip))) \
2800  { \
2801  if (0 == elect_map_ ## name (lcm)) \
2802  /* all map resolvers/servers are down */ \
2803  { \
2804  /* restart MR/MS checking by marking all of them up */ \
2805  vec_foreach (mr, lcm->map_ ## name ## s) mr->is_down = 0; \
2806  return -1; \
2807  } \
2808  } \
2809  return 0; \
2810 }
2811 
2813 #undef _
2814 /* CP output statistics */
2815 #define foreach_lisp_cp_output_error \
2816 _(MAP_REGISTERS_SENT, "map-registers sent") \
2817 _(MAP_REQUESTS_SENT, "map-requests sent") \
2818 _(RLOC_PROBES_SENT, "rloc-probes sent")
2820 #define _(sym,string) string,
2822 #undef _
2823 };
2824 
2825 typedef enum
2826 {
2827 #define _(sym,str) LISP_CP_OUTPUT_ERROR_##sym,
2829 #undef _
2832 
2833 static uword
2835  vlib_frame_t * from_frame)
2836 {
2837  return 0;
2838 }
2839 
2840 /* placeholder node used only for statistics */
2841 /* *INDENT-OFF* */
2843  .function = lisp_cp_output,
2844  .name = "lisp-cp-output",
2845  .vector_size = sizeof (u32),
2846  .format_trace = format_lisp_cp_input_trace,
2848 
2849  .n_errors = LISP_CP_OUTPUT_N_ERROR,
2850  .error_strings = lisp_cp_output_error_strings,
2851 
2852  .n_next_nodes = LISP_CP_INPUT_N_NEXT,
2853 
2854  .next_nodes = {
2855  [LISP_CP_INPUT_NEXT_DROP] = "error-drop",
2856  },
2857 };
2858 /* *INDENT-ON* */
2859 
2860 static int
2862  u32 local_locator_set_index, ip_address_t * sloc,
2863  ip_address_t * rloc)
2864 {
2865  locator_set_t *ls;
2866  u32 bi;
2867  vlib_buffer_t *b;
2868  vlib_frame_t *f;
2869  u64 nonce = 0;
2870  u32 next_index, *to_next;
2871  gid_address_t *itr_rlocs;
2872 
2873  ls = pool_elt_at_index (lcm->locator_set_pool, local_locator_set_index);
2874  itr_rlocs = build_itr_rloc_list (lcm, ls);
2875 
2876  b = build_map_request (lcm, deid, sloc, rloc, itr_rlocs, &nonce, &bi);
2877  vec_free (itr_rlocs);
2878  if (!b)
2879  return -1;
2880 
2881  vnet_buffer (b)->sw_if_index[VLIB_TX] = 0;
2882 
2883  next_index = (ip_addr_version (rloc) == AF_IP4) ?
2884  ip4_lookup_node.index : ip6_lookup_node.index;
2885 
2886  f = vlib_get_frame_to_node (lcm->vlib_main, next_index);
2887 
2888  /* Enqueue the packet */
2889  to_next = vlib_frame_vector_args (f);
2890  to_next[0] = bi;
2891  f->n_vectors = 1;
2892  vlib_put_frame_to_node (lcm->vlib_main, next_index, f);
2893 
2894  return 0;
2895 }
2896 
2897 static int
2899 {
2900  u8 lprio = 0;
2901  mapping_t *lm;
2902  fwd_entry_t *e;
2903  locator_pair_t *lp;
2904  u32 si, rloc_probes_sent = 0;
2905 
2906  /* *INDENT-OFF* */
2907  pool_foreach (e, lcm->fwd_entry_pool,
2908  {
2909  if (vec_len (e->locator_pairs) == 0)
2910  continue;
2911 
2912  si = gid_dictionary_lookup (&lcm->mapping_index_by_gid, &e->leid);
2913  if (~0 == si)
2914  {
2915  clib_warning ("internal error: cannot find local eid %U in "
2916  "map-cache!", format_gid_address, &e->leid);
2917  continue;
2918  }
2919  lm = pool_elt_at_index (lcm->mapping_pool, si);
2920 
2921  /* get the best (lowest) priority */
2922  lprio = e->locator_pairs[0].priority;
2923 
2924  /* send rloc-probe for pair(s) with the best remote locator priority */
2925  vec_foreach (lp, e->locator_pairs)
2926  {
2927  if (lp->priority != lprio)
2928  break;
2929 
2930  /* get first remote locator */
2931  send_rloc_probe (lcm, &e->reid, lm->locator_set_index, &lp->lcl_loc,
2932  &lp->rmt_loc);
2933  rloc_probes_sent++;
2934  }
2935  });
2936  /* *INDENT-ON* */
2937 
2939  LISP_CP_OUTPUT_ERROR_RLOC_PROBES_SENT,
2940  rloc_probes_sent);
2941  return 0;
2942 }
2943 
2944 static int
2945 send_map_register (lisp_cp_main_t * lcm, u8 want_map_notif)
2946 {
2948  u32 bi, map_registers_sent = 0;
2949  vlib_buffer_t *b;
2950  ip_address_t sloc;
2951  vlib_frame_t *f;
2952  u64 nonce = 0;
2953  u32 next_index, *to_next;
2954  mapping_t *records, *r, *group, *k;
2955 
2956  if (get_egress_map_server_ip (lcm, &sloc) < 0)
2957  return -1;
2958 
2959  records = build_map_register_record_list (lcm);
2960  if (!records)
2961  return -1;
2962 
2963  vec_foreach (r, records)
2964  {
2965  u8 *key = r->key;
2966  u8 key_id = r->key_id;
2967 
2968  if (!key)
2969  continue; /* no secret key -> map-register cannot be sent */
2970 
2971  group = 0;
2972  vec_add1 (group, r[0]);
2973 
2974  /* group mappings that share common key */
2975  for (k = r + 1; k < vec_end (records); k++)
2976  {
2977  if (k->key_id != r->key_id)
2978  continue;
2979 
2980  if (vec_is_equal (k->key, r->key))
2981  {
2982  vec_add1 (group, k[0]);
2983  k->key = 0; /* don't process this mapping again */
2984  }
2985  }
2986 
2987  b = build_map_register (lcm, &sloc, &lcm->active_map_server, &nonce,
2988  want_map_notif, group, key_id, key, &bi);
2989  vec_free (group);
2990  if (!b)
2991  continue;
2992 
2993  vnet_buffer (b)->sw_if_index[VLIB_TX] = 0;
2994 
2995  next_index = (ip_addr_version (&lcm->active_map_server) == AF_IP4) ?
2996  ip4_lookup_node.index : ip6_lookup_node.index;
2997 
2998  f = vlib_get_frame_to_node (lcm->vlib_main, next_index);
2999 
3000  /* Enqueue the packet */
3001  to_next = vlib_frame_vector_args (f);
3002  to_next[0] = bi;
3003  f->n_vectors = 1;
3004  vlib_put_frame_to_node (lcm->vlib_main, next_index, f);
3005  map_registers_sent++;
3006 
3008  clib_memset (pmr, 0, sizeof (*pmr));
3011  pmr - lcm->pending_map_registers_pool);
3012  }
3013  free_map_register_records (records);
3014 
3016  LISP_CP_OUTPUT_ERROR_MAP_REGISTERS_SENT,
3017  map_registers_sent);
3018 
3019  return 0;
3020 }
3021 
3022 #define send_encapsulated_map_request(lcm, seid, deid, smr) \
3023  _send_encapsulated_map_request(lcm, seid, deid, smr, 0)
3024 
3025 #define resend_encapsulated_map_request(lcm, seid, deid, smr) \
3026  _send_encapsulated_map_request(lcm, seid, deid, smr, 1)
3027 
3028 static int
3029 _send_encapsulated_map_request (lisp_cp_main_t * lcm,
3030  gid_address_t * seid, gid_address_t * deid,
3031  u8 is_smr_invoked, u8 is_resend)
3032 {
3033  u32 next_index, bi = 0, *to_next, map_index;
3034  vlib_buffer_t *b;
3035  vlib_frame_t *f;
3036  u64 nonce = 0;
3037  locator_set_t *loc_set;
3038  mapping_t *map;
3039  pending_map_request_t *pmr, *duplicate_pmr = 0;
3040  ip_address_t sloc;
3041  u32 ls_index;
3042 
3043  /* if there is already a pending request remember it */
3044 
3045  /* *INDENT-OFF* */
3047  ({
3048  if (!gid_address_cmp (&pmr->src, seid)
3049  && !gid_address_cmp (&pmr->dst, deid))
3050  {
3051  duplicate_pmr = pmr;
3052  break;
3053  }
3054  }));
3055  /* *INDENT-ON* */
3056 
3057  if (!is_resend && duplicate_pmr)
3058  {
3059  /* don't send the request if there is a pending map request already */
3060  return 0;
3061  }
3062 
3063  u8 pitr_mode = lcm->flags & LISP_FLAG_PITR_MODE;
3064 
3065  /* get locator-set for seid */
3066  if (!pitr_mode && gid_address_type (deid) != GID_ADDR_NSH)
3067  {
3068  map_index = gid_dictionary_lookup (&lcm->mapping_index_by_gid, seid);
3069  if (map_index == ~0)
3070  {
3071  clib_warning ("No local mapping found in eid-table for %U!",
3072  format_gid_address, seid);
3073  return -1;
3074  }
3075 
3076  map = pool_elt_at_index (lcm->mapping_pool, map_index);
3077 
3078  if (!map->local)
3079  {
3080  clib_warning
3081  ("Mapping found for src eid %U is not marked as local!",
3082  format_gid_address, seid);
3083  return -1;
3084  }
3085  ls_index = map->locator_set_index;
3086  }
3087  else
3088  {
3089  if (pitr_mode)
3090  {
3091  if (lcm->pitr_map_index != ~0)
3092  {
3093  map =
3094  pool_elt_at_index (lcm->mapping_pool, lcm->pitr_map_index);
3095  ls_index = map->locator_set_index;
3096  }
3097  else
3098  {
3099  return -1;
3100  }
3101  }
3102  else
3103  {
3104  if (lcm->nsh_map_index == (u32) ~ 0)
3105  {
3106  clib_warning ("No locator-set defined for NSH!");
3107  return -1;
3108  }
3109  else
3110  {
3111  map = pool_elt_at_index (lcm->mapping_pool, lcm->nsh_map_index);
3112  ls_index = map->locator_set_index;
3113  }
3114  }
3115  }
3116 
3117  /* overwrite locator set if map-request itr-rlocs configured */
3118  if (~0 != lcm->mreq_itr_rlocs)
3119  {
3120  ls_index = lcm->mreq_itr_rlocs;
3121  }
3122 
3123  loc_set = pool_elt_at_index (lcm->locator_set_pool, ls_index);
3124 
3125  if (get_egress_map_resolver_ip (lcm, &sloc) < 0)
3126  {
3127  if (duplicate_pmr)
3128  duplicate_pmr->to_be_removed = 1;
3129  return -1;
3130  }
3131 
3132  /* build the encapsulated map request */
3133  b = build_encapsulated_map_request (lcm, seid, deid, loc_set,
3134  &lcm->active_map_resolver,
3135  &sloc, is_smr_invoked, &nonce, &bi);
3136 
3137  if (!b)
3138  return -1;
3139 
3140  /* set fib index to default and lookup node */
3141  vnet_buffer (b)->sw_if_index[VLIB_TX] = 0;
3142  next_index = (ip_addr_version (&lcm->active_map_resolver) == AF_IP4) ?
3143  ip4_lookup_node.index : ip6_lookup_node.index;
3144 
3145  f = vlib_get_frame_to_node (lcm->vlib_main, next_index);
3146 
3147  /* Enqueue the packet */
3148  to_next = vlib_frame_vector_args (f);
3149  to_next[0] = bi;
3150  f->n_vectors = 1;
3151  vlib_put_frame_to_node (lcm->vlib_main, next_index, f);
3152 
3154  LISP_CP_OUTPUT_ERROR_MAP_REQUESTS_SENT, 1);
3155 
3156  if (duplicate_pmr)
3157  /* if there is a pending request already update it */
3158  {
3159  if (clib_fifo_elts (duplicate_pmr->nonces) >= PENDING_MREQ_QUEUE_LEN)
3160  {
3161  /* remove the oldest nonce */
3162  u64 CLIB_UNUSED (tmp), *nonce_del;
3163  nonce_del = clib_fifo_head (duplicate_pmr->nonces);
3164  hash_unset (lcm->pending_map_requests_by_nonce, nonce_del[0]);
3165  clib_fifo_sub1 (duplicate_pmr->nonces, tmp);
3166  }
3167 
3168  clib_fifo_add1 (duplicate_pmr->nonces, nonce);
3169  hash_set (lcm->pending_map_requests_by_nonce, nonce,
3170  duplicate_pmr - lcm->pending_map_requests_pool);
3171  }
3172  else
3173  {
3174  /* add map-request to pending requests table */
3175  pool_get (lcm->pending_map_requests_pool, pmr);
3176  clib_memset (pmr, 0, sizeof (*pmr));
3177  gid_address_copy (&pmr->src, seid);
3178  gid_address_copy (&pmr->dst, deid);
3179  clib_fifo_add1 (pmr->nonces, nonce);
3180  pmr->is_smr_invoked = is_smr_invoked;
3182  hash_set (lcm->pending_map_requests_by_nonce, nonce,
3183  pmr - lcm->pending_map_requests_pool);
3184  }
3185 
3186  return 0;
3187 }
3188 
3189 static void
3191 {
3192  ip4_header_t *ip4 = hdr;
3193  ip6_header_t *ip6;
3194 
3195  if ((ip4->ip_version_and_header_length & 0xF0) == 0x40)
3196  {
3197  ip_address_set (src, &ip4->src_address, AF_IP4);
3198  ip_address_set (dst, &ip4->dst_address, AF_IP4);
3199  }
3200  else
3201  {
3202  ip6 = hdr;
3203  ip_address_set (src, &ip6->src_address, AF_IP6);
3204  ip_address_set (dst, &ip6->dst_address, AF_IP6);
3205  }
3206 }
3207 
3208 static u32
3210  u8 version)
3211 {
3212  uword *vnip;
3213  u32 vni = ~0, table_id = ~0;
3214 
3216  AF_IP4 ?
3219  vnet_buffer
3220  (b)->sw_if_index
3221  [VLIB_RX]);
3222 
3223  vnip = hash_get (lcm->vni_by_table_id, table_id);
3224  if (vnip)
3225  vni = vnip[0];
3226  else
3227  clib_warning ("vrf %d is not mapped to any vni!", table_id);
3228 
3229  return vni;
3230 }
3231 
3234 {
3235  u32 sw_if_index0;
3236 
3237  l2input_main_t *l2im = &l2input_main;
3238  l2_input_config_t *config;
3239  l2_bridge_domain_t *bd_config;
3240 
3241  sw_if_index0 = vnet_buffer (b)->sw_if_index[VLIB_RX];
3242  config = vec_elt_at_index (l2im->configs, sw_if_index0);
3243  bd_config = vec_elt_at_index (l2im->bd_configs, config->bd_index);
3244 
3245  return bd_config->bd_id;
3246 }
3247 
3250 {
3251  uword *vnip;
3252  u32 vni = ~0;
3254 
3255  vnip = hash_get (lcm->vni_by_bd_id, bd);
3256  if (vnip)
3257  vni = vnip[0];
3258  else
3259  clib_warning ("bridge domain %d is not mapped to any vni!", bd);
3260 
3261  return vni;
3262 }
3263 
3264 void
3267  u16 type)
3268 {
3269  ethernet_header_t *eh;
3270  u32 vni = 0;
3271  icmp6_neighbor_discovery_ethernet_link_layer_address_option_t *opt;
3272 
3273  clib_memset (src, 0, sizeof (*src));
3274  clib_memset (dst, 0, sizeof (*dst));
3275 
3278 
3279  if (LISP_AFI_IP == type || LISP_AFI_IP6 == type)
3280  {
3281  ip4_header_t *ip;
3282  u8 version, preflen;
3283 
3286 
3287  ip = vlib_buffer_get_current (b);
3288  get_src_and_dst_ip (ip, &gid_address_ip (src), &gid_address_ip (dst));
3289 
3290  version = gid_address_ip_version (src);
3291  preflen = ip_address_max_len (version);
3292  gid_address_ippref_len (src) = preflen;
3293  gid_address_ippref_len (dst) = preflen;
3294 
3295  vni = lisp_get_vni_from_buffer_ip (lcm, b, version);
3296  gid_address_vni (dst) = vni;
3297  gid_address_vni (src) = vni;
3298  }
3299  else if (LISP_AFI_MAC == type)
3300  {
3302 
3303  eh = vlib_buffer_get_current (b);
3304 
3305  if (clib_net_to_host_u16 (eh->type) == ETHERNET_TYPE_ARP)
3306  {
3307  ah = (ethernet_arp_header_t *) (((u8 *) eh) + sizeof (*eh));
3309 
3310  if (clib_net_to_host_u16 (ah->opcode)
3311  != ETHERNET_ARP_OPCODE_request)
3312  {
3314  sizeof (ip_address_t));
3316  gid_address_arp_ndp_bd (dst) = ~0;
3317  return;
3318  }
3319 
3322  &ah->ip4_over_ethernet[1].ip4, 4);
3323  }
3324  else
3325  {
3326  if (clib_net_to_host_u16 (eh->type) == ETHERNET_TYPE_IP6)
3327  {
3328  ip6_header_t *ip;
3329  ip = (ip6_header_t *) (eh + 1);
3330 
3331  if (IP_PROTOCOL_ICMP6 == ip->protocol)
3332  {
3333  icmp6_neighbor_solicitation_or_advertisement_header_t *ndh;
3334  ndh = ip6_next_header (ip);
3335  if (ndh->icmp.type == ICMP6_neighbor_solicitation)
3336  {
3338 
3339  /* check that source link layer address option is present */
3340  opt = (void *) (ndh + 1);
3341  if ((opt->header.type !=
3342  ICMP6_NEIGHBOR_DISCOVERY_OPTION_source_link_layer_address)
3343  || (opt->header.n_data_u64s != 1))
3344  {
3346  sizeof (ip_address_t));
3348  AF_IP6;
3349  gid_address_arp_ndp_bd (dst) = ~0;
3351  return;
3352  }
3353 
3354  gid_address_ndp_bd (dst) =
3357  &ndh->target_address, AF_IP6);
3358  return;
3359  }
3360  }
3361  }
3362 
3365  mac_copy (&gid_address_mac (src), eh->src_address);
3366  mac_copy (&gid_address_mac (dst), eh->dst_address);
3367 
3368  /* get vni */
3369  vni = lisp_get_vni_from_buffer_eth (lcm, b);
3370 
3371  gid_address_vni (dst) = vni;
3372  gid_address_vni (src) = vni;
3373  }
3374  }
3375  else if (LISP_AFI_LCAF == type)
3376  {
3377  lisp_nsh_hdr_t *nh;
3378  eh = vlib_buffer_get_current (b);
3379 
3380  if (clib_net_to_host_u16 (eh->type) == ETHERNET_TYPE_NSH)
3381  {
3382  nh = (lisp_nsh_hdr_t *) (((u8 *) eh) + sizeof (*eh));
3383  u32 spi = clib_net_to_host_u32 (nh->spi_si << 8);
3384  u8 si = (u8) clib_net_to_host_u32 (nh->spi_si);
3385  gid_address_nsh_spi (dst) = spi;
3386  gid_address_nsh_si (dst) = si;
3387 
3390  }
3391  }
3392 }
3393 
3394 static uword
3397  vlib_frame_t * from_frame, int overlay)
3398 {
3399  icmp6_neighbor_discovery_ethernet_link_layer_address_option_t *opt;
3400  u32 *from, *to_next, di, si;
3402  u32 next_index;
3403  uword n_left_from, n_left_to_next;
3404  vnet_main_t *vnm = vnet_get_main ();
3405 
3406  from = vlib_frame_vector_args (from_frame);
3407  n_left_from = from_frame->n_vectors;
3408  next_index = node->cached_next_index;
3409 
3410  while (n_left_from > 0)
3411  {
3412  vlib_get_next_frame (vm, node, next_index, to_next, n_left_to_next);
3413 
3414  while (n_left_from > 0 && n_left_to_next > 0)
3415  {
3416  u32 pi0, sw_if_index0, next0;
3417  u64 mac0;
3418  vlib_buffer_t *b0;
3420  ethernet_arp_header_t *arp0;
3421  ethernet_header_t *eth0;
3422  vnet_hw_interface_t *hw_if0;
3423  ethernet_header_t *eh0;
3424  icmp6_neighbor_solicitation_or_advertisement_header_t *ndh;
3425  ip6_header_t *ip0;
3426 
3427  pi0 = from[0];
3428  from += 1;
3429  n_left_from -= 1;
3430  to_next[0] = pi0;
3431  to_next += 1;
3432  n_left_to_next -= 1;
3433 
3434  b0 = vlib_get_buffer (vm, pi0);
3435 
3436  /* src/dst eid pair */
3437  get_src_and_dst_eids_from_buffer (lcm, b0, &src, &dst, overlay);
3438 
3439  if (gid_address_type (&dst) == GID_ADDR_ARP)
3440  {
3441  mac0 = gid_dictionary_lookup (&lcm->mapping_index_by_gid, &dst);
3442  if (GID_LOOKUP_MISS_L2 == mac0)
3443  goto drop;
3444 
3445  /* send ARP reply */
3446  sw_if_index0 = vnet_buffer (b0)->sw_if_index[VLIB_RX];
3447  vnet_buffer (b0)->sw_if_index[VLIB_TX] = sw_if_index0;
3448 
3449  hw_if0 = vnet_get_sup_hw_interface (vnm, sw_if_index0);
3450 
3451  eth0 = vlib_buffer_get_current (b0);
3452  arp0 = (ethernet_arp_header_t *) (((u8 *) eth0)
3453  + sizeof (*eth0));
3454  arp0->opcode = clib_host_to_net_u16 (ETHERNET_ARP_OPCODE_reply);
3455  arp0->ip4_over_ethernet[1] = arp0->ip4_over_ethernet[0];
3456  mac_address_from_u64 (&arp0->ip4_over_ethernet[0].mac, mac0);
3457  clib_memcpy (&arp0->ip4_over_ethernet[0].ip4,
3458  &gid_address_arp_ip4 (&dst), 4);
3459 
3460  /* Hardware must be ethernet-like. */
3461  ASSERT (vec_len (hw_if0->hw_address) == 6);
3462 
3463  clib_memcpy (eth0->dst_address, eth0->src_address, 6);
3464  clib_memcpy (eth0->src_address, hw_if0->hw_address, 6);
3465 
3466  b0->error = node->errors[LISP_CP_LOOKUP_ERROR_ARP_REPLY_TX];
3468  goto enqueue;
3469  }
3470  else if (gid_address_type (&dst) == GID_ADDR_NDP)
3471  {
3472  mac0 = gid_dictionary_lookup (&lcm->mapping_index_by_gid, &dst);
3473  if (GID_LOOKUP_MISS_L2 == mac0)
3474  goto drop;
3475 
3476  sw_if_index0 = vnet_buffer (b0)->sw_if_index[VLIB_RX];
3477  vnet_buffer (b0)->sw_if_index[VLIB_TX] = sw_if_index0;
3478 
3479  eh0 = vlib_buffer_get_current (b0);
3480  ip0 = (ip6_header_t *) (eh0 + 1);
3481  ndh = ip6_next_header (ip0);
3482  int bogus_length;
3483  ip0->dst_address = ip0->src_address;
3484  ip0->src_address = ndh->target_address;
3485  ip0->hop_limit = 255;
3486  opt = (void *) (ndh + 1);
3487  opt->header.type =
3488  ICMP6_NEIGHBOR_DISCOVERY_OPTION_target_link_layer_address;
3489  clib_memcpy (opt->ethernet_address, (u8 *) & mac0, 6);
3490  ndh->icmp.type = ICMP6_neighbor_advertisement;
3491  ndh->advertisement_flags = clib_host_to_net_u32
3494  ndh->icmp.checksum = 0;
3495  ndh->icmp.checksum =
3496  ip6_tcp_udp_icmp_compute_checksum (vm, b0, ip0,
3497  &bogus_length);
3498  clib_memcpy (eh0->dst_address, eh0->src_address, 6);
3499  clib_memcpy (eh0->src_address, (u8 *) & mac0, 6);
3500  b0->error =
3501  node->errors
3502  [LISP_CP_LOOKUP_ERROR_NDP_NEIGHBOR_ADVERTISEMENT_TX];
3504  goto enqueue;
3505  }
3506 
3507  /* if we have remote mapping for destination already in map-cache
3508  add forwarding tunnel directly. If not send a map-request */
3510  &src);
3511  if (~0 != di)
3512  {
3513  mapping_t *m = vec_elt_at_index (lcm->mapping_pool, di);
3514  /* send a map-request also in case of negative mapping entry
3515  with corresponding action */
3516  if (m->action == LISP_SEND_MAP_REQUEST)
3517  {
3518  /* send map-request */
3519  queue_map_request (&src, &dst, 0 /* smr_invoked */ ,
3520  0 /* is_resend */ );
3521  }
3522  else
3523  {
3524  if (GID_ADDR_NSH != gid_address_type (&dst))
3525  {
3527  &src);
3528  }
3529  else
3530  si = lcm->nsh_map_index;
3531 
3532  if (~0 != si)
3533  {
3534  dp_add_fwd_entry_from_mt (si, di);
3535  }
3536  }
3537  }
3538  else
3539  {
3540  /* send map-request */
3541  queue_map_request (&src, &dst, 0 /* smr_invoked */ ,
3542  0 /* is_resend */ );
3543  }
3544 
3545  drop:
3546  b0->error = node->errors[LISP_CP_LOOKUP_ERROR_DROP];
3547  next0 = LISP_CP_LOOKUP_NEXT_DROP;
3548  enqueue:
3549  if (PREDICT_FALSE (b0->flags & VLIB_BUFFER_IS_TRACED))
3550  {
3551  lisp_cp_lookup_trace_t *tr = vlib_add_trace (vm, node, b0,
3552  sizeof (*tr));
3553 
3554  clib_memset (tr, 0, sizeof (*tr));
3555  if ((gid_address_type (&dst) == GID_ADDR_NDP) ||
3556  (gid_address_type (&dst) == GID_ADDR_ARP))
3557  clib_memcpy (&tr->dst_eid, &dst, sizeof (gid_address_t));
3558  else
3559  gid_address_copy (&tr->dst_eid, &dst);
3561  &lcm->active_map_resolver);
3562  }
3563  gid_address_free (&dst);
3564  gid_address_free (&src);
3565  vlib_validate_buffer_enqueue_x1 (vm, node, next_index,
3566  to_next,
3567  n_left_to_next, pi0, next0);
3568  }
3569 
3570  vlib_put_next_frame (vm, node, next_index, n_left_to_next);
3571  }
3572  return from_frame->n_vectors;
3573 }
3574 
3575 static uword
3577  vlib_node_runtime_t * node, vlib_frame_t * from_frame)
3578 {
3579  return (lisp_cp_lookup_inline (vm, node, from_frame, LISP_AFI_IP));
3580 }
3581 
3582 static uword
3584  vlib_node_runtime_t * node, vlib_frame_t * from_frame)
3585 {
3586  return (lisp_cp_lookup_inline (vm, node, from_frame, LISP_AFI_IP6));
3587 }
3588 
3589 static uword
3591  vlib_node_runtime_t * node, vlib_frame_t * from_frame)
3592 {
3593  return (lisp_cp_lookup_inline (vm, node, from_frame, LISP_AFI_MAC));
3594 }
3595 
3596 static uword
3598  vlib_node_runtime_t * node, vlib_frame_t * from_frame)
3599 {
3600  /* TODO decide if NSH should be propagated as LCAF or not */
3601  return (lisp_cp_lookup_inline (vm, node, from_frame, LISP_AFI_LCAF));
3602 }
3603 
3604 /* *INDENT-OFF* */
3606  .function = lisp_cp_lookup_ip4,
3607  .name = "lisp-cp-lookup-ip4",
3608  .vector_size = sizeof (u32),
3609  .format_trace = format_lisp_cp_lookup_trace,
3611 
3612  .n_errors = LISP_CP_LOOKUP_N_ERROR,
3613  .error_strings = lisp_cp_lookup_error_strings,
3614 
3615  .n_next_nodes = LISP_CP_LOOKUP_N_NEXT,
3616 
3617  .next_nodes = {
3618  [LISP_CP_LOOKUP_NEXT_DROP] = "error-drop",
3619  [LISP_CP_LOOKUP_NEXT_ARP_NDP_REPLY_TX] = "interface-output",
3620  },
3621 };
3622 /* *INDENT-ON* */
3623 
3624 /* *INDENT-OFF* */
3626  .function = lisp_cp_lookup_ip6,
3627  .name = "lisp-cp-lookup-ip6",
3628  .vector_size = sizeof (u32),
3629  .format_trace = format_lisp_cp_lookup_trace,
3631 
3632  .n_errors = LISP_CP_LOOKUP_N_ERROR,
3633  .error_strings = lisp_cp_lookup_error_strings,
3634 
3635  .n_next_nodes = LISP_CP_LOOKUP_N_NEXT,
3636 
3637  .next_nodes = {
3638  [LISP_CP_LOOKUP_NEXT_DROP] = "error-drop",
3639  [LISP_CP_LOOKUP_NEXT_ARP_NDP_REPLY_TX] = "interface-output",
3640  },
3641 };
3642 /* *INDENT-ON* */
3643 
3644 /* *INDENT-OFF* */
3646  .function = lisp_cp_lookup_l2,
3647  .name = "lisp-cp-lookup-l2",
3648  .vector_size = sizeof (u32),
3649  .format_trace = format_lisp_cp_lookup_trace,
3651 
3652  .n_errors = LISP_CP_LOOKUP_N_ERROR,
3653  .error_strings = lisp_cp_lookup_error_strings,
3654 
3655  .n_next_nodes = LISP_CP_LOOKUP_N_NEXT,
3656 
3657  .next_nodes = {
3658  [LISP_CP_LOOKUP_NEXT_DROP] = "error-drop",
3659  [LISP_CP_LOOKUP_NEXT_ARP_NDP_REPLY_TX] = "interface-output",
3660  },
3661 };
3662 /* *INDENT-ON* */
3663 
3664 /* *INDENT-OFF* */
3666  .function = lisp_cp_lookup_nsh,
3667  .name = "lisp-cp-lookup-nsh",
3668  .vector_size = sizeof (u32),
3669  .format_trace = format_lisp_cp_lookup_trace,
3671 
3672  .n_errors = LISP_CP_LOOKUP_N_ERROR,
3673  .error_strings = lisp_cp_lookup_error_strings,
3674 
3675  .n_next_nodes = LISP_CP_LOOKUP_N_NEXT,
3676 
3677  .next_nodes = {
3678  [LISP_CP_LOOKUP_NEXT_DROP] = "error-drop",
3679  [LISP_CP_LOOKUP_NEXT_ARP_NDP_REPLY_TX] = "interface-output",
3680  },
3681 };
3682 /* *INDENT-ON* */
3683 
3684 /* lisp_cp_input statistics */
3685 #define foreach_lisp_cp_input_error \
3686 _(DROP, "drop") \
3687 _(RLOC_PROBE_REQ_RECEIVED, "rloc-probe requests received") \
3688 _(RLOC_PROBE_REP_RECEIVED, "rloc-probe replies received") \
3689 _(MAP_NOTIFIES_RECEIVED, "map-notifies received") \
3690 _(MAP_REPLIES_RECEIVED, "map-replies received")
3691 
3693 #define _(sym,string) string,
3695 #undef _
3696 };
3697 
3698 typedef enum
3699 {
3700 #define _(sym,str) LISP_CP_INPUT_ERROR_##sym,
3702 #undef _
3705 
3706 typedef struct
3707 {
3711 
3712 u8 *
3713 format_lisp_cp_input_trace (u8 * s, va_list * args)
3714 {
3715  CLIB_UNUSED (vlib_main_t * vm) = va_arg (*args, vlib_main_t *);
3716  CLIB_UNUSED (vlib_node_t * node) = va_arg (*args, vlib_node_t *);
3718  va_arg (*args, lisp_cp_input_trace_t *);
3719 
3720  s = format (s, "LISP-CP-INPUT: TODO");
3721  return s;
3722 }
3723 
3724 static void
3726 {
3727  mapping_t *m;
3728  vnet_lisp_add_del_adjacency_args_t _adj_args, *adj_args = &_adj_args;
3729  clib_memset (adj_args, 0, sizeof (adj_args[0]));
3730 
3731  m = pool_elt_at_index (lcm->mapping_pool, mi);
3732 
3733  gid_address_copy (&adj_args->reid, &m->eid);
3734  adj_args->is_add = 0;
3735  if (vnet_lisp_add_del_adjacency (adj_args))
3736  clib_warning ("failed to del adjacency!");
3737 
3738  TW (tw_timer_stop) (&lcm->wheel, m->timer_handle);
3739  vnet_lisp_del_mapping (&m->eid, NULL);
3740 }
3741 
3742 static void
3744  f64 expiration_time)
3745 {
3746  mapping_t *m;
3747  u64 now = clib_cpu_time_now ();
3748  u64 cpu_cps = lcm->vlib_main->clib_time.clocks_per_second;
3749  u64 exp_clock_time = now + expiration_time * cpu_cps;
3750 
3751  m = pool_elt_at_index (lcm->mapping_pool, mi);
3752 
3753  m->timer_set = 1;
3754  m->timer_handle = TW (tw_timer_start) (&lcm->wheel, mi, 0, exp_clock_time);
3755 }
3756 
3757 static void
3759 {
3760  int rv;
3762  mapping_t *m = pool_elt_at_index (lcm->mapping_pool, mi);
3763  uword *fei;
3764  fwd_entry_t *fe;
3765  vlib_counter_t c;
3766  u8 have_stats = 0;
3767 
3768  if (m->delete_after_expiration)
3769  {
3770  remove_expired_mapping (lcm, mi);
3771  return;
3772  }
3773 
3774  fei = hash_get (lcm->fwd_entry_by_mapping_index, mi);
3775  if (!fei)
3776  return;
3777 
3778  fe = pool_elt_at_index (lcm->fwd_entry_pool, fei[0]);
3779 
3780  clib_memset (a, 0, sizeof (*a));
3781  a->rmt_eid = fe->reid;
3782  if (fe->is_src_dst)
3783  a->lcl_eid = fe->leid;
3784  a->vni = gid_address_vni (&fe->reid);
3785 
3786  rv = vnet_lisp_gpe_get_fwd_stats (a, &c);
3787  if (0 == rv)
3788  have_stats = 1;
3789 
3790  if (m->almost_expired)
3791  {
3792  m->almost_expired = 0; /* reset flag */
3793  if (have_stats)
3794  {
3795  if (m->packets != c.packets)
3796  {
3797  /* mapping is in use, re-fetch */
3798  map_request_args_t mr_args;
3799  clib_memset (&mr_args, 0, sizeof (mr_args));
3800  mr_args.seid = fe->leid;
3801  mr_args.deid = fe->reid;
3802 
3803  send_map_request_thread_fn (&mr_args);
3804  }
3805  else
3806  remove_expired_mapping (lcm, mi);
3807  }
3808  else
3809  remove_expired_mapping (lcm, mi);
3810  }
3811  else
3812  {
3813  m->almost_expired = 1;
3815 
3816  if (have_stats)
3817  /* save counter */
3818  m->packets = c.packets;
3819  else
3820  m->delete_after_expiration = 1;
3821  }
3822 }
3823 
3824 static void
3826 {
3828  mapping_t *m;
3829  vec_foreach (m, a->mappings)
3830  {
3831  vec_free (m->locators);
3832  gid_address_free (&m->eid);
3833  }
3835 }
3836 
3837 void *
3839 {
3840  mapping_t *m;
3842  u32 dst_map_index = 0;
3843  pending_map_request_t *pmr;
3844  u64 *noncep;
3845  uword *pmr_index;
3846  u8 is_changed = 0;
3847 
3848  if (a->is_rloc_probe)
3849  goto done;
3850 
3851  /* Check pending requests table and nonce */
3852  pmr_index = hash_get (lcm->pending_map_requests_by_nonce, a->nonce);
3853  if (!pmr_index)
3854  {
3855  clib_warning ("No pending map-request entry with nonce %lu!", a->nonce);
3856  goto done;
3857  }
3858  pmr = pool_elt_at_index (lcm->pending_map_requests_pool, pmr_index[0]);
3859 
3860  vec_foreach (m, a->mappings)
3861  {
3862  vnet_lisp_add_del_mapping_args_t _m_args, *m_args = &_m_args;
3863  clib_memset (m_args, 0, sizeof (m_args[0]));
3864  gid_address_copy (&m_args->eid, &m->eid);
3865  m_args->action = m->action;
3866  m_args->authoritative = m->authoritative;
3867  m_args->ttl = m->ttl;
3868  m_args->is_static = 0;
3869 
3870  /* insert/update mappings cache */
3871  vnet_lisp_add_mapping (m_args, m->locators, &dst_map_index, &is_changed);
3872 
3873  if (dst_map_index == (u32) ~ 0)
3874  continue;
3875 
3876  if (is_changed)
3877  {
3878  /* try to program forwarding only if mapping saved or updated */
3879  vnet_lisp_add_del_adjacency_args_t _adj_args, *adj_args = &_adj_args;
3880  clib_memset (adj_args, 0, sizeof (adj_args[0]));
3881 
3882  gid_address_copy (&adj_args->leid, &pmr->src);
3883  gid_address_copy (&adj_args->reid, &m->eid);
3884  adj_args->is_add = 1;
3885 
3886  if (vnet_lisp_add_del_adjacency (adj_args))
3887  clib_warning ("failed to add adjacency!");
3888  }
3889 
3890  if ((u32) ~ 0 != m->ttl)
3891  mapping_start_expiration_timer (lcm, dst_map_index,
3892  (m->ttl == 0) ? 0 : MAPPING_TIMEOUT);
3893  }
3894 
3895  /* remove pending map request entry */
3896 
3897  /* *INDENT-OFF* */
3898  clib_fifo_foreach (noncep, pmr->nonces, ({
3899  hash_unset(lcm->pending_map_requests_by_nonce, noncep[0]);
3900  }));
3901  /* *INDENT-ON* */
3902 
3903  clib_fifo_free (pmr->nonces);
3904  pool_put (lcm->pending_map_requests_pool, pmr);
3905 
3906 done:
3907  a->is_free = 1;
3908  return 0;
3909 }
3910 
3911 static int
3913  lisp_key_type_t key_id, u8 * key)
3914 {
3916  u8 *auth_data = 0;
3917  u16 auth_data_len;
3918  int result;
3919  vnet_crypto_op_t _op, *op = &_op;
3921  u8 out[EVP_MAX_MD_SIZE] = { 0, };
3922 
3923  auth_data_len = auth_data_len_by_key_id (key_id);
3924  if ((u16) ~ 0 == auth_data_len)
3925  {
3926  clib_warning ("invalid length for key_id %d!", key_id);
3927  return 0;
3928  }
3929 
3930  /* save auth data */
3931  vec_validate (auth_data, auth_data_len - 1);
3932  clib_memcpy (auth_data, MNOTIFY_DATA (h), auth_data_len);
3933 
3934  /* clear auth data */
3935  clib_memset (MNOTIFY_DATA (h), 0, auth_data_len);
3936 
3938  op->len = msg_len;
3939  op->digest = out;
3940  op->src = (u8 *) h;
3941  op->digest_len = 0;
3942  op->iv = 0;
3943 
3944  ki = vnet_crypto_key_add (lcm->vlib_main,
3945  lisp_key_type_to_crypto_alg (key_id), key,
3946  vec_len (key));
3947 
3948  op->key_index = ki;
3949 
3950  vnet_crypto_process_ops (lcm->vlib_main, op, 1);
3951  vnet_crypto_key_del (lcm->vlib_main, ki);
3952 
3953  result = memcmp (out, auth_data, auth_data_len);
3954 
3955  vec_free (auth_data);
3956 
3957  return !result;
3958 }
3959 
3960 static void
3962 {
3964  uword *pmr_index;
3965 
3966  pmr_index = hash_get (lcm->map_register_messages_by_nonce, a->nonce);
3967  if (!pmr_index)
3968  {
3969  clib_warning ("No pending map-register entry with nonce %lu!",
3970  a->nonce);
3971  return;
3972  }
3973 
3974  a->is_free = 1;
3975  pool_put_index (lcm->pending_map_registers_pool, pmr_index[0]);
3977 
3978  /* reset map-notify counter */
3979  lcm->expired_map_registers = 0;
3980 }
3981 
3982 static mapping_t *
3984 {
3985  u32 mi;
3986 
3988  if (~0 == mi)
3989  {
3990  clib_warning ("eid %U not found in map-cache!", unformat_gid_address,
3991  e);
3992  return 0;
3993  }
3994  return pool_elt_at_index (lcm->mapping_pool, mi);
3995 }
3996 
3997 /**
3998  * When map-notify is received it is necessary that all EIDs in the record
3999  * list share common key. The key is then used to verify authentication
4000  * data in map-notify message.
4001  */
4002 static int
4004  u32 key_id, u8 ** key_out)
4005 {
4006  u32 i, len = vec_len (maps);
4007  mapping_t *m;
4008 
4009  /* get key of the first mapping */
4010  m = get_mapping (lcm, &maps[0].eid);
4011  if (!m || !m->key)
4012  return -1;
4013 
4014  key_out[0] = m->key;
4015 
4016  for (i = 1; i < len; i++)
4017  {
4018  m = get_mapping (lcm, &maps[i].eid);
4019  if (!m || !m->key)
4020  return -1;
4021 
4022  if (key_id != m->key_id || vec_cmp (m->key, key_out[0]))
4023  {
4024  clib_warning ("keys does not match! %v, %v", key_out[0], m->key);
4025  return -1;
4026  }
4027  }
4028  return 0;
4029 }
4030 
4031 static int
4033 {
4034  locator_t *locators = 0;
4035  u32 i, len;
4036  gid_address_t deid;
4037  mapping_t m;
4038  locator_t *loc;
4039 
4040  clib_memset (&m, 0, sizeof (m));
4041 
4042  /* parse record eid */
4043  for (i = 0; i < count; i++)
4044  {
4045  locators = 0;
4046  len = lisp_msg_parse_mapping_record (b, &deid, &locators, NULL);
4047  if (len == ~0)
4048  {
4049  clib_warning ("Failed to parse mapping record!");
4050  vec_foreach (loc, locators) locator_free (loc);
4051  vec_free (locators);
4052  return -1;
4053  }
4054 
4055  m.locators = locators;
4056  gid_address_copy (&m.eid, &deid);
4057  vec_add1 (a->mappings, m);
4058  }
4059 
4060  return 0;
4061 }
4062 
4063 static map_records_arg_t *
4065 {
4067  map_records_arg_t *rec;
4068 
4069  /* Cleanup first */
4070  /* *INDENT-OFF* */
4072  if (rec->is_free)
4073  map_records_arg_free (rec);
4074  }));
4075  /* *INDENT-ON* */
4076 
4078  return rec;
4079 }
4080 
4081 static map_records_arg_t *
4083 {
4084  int rc = 0;
4085  map_notify_hdr_t *mnotif_hdr;
4086  lisp_key_type_t key_id;
4088  u8 *key = 0;
4089  gid_address_t deid;
4090  u16 auth_data_len = 0;
4091  u8 record_count;
4093 
4094  a = map_record_args_get ();
4095  clib_memset (a, 0, sizeof (*a));
4096  mnotif_hdr = vlib_buffer_get_current (b);
4097  vlib_buffer_pull (b, sizeof (*mnotif_hdr));
4098  clib_memset (&deid, 0, sizeof (deid));
4099 
4100  a->nonce = MNOTIFY_NONCE (mnotif_hdr);
4101  key_id = clib_net_to_host_u16 (MNOTIFY_KEY_ID (mnotif_hdr));
4102  auth_data_len = auth_data_len_by_key_id (key_id);
4103 
4104  /* advance buffer by authentication data */
4105  vlib_buffer_pull (b, auth_data_len);
4106 
4107  record_count = MNOTIFY_REC_COUNT (mnotif_hdr);
4108  rc = parse_map_records (b, a, record_count);
4109  if (rc != 0)
4110  {
4112  return 0;
4113  }
4114 
4115  rc = map_record_integrity_check (lcm, a->mappings, key_id, &key);
4116  if (rc != 0)
4117  {
4119  return 0;
4120  }
4121 
4122  /* verify authentication data */
4123  if (!is_auth_data_valid (mnotif_hdr, vlib_buffer_get_tail (b)
4124  - (u8 *) mnotif_hdr, key_id, key))
4125  {
4126  clib_warning ("Map-notify auth data verification failed for nonce "
4127  "0x%lx!", a->nonce);
4129  return 0;
4130  }
4131  return a;
4132 }
4133 
4134 static vlib_buffer_t *
4136  ip_address_t * dst, u64 nonce, u8 probe_bit,
4137  mapping_t * records, u16 dst_port, u32 * bi_res)
4138 {
4139  vlib_buffer_t *b;
4140  u32 bi;
4141  vlib_main_t *vm = lcm->vlib_main;
4142 
4143  if (vlib_buffer_alloc (vm, &bi, 1) != 1)
4144  {
4145  clib_warning ("Can't allocate buffer for Map-Register!");
4146  return 0;
4147  }
4148 
4149  b = vlib_get_buffer (vm, bi);
4150 
4151  /* leave some space for the encap headers */
4153 
4154  lisp_msg_put_map_reply (b, records, nonce, probe_bit);
4155 
4156  /* push outer ip header */
4157  pkt_push_udp_and_ip (vm, b, LISP_CONTROL_PORT, dst_port, sloc, dst, 1);
4158 
4159  bi_res[0] = bi;
4160  return b;
4161 }
4162 
4163 static int
4165  u8 probe_bit, u64 nonce, u16 dst_port,
4166  ip_address_t * probed_loc)
4167 {
4168  ip_address_t src;
4169  u32 bi;
4170  vlib_buffer_t *b;
4171  vlib_frame_t *f;
4172  u32 next_index, *to_next;
4173  mapping_t *records = 0, *m;
4174 
4175  m = pool_elt_at_index (lcm->mapping_pool, mi);
4176  if (!m)
4177  return -1;
4178 
4179  vec_add1 (records, m[0]);
4180  add_locators (lcm, &records[0], m->locator_set_index, probed_loc);
4181  clib_memset (&src, 0, sizeof (src));
4182 
4183  if (!ip_fib_get_first_egress_ip_for_dst (lcm, dst, &src))
4184  {
4185  clib_warning ("can't find interface address for %U", format_ip_address,
4186  dst);
4187  return -1;
4188  }
4189 
4190  b = build_map_reply (lcm, &src, dst, nonce, probe_bit, records, dst_port,
4191  &bi);
4192  if (!b)
4193  return -1;
4194  free_map_register_records (records);
4195 
4196  vnet_buffer (b)->sw_if_index[VLIB_TX] = 0;
4197  next_index = (ip_addr_version (&lcm->active_map_resolver) == AF_IP4) ?
4198  ip4_lookup_node.index : ip6_lookup_node.index;
4199 
4200  f = vlib_get_frame_to_node (lcm->vlib_main, next_index);
4201 
4202  /* Enqueue the packet */
4203  to_next = vlib_frame_vector_args (f);
4204  to_next[0] = bi;
4205  f->n_vectors = 1;
4206  vlib_put_frame_to_node (lcm->vlib_main, next_index, f);
4207  return 0;
4208 }
4209 
4210 static void
4212 {
4213  const i32 start = vnet_buffer (b)->l3_hdr_offset;
4214  if (start < 0 && start < -sizeof (b->pre_data))
4215  {
4216  *ip_hdr = 0;
4217  return;
4218  }
4219 
4220  *ip_hdr = b->data + start;
4221  if ((u8 *) * ip_hdr > (u8 *) vlib_buffer_get_current (b))
4222  *ip_hdr = 0;
4223 }
4224 
4225 void
4227  lisp_cp_main_t * lcm, vlib_buffer_t * b)
4228 {
4229  u8 *ip_hdr = 0;
4230  ip_address_t *dst_loc = 0, probed_loc, src_loc;
4231  mapping_t m;
4232  map_request_hdr_t *mreq_hdr;
4234  u64 nonce;
4235  u32 i, len = 0, rloc_probe_recv = 0;
4236  gid_address_t *itr_rlocs = 0;
4237 
4238  mreq_hdr = vlib_buffer_get_current (b);
4239  if (!MREQ_SMR (mreq_hdr) && !MREQ_RLOC_PROBE (mreq_hdr))
4240  {
4241  clib_warning
4242  ("Only SMR Map-Requests and RLOC probe supported for now!");
4243  return;
4244  }
4245 
4246  vlib_buffer_pull (b, sizeof (*mreq_hdr));
4247  nonce = MREQ_NONCE (mreq_hdr);
4248 
4249  /* parse src eid */
4250  len = lisp_msg_parse_addr (b, &src);
4251  if (len == ~0)
4252  return;
4253 
4254  len = lisp_msg_parse_itr_rlocs (b, &itr_rlocs,
4255  MREQ_ITR_RLOC_COUNT (mreq_hdr) + 1);
4256  if (len == ~0)
4257  goto done;
4258 
4259  /* parse eid records and send SMR-invoked map-requests */
4260  for (i = 0; i < MREQ_REC_COUNT (mreq_hdr); i++)
4261  {
4262  clib_memset (&dst, 0, sizeof (dst));
4263  len = lisp_msg_parse_eid_rec (b, &dst);
4264  if (len == ~0)
4265  {
4266  clib_warning ("Can't parse map-request EID-record");
4267  goto done;
4268  }
4269 
4270  if (MREQ_SMR (mreq_hdr))
4271  {
4272  /* send SMR-invoked map-requests */
4273  queue_map_request (&dst, &src, 1 /* invoked */ , 0 /* resend */ );
4274  }
4275  else if (MREQ_RLOC_PROBE (mreq_hdr))
4276  {
4277  find_ip_header (b, &ip_hdr);
4278  if (!ip_hdr)
4279  {
4280  clib_warning ("Cannot find the IP header!");
4281  goto done;
4282  }
4283  rloc_probe_recv++;
4284  clib_memset (&m, 0, sizeof (m));
4285  u32 mi = gid_dictionary_lookup (&lcm->mapping_index_by_gid, &dst);
4286 
4287  // TODO: select best locator; for now use the first one
4288  dst_loc = &gid_address_ip (&itr_rlocs[0]);
4289 
4290  /* get src/dst IP addresses */
4291  get_src_and_dst_ip (ip_hdr, &src_loc, &probed_loc);
4292 
4293  // TODO get source port from buffer
4295 
4296  send_map_reply (lcm, mi, dst_loc, 1 /* probe-bit */ , nonce,
4297  src_port, &probed_loc);
4298  }
4299  }
4300 
4301 done:
4303  LISP_CP_INPUT_ERROR_RLOC_PROBE_REQ_RECEIVED,
4304  rloc_probe_recv);
4305  vec_free (itr_rlocs);
4306 }
4307 
4310 {
4311  locator_t probed;
4312  gid_address_t deid;
4313  void *h;
4314  u32 i, len = 0;
4315  mapping_t m;
4316  map_reply_hdr_t *mrep_hdr;
4318 
4319  a = map_record_args_get ();
4320  clib_memset (a, 0, sizeof (*a));
4321 
4322  locator_t *locators;
4323 
4324  mrep_hdr = vlib_buffer_get_current (b);
4325  a->nonce = MREP_NONCE (mrep_hdr);
4326  a->is_rloc_probe = MREP_RLOC_PROBE (mrep_hdr);
4327  if (!vlib_buffer_has_space (b, sizeof (*mrep_hdr)))
4328  {
4330  return 0;
4331  }
4332  vlib_buffer_pull (b, sizeof (*mrep_hdr));
4333 
4334  for (i = 0; i < MREP_REC_COUNT (mrep_hdr); i++)
4335  {
4336  clib_memset (&m, 0, sizeof (m));
4337  locators = 0;
4338  h = vlib_buffer_get_current (b);
4339 
4340  m.ttl = clib_net_to_host_u32 (MAP_REC_TTL (h));
4341  m.action = MAP_REC_ACTION (h);
4342  m.authoritative = MAP_REC_AUTH (h);
4343 
4344  len = lisp_msg_parse_mapping_record (b, &deid, &locators, &probed);
4345  if (len == ~0)
4346  {
4347  clib_warning ("Failed to parse mapping record!");
4349  return 0;
4350  }
4351 
4352  m.locators = locators;
4353  gid_address_copy (&m.eid, &deid);
4354  vec_add1 (a->mappings, m);
4355  }
4356  return a;
4357 }
4358 
4359 static void
4361 {
4362  vl_api_rpc_call_main_thread (process_map_reply, (u8 *) a, sizeof (*a));
4363 }
4364 
4365 static void
4367 {
4368  vl_api_rpc_call_main_thread (process_map_notify, (u8 *) a, sizeof (a[0]));
4369 }
4370 
4371 static uword
4373  vlib_frame_t * from_frame)
4374 {
4375  u32 n_left_from, *from, *to_next_drop, rloc_probe_rep_recv = 0,
4376  map_notifies_recv = 0;
4380 
4381  from = vlib_frame_vector_args (from_frame);
4382  n_left_from = from_frame->n_vectors;
4383 
4384 
4385  while (n_left_from > 0)
4386  {
4387  u32 n_left_to_next_drop;
4388 
4390  to_next_drop, n_left_to_next_drop);
4391  while (n_left_from > 0 && n_left_to_next_drop > 0)
4392  {
4393  u32 bi0;
4394  vlib_buffer_t *b0;
4395 
4396  bi0 = from[0];
4397  from += 1;
4398  n_left_from -= 1;
4399  to_next_drop[0] = bi0;
4400  to_next_drop += 1;
4401  n_left_to_next_drop -= 1;
4402 
4403  b0 = vlib_get_buffer (vm, bi0);
4404 
4405  type = lisp_msg_type (vlib_buffer_get_current (b0));
4406  switch (type)
4407  {
4408  case LISP_MAP_REPLY:
4409  a = parse_map_reply (b0);
4410  if (a)
4411  {
4412  if (a->is_rloc_probe)
4413  rloc_probe_rep_recv++;
4415  }
4416  break;
4417  case LISP_MAP_REQUEST:
4418  process_map_request (vm, node, lcm, b0);
4419  break;
4420  case LISP_MAP_NOTIFY:
4421  a = parse_map_notify (b0);
4422  if (a)
4423  {
4424  map_notifies_recv++;
4426  }
4427  break;
4428  default:
4429  clib_warning ("Unsupported LISP message type %d", type);
4430  break;
4431  }
4432 
4433  b0->error = node->errors[LISP_CP_INPUT_ERROR_DROP];
4434 
4435  if (PREDICT_FALSE (b0->flags & VLIB_BUFFER_IS_TRACED))
4436  {
4437 
4438  }
4439  }
4440 
4442  n_left_to_next_drop);
4443  }
4445  LISP_CP_INPUT_ERROR_RLOC_PROBE_REP_RECEIVED,
4446  rloc_probe_rep_recv);
4448  LISP_CP_INPUT_ERROR_MAP_NOTIFIES_RECEIVED,
4449  map_notifies_recv);
4450  return from_frame->n_vectors;
4451 }
4452 
4453 /* *INDENT-OFF* */
4455  .function = lisp_cp_input,
4456  .name = "lisp-cp-input",
4457  .vector_size = sizeof (u32),
4458  .format_trace = format_lisp_cp_input_trace,
4460 
4461  .n_errors = LISP_CP_INPUT_N_ERROR,
4462  .error_strings = lisp_cp_input_error_strings,
4463 
4464  .n_next_nodes = LISP_CP_INPUT_N_NEXT,
4465 
4466  .next_nodes = {
4467  [LISP_CP_INPUT_NEXT_DROP] = "error-drop",
4468  },
4469 };
4470 /* *INDENT-ON* */
4471 
4472 clib_error_t *
4474 {
4476  clib_error_t *error = 0;
4478  u32 num_threads;
4479 
4480  if ((error = vlib_call_init_function (vm, lisp_gpe_init)))
4481  return error;
4482 
4483  lcm->im4 = &ip4_main;
4484  lcm->im6 = &ip6_main;
4485  lcm->vlib_main = vm;
4486  lcm->vnet_main = vnet_get_main ();
4487  lcm->mreq_itr_rlocs = ~0;
4488  lcm->flags = 0;
4489  lcm->pitr_map_index = ~0;
4490  lcm->petr_map_index = ~0;
4491  clib_memset (&lcm->active_map_resolver, 0,
4492  sizeof (lcm->active_map_resolver));
4493  clib_memset (&lcm->active_map_server, 0, sizeof (lcm->active_map_server));
4494 
4496  lcm->do_map_resolver_election = 1;
4497  lcm->do_map_server_election = 1;
4499 
4500  num_threads = 1 /* main thread */ + vtm->n_threads;
4501  vec_validate (lcm->map_records_args_pool, num_threads - 1);
4502 
4503  /* default vrf mapped to vni 0 */
4504  hash_set (lcm->table_id_by_vni, 0, 0);
4505  hash_set (lcm->vni_by_table_id, 0, 0);
4506 
4507  TW (tw_timer_wheel_init) (&lcm->wheel, 0 /* no callback */ ,
4508  1e-3 /* timer period 1ms */ ,
4509  ~0 /* max expirations per call */ );
4510  lcm->nsh_map_index = ~0;
4513  lcm->expired_map_registers = 0;
4515  lcm->flags |= LISP_FLAG_XTR_MODE;
4516  return 0;
4517 }
4518 
4519 static int
4522  u32 stats_index)
4523 {
4524  vlib_counter_t v;
4526  lisp_gpe_fwd_entry_key_t fwd_key;
4527  const lisp_gpe_tunnel_t *lgt;
4528  fwd_entry_t *fe;
4529 
4530  clib_memset (stat, 0, sizeof (*stat));
4531  clib_memset (&fwd_key, 0, sizeof (fwd_key));
4532 
4534  ASSERT (fe != 0);
4535 
4536  gid_to_dp_address (&fe->reid, &stat->deid);
4537  gid_to_dp_address (&fe->leid, &stat->seid);
4538  stat->vni = gid_address_vni (&fe->reid);
4539 
4540  lgt = lisp_gpe_tunnel_get (key->tunnel_index);
4541  stat->loc_rloc = lgt->key->lcl;
4542  stat->rmt_rloc = lgt->key->rmt;
4543 
4544  vlib_get_combined_counter (cm, stats_index, &v);
4545  stat->counters = v;
4546  return 1;
4547 }
4548 
4551 {
4554  lisp_api_stats_t *stats = 0, stat;
4556  u32 index;
4557 
4558  /* *INDENT-OFF* */
4559  hash_foreach_mem (key, index, lgm->lisp_stats_index_by_key,
4560  {
4561  if (lisp_stats_api_fill (lcm, lgm, &stat, key, index))
4562  vec_add1 (stats, stat);
4563  });
4564  /* *INDENT-ON* */
4565 
4566  return stats;
4567 }
4568 
4569 static void *
4571 {
4572  map_request_args_t *a = arg;
4574 
4575  if (a->is_resend)
4577  else
4578  send_encapsulated_map_request (lcm, &a->seid, &a->deid, a->smr_invoked);
4579 
4580  return 0;
4581 }
4582 
4583 static int
4585  u8 smr_invoked, u8 is_resend)
4586 {
4588 
4589  a.is_resend = is_resend;
4590  gid_address_copy (&a.seid, seid);
4591  gid_address_copy (&a.deid, deid);
4592  a.smr_invoked = smr_invoked;
4593 
4595  (u8 *) & a, sizeof (a));
4596  return 0;
4597 }
4598 
4599 /**
4600  * Take an action with a pending map request depending on expiration time
4601  * and re-try counters.
4602  */
4603 static void
4605 {
4607  lisp_msmr_t *mr;
4608 
4609  if (r->time_to_expire - dt < 0)
4610  /* it's time to decide what to do with this pending request */
4611  {
4612  if (r->retries_num >= NUMBER_OF_RETRIES)
4613  /* too many retries -> assume current map resolver is not available */
4614  {
4616  if (!mr)
4617  {
4618  clib_warning ("Map resolver %U not found - probably deleted "
4619  "by the user recently.", format_ip_address,
4620  &lcm->active_map_resolver);
4621  }
4622  else
4623  {
4624  clib_warning ("map resolver %U is unreachable, ignoring",
4626 
4627  /* mark current map resolver unavailable so it won't be
4628  * selected next time */
4629  mr->is_down = 1;
4630  mr->last_update = vlib_time_now (lcm->vlib_main);
4631  }
4632 
4634  elect_map_resolver (lcm);
4635 
4636  /* try to find a next eligible map resolver and re-send */
4637  queue_map_request (&r->src, &r->dst, r->is_smr_invoked,
4638  1 /* resend */ );
4639  }
4640  else
4641  {
4642  /* try again */
4643  queue_map_request (&r->src, &r->dst, r->is_smr_invoked,
4644  1 /* resend */ );
4645  r->retries_num++;
4647  }
4648  }
4649  else
4650  r->time_to_expire -= dt;
4651 }
4652 
4653 static void
4655 {
4656  u64 *nonce;
4657  pending_map_request_t *pmr;
4658  u32 *to_be_removed = 0, *pmr_index;
4659 
4660  /* *INDENT-OFF* */
4662  ({
4663  if (pmr->to_be_removed)
4664  {
4665  clib_fifo_foreach (nonce, pmr->nonces, ({
4666  hash_unset (lcm->pending_map_requests_by_nonce, nonce[0]);
4667  }));
4668 
4669  vec_add1 (to_be_removed, pmr - lcm->pending_map_requests_pool);
4670  }
4671  }));
4672  /* *INDENT-ON* */
4673 
4674  vec_foreach (pmr_index, to_be_removed)
4675  pool_put_index (lcm->pending_map_requests_pool, pmr_index[0]);
4676 
4677  vec_free (to_be_removed);
4678 }
4679 
4680 static void
4682 {
4683  static f64 time_left = RLOC_PROBING_INTERVAL;
4684 
4685  if (!lcm->is_enabled || !lcm->rloc_probing)
4686  return;
4687 
4688  time_left -= dt;
4689  if (time_left <= 0)
4690  {
4691  time_left = RLOC_PROBING_INTERVAL;
4692  send_rloc_probes (lcm);
4693  }
4694 }
4695 
4696 static int
4698 {
4700  lisp_msmr_t *ms;
4701  del_all[0] = 0;
4702 
4703  r->time_to_expire -= dt;
4704 
4705  if (r->time_to_expire < 0)
4706  {
4707  lcm->expired_map_registers++;
4708 
4710  {
4711  ms = get_map_server (&lcm->active_map_server);
4712  if (!ms)
4713  {
4714  clib_warning ("Map server %U not found - probably deleted "
4715  "by the user recently.", format_ip_address,
4716  &lcm->active_map_server);
4717  }
4718  else
4719  {
4720  clib_warning ("map server %U is unreachable, ignoring",
4722 
4723  /* mark current map server unavailable so it won't be
4724  * elected next time */
4725  ms->is_down = 1;
4726  ms->last_update = vlib_time_now (lcm->vlib_main);
4727  }
4728 
4729  elect_map_server (lcm);
4730 
4731  /* indication for deleting all pending map registers */
4732  del_all[0] = 1;
4733  lcm->expired_map_registers = 0;
4734  return 0;
4735  }
4736  else
4737  {
4738  /* delete pending map register */
4739  return 0;
4740  }
4741  }
4742  return 1;
4743 }
4744 
4745 static void
4747 {
4748  u32 *to_be_removed = 0, *pmr_index;
4749  static f64 time_left = QUICK_MAP_REGISTER_INTERVAL;
4750  static u64 mreg_sent_counter = 0;
4751 
4753  u8 del_all = 0;
4754 
4755  if (!lcm->is_enabled || !lcm->map_registering)
4756  return;
4757 
4758  /* *INDENT-OFF* */
4760  ({
4761  if (!update_pending_map_register (pmr, dt, &del_all))
4762  {
4763  if (del_all)
4764  break;
4765  vec_add1 (to_be_removed, pmr - lcm->pending_map_registers_pool);
4766  }
4767  }));
4768  /* *INDENT-ON* */
4769 
4770  if (del_all)
4771  {
4772  /* delete all pending map register messages so they won't
4773  * trigger another map server election.. */
4774  pool_free (lcm->pending_map_registers_pool);
4775  hash_free (lcm->map_register_messages_by_nonce);
4776 
4777  /* ..and trigger registration against next map server (if any) */
4778  time_left = 0;
4779  }
4780  else
4781  {
4782  vec_foreach (pmr_index, to_be_removed)
4783  pool_put_index (lcm->pending_map_registers_pool, pmr_index[0]);
4784  }
4785 
4786  vec_free (to_be_removed);
4787 
4788  time_left -= dt;
4789  if (time_left <= 0)
4790  {
4791  if (mreg_sent_counter >= QUICK_MAP_REGISTER_MSG_COUNT)
4792  time_left = MAP_REGISTER_INTERVAL;
4793  else
4794  {
4795  mreg_sent_counter++;
4796  time_left = QUICK_MAP_REGISTER_INTERVAL;
4797  }
4798  send_map_register (lcm, 1 /* want map notify */ );
4799  }
4800 }
4801 
4802 static uword
4805 {
4806  u32 *expired = 0;
4807  f64 period = 2.0;
4808  pending_map_request_t *pmr;
4810 
4811  while (1)
4812  {
4814 
4815  /* currently no signals are expected - just wait for clock */
4816  (void) vlib_process_get_events (vm, 0);
4817 
4818  /* *INDENT-OFF* */
4820  ({
4821  if (!pmr->to_be_removed)
4822  update_pending_request (pmr, period);
4823  }));
4824  /* *INDENT-ON* */
4825 
4827 
4828  update_map_register (lcm, period);
4829  update_rloc_probing (lcm, period);
4830 
4831  expired = TW (tw_timer_expire_timers_vec) (&lcm->wheel,
4832  vlib_time_now (vm), expired);
4833  if (vec_len (expired) > 0)
4834  {
4835  u32 *mi = 0;
4836  vec_foreach (mi, expired)
4837  {
4838  process_expired_mapping (lcm, mi[0]);
4839  }
4840  _vec_len (expired) = 0;
4841  }
4842  }
4843 
4844  /* unreachable */
4845  return 0;
4846 }
4847 
4850 {
4852 
4853  if (vnet_lisp_enable_disable_status () == 0)
4854  return VNET_API_ERROR_LISP_DISABLED;
4855 
4856  if (enable)
4857  lcm->flags |= LISP_FLAG_STATS_ENABLED;
4858  else
4859  lcm->flags &= ~LISP_FLAG_STATS_ENABLED;
4860 
4861  return 0;
4862 }
4863 
4864 u8
4866 {
4868 
4869  if (vnet_lisp_enable_disable_status () == 0)
4870  return VNET_API_ERROR_LISP_DISABLED;
4871 
4872  return lcm->flags & LISP_FLAG_STATS_ENABLED;
4873 }
4874 
4875 void
4877 {
4878  if (lcm->retry_service_index)
4879  return;
4880 
4882  "lisp-retry-service",
4884  16 /* stack_bytes */ );
4885 }
4886 
4887 u32
4889 {
4891 
4892  if (protocol < LISP_TRANSPORT_PROTOCOL_UDP ||
4893  protocol > LISP_TRANSPORT_PROTOCOL_API)
4894  return VNET_API_ERROR_INVALID_ARGUMENT;
4895 
4897  return 0;
4898 }
4899 
4902 {
4904  return lcm->transport_protocol;
4905 }
4906 
4907 int
4909 {
4911  u8 pitr_mode = lcm->flags & LISP_FLAG_PITR_MODE;
4912  u8 xtr_mode = lcm->flags & LISP_FLAG_XTR_MODE;
4913  u8 petr_mode = lcm->flags & LISP_FLAG_PETR_MODE;
4914 
4915  if (pitr_mode && is_enabled)
4916  return VNET_API_ERROR_INVALID_ARGUMENT;
4917 
4918  if (is_enabled && xtr_mode)
4919  return 0;
4920  if (!is_enabled && !xtr_mode)
4921  return 0;
4922 
4923  if (is_enabled)
4924  {
4925  if (!petr_mode)
4926  {
4928  }
4929  lisp_cp_enable_l2_l3_ifaces (lcm, 1 /* with_default_route */ );
4930  lcm->flags |= LISP_FLAG_XTR_MODE;
4931  }
4932  else
4933  {
4934  if (!petr_mode)
4935  {
4937  }
4939  lcm->flags &= ~LISP_FLAG_XTR_MODE;
4940  }
4941  return 0;
4942 }
4943 
4944 int
4946 {
4948  u8 xtr_mode = lcm->flags & LISP_FLAG_XTR_MODE;
4949  u8 pitr_mode = lcm->flags & LISP_FLAG_PITR_MODE;
4950 
4951  if (xtr_mode && is_enabled)
4952  return VNET_API_ERROR_INVALID_VALUE;
4953 
4954  if (is_enabled && pitr_mode)
4955  return 0;
4956  if (!is_enabled && !pitr_mode)
4957  return 0;
4958 
4959  if (is_enabled)
4960  {
4961  /* create iface, no default route */
4962  lisp_cp_enable_l2_l3_ifaces (lcm, 0 /* with_default_route */ );
4963  lcm->flags |= LISP_FLAG_PITR_MODE;
4964  }
4965  else
4966  {
4968  lcm->flags &= ~LISP_FLAG_PITR_MODE;
4969  }
4970  return 0;
4971 }
4972 
4973 int
4975 {
4977  u8 xtr_mode = lcm->flags & LISP_FLAG_XTR_MODE;
4978  u8 petr_mode = lcm->flags & LISP_FLAG_PETR_MODE;
4979 
4980  if (is_enabled && petr_mode)
4981  return 0;
4982  if (!is_enabled && !petr_mode)
4983  return 0;
4984 
4985  if (is_enabled)
4986  {
4987  if (!xtr_mode)
4988  {
4990  }
4991  lcm->flags |= LISP_FLAG_PETR_MODE;
4992  }
4993  else
4994  {
4995  if (!xtr_mode)
4996  {
4998  }
4999  lcm->flags &= ~LISP_FLAG_PETR_MODE;
5000  }
5001  return 0;
5002 }
5003 
5004 u8
5006 {
5008  return (lcm->flags & LISP_FLAG_XTR_MODE);
5009 }
5010 
5011 u8
5013 {
5015  return (lcm->flags & LISP_FLAG_PITR_MODE);
5016 }
5017 
5018 u8
5020 {
5022  return (lcm->flags & LISP_FLAG_PETR_MODE);
5023 }
5024 
5026 
5027 /*
5028  * fd.io coding-style-patch-verification: ON
5029  *
5030  * Local Variables:
5031  * eval: (c-set-style "gnu")
5032  * End:
5033  */
u32 vnet_crypto_process_ops(vlib_main_t *vm, vnet_crypto_op_t ops[], u32 n_ops)
Definition: crypto.c:99
void lisp_gpe_tenant_l2_iface_unlock(u32 vni)
Release the lock held on the tenant&#39;s L3 interface.
#define ICMP6_NEIGHBOR_ADVERTISEMENT_FLAG_SOLICITED
#define vec_validate(V, I)
Make sure vector is long enough for given index (no header, unspecified alignment) ...
Definition: vec.h:509
#define MREQ_SMR(h_)
#define QUICK_MAP_REGISTER_INTERVAL
Definition: control.h:35
#define MNOTIFY_REC_COUNT(h_)
u32 flags
buffer flags: VLIB_BUFFER_FREE_LIST_INDEX_MASK: bits used to store free list index, VLIB_BUFFER_IS_TRACED: trace this buffer.
Definition: buffer.h:124
u8 count
Definition: dhcp.api:208
const lisp_gpe_tunnel_t * lisp_gpe_tunnel_get(index_t lgti)
#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:4372
#define gid_address_ip_version(_a)
Definition: lisp_types.h:207
#define vec_foreach_index(var, v)
Iterate over vector indices.
map_records_arg_t ** map_records_args_pool
Per thread pool of records shared with thread0.
Definition: control.h:273
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, u8 rloc_probe_set, u64 *nonce)
void TW() tw_timer_wheel_init(TWT(tw_timer_wheel) *tw, void *expired_timer_callback, f64 timer_interval_in_seconds, u32 max_expirations)
Initialize a tw timer wheel template instance.
u16 vni
Definition: flow_types.api:160
u8 is_down
Definition: control.h:87
u32 pitr_map_index
Definition: control.h:251
void * lisp_msg_put_map_register(vlib_buffer_t *b, mapping_t *records, u8 want_map_notify, u16 auth_data_len, u64 *nonce, u32 *msg_len)
#define MREP_REC_COUNT(h_)
static int send_map_register(lisp_cp_main_t *lcm, u8 want_map_notif)
Definition: control.c:2945
vnet_api_error_t
Definition: api_errno.h:162
#define hash_set(h, key, value)
Definition: hash.h:255
l2_input_config_t * configs
Definition: l2_input.h:62
static u8 * vlib_buffer_get_tail(vlib_buffer_t *b)
Get pointer to the end of buffer&#39;s data.
Definition: buffer.h:310
#define clib_fifo_head(v)
Definition: fifo.h:254
u8 vnet_lisp_get_pitr_mode(void)
Definition: control.c:5012
#define gid_address_type(_a)
Definition: lisp_types.h:203
counter_t packets
Definition: lisp_types.h:319
#define CLIB_UNUSED(x)
Definition: clib.h:87
u8 timer_set
Definition: lisp_types.h:317
vlib_node_registration_t lisp_cp_lookup_ip4_node
(constructor) VLIB_REGISTER_NODE (lisp_cp_lookup_ip4_node)
Definition: control.c:3605
map_records_arg_t * parse_map_reply(vlib_buffer_t *b)
Definition: control.c:4309
static void mapping_start_expiration_timer(lisp_cp_main_t *lcm, u32 mi, f64 expiration_time)
Definition: control.c:3743
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:751
vl_api_mac_address_t mac
Definition: l2.api:502
#define hash_unset(h, key)
Definition: hash.h:261
vl_api_wireguard_peer_flags_t flags
Definition: wireguard.api:103
u32 * lcl_to_rmt_adjs_by_lcl_idx
Definition: control.h:203
a
Definition: bitmap.h:538
#define ip_prefix_addr(_a)
Definition: ip_types.h:87
void process_map_request(vlib_main_t *vm, vlib_node_runtime_t *node, lisp_cp_main_t *lcm, vlib_buffer_t *b)
Definition: control.c:4226
gid_address_t deid
Definition: control.c:52
void ip_address_set(ip_address_t *dst, const void *src, u8 version)
Definition: ip_types.c:205
lisp_api_l2_arp_entry_t * vnet_lisp_l2_arp_entries_get_by_bd(u32 bd)
Definition: control.c:946
#define SHA256_AUTH_DATA_LEN
Definition: lisp_types.h:23
lisp_cp_lookup_next_t
Definition: control.c:2393
ip4_address_t src_address
Definition: ip4_packet.h:125
static uword clib_fifo_elts(void *v)
Definition: fifo.h:66
ip_address_t active_map_resolver
Definition: control.h:230
vnet_main_t * vnet_get_main(void)
Definition: misc.c:46
static vnet_hw_interface_t * vnet_get_sup_hw_interface(vnet_main_t *vnm, u32 sw_if_index)
#define RLOC_PROBING_INTERVAL
Definition: control.h:29
u32 bd_id
bridge domain id
Definition: lisp_gpe.h:270
lisp_msmr_t * map_resolvers
Definition: control.h:221
#define MAP_REC_TTL(h)
gid_address_t dst_eid
Definition: control.c:3708
u32 vnet_lisp_set_transport_protocol(u8 protocol)
Definition: control.c:4888
#define MREQ_REC_COUNT(h_)
vl_api_fib_path_nh_t nh
Definition: fib_types.api:126
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:2533
static void lisp_cp_register_dst_port(vlib_main_t *vm)
Definition: control.c:2149
locator_pair_t * locator_pairs
Definition: control.h:69
uword * table_id_by_vni
Definition: control.h:240
static void queue_map_notify_for_processing(map_records_arg_t *a)
Definition: control.c:4366
option version
Definition: sample.api:19
unsigned long u64
Definition: types.h:89
vl_api_ip_port_and_mask_t dst_port
Definition: flow_types.api:92
void lisp_gpe_tenant_l3_iface_unlock(u32 vni)
Release the lock held on the tenant&#39;s L3 interface.
static void * ip_interface_address_get_address(ip_lookup_main_t *lm, ip_interface_address_t *a)
Definition: ip_interface.h:43
u32 retry_service_index
Retry service node index.
Definition: control.h:286
clib_error_t * vnet_lisp_gpe_enable_disable(vnet_lisp_gpe_enable_disable_args_t *a)
Enable/disable LISP-GPE.
Definition: lisp_gpe.c:193
clib_memset(h->entries, 0, sizeof(h->entries[0]) *entries)
#define MAPPING_TIMEOUT
Definition: control.c:35
#define foreach_lisp_cp_input_error
Definition: control.c:3685
static uword lisp_cp_lookup_nsh(vlib_main_t *vm, vlib_node_runtime_t *node, vlib_frame_t *from_frame)
Definition: control.c:3597
u32 * local_mappings_indexes
Definition: control.h:193
static f64 vlib_time_now(vlib_main_t *vm)
Definition: main.h:333
static void update_adjacencies_by_map_index(lisp_cp_main_t *lcm, u32 mapping_index, u8 remove_only)
Definition: control.c:1794
u32 vnet_lisp_gpe_add_nsh_iface(lisp_gpe_main_t *lgm)
Add LISP-GPE NSH interface.
Definition: interface.c:754
locator_t * locator_pool
Definition: control.h:178
f64 clocks_per_second
Definition: time.h:54
static void lisp_cp_enable_l2_l3_ifaces(lisp_cp_main_t *lcm, u8 with_default_route)
lisp_cp_enable_l2_l3_ifaces
Definition: control.c:2170
dp_address_t seid
Definition: lisp_gpe.h:103
#define PENDING_MREQ_QUEUE_LEN
Definition: control.h:27
u8 src_address[6]
Definition: packet.h:56
LISP-GPE global state.
Definition: lisp_gpe.h:118
u8 vnet_lisp_get_map_request_mode(void)
Definition: control.c:57
vlib_node_registration_t lisp_cp_lookup_nsh_node
(constructor) VLIB_REGISTER_NODE (lisp_cp_lookup_nsh_node)
Definition: control.c:3665
ip_address_t loc_rloc
Definition: lisp_gpe.h:104
#define vec_add1(V, E)
Add 1 element to end of vector (unspecified alignment).
Definition: vec.h:592
static uword lisp_cp_output(vlib_main_t *vm, vlib_node_runtime_t *node, vlib_frame_t *from_frame)
Definition: control.c:2834
Definition: control.h:64
static u64 clib_cpu_time_now(void)
Definition: time.h:81
static int add_l2_arp_entry(BVT(clib_bihash_kv) *kvp, void *arg)
Definition: control.c:925
static void dp_del_fwd_entry(lisp_cp_main_t *lcm, u32 dst_map_index)
Definition: control.c:222
Combined counter to hold both packets and byte differences.
Definition: counter_types.h:26
vl_api_address_t src
Definition: gre.api:54
LISP-GPE definitions.
lisp_cp_input_next_t
Definition: control.c:42
#define QUICK_MAP_REGISTER_MSG_COUNT
Definition: control.h:34
#define MREG_KEY_ID(h_)
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:131
#define hash_set_mem(h, key, value)
Definition: hash.h:275
static char * lisp_cp_input_error_strings[]
Definition: control.c:3692
ip_lookup_main_t lookup_main
Definition: ip4.h:108
static vnet_sw_interface_t * vnet_get_sw_interface(vnet_main_t *vnm, u32 sw_if_index)
vlib_main_t * vm
Definition: in2out_ed.c:1582
u32 nsh_map_index
Definition: control.h:258
u8 * format(u8 *s, const char *fmt,...)
Definition: format.c:424
void vnet_lisp_gpe_add_fwd_counters(vnet_lisp_gpe_add_del_fwd_entry_args_t *a, u32 fwd_entry_index)
clib_time_t clib_time
Definition: main.h:124
#define SHA1_AUTH_DATA_LEN
Definition: lisp_types.h:22
static void remove_dead_pending_map_requests(lisp_cp_main_t *lcm)
Definition: control.c:4654
ip_address_t address
Definition: control.h:89
vnet_api_error_t vnet_lisp_stats_enable_disable(u8 enable)
Definition: control.c:4849
vl_api_prefix_t prefix
Definition: ip.api:144
int vnet_lisp_add_mapping(vnet_lisp_add_del_mapping_args_t *a, locator_t *rlocs, u32 *res_map_index, u8 *is_updated)
Adds/updates mapping.
Definition: control.c:1230
static lisp_msmr_t * get_map_server(ip_address_t *a)
Definition: control.c:601
vlib_error_t * errors
Vector of errors for this node.
Definition: node.h:469
static int update_pending_map_register(pending_map_register_t *r, f64 dt, u8 *del_all)
Definition: control.c:4697
uword * vni_by_table_id
Definition: control.h:241
#define ip_addr_version(_a)
Definition: ip_types.h:60
static void * send_map_request_thread_fn(void *arg)
Definition: control.c:4570
#define pool_get(P, E)
Allocate an object E from a pool P (unspecified alignment).
Definition: pool.h:252
vhost_vring_addr_t addr
Definition: vhost_user.h:111
ip6_address_t src_address
Definition: ip6_packet.h:310
u8 vnet_lisp_stats_enable_disable_state(void)
Definition: control.c:4865
unsigned char u8
Definition: types.h:56
#define fid_addr_mac(_a)
Definition: lisp_types.h:85
void gid_dictionary_init(gid_dictionary_t *db)
u8 vnet_lisp_map_register_state_get(void)
Definition: control.c:376
static int send_map_reply(lisp_cp_main_t *lcm, u32 mi, ip_address_t *dst, u8 probe_bit, u64 nonce, u16 dst_port, ip_address_t *probed_loc)
Definition: control.c:4164
void gid_address_from_ip(gid_address_t *g, ip_address_t *ip)
Definition: lisp_types.c:744
u8 vnet_lisp_get_petr_mode(void)
Definition: control.c:5019
int vnet_lisp_set_map_request_mode(u8 mode)
Definition: control.c:1510
static int is_local_ip(lisp_cp_main_t *lcm, ip_address_t *addr)
Definition: control.c:1207
static void clean_locator_to_locator_set(lisp_cp_main_t *lcm, u32 lsi)
Definition: control.c:1709
int vnet_lisp_add_del_adjacency(vnet_lisp_add_del_adjacency_args_t *a)
Adds adjacency or removes forwarding entry associated to remote mapping.
Definition: control.c:1439
double f64
Definition: types.h:142
static char * lisp_cp_output_error_strings[]
Definition: control.c:2819
#define NUMBER_OF_RETRIES
Definition: control.h:25
vlib_node_registration_t ip4_lookup_node
(constructor) VLIB_REGISTER_NODE (ip4_lookup_node)
Definition: ip4_forward.c:104
#define clib_memcpy(d, s, n)
Definition: string.h:180
#define MNOTIFY_NONCE(h_)
static int update_map_register_auth_data(map_register_hdr_t *map_reg_hdr, lisp_key_type_t key_id, u8 *key, u16 auth_data_len, u32 msg_len)
Definition: control.c:2725
lisp_msmr_t * map_servers
Definition: control.h:224
lisp_transport_protocol_t vnet_lisp_get_transport_protocol(void)
Definition: control.c:4901
#define MREQ_NONCE(h_)
int vnet_lisp_enable_disable_petr_mode(u8 is_enabled)
Definition: control.c:4974
static lisp_gpe_main_t * vnet_lisp_gpe_get_main()
Definition: lisp_gpe.h:183
vl_api_ip_proto_t protocol
Definition: lb_types.api:71
static void reset_pending_mr_counters(pending_map_request_t *r)
Definition: control.c:2589
u32 ** locator_to_locator_sets
Definition: control.h:184
vlib_main_t * vlib_main
Definition: control.h:291
u32 gid_dictionary_add_del(gid_dictionary_t *db, gid_address_t *key, u64 value, u8 is_add)
int vnet_lisp_enable_disable_pitr_mode(u8 is_enabled)
Definition: control.c:4945
#define pool_foreach(VAR, POOL, BODY)
Iterate through pool.
Definition: pool.h:513
ethernet_arp_ip4_over_ethernet_address_t ip4_over_ethernet[2]
Definition: arp_packet.h:142
#define VLIB_INIT_FUNCTION(x)
Definition: init.h:173
u32 fwd_entry_index
Definition: lisp_gpe.h:95
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:579
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:148
vl_api_ip6_address_t ip6
Definition: one.api:424
u8 * key
Definition: lisp_types.h:315
#define ICMP6_NEIGHBOR_ADVERTISEMENT_FLAG_OVERRIDE
gid_address_t * eids_to_be_deleted
Definition: control.c:1120
ip4_address_t dst_address
Definition: ip4_packet.h:125
ip_address_t rmt_rloc
Definition: lisp_gpe.h:105
u8 dst_address[6]
Definition: packet.h:55
vlib_combined_counter_main_t counters
Definition: lisp_gpe.h:164
static int dp_add_fwd_entry_from_mt(u32 si, u32 di)
Definition: control.c:557
LISP-GPE fwd entry key.
u8 is_add
Definition: lisp_gpe.h:234
#define hash_foreach(key_var, value_var, h, body)
Definition: hash.h:442
static_always_inline void vnet_crypto_op_init(vnet_crypto_op_t *op, vnet_crypto_op_id_t type)
Definition: crypto.h:496
#define gid_address_sd_src(_a)
Definition: lisp_types.h:220
#define vec_elt_at_index(v, i)
Get vector value at index i checking that i is in bounds.
void vnet_lisp_gpe_del_fwd_counters(vnet_lisp_gpe_add_del_fwd_entry_args_t *a, u32 fwd_entry_index)
Aggregate type for a prefix.
Definition: fib_types.h:203
vlib_frame_t * vlib_get_frame_to_node(vlib_main_t *vm, u32 to_node_index)
Definition: main.c:182
u32 * fwd_entry_by_mapping_index
Definition: control.h:197
#define clib_error_return(e, args...)
Definition: error.h:99
u32 expired_map_registers
Definition: control.h:280
void vl_api_rpc_call_main_thread(void *fp, u8 *data, u32 data_length)
Definition: vlib_api.c:619
void ip_address_to_fib_prefix(const ip_address_t *addr, fib_prefix_t *prefix)
convert from a IP address to a FIB prefix
Definition: ip_types.c:268
static mapping_t * get_mapping(lisp_cp_main_t *lcm, gid_address_t *e)
Definition: control.c:3983
typedef eid
Definition: lisp_types.api:59
int vnet_lisp_eid_table_map(u32 vni, u32 dp_id, u8 is_l2, u8 is_add)
Definition: control.c:1036
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:259
lisp_api_ndp_entry_t * vnet_lisp_ndp_entries_get_by_bd(u32 bd)
Definition: control.c:982
unsigned int u32
Definition: types.h:88
#define vec_end(v)
End (last data address) of vector.
uword * bd_id_by_vni
Definition: control.h:244
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.
static lisp_cp_main_t * vnet_lisp_cp_get_main()
Definition: control.h:305
#define vlib_call_init_function(vm, x)
Definition: init.h:270
u8 do_map_server_election
Definition: control.h:234
uword * vni_by_bd_id
Definition: control.h:245
u32 vnet_crypto_key_add(vlib_main_t *vm, vnet_crypto_alg_t alg, u8 *data, u16 length)
Definition: crypto.c:345
u8 delete_after_expiration
Definition: lisp_types.h:312
vnet_crypto_alg_t
Definition: crypto.h:124
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:68
Definition: lisp_gpe.h:227
gid_address_t src
Definition: control.h:50
u32 petr_map_index
Proxy ETR map index used for &#39;use-petr&#39;.
Definition: control.h:255
ip6_main_t * im6
Definition: control.h:290
void gid_to_dp_address(gid_address_t *g, dp_address_t *d)
Definition: lisp_types.c:489
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:4604
vl_api_fib_path_type_t type
Definition: fib_types.api:123
clib_error_t * vnet_lisp_enable_disable(u8 is_enable)
Definition: control.c:2206
vlib_error_t error
Error code for buffers to be enqueued to error handler.
Definition: buffer.h:136
vl_api_ikev2_id_t loc_id
Definition: ikev2_types.api:73
u32 dp_table
Definition: lisp_gpe.api:116
#define MAX_EXPIRED_MAP_REGISTERS_DEFAULT
Definition: control.h:41
vlib_node_registration_t lisp_cp_lookup_ip6_node
(constructor) VLIB_REGISTER_NODE (lisp_cp_lookup_ip6_node)
Definition: control.c:3625
static void add_locators(lisp_cp_main_t *lcm, mapping_t *m, u32 locator_set_index, ip_address_t *probed_loc)
Definition: control.c:2627
Definition: fib_entry.h:117
vnet_crypto_main_t * cm
Definition: quic_crypto.c:53
void vnet_lisp_gpe_del_nsh_iface(lisp_gpe_main_t *lgm)
Del LISP-GPE NSH interface.
Definition: interface.c:794
#define hash_get(h, key)
Definition: hash.h:249
#define MREQ_RLOC_PROBE(h_)
u8 is_src_dst
Definition: control.h:68
int vnet_lisp_pitr_set_locator_set(u8 *locator_set_name, u8 is_add)
Definition: control.c:1582
#define pool_elt_at_index(p, i)
Returns pointer to element at given index.
Definition: pool.h:534
u8 vnet_lisp_rloc_probe_state_get(void)
Definition: control.c:383
static void queue_map_reply_for_processing(map_records_arg_t *a)
Definition: control.c:4360
#define hash_unset_mem(h, key)
Definition: hash.h:291
Common utility functions for IPv4, IPv6 and L2 LISP-GPE tunnels.
lisp_cp_lookup_error_t
Definition: control.c:2385
counter_t packets
packet counter
Definition: counter_types.h:28
u8 do_map_resolver_election
Definition: control.h:233
#define clib_fifo_sub1(f, e)
Definition: fifo.h:224
u32 table_id
table (vrf) id
Definition: lisp_gpe.h:267
#define gid_address_arp_ndp_ip(_a)
Definition: lisp_types.h:226
static void * vlib_buffer_make_headroom(vlib_buffer_t *b, u8 size)
Make head room, typically for packet headers.
Definition: buffer.h:350
f64 last_update
Definition: control.h:88
void gid_dict_foreach_subprefix(gid_dictionary_t *db, gid_address_t *eid, foreach_subprefix_match_cb_t cb, void *arg)
#define gid_address_mac(_a)
Definition: lisp_types.h:209
static u16 auth_data_len_by_key_id(lisp_key_type_t key_id)
Definition: control.c:64
static __clib_warn_unused_result u32 vlib_buffer_alloc(vlib_main_t *vm, u32 *buffers, u32 n_buffers)
Allocate buffers into supplied array.
Definition: buffer_funcs.h:677
u32 lisp_gpe_tenant_l3_iface_add_or_lock(u32 vni, u32 table_id, u8 with_default_route)
Add/create and lock a new or find and lock the existing L3 interface for the tenant.
int get_mr_and_local_iface_ip(lisp_cp_main_t *lcm, ip_address_t *mr_ip, ip_address_t *sloc)
Definition: control.c:2420
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:684
#define MAP_REC_AUTH(h)
unsigned short u16
Definition: types.h:57
u32 vlib_process_create(vlib_main_t *vm, char *name, vlib_node_function_t *f, u32 log2_n_stack_bytes)
Create a vlib process.
Definition: node.c:736
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:837
u32 lisp_msg_parse_addr(vlib_buffer_t *b, gid_address_t *eid)
void vnet_crypto_key_del(vlib_main_t *vm, vnet_crypto_key_index_t index)
Definition: crypto.c:371
vlib_node_registration_t lisp_cp_input_node
(constructor) VLIB_REGISTER_NODE (lisp_cp_input_node)
Definition: control.c:4454
void vlib_put_frame_to_node(vlib_main_t *vm, u32 to_node_index, vlib_frame_t *f)
Definition: main.c:216
vec_header_t h
Definition: buffer.c:322
#define MNOTIFY_KEY_ID(h_)
static void * vlib_buffer_get_current(vlib_buffer_t *b)
Get pointer to current data to process.
Definition: buffer.h:229
#define hash_free(h)
Definition: hash.h:310
void gid_address_free(gid_address_t *a)
Definition: lisp_types.c:733
u32 *TW() tw_timer_expire_timers_vec(TWT(tw_timer_wheel) *tw, f64 now, u32 *vec)
void di(unformat_input_t *i)
Definition: unformat.c:163
vlib_node_registration_t lisp_cp_lookup_l2_node
(constructor) VLIB_REGISTER_NODE (lisp_cp_lookup_l2_node)
Definition: control.c:3645
#define pool_put(P, E)
Free an object E in pool P.
Definition: pool.h:302
#define gid_address_sd_dst_type(_a)
Definition: lisp_types.h:223
#define vec_dup(V)
Return copy of vector (no header, no alignment)
Definition: vec.h:429
static void cleanup(void)
Definition: client.c:120
u8 authoritative
Definition: lisp_types.h:305
lisp_api_stats_t * vnet_lisp_get_stats(void)
Definition: control.c:4550
static void remove_expired_mapping(lisp_cp_main_t *lcm, u32 mi)
Definition: control.c:3725
u32 * local_locator_set_indexes
Definition: control.h:194
#define PREDICT_FALSE(x)
Definition: clib.h:120
static int map_record_integrity_check(lisp_cp_main_t *lcm, mapping_t *maps, u32 key_id, u8 **key_out)
When map-notify is received it is necessary that all EIDs in the record list share common key...
Definition: control.c:4003
uword unformat_gid_address(unformat_input_t *input, va_list *args)
Definition: lisp_types.c:272
gid_address_t reid
Definition: control.h:67
#define always_inline
Definition: ipsec.h:28
vnet_sw_interface_flags_t flags
Definition: interface.h:738
#define vec_del1(v, i)
Delete the element at index I.
Definition: vec.h:875
vl_api_ip4_address_t ip4
Definition: one.api:376
u8 * format_gid_address(u8 *s, va_list *args)
Definition: lisp_types.c:187
ip6_main_t ip6_main
Definition: ip6_forward.c:2781
static uword lisp_cp_lookup_ip4(vlib_main_t *vm, vlib_node_runtime_t *node, vlib_frame_t *from_frame)
Definition: control.c:3576
ip_address_t lcl_loc
Definition: lisp_types.h:329
volatile u8 is_free
Definition: control.h:158
u8 map_request_mode
Definition: control.h:261
static u8 compare_locators(lisp_cp_main_t *lcm, u32 *old_ls_indexes, locator_t *new_locators)
Definition: control.c:1094
#define foreach_lisp_cp_lookup_error
Definition: control.c:2372
u8 vnet_lisp_get_xtr_mode(void)
Definition: control.c:5005
static_always_inline void mac_address_from_u64(mac_address_t *mac, u64 u)
Definition: mac_address.h:122
static void lisp_cp_unregister_dst_port(vlib_main_t *vm)
Definition: control.c:2158
vlib_node_registration_t lisp_cp_output_node
(constructor) VLIB_REGISTER_NODE (lisp_cp_output_node)
Definition: control.c:2842
u32 node_index
Node index.
Definition: node.h:487
#define MAX_LISP_MSG_ENCAP_LEN
#define vlib_validate_buffer_enqueue_x1(vm, node, next_index, to_next, n_left_to_next, bi0, next0)
Finish enqueueing one buffer forward in the graph.
Definition: buffer_node.h:224
vl_api_address_t dst
Definition: gre.api:55
#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:391
ip_address_t map_resolver_ip
Definition: control.c:2403
#define hash_foreach_mem(key_var, value_var, h, body)
Definition: hash.h:461
#define TIME_UNTIL_REFETCH_OR_DELETE
Definition: control.c:34
#define MREG_AUTH_DATA_LEN(h_)
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, u8 csum_offload)
Definition: packets.c:171
#define clib_fifo_foreach(v, f, body)
Definition: fifo.h:279
vl_api_tunnel_mode_t mode
Definition: gre.api:48
static void process_map_notify(map_records_arg_t *a)
Definition: control.c:3961
u8 map_registering
Definition: control.h:264
static int queue_map_request(gid_address_t *seid, gid_address_t *deid, u8 smr_invoked, u8 is_resend)
Definition: control.c:4584
static void vlib_node_increment_counter(vlib_main_t *vm, u32 node_index, u32 counter_index, u64 increment)
Definition: node_funcs.h:1231
static void remove_locator_from_locator_set(locator_set_t *ls, u32 *locit, u32 ls_index, u32 loc_id)
Definition: control.c:1876
#define gid_address_ippref(_a)
Definition: lisp_types.h:204
u8 len
Definition: ip_types.api:92
dp_address_t deid
Definition: lisp_gpe.h:102
lisp_adjacency_t * vnet_lisp_adjacencies_get_by_vni(u32 vni)
Returns vector of adjacencies.
Definition: control.c:579
u32 fib_entry_get_resolving_interface(fib_node_index_t entry_index)
Definition: fib_entry.c:1458
u8 is_negative
type of mapping
Definition: lisp_gpe.h:237
static int is_locator_in_locator_set(lisp_cp_main_t *lcm, locator_set_t *ls, locator_t *loc)
Definition: control.c:1770
BVT(clib_bihash)
Definition: l2_fib.c:972
#define pool_free(p)
Free a pool.
Definition: pool.h:427
u32 lisp_msg_parse_itr_rlocs(vlib_buffer_t *b, gid_address_t **rlocs, u8 rloc_count)
vl_api_ip_port_and_mask_t src_port
Definition: flow_types.api:91
u32 sw_if_index
Definition: lisp_types.h:266
clib_error_t * lisp_cp_init(vlib_main_t *vm)
Definition: control.c:4473
u32 * vnet_lisp_ndp_bds_get(void)
Definition: control.c:908
u32 vni
VNI/tenant id in HOST byte order.
Definition: lisp_gpe.h:261
u8 * format_lisp_cp_input_trace(u8 *s, va_list *args)
Definition: control.c:3713
static vlib_buffer_t * build_map_reply(lisp_cp_main_t *lcm, ip_address_t *sloc, ip_address_t *dst, u64 nonce, u8 probe_bit, mapping_t *records, u16 dst_port, u32 *bi_res)
Definition: control.c:4135
#define VLIB_REGISTER_NODE(x,...)
Definition: node.h:169
static uword lisp_cp_lookup_l2(vlib_main_t *vm, vlib_node_runtime_t *node, vlib_frame_t *from_frame)
Definition: control.c:3590
uword * pending_map_requests_by_nonce
Definition: control.h:209
static void dp_add_fwd_entry(lisp_cp_main_t *lcm, u32 src_map_index, u32 dst_map_index)
Definition: control.c:390
int vnet_lisp_add_del_mreq_itr_rlocs(vnet_lisp_add_del_mreq_itr_rloc_args_t *a)
Definition: control.c:2341
svmdb_client_t * c
u16 n_vectors
Definition: node.h:396
vlib_counter_t counters
Definition: lisp_gpe.h:107
static_always_inline uword vlib_get_thread_index(void)
Definition: threads.h:219
static lisp_msmr_t * get_map_resolver(ip_address_t *a)
Definition: control.c:617
static void vlib_get_combined_counter(const vlib_combined_counter_main_t *cm, u32 index, vlib_counter_t *result)
Get the value of a combined counter, never called in the speed path Scrapes the entire set of per-thr...
Definition: counter.h:259
#define MAP_REC_ACTION(h)
int gid_address_cmp(gid_address_t *a1, gid_address_t *a2)
Definition: lisp_types.c:1340
#define gid_address_arp_bd
Definition: lisp_types.h:230
static void update_fwd_entries_by_locator_set(lisp_cp_main_t *lcm, u32 ls_index, u8 remove_only)
Definition: control.c:1857
sll srl srl sll sra u16x4 i
Definition: vector_sse42.h:317
#define vec_free(V)
Free vector&#39;s memory (no header).
Definition: vec.h:380
#define gid_address_ippref_len(_a)
Definition: lisp_types.h:205
void udp_unregister_dst_port(vlib_main_t *vm, udp_dst_port_t dst_port, u8 is_ip4)
Definition: udp_local.c:506
static map_records_arg_t * parse_map_notify(vlib_buffer_t *b)
Definition: control.c:4082
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:1127
u8 ttl
Definition: fib_types.api:26
#define clib_warning(format, args...)
Definition: error.h:59
u32 locator_set_index
Definition: lisp_types.h:298
u8 data[]
Packet data.
Definition: buffer.h:181
u8 * format_ip_address(u8 *s, va_list *args)
Definition: ip_types.c:21
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)
u8 almost_expired
Definition: lisp_types.h:311
u32 locator_cmp(locator_t *l1, locator_t *l2)
Definition: lisp_types.c:1427
static void update_map_register(lisp_cp_main_t *lcm, f64 dt)
Definition: control.c:4746
int vnet_lisp_map_register_enable_disable(u8 is_enable)
Definition: control.c:2140
u32 spi
Definition: flow_types.api:140
u32 vnet_lisp_map_register_fallback_threshold_get(void)
Definition: control.c:1634
u32 fib_node_index_t
A typedef of a node index.
Definition: fib_types.h:30
#define pool_is_free_index(P, I)
Use free bitmap to query whether given index is free.
Definition: pool.h:299
void * lisp_msg_put_map_reply(vlib_buffer_t *b, mapping_t *records, u64 nonce, u8 probe_bit)
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:483
ip4_address_t map_resolver_ip
Definition: control.c:3709
static int send_rloc_probe(lisp_cp_main_t *lcm, gid_address_t *deid, u32 local_locator_set_index, ip_address_t *sloc, ip_address_t *rloc)
Definition: control.c:2861
lisp_key_type_t key_id
Definition: lisp_types.h:316
lisp_transport_protocol_t
Definition: control.h:147
#define PENDING_MREG_EXPIRATION_TIME
Definition: control.h:43
#define gid_address_nsh_si(_a)
Definition: lisp_types.h:212
#define vec_is_equal(v1, v2)
Compare two vectors, not NULL-pointer tolerant.
Definition: vec.h:981
void * ip_interface_get_first_address(ip_lookup_main_t *lm, u32 sw_if_index, u8 version)
Definition: control.c:99
enum fib_entry_flag_t_ fib_entry_flag_t
static void * ip6_next_header(ip6_header_t *i)
Definition: ip6_packet.h:371
vlib_main_t vlib_node_runtime_t * node
Definition: in2out_ed.c:1582
#define gid_address_arp_ndp_bd(_a)
Definition: lisp_types.h:225
lisp_gpe_tunnel_key_t * key
RLOC pair and rloc fib_index.
#define fid_addr_ippref(_a)
Definition: lisp_types.h:82
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:2271
#define MAX_VALUE_U24
Definition: control.c:31
int vnet_lisp_enable_disable_xtr_mode(u8 is_enabled)
Definition: control.c:4908
Definition: control.h:107
u16 ip6_tcp_udp_icmp_compute_checksum(vlib_main_t *vm, vlib_buffer_t *p0, ip6_header_t *ip0, int *bogus_lengthp)
Definition: ip6_forward.c:1095
Definition: control.c:541
signed int i32
Definition: types.h:77
vlib_node_registration_t ip6_lookup_node
(constructor) VLIB_REGISTER_NODE (ip6_lookup_node)
Definition: ip6_forward.c:741
static uword send_map_resolver_service(vlib_main_t *vm, vlib_node_runtime_t *rt, vlib_frame_t *f)
Definition: control.c:4803
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:1073
void vnet_lisp_create_retry_process(lisp_cp_main_t *lcm)
Definition: control.c:4876
u16 cached_next_index
Next frame index that vector arguments were last enqueued to last time this node ran.
Definition: node.h:510
u32 stats_index
Definition: ip.api:143
u8 value
Definition: qos.api:54
#define pool_put_index(p, i)
Free pool element with given index.
Definition: pool.h:331
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:111
int vnet_lisp_add_del_map_server(ip_address_t *addr, u8 is_add)
Definition: control.c:633
#define ASSERT(truth)
#define fid_addr_type(_a)
Definition: lisp_types.h:87
static lisp_msg_type_e lisp_msg_type(void *b)
manual_print typedef address
Definition: ip_types.api:85
#define GID_LOOKUP_MISS
static int send_rloc_probes(lisp_cp_main_t *lcm)
Definition: control.c:2898
u8 pre_data[VLIB_BUFFER_PRE_DATA_SIZE]
Space for inserting data before buffer start.
Definition: buffer.h:178
#define foreach_msmr
Definition: control.c:2595
int vnet_lisp_clear_all_remote_adjacencies(void)
Definition: control.c:1388
ip_lookup_main_t lookup_main
Definition: ip6.h:181
#define gid_address_sd_dst(_a)
Definition: lisp_types.h:221
#define MAP_REGISTER_INTERVAL
Definition: control.h:38
gid_address_t seid
Definition: control.c:51
static void get_src_and_dst_ip(void *hdr, ip_address_t *src, ip_address_t *dst)
Definition: control.c:3190
lisp_transport_protocol_t transport_protocol
either UDP based or binary API.
Definition: control.h:283
clib_error_t * lisp_gpe_init(vlib_main_t *vm)
LISP-GPE init function.
Definition: lisp_gpe.c:600
gid_dictionary_t mapping_index_by_gid
Definition: control.h:169
ip_interface_address_t * ip_interface_get_first_interface_address(ip_lookup_main_t *lm, u32 sw_if_index, u8 loop)
Definition: control.c:84
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:3209
locator_set_t * locator_set_pool
Definition: control.h:181
u32 vnet_crypto_key_index_t
Definition: crypto.h:346
u8 is_static
Definition: lisp_types.h:308
u8 is_src_dst
Definition: lisp_gpe.h:232
static void gid_address_sd_to_flat(gid_address_t *dst, gid_address_t *src, fid_address_t *fid)
Definition: control.c:352
#define gid_address_ndp_bd
Definition: lisp_types.h:229
int vnet_lisp_rloc_probe_enable_disable(u8 is_enable)
Definition: control.c:2131
u32 ** locator_set_to_eids
Definition: control.h:190
static vnet_crypto_op_id_t lisp_key_type_to_crypto_op(lisp_key_type_t key_id)
Definition: control.c:2709
#define LISP_CONTROL_PORT
static u64 mac_to_u64(u8 *m)
int ip_address_cmp(const ip_address_t *ip1, const ip_address_t *ip2)
Definition: ip_types.c:114
#define vec_cmp(v1, v2)
Compare two vectors (only applicable to vectors of signed numbers).
Definition: vec.h:991
gid_address_t rmt_eid
remote eid
Definition: lisp_gpe.h:246
u64 gid_dictionary_lookup(gid_dictionary_t *db, gid_address_t *key)
#define foreach_lisp_cp_output_error
Definition: control.c:2815
#define clib_fifo_free(f)
Definition: fifo.h:257
Definition: control.h:101
pending_map_register_t * pending_map_registers_pool
Definition: control.h:215
u32 map_register_ttl
Definition: control.h:276
fwd_entry_t * fwd_entry_pool
Definition: control.h:206
static vlib_main_t * vlib_get_main(void)
Definition: global_funcs.h:23
u32 entries
#define vec_elt(v, i)
Get vector value at index i.
int vnet_lisp_map_register_fallback_threshold_set(u32 value)
Definition: control.c:1621
pending_map_request_t * pending_map_requests_pool
Definition: control.h:212
typedef key
Definition: ipsec_types.api:85
void gid_dict_foreach_l2_arp_ndp_entry(gid_dictionary_t *db, cb, void *ht)
int vnet_lisp_add_del_locator_set(vnet_lisp_add_del_locator_set_args_t *a, u32 *ls_result)
Definition: control.c:1996
#define gid_address_ip(_a)
Definition: lisp_types.h:206
u32 timer_handle
Definition: lisp_types.h:318
Definition: defs.h:47
negative_fwd_actions_e action
action for negative mappings
Definition: lisp_gpe.h:240
#define clib_fifo_add1(f, e)
Definition: fifo.h:192
static u32 lisp_get_bd_from_buffer_eth(vlib_buffer_t *b)
Definition: control.c:3233
lisp_key_type_t
Definition: lisp_types.h:25
l2input_main_t l2input_main
Definition: l2_input.c:127
static u8 vlib_buffer_has_space(vlib_buffer_t *b, word l)
Check if there is enough space in buffer to advance.
Definition: buffer.h:265
#define gid_address_vni(_a)
Definition: lisp_types.h:213
#define hash_create_vec(elts, key_bytes, value_bytes)
Definition: hash.h:668
static u32 lisp_get_vni_from_buffer_eth(lisp_cp_main_t *lcm, vlib_buffer_t *b)
Definition: control.c:3249
#define MNOTIFY_DATA(h_)
static vlib_buffer_t * build_map_register(lisp_cp_main_t *lcm, ip_address_t *sloc, ip_address_t *ms_ip, u64 *nonce_res, u8 want_map_notif, mapping_t *records, lisp_key_type_t key_id, u8 *key, u32 *bi_res)
Definition: control.c:2755
vl_api_address_t ip
Definition: l2.api:501
static uword * get_locator_set_index(vnet_lisp_add_del_locator_set_args_t *a, uword *p)
Definition: control.c:1748
void locator_free(locator_t *l)
Definition: lisp_types.c:1445
ip_address_t active_map_server
Definition: control.h:231
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:1167
#define vec_len(v)
Number of elements in vector (rvalue-only, NULL tolerant)
static char * lisp_cp_lookup_error_strings[]
Definition: control.c:2379
#define GID_LOOKUP_MISS_L2
#define foreach_ip_interface_address(lm, a, sw_if_index, loop, body)
Definition: ip_interface.h:57
VLIB buffer representation.
Definition: buffer.h:102
u64 uword
Definition: types.h:112
static void * vlib_frame_vector_args(vlib_frame_t *f)
Get pointer to frame vector data.
Definition: node_funcs.h:297
#define gid_address_nsh_spi(_a)
Definition: lisp_types.h:211
int vnet_lisp_del_mapping(gid_address_t *eid, u32 *res_map_index)
Removes a mapping.
Definition: control.c:1339
u32 * vnet_lisp_l2_arp_bds_get(void)
Definition: control.c:884
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:1892
locator_pair_t * locator_pairs
vector of locator pairs
Definition: lisp_gpe.h:249
static mapping_t * lisp_get_petr_mapping(lisp_cp_main_t *lcm)
Definition: control.h:435
mapping_t * mapping_pool
Definition: control.h:172
u32 table_id
Definition: wireguard.api:100
u32 index
Definition: flow_types.api:221
u8 ip_address_max_len(u8 version)
Definition: lisp_types.c:432
uword * locator_set_index_by_name
Definition: control.h:187
int vnet_lisp_nsh_set_locator_set(u8 *locator_set_name, u8 is_add)
Definition: control.c:1531
static map_records_arg_t * map_record_args_get()
Definition: control.c:4064
static gid_address_t * build_itr_rloc_list(lisp_cp_main_t *lcm, locator_set_t *loc_set)
Definition: control.c:2451
l2_bridge_domain_t * bd_configs
Definition: l2_input.h:65
void gid_address_copy(gid_address_t *dst, gid_address_t *src)
Definition: lisp_types.c:1203
u32 di
Definition: control.c:544
A collection of combined counters.
Definition: counter.h:188
static vlib_buffer_t * build_map_request(lisp_cp_main_t *lcm, gid_address_t *deid, ip_address_t *sloc, ip_address_t *rloc, gid_address_t *itr_rlocs, u64 *nonce_res, u32 *bi_res)
Definition: control.c:2500
gid_address_t eid
Definition: lisp_types.h:293
gid_address_t address
Definition: lisp_types.h:267
#define hash_get_mem(h, key)
Definition: hash.h:269
void mac_copy(void *dst, void *src)
Definition: lisp_types.c:783
u32 lisp_msg_parse_eid_rec(vlib_buffer_t *b, gid_address_t *eid)
#define MREG_DATA(h_)
#define vnet_buffer(b)
Definition: buffer.h:417
vnet_crypto_op_id_t
Definition: crypto.h:196
gid_address_t dst
Definition: control.h:51
static int add_ndp_entry(BVT(clib_bihash_kv) *kvp, void *arg)
Definition: control.c:961
static void map_records_arg_free(map_records_arg_t *a)
Definition: control.c:3825
void ip_address_copy(ip_address_t *dst, const ip_address_t *src)
Definition: ip_types.c:130
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, u16 type)
Definition: control.c:3265
int vnet_lisp_add_del_map_resolver(vnet_lisp_add_del_map_resolver_args_t *a)
Definition: control.c:2278
ip4_main_t ip4_main
Global ip4 main structure.
Definition: ip4_forward.c:1144
int vnet_lisp_gpe_get_fwd_stats(vnet_lisp_gpe_add_del_fwd_entry_args_t *a, vlib_counter_t *c)
u32 TW() tw_timer_start(TWT(tw_timer_wheel) *tw, u32 user_id, u32 timer_id, u64 interval)
Start a Tw Timer.
int vnet_lisp_add_del_l2_arp_ndp_entry(gid_address_t *key, u8 *mac, u8 is_add)
Definition: control.c:997
u32 ** lcl_to_rmt_adjacencies
Definition: control.h:200
static vlib_thread_main_t * vlib_get_thread_main()
Definition: global_funcs.h:32
static void find_ip_header(vlib_buffer_t *b, u8 **ip_hdr)
Definition: control.c:4211
ip_address_t rmt_loc
Definition: lisp_types.h:330
static void process_expired_mapping(lisp_cp_main_t *lcm, u32 mi)
Definition: control.c:3758
#define vec_foreach(var, vec)
Vector iterator.
static void * vlib_buffer_pull(vlib_buffer_t *b, u8 size)
Retrieve bytes from buffer head.
Definition: buffer.h:400
save_rewrite_length must be aligned so that reass doesn t overwrite it
Definition: buffer.h:401
static int add_l2_arp_bd(BVT(clib_bihash_kv) *kvp, void *arg)
Definition: control.c:871
uword * map_register_messages_by_nonce
Definition: control.h:218
void * vlib_add_trace(vlib_main_t *vm, vlib_node_runtime_t *r, vlib_buffer_t *b, u32 n_data_bytes)
Definition: trace.c:577
static void update_rloc_probing(lisp_cp_main_t *lcm, f64 dt)
Definition: control.c:4681
lisp_cp_main_t lisp_control_main
Definition: control.c:37
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:468
u8 si
Definition: lisp_types.api:47
#define gid_address_arp_ip4(_a)
Definition: lisp_types.h:227
void * process_map_reply(map_records_arg_t *a)
Definition: control.c:3838
gid_address_t dst_eid
Definition: control.c:2402
static int parse_map_records(vlib_buffer_t *b, map_records_arg_t *a, u8 count)
Definition: control.c:4032
u8 ip_version_and_header_length
Definition: ip4_packet.h:93
uword * lisp_stats_index_by_key
Definition: lisp_gpe.h:163
#define MREP_NONCE(h_)
mapping_t * mappings
Definition: control.h:157
#define pool_foreach_index(i, v, body)
Iterate pool by index.
Definition: pool.h:558
static int dp_add_del_iface(lisp_cp_main_t *lcm, u32 vni, u8 is_l2, u8 is_add, u8 with_default_route)
Definition: control.c:176
u32 max_expired_map_registers
Definition: control.h:279
static void lisp_cp_disable_l2_l3_ifaces(lisp_cp_main_t *lcm)
Definition: control.c:2187
#define TW(a)
int vnet_lisp_map_register_set_ttl(u32 ttl)
Definition: control.c:2326
u32 si
Definition: control.c:543
u32 vnet_lisp_map_register_get_ttl(void)
Definition: control.c:2334
static void * dp_add_fwd_entry_thread_fn(void *arg)
Definition: control.c:548
void build_src_dst(gid_address_t *sd, gid_address_t *src, gid_address_t *dst)
Definition: lisp_types.c:1452
static uword lisp_cp_lookup_ip6(vlib_main_t *vm, vlib_node_runtime_t *node, vlib_frame_t *from_frame)
Definition: control.c:3583
int vnet_lisp_use_petr(ip_address_t *ip, u8 is_add)
Configure Proxy-ETR.
Definition: control.c:1649
gid_address_t lcl_eid
local eid
Definition: lisp_gpe.h:243
u32 mreq_itr_rlocs
Definition: control.h:237
static vnet_crypto_alg_t lisp_key_type_to_crypto_alg(lisp_key_type_t key_id)
Definition: control.c:2693
static vlib_buffer_t * vlib_get_buffer(vlib_main_t *vm, u32 buffer_index)
Translate buffer index into buffer pointer.
Definition: buffer_funcs.h:85
static foreach_msmr void free_map_register_records(mapping_t *maps)
Definition: control.c:2618
u32 * locator_indices
Definition: lisp_types.h:287
#define send_encapsulated_map_request(lcm, seid, deid, smr)
Definition: control.c:3022
vnet_main_t * vnet_main
Definition: control.h:292
void TW() tw_timer_stop(TWT(tw_timer_wheel) *tw, u32 handle)
Stop a tw timer.
#define MREP_RLOC_PROBE(h_)
static int is_auth_data_valid(map_notify_hdr_t *h, u32 msg_len, lisp_key_type_t key_id, u8 *key)
Definition: control.c:3912
A LISP GPE Tunnel.
static mapping_t * build_map_register_record_list(lisp_cp_main_t *lcm)
Definition: control.c:2672
vl_api_interface_index_t sw_if_index
Definition: wireguard.api:33
u8 * format_lisp_cp_lookup_trace(u8 *s, va_list *args)
Definition: control.c:2407
#define MAP_REGISTER_DEFAULT_TTL
Definition: control.h:46
ip4_main_t * im4
Definition: control.h:289
gid_address_t leid
Definition: control.h:66
Definition: defs.h:46
lisp_msg_type_e
ip6_address_t dst_address
Definition: ip6_packet.h:310
#define resend_encapsulated_map_request(lcm, seid, deid, smr)
Definition: control.c:3025
lisp_cp_output_error_t
Definition: control.c:2825
#define PENDING_MREQ_EXPIRATION_TIME
Definition: control.h:26
static int lisp_stats_api_fill(lisp_cp_main_t *lcm, lisp_gpe_main_t *lgm, lisp_api_stats_t *stat, lisp_stats_key_t *key, u32 stats_index)
Definition: control.c:4520
locator_t * locators
Definition: lisp_types.h:299
lisp_cp_input_error_t
Definition: control.c:3698
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:3395
static int add_ndp_bd(BVT(clib_bihash_kv) *kvp, void *arg)
Definition: control.c:895
fib_entry_flag_t fib_entry_get_flags(fib_node_index_t fib_entry_index)
Definition: fib_entry.c:291