FD.io VPP  v20.01-48-g3e0dafb74
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 int
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 (BIHASH_WALK_CONTINUE);
909 
910  u32 bd = (u32) (kvp->key[0] >> 32);
911  hash_set (ht[0], bd, 0);
912  return (BIHASH_WALK_CONTINUE);
913 }
914 
915 u32 *
917 {
919  u32 *bds = 0;
920 
922  add_l2_arp_bd, &bds);
923  return bds;
924 }
925 
926 static int
927 add_ndp_bd (BVT (clib_bihash_kv) * kvp, void *arg)
928 {
929  u32 **ht = arg;
930  u32 version = (u32) kvp->key[0];
931  if (AF_IP4 == version)
932  return (BIHASH_WALK_CONTINUE);
933 
934  u32 bd = (u32) (kvp->key[0] >> 32);
935  hash_set (ht[0], bd, 0);
936  return (BIHASH_WALK_CONTINUE);
937 }
938 
939 u32 *
941 {
943  u32 *bds = 0;
944 
946  add_ndp_bd, &bds);
947  return bds;
948 }
949 
950 typedef struct
951 {
952  void *vector;
955 
956 static int
957 add_l2_arp_entry (BVT (clib_bihash_kv) * kvp, void *arg)
958 {
960  lisp_api_l2_arp_entry_t **vector = a->vector, e;
961 
962  u32 version = (u32) kvp->key[0];
963  if (AF_IP6 == version)
964  return (BIHASH_WALK_CONTINUE);
965 
966  u32 bd = (u32) (kvp->key[0] >> 32);
967 
968  if (bd == a->bd)
969  {
970  mac_copy (e.mac, (void *) &kvp->value);
971  e.ip4 = (u32) kvp->key[1];
972  vec_add1 (vector[0], e);
973  }
974  return (BIHASH_WALK_CONTINUE);
975 }
976 
979 {
983 
984  a.vector = &entries;
985  a.bd = bd;
986 
988  add_l2_arp_entry, &a);
989  return entries;
990 }
991 
992 static int
993 add_ndp_entry (BVT (clib_bihash_kv) * kvp, void *arg)
994 {
996  lisp_api_ndp_entry_t **vector = a->vector, e;
997 
998  u32 version = (u32) kvp->key[0];
999  if (AF_IP4 == version)
1000  return (BIHASH_WALK_CONTINUE);
1001 
1002  u32 bd = (u32) (kvp->key[0] >> 32);
1003 
1004  if (bd == a->bd)
1005  {
1006  mac_copy (e.mac, (void *) &kvp->value);
1007  clib_memcpy (e.ip6, &kvp->key[1], 16);
1008  vec_add1 (vector[0], e);
1009  }
1010  return (BIHASH_WALK_CONTINUE);
1011 }
1012 
1015 {
1019 
1020  a.vector = &entries;
1021  a.bd = bd;
1022 
1024  add_ndp_entry, &a);
1025  return entries;
1026 }
1027 
1028 int
1030 {
1031  if (vnet_lisp_enable_disable_status () == 0)
1032  {
1033  clib_warning ("LISP is disabled!");
1034  return VNET_API_ERROR_LISP_DISABLED;
1035  }
1036 
1038  int rc = 0;
1039 
1040  u64 res = gid_dictionary_lookup (&lcm->mapping_index_by_gid, key);
1041  if (is_add)
1042  {
1043  if (res != GID_LOOKUP_MISS_L2)
1044  {
1045  clib_warning ("Entry %U exists in DB!", format_gid_address, key);
1046  return VNET_API_ERROR_ENTRY_ALREADY_EXISTS;
1047  }
1048  u64 val = mac_to_u64 (mac);
1050  1 /* is_add */ );
1051  }
1052  else
1053  {
1054  if (res == GID_LOOKUP_MISS_L2)
1055  {
1056  clib_warning ("ONE entry %U not found - cannot delete!",
1057  format_gid_address, key);
1058  return -1;
1059  }
1061  0 /* is_add */ );
1062  }
1063 
1064  return rc;
1065 }
1066 
1067 int
1068 vnet_lisp_eid_table_map (u32 vni, u32 dp_id, u8 is_l2, u8 is_add)
1069 {
1071  uword *dp_idp, *vnip, **dp_table_by_vni, **vni_by_dp_table;
1072 
1073  if (vnet_lisp_enable_disable_status () == 0)
1074  {
1075  clib_warning ("LISP is disabled!");
1076  return VNET_API_ERROR_LISP_DISABLED;
1077  }
1078 
1079  dp_table_by_vni = is_l2 ? &lcm->bd_id_by_vni : &lcm->table_id_by_vni;
1080  vni_by_dp_table = is_l2 ? &lcm->vni_by_bd_id : &lcm->vni_by_table_id;
1081 
1082  if (!is_l2 && (vni == 0 || dp_id == 0))
1083  {
1084  clib_warning ("can't add/del default vni-vrf mapping!");
1085  return -1;
1086  }
1087 
1088  dp_idp = hash_get (dp_table_by_vni[0], vni);
1089  vnip = hash_get (vni_by_dp_table[0], dp_id);
1090 
1091  if (is_add)
1092  {
1093  if (dp_idp || vnip)
1094  {
1095  clib_warning ("vni %d or vrf %d already used in vrf/vni "
1096  "mapping!", vni, dp_id);
1097  return -1;
1098  }
1099  hash_set (dp_table_by_vni[0], vni, dp_id);
1100  hash_set (vni_by_dp_table[0], dp_id, vni);
1101 
1102  /* create dp iface */
1103  dp_add_del_iface (lcm, vni, is_l2, 1 /* is_add */ ,
1104  1 /* with_default_route */ );
1105  }
1106  else
1107  {
1108  if (!dp_idp || !vnip)
1109  {
1110  clib_warning ("vni %d or vrf %d not used in any vrf/vni! "
1111  "mapping!", vni, dp_id);
1112  return -1;
1113  }
1114  /* remove dp iface */
1115  dp_add_del_iface (lcm, vni, is_l2, 0 /* is_add */ , 0 /* unused */ );
1116 
1117  hash_unset (dp_table_by_vni[0], vni);
1118  hash_unset (vni_by_dp_table[0], dp_id);
1119  }
1120  return 0;
1121 
1122 }
1123 
1124 /* return 0 if the two locator sets are identical 1 otherwise */
1125 static u8
1126 compare_locators (lisp_cp_main_t * lcm, u32 * old_ls_indexes,
1127  locator_t * new_locators)
1128 {
1129  u32 i, old_li;
1130  locator_t *old_loc, *new_loc;
1131 
1132  if (vec_len (old_ls_indexes) != vec_len (new_locators))
1133  return 1;
1134 
1135  for (i = 0; i < vec_len (new_locators); i++)
1136  {
1137  old_li = vec_elt (old_ls_indexes, i);
1138  old_loc = pool_elt_at_index (lcm->locator_pool, old_li);
1139 
1140  new_loc = vec_elt_at_index (new_locators, i);
1141 
1142  if (locator_cmp (old_loc, new_loc))
1143  return 1;
1144  }
1145  return 0;
1146 }
1147 
1148 typedef struct
1149 {
1151  void *lcm;
1154 
1155 /**
1156  * Callback invoked when a sub-prefix is found
1157  */
1158 static void
1160 {
1161  u8 delete = 0;
1162  remove_mapping_args_t *a = arg;
1163  lisp_cp_main_t *lcm = a->lcm;
1164  mapping_t *m;
1165  locator_set_t *ls;
1166 
1167  m = pool_elt_at_index (lcm->mapping_pool, mi);
1168  if (!m)
1169  return;
1170 
1172 
1173  if (a->is_negative)
1174  {
1175  if (0 != vec_len (ls->locator_indices))
1176  delete = 1;
1177  }
1178  else
1179  {
1180  if (0 == vec_len (ls->locator_indices))
1181  delete = 1;
1182  }
1183 
1184  if (delete)
1185  vec_add1 (a->eids_to_be_deleted, m->eid);
1186 }
1187 
1188 /**
1189  * This function searches map cache and looks for IP prefixes that are subset
1190  * of the provided one. If such prefix is found depending on 'is_negative'
1191  * it does follows:
1192  *
1193  * 1) if is_negative is true and found prefix points to positive mapping,
1194  * then the mapping is removed
1195  * 2) if is_negative is false and found prefix points to negative mapping,
1196  * then the mapping is removed
1197  */
1198 static void
1200  u8 is_negative)
1201 {
1202  gid_address_t *e;
1204 
1205  clib_memset (&a, 0, sizeof (a));
1206 
1207  /* do this only in src/dst mode ... */
1208  if (MR_MODE_SRC_DST != lcm->map_request_mode)
1209  return;
1210 
1211  /* ... and only for IP prefix */
1212  if (GID_ADDR_SRC_DST != gid_address_type (eid)
1214  return;
1215 
1216  a.is_negative = is_negative;
1217  a.lcm = lcm;
1218 
1221 
1223  {
1224  vnet_lisp_add_del_adjacency_args_t _adj_args, *adj_args = &_adj_args;
1225 
1226  clib_memset (adj_args, 0, sizeof (adj_args[0]));
1227  gid_address_copy (&adj_args->reid, e);
1228  adj_args->is_add = 0;
1229  if (vnet_lisp_add_del_adjacency (adj_args))
1230  clib_warning ("failed to del adjacency!");
1231 
1233  }
1234 
1236 }
1237 
1238 static void
1240 {
1241  timing_wheel_delete (&lcm->wheel, mi);
1242 }
1243 
1244 static int
1246 {
1247  fib_node_index_t fei;
1250 
1251  ip_address_to_fib_prefix (addr, &prefix);
1252 
1253  fei = fib_table_lookup (0, &prefix);
1254  flags = fib_entry_get_flags (fei);
1255  return (FIB_ENTRY_FLAG_LOCAL & flags);
1256 }
1257 
1258 /**
1259  * Adds/updates mapping. Does not program forwarding.
1260  *
1261  * @param a parameters of the new mapping
1262  * @param rlocs vector of remote locators
1263  * @param res_map_index index of the newly created mapping
1264  * @param locators_changed indicator if locators were updated in the mapping
1265  * @return return code
1266  */
1267 int
1269  locator_t * rlocs,
1270  u32 * res_map_index, u8 * is_updated)
1271 {
1272  vnet_lisp_add_del_locator_set_args_t _ls_args, *ls_args = &_ls_args;
1274  u32 mi, ls_index = 0, dst_map_index;
1275  mapping_t *old_map;
1276  locator_t *loc;
1277 
1278  if (vnet_lisp_enable_disable_status () == 0)
1279  {
1280  clib_warning ("LISP is disabled!");
1281  return VNET_API_ERROR_LISP_DISABLED;
1282  }
1283 
1284  if (res_map_index)
1285  res_map_index[0] = ~0;
1286  if (is_updated)
1287  is_updated[0] = 0;
1288 
1289  clib_memset (ls_args, 0, sizeof (ls_args[0]));
1290 
1291  ls_args->locators = rlocs;
1293  old_map = ((u32) ~ 0 != mi) ? pool_elt_at_index (lcm->mapping_pool, mi) : 0;
1294 
1295  /* check if none of the locators match locally configured address */
1296  vec_foreach (loc, rlocs)
1297  {
1298  ip_prefix_t *p = &gid_address_ippref (&loc->address);
1299  if (is_local_ip (lcm, &ip_prefix_addr (p)))
1300  {
1301  clib_warning ("RLOC %U matches a local address!",
1302  format_gid_address, &loc->address);
1303  return VNET_API_ERROR_LISP_RLOC_LOCAL;
1304  }
1305  }
1306 
1307  /* overwrite: if mapping already exists, decide if locators should be
1308  * updated and be done */
1309  if (old_map && gid_address_cmp (&old_map->eid, &a->eid) == 0)
1310  {
1311  if (!a->is_static && (old_map->is_static || old_map->local))
1312  {
1313  /* do not overwrite local or static remote mappings */
1314  clib_warning ("mapping %U rejected due to collision with local "
1315  "or static remote mapping!", format_gid_address,
1316  &a->eid);
1317  return 0;
1318  }
1319 
1320  locator_set_t *old_ls;
1321 
1322  /* update mapping attributes */
1323  old_map->action = a->action;
1324  if (old_map->action != a->action && NULL != is_updated)
1325  is_updated[0] = 1;
1326 
1327  old_map->authoritative = a->authoritative;
1328  old_map->ttl = a->ttl;
1329 
1330  old_ls = pool_elt_at_index (lcm->locator_set_pool,
1331  old_map->locator_set_index);
1332  if (compare_locators (lcm, old_ls->locator_indices, ls_args->locators))
1333  {
1334  /* set locator-set index to overwrite */
1335  ls_args->is_add = 1;
1336  ls_args->index = old_map->locator_set_index;
1337  vnet_lisp_add_del_locator_set (ls_args, 0);
1338  if (is_updated)
1339  is_updated[0] = 1;
1340  }
1341  if (res_map_index)
1342  res_map_index[0] = mi;
1343  }
1344  /* new mapping */
1345  else
1346  {
1347  if (is_updated)
1348  is_updated[0] = 1;
1349  remove_overlapping_sub_prefixes (lcm, &a->eid, 0 == ls_args->locators);
1350 
1351  ls_args->is_add = 1;
1352  ls_args->index = ~0;
1353 
1354  vnet_lisp_add_del_locator_set (ls_args, &ls_index);
1355 
1356  /* add mapping */
1357  a->is_add = 1;
1358  a->locator_set_index = ls_index;
1359  vnet_lisp_map_cache_add_del (a, &dst_map_index);
1360 
1361  if (res_map_index)
1362  res_map_index[0] = dst_map_index;
1363  }
1364 
1365  /* success */
1366  return 0;
1367 }
1368 
1369 /**
1370  * Removes a mapping. Does not program forwarding.
1371  *
1372  * @param eid end-host identifier
1373  * @param res_map_index index of the removed mapping
1374  * @return return code
1375  */
1376 int
1377 vnet_lisp_del_mapping (gid_address_t * eid, u32 * res_map_index)
1378 {
1380  vnet_lisp_add_del_mapping_args_t _m_args, *m_args = &_m_args;
1381  vnet_lisp_add_del_locator_set_args_t _ls_args, *ls_args = &_ls_args;
1382  mapping_t *old_map;
1383  u32 mi;
1384 
1385  clib_memset (ls_args, 0, sizeof (ls_args[0]));
1386  clib_memset (m_args, 0, sizeof (m_args[0]));
1387  if (res_map_index)
1388  res_map_index[0] = ~0;
1389 
1390  mi = gid_dictionary_lookup (&lcm->mapping_index_by_gid, eid);
1391  old_map = ((u32) ~ 0 != mi) ? pool_elt_at_index (lcm->mapping_pool, mi) : 0;
1392 
1393  if (old_map == 0 || gid_address_cmp (&old_map->eid, eid) != 0)
1394  {
1395  clib_warning ("cannot delete mapping for eid %U",
1396  format_gid_address, eid);
1397  return -1;
1398  }
1399 
1400  m_args->is_add = 0;
1401  gid_address_copy (&m_args->eid, eid);
1402  m_args->locator_set_index = old_map->locator_set_index;
1403 
1404  /* delete mapping associated from map-cache */
1405  vnet_lisp_map_cache_add_del (m_args, 0);
1406 
1407  ls_args->is_add = 0;
1408  ls_args->index = old_map->locator_set_index;
1409 
1410  /* delete locator set */
1411  vnet_lisp_add_del_locator_set (ls_args, 0);
1412 
1413  /* delete timer associated to the mapping if any */
1414  if (old_map->timer_set)
1415  mapping_delete_timer (lcm, mi);
1416 
1417  /* return old mapping index */
1418  if (res_map_index)
1419  res_map_index[0] = mi;
1420 
1421  /* success */
1422  return 0;
1423 }
1424 
1425 int
1427 {
1428  int rv = 0;
1429  u32 mi, *map_indices = 0, *map_indexp;
1431  vnet_lisp_add_del_mapping_args_t _dm_args, *dm_args = &_dm_args;
1432  vnet_lisp_add_del_locator_set_args_t _ls, *ls = &_ls;
1433 
1434  /* *INDENT-OFF* */
1435  pool_foreach_index (mi, lcm->mapping_pool,
1436  ({
1437  vec_add1 (map_indices, mi);
1438  }));
1439  /* *INDENT-ON* */
1440 
1441  vec_foreach (map_indexp, map_indices)
1442  {
1443  mapping_t *map = pool_elt_at_index (lcm->mapping_pool, map_indexp[0]);
1444  if (!map->local)
1445  {
1446  dp_del_fwd_entry (lcm, map_indexp[0]);
1447 
1448  dm_args->is_add = 0;
1449  gid_address_copy (&dm_args->eid, &map->eid);
1450  dm_args->locator_set_index = map->locator_set_index;
1451 
1452  /* delete mapping associated to fwd entry */
1453  vnet_lisp_map_cache_add_del (dm_args, 0);
1454 
1455  ls->is_add = 0;
1456  ls->local = 0;
1457  ls->index = map->locator_set_index;
1458  /* delete locator set */
1459  rv = vnet_lisp_add_del_locator_set (ls, 0);
1460  if (rv != 0)
1461  goto cleanup;
1462  }
1463  }
1464 
1465 cleanup:
1466  if (map_indices)
1467  vec_free (map_indices);
1468  return rv;
1469 }
1470 
1471 /**
1472  * Adds adjacency or removes forwarding entry associated to remote mapping.
1473  * Note that adjacencies are not stored, they only result in forwarding entries
1474  * being created.
1475  */
1476 int
1478 {
1480  u32 local_mi, remote_mi = ~0;
1481 
1482  if (vnet_lisp_enable_disable_status () == 0)
1483  {
1484  clib_warning ("LISP is disabled!");
1485  return VNET_API_ERROR_LISP_DISABLED;
1486  }
1487 
1489  &a->reid, &a->leid);
1490  if (GID_LOOKUP_MISS == remote_mi)
1491  {
1492  clib_warning ("Remote eid %U not found. Cannot add adjacency!",
1493  format_gid_address, &a->reid);
1494 
1495  return -1;
1496  }
1497 
1498  if (a->is_add)
1499  {
1500  /* check if source eid has an associated mapping. If pitr mode is on,
1501  * just use the pitr's mapping */
1502  if (lcm->flags & LISP_FLAG_PITR_MODE)
1503  {
1504  if (lcm->pitr_map_index != ~0)
1505  {
1506  local_mi = lcm->pitr_map_index;
1507  }
1508  else
1509  {
1510  /* PITR mode is on, but no mapping is configured */
1511  return -1;
1512  }
1513  }
1514  else
1515  {
1516  if (gid_address_type (&a->reid) == GID_ADDR_NSH)
1517  {
1518  if (lcm->nsh_map_index == ~0)
1519  local_mi = GID_LOOKUP_MISS;
1520  else
1521  local_mi = lcm->nsh_map_index;
1522  }
1523  else
1524  {
1525  local_mi = gid_dictionary_lookup (&lcm->mapping_index_by_gid,
1526  &a->leid);
1527  }
1528  }
1529 
1530  if (GID_LOOKUP_MISS == local_mi)
1531  {
1532  clib_warning ("Local eid %U not found. Cannot add adjacency!",
1533  format_gid_address, &a->leid);
1534 
1535  return -1;
1536  }
1537 
1538  /* update forwarding */
1539  dp_add_fwd_entry (lcm, local_mi, remote_mi);
1540  }
1541  else
1542  dp_del_fwd_entry (lcm, remote_mi);
1543 
1544  return 0;
1545 }
1546 
1547 int
1549 {
1551 
1552  if (vnet_lisp_enable_disable_status () == 0)
1553  {
1554  clib_warning ("LISP is disabled!");
1555  return VNET_API_ERROR_LISP_DISABLED;
1556  }
1557 
1558  if (mode >= _MR_MODE_MAX)
1559  {
1560  clib_warning ("Invalid LISP map request mode %d!", mode);
1561  return VNET_API_ERROR_INVALID_ARGUMENT;
1562  }
1563 
1564  lcm->map_request_mode = mode;
1565  return 0;
1566 }
1567 
1568 int
1569 vnet_lisp_nsh_set_locator_set (u8 * locator_set_name, u8 is_add)
1570 {
1573  u32 locator_set_index = ~0;
1574  mapping_t *m;
1575  uword *p;
1576 
1577  if (vnet_lisp_enable_disable_status () == 0)
1578  {
1579  clib_warning ("LISP is disabled!");
1580  return VNET_API_ERROR_LISP_DISABLED;
1581  }
1582 
1583  if (is_add)
1584  {
1585  if (lcm->nsh_map_index == (u32) ~ 0)
1586  {
1587  p = hash_get_mem (lcm->locator_set_index_by_name, locator_set_name);
1588  if (!p)
1589  {
1590  clib_warning ("locator-set %v doesn't exist", locator_set_name);
1591  return -1;
1592  }
1593  locator_set_index = p[0];
1594 
1595  pool_get (lcm->mapping_pool, m);
1596  clib_memset (m, 0, sizeof *m);
1597  m->locator_set_index = locator_set_index;
1598  m->local = 1;
1599  m->nsh_set = 1;
1600  lcm->nsh_map_index = m - lcm->mapping_pool;
1601 
1602  if (~0 == vnet_lisp_gpe_add_nsh_iface (lgm))
1603  return -1;
1604  }
1605  }
1606  else
1607  {
1608  if (lcm->nsh_map_index != (u32) ~ 0)
1609  {
1610  /* remove NSH mapping */
1612  lcm->nsh_map_index = ~0;
1614  }
1615  }
1616  return 0;
1617 }
1618 
1619 int
1620 vnet_lisp_pitr_set_locator_set (u8 * locator_set_name, u8 is_add)
1621 {
1623  u32 locator_set_index = ~0;
1624  mapping_t *m;
1625  uword *p;
1626 
1627  if (vnet_lisp_enable_disable_status () == 0)
1628  {
1629  clib_warning ("LISP is disabled!");
1630  return VNET_API_ERROR_LISP_DISABLED;
1631  }
1632 
1633  p = hash_get_mem (lcm->locator_set_index_by_name, locator_set_name);
1634  if (!p)
1635  {
1636  clib_warning ("locator-set %v doesn't exist", locator_set_name);
1637  return -1;
1638  }
1639  locator_set_index = p[0];
1640 
1641  if (is_add)
1642  {
1643  pool_get (lcm->mapping_pool, m);
1644  m->locator_set_index = locator_set_index;
1645  m->local = 1;
1646  m->pitr_set = 1;
1647  lcm->pitr_map_index = m - lcm->mapping_pool;
1648  }
1649  else
1650  {
1651  /* remove pitr mapping */
1653  lcm->pitr_map_index = ~0;
1654  }
1655  return 0;
1656 }
1657 
1658 int
1660 {
1662  if (0 == value)
1663  {
1664  return VNET_API_ERROR_INVALID_ARGUMENT;
1665  }
1666 
1668  return 0;
1669 }
1670 
1671 u32
1673 {
1675  return lcm->max_expired_map_registers;
1676 }
1677 
1678 /**
1679  * Configure Proxy-ETR
1680  *
1681  * @param ip PETR's IP address
1682  * @param is_add Flag that indicates if this is an addition or removal
1683  *
1684  * return 0 on success
1685  */
1686 int
1688 {
1690  u32 ls_index = ~0;
1691  mapping_t *m;
1692  vnet_lisp_add_del_locator_set_args_t _ls_args, *ls_args = &_ls_args;
1693  locator_t loc;
1694 
1695  if (vnet_lisp_enable_disable_status () == 0)
1696  {
1697  clib_warning ("LISP is disabled!");
1698  return VNET_API_ERROR_LISP_DISABLED;
1699  }
1700 
1701  clib_memset (ls_args, 0, sizeof (*ls_args));
1702 
1703  if (is_add)
1704  {
1705  /* Create dummy petr locator-set */
1706  clib_memset (&loc, 0, sizeof (loc));
1707  gid_address_from_ip (&loc.address, ip);
1708  loc.priority = 1;
1709  loc.state = loc.weight = 1;
1710  loc.local = 0;
1711 
1712  ls_args->is_add = 1;
1713  ls_args->index = ~0;
1714  vec_add1 (ls_args->locators, loc);
1715  vnet_lisp_add_del_locator_set (ls_args, &ls_index);
1716 
1717  /* Add petr mapping */
1718  pool_get (lcm->mapping_pool, m);
1719  m->locator_set_index = ls_index;
1720  lcm->petr_map_index = m - lcm->mapping_pool;
1721 
1722  /* Enable use-petr */
1723  lcm->flags |= LISP_FLAG_USE_PETR;
1724  }
1725  else
1726  {
1728 
1729  /* Remove petr locator */
1730  ls_args->is_add = 0;
1731  ls_args->index = m->locator_set_index;
1732  vnet_lisp_add_del_locator_set (ls_args, 0);
1733 
1734  /* Remove petr mapping */
1736 
1737  /* Disable use-petr */
1738  lcm->flags &= ~LISP_FLAG_USE_PETR;
1739  lcm->petr_map_index = ~0;
1740  }
1741  return 0;
1742 }
1743 
1744 /* cleans locator to locator-set data and removes locators not part of
1745  * any locator-set */
1746 static void
1748 {
1749  u32 i, j, *loc_indexp, *ls_indexp, **ls_indexes, *to_be_deleted = 0;
1751  for (i = 0; i < vec_len (ls->locator_indices); i++)
1752  {
1753  loc_indexp = vec_elt_at_index (ls->locator_indices, i);
1754  ls_indexes = vec_elt_at_index (lcm->locator_to_locator_sets,
1755  loc_indexp[0]);
1756  for (j = 0; j < vec_len (ls_indexes[0]); j++)
1757  {
1758  ls_indexp = vec_elt_at_index (ls_indexes[0], j);
1759  if (ls_indexp[0] == lsi)
1760  break;
1761  }
1762 
1763  /* delete index for removed locator-set */
1764  vec_del1 (ls_indexes[0], j);
1765 
1766  /* delete locator if it's part of no locator-set */
1767  if (vec_len (ls_indexes[0]) == 0)
1768  {
1769  pool_put_index (lcm->locator_pool, loc_indexp[0]);
1770  vec_add1 (to_be_deleted, i);
1771  }
1772  }
1773 
1774  if (to_be_deleted)
1775  {
1776  for (i = 0; i < vec_len (to_be_deleted); i++)
1777  {
1778  loc_indexp = vec_elt_at_index (to_be_deleted, i);
1779  vec_del1 (ls->locator_indices, loc_indexp[0]);
1780  }
1781  vec_free (to_be_deleted);
1782  }
1783 }
1784 
1785 static inline uword *
1787 {
1789 
1790  ASSERT (a != NULL);
1791  ASSERT (p != NULL);
1792 
1793  /* find locator-set */
1794  if (a->local)
1795  {
1796  ASSERT (a->name);
1798  }
1799  else
1800  {
1801  *p = a->index;
1802  }
1803 
1804  return p;
1805 }
1806 
1807 static inline int
1809  locator_t * loc)
1810 {
1811  locator_t *itloc;
1812  u32 *locit;
1813 
1814  ASSERT (ls != NULL);
1815  ASSERT (loc != NULL);
1816 
1817  vec_foreach (locit, ls->locator_indices)
1818  {
1819  itloc = pool_elt_at_index (lcm->locator_pool, locit[0]);
1820  if ((ls->local && itloc->sw_if_index == loc->sw_if_index) ||
1821  (!ls->local && !gid_address_cmp (&itloc->address, &loc->address)))
1822  {
1823  clib_warning ("Duplicate locator");
1824  return VNET_API_ERROR_VALUE_EXIST;
1825  }
1826  }
1827 
1828  return 0;
1829 }
1830 
1831 static void
1833  u32 mapping_index, u8 remove_only)
1834 {
1835  fwd_entry_t *fwd;
1836  mapping_t *map;
1837  uword *fei = 0, *rmts_idxp = 0;
1838  u32 **rmts = 0, *remote_idxp = 0, *rmts_copy = 0;
1840  clib_memset (a, 0, sizeof (*a));
1841 
1842  map = pool_elt_at_index (lcm->mapping_pool, mapping_index);
1843 
1844  if (map->local)
1845  {
1846  rmts_idxp = hash_get (lcm->lcl_to_rmt_adjs_by_lcl_idx, mapping_index);
1847  if (rmts_idxp)
1848  {
1849  rmts =
1850  pool_elt_at_index (lcm->lcl_to_rmt_adjacencies, rmts_idxp[0]);
1851  rmts_copy = vec_dup (rmts[0]);
1852 
1853  vec_foreach (remote_idxp, rmts_copy)
1854  {
1855  fei = hash_get (lcm->fwd_entry_by_mapping_index, remote_idxp[0]);
1856  if (!fei)
1857  continue;
1858 
1859  fwd = pool_elt_at_index (lcm->fwd_entry_pool, fei[0]);
1860  a->is_add = 0;
1861  gid_address_copy (&a->leid, &fwd->leid);
1862  gid_address_copy (&a->reid, &fwd->reid);
1864 
1865  if (!remove_only)
1866  {
1867  a->is_add = 1;
1869  }
1870  }
1871  vec_free (rmts_copy);
1872  }
1873  }
1874  else
1875  {
1876  fei = hash_get (lcm->fwd_entry_by_mapping_index, mapping_index);
1877  if (!fei)
1878  return;
1879 
1880  fwd = pool_elt_at_index (lcm->fwd_entry_pool, fei[0]);
1881  a->is_add = 0;
1882  gid_address_copy (&a->leid, &fwd->leid);
1883  gid_address_copy (&a->reid, &fwd->reid);
1885 
1886  if (!remove_only)
1887  {
1888  a->is_add = 1;
1890  }
1891  }
1892 }
1893 
1894 static void
1896  u32 ls_index, u8 remove_only)
1897 {
1898  u32 i, *map_indexp;
1899  u32 **eid_indexes;
1900 
1901  if (vec_len (lcm->locator_set_to_eids) <= ls_index)
1902  return;
1903 
1904  eid_indexes = vec_elt_at_index (lcm->locator_set_to_eids, ls_index);
1905 
1906  for (i = 0; i < vec_len (eid_indexes[0]); i++)
1907  {
1908  map_indexp = vec_elt_at_index (eid_indexes[0], i);
1909  update_adjacencies_by_map_index (lcm, map_indexp[0], remove_only);
1910  }
1911 }
1912 
1913 static inline void
1915  u32 ls_index, u32 loc_id)
1916 {
1918  u32 **ls_indexes = NULL;
1919 
1920  ASSERT (ls != NULL);
1921  ASSERT (locit != NULL);
1922 
1923  ls_indexes = vec_elt_at_index (lcm->locator_to_locator_sets, locit[0]);
1924  pool_put_index (lcm->locator_pool, locit[0]);
1925  vec_del1 (ls->locator_indices, loc_id);
1926  vec_del1 (ls_indexes[0], ls_index);
1927 }
1928 
1929 int
1931  locator_set_t * ls, u32 * ls_result)
1932 {
1934  locator_t *loc = NULL, *itloc = NULL;
1935  uword _p = (u32) ~ 0, *p = &_p;
1936  u32 loc_index = ~0, ls_index = ~0, *locit = NULL, **ls_indexes = NULL;
1937  u32 loc_id = ~0;
1938  int ret = 0;
1939 
1940  ASSERT (a != NULL);
1941 
1942  if (vnet_lisp_enable_disable_status () == 0)
1943  {
1944  clib_warning ("LISP is disabled!");
1945  return VNET_API_ERROR_LISP_DISABLED;
1946  }
1947 
1948  p = get_locator_set_index (a, p);
1949  if (!p)
1950  {
1951  clib_warning ("locator-set %v doesn't exist", a->name);
1952  return VNET_API_ERROR_INVALID_ARGUMENT;
1953  }
1954 
1955  if (ls == 0)
1956  {
1957  ls = pool_elt_at_index (lcm->locator_set_pool, p[0]);
1958  if (!ls)
1959  {
1960  clib_warning ("locator-set %d to be overwritten doesn't exist!",
1961  p[0]);
1962  return VNET_API_ERROR_INVALID_ARGUMENT;
1963  }
1964  }
1965 
1966  if (a->is_add)
1967  {
1968  if (ls_result)
1969  ls_result[0] = p[0];
1970 
1971  /* allocate locators */
1972  vec_foreach (itloc, a->locators)
1973  {
1974  ret = is_locator_in_locator_set (lcm, ls, itloc);
1975  if (0 != ret)
1976  {
1977  return ret;
1978  }
1979 
1980  pool_get (lcm->locator_pool, loc);
1981  loc[0] = itloc[0];
1982  loc_index = loc - lcm->locator_pool;
1983 
1984  vec_add1 (ls->locator_indices, loc_index);
1985 
1986  vec_validate (lcm->locator_to_locator_sets, loc_index);
1987  ls_indexes = vec_elt_at_index (lcm->locator_to_locator_sets,
1988  loc_index);
1989  vec_add1 (ls_indexes[0], p[0]);
1990  }
1991  }
1992  else
1993  {
1994  ls_index = p[0];
1995  u8 removed;
1996 
1997  vec_foreach (itloc, a->locators)
1998  {
1999  removed = 0;
2000  loc_id = 0;
2001  vec_foreach (locit, ls->locator_indices)
2002  {
2003  loc = pool_elt_at_index (lcm->locator_pool, locit[0]);
2004 
2005  if (loc->local && loc->sw_if_index == itloc->sw_if_index)
2006  {
2007  removed = 1;
2008  remove_locator_from_locator_set (ls, locit, ls_index, loc_id);
2009  }
2010  if (0 == loc->local &&
2011  !gid_address_cmp (&loc->address, &itloc->address))
2012  {
2013  removed = 1;
2014  remove_locator_from_locator_set (ls, locit, ls_index, loc_id);
2015  }
2016 
2017  if (removed)
2018  {
2019  /* update fwd entries using this locator in DP */
2020  update_fwd_entries_by_locator_set (lcm, ls_index,
2021  vec_len (ls->locator_indices)
2022  == 0);
2023  }
2024 
2025  loc_id++;
2026  }
2027  }
2028  }
2029 
2030  return 0;
2031 }
2032 
2033 int
2035  u32 * ls_result)
2036 {
2038  locator_set_t *ls;
2039  uword _p = (u32) ~ 0, *p = &_p;
2040  u32 ls_index;
2041  u32 **eid_indexes;
2042  int ret = 0;
2043 
2044  if (vnet_lisp_enable_disable_status () == 0)
2045  {
2046  clib_warning ("LISP is disabled!");
2047  return VNET_API_ERROR_LISP_DISABLED;
2048  }
2049 
2050  if (a->is_add)
2051  {
2052  p = get_locator_set_index (a, p);
2053 
2054  /* overwrite */
2055  if (p && p[0] != (u32) ~ 0)
2056  {
2057  ls = pool_elt_at_index (lcm->locator_set_pool, p[0]);
2058  if (!ls)
2059  {
2060  clib_warning ("locator-set %d to be overwritten doesn't exist!",
2061  p[0]);
2062  return -1;
2063  }
2064 
2065  /* clean locator to locator-set vectors and remove locators if
2066  * they're not part of another locator-set */
2067  clean_locator_to_locator_set (lcm, p[0]);
2068 
2069  /* remove locator indices from locator set */
2070  vec_free (ls->locator_indices);
2071 
2072  ls_index = p[0];
2073 
2074  if (ls_result)
2075  ls_result[0] = p[0];
2076  }
2077  /* new locator-set */
2078  else
2079  {
2080  pool_get (lcm->locator_set_pool, ls);
2081  clib_memset (ls, 0, sizeof (*ls));
2082  ls_index = ls - lcm->locator_set_pool;
2083 
2084  if (a->local)
2085  {
2086  ls->name = vec_dup (a->name);
2087 
2088  if (!lcm->locator_set_index_by_name)
2090  /* size */
2091  0,
2092  sizeof
2093  (ls->name
2094  [0]),
2095  sizeof
2096  (uword));
2098  ls_index);
2099 
2100  /* mark as local locator-set */
2101  vec_add1 (lcm->local_locator_set_indexes, ls_index);
2102  }
2103  ls->local = a->local;
2104  if (ls_result)
2105  ls_result[0] = ls_index;
2106  }
2107 
2108  ret = vnet_lisp_add_del_locator (a, ls, NULL);
2109  if (0 != ret)
2110  {
2111  return ret;
2112  }
2113  }
2114  else
2115  {
2116  p = get_locator_set_index (a, p);
2117  if (!p)
2118  {
2119  clib_warning ("locator-set %v doesn't exists", a->name);
2120  return -1;
2121  }
2122 
2123  ls = pool_elt_at_index (lcm->locator_set_pool, p[0]);
2124  if (!ls)
2125  {
2126  clib_warning ("locator-set with index %d doesn't exists", p[0]);
2127  return -1;
2128  }
2129 
2130  if (lcm->mreq_itr_rlocs == p[0])
2131  {
2132  clib_warning ("Can't delete the locator-set used to constrain "
2133  "the itr-rlocs in map-requests!");
2134  return -1;
2135  }
2136 
2137  if (vec_len (lcm->locator_set_to_eids) != 0)
2138  {
2139  eid_indexes = vec_elt_at_index (lcm->locator_set_to_eids, p[0]);
2140  if (vec_len (eid_indexes[0]) != 0)
2141  {
2142  clib_warning
2143  ("Can't delete a locator that supports a mapping!");
2144  return -1;
2145  }
2146  }
2147 
2148  /* clean locator to locator-sets data */
2149  clean_locator_to_locator_set (lcm, p[0]);
2150 
2151  if (ls->local)
2152  {
2153  u32 it, lsi;
2154 
2156  {
2157  lsi = vec_elt (lcm->local_locator_set_indexes, it);
2158  if (lsi == p[0])
2159  {
2161  break;
2162  }
2163  }
2165  }
2166  vec_free (ls->name);
2167  vec_free (ls->locator_indices);
2168  pool_put (lcm->locator_set_pool, ls);
2169  }
2170  return 0;
2171 }
2172 
2173 int
2175 {
2177 
2178  lcm->rloc_probing = is_enable;
2179  return 0;
2180 }
2181 
2182 int
2184 {
2186 
2187  lcm->map_registering = is_enable;
2188  return 0;
2189 }
2190 
2191 static void
2193 {
2194  udp_register_dst_port (vm, UDP_DST_PORT_lisp_cp,
2195  lisp_cp_input_node.index, 1 /* is_ip4 */ );
2196  udp_register_dst_port (vm, UDP_DST_PORT_lisp_cp6,
2197  lisp_cp_input_node.index, 0 /* is_ip4 */ );
2198 }
2199 
2200 static void
2202 {
2203  udp_unregister_dst_port (vm, UDP_DST_PORT_lisp_cp, 0 /* is_ip4 */ );
2204  udp_unregister_dst_port (vm, UDP_DST_PORT_lisp_cp6, 1 /* is_ip4 */ );
2205 }
2206 
2207 /**
2208  * lisp_cp_enable_l2_l3_ifaces
2209  *
2210  * Enable all l2 and l3 ifaces
2211  */
2212 static void
2213 lisp_cp_enable_l2_l3_ifaces (lisp_cp_main_t * lcm, u8 with_default_route)
2214 {
2215  u32 vni, dp_table;
2216 
2217  /* *INDENT-OFF* */
2218  hash_foreach(vni, dp_table, lcm->table_id_by_vni, ({
2219  dp_add_del_iface(lcm, vni, /* is_l2 */ 0, /* is_add */1,
2220  with_default_route);
2221  }));
2222  hash_foreach(vni, dp_table, lcm->bd_id_by_vni, ({
2223  dp_add_del_iface(lcm, vni, /* is_l2 */ 1, 1,
2224  with_default_route);
2225  }));
2226  /* *INDENT-ON* */
2227 }
2228 
2229 static void
2231 {
2232  u32 **rmts;
2233 
2234  /* clear interface table */
2236  pool_free (lcm->fwd_entry_pool);
2237  /* Clear state tracking rmt-lcl fwd entries */
2238  /* *INDENT-OFF* */
2240  {
2241  vec_free(rmts[0]);
2242  });
2243  /* *INDENT-ON* */
2246 }
2247 
2248 clib_error_t *
2250 {
2251  clib_error_t *error = 0;
2254 
2255  a->is_en = is_enable;
2256  error = vnet_lisp_gpe_enable_disable (a);
2257  if (error)
2258  {
2259  return clib_error_return (0, "failed to %s data-plane!",
2260  a->is_en ? "enable" : "disable");
2261  }
2262 
2263  /* decide what to do based on mode */
2264 
2265  if (lcm->flags & LISP_FLAG_XTR_MODE)
2266  {
2267  if (is_enable)
2268  {
2270  lisp_cp_enable_l2_l3_ifaces (lcm, 1 /* with_default_route */ );
2271  }
2272  else
2273  {
2276  }
2277  }
2278 
2279  if (lcm->flags & LISP_FLAG_PETR_MODE)
2280  {
2281  /* if in xTR mode, the LISP ports were already (un)registered above */
2282  if (!(lcm->flags & LISP_FLAG_XTR_MODE))
2283  {
2284  if (is_enable)
2286  else
2288  }
2289  }
2290 
2291  if (lcm->flags & LISP_FLAG_PITR_MODE)
2292  {
2293  if (is_enable)
2294  {
2295  /* install interfaces, but no default routes */
2296  lisp_cp_enable_l2_l3_ifaces (lcm, 0 /* with_default_route */ );
2297  }
2298  else
2299  {
2301  }
2302  }
2303 
2304  if (is_enable)
2306 
2307  /* update global flag */
2308  lcm->is_enabled = is_enable;
2309 
2310  return 0;
2311 }
2312 
2313 u8
2315 {
2317  return lcm->is_enabled;
2318 }
2319 
2320 int
2322 {
2324  u32 i;
2325  lisp_msmr_t _mr, *mr = &_mr;
2326 
2327  if (vnet_lisp_enable_disable_status () == 0)
2328  {
2329  clib_warning ("LISP is disabled!");
2330  return VNET_API_ERROR_LISP_DISABLED;
2331  }
2332 
2333  if (a->is_add)
2334  {
2335 
2336  if (get_map_resolver (&a->address))
2337  {
2338  clib_warning ("map-resolver %U already exists!", format_ip_address,
2339  &a->address);
2340  return -1;
2341  }
2342 
2343  clib_memset (mr, 0, sizeof (*mr));
2344  ip_address_copy (&mr->address, &a->address);
2345  vec_add1 (lcm->map_resolvers, *mr);
2346 
2347  if (vec_len (lcm->map_resolvers) == 1)
2348  lcm->do_map_resolver_election = 1;
2349  }
2350  else
2351  {
2352  for (i = 0; i < vec_len (lcm->map_resolvers); i++)
2353  {
2354  mr = vec_elt_at_index (lcm->map_resolvers, i);
2355  if (!ip_address_cmp (&mr->address, &a->address))
2356  {
2357  if (!ip_address_cmp (&mr->address, &lcm->active_map_resolver))
2358  lcm->do_map_resolver_election = 1;
2359 
2360  vec_del1 (lcm->map_resolvers, i);
2361  break;
2362  }
2363  }
2364  }
2365  return 0;
2366 }
2367 
2368 int
2370 {
2372  lcm->map_register_ttl = ttl;
2373  return 0;
2374 }
2375 
2376 u32
2378 {
2380  return lcm->map_register_ttl;
2381 }
2382 
2383 int
2385 {
2387  uword *p = 0;
2388 
2389  if (vnet_lisp_enable_disable_status () == 0)
2390  {
2391  clib_warning ("LISP is disabled!");
2392  return VNET_API_ERROR_LISP_DISABLED;
2393  }
2394 
2395  if (a->is_add)
2396  {
2398  if (!p)
2399  {
2400  clib_warning ("locator-set %v doesn't exist", a->locator_set_name);
2401  return VNET_API_ERROR_INVALID_ARGUMENT;
2402  }
2403 
2404  lcm->mreq_itr_rlocs = p[0];
2405  }
2406  else
2407  {
2408  lcm->mreq_itr_rlocs = ~0;
2409  }
2410 
2411  return 0;
2412 }
2413 
2414 /* Statistics (not really errors) */
2415 #define foreach_lisp_cp_lookup_error \
2416 _(DROP, "drop") \
2417 _(MAP_REQUESTS_SENT, "map-request sent") \
2418 _(ARP_REPLY_TX, "ARP replies sent") \
2419 _(NDP_NEIGHBOR_ADVERTISEMENT_TX, \
2420  "neighbor advertisement sent")
2421 
2423 #define _(sym,string) string,
2425 #undef _
2426 };
2427 
2428 typedef enum
2429 {
2430 #define _(sym,str) LISP_CP_LOOKUP_ERROR_##sym,
2432 #undef _
2435 
2436 typedef enum
2437 {
2442 
2443 typedef struct
2444 {
2448 
2449 u8 *
2450 format_lisp_cp_lookup_trace (u8 * s, va_list * args)
2451 {
2452  CLIB_UNUSED (vlib_main_t * vm) = va_arg (*args, vlib_main_t *);
2453  CLIB_UNUSED (vlib_node_t * node) = va_arg (*args, vlib_node_t *);
2454  lisp_cp_lookup_trace_t *t = va_arg (*args, lisp_cp_lookup_trace_t *);
2455 
2456  s = format (s, "LISP-CP-LOOKUP: map-resolver: %U destination eid %U",
2458  &t->dst_eid);
2459  return s;
2460 }
2461 
2462 int
2464  ip_address_t * sloc)
2465 {
2466  lisp_msmr_t *mrit;
2467  ip_address_t *a;
2468 
2469  if (vec_len (lcm->map_resolvers) == 0)
2470  {
2471  clib_warning ("No map-resolver configured");
2472  return 0;
2473  }
2474 
2475  /* find the first mr ip we have a route to and the ip of the
2476  * iface that has a route to it */
2477  vec_foreach (mrit, lcm->map_resolvers)
2478  {
2479  a = &mrit->address;
2480  if (0 != ip_fib_get_first_egress_ip_for_dst (lcm, a, sloc))
2481  {
2482  ip_address_copy (mr_ip, a);
2483 
2484  /* also update globals */
2485  return 1;
2486  }
2487  }
2488 
2489  clib_warning ("Can't find map-resolver and local interface ip!");
2490  return 0;
2491 }
2492 
2493 static gid_address_t *
2495 {
2496  void *addr;
2497  u32 i;
2498  locator_t *loc;
2499  u32 *loc_indexp;
2500  ip_interface_address_t *ia = 0;
2501  gid_address_t gid_data, *gid = &gid_data;
2502  gid_address_t *rlocs = 0;
2503  ip_prefix_t *ippref = &gid_address_ippref (gid);
2504  ip_address_t *rloc = &ip_prefix_addr (ippref);
2505 
2506  clib_memset (gid, 0, sizeof (gid[0]));
2508  for (i = 0; i < vec_len (loc_set->locator_indices); i++)
2509  {
2510  loc_indexp = vec_elt_at_index (loc_set->locator_indices, i);
2511  loc = pool_elt_at_index (lcm->locator_pool, loc_indexp[0]);
2512 
2513  /* Add ipv4 locators first TODO sort them */
2514 
2515  /* *INDENT-OFF* */
2517  loc->sw_if_index, 1 /* unnumbered */,
2518  ({
2519  addr = ip_interface_address_get_address (&lcm->im4->lookup_main, ia);
2520  ip_address_set (rloc, addr, AF_IP4);
2521  ip_prefix_len (ippref) = 32;
2522  ip_prefix_normalize (ippref);
2523  vec_add1 (rlocs, gid[0]);
2524  }));
2525 
2526  /* Add ipv6 locators */
2528  loc->sw_if_index, 1 /* unnumbered */,
2529  ({
2530  addr = ip_interface_address_get_address (&lcm->im6->lookup_main, ia);
2531  ip_address_set (rloc, addr, AF_IP6);
2532  ip_prefix_len (ippref) = 128;
2533  ip_prefix_normalize (ippref);
2534  vec_add1 (rlocs, gid[0]);
2535  }));
2536  /* *INDENT-ON* */
2537 
2538  }
2539  return rlocs;
2540 }
2541 
2542 static vlib_buffer_t *
2544  ip_address_t * sloc, ip_address_t * rloc,
2545  gid_address_t * itr_rlocs, u64 * nonce_res, u32 * bi_res)
2546 {
2547  vlib_buffer_t *b;
2548  u32 bi;
2549  vlib_main_t *vm = lcm->vlib_main;
2550 
2551  if (vlib_buffer_alloc (vm, &bi, 1) != 1)
2552  {
2553  clib_warning ("Can't allocate buffer for Map-Request!");
2554  return 0;
2555  }
2556 
2557  b = vlib_get_buffer (vm, bi);
2558 
2559  /* leave some space for the encap headers */
2561 
2562  /* put lisp msg */
2563  lisp_msg_put_mreq (lcm, b, NULL, deid, itr_rlocs, 0 /* smr invoked */ ,
2564  1 /* rloc probe */ , nonce_res);
2565 
2566  /* push outer ip header */
2568  rloc, 1);
2569 
2570  bi_res[0] = bi;
2571 
2572  return b;
2573 }
2574 
2575 static vlib_buffer_t *
2577  gid_address_t * seid, gid_address_t * deid,
2578  locator_set_t * loc_set, ip_address_t * mr_ip,
2579  ip_address_t * sloc, u8 is_smr_invoked,
2580  u64 * nonce_res, u32 * bi_res)
2581 {
2582  vlib_buffer_t *b;
2583  u32 bi;
2584  gid_address_t *rlocs = 0;
2585  vlib_main_t *vm = lcm->vlib_main;
2586 
2587  if (vlib_buffer_alloc (vm, &bi, 1) != 1)
2588  {
2589  clib_warning ("Can't allocate buffer for Map-Request!");
2590  return 0;
2591  }
2592 
2593  b = vlib_get_buffer (vm, bi);
2594  b->flags = 0;
2595 
2596  /* leave some space for the encap headers */
2598 
2599  /* get rlocs */
2600  rlocs = build_itr_rloc_list (lcm, loc_set);
2601 
2602  if (MR_MODE_SRC_DST == lcm->map_request_mode
2603  && GID_ADDR_SRC_DST != gid_address_type (deid))
2604  {
2605  gid_address_t sd;
2606  clib_memset (&sd, 0, sizeof (sd));
2607  build_src_dst (&sd, seid, deid);
2608  lisp_msg_put_mreq (lcm, b, seid, &sd, rlocs, is_smr_invoked,
2609  0 /* rloc probe */ , nonce_res);
2610  }
2611  else
2612  {
2613  /* put lisp msg */
2614  lisp_msg_put_mreq (lcm, b, seid, deid, rlocs, is_smr_invoked,
2615  0 /* rloc probe */ , nonce_res);
2616  }
2617 
2618  /* push ecm: udp-ip-lisp */
2620 
2621  /* push outer ip header */
2623  mr_ip, 1);
2624 
2625  bi_res[0] = bi;
2626 
2627  vec_free (rlocs);
2628  return b;
2629 }
2630 
2631 static void
2633 {
2635  r->retries_num = 0;
2636 }
2637 
2638 #define foreach_msmr \
2639  _(server) \
2640  _(resolver)
2641 
2642 #define _(name) \
2643 static int \
2644 elect_map_ ## name (lisp_cp_main_t * lcm) \
2645 { \
2646  lisp_msmr_t *mr; \
2647  vec_foreach (mr, lcm->map_ ## name ## s) \
2648  { \
2649  if (!mr->is_down) \
2650  { \
2651  ip_address_copy (&lcm->active_map_ ##name, &mr->address); \
2652  lcm->do_map_ ## name ## _election = 0; \
2653  return 1; \
2654  } \
2655  } \
2656  return 0; \
2657 }
2659 #undef _
2660  static void
2662 {
2663  mapping_t *map;
2664  vec_foreach (map, maps) vec_free (map->locators);
2665 
2666  vec_free (maps);
2667 }
2668 
2669 static void
2670 add_locators (lisp_cp_main_t * lcm, mapping_t * m, u32 locator_set_index,
2671  ip_address_t * probed_loc)
2672 {
2673  u32 *li;
2674  locator_t *loc, new;
2675  ip_interface_address_t *ia = 0;
2676  void *addr;
2677  ip_address_t *new_ip = &gid_address_ip (&new.address);
2678 
2679  m->locators = 0;
2681  locator_set_index);
2682  vec_foreach (li, ls->locator_indices)
2683  {
2684  loc = pool_elt_at_index (lcm->locator_pool, li[0]);
2685  new = loc[0];
2686  if (loc->local)
2687  {
2688  /* *INDENT-OFF* */
2690  loc->sw_if_index, 1 /* unnumbered */,
2691  ({
2692  addr = ip_interface_address_get_address (&lcm->im4->lookup_main,
2693  ia);
2694  ip_address_set (new_ip, addr, AF_IP4);
2695  }));
2696 
2697  /* Add ipv6 locators */
2699  loc->sw_if_index, 1 /* unnumbered */,
2700  ({
2701  addr = ip_interface_address_get_address (&lcm->im6->lookup_main,
2702  ia);
2703  ip_address_set (new_ip, addr, AF_IP6);
2704  }));
2705  /* *INDENT-ON* */
2706 
2707  if (probed_loc && ip_address_cmp (probed_loc, new_ip) == 0)
2708  new.probed = 1;
2709  }
2710  vec_add1 (m->locators, new);
2711  }
2712 }
2713 
2714 static mapping_t *
2716 {
2717  mapping_t *recs = 0, rec, *m;
2718 
2719  /* *INDENT-OFF* */
2720  pool_foreach(m, lcm->mapping_pool,
2721  {
2722  /* for now build only local mappings */
2723  if (!m->local)
2724  continue;
2725 
2726  rec = m[0];
2727  add_locators (lcm, &rec, m->locator_set_index, NULL);
2728  vec_add1 (recs, rec);
2729  });
2730  /* *INDENT-ON* */
2731 
2732  return recs;
2733 }
2734 
2735 static vnet_crypto_alg_t
2737 {
2738  switch (key_id)
2739  {
2740  case HMAC_SHA_1_96:
2741  return VNET_CRYPTO_ALG_HMAC_SHA1;
2742  case HMAC_SHA_256_128:
2743  return VNET_CRYPTO_ALG_HMAC_SHA256;
2744  default:
2745  clib_warning ("unsupported encryption key type: %d!", key_id);
2746  break;
2747  }
2748  return VNET_CRYPTO_ALG_NONE;
2749 }
2750 
2751 static vnet_crypto_op_id_t
2753 {
2754  switch (key_id)
2755  {
2756  case HMAC_SHA_1_96:
2757  return VNET_CRYPTO_OP_SHA1_HMAC;
2758  case HMAC_SHA_256_128:
2759  return VNET_CRYPTO_OP_SHA256_HMAC;
2760  default:
2761  clib_warning ("unsupported encryption key type: %d!", key_id);
2762  break;
2763  }
2764  return VNET_CRYPTO_OP_NONE;
2765 }
2766 
2767 static int
2769  lisp_key_type_t key_id, u8 * key,
2770  u16 auth_data_len, u32 msg_len)
2771 {
2773  MREG_KEY_ID (map_reg_hdr) = clib_host_to_net_u16 (key_id);
2774  MREG_AUTH_DATA_LEN (map_reg_hdr) = clib_host_to_net_u16 (auth_data_len);
2775  vnet_crypto_op_t _op, *op = &_op;
2777 
2779  op->len = msg_len;
2780  op->digest = MREG_DATA (map_reg_hdr);
2781  op->src = (u8 *) map_reg_hdr;
2782  op->digest_len = 0;
2783  op->iv = 0;
2784 
2785  ki = vnet_crypto_key_add (lcm->vlib_main,
2786  lisp_key_type_to_crypto_alg (key_id), key,
2787  vec_len (key));
2788 
2789  op->key_index = ki;
2790 
2791  vnet_crypto_process_ops (lcm->vlib_main, op, 1);
2792  vnet_crypto_key_del (lcm->vlib_main, ki);
2793 
2794  return 0;
2795 }
2796 
2797 static vlib_buffer_t *
2799  ip_address_t * ms_ip, u64 * nonce_res, u8 want_map_notif,
2800  mapping_t * records, lisp_key_type_t key_id, u8 * key,
2801  u32 * bi_res)
2802 {
2803  void *map_reg_hdr;
2804  vlib_buffer_t *b;
2805  u32 bi, auth_data_len = 0, msg_len = 0;
2806  vlib_main_t *vm = lcm->vlib_main;
2807 
2808  if (vlib_buffer_alloc (vm, &bi, 1) != 1)
2809  {
2810  clib_warning ("Can't allocate buffer for Map-Register!");
2811  return 0;
2812  }
2813 
2814  b = vlib_get_buffer (vm, bi);
2815 
2816  /* leave some space for the encap headers */
2818 
2819  auth_data_len = auth_data_len_by_key_id (key_id);
2820  map_reg_hdr = lisp_msg_put_map_register (b, records, want_map_notif,
2821  auth_data_len, nonce_res,
2822  &msg_len);
2823 
2824  update_map_register_auth_data (map_reg_hdr, key_id, key, auth_data_len,
2825  msg_len);
2826 
2827  /* push outer ip header */
2829  ms_ip, 1);
2830 
2831  bi_res[0] = bi;
2832  return b;
2833 }
2834 
2835 #define _(name) \
2836 static int \
2837 get_egress_map_ ##name## _ip (lisp_cp_main_t * lcm, ip_address_t * ip) \
2838 { \
2839  lisp_msmr_t *mr; \
2840  while (lcm->do_map_ ## name ## _election \
2841  | (0 == ip_fib_get_first_egress_ip_for_dst \
2842  (lcm, &lcm->active_map_ ##name, ip))) \
2843  { \
2844  if (0 == elect_map_ ## name (lcm)) \
2845  /* all map resolvers/servers are down */ \
2846  { \
2847  /* restart MR/MS checking by marking all of them up */ \
2848  vec_foreach (mr, lcm->map_ ## name ## s) mr->is_down = 0; \
2849  return -1; \
2850  } \
2851  } \
2852  return 0; \
2853 }
2854 
2856 #undef _
2857 /* CP output statistics */
2858 #define foreach_lisp_cp_output_error \
2859 _(MAP_REGISTERS_SENT, "map-registers sent") \
2860 _(MAP_REQUESTS_SENT, "map-requests sent") \
2861 _(RLOC_PROBES_SENT, "rloc-probes sent")
2863 #define _(sym,string) string,
2865 #undef _
2866 };
2867 
2868 typedef enum
2869 {
2870 #define _(sym,str) LISP_CP_OUTPUT_ERROR_##sym,
2872 #undef _
2875 
2876 static uword
2878  vlib_frame_t * from_frame)
2879 {
2880  return 0;
2881 }
2882 
2883 /* dummy node used only for statistics */
2884 /* *INDENT-OFF* */
2886  .function = lisp_cp_output,
2887  .name = "lisp-cp-output",
2888  .vector_size = sizeof (u32),
2889  .format_trace = format_lisp_cp_input_trace,
2891 
2892  .n_errors = LISP_CP_OUTPUT_N_ERROR,
2893  .error_strings = lisp_cp_output_error_strings,
2894 
2895  .n_next_nodes = LISP_CP_INPUT_N_NEXT,
2896 
2897  .next_nodes = {
2898  [LISP_CP_INPUT_NEXT_DROP] = "error-drop",
2899  },
2900 };
2901 /* *INDENT-ON* */
2902 
2903 static int
2905  u32 local_locator_set_index, ip_address_t * sloc,
2906  ip_address_t * rloc)
2907 {
2908  locator_set_t *ls;
2909  u32 bi;
2910  vlib_buffer_t *b;
2911  vlib_frame_t *f;
2912  u64 nonce = 0;
2913  u32 next_index, *to_next;
2914  gid_address_t *itr_rlocs;
2915 
2916  ls = pool_elt_at_index (lcm->locator_set_pool, local_locator_set_index);
2917  itr_rlocs = build_itr_rloc_list (lcm, ls);
2918 
2919  b = build_map_request (lcm, deid, sloc, rloc, itr_rlocs, &nonce, &bi);
2920  vec_free (itr_rlocs);
2921  if (!b)
2922  return -1;
2923 
2924  vnet_buffer (b)->sw_if_index[VLIB_TX] = 0;
2925 
2926  next_index = (ip_addr_version (rloc) == AF_IP4) ?
2927  ip4_lookup_node.index : ip6_lookup_node.index;
2928 
2929  f = vlib_get_frame_to_node (lcm->vlib_main, next_index);
2930 
2931  /* Enqueue the packet */
2932  to_next = vlib_frame_vector_args (f);
2933  to_next[0] = bi;
2934  f->n_vectors = 1;
2935  vlib_put_frame_to_node (lcm->vlib_main, next_index, f);
2936 
2937  return 0;
2938 }
2939 
2940 static int
2942 {
2943  u8 lprio = 0;
2944  mapping_t *lm;
2945  fwd_entry_t *e;
2946  locator_pair_t *lp;
2947  u32 si, rloc_probes_sent = 0;
2948 
2949  /* *INDENT-OFF* */
2950  pool_foreach (e, lcm->fwd_entry_pool,
2951  {
2952  if (vec_len (e->locator_pairs) == 0)
2953  continue;
2954 
2955  si = gid_dictionary_lookup (&lcm->mapping_index_by_gid, &e->leid);
2956  if (~0 == si)
2957  {
2958  clib_warning ("internal error: cannot find local eid %U in "
2959  "map-cache!", format_gid_address, &e->leid);
2960  continue;
2961  }
2962  lm = pool_elt_at_index (lcm->mapping_pool, si);
2963 
2964  /* get the best (lowest) priority */
2965  lprio = e->locator_pairs[0].priority;
2966 
2967  /* send rloc-probe for pair(s) with the best remote locator priority */
2968  vec_foreach (lp, e->locator_pairs)
2969  {
2970  if (lp->priority != lprio)
2971  break;
2972 
2973  /* get first remote locator */
2974  send_rloc_probe (lcm, &e->reid, lm->locator_set_index, &lp->lcl_loc,
2975  &lp->rmt_loc);
2976  rloc_probes_sent++;
2977  }
2978  });
2979  /* *INDENT-ON* */
2980 
2982  LISP_CP_OUTPUT_ERROR_RLOC_PROBES_SENT,
2983  rloc_probes_sent);
2984  return 0;
2985 }
2986 
2987 static int
2988 send_map_register (lisp_cp_main_t * lcm, u8 want_map_notif)
2989 {
2991  u32 bi, map_registers_sent = 0;
2992  vlib_buffer_t *b;
2993  ip_address_t sloc;
2994  vlib_frame_t *f;
2995  u64 nonce = 0;
2996  u32 next_index, *to_next;
2997  mapping_t *records, *r, *group, *k;
2998 
2999  if (get_egress_map_server_ip (lcm, &sloc) < 0)
3000  return -1;
3001 
3002  records = build_map_register_record_list (lcm);
3003  if (!records)
3004  return -1;
3005 
3006  vec_foreach (r, records)
3007  {
3008  u8 *key = r->key;
3009  u8 key_id = r->key_id;
3010 
3011  if (!key)
3012  continue; /* no secret key -> map-register cannot be sent */
3013 
3014  group = 0;
3015  vec_add1 (group, r[0]);
3016 
3017  /* group mappings that share common key */
3018  for (k = r + 1; k < vec_end (records); k++)
3019  {
3020  if (k->key_id != r->key_id)
3021  continue;
3022 
3023  if (vec_is_equal (k->key, r->key))
3024  {
3025  vec_add1 (group, k[0]);
3026  k->key = 0; /* don't process this mapping again */
3027  }
3028  }
3029 
3030  b = build_map_register (lcm, &sloc, &lcm->active_map_server, &nonce,
3031  want_map_notif, group, key_id, key, &bi);
3032  vec_free (group);
3033  if (!b)
3034  continue;
3035 
3036  vnet_buffer (b)->sw_if_index[VLIB_TX] = 0;
3037 
3038  next_index = (ip_addr_version (&lcm->active_map_server) == AF_IP4) ?
3039  ip4_lookup_node.index : ip6_lookup_node.index;
3040 
3041  f = vlib_get_frame_to_node (lcm->vlib_main, next_index);
3042 
3043  /* Enqueue the packet */
3044  to_next = vlib_frame_vector_args (f);
3045  to_next[0] = bi;
3046  f->n_vectors = 1;
3047  vlib_put_frame_to_node (lcm->vlib_main, next_index, f);
3048  map_registers_sent++;
3049 
3051  clib_memset (pmr, 0, sizeof (*pmr));
3054  pmr - lcm->pending_map_registers_pool);
3055  }
3056  free_map_register_records (records);
3057 
3059  LISP_CP_OUTPUT_ERROR_MAP_REGISTERS_SENT,
3060  map_registers_sent);
3061 
3062  return 0;
3063 }
3064 
3065 #define send_encapsulated_map_request(lcm, seid, deid, smr) \
3066  _send_encapsulated_map_request(lcm, seid, deid, smr, 0)
3067 
3068 #define resend_encapsulated_map_request(lcm, seid, deid, smr) \
3069  _send_encapsulated_map_request(lcm, seid, deid, smr, 1)
3070 
3071 static int
3072 _send_encapsulated_map_request (lisp_cp_main_t * lcm,
3073  gid_address_t * seid, gid_address_t * deid,
3074  u8 is_smr_invoked, u8 is_resend)
3075 {
3076  u32 next_index, bi = 0, *to_next, map_index;
3077  vlib_buffer_t *b;
3078  vlib_frame_t *f;
3079  u64 nonce = 0;
3080  locator_set_t *loc_set;
3081  mapping_t *map;
3082  pending_map_request_t *pmr, *duplicate_pmr = 0;
3083  ip_address_t sloc;
3084  u32 ls_index;
3085 
3086  /* if there is already a pending request remember it */
3087 
3088  /* *INDENT-OFF* */
3090  ({
3091  if (!gid_address_cmp (&pmr->src, seid)
3092  && !gid_address_cmp (&pmr->dst, deid))
3093  {
3094  duplicate_pmr = pmr;
3095  break;
3096  }
3097  }));
3098  /* *INDENT-ON* */
3099 
3100  if (!is_resend && duplicate_pmr)
3101  {
3102  /* don't send the request if there is a pending map request already */
3103  return 0;
3104  }
3105 
3106  u8 pitr_mode = lcm->flags & LISP_FLAG_PITR_MODE;
3107 
3108  /* get locator-set for seid */
3109  if (!pitr_mode && gid_address_type (deid) != GID_ADDR_NSH)
3110  {
3111  map_index = gid_dictionary_lookup (&lcm->mapping_index_by_gid, seid);
3112  if (map_index == ~0)
3113  {
3114  clib_warning ("No local mapping found in eid-table for %U!",
3115  format_gid_address, seid);
3116  return -1;
3117  }
3118 
3119  map = pool_elt_at_index (lcm->mapping_pool, map_index);
3120 
3121  if (!map->local)
3122  {
3123  clib_warning
3124  ("Mapping found for src eid %U is not marked as local!",
3125  format_gid_address, seid);
3126  return -1;
3127  }
3128  ls_index = map->locator_set_index;
3129  }
3130  else
3131  {
3132  if (pitr_mode)
3133  {
3134  if (lcm->pitr_map_index != ~0)
3135  {
3136  map =
3137  pool_elt_at_index (lcm->mapping_pool, lcm->pitr_map_index);
3138  ls_index = map->locator_set_index;
3139  }
3140  else
3141  {
3142  return -1;
3143  }
3144  }
3145  else
3146  {
3147  if (lcm->nsh_map_index == (u32) ~ 0)
3148  {
3149  clib_warning ("No locator-set defined for NSH!");
3150  return -1;
3151  }
3152  else
3153  {
3154  map = pool_elt_at_index (lcm->mapping_pool, lcm->nsh_map_index);
3155  ls_index = map->locator_set_index;
3156  }
3157  }
3158  }
3159 
3160  /* overwrite locator set if map-request itr-rlocs configured */
3161  if (~0 != lcm->mreq_itr_rlocs)
3162  {
3163  ls_index = lcm->mreq_itr_rlocs;
3164  }
3165 
3166  loc_set = pool_elt_at_index (lcm->locator_set_pool, ls_index);
3167 
3168  if (get_egress_map_resolver_ip (lcm, &sloc) < 0)
3169  {
3170  if (duplicate_pmr)
3171  duplicate_pmr->to_be_removed = 1;
3172  return -1;
3173  }
3174 
3175  /* build the encapsulated map request */
3176  b = build_encapsulated_map_request (lcm, seid, deid, loc_set,
3177  &lcm->active_map_resolver,
3178  &sloc, is_smr_invoked, &nonce, &bi);
3179 
3180  if (!b)
3181  return -1;
3182 
3183  /* set fib index to default and lookup node */
3184  vnet_buffer (b)->sw_if_index[VLIB_TX] = 0;
3185  next_index = (ip_addr_version (&lcm->active_map_resolver) == AF_IP4) ?
3186  ip4_lookup_node.index : ip6_lookup_node.index;
3187 
3188  f = vlib_get_frame_to_node (lcm->vlib_main, next_index);
3189 
3190  /* Enqueue the packet */
3191  to_next = vlib_frame_vector_args (f);
3192  to_next[0] = bi;
3193  f->n_vectors = 1;
3194  vlib_put_frame_to_node (lcm->vlib_main, next_index, f);
3195 
3197  LISP_CP_OUTPUT_ERROR_MAP_REQUESTS_SENT, 1);
3198 
3199  if (duplicate_pmr)
3200  /* if there is a pending request already update it */
3201  {
3202  if (clib_fifo_elts (duplicate_pmr->nonces) >= PENDING_MREQ_QUEUE_LEN)
3203  {
3204  /* remove the oldest nonce */
3205  u64 CLIB_UNUSED (tmp), *nonce_del;
3206  nonce_del = clib_fifo_head (duplicate_pmr->nonces);
3207  hash_unset (lcm->pending_map_requests_by_nonce, nonce_del[0]);
3208  clib_fifo_sub1 (duplicate_pmr->nonces, tmp);
3209  }
3210 
3211  clib_fifo_add1 (duplicate_pmr->nonces, nonce);
3212  hash_set (lcm->pending_map_requests_by_nonce, nonce,
3213  duplicate_pmr - lcm->pending_map_requests_pool);
3214  }
3215  else
3216  {
3217  /* add map-request to pending requests table */
3218  pool_get (lcm->pending_map_requests_pool, pmr);
3219  clib_memset (pmr, 0, sizeof (*pmr));
3220  gid_address_copy (&pmr->src, seid);
3221  gid_address_copy (&pmr->dst, deid);
3222  clib_fifo_add1 (pmr->nonces, nonce);
3223  pmr->is_smr_invoked = is_smr_invoked;
3225  hash_set (lcm->pending_map_requests_by_nonce, nonce,
3226  pmr - lcm->pending_map_requests_pool);
3227  }
3228 
3229  return 0;
3230 }
3231 
3232 static void
3234 {
3235  ip4_header_t *ip4 = hdr;
3236  ip6_header_t *ip6;
3237 
3238  if ((ip4->ip_version_and_header_length & 0xF0) == 0x40)
3239  {
3240  ip_address_set (src, &ip4->src_address, AF_IP4);
3241  ip_address_set (dst, &ip4->dst_address, AF_IP4);
3242  }
3243  else
3244  {
3245  ip6 = hdr;
3246  ip_address_set (src, &ip6->src_address, AF_IP6);
3247  ip_address_set (dst, &ip6->dst_address, AF_IP6);
3248  }
3249 }
3250 
3251 static u32
3253  u8 version)
3254 {
3255  uword *vnip;
3256  u32 vni = ~0, table_id = ~0;
3257 
3259  AF_IP4 ?
3262  vnet_buffer
3263  (b)->sw_if_index
3264  [VLIB_RX]);
3265 
3266  vnip = hash_get (lcm->vni_by_table_id, table_id);
3267  if (vnip)
3268  vni = vnip[0];
3269  else
3270  clib_warning ("vrf %d is not mapped to any vni!", table_id);
3271 
3272  return vni;
3273 }
3274 
3277 {
3278  u32 sw_if_index0;
3279 
3280  l2input_main_t *l2im = &l2input_main;
3281  l2_input_config_t *config;
3282  l2_bridge_domain_t *bd_config;
3283 
3284  sw_if_index0 = vnet_buffer (b)->sw_if_index[VLIB_RX];
3285  config = vec_elt_at_index (l2im->configs, sw_if_index0);
3286  bd_config = vec_elt_at_index (l2im->bd_configs, config->bd_index);
3287 
3288  return bd_config->bd_id;
3289 }
3290 
3293 {
3294  uword *vnip;
3295  u32 vni = ~0;
3297 
3298  vnip = hash_get (lcm->vni_by_bd_id, bd);
3299  if (vnip)
3300  vni = vnip[0];
3301  else
3302  clib_warning ("bridge domain %d is not mapped to any vni!", bd);
3303 
3304  return vni;
3305 }
3306 
3307 void
3310  u16 type)
3311 {
3312  ethernet_header_t *eh;
3313  u32 vni = 0;
3314  icmp6_neighbor_discovery_ethernet_link_layer_address_option_t *opt;
3315 
3316  clib_memset (src, 0, sizeof (*src));
3317  clib_memset (dst, 0, sizeof (*dst));
3318 
3321 
3322  if (LISP_AFI_IP == type || LISP_AFI_IP6 == type)
3323  {
3324  ip4_header_t *ip;
3325  u8 version, preflen;
3326 
3329 
3330  ip = vlib_buffer_get_current (b);
3331  get_src_and_dst_ip (ip, &gid_address_ip (src), &gid_address_ip (dst));
3332 
3333  version = gid_address_ip_version (src);
3334  preflen = ip_address_max_len (version);
3335  gid_address_ippref_len (src) = preflen;
3336  gid_address_ippref_len (dst) = preflen;
3337 
3338  vni = lisp_get_vni_from_buffer_ip (lcm, b, version);
3339  gid_address_vni (dst) = vni;
3340  gid_address_vni (src) = vni;
3341  }
3342  else if (LISP_AFI_MAC == type)
3343  {
3345 
3346  eh = vlib_buffer_get_current (b);
3347 
3348  if (clib_net_to_host_u16 (eh->type) == ETHERNET_TYPE_ARP)
3349  {
3350  ah = (ethernet_arp_header_t *) (((u8 *) eh) + sizeof (*eh));
3352 
3353  if (clib_net_to_host_u16 (ah->opcode)
3354  != ETHERNET_ARP_OPCODE_request)
3355  {
3357  sizeof (ip_address_t));
3359  gid_address_arp_ndp_bd (dst) = ~0;
3360  return;
3361  }
3362 
3365  &ah->ip4_over_ethernet[1].ip4, 4);
3366  }
3367  else
3368  {
3369  if (clib_net_to_host_u16 (eh->type) == ETHERNET_TYPE_IP6)
3370  {
3371  ip6_header_t *ip;
3372  ip = (ip6_header_t *) (eh + 1);
3373 
3374  if (IP_PROTOCOL_ICMP6 == ip->protocol)
3375  {
3376  icmp6_neighbor_solicitation_or_advertisement_header_t *ndh;
3377  ndh = ip6_next_header (ip);
3378  if (ndh->icmp.type == ICMP6_neighbor_solicitation)
3379  {
3381 
3382  /* check that source link layer address option is present */
3383  opt = (void *) (ndh + 1);
3384  if ((opt->header.type !=
3385  ICMP6_NEIGHBOR_DISCOVERY_OPTION_source_link_layer_address)
3386  || (opt->header.n_data_u64s != 1))
3387  {
3389  sizeof (ip_address_t));
3391  AF_IP6;
3392  gid_address_arp_ndp_bd (dst) = ~0;
3394  return;
3395  }
3396 
3397  gid_address_ndp_bd (dst) =
3400  &ndh->target_address, AF_IP6);
3401  return;
3402  }
3403  }
3404  }
3405 
3408  mac_copy (&gid_address_mac (src), eh->src_address);
3409  mac_copy (&gid_address_mac (dst), eh->dst_address);
3410 
3411  /* get vni */
3412  vni = lisp_get_vni_from_buffer_eth (lcm, b);
3413 
3414  gid_address_vni (dst) = vni;
3415  gid_address_vni (src) = vni;
3416  }
3417  }
3418  else if (LISP_AFI_LCAF == type)
3419  {
3420  lisp_nsh_hdr_t *nh;
3421  eh = vlib_buffer_get_current (b);
3422 
3423  if (clib_net_to_host_u16 (eh->type) == ETHERNET_TYPE_NSH)
3424  {
3425  nh = (lisp_nsh_hdr_t *) (((u8 *) eh) + sizeof (*eh));
3426  u32 spi = clib_net_to_host_u32 (nh->spi_si << 8);
3427  u8 si = (u8) clib_net_to_host_u32 (nh->spi_si);
3428  gid_address_nsh_spi (dst) = spi;
3429  gid_address_nsh_si (dst) = si;
3430 
3433  }
3434  }
3435 }
3436 
3437 static uword
3440  vlib_frame_t * from_frame, int overlay)
3441 {
3442  icmp6_neighbor_discovery_ethernet_link_layer_address_option_t *opt;
3443  u32 *from, *to_next, di, si;
3445  u32 next_index;
3446  uword n_left_from, n_left_to_next;
3447  vnet_main_t *vnm = vnet_get_main ();
3448 
3449  from = vlib_frame_vector_args (from_frame);
3450  n_left_from = from_frame->n_vectors;
3451  next_index = node->cached_next_index;
3452 
3453  while (n_left_from > 0)
3454  {
3455  vlib_get_next_frame (vm, node, next_index, to_next, n_left_to_next);
3456 
3457  while (n_left_from > 0 && n_left_to_next > 0)
3458  {
3459  u32 pi0, sw_if_index0, next0;
3460  u64 mac0;
3461  vlib_buffer_t *b0;
3463  ethernet_arp_header_t *arp0;
3464  ethernet_header_t *eth0;
3465  vnet_hw_interface_t *hw_if0;
3466  ethernet_header_t *eh0;
3467  icmp6_neighbor_solicitation_or_advertisement_header_t *ndh;
3468  ip6_header_t *ip0;
3469 
3470  pi0 = from[0];
3471  from += 1;
3472  n_left_from -= 1;
3473  to_next[0] = pi0;
3474  to_next += 1;
3475  n_left_to_next -= 1;
3476 
3477  b0 = vlib_get_buffer (vm, pi0);
3478 
3479  /* src/dst eid pair */
3480  get_src_and_dst_eids_from_buffer (lcm, b0, &src, &dst, overlay);
3481 
3482  if (gid_address_type (&dst) == GID_ADDR_ARP)
3483  {
3484  mac0 = gid_dictionary_lookup (&lcm->mapping_index_by_gid, &dst);
3485  if (GID_LOOKUP_MISS_L2 == mac0)
3486  goto drop;
3487 
3488  /* send ARP reply */
3489  sw_if_index0 = vnet_buffer (b0)->sw_if_index[VLIB_RX];
3490  vnet_buffer (b0)->sw_if_index[VLIB_TX] = sw_if_index0;
3491 
3492  hw_if0 = vnet_get_sup_hw_interface (vnm, sw_if_index0);
3493 
3494  eth0 = vlib_buffer_get_current (b0);
3495  arp0 = (ethernet_arp_header_t *) (((u8 *) eth0)
3496  + sizeof (*eth0));
3497  arp0->opcode = clib_host_to_net_u16 (ETHERNET_ARP_OPCODE_reply);
3498  arp0->ip4_over_ethernet[1] = arp0->ip4_over_ethernet[0];
3499  mac_address_from_u64 (&arp0->ip4_over_ethernet[0].mac, mac0);
3500  clib_memcpy (&arp0->ip4_over_ethernet[0].ip4,
3501  &gid_address_arp_ip4 (&dst), 4);
3502 
3503  /* Hardware must be ethernet-like. */
3504  ASSERT (vec_len (hw_if0->hw_address) == 6);
3505 
3506  clib_memcpy (eth0->dst_address, eth0->src_address, 6);
3507  clib_memcpy (eth0->src_address, hw_if0->hw_address, 6);
3508 
3509  b0->error = node->errors[LISP_CP_LOOKUP_ERROR_ARP_REPLY_TX];
3511  goto enqueue;
3512  }
3513  else if (gid_address_type (&dst) == GID_ADDR_NDP)
3514  {
3515  mac0 = gid_dictionary_lookup (&lcm->mapping_index_by_gid, &dst);
3516  if (GID_LOOKUP_MISS_L2 == mac0)
3517  goto drop;
3518 
3519  sw_if_index0 = vnet_buffer (b0)->sw_if_index[VLIB_RX];
3520  vnet_buffer (b0)->sw_if_index[VLIB_TX] = sw_if_index0;
3521 
3522  eh0 = vlib_buffer_get_current (b0);
3523  ip0 = (ip6_header_t *) (eh0 + 1);
3524  ndh = ip6_next_header (ip0);
3525  int bogus_length;
3526  ip0->dst_address = ip0->src_address;
3527  ip0->src_address = ndh->target_address;
3528  ip0->hop_limit = 255;
3529  opt = (void *) (ndh + 1);
3530  opt->header.type =
3531  ICMP6_NEIGHBOR_DISCOVERY_OPTION_target_link_layer_address;
3532  clib_memcpy (opt->ethernet_address, (u8 *) & mac0, 6);
3533  ndh->icmp.type = ICMP6_neighbor_advertisement;
3534  ndh->advertisement_flags = clib_host_to_net_u32
3537  ndh->icmp.checksum = 0;
3538  ndh->icmp.checksum =
3539  ip6_tcp_udp_icmp_compute_checksum (vm, b0, ip0,
3540  &bogus_length);
3541  clib_memcpy (eh0->dst_address, eh0->src_address, 6);
3542  clib_memcpy (eh0->src_address, (u8 *) & mac0, 6);
3543  b0->error =
3544  node->errors
3545  [LISP_CP_LOOKUP_ERROR_NDP_NEIGHBOR_ADVERTISEMENT_TX];
3547  goto enqueue;
3548  }
3549 
3550  /* if we have remote mapping for destination already in map-cache
3551  add forwarding tunnel directly. If not send a map-request */
3553  &src);
3554  if (~0 != di)
3555  {
3556  mapping_t *m = vec_elt_at_index (lcm->mapping_pool, di);
3557  /* send a map-request also in case of negative mapping entry
3558  with corresponding action */
3559  if (m->action == LISP_SEND_MAP_REQUEST)
3560  {
3561  /* send map-request */
3562  queue_map_request (&src, &dst, 0 /* smr_invoked */ ,
3563  0 /* is_resend */ );
3564  }
3565  else
3566  {
3567  if (GID_ADDR_NSH != gid_address_type (&dst))
3568  {
3570  &src);
3571  }
3572  else
3573  si = lcm->nsh_map_index;
3574 
3575  if (~0 != si)
3576  {
3577  dp_add_fwd_entry_from_mt (si, di);
3578  }
3579  }
3580  }
3581  else
3582  {
3583  /* send map-request */
3584  queue_map_request (&src, &dst, 0 /* smr_invoked */ ,
3585  0 /* is_resend */ );
3586  }
3587 
3588  drop:
3589  b0->error = node->errors[LISP_CP_LOOKUP_ERROR_DROP];
3590  next0 = LISP_CP_LOOKUP_NEXT_DROP;
3591  enqueue:
3592  if (PREDICT_FALSE (b0->flags & VLIB_BUFFER_IS_TRACED))
3593  {
3594  lisp_cp_lookup_trace_t *tr = vlib_add_trace (vm, node, b0,
3595  sizeof (*tr));
3596 
3597  clib_memset (tr, 0, sizeof (*tr));
3598  gid_address_copy (&tr->dst_eid, &dst);
3600  &lcm->active_map_resolver);
3601  }
3602  gid_address_free (&dst);
3603  gid_address_free (&src);
3604  vlib_validate_buffer_enqueue_x1 (vm, node, next_index,
3605  to_next,
3606  n_left_to_next, pi0, next0);
3607  }
3608 
3609  vlib_put_next_frame (vm, node, next_index, n_left_to_next);
3610  }
3611  return from_frame->n_vectors;
3612 }
3613 
3614 static uword
3616  vlib_node_runtime_t * node, vlib_frame_t * from_frame)
3617 {
3618  return (lisp_cp_lookup_inline (vm, node, from_frame, LISP_AFI_IP));
3619 }
3620 
3621 static uword
3623  vlib_node_runtime_t * node, vlib_frame_t * from_frame)
3624 {
3625  return (lisp_cp_lookup_inline (vm, node, from_frame, LISP_AFI_IP6));
3626 }
3627 
3628 static uword
3630  vlib_node_runtime_t * node, vlib_frame_t * from_frame)
3631 {
3632  return (lisp_cp_lookup_inline (vm, node, from_frame, LISP_AFI_MAC));
3633 }
3634 
3635 static uword
3637  vlib_node_runtime_t * node, vlib_frame_t * from_frame)
3638 {
3639  /* TODO decide if NSH should be propagated as LCAF or not */
3640  return (lisp_cp_lookup_inline (vm, node, from_frame, LISP_AFI_LCAF));
3641 }
3642 
3643 /* *INDENT-OFF* */
3645  .function = lisp_cp_lookup_ip4,
3646  .name = "lisp-cp-lookup-ip4",
3647  .vector_size = sizeof (u32),
3648  .format_trace = format_lisp_cp_lookup_trace,
3650 
3651  .n_errors = LISP_CP_LOOKUP_N_ERROR,
3652  .error_strings = lisp_cp_lookup_error_strings,
3653 
3654  .n_next_nodes = LISP_CP_LOOKUP_N_NEXT,
3655 
3656  .next_nodes = {
3657  [LISP_CP_LOOKUP_NEXT_DROP] = "error-drop",
3658  [LISP_CP_LOOKUP_NEXT_ARP_NDP_REPLY_TX] = "interface-output",
3659  },
3660 };
3661 /* *INDENT-ON* */
3662 
3663 /* *INDENT-OFF* */
3665  .function = lisp_cp_lookup_ip6,
3666  .name = "lisp-cp-lookup-ip6",
3667  .vector_size = sizeof (u32),
3668  .format_trace = format_lisp_cp_lookup_trace,
3670 
3671  .n_errors = LISP_CP_LOOKUP_N_ERROR,
3672  .error_strings = lisp_cp_lookup_error_strings,
3673 
3674  .n_next_nodes = LISP_CP_LOOKUP_N_NEXT,
3675 
3676  .next_nodes = {
3677  [LISP_CP_LOOKUP_NEXT_DROP] = "error-drop",
3678  [LISP_CP_LOOKUP_NEXT_ARP_NDP_REPLY_TX] = "interface-output",
3679  },
3680 };
3681 /* *INDENT-ON* */
3682 
3683 /* *INDENT-OFF* */
3685  .function = lisp_cp_lookup_l2,
3686  .name = "lisp-cp-lookup-l2",
3687  .vector_size = sizeof (u32),
3688  .format_trace = format_lisp_cp_lookup_trace,
3690 
3691  .n_errors = LISP_CP_LOOKUP_N_ERROR,
3692  .error_strings = lisp_cp_lookup_error_strings,
3693 
3694  .n_next_nodes = LISP_CP_LOOKUP_N_NEXT,
3695 
3696  .next_nodes = {
3697  [LISP_CP_LOOKUP_NEXT_DROP] = "error-drop",
3698  [LISP_CP_LOOKUP_NEXT_ARP_NDP_REPLY_TX] = "interface-output",
3699  },
3700 };
3701 /* *INDENT-ON* */
3702 
3703 /* *INDENT-OFF* */
3705  .function = lisp_cp_lookup_nsh,
3706  .name = "lisp-cp-lookup-nsh",
3707  .vector_size = sizeof (u32),
3708  .format_trace = format_lisp_cp_lookup_trace,
3710 
3711  .n_errors = LISP_CP_LOOKUP_N_ERROR,
3712  .error_strings = lisp_cp_lookup_error_strings,
3713 
3714  .n_next_nodes = LISP_CP_LOOKUP_N_NEXT,
3715 
3716  .next_nodes = {
3717  [LISP_CP_LOOKUP_NEXT_DROP] = "error-drop",
3718  [LISP_CP_LOOKUP_NEXT_ARP_NDP_REPLY_TX] = "interface-output",
3719  },
3720 };
3721 /* *INDENT-ON* */
3722 
3723 /* lisp_cp_input statistics */
3724 #define foreach_lisp_cp_input_error \
3725 _(DROP, "drop") \
3726 _(RLOC_PROBE_REQ_RECEIVED, "rloc-probe requests received") \
3727 _(RLOC_PROBE_REP_RECEIVED, "rloc-probe replies received") \
3728 _(MAP_NOTIFIES_RECEIVED, "map-notifies received") \
3729 _(MAP_REPLIES_RECEIVED, "map-replies received")
3730 
3732 #define _(sym,string) string,
3734 #undef _
3735 };
3736 
3737 typedef enum
3738 {
3739 #define _(sym,str) LISP_CP_INPUT_ERROR_##sym,
3741 #undef _
3744 
3745 typedef struct
3746 {
3750 
3751 u8 *
3752 format_lisp_cp_input_trace (u8 * s, va_list * args)
3753 {
3754  CLIB_UNUSED (vlib_main_t * vm) = va_arg (*args, vlib_main_t *);
3755  CLIB_UNUSED (vlib_node_t * node) = va_arg (*args, vlib_node_t *);
3757  va_arg (*args, lisp_cp_input_trace_t *);
3758 
3759  s = format (s, "LISP-CP-INPUT: TODO");
3760  return s;
3761 }
3762 
3763 static void
3765 {
3766  mapping_t *m;
3767  vnet_lisp_add_del_adjacency_args_t _adj_args, *adj_args = &_adj_args;
3768  clib_memset (adj_args, 0, sizeof (adj_args[0]));
3769 
3770  m = pool_elt_at_index (lcm->mapping_pool, mi);
3771 
3772  gid_address_copy (&adj_args->reid, &m->eid);
3773  adj_args->is_add = 0;
3774  if (vnet_lisp_add_del_adjacency (adj_args))
3775  clib_warning ("failed to del adjacency!");
3776 
3778  mapping_delete_timer (lcm, mi);
3779 }
3780 
3781 static void
3783  f64 expiration_time)
3784 {
3785  mapping_t *m;
3786  u64 now = clib_cpu_time_now ();
3787  u64 cpu_cps = lcm->vlib_main->clib_time.clocks_per_second;
3788  u64 exp_clock_time = now + expiration_time * cpu_cps;
3789 
3790  m = pool_elt_at_index (lcm->mapping_pool, mi);
3791 
3792  m->timer_set = 1;
3793  timing_wheel_insert (&lcm->wheel, exp_clock_time, mi);
3794 }
3795 
3796 static void
3798 {
3799  int rv;
3801  mapping_t *m = pool_elt_at_index (lcm->mapping_pool, mi);
3802  uword *fei;
3803  fwd_entry_t *fe;
3804  vlib_counter_t c;
3805  u8 have_stats = 0;
3806 
3807  if (m->delete_after_expiration)
3808  {
3809  remove_expired_mapping (lcm, mi);
3810  return;
3811  }
3812 
3813  fei = hash_get (lcm->fwd_entry_by_mapping_index, mi);
3814  if (!fei)
3815  return;
3816 
3817  fe = pool_elt_at_index (lcm->fwd_entry_pool, fei[0]);
3818 
3819  clib_memset (a, 0, sizeof (*a));
3820  a->rmt_eid = fe->reid;
3821  if (fe->is_src_dst)
3822  a->lcl_eid = fe->leid;
3823  a->vni = gid_address_vni (&fe->reid);
3824 
3825  rv = vnet_lisp_gpe_get_fwd_stats (a, &c);
3826  if (0 == rv)
3827  have_stats = 1;
3828 
3829  if (m->almost_expired)
3830  {
3831  m->almost_expired = 0; /* reset flag */
3832  if (have_stats)
3833  {
3834  if (m->packets != c.packets)
3835  {
3836  /* mapping is in use, re-fetch */
3837  map_request_args_t mr_args;
3838  clib_memset (&mr_args, 0, sizeof (mr_args));
3839  mr_args.seid = fe->leid;
3840  mr_args.deid = fe->reid;
3841 
3842  send_map_request_thread_fn (&mr_args);
3843  }
3844  else
3845  remove_expired_mapping (lcm, mi);
3846  }
3847  else
3848  remove_expired_mapping (lcm, mi);
3849  }
3850  else
3851  {
3852  m->almost_expired = 1;
3854 
3855  if (have_stats)
3856  /* save counter */
3857  m->packets = c.packets;
3858  else
3859  m->delete_after_expiration = 1;
3860  }
3861 }
3862 
3863 static void
3865 {
3867  mapping_t *m;
3868  vec_foreach (m, a->mappings)
3869  {
3870  vec_free (m->locators);
3871  gid_address_free (&m->eid);
3872  }
3874 }
3875 
3876 void *
3878 {
3879  mapping_t *m;
3881  u32 dst_map_index = 0;
3882  pending_map_request_t *pmr;
3883  u64 *noncep;
3884  uword *pmr_index;
3885  u8 is_changed = 0;
3886 
3887  if (a->is_rloc_probe)
3888  goto done;
3889 
3890  /* Check pending requests table and nonce */
3891  pmr_index = hash_get (lcm->pending_map_requests_by_nonce, a->nonce);
3892  if (!pmr_index)
3893  {
3894  clib_warning ("No pending map-request entry with nonce %lu!", a->nonce);
3895  goto done;
3896  }
3897  pmr = pool_elt_at_index (lcm->pending_map_requests_pool, pmr_index[0]);
3898 
3899  vec_foreach (m, a->mappings)
3900  {
3901  vnet_lisp_add_del_mapping_args_t _m_args, *m_args = &_m_args;
3902  clib_memset (m_args, 0, sizeof (m_args[0]));
3903  gid_address_copy (&m_args->eid, &m->eid);
3904  m_args->action = m->action;
3905  m_args->authoritative = m->authoritative;
3906  m_args->ttl = m->ttl;
3907  m_args->is_static = 0;
3908 
3909  /* insert/update mappings cache */
3910  vnet_lisp_add_mapping (m_args, m->locators, &dst_map_index, &is_changed);
3911 
3912  if (dst_map_index == (u32) ~ 0)
3913  continue;
3914 
3915  if (is_changed)
3916  {
3917  /* try to program forwarding only if mapping saved or updated */
3918  vnet_lisp_add_del_adjacency_args_t _adj_args, *adj_args = &_adj_args;
3919  clib_memset (adj_args, 0, sizeof (adj_args[0]));
3920 
3921  gid_address_copy (&adj_args->leid, &pmr->src);
3922  gid_address_copy (&adj_args->reid, &m->eid);
3923  adj_args->is_add = 1;
3924 
3925  if (vnet_lisp_add_del_adjacency (adj_args))
3926  clib_warning ("failed to add adjacency!");
3927  }
3928 
3929  if ((u32) ~ 0 != m->ttl)
3930  mapping_start_expiration_timer (lcm, dst_map_index,
3931  (m->ttl == 0) ? 0 : MAPPING_TIMEOUT);
3932  }
3933 
3934  /* remove pending map request entry */
3935 
3936  /* *INDENT-OFF* */
3937  clib_fifo_foreach (noncep, pmr->nonces, ({
3938  hash_unset(lcm->pending_map_requests_by_nonce, noncep[0]);
3939  }));
3940  /* *INDENT-ON* */
3941 
3942  clib_fifo_free (pmr->nonces);
3943  pool_put (lcm->pending_map_requests_pool, pmr);
3944 
3945 done:
3946  a->is_free = 1;
3947  return 0;
3948 }
3949 
3950 static int
3952  lisp_key_type_t key_id, u8 * key)
3953 {
3955  u8 *auth_data = 0;
3956  u16 auth_data_len;
3957  int result;
3958  vnet_crypto_op_t _op, *op = &_op;
3960  u8 out[EVP_MAX_MD_SIZE] = { 0, };
3961 
3962  auth_data_len = auth_data_len_by_key_id (key_id);
3963  if ((u16) ~ 0 == auth_data_len)
3964  {
3965  clib_warning ("invalid length for key_id %d!", key_id);
3966  return 0;
3967  }
3968 
3969  /* save auth data */
3970  vec_validate (auth_data, auth_data_len - 1);
3971  clib_memcpy (auth_data, MNOTIFY_DATA (h), auth_data_len);
3972 
3973  /* clear auth data */
3974  clib_memset (MNOTIFY_DATA (h), 0, auth_data_len);
3975 
3977  op->len = msg_len;
3978  op->digest = out;
3979  op->src = (u8 *) h;
3980  op->digest_len = 0;
3981  op->iv = 0;
3982 
3983  ki = vnet_crypto_key_add (lcm->vlib_main,
3984  lisp_key_type_to_crypto_alg (key_id), key,
3985  vec_len (key));
3986 
3987  op->key_index = ki;
3988 
3989  vnet_crypto_process_ops (lcm->vlib_main, op, 1);
3990  vnet_crypto_key_del (lcm->vlib_main, ki);
3991 
3992  result = memcmp (out, auth_data, auth_data_len);
3993 
3994  vec_free (auth_data);
3995 
3996  return !result;
3997 }
3998 
3999 static void
4001 {
4003  uword *pmr_index;
4004 
4005  pmr_index = hash_get (lcm->map_register_messages_by_nonce, a->nonce);
4006  if (!pmr_index)
4007  {
4008  clib_warning ("No pending map-register entry with nonce %lu!",
4009  a->nonce);
4010  return;
4011  }
4012 
4013  a->is_free = 1;
4014  pool_put_index (lcm->pending_map_registers_pool, pmr_index[0]);
4016 
4017  /* reset map-notify counter */
4018  lcm->expired_map_registers = 0;
4019 }
4020 
4021 static mapping_t *
4023 {
4024  u32 mi;
4025 
4027  if (~0 == mi)
4028  {
4029  clib_warning ("eid %U not found in map-cache!", unformat_gid_address,
4030  e);
4031  return 0;
4032  }
4033  return pool_elt_at_index (lcm->mapping_pool, mi);
4034 }
4035 
4036 /**
4037  * When map-notify is received it is necessary that all EIDs in the record
4038  * list share common key. The key is then used to verify authentication
4039  * data in map-notify message.
4040  */
4041 static int
4043  u32 key_id, u8 ** key_out)
4044 {
4045  u32 i, len = vec_len (maps);
4046  mapping_t *m;
4047 
4048  /* get key of the first mapping */
4049  m = get_mapping (lcm, &maps[0].eid);
4050  if (!m || !m->key)
4051  return -1;
4052 
4053  key_out[0] = m->key;
4054 
4055  for (i = 1; i < len; i++)
4056  {
4057  m = get_mapping (lcm, &maps[i].eid);
4058  if (!m || !m->key)
4059  return -1;
4060 
4061  if (key_id != m->key_id || vec_cmp (m->key, key_out[0]))
4062  {
4063  clib_warning ("keys does not match! %v, %v", key_out[0], m->key);
4064  return -1;
4065  }
4066  }
4067  return 0;
4068 }
4069 
4070 static int
4072 {
4073  locator_t *locators = 0;
4074  u32 i, len;
4075  gid_address_t deid;
4076  mapping_t m;
4077  locator_t *loc;
4078 
4079  clib_memset (&m, 0, sizeof (m));
4080 
4081  /* parse record eid */
4082  for (i = 0; i < count; i++)
4083  {
4084  locators = 0;
4085  len = lisp_msg_parse_mapping_record (b, &deid, &locators, NULL);
4086  if (len == ~0)
4087  {
4088  clib_warning ("Failed to parse mapping record!");
4089  vec_foreach (loc, locators) locator_free (loc);
4090  vec_free (locators);
4091  return -1;
4092  }
4093 
4094  m.locators = locators;
4095  gid_address_copy (&m.eid, &deid);
4096  vec_add1 (a->mappings, m);
4097  }
4098 
4099  return 0;
4100 }
4101 
4102 static map_records_arg_t *
4104 {
4106  map_records_arg_t *rec;
4107 
4108  /* Cleanup first */
4109  /* *INDENT-OFF* */
4111  if (rec->is_free)
4112  map_records_arg_free (rec);
4113  }));
4114  /* *INDENT-ON* */
4115 
4117  return rec;
4118 }
4119 
4120 static map_records_arg_t *
4122 {
4123  int rc = 0;
4124  map_notify_hdr_t *mnotif_hdr;
4125  lisp_key_type_t key_id;
4127  u8 *key = 0;
4128  gid_address_t deid;
4129  u16 auth_data_len = 0;
4130  u8 record_count;
4132 
4133  a = map_record_args_get ();
4134  clib_memset (a, 0, sizeof (*a));
4135  mnotif_hdr = vlib_buffer_get_current (b);
4136  vlib_buffer_pull (b, sizeof (*mnotif_hdr));
4137  clib_memset (&deid, 0, sizeof (deid));
4138 
4139  a->nonce = MNOTIFY_NONCE (mnotif_hdr);
4140  key_id = clib_net_to_host_u16 (MNOTIFY_KEY_ID (mnotif_hdr));
4141  auth_data_len = auth_data_len_by_key_id (key_id);
4142 
4143  /* advance buffer by authentication data */
4144  vlib_buffer_pull (b, auth_data_len);
4145 
4146  record_count = MNOTIFY_REC_COUNT (mnotif_hdr);
4147  rc = parse_map_records (b, a, record_count);
4148  if (rc != 0)
4149  {
4151  return 0;
4152  }
4153 
4154  rc = map_record_integrity_check (lcm, a->mappings, key_id, &key);
4155  if (rc != 0)
4156  {
4158  return 0;
4159  }
4160 
4161  /* verify authentication data */
4162  if (!is_auth_data_valid (mnotif_hdr, vlib_buffer_get_tail (b)
4163  - (u8 *) mnotif_hdr, key_id, key))
4164  {
4165  clib_warning ("Map-notify auth data verification failed for nonce "
4166  "0x%lx!", a->nonce);
4168  return 0;
4169  }
4170  return a;
4171 }
4172 
4173 static vlib_buffer_t *
4175  ip_address_t * dst, u64 nonce, u8 probe_bit,
4176  mapping_t * records, u16 dst_port, u32 * bi_res)
4177 {
4178  vlib_buffer_t *b;
4179  u32 bi;
4180  vlib_main_t *vm = lcm->vlib_main;
4181 
4182  if (vlib_buffer_alloc (vm, &bi, 1) != 1)
4183  {
4184  clib_warning ("Can't allocate buffer for Map-Register!");
4185  return 0;
4186  }
4187 
4188  b = vlib_get_buffer (vm, bi);
4189 
4190  /* leave some space for the encap headers */
4192 
4193  lisp_msg_put_map_reply (b, records, nonce, probe_bit);
4194 
4195  /* push outer ip header */
4196  pkt_push_udp_and_ip (vm, b, LISP_CONTROL_PORT, dst_port, sloc, dst, 1);
4197 
4198  bi_res[0] = bi;
4199  return b;
4200 }
4201 
4202 static int
4204  u8 probe_bit, u64 nonce, u16 dst_port,
4205  ip_address_t * probed_loc)
4206 {
4207  ip_address_t src;
4208  u32 bi;
4209  vlib_buffer_t *b;
4210  vlib_frame_t *f;
4211  u32 next_index, *to_next;
4212  mapping_t *records = 0, *m;
4213 
4214  m = pool_elt_at_index (lcm->mapping_pool, mi);
4215  if (!m)
4216  return -1;
4217 
4218  vec_add1 (records, m[0]);
4219  add_locators (lcm, &records[0], m->locator_set_index, probed_loc);
4220  clib_memset (&src, 0, sizeof (src));
4221 
4222  if (!ip_fib_get_first_egress_ip_for_dst (lcm, dst, &src))
4223  {
4224  clib_warning ("can't find interface address for %U", format_ip_address,
4225  dst);
4226  return -1;
4227  }
4228 
4229  b = build_map_reply (lcm, &src, dst, nonce, probe_bit, records, dst_port,
4230  &bi);
4231  if (!b)
4232  return -1;
4233  free_map_register_records (records);
4234 
4235  vnet_buffer (b)->sw_if_index[VLIB_TX] = 0;
4236  next_index = (ip_addr_version (&lcm->active_map_resolver) == AF_IP4) ?
4237  ip4_lookup_node.index : ip6_lookup_node.index;
4238 
4239  f = vlib_get_frame_to_node (lcm->vlib_main, next_index);
4240 
4241  /* Enqueue the packet */
4242  to_next = vlib_frame_vector_args (f);
4243  to_next[0] = bi;
4244  f->n_vectors = 1;
4245  vlib_put_frame_to_node (lcm->vlib_main, next_index, f);
4246  return 0;
4247 }
4248 
4249 static void
4251 {
4252  const i32 start = vnet_buffer (b)->l3_hdr_offset;
4253  if (start < 0 && start < -sizeof (b->pre_data))
4254  {
4255  *ip_hdr = 0;
4256  return;
4257  }
4258 
4259  *ip_hdr = b->data + start;
4260  if ((u8 *) * ip_hdr > (u8 *) vlib_buffer_get_current (b))
4261  *ip_hdr = 0;
4262 }
4263 
4264 void
4266  lisp_cp_main_t * lcm, vlib_buffer_t * b)
4267 {
4268  u8 *ip_hdr = 0;
4269  ip_address_t *dst_loc = 0, probed_loc, src_loc;
4270  mapping_t m;
4271  map_request_hdr_t *mreq_hdr;
4273  u64 nonce;
4274  u32 i, len = 0, rloc_probe_recv = 0;
4275  gid_address_t *itr_rlocs = 0;
4276 
4277  mreq_hdr = vlib_buffer_get_current (b);
4278  if (!MREQ_SMR (mreq_hdr) && !MREQ_RLOC_PROBE (mreq_hdr))
4279  {
4280  clib_warning
4281  ("Only SMR Map-Requests and RLOC probe supported for now!");
4282  return;
4283  }
4284 
4285  vlib_buffer_pull (b, sizeof (*mreq_hdr));
4286  nonce = MREQ_NONCE (mreq_hdr);
4287 
4288  /* parse src eid */
4289  len = lisp_msg_parse_addr (b, &src);
4290  if (len == ~0)
4291  return;
4292 
4293  len = lisp_msg_parse_itr_rlocs (b, &itr_rlocs,
4294  MREQ_ITR_RLOC_COUNT (mreq_hdr) + 1);
4295  if (len == ~0)
4296  goto done;
4297 
4298  /* parse eid records and send SMR-invoked map-requests */
4299  for (i = 0; i < MREQ_REC_COUNT (mreq_hdr); i++)
4300  {
4301  clib_memset (&dst, 0, sizeof (dst));
4302  len = lisp_msg_parse_eid_rec (b, &dst);
4303  if (len == ~0)
4304  {
4305  clib_warning ("Can't parse map-request EID-record");
4306  goto done;
4307  }
4308 
4309  if (MREQ_SMR (mreq_hdr))
4310  {
4311  /* send SMR-invoked map-requests */
4312  queue_map_request (&dst, &src, 1 /* invoked */ , 0 /* resend */ );
4313  }
4314  else if (MREQ_RLOC_PROBE (mreq_hdr))
4315  {
4316  find_ip_header (b, &ip_hdr);
4317  if (!ip_hdr)
4318  {
4319  clib_warning ("Cannot find the IP header!");
4320  goto done;
4321  }
4322  rloc_probe_recv++;
4323  clib_memset (&m, 0, sizeof (m));
4324  u32 mi = gid_dictionary_lookup (&lcm->mapping_index_by_gid, &dst);
4325 
4326  // TODO: select best locator; for now use the first one
4327  dst_loc = &gid_address_ip (&itr_rlocs[0]);
4328 
4329  /* get src/dst IP addresses */
4330  get_src_and_dst_ip (ip_hdr, &src_loc, &probed_loc);
4331 
4332  // TODO get source port from buffer
4334 
4335  send_map_reply (lcm, mi, dst_loc, 1 /* probe-bit */ , nonce,
4336  src_port, &probed_loc);
4337  }
4338  }
4339 
4340 done:
4342  LISP_CP_INPUT_ERROR_RLOC_PROBE_REQ_RECEIVED,
4343  rloc_probe_recv);
4344  vec_free (itr_rlocs);
4345 }
4346 
4349 {
4350  locator_t probed;
4351  gid_address_t deid;
4352  void *h;
4353  u32 i, len = 0;
4354  mapping_t m;
4355  map_reply_hdr_t *mrep_hdr;
4357 
4358  a = map_record_args_get ();
4359  clib_memset (a, 0, sizeof (*a));
4360 
4361  locator_t *locators;
4362 
4363  mrep_hdr = vlib_buffer_get_current (b);
4364  a->nonce = MREP_NONCE (mrep_hdr);
4365  a->is_rloc_probe = MREP_RLOC_PROBE (mrep_hdr);
4366  if (!vlib_buffer_has_space (b, sizeof (*mrep_hdr)))
4367  {
4369  return 0;
4370  }
4371  vlib_buffer_pull (b, sizeof (*mrep_hdr));
4372 
4373  for (i = 0; i < MREP_REC_COUNT (mrep_hdr); i++)
4374  {
4375  clib_memset (&m, 0, sizeof (m));
4376  locators = 0;
4377  h = vlib_buffer_get_current (b);
4378 
4379  m.ttl = clib_net_to_host_u32 (MAP_REC_TTL (h));
4380  m.action = MAP_REC_ACTION (h);
4381  m.authoritative = MAP_REC_AUTH (h);
4382 
4383  len = lisp_msg_parse_mapping_record (b, &deid, &locators, &probed);
4384  if (len == ~0)
4385  {
4386  clib_warning ("Failed to parse mapping record!");
4388  return 0;
4389  }
4390 
4391  m.locators = locators;
4392  gid_address_copy (&m.eid, &deid);
4393  vec_add1 (a->mappings, m);
4394  }
4395  return a;
4396 }
4397 
4398 static void
4400 {
4401  vl_api_rpc_call_main_thread (process_map_reply, (u8 *) a, sizeof (*a));
4402 }
4403 
4404 static void
4406 {
4407  vl_api_rpc_call_main_thread (process_map_notify, (u8 *) a, sizeof (a[0]));
4408 }
4409 
4410 static uword
4412  vlib_frame_t * from_frame)
4413 {
4414  u32 n_left_from, *from, *to_next_drop, rloc_probe_rep_recv = 0,
4415  map_notifies_recv = 0;
4419 
4420  from = vlib_frame_vector_args (from_frame);
4421  n_left_from = from_frame->n_vectors;
4422 
4423 
4424  while (n_left_from > 0)
4425  {
4426  u32 n_left_to_next_drop;
4427 
4429  to_next_drop, n_left_to_next_drop);
4430  while (n_left_from > 0 && n_left_to_next_drop > 0)
4431  {
4432  u32 bi0;
4433  vlib_buffer_t *b0;
4434 
4435  bi0 = from[0];
4436  from += 1;
4437  n_left_from -= 1;
4438  to_next_drop[0] = bi0;
4439  to_next_drop += 1;
4440  n_left_to_next_drop -= 1;
4441 
4442  b0 = vlib_get_buffer (vm, bi0);
4443 
4444  type = lisp_msg_type (vlib_buffer_get_current (b0));
4445  switch (type)
4446  {
4447  case LISP_MAP_REPLY:
4448  a = parse_map_reply (b0);
4449  if (a)
4450  {
4451  if (a->is_rloc_probe)
4452  rloc_probe_rep_recv++;
4454  }
4455  break;
4456  case LISP_MAP_REQUEST:
4457  process_map_request (vm, node, lcm, b0);
4458  break;
4459  case LISP_MAP_NOTIFY:
4460  a = parse_map_notify (b0);
4461  if (a)
4462  {
4463  map_notifies_recv++;
4465  }
4466  break;
4467  default:
4468  clib_warning ("Unsupported LISP message type %d", type);
4469  break;
4470  }
4471 
4472  b0->error = node->errors[LISP_CP_INPUT_ERROR_DROP];
4473 
4474  if (PREDICT_FALSE (b0->flags & VLIB_BUFFER_IS_TRACED))
4475  {
4476 
4477  }
4478  }
4479 
4481  n_left_to_next_drop);
4482  }
4484  LISP_CP_INPUT_ERROR_RLOC_PROBE_REP_RECEIVED,
4485  rloc_probe_rep_recv);
4487  LISP_CP_INPUT_ERROR_MAP_NOTIFIES_RECEIVED,
4488  map_notifies_recv);
4489  return from_frame->n_vectors;
4490 }
4491 
4492 /* *INDENT-OFF* */
4494  .function = lisp_cp_input,
4495  .name = "lisp-cp-input",
4496  .vector_size = sizeof (u32),
4497  .format_trace = format_lisp_cp_input_trace,
4499 
4500  .n_errors = LISP_CP_INPUT_N_ERROR,
4501  .error_strings = lisp_cp_input_error_strings,
4502 
4503  .n_next_nodes = LISP_CP_INPUT_N_NEXT,
4504 
4505  .next_nodes = {
4506  [LISP_CP_INPUT_NEXT_DROP] = "error-drop",
4507  },
4508 };
4509 /* *INDENT-ON* */
4510 
4511 clib_error_t *
4513 {
4515  clib_error_t *error = 0;
4517  u32 num_threads;
4518 
4519  if ((error = vlib_call_init_function (vm, lisp_gpe_init)))
4520  return error;
4521 
4522  lcm->im4 = &ip4_main;
4523  lcm->im6 = &ip6_main;
4524  lcm->vlib_main = vm;
4525  lcm->vnet_main = vnet_get_main ();
4526  lcm->mreq_itr_rlocs = ~0;
4527  lcm->flags = 0;
4528  lcm->pitr_map_index = ~0;
4529  lcm->petr_map_index = ~0;
4530  clib_memset (&lcm->active_map_resolver, 0,
4531  sizeof (lcm->active_map_resolver));
4532  clib_memset (&lcm->active_map_server, 0, sizeof (lcm->active_map_server));
4533 
4535  lcm->do_map_resolver_election = 1;
4536  lcm->do_map_server_election = 1;
4538 
4539  num_threads = 1 /* main thread */ + vtm->n_threads;
4540  vec_validate (lcm->map_records_args_pool, num_threads - 1);
4541 
4542  /* default vrf mapped to vni 0 */
4543  hash_set (lcm->table_id_by_vni, 0, 0);
4544  hash_set (lcm->vni_by_table_id, 0, 0);
4545 
4546  u64 now = clib_cpu_time_now ();
4548  lcm->nsh_map_index = ~0;
4551  lcm->expired_map_registers = 0;
4553  lcm->flags |= LISP_FLAG_XTR_MODE;
4554  return 0;
4555 }
4556 
4557 static int
4560  u32 stats_index)
4561 {
4562  vlib_counter_t v;
4564  lisp_gpe_fwd_entry_key_t fwd_key;
4565  const lisp_gpe_tunnel_t *lgt;
4566  fwd_entry_t *fe;
4567 
4568  clib_memset (stat, 0, sizeof (*stat));
4569  clib_memset (&fwd_key, 0, sizeof (fwd_key));
4570 
4572  ASSERT (fe != 0);
4573 
4574  gid_to_dp_address (&fe->reid, &stat->deid);
4575  gid_to_dp_address (&fe->leid, &stat->seid);
4576  stat->vni = gid_address_vni (&fe->reid);
4577 
4578  lgt = lisp_gpe_tunnel_get (key->tunnel_index);
4579  stat->loc_rloc = lgt->key->lcl;
4580  stat->rmt_rloc = lgt->key->rmt;
4581 
4582  vlib_get_combined_counter (cm, stats_index, &v);
4583  stat->counters = v;
4584  return 1;
4585 }
4586 
4589 {
4592  lisp_api_stats_t *stats = 0, stat;
4594  u32 index;
4595 
4596  /* *INDENT-OFF* */
4597  hash_foreach_mem (key, index, lgm->lisp_stats_index_by_key,
4598  {
4599  if (lisp_stats_api_fill (lcm, lgm, &stat, key, index))
4600  vec_add1 (stats, stat);
4601  });
4602  /* *INDENT-ON* */
4603 
4604  return stats;
4605 }
4606 
4607 static void *
4609 {
4610  map_request_args_t *a = arg;
4612 
4613  if (a->is_resend)
4615  else
4616  send_encapsulated_map_request (lcm, &a->seid, &a->deid, a->smr_invoked);
4617 
4618  return 0;
4619 }
4620 
4621 static int
4623  u8 smr_invoked, u8 is_resend)
4624 {
4626 
4627  a.is_resend = is_resend;
4628  gid_address_copy (&a.seid, seid);
4629  gid_address_copy (&a.deid, deid);
4630  a.smr_invoked = smr_invoked;
4631 
4633  (u8 *) & a, sizeof (a));
4634  return 0;
4635 }
4636 
4637 /**
4638  * Take an action with a pending map request depending on expiration time
4639  * and re-try counters.
4640  */
4641 static void
4643 {
4645  lisp_msmr_t *mr;
4646 
4647  if (r->time_to_expire - dt < 0)
4648  /* it's time to decide what to do with this pending request */
4649  {
4650  if (r->retries_num >= NUMBER_OF_RETRIES)
4651  /* too many retries -> assume current map resolver is not available */
4652  {
4654  if (!mr)
4655  {
4656  clib_warning ("Map resolver %U not found - probably deleted "
4657  "by the user recently.", format_ip_address,
4658  &lcm->active_map_resolver);
4659  }
4660  else
4661  {
4662  clib_warning ("map resolver %U is unreachable, ignoring",
4664 
4665  /* mark current map resolver unavailable so it won't be
4666  * selected next time */
4667  mr->is_down = 1;
4668  mr->last_update = vlib_time_now (lcm->vlib_main);
4669  }
4670 
4672  elect_map_resolver (lcm);
4673 
4674  /* try to find a next eligible map resolver and re-send */
4675  queue_map_request (&r->src, &r->dst, r->is_smr_invoked,
4676  1 /* resend */ );
4677  }
4678  else
4679  {
4680  /* try again */
4681  queue_map_request (&r->src, &r->dst, r->is_smr_invoked,
4682  1 /* resend */ );
4683  r->retries_num++;
4685  }
4686  }
4687  else
4688  r->time_to_expire -= dt;
4689 }
4690 
4691 static void
4693 {
4694  u64 *nonce;
4695  pending_map_request_t *pmr;
4696  u32 *to_be_removed = 0, *pmr_index;
4697 
4698  /* *INDENT-OFF* */
4700  ({
4701  if (pmr->to_be_removed)
4702  {
4703  clib_fifo_foreach (nonce, pmr->nonces, ({
4704  hash_unset (lcm->pending_map_requests_by_nonce, nonce[0]);
4705  }));
4706 
4707  vec_add1 (to_be_removed, pmr - lcm->pending_map_requests_pool);
4708  }
4709  }));
4710  /* *INDENT-ON* */
4711 
4712  vec_foreach (pmr_index, to_be_removed)
4713  pool_put_index (lcm->pending_map_requests_pool, pmr_index[0]);
4714 
4715  vec_free (to_be_removed);
4716 }
4717 
4718 static void
4720 {
4721  static f64 time_left = RLOC_PROBING_INTERVAL;
4722 
4723  if (!lcm->is_enabled || !lcm->rloc_probing)
4724  return;
4725 
4726  time_left -= dt;
4727  if (time_left <= 0)
4728  {
4729  time_left = RLOC_PROBING_INTERVAL;
4730  send_rloc_probes (lcm);
4731  }
4732 }
4733 
4734 static int
4736 {
4738  lisp_msmr_t *ms;
4739  del_all[0] = 0;
4740 
4741  r->time_to_expire -= dt;
4742 
4743  if (r->time_to_expire < 0)
4744  {
4745  lcm->expired_map_registers++;
4746 
4748  {
4749  ms = get_map_server (&lcm->active_map_server);
4750  if (!ms)
4751  {
4752  clib_warning ("Map server %U not found - probably deleted "
4753  "by the user recently.", format_ip_address,
4754  &lcm->active_map_server);
4755  }
4756  else
4757  {
4758  clib_warning ("map server %U is unreachable, ignoring",
4760 
4761  /* mark current map server unavailable so it won't be
4762  * elected next time */
4763  ms->is_down = 1;
4764  ms->last_update = vlib_time_now (lcm->vlib_main);
4765  }
4766 
4767  elect_map_server (lcm);
4768 
4769  /* indication for deleting all pending map registers */
4770  del_all[0] = 1;
4771  lcm->expired_map_registers = 0;
4772  return 0;
4773  }
4774  else
4775  {
4776  /* delete pending map register */
4777  return 0;
4778  }
4779  }
4780  return 1;
4781 }
4782 
4783 static void
4785 {
4786  u32 *to_be_removed = 0, *pmr_index;
4787  static f64 time_left = QUICK_MAP_REGISTER_INTERVAL;
4788  static u64 mreg_sent_counter = 0;
4789 
4791  u8 del_all = 0;
4792 
4793  if (!lcm->is_enabled || !lcm->map_registering)
4794  return;
4795 
4796  /* *INDENT-OFF* */
4798  ({
4799  if (!update_pending_map_register (pmr, dt, &del_all))
4800  {
4801  if (del_all)
4802  break;
4803  vec_add1 (to_be_removed, pmr - lcm->pending_map_registers_pool);
4804  }
4805  }));
4806  /* *INDENT-ON* */
4807 
4808  if (del_all)
4809  {
4810  /* delete all pending map register messages so they won't
4811  * trigger another map server election.. */
4812  pool_free (lcm->pending_map_registers_pool);
4813  hash_free (lcm->map_register_messages_by_nonce);
4814 
4815  /* ..and trigger registration against next map server (if any) */
4816  time_left = 0;
4817  }
4818  else
4819  {
4820  vec_foreach (pmr_index, to_be_removed)
4821  pool_put_index (lcm->pending_map_registers_pool, pmr_index[0]);
4822  }
4823 
4824  vec_free (to_be_removed);
4825 
4826  time_left -= dt;
4827  if (time_left <= 0)
4828  {
4829  if (mreg_sent_counter >= QUICK_MAP_REGISTER_MSG_COUNT)
4830  time_left = MAP_REGISTER_INTERVAL;
4831  else
4832  {
4833  mreg_sent_counter++;
4834  time_left = QUICK_MAP_REGISTER_INTERVAL;
4835  }
4836  send_map_register (lcm, 1 /* want map notify */ );
4837  }
4838 }
4839 
4840 static uword
4843 {
4844  u32 *expired = 0;
4845  f64 period = 2.0;
4846  pending_map_request_t *pmr;
4848 
4849  while (1)
4850  {
4852 
4853  /* currently no signals are expected - just wait for clock */
4854  (void) vlib_process_get_events (vm, 0);
4855 
4856  /* *INDENT-OFF* */
4858  ({
4859  if (!pmr->to_be_removed)
4860  update_pending_request (pmr, period);
4861  }));
4862  /* *INDENT-ON* */
4863 
4865 
4866  update_map_register (lcm, period);
4867  update_rloc_probing (lcm, period);
4868 
4869  u64 now = clib_cpu_time_now ();
4870 
4871  expired = timing_wheel_advance (&lcm->wheel, now, expired, 0);
4872  if (vec_len (expired) > 0)
4873  {
4874  u32 *mi = 0;
4875  vec_foreach (mi, expired)
4876  {
4877  process_expired_mapping (lcm, mi[0]);
4878  }
4879  _vec_len (expired) = 0;
4880  }
4881  }
4882 
4883  /* unreachable */
4884  return 0;
4885 }
4886 
4889 {
4891 
4892  if (vnet_lisp_enable_disable_status () == 0)
4893  return VNET_API_ERROR_LISP_DISABLED;
4894 
4895  if (enable)
4896  lcm->flags |= LISP_FLAG_STATS_ENABLED;
4897  else
4898  lcm->flags &= ~LISP_FLAG_STATS_ENABLED;
4899 
4900  return 0;
4901 }
4902 
4903 u8
4905 {
4907 
4908  if (vnet_lisp_enable_disable_status () == 0)
4909  return VNET_API_ERROR_LISP_DISABLED;
4910 
4911  return lcm->flags & LISP_FLAG_STATS_ENABLED;
4912 }
4913 
4914 void
4916 {
4917  if (lcm->retry_service_index)
4918  return;
4919 
4921  "lisp-retry-service",
4923  16 /* stack_bytes */ );
4924 }
4925 
4926 u32
4928 {
4930 
4931  if (protocol < LISP_TRANSPORT_PROTOCOL_UDP ||
4932  protocol > LISP_TRANSPORT_PROTOCOL_API)
4933  return VNET_API_ERROR_INVALID_ARGUMENT;
4934 
4936  return 0;
4937 }
4938 
4941 {
4943  return lcm->transport_protocol;
4944 }
4945 
4946 int
4948 {
4950  u8 pitr_mode = lcm->flags & LISP_FLAG_PITR_MODE;
4951  u8 xtr_mode = lcm->flags & LISP_FLAG_XTR_MODE;
4952  u8 petr_mode = lcm->flags & LISP_FLAG_PETR_MODE;
4953 
4954  if (pitr_mode && is_enabled)
4955  return VNET_API_ERROR_INVALID_ARGUMENT;
4956 
4957  if (is_enabled && xtr_mode)
4958  return 0;
4959  if (!is_enabled && !xtr_mode)
4960  return 0;
4961 
4962  if (is_enabled)
4963  {
4964  if (!petr_mode)
4965  {
4967  }
4968  lisp_cp_enable_l2_l3_ifaces (lcm, 1 /* with_default_route */ );
4969  lcm->flags |= LISP_FLAG_XTR_MODE;
4970  }
4971  else
4972  {
4973  if (!petr_mode)
4974  {
4976  }
4978  lcm->flags &= ~LISP_FLAG_XTR_MODE;
4979  }
4980  return 0;
4981 }
4982 
4983 int
4985 {
4987  u8 xtr_mode = lcm->flags & LISP_FLAG_XTR_MODE;
4988  u8 pitr_mode = lcm->flags & LISP_FLAG_PITR_MODE;
4989 
4990  if (xtr_mode && is_enabled)
4991  return VNET_API_ERROR_INVALID_VALUE;
4992 
4993  if (is_enabled && pitr_mode)
4994  return 0;
4995  if (!is_enabled && !pitr_mode)
4996  return 0;
4997 
4998  if (is_enabled)
4999  {
5000  /* create iface, no default route */
5001  lisp_cp_enable_l2_l3_ifaces (lcm, 0 /* with_default_route */ );
5002  lcm->flags |= LISP_FLAG_PITR_MODE;
5003  }
5004  else
5005  {
5007  lcm->flags &= ~LISP_FLAG_PITR_MODE;
5008  }
5009  return 0;
5010 }
5011 
5012 int
5014 {
5016  u8 xtr_mode = lcm->flags & LISP_FLAG_XTR_MODE;
5017  u8 petr_mode = lcm->flags & LISP_FLAG_PETR_MODE;
5018 
5019  if (is_enabled && petr_mode)
5020  return 0;
5021  if (!is_enabled && !petr_mode)
5022  return 0;
5023 
5024  if (is_enabled)
5025  {
5026  if (!xtr_mode)
5027  {
5029  }
5030  lcm->flags |= LISP_FLAG_PETR_MODE;
5031  }
5032  else
5033  {
5034  if (!xtr_mode)
5035  {
5037  }
5038  lcm->flags &= ~LISP_FLAG_PETR_MODE;
5039  }
5040  return 0;
5041 }
5042 
5043 u8
5045 {
5047  return (lcm->flags & LISP_FLAG_XTR_MODE);
5048 }
5049 
5050 u8
5052 {
5054  return (lcm->flags & LISP_FLAG_PITR_MODE);
5055 }
5056 
5057 u8
5059 {
5061  return (lcm->flags & LISP_FLAG_PETR_MODE);
5062 }
5063 
5065 
5066 /*
5067  * fd.io coding-style-patch-verification: ON
5068  *
5069  * Local Variables:
5070  * eval: (c-set-style "gnu")
5071  * End:
5072  */
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:440
#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
u8 count
Definition: dhcp.api:208
const lisp_gpe_tunnel_t * lisp_gpe_tunnel_get(index_t lgti)
u32 spi
#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:4411
#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
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:2988
vnet_api_error_t
Definition: api_errno.h:158
#define hash_set(h, key, value)
Definition: hash.h:255
l2_input_config_t * configs
Definition: l2_input.h:62
static u8 * vlib_buffer_get_tail(vlib_buffer_t *b)
Get pointer to the end of buffer&#39;s data.
Definition: buffer.h:310
#define clib_fifo_head(v)
Definition: fifo.h:254
u8 vnet_lisp_get_pitr_mode(void)
Definition: control.c:5051
#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:3644
map_records_arg_t * parse_map_reply(vlib_buffer_t *b)
Definition: control.c:4348
static void mapping_start_expiration_timer(lisp_cp_main_t *lcm, u32 mi, f64 expiration_time)
Definition: control.c:3782
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:491
#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:4265
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:978
#define SHA256_AUTH_DATA_LEN
Definition: lisp_types.h:23
lisp_cp_lookup_next_t
Definition: control.c:2436
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:3747
u32 vnet_lisp_set_transport_protocol(u8 protocol)
Definition: control.c:4927
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:2576
static void lisp_cp_register_dst_port(vlib_main_t *vm)
Definition: control.c:2192
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:4405
option version
Definition: sample.api:19
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:3724
static uword lisp_cp_lookup_nsh(vlib_main_t *vm, vlib_node_runtime_t *node, vlib_frame_t *from_frame)
Definition: control.c:3636
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:1832
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:53
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:2213
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:3704
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:523
static uword lisp_cp_output(vlib_main_t *vm, vlib_node_runtime_t *node, vlib_frame_t *from_frame)
Definition: control.c:2877
Definition: control.h:63
static u64 clib_cpu_time_now(void)
Definition: time.h:75
static int add_l2_arp_entry(BVT(clib_bihash_kv) *kvp, void *arg)
Definition: control.c:957
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:60
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:3731
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:4692
ip_address_t address
Definition: control.h:88
vnet_api_error_t vnet_lisp_stats_enable_disable(u8 enable)
Definition: control.c:4888
vl_api_prefix_t prefix
Definition: ip.api:144
int vnet_lisp_add_mapping(vnet_lisp_add_del_mapping_args_t *a, locator_t *rlocs, u32 *res_map_index, u8 *is_updated)
Adds/updates mapping.
Definition: control.c:1268
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:4735
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:4608
#define pool_get(P, E)
Allocate an object E from a pool P (unspecified alignment).
Definition: pool.h:237
vhost_vring_addr_t addr
Definition: vhost_user.h:147
ip6_address_t src_address
Definition: ip6_packet.h:307
u8 vnet_lisp_stats_enable_disable_state(void)
Definition: control.c:4904
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:4203
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:5058
int vnet_lisp_set_map_request_mode(u8 mode)
Definition: control.c:1548
static int is_local_ip(lisp_cp_main_t *lcm, ip_address_t *addr)
Definition: control.c:1245
static void clean_locator_to_locator_set(lisp_cp_main_t *lcm, u32 lsi)
Definition: control.c:1747
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:1477
double f64
Definition: types.h:142
static char * lisp_cp_output_error_strings[]
Definition: control.c:2862
#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:102
#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:2768
lisp_msmr_t * map_servers
Definition: control.h:223
lisp_transport_protocol_t vnet_lisp_get_transport_protocol(void)
Definition: control.c:4940
#define MREQ_NONCE(h_)
int vnet_lisp_enable_disable_petr_mode(u8 is_enabled)
Definition: control.c:5013
static lisp_gpe_main_t * vnet_lisp_gpe_get_main()
Definition: lisp_gpe.h:183
vl_api_ip_proto_t protocol
Definition: lb_types.api:71
static void reset_pending_mr_counters(pending_map_request_t *r)
Definition: control.c:2632
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)
int vnet_lisp_enable_disable_pitr_mode(u8 is_enabled)
Definition: control.c:4984
#define pool_foreach(VAR, POOL, BODY)
Iterate through pool.
Definition: pool.h:498
vl_api_interface_index_t sw_if_index
Definition: gre.api:59
ethernet_arp_ip4_over_ethernet_address_t ip4_over_ethernet[2]
Definition: arp_packet.h:142
#define VLIB_INIT_FUNCTION(x)
Definition: init.h:173
u32 fwd_entry_index
Definition: lisp_gpe.h:95
static uword vlib_process_get_events(vlib_main_t *vm, uword **data_vector)
Return the first event type which has occurred and a vector of per-event data of that type...
Definition: node_funcs.h:516
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:1152
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
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:607
static mapping_t * get_mapping(lisp_cp_main_t *lcm, gid_address_t *e)
Definition: control.c:4022
int vnet_lisp_eid_table_map(u32 vni, u32 dp_id, u8 is_l2, u8 is_add)
Definition: control.c:1068
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:1014
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:68
Definition: lisp_gpe.h:227
gid_address_t src
Definition: control.h:49
vl_api_gre_tunnel_mode_t mode
Definition: gre.api:55
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:4642
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:2249
vlib_error_t error
Error code for buffers to be enqueued to error handler.
Definition: buffer.h:136
u32 dp_table
Definition: lisp_gpe.api:123
#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:3664
static void add_locators(lisp_cp_main_t *lcm, mapping_t *m, u32 locator_set_index, ip_address_t *probed_loc)
Definition: control.c:2670
Definition: fib_entry.h:117
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:1239
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:1620
#define pool_elt_at_index(p, i)
Returns pointer to element at given index.
Definition: pool.h:519
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:4399
#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:2428
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
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:2463
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)
u32 vni
Definition: lisp_gpe.api:129
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:4493
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
void di(unformat_input_t *i)
Definition: unformat.c:163
vlib_node_registration_t lisp_cp_lookup_l2_node
(constructor) VLIB_REGISTER_NODE (lisp_cp_lookup_l2_node)
Definition: control.c:3684
#define pool_put(P, E)
Free an object E in pool P.
Definition: pool.h:287
#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:376
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:4588
static void remove_expired_mapping(lisp_cp_main_t *lcm, u32 mi)
Definition: control.c:3764
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:4042
uword unformat_gid_address(unformat_input_t *input, va_list *args)
Definition: lisp_types.c:272
gid_address_t reid
Definition: control.h:66
#define always_inline
Definition: ipsec.h:28
vnet_sw_interface_flags_t flags
Definition: interface.h:720
#define vec_del1(v, i)
Delete the element at index I.
Definition: vec.h:806
u8 * format_gid_address(u8 *s, va_list *args)
Definition: lisp_types.c:187
ip6_main_t ip6_main
Definition: ip6_forward.c:2703
static uword lisp_cp_lookup_ip4(vlib_main_t *vm, vlib_node_runtime_t *node, vlib_frame_t *from_frame)
Definition: control.c:3615
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:1126
#define foreach_lisp_cp_lookup_error
Definition: control.c:2415
u8 vnet_lisp_get_xtr_mode(void)
Definition: control.c:5044
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:2201
vlib_node_registration_t lisp_cp_output_node
(constructor) VLIB_REGISTER_NODE (lisp_cp_output_node)
Definition: control.c:2885
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:61
#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:2446
#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
vlib_main_t * vm
Definition: in2out_ed.c:1810
#define clib_fifo_foreach(v, f, body)
Definition: fifo.h:279
static void process_map_notify(map_records_arg_t *a)
Definition: control.c:4000
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:4622
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:1914
#define gid_address_ippref(_a)
Definition: lisp_types.h:204
u8 len
Definition: ip_types.api:91
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:1808
#define pool_free(p)
Free a pool.
Definition: pool.h:412
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:4512
u8 ip6[16]
Definition: one.api:477
u32 * vnet_lisp_ndp_bds_get(void)
Definition: control.c:940
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:3752
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:4174
#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:3629
u32 flags
Definition: vhost_user.h:141
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:2384
svmdb_client_t * c
u16 n_vectors
Definition: node.h:397
vlib_counter_t counters
Definition: lisp_gpe.h:107
static_always_inline uword vlib_get_thread_index(void)
Definition: threads.h:218
static lisp_msmr_t * get_map_resolver(ip_address_t *a)
Definition: control.c: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)
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:1895
#define vec_free(V)
Free vector&#39;s memory (no header).
Definition: vec.h:342
#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:4121
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:1159
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:4784
int vnet_lisp_map_register_enable_disable(u8 is_enable)
Definition: control.c:2183
u32 vnet_lisp_map_register_fallback_threshold_get(void)
Definition: control.c:1672
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:284
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:3748
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:2904
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:912
void * ip_interface_get_first_address(ip_lookup_main_t *lm, u32 sw_if_index, u8 version)
Definition: control.c:99
vlib_main_t vlib_node_runtime_t * node
Definition: in2out_ed.c:1810
enum fib_entry_flag_t_ fib_entry_flag_t
static void * ip6_next_header(ip6_header_t *i)
Definition: ip6_packet.h:368
#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:2314
#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:4947
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:1021
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:667
static uword send_map_resolver_service(vlib_main_t *vm, vlib_node_runtime_t *rt, vlib_frame_t *f)
Definition: control.c:4841
struct _gid_address_t gid_address_t
u32 fib_table_get_table_id_for_sw_if_index(fib_protocol_t proto, u32 sw_if_index)
Get the Table-ID of the FIB bound to the interface.
Definition: fib_table.c:1073
void vnet_lisp_create_retry_process(lisp_cp_main_t *lcm)
Definition: control.c:4915
u16 cached_next_index
Next frame index that vector arguments were last enqueued to last time this node ran.
Definition: node.h:515
u32 stats_index
Definition: ip.api:143
u8 value
Definition: qos.api:54
#define pool_put_index(p, i)
Free pool element with given index.
Definition: pool.h:316
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)
manual_print typedef address
Definition: ip_types.api:84
#define GID_LOOKUP_MISS
static int send_rloc_probes(lisp_cp_main_t *lcm)
Definition: control.c:2941
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:2638
int vnet_lisp_clear_all_remote_adjacencies(void)
Definition: control.c:1426
ip_lookup_main_t lookup_main
Definition: ip6.h:180
#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:3233
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:3252
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
u8 is_static
Definition: lisp_types.h:308
u8 is_src_dst
Definition: lisp_gpe.h:232
static void gid_address_sd_to_flat(gid_address_t *dst, gid_address_t *src, fid_address_t *fid)
Definition: control.c:384
#define gid_address_ndp_bd
Definition: lisp_types.h:229
int vnet_lisp_rloc_probe_enable_disable(u8 is_enable)
Definition: control.c:2174
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:2752
#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
#define vec_cmp(v1, v2)
Compare two vectors (only applicable to vectors of signed numbers).
Definition: vec.h:922
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:2858
#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:1659
pending_map_request_t * pending_map_requests_pool
Definition: control.h:211
typedef key
Definition: ipsec_types.api:83
void gid_dict_foreach_l2_arp_ndp_entry(gid_dictionary_t *db, cb, void *ht)
int vnet_lisp_add_del_locator_set(vnet_lisp_add_del_locator_set_args_t *a, u32 *ls_result)
Definition: control.c:2034
#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:3276
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:3292
#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:2798
vl_api_address_t ip
Definition: l2.api:490
static uword * get_locator_set_index(vnet_lisp_add_del_locator_set_args_t *a, uword *p)
Definition: control.c:1786
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:1199
#define vec_len(v)
Number of elements in vector (rvalue-only, NULL tolerant)
static char * lisp_cp_lookup_error_strings[]
Definition: control.c:2422
#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:1377
u32 * vnet_lisp_l2_arp_bds_get(void)
Definition: control.c:916
int vnet_lisp_add_del_locator(vnet_lisp_add_del_locator_set_args_t *a, locator_set_t *ls, u32 *ls_result)
Definition: control.c:1930
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
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:1569
union ip_address::@304 ip
static map_records_arg_t * map_record_args_get()
Definition: control.c:4103
static gid_address_t * build_itr_rloc_list(lisp_cp_main_t *lcm, locator_set_t *loc_set)
Definition: control.c:2494
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:2543
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:408
vnet_crypto_op_id_t
Definition: crypto.h:105
gid_address_t dst
Definition: control.h:50
static int add_ndp_entry(BVT(clib_bihash_kv) *kvp, void *arg)
Definition: control.c:993
static void map_records_arg_free(map_records_arg_t *a)
Definition: control.c:3864
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:3308
int vnet_lisp_add_del_map_resolver(vnet_lisp_add_del_map_resolver_args_t *a)
Definition: control.c:2321
ip4_main_t ip4_main
Global ip4 main structure.
Definition: ip4_forward.c:1079
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:1029
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:4250
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:3797
#define vec_foreach(var, vec)
Vector iterator.
static void * vlib_buffer_pull(vlib_buffer_t *b, u8 size)
Retrieve bytes from buffer head.
Definition: buffer.h:400
static int add_l2_arp_bd(BVT(clib_bihash_kv) *kvp, void *arg)
Definition: control.c:903
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:4719
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:3877
u16 dst_port
Definition: udp.api:42
gid_address_t dst_eid
Definition: control.c:2445
static int parse_map_records(vlib_buffer_t *b, map_records_arg_t *a, u8 count)
Definition: control.c:4071
u8 ip_version_and_header_length
Definition: ip4_packet.h:138
uword * lisp_stats_index_by_key
Definition: lisp_gpe.h:163
u32 ip4
Definition: one.api:440
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:543
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:2230
int vnet_lisp_map_register_set_ttl(u32 ttl)
Definition: control.c:2369
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:630
u32 vnet_lisp_map_register_get_ttl(void)
Definition: control.c:2377
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:3622
int vnet_lisp_use_petr(ip_address_t *ip, u8 is_add)
Configure Proxy-ETR.
Definition: control.c:1687
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:2736
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:2661
u32 * locator_indices
Definition: lisp_types.h:287
#define send_encapsulated_map_request(lcm, seid, deid, smr)
Definition: control.c:3065
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:3951
A LISP GPE Tunnel.
static mapping_t * build_map_register_record_list(lisp_cp_main_t *lcm)
Definition: control.c:2715
u8 * format_lisp_cp_lookup_trace(u8 *s, va_list *args)
Definition: control.c:2450
#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:307
#define resend_encapsulated_map_request(lcm, seid, deid, smr)
Definition: control.c:3068
lisp_cp_output_error_t
Definition: control.c:2868
#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:4558
locator_t * locators
Definition: lisp_types.h:299
lisp_cp_input_error_t
Definition: control.c:3737
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:3438
static int add_ndp_bd(BVT(clib_bihash_kv) *kvp, void *arg)
Definition: control.c:927
fib_entry_flag_t fib_entry_get_flags(fib_node_index_t fib_entry_index)
Definition: fib_entry.c:291