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