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