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