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