FD.io VPP  v19.04.4-rc0-5-ge88582fac
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
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
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
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
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 
1663  lcm->max_expired_map_registers = value;
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  /* update global flag */
2301  lcm->is_enabled = is_enable;
2302 
2303  return 0;
2304 }
2305 
2306 u8
2308 {
2310  return lcm->is_enabled;
2311 }
2312 
2313 int
2315 {
2317  u32 i;
2318  lisp_msmr_t _mr, *mr = &_mr;
2319 
2320  if (vnet_lisp_enable_disable_status () == 0)
2321  {
2322  clib_warning ("LISP is disabled!");
2323  return VNET_API_ERROR_LISP_DISABLED;
2324  }
2325 
2326  if (a->is_add)
2327  {
2328 
2329  if (get_map_resolver (&a->address))
2330  {
2331  clib_warning ("map-resolver %U already exists!", format_ip_address,
2332  &a->address);
2333  return -1;
2334  }
2335 
2336  clib_memset (mr, 0, sizeof (*mr));
2337  ip_address_copy (&mr->address, &a->address);
2338  vec_add1 (lcm->map_resolvers, *mr);
2339 
2340  if (vec_len (lcm->map_resolvers) == 1)
2341  lcm->do_map_resolver_election = 1;
2342  }
2343  else
2344  {
2345  for (i = 0; i < vec_len (lcm->map_resolvers); i++)
2346  {
2347  mr = vec_elt_at_index (lcm->map_resolvers, i);
2348  if (!ip_address_cmp (&mr->address, &a->address))
2349  {
2350  if (!ip_address_cmp (&mr->address, &lcm->active_map_resolver))
2351  lcm->do_map_resolver_election = 1;
2352 
2353  vec_del1 (lcm->map_resolvers, i);
2354  break;
2355  }
2356  }
2357  }
2358  return 0;
2359 }
2360 
2361 int
2363 {
2365  lcm->map_register_ttl = ttl;
2366  return 0;
2367 }
2368 
2369 u32
2371 {
2373  return lcm->map_register_ttl;
2374 }
2375 
2376 int
2378 {
2380  uword *p = 0;
2381 
2382  if (vnet_lisp_enable_disable_status () == 0)
2383  {
2384  clib_warning ("LISP is disabled!");
2385  return VNET_API_ERROR_LISP_DISABLED;
2386  }
2387 
2388  if (a->is_add)
2389  {
2391  if (!p)
2392  {
2393  clib_warning ("locator-set %v doesn't exist", a->locator_set_name);
2394  return VNET_API_ERROR_INVALID_ARGUMENT;
2395  }
2396 
2397  lcm->mreq_itr_rlocs = p[0];
2398  }
2399  else
2400  {
2401  lcm->mreq_itr_rlocs = ~0;
2402  }
2403 
2404  return 0;
2405 }
2406 
2407 /* Statistics (not really errors) */
2408 #define foreach_lisp_cp_lookup_error \
2409 _(DROP, "drop") \
2410 _(MAP_REQUESTS_SENT, "map-request sent") \
2411 _(ARP_REPLY_TX, "ARP replies sent") \
2412 _(NDP_NEIGHBOR_ADVERTISEMENT_TX, \
2413  "neighbor advertisement sent")
2414 
2416 #define _(sym,string) string,
2418 #undef _
2419 };
2420 
2421 typedef enum
2422 {
2423 #define _(sym,str) LISP_CP_LOOKUP_ERROR_##sym,
2425 #undef _
2428 
2429 typedef enum
2430 {
2435 
2436 typedef struct
2437 {
2441 
2442 u8 *
2443 format_lisp_cp_lookup_trace (u8 * s, va_list * args)
2444 {
2445  CLIB_UNUSED (vlib_main_t * vm) = va_arg (*args, vlib_main_t *);
2446  CLIB_UNUSED (vlib_node_t * node) = va_arg (*args, vlib_node_t *);
2447  lisp_cp_lookup_trace_t *t = va_arg (*args, lisp_cp_lookup_trace_t *);
2448 
2449  s = format (s, "LISP-CP-LOOKUP: map-resolver: %U destination eid %U",
2451  &t->dst_eid);
2452  return s;
2453 }
2454 
2455 int
2457  ip_address_t * sloc)
2458 {
2459  lisp_msmr_t *mrit;
2460  ip_address_t *a;
2461 
2462  if (vec_len (lcm->map_resolvers) == 0)
2463  {
2464  clib_warning ("No map-resolver configured");
2465  return 0;
2466  }
2467 
2468  /* find the first mr ip we have a route to and the ip of the
2469  * iface that has a route to it */
2470  vec_foreach (mrit, lcm->map_resolvers)
2471  {
2472  a = &mrit->address;
2473  if (0 != ip_fib_get_first_egress_ip_for_dst (lcm, a, sloc))
2474  {
2475  ip_address_copy (mr_ip, a);
2476 
2477  /* also update globals */
2478  return 1;
2479  }
2480  }
2481 
2482  clib_warning ("Can't find map-resolver and local interface ip!");
2483  return 0;
2484 }
2485 
2486 static gid_address_t *
2488 {
2489  void *addr;
2490  u32 i;
2491  locator_t *loc;
2492  u32 *loc_indexp;
2493  ip_interface_address_t *ia = 0;
2494  gid_address_t gid_data, *gid = &gid_data;
2495  gid_address_t *rlocs = 0;
2496  ip_prefix_t *ippref = &gid_address_ippref (gid);
2497  ip_address_t *rloc = &ip_prefix_addr (ippref);
2498 
2499  clib_memset (gid, 0, sizeof (gid[0]));
2501  for (i = 0; i < vec_len (loc_set->locator_indices); i++)
2502  {
2503  loc_indexp = vec_elt_at_index (loc_set->locator_indices, i);
2504  loc = pool_elt_at_index (lcm->locator_pool, loc_indexp[0]);
2505 
2506  /* Add ipv4 locators first TODO sort them */
2507 
2508  /* *INDENT-OFF* */
2510  loc->sw_if_index, 1 /* unnumbered */,
2511  ({
2512  addr = ip_interface_address_get_address (&lcm->im4->lookup_main, ia);
2513  ip_address_set (rloc, addr, IP4);
2514  ip_prefix_len (ippref) = 32;
2515  ip_prefix_normalize (ippref);
2516  vec_add1 (rlocs, gid[0]);
2517  }));
2518 
2519  /* Add ipv6 locators */
2521  loc->sw_if_index, 1 /* unnumbered */,
2522  ({
2523  addr = ip_interface_address_get_address (&lcm->im6->lookup_main, ia);
2524  ip_address_set (rloc, addr, IP6);
2525  ip_prefix_len (ippref) = 128;
2526  ip_prefix_normalize (ippref);
2527  vec_add1 (rlocs, gid[0]);
2528  }));
2529  /* *INDENT-ON* */
2530 
2531  }
2532  return rlocs;
2533 }
2534 
2535 static vlib_buffer_t *
2537  ip_address_t * sloc, ip_address_t * rloc,
2538  gid_address_t * itr_rlocs, u64 * nonce_res, u32 * bi_res)
2539 {
2540  vlib_buffer_t *b;
2541  u32 bi;
2542  vlib_main_t *vm = lcm->vlib_main;
2543 
2544  if (vlib_buffer_alloc (vm, &bi, 1) != 1)
2545  {
2546  clib_warning ("Can't allocate buffer for Map-Request!");
2547  return 0;
2548  }
2549 
2550  b = vlib_get_buffer (vm, bi);
2551 
2552  /* leave some space for the encap headers */
2554 
2555  /* put lisp msg */
2556  lisp_msg_put_mreq (lcm, b, NULL, deid, itr_rlocs, 0 /* smr invoked */ ,
2557  1 /* rloc probe */ , nonce_res);
2558 
2559  /* push outer ip header */
2561  rloc, 1);
2562 
2563  bi_res[0] = bi;
2564 
2565  return b;
2566 }
2567 
2568 static vlib_buffer_t *
2570  gid_address_t * seid, gid_address_t * deid,
2571  locator_set_t * loc_set, ip_address_t * mr_ip,
2572  ip_address_t * sloc, u8 is_smr_invoked,
2573  u64 * nonce_res, u32 * bi_res)
2574 {
2575  vlib_buffer_t *b;
2576  u32 bi;
2577  gid_address_t *rlocs = 0;
2578  vlib_main_t *vm = lcm->vlib_main;
2579 
2580  if (vlib_buffer_alloc (vm, &bi, 1) != 1)
2581  {
2582  clib_warning ("Can't allocate buffer for Map-Request!");
2583  return 0;
2584  }
2585 
2586  b = vlib_get_buffer (vm, bi);
2587  b->flags = 0;
2588 
2589  /* leave some space for the encap headers */
2591 
2592  /* get rlocs */
2593  rlocs = build_itr_rloc_list (lcm, loc_set);
2594 
2595  if (MR_MODE_SRC_DST == lcm->map_request_mode
2596  && GID_ADDR_SRC_DST != gid_address_type (deid))
2597  {
2598  gid_address_t sd;
2599  clib_memset (&sd, 0, sizeof (sd));
2600  build_src_dst (&sd, seid, deid);
2601  lisp_msg_put_mreq (lcm, b, seid, &sd, rlocs, is_smr_invoked,
2602  0 /* rloc probe */ , nonce_res);
2603  }
2604  else
2605  {
2606  /* put lisp msg */
2607  lisp_msg_put_mreq (lcm, b, seid, deid, rlocs, is_smr_invoked,
2608  0 /* rloc probe */ , nonce_res);
2609  }
2610 
2611  /* push ecm: udp-ip-lisp */
2613 
2614  /* push outer ip header */
2616  mr_ip, 1);
2617 
2618  bi_res[0] = bi;
2619 
2620  vec_free (rlocs);
2621  return b;
2622 }
2623 
2624 static void
2626 {
2628  r->retries_num = 0;
2629 }
2630 
2631 #define foreach_msmr \
2632  _(server) \
2633  _(resolver)
2634 
2635 #define _(name) \
2636 static int \
2637 elect_map_ ## name (lisp_cp_main_t * lcm) \
2638 { \
2639  lisp_msmr_t *mr; \
2640  vec_foreach (mr, lcm->map_ ## name ## s) \
2641  { \
2642  if (!mr->is_down) \
2643  { \
2644  ip_address_copy (&lcm->active_map_ ##name, &mr->address); \
2645  lcm->do_map_ ## name ## _election = 0; \
2646  return 1; \
2647  } \
2648  } \
2649  return 0; \
2650 }
2652 #undef _
2653  static void
2655 {
2656  mapping_t *map;
2657  vec_foreach (map, maps) vec_free (map->locators);
2658 
2659  vec_free (maps);
2660 }
2661 
2662 static void
2663 add_locators (lisp_cp_main_t * lcm, mapping_t * m, u32 locator_set_index,
2664  ip_address_t * probed_loc)
2665 {
2666  u32 *li;
2667  locator_t *loc, new;
2668  ip_interface_address_t *ia = 0;
2669  void *addr;
2670  ip_address_t *new_ip = &gid_address_ip (&new.address);
2671 
2672  m->locators = 0;
2674  locator_set_index);
2675  vec_foreach (li, ls->locator_indices)
2676  {
2677  loc = pool_elt_at_index (lcm->locator_pool, li[0]);
2678  new = loc[0];
2679  if (loc->local)
2680  {
2681  /* *INDENT-OFF* */
2683  loc->sw_if_index, 1 /* unnumbered */,
2684  ({
2685  addr = ip_interface_address_get_address (&lcm->im4->lookup_main,
2686  ia);
2687  ip_address_set (new_ip, addr, IP4);
2688  }));
2689 
2690  /* Add ipv6 locators */
2692  loc->sw_if_index, 1 /* unnumbered */,
2693  ({
2694  addr = ip_interface_address_get_address (&lcm->im6->lookup_main,
2695  ia);
2696  ip_address_set (new_ip, addr, IP6);
2697  }));
2698  /* *INDENT-ON* */
2699 
2700  if (probed_loc && ip_address_cmp (probed_loc, new_ip) == 0)
2701  new.probed = 1;
2702  }
2703  vec_add1 (m->locators, new);
2704  }
2705 }
2706 
2707 static mapping_t *
2709 {
2710  mapping_t *recs = 0, rec, *m;
2711 
2712  /* *INDENT-OFF* */
2713  pool_foreach(m, lcm->mapping_pool,
2714  {
2715  /* for now build only local mappings */
2716  if (!m->local)
2717  continue;
2718 
2719  rec = m[0];
2720  add_locators (lcm, &rec, m->locator_set_index, NULL);
2721  vec_add1 (recs, rec);
2722  });
2723  /* *INDENT-ON* */
2724 
2725  return recs;
2726 }
2727 
2728 static vnet_crypto_op_id_t
2730 {
2731  switch (key_id)
2732  {
2733  case HMAC_SHA_1_96:
2734  return VNET_CRYPTO_OP_SHA1_HMAC;
2735  case HMAC_SHA_256_128:
2736  return VNET_CRYPTO_OP_SHA256_HMAC;
2737  default:
2738  clib_warning ("unsupported encryption key type: %d!", key_id);
2739  break;
2740  }
2741  return VNET_CRYPTO_OP_NONE;
2742 }
2743 
2744 static int
2746  lisp_key_type_t key_id, u8 * key,
2747  u16 auth_data_len, u32 msg_len)
2748 {
2750  MREG_KEY_ID (map_reg_hdr) = clib_host_to_net_u16 (key_id);
2751  MREG_AUTH_DATA_LEN (map_reg_hdr) = clib_host_to_net_u16 (auth_data_len);
2752  vnet_crypto_op_t _op, *op = &_op;
2753 
2755  op->key = key;
2756  op->key_len = vec_len (key);
2757  op->len = msg_len;
2758  op->digest = MREG_DATA (map_reg_hdr);
2759  op->src = (u8 *) map_reg_hdr;
2760  op->digest_len = 0;
2761  op->iv = 0;
2762 
2763  vnet_crypto_process_ops (lcm->vlib_main, op, 1);
2764 
2765  return 0;
2766 }
2767 
2768 static vlib_buffer_t *
2770  ip_address_t * ms_ip, u64 * nonce_res, u8 want_map_notif,
2771  mapping_t * records, lisp_key_type_t key_id, u8 * key,
2772  u32 * bi_res)
2773 {
2774  void *map_reg_hdr;
2775  vlib_buffer_t *b;
2776  u32 bi, auth_data_len = 0, msg_len = 0;
2777  vlib_main_t *vm = lcm->vlib_main;
2778 
2779  if (vlib_buffer_alloc (vm, &bi, 1) != 1)
2780  {
2781  clib_warning ("Can't allocate buffer for Map-Register!");
2782  return 0;
2783  }
2784 
2785  b = vlib_get_buffer (vm, bi);
2786 
2787  /* leave some space for the encap headers */
2789 
2790  auth_data_len = auth_data_len_by_key_id (key_id);
2791  map_reg_hdr = lisp_msg_put_map_register (b, records, want_map_notif,
2792  auth_data_len, nonce_res,
2793  &msg_len);
2794 
2795  update_map_register_auth_data (map_reg_hdr, key_id, key, auth_data_len,
2796  msg_len);
2797 
2798  /* push outer ip header */
2800  ms_ip, 1);
2801 
2802  bi_res[0] = bi;
2803  return b;
2804 }
2805 
2806 #define _(name) \
2807 static int \
2808 get_egress_map_ ##name## _ip (lisp_cp_main_t * lcm, ip_address_t * ip) \
2809 { \
2810  lisp_msmr_t *mr; \
2811  while (lcm->do_map_ ## name ## _election \
2812  | (0 == ip_fib_get_first_egress_ip_for_dst \
2813  (lcm, &lcm->active_map_ ##name, ip))) \
2814  { \
2815  if (0 == elect_map_ ## name (lcm)) \
2816  /* all map resolvers/servers are down */ \
2817  { \
2818  /* restart MR/MS checking by marking all of them up */ \
2819  vec_foreach (mr, lcm->map_ ## name ## s) mr->is_down = 0; \
2820  return -1; \
2821  } \
2822  } \
2823  return 0; \
2824 }
2825 
2827 #undef _
2828 /* CP output statistics */
2829 #define foreach_lisp_cp_output_error \
2830 _(MAP_REGISTERS_SENT, "map-registers sent") \
2831 _(MAP_REQUESTS_SENT, "map-requests sent") \
2832 _(RLOC_PROBES_SENT, "rloc-probes sent")
2834 #define _(sym,string) string,
2836 #undef _
2837 };
2838 
2839 typedef enum
2840 {
2841 #define _(sym,str) LISP_CP_OUTPUT_ERROR_##sym,
2843 #undef _
2846 
2847 static uword
2849  vlib_frame_t * from_frame)
2850 {
2851  return 0;
2852 }
2853 
2854 /* dummy node used only for statistics */
2855 /* *INDENT-OFF* */
2857  .function = lisp_cp_output,
2858  .name = "lisp-cp-output",
2859  .vector_size = sizeof (u32),
2860  .format_trace = format_lisp_cp_input_trace,
2861  .type = VLIB_NODE_TYPE_INTERNAL,
2862 
2863  .n_errors = LISP_CP_OUTPUT_N_ERROR,
2864  .error_strings = lisp_cp_output_error_strings,
2865 
2866  .n_next_nodes = LISP_CP_INPUT_N_NEXT,
2867 
2868  .next_nodes = {
2869  [LISP_CP_INPUT_NEXT_DROP] = "error-drop",
2870  },
2871 };
2872 /* *INDENT-ON* */
2873 
2874 static int
2876  u32 local_locator_set_index, ip_address_t * sloc,
2877  ip_address_t * rloc)
2878 {
2879  locator_set_t *ls;
2880  u32 bi;
2881  vlib_buffer_t *b;
2882  vlib_frame_t *f;
2883  u64 nonce = 0;
2884  u32 next_index, *to_next;
2885  gid_address_t *itr_rlocs;
2886 
2887  ls = pool_elt_at_index (lcm->locator_set_pool, local_locator_set_index);
2888  itr_rlocs = build_itr_rloc_list (lcm, ls);
2889 
2890  b = build_map_request (lcm, deid, sloc, rloc, itr_rlocs, &nonce, &bi);
2891  vec_free (itr_rlocs);
2892  if (!b)
2893  return -1;
2894 
2895  vnet_buffer (b)->sw_if_index[VLIB_TX] = 0;
2896 
2897  next_index = (ip_addr_version (rloc) == IP4) ?
2898  ip4_lookup_node.index : ip6_lookup_node.index;
2899 
2900  f = vlib_get_frame_to_node (lcm->vlib_main, next_index);
2901 
2902  /* Enqueue the packet */
2903  to_next = vlib_frame_vector_args (f);
2904  to_next[0] = bi;
2905  f->n_vectors = 1;
2906  vlib_put_frame_to_node (lcm->vlib_main, next_index, f);
2907 
2908  return 0;
2909 }
2910 
2911 static int
2913 {
2914  u8 lprio = 0;
2915  mapping_t *lm;
2916  fwd_entry_t *e;
2917  locator_pair_t *lp;
2918  u32 si, rloc_probes_sent = 0;
2919 
2920  /* *INDENT-OFF* */
2921  pool_foreach (e, lcm->fwd_entry_pool,
2922  {
2923  if (vec_len (e->locator_pairs) == 0)
2924  continue;
2925 
2926  si = gid_dictionary_lookup (&lcm->mapping_index_by_gid, &e->leid);
2927  if (~0 == si)
2928  {
2929  clib_warning ("internal error: cannot find local eid %U in "
2930  "map-cache!", format_gid_address, &e->leid);
2931  continue;
2932  }
2933  lm = pool_elt_at_index (lcm->mapping_pool, si);
2934 
2935  /* get the best (lowest) priority */
2936  lprio = e->locator_pairs[0].priority;
2937 
2938  /* send rloc-probe for pair(s) with the best remote locator priority */
2939  vec_foreach (lp, e->locator_pairs)
2940  {
2941  if (lp->priority != lprio)
2942  break;
2943 
2944  /* get first remote locator */
2945  send_rloc_probe (lcm, &e->reid, lm->locator_set_index, &lp->lcl_loc,
2946  &lp->rmt_loc);
2947  rloc_probes_sent++;
2948  }
2949  });
2950  /* *INDENT-ON* */
2951 
2953  LISP_CP_OUTPUT_ERROR_RLOC_PROBES_SENT,
2954  rloc_probes_sent);
2955  return 0;
2956 }
2957 
2958 static int
2959 send_map_register (lisp_cp_main_t * lcm, u8 want_map_notif)
2960 {
2962  u32 bi, map_registers_sent = 0;
2963  vlib_buffer_t *b;
2964  ip_address_t sloc;
2965  vlib_frame_t *f;
2966  u64 nonce = 0;
2967  u32 next_index, *to_next;
2968  mapping_t *records, *r, *group, *k;
2969 
2970  if (get_egress_map_server_ip (lcm, &sloc) < 0)
2971  return -1;
2972 
2973  records = build_map_register_record_list (lcm);
2974  if (!records)
2975  return -1;
2976 
2977  vec_foreach (r, records)
2978  {
2979  u8 *key = r->key;
2980  u8 key_id = r->key_id;
2981 
2982  if (!key)
2983  continue; /* no secret key -> map-register cannot be sent */
2984 
2985  group = 0;
2986  vec_add1 (group, r[0]);
2987 
2988  /* group mappings that share common key */
2989  for (k = r + 1; k < vec_end (records); k++)
2990  {
2991  if (k->key_id != r->key_id)
2992  continue;
2993 
2994  if (vec_is_equal (k->key, r->key))
2995  {
2996  vec_add1 (group, k[0]);
2997  k->key = 0; /* don't process this mapping again */
2998  }
2999  }
3000 
3001  b = build_map_register (lcm, &sloc, &lcm->active_map_server, &nonce,
3002  want_map_notif, group, key_id, key, &bi);
3003  vec_free (group);
3004  if (!b)
3005  continue;
3006 
3007  vnet_buffer (b)->sw_if_index[VLIB_TX] = 0;
3008 
3009  next_index = (ip_addr_version (&lcm->active_map_server) == IP4) ?
3010  ip4_lookup_node.index : ip6_lookup_node.index;
3011 
3012  f = vlib_get_frame_to_node (lcm->vlib_main, next_index);
3013 
3014  /* Enqueue the packet */
3015  to_next = vlib_frame_vector_args (f);
3016  to_next[0] = bi;
3017  f->n_vectors = 1;
3018  vlib_put_frame_to_node (lcm->vlib_main, next_index, f);
3019  map_registers_sent++;
3020 
3022  clib_memset (pmr, 0, sizeof (*pmr));
3025  pmr - lcm->pending_map_registers_pool);
3026  }
3027  free_map_register_records (records);
3028 
3030  LISP_CP_OUTPUT_ERROR_MAP_REGISTERS_SENT,
3031  map_registers_sent);
3032 
3033  return 0;
3034 }
3035 
3036 #define send_encapsulated_map_request(lcm, seid, deid, smr) \
3037  _send_encapsulated_map_request(lcm, seid, deid, smr, 0)
3038 
3039 #define resend_encapsulated_map_request(lcm, seid, deid, smr) \
3040  _send_encapsulated_map_request(lcm, seid, deid, smr, 1)
3041 
3042 static int
3043 _send_encapsulated_map_request (lisp_cp_main_t * lcm,
3044  gid_address_t * seid, gid_address_t * deid,
3045  u8 is_smr_invoked, u8 is_resend)
3046 {
3047  u32 next_index, bi = 0, *to_next, map_index;
3048  vlib_buffer_t *b;
3049  vlib_frame_t *f;
3050  u64 nonce = 0;
3051  locator_set_t *loc_set;
3052  mapping_t *map;
3053  pending_map_request_t *pmr, *duplicate_pmr = 0;
3054  ip_address_t sloc;
3055  u32 ls_index;
3056 
3057  /* if there is already a pending request remember it */
3058 
3059  /* *INDENT-OFF* */
3061  ({
3062  if (!gid_address_cmp (&pmr->src, seid)
3063  && !gid_address_cmp (&pmr->dst, deid))
3064  {
3065  duplicate_pmr = pmr;
3066  break;
3067  }
3068  }));
3069  /* *INDENT-ON* */
3070 
3071  if (!is_resend && duplicate_pmr)
3072  {
3073  /* don't send the request if there is a pending map request already */
3074  return 0;
3075  }
3076 
3077  u8 pitr_mode = lcm->flags & LISP_FLAG_PITR_MODE;
3078 
3079  /* get locator-set for seid */
3080  if (!pitr_mode && gid_address_type (deid) != GID_ADDR_NSH)
3081  {
3082  map_index = gid_dictionary_lookup (&lcm->mapping_index_by_gid, seid);
3083  if (map_index == ~0)
3084  {
3085  clib_warning ("No local mapping found in eid-table for %U!",
3086  format_gid_address, seid);
3087  return -1;
3088  }
3089 
3090  map = pool_elt_at_index (lcm->mapping_pool, map_index);
3091 
3092  if (!map->local)
3093  {
3094  clib_warning
3095  ("Mapping found for src eid %U is not marked as local!",
3096  format_gid_address, seid);
3097  return -1;
3098  }
3099  ls_index = map->locator_set_index;
3100  }
3101  else
3102  {
3103  if (pitr_mode)
3104  {
3105  if (lcm->pitr_map_index != ~0)
3106  {
3107  map =
3108  pool_elt_at_index (lcm->mapping_pool, lcm->pitr_map_index);
3109  ls_index = map->locator_set_index;
3110  }
3111  else
3112  {
3113  return -1;
3114  }
3115  }
3116  else
3117  {
3118  if (lcm->nsh_map_index == (u32) ~ 0)
3119  {
3120  clib_warning ("No locator-set defined for NSH!");
3121  return -1;
3122  }
3123  else
3124  {
3125  map = pool_elt_at_index (lcm->mapping_pool, lcm->nsh_map_index);
3126  ls_index = map->locator_set_index;
3127  }
3128  }
3129  }
3130 
3131  /* overwrite locator set if map-request itr-rlocs configured */
3132  if (~0 != lcm->mreq_itr_rlocs)
3133  {
3134  ls_index = lcm->mreq_itr_rlocs;
3135  }
3136 
3137  loc_set = pool_elt_at_index (lcm->locator_set_pool, ls_index);
3138 
3139  if (get_egress_map_resolver_ip (lcm, &sloc) < 0)
3140  {
3141  if (duplicate_pmr)
3142  duplicate_pmr->to_be_removed = 1;
3143  return -1;
3144  }
3145 
3146  /* build the encapsulated map request */
3147  b = build_encapsulated_map_request (lcm, seid, deid, loc_set,
3148  &lcm->active_map_resolver,
3149  &sloc, is_smr_invoked, &nonce, &bi);
3150 
3151  if (!b)
3152  return -1;
3153 
3154  /* set fib index to default and lookup node */
3155  vnet_buffer (b)->sw_if_index[VLIB_TX] = 0;
3156  next_index = (ip_addr_version (&lcm->active_map_resolver) == IP4) ?
3157  ip4_lookup_node.index : ip6_lookup_node.index;
3158 
3159  f = vlib_get_frame_to_node (lcm->vlib_main, next_index);
3160 
3161  /* Enqueue the packet */
3162  to_next = vlib_frame_vector_args (f);
3163  to_next[0] = bi;
3164  f->n_vectors = 1;
3165  vlib_put_frame_to_node (lcm->vlib_main, next_index, f);
3166 
3168  LISP_CP_OUTPUT_ERROR_MAP_REQUESTS_SENT, 1);
3169 
3170  if (duplicate_pmr)
3171  /* if there is a pending request already update it */
3172  {
3173  if (clib_fifo_elts (duplicate_pmr->nonces) >= PENDING_MREQ_QUEUE_LEN)
3174  {
3175  /* remove the oldest nonce */
3176  u64 CLIB_UNUSED (tmp), *nonce_del;
3177  nonce_del = clib_fifo_head (duplicate_pmr->nonces);
3178  hash_unset (lcm->pending_map_requests_by_nonce, nonce_del[0]);
3179  clib_fifo_sub1 (duplicate_pmr->nonces, tmp);
3180  }
3181 
3182  clib_fifo_add1 (duplicate_pmr->nonces, nonce);
3183  hash_set (lcm->pending_map_requests_by_nonce, nonce,
3184  duplicate_pmr - lcm->pending_map_requests_pool);
3185  }
3186  else
3187  {
3188  /* add map-request to pending requests table */
3189  pool_get (lcm->pending_map_requests_pool, pmr);
3190  clib_memset (pmr, 0, sizeof (*pmr));
3191  gid_address_copy (&pmr->src, seid);
3192  gid_address_copy (&pmr->dst, deid);
3193  clib_fifo_add1 (pmr->nonces, nonce);
3194  pmr->is_smr_invoked = is_smr_invoked;
3196  hash_set (lcm->pending_map_requests_by_nonce, nonce,
3197  pmr - lcm->pending_map_requests_pool);
3198  }
3199 
3200  return 0;
3201 }
3202 
3203 static void
3205 {
3206  ip4_header_t *ip4 = hdr;
3207  ip6_header_t *ip6;
3208 
3209  if ((ip4->ip_version_and_header_length & 0xF0) == 0x40)
3210  {
3211  ip_address_set (src, &ip4->src_address, IP4);
3212  ip_address_set (dst, &ip4->dst_address, IP4);
3213  }
3214  else
3215  {
3216  ip6 = hdr;
3217  ip_address_set (src, &ip6->src_address, IP6);
3218  ip_address_set (dst, &ip6->dst_address, IP6);
3219  }
3220 }
3221 
3222 static u32
3224  u8 version)
3225 {
3226  uword *vnip;
3227  u32 vni = ~0, table_id = ~0;
3228 
3229  table_id = fib_table_get_table_id_for_sw_if_index ((version ==
3230  IP4 ? FIB_PROTOCOL_IP4 :
3232  vnet_buffer
3233  (b)->sw_if_index
3234  [VLIB_RX]);
3235 
3236  vnip = hash_get (lcm->vni_by_table_id, table_id);
3237  if (vnip)
3238  vni = vnip[0];
3239  else
3240  clib_warning ("vrf %d is not mapped to any vni!", table_id);
3241 
3242  return vni;
3243 }
3244 
3247 {
3248  u32 sw_if_index0;
3249 
3250  l2input_main_t *l2im = &l2input_main;
3251  l2_input_config_t *config;
3252  l2_bridge_domain_t *bd_config;
3253 
3254  sw_if_index0 = vnet_buffer (b)->sw_if_index[VLIB_RX];
3255  config = vec_elt_at_index (l2im->configs, sw_if_index0);
3256  bd_config = vec_elt_at_index (l2im->bd_configs, config->bd_index);
3257 
3258  return bd_config->bd_id;
3259 }
3260 
3263 {
3264  uword *vnip;
3265  u32 vni = ~0;
3267 
3268  vnip = hash_get (lcm->vni_by_bd_id, bd);
3269  if (vnip)
3270  vni = vnip[0];
3271  else
3272  clib_warning ("bridge domain %d is not mapped to any vni!", bd);
3273 
3274  return vni;
3275 }
3276 
3277 void
3280  u16 type)
3281 {
3282  ethernet_header_t *eh;
3283  u32 vni = 0;
3284  icmp6_neighbor_discovery_ethernet_link_layer_address_option_t *opt;
3285 
3286  clib_memset (src, 0, sizeof (*src));
3287  clib_memset (dst, 0, sizeof (*dst));
3288 
3291 
3292  if (LISP_AFI_IP == type || LISP_AFI_IP6 == type)
3293  {
3294  ip4_header_t *ip;
3295  u8 version, preflen;
3296 
3299 
3300  ip = vlib_buffer_get_current (b);
3301  get_src_and_dst_ip (ip, &gid_address_ip (src), &gid_address_ip (dst));
3302 
3303  version = gid_address_ip_version (src);
3304  preflen = ip_address_max_len (version);
3305  gid_address_ippref_len (src) = preflen;
3306  gid_address_ippref_len (dst) = preflen;
3307 
3308  vni = lisp_get_vni_from_buffer_ip (lcm, b, version);
3309  gid_address_vni (dst) = vni;
3310  gid_address_vni (src) = vni;
3311  }
3312  else if (LISP_AFI_MAC == type)
3313  {
3315 
3316  eh = vlib_buffer_get_current (b);
3317 
3318  if (clib_net_to_host_u16 (eh->type) == ETHERNET_TYPE_ARP)
3319  {
3320  ah = (ethernet_arp_header_t *) (((u8 *) eh) + sizeof (*eh));
3322 
3323  if (clib_net_to_host_u16 (ah->opcode)
3324  != ETHERNET_ARP_OPCODE_request)
3325  {
3327  sizeof (ip_address_t));
3329  gid_address_arp_ndp_bd (dst) = ~0;
3330  return;
3331  }
3332 
3335  &ah->ip4_over_ethernet[1].ip4, 4);
3336  }
3337  else
3338  {
3339  if (clib_net_to_host_u16 (eh->type) == ETHERNET_TYPE_IP6)
3340  {
3341  ip6_header_t *ip;
3342  ip = (ip6_header_t *) (eh + 1);
3343 
3344  if (IP_PROTOCOL_ICMP6 == ip->protocol)
3345  {
3346  icmp6_neighbor_solicitation_or_advertisement_header_t *ndh;
3347  ndh = ip6_next_header (ip);
3348  if (ndh->icmp.type == ICMP6_neighbor_solicitation)
3349  {
3351 
3352  /* check that source link layer address option is present */
3353  opt = (void *) (ndh + 1);
3354  if ((opt->header.type !=
3355  ICMP6_NEIGHBOR_DISCOVERY_OPTION_source_link_layer_address)
3356  || (opt->header.n_data_u64s != 1))
3357  {
3359  sizeof (ip_address_t));
3361  IP6;
3362  gid_address_arp_ndp_bd (dst) = ~0;
3364  return;
3365  }
3366 
3367  gid_address_ndp_bd (dst) =
3370  &ndh->target_address, IP6);
3371  return;
3372  }
3373  }
3374  }
3375 
3378  mac_copy (&gid_address_mac (src), eh->src_address);
3379  mac_copy (&gid_address_mac (dst), eh->dst_address);
3380 
3381  /* get vni */
3382  vni = lisp_get_vni_from_buffer_eth (lcm, b);
3383 
3384  gid_address_vni (dst) = vni;
3385  gid_address_vni (src) = vni;
3386  }
3387  }
3388  else if (LISP_AFI_LCAF == type)
3389  {
3390  lisp_nsh_hdr_t *nh;
3391  eh = vlib_buffer_get_current (b);
3392 
3393  if (clib_net_to_host_u16 (eh->type) == ETHERNET_TYPE_NSH)
3394  {
3395  nh = (lisp_nsh_hdr_t *) (((u8 *) eh) + sizeof (*eh));
3396  u32 spi = clib_net_to_host_u32 (nh->spi_si << 8);
3397  u8 si = (u8) clib_net_to_host_u32 (nh->spi_si);
3398  gid_address_nsh_spi (dst) = spi;
3399  gid_address_nsh_si (dst) = si;
3400 
3403  }
3404  }
3405 }
3406 
3407 static uword
3409  vlib_node_runtime_t * node,
3410  vlib_frame_t * from_frame, int overlay)
3411 {
3412  icmp6_neighbor_discovery_ethernet_link_layer_address_option_t *opt;
3413  u32 *from, *to_next, di, si;
3415  u32 next_index;
3416  uword n_left_from, n_left_to_next;
3417  vnet_main_t *vnm = vnet_get_main ();
3418 
3419  from = vlib_frame_vector_args (from_frame);
3420  n_left_from = from_frame->n_vectors;
3421  next_index = node->cached_next_index;
3422 
3423  while (n_left_from > 0)
3424  {
3425  vlib_get_next_frame (vm, node, next_index, to_next, n_left_to_next);
3426 
3427  while (n_left_from > 0 && n_left_to_next > 0)
3428  {
3429  u32 pi0, sw_if_index0, next0;
3430  u64 mac0;
3431  vlib_buffer_t *b0;
3433  ethernet_arp_header_t *arp0;
3434  ethernet_header_t *eth0;
3435  vnet_hw_interface_t *hw_if0;
3436  ethernet_header_t *eh0;
3437  icmp6_neighbor_solicitation_or_advertisement_header_t *ndh;
3438  ip6_header_t *ip0;
3439 
3440  pi0 = from[0];
3441  from += 1;
3442  n_left_from -= 1;
3443  to_next[0] = pi0;
3444  to_next += 1;
3445  n_left_to_next -= 1;
3446 
3447  b0 = vlib_get_buffer (vm, pi0);
3448 
3449  /* src/dst eid pair */
3450  get_src_and_dst_eids_from_buffer (lcm, b0, &src, &dst, overlay);
3451 
3452  if (gid_address_type (&dst) == GID_ADDR_ARP)
3453  {
3454  mac0 = gid_dictionary_lookup (&lcm->mapping_index_by_gid, &dst);
3455  if (GID_LOOKUP_MISS_L2 == mac0)
3456  goto drop;
3457 
3458  /* send ARP reply */
3459  sw_if_index0 = vnet_buffer (b0)->sw_if_index[VLIB_RX];
3460  vnet_buffer (b0)->sw_if_index[VLIB_TX] = sw_if_index0;
3461 
3462  hw_if0 = vnet_get_sup_hw_interface (vnm, sw_if_index0);
3463 
3464  eth0 = vlib_buffer_get_current (b0);
3465  arp0 = (ethernet_arp_header_t *) (((u8 *) eth0)
3466  + sizeof (*eth0));
3467  arp0->opcode = clib_host_to_net_u16 (ETHERNET_ARP_OPCODE_reply);
3468  arp0->ip4_over_ethernet[1] = arp0->ip4_over_ethernet[0];
3469  mac_address_from_u64 (&arp0->ip4_over_ethernet[0].mac, mac0);
3470  clib_memcpy (&arp0->ip4_over_ethernet[0].ip4,
3471  &gid_address_arp_ip4 (&dst), 4);
3472 
3473  /* Hardware must be ethernet-like. */
3474  ASSERT (vec_len (hw_if0->hw_address) == 6);
3475 
3476  clib_memcpy (eth0->dst_address, eth0->src_address, 6);
3477  clib_memcpy (eth0->src_address, hw_if0->hw_address, 6);
3478 
3479  b0->error = node->errors[LISP_CP_LOOKUP_ERROR_ARP_REPLY_TX];
3481  goto enqueue;
3482  }
3483  else if (gid_address_type (&dst) == GID_ADDR_NDP)
3484  {
3485  mac0 = gid_dictionary_lookup (&lcm->mapping_index_by_gid, &dst);
3486  if (GID_LOOKUP_MISS_L2 == mac0)
3487  goto drop;
3488 
3489  sw_if_index0 = vnet_buffer (b0)->sw_if_index[VLIB_RX];
3490  vnet_buffer (b0)->sw_if_index[VLIB_TX] = sw_if_index0;
3491 
3492  eh0 = vlib_buffer_get_current (b0);
3493  ip0 = (ip6_header_t *) (eh0 + 1);
3494  ndh = ip6_next_header (ip0);
3495  int bogus_length;
3496  ip0->dst_address = ip0->src_address;
3497  ip0->src_address = ndh->target_address;
3498  ip0->hop_limit = 255;
3499  opt = (void *) (ndh + 1);
3500  opt->header.type =
3501  ICMP6_NEIGHBOR_DISCOVERY_OPTION_target_link_layer_address;
3502  clib_memcpy (opt->ethernet_address, (u8 *) & mac0, 6);
3503  ndh->icmp.type = ICMP6_neighbor_advertisement;
3504  ndh->advertisement_flags = clib_host_to_net_u32
3507  ndh->icmp.checksum = 0;
3508  ndh->icmp.checksum =
3509  ip6_tcp_udp_icmp_compute_checksum (vm, b0, ip0,
3510  &bogus_length);
3511  clib_memcpy (eh0->dst_address, eh0->src_address, 6);
3512  clib_memcpy (eh0->src_address, (u8 *) & mac0, 6);
3513  b0->error =
3514  node->errors
3515  [LISP_CP_LOOKUP_ERROR_NDP_NEIGHBOR_ADVERTISEMENT_TX];
3517  goto enqueue;
3518  }
3519 
3520  /* if we have remote mapping for destination already in map-cache
3521  add forwarding tunnel directly. If not send a map-request */
3523  &src);
3524  if (~0 != di)
3525  {
3526  mapping_t *m = vec_elt_at_index (lcm->mapping_pool, di);
3527  /* send a map-request also in case of negative mapping entry
3528  with corresponding action */
3529  if (m->action == LISP_SEND_MAP_REQUEST)
3530  {
3531  /* send map-request */
3532  queue_map_request (&src, &dst, 0 /* smr_invoked */ ,
3533  0 /* is_resend */ );
3534  }
3535  else
3536  {
3537  if (GID_ADDR_NSH != gid_address_type (&dst))
3538  {
3540  &src);
3541  }
3542  else
3543  si = lcm->nsh_map_index;
3544 
3545  if (~0 != si)
3546  {
3547  dp_add_fwd_entry_from_mt (si, di);
3548  }
3549  }
3550  }
3551  else
3552  {
3553  /* send map-request */
3554  queue_map_request (&src, &dst, 0 /* smr_invoked */ ,
3555  0 /* is_resend */ );
3556  }
3557 
3558  drop:
3559  b0->error = node->errors[LISP_CP_LOOKUP_ERROR_DROP];
3560  next0 = LISP_CP_LOOKUP_NEXT_DROP;
3561  enqueue:
3562  if (PREDICT_FALSE (b0->flags & VLIB_BUFFER_IS_TRACED))
3563  {
3564  lisp_cp_lookup_trace_t *tr = vlib_add_trace (vm, node, b0,
3565  sizeof (*tr));
3566 
3567  clib_memset (tr, 0, sizeof (*tr));
3568  gid_address_copy (&tr->dst_eid, &dst);
3570  &lcm->active_map_resolver);
3571  }
3572  gid_address_free (&dst);
3573  gid_address_free (&src);
3574  vlib_validate_buffer_enqueue_x1 (vm, node, next_index,
3575  to_next,
3576  n_left_to_next, pi0, next0);
3577  }
3578 
3579  vlib_put_next_frame (vm, node, next_index, n_left_to_next);
3580  }
3581  return from_frame->n_vectors;
3582 }
3583 
3584 static uword
3586  vlib_node_runtime_t * node, vlib_frame_t * from_frame)
3587 {
3588  return (lisp_cp_lookup_inline (vm, node, from_frame, LISP_AFI_IP));
3589 }
3590 
3591 static uword
3593  vlib_node_runtime_t * node, vlib_frame_t * from_frame)
3594 {
3595  return (lisp_cp_lookup_inline (vm, node, from_frame, LISP_AFI_IP6));
3596 }
3597 
3598 static uword
3600  vlib_node_runtime_t * node, vlib_frame_t * from_frame)
3601 {
3602  return (lisp_cp_lookup_inline (vm, node, from_frame, LISP_AFI_MAC));
3603 }
3604 
3605 static uword
3607  vlib_node_runtime_t * node, vlib_frame_t * from_frame)
3608 {
3609  /* TODO decide if NSH should be propagated as LCAF or not */
3610  return (lisp_cp_lookup_inline (vm, node, from_frame, LISP_AFI_LCAF));
3611 }
3612 
3613 /* *INDENT-OFF* */
3615  .function = lisp_cp_lookup_ip4,
3616  .name = "lisp-cp-lookup-ip4",
3617  .vector_size = sizeof (u32),
3618  .format_trace = format_lisp_cp_lookup_trace,
3619  .type = VLIB_NODE_TYPE_INTERNAL,
3620 
3621  .n_errors = LISP_CP_LOOKUP_N_ERROR,
3622  .error_strings = lisp_cp_lookup_error_strings,
3623 
3624  .n_next_nodes = LISP_CP_LOOKUP_N_NEXT,
3625 
3626  .next_nodes = {
3627  [LISP_CP_LOOKUP_NEXT_DROP] = "error-drop",
3628  [LISP_CP_LOOKUP_NEXT_ARP_NDP_REPLY_TX] = "interface-output",
3629  },
3630 };
3631 /* *INDENT-ON* */
3632 
3633 /* *INDENT-OFF* */
3635  .function = lisp_cp_lookup_ip6,
3636  .name = "lisp-cp-lookup-ip6",
3637  .vector_size = sizeof (u32),
3638  .format_trace = format_lisp_cp_lookup_trace,
3639  .type = VLIB_NODE_TYPE_INTERNAL,
3640 
3641  .n_errors = LISP_CP_LOOKUP_N_ERROR,
3642  .error_strings = lisp_cp_lookup_error_strings,
3643 
3644  .n_next_nodes = LISP_CP_LOOKUP_N_NEXT,
3645 
3646  .next_nodes = {
3647  [LISP_CP_LOOKUP_NEXT_DROP] = "error-drop",
3648  [LISP_CP_LOOKUP_NEXT_ARP_NDP_REPLY_TX] = "interface-output",
3649  },
3650 };
3651 /* *INDENT-ON* */
3652 
3653 /* *INDENT-OFF* */
3655  .function = lisp_cp_lookup_l2,
3656  .name = "lisp-cp-lookup-l2",
3657  .vector_size = sizeof (u32),
3658  .format_trace = format_lisp_cp_lookup_trace,
3659  .type = VLIB_NODE_TYPE_INTERNAL,
3660 
3661  .n_errors = LISP_CP_LOOKUP_N_ERROR,
3662  .error_strings = lisp_cp_lookup_error_strings,
3663 
3664  .n_next_nodes = LISP_CP_LOOKUP_N_NEXT,
3665 
3666  .next_nodes = {
3667  [LISP_CP_LOOKUP_NEXT_DROP] = "error-drop",
3668  [LISP_CP_LOOKUP_NEXT_ARP_NDP_REPLY_TX] = "interface-output",
3669  },
3670 };
3671 /* *INDENT-ON* */
3672 
3673 /* *INDENT-OFF* */
3675  .function = lisp_cp_lookup_nsh,
3676  .name = "lisp-cp-lookup-nsh",
3677  .vector_size = sizeof (u32),
3678  .format_trace = format_lisp_cp_lookup_trace,
3679  .type = VLIB_NODE_TYPE_INTERNAL,
3680 
3681  .n_errors = LISP_CP_LOOKUP_N_ERROR,
3682  .error_strings = lisp_cp_lookup_error_strings,
3683 
3684  .n_next_nodes = LISP_CP_LOOKUP_N_NEXT,
3685 
3686  .next_nodes = {
3687  [LISP_CP_LOOKUP_NEXT_DROP] = "error-drop",
3688  [LISP_CP_LOOKUP_NEXT_ARP_NDP_REPLY_TX] = "interface-output",
3689  },
3690 };
3691 /* *INDENT-ON* */
3692 
3693 /* lisp_cp_input statistics */
3694 #define foreach_lisp_cp_input_error \
3695 _(DROP, "drop") \
3696 _(RLOC_PROBE_REQ_RECEIVED, "rloc-probe requests received") \
3697 _(RLOC_PROBE_REP_RECEIVED, "rloc-probe replies received") \
3698 _(MAP_NOTIFIES_RECEIVED, "map-notifies received") \
3699 _(MAP_REPLIES_RECEIVED, "map-replies received")
3700 
3702 #define _(sym,string) string,
3704 #undef _
3705 };
3706 
3707 typedef enum
3708 {
3709 #define _(sym,str) LISP_CP_INPUT_ERROR_##sym,
3711 #undef _
3714 
3715 typedef struct
3716 {
3720 
3721 u8 *
3722 format_lisp_cp_input_trace (u8 * s, va_list * args)
3723 {
3724  CLIB_UNUSED (vlib_main_t * vm) = va_arg (*args, vlib_main_t *);
3725  CLIB_UNUSED (vlib_node_t * node) = va_arg (*args, vlib_node_t *);
3727  va_arg (*args, lisp_cp_input_trace_t *);
3728 
3729  s = format (s, "LISP-CP-INPUT: TODO");
3730  return s;
3731 }
3732 
3733 static void
3735 {
3736  mapping_t *m;
3737  vnet_lisp_add_del_adjacency_args_t _adj_args, *adj_args = &_adj_args;
3738  clib_memset (adj_args, 0, sizeof (adj_args[0]));
3739 
3740  m = pool_elt_at_index (lcm->mapping_pool, mi);
3741 
3742  gid_address_copy (&adj_args->reid, &m->eid);
3743  adj_args->is_add = 0;
3744  if (vnet_lisp_add_del_adjacency (adj_args))
3745  clib_warning ("failed to del adjacency!");
3746 
3748  mapping_delete_timer (lcm, mi);
3749 }
3750 
3751 static void
3753  f64 expiration_time)
3754 {
3755  mapping_t *m;
3756  u64 now = clib_cpu_time_now ();
3757  u64 cpu_cps = lcm->vlib_main->clib_time.clocks_per_second;
3758  u64 exp_clock_time = now + expiration_time * cpu_cps;
3759 
3760  m = pool_elt_at_index (lcm->mapping_pool, mi);
3761 
3762  m->timer_set = 1;
3763  timing_wheel_insert (&lcm->wheel, exp_clock_time, mi);
3764 }
3765 
3766 static void
3768 {
3769  int rv;
3771  mapping_t *m = pool_elt_at_index (lcm->mapping_pool, mi);
3772  uword *fei;
3773  fwd_entry_t *fe;
3774  vlib_counter_t c;
3775  u8 have_stats = 0;
3776 
3777  if (m->delete_after_expiration)
3778  {
3779  remove_expired_mapping (lcm, mi);
3780  return;
3781  }
3782 
3783  fei = hash_get (lcm->fwd_entry_by_mapping_index, mi);
3784  if (!fei)
3785  return;
3786 
3787  fe = pool_elt_at_index (lcm->fwd_entry_pool, fei[0]);
3788 
3789  clib_memset (a, 0, sizeof (*a));
3790  a->rmt_eid = fe->reid;
3791  if (fe->is_src_dst)
3792  a->lcl_eid = fe->leid;
3793  a->vni = gid_address_vni (&fe->reid);
3794 
3795  rv = vnet_lisp_gpe_get_fwd_stats (a, &c);
3796  if (0 == rv)
3797  have_stats = 1;
3798 
3799  if (m->almost_expired)
3800  {
3801  m->almost_expired = 0; /* reset flag */
3802  if (have_stats)
3803  {
3804  if (m->packets != c.packets)
3805  {
3806  /* mapping is in use, re-fetch */
3807  map_request_args_t mr_args;
3808  clib_memset (&mr_args, 0, sizeof (mr_args));
3809  mr_args.seid = fe->leid;
3810  mr_args.deid = fe->reid;
3811 
3812  send_map_request_thread_fn (&mr_args);
3813  }
3814  else
3815  remove_expired_mapping (lcm, mi);
3816  }
3817  else
3818  remove_expired_mapping (lcm, mi);
3819  }
3820  else
3821  {
3822  m->almost_expired = 1;
3824 
3825  if (have_stats)
3826  /* save counter */
3827  m->packets = c.packets;
3828  else
3829  m->delete_after_expiration = 1;
3830  }
3831 }
3832 
3833 static void
3835 {
3837  mapping_t *m;
3838  vec_foreach (m, a->mappings)
3839  {
3840  vec_free (m->locators);
3841  gid_address_free (&m->eid);
3842  }
3844 }
3845 
3846 void *
3848 {
3849  mapping_t *m;
3851  u32 dst_map_index = 0;
3852  pending_map_request_t *pmr;
3853  u64 *noncep;
3854  uword *pmr_index;
3855  u8 is_changed = 0;
3856 
3857  if (a->is_rloc_probe)
3858  goto done;
3859 
3860  /* Check pending requests table and nonce */
3861  pmr_index = hash_get (lcm->pending_map_requests_by_nonce, a->nonce);
3862  if (!pmr_index)
3863  {
3864  clib_warning ("No pending map-request entry with nonce %lu!", a->nonce);
3865  goto done;
3866  }
3867  pmr = pool_elt_at_index (lcm->pending_map_requests_pool, pmr_index[0]);
3868 
3869  vec_foreach (m, a->mappings)
3870  {
3871  vnet_lisp_add_del_mapping_args_t _m_args, *m_args = &_m_args;
3872  clib_memset (m_args, 0, sizeof (m_args[0]));
3873  gid_address_copy (&m_args->eid, &m->eid);
3874  m_args->action = m->action;
3875  m_args->authoritative = m->authoritative;
3876  m_args->ttl = m->ttl;
3877  m_args->is_static = 0;
3878 
3879  /* insert/update mappings cache */
3880  vnet_lisp_add_mapping (m_args, m->locators, &dst_map_index, &is_changed);
3881 
3882  if (dst_map_index == (u32) ~ 0)
3883  continue;
3884 
3885  if (is_changed)
3886  {
3887  /* try to program forwarding only if mapping saved or updated */
3888  vnet_lisp_add_del_adjacency_args_t _adj_args, *adj_args = &_adj_args;
3889  clib_memset (adj_args, 0, sizeof (adj_args[0]));
3890 
3891  gid_address_copy (&adj_args->leid, &pmr->src);
3892  gid_address_copy (&adj_args->reid, &m->eid);
3893  adj_args->is_add = 1;
3894 
3895  if (vnet_lisp_add_del_adjacency (adj_args))
3896  clib_warning ("failed to add adjacency!");
3897  }
3898 
3899  if ((u32) ~ 0 != m->ttl)
3900  mapping_start_expiration_timer (lcm, dst_map_index,
3901  (m->ttl == 0) ? 0 : MAPPING_TIMEOUT);
3902  }
3903 
3904  /* remove pending map request entry */
3905 
3906  /* *INDENT-OFF* */
3907  clib_fifo_foreach (noncep, pmr->nonces, ({
3908  hash_unset(lcm->pending_map_requests_by_nonce, noncep[0]);
3909  }));
3910  /* *INDENT-ON* */
3911 
3912  clib_fifo_free (pmr->nonces);
3913  pool_put (lcm->pending_map_requests_pool, pmr);
3914 
3915 done:
3916  a->is_free = 1;
3917  return 0;
3918 }
3919 
3920 static int
3922  lisp_key_type_t key_id, u8 * key)
3923 {
3925  u8 *auth_data = 0;
3926  u16 auth_data_len;
3927  int result;
3928  vnet_crypto_op_t _op, *op = &_op;
3929  u8 out[EVP_MAX_MD_SIZE] = { 0, };
3930 
3931  auth_data_len = auth_data_len_by_key_id (key_id);
3932  if ((u16) ~ 0 == auth_data_len)
3933  {
3934  clib_warning ("invalid length for key_id %d!", key_id);
3935  return 0;
3936  }
3937 
3938  /* save auth data */
3939  vec_validate (auth_data, auth_data_len - 1);
3940  clib_memcpy (auth_data, MNOTIFY_DATA (h), auth_data_len);
3941 
3942  /* clear auth data */
3943  clib_memset (MNOTIFY_DATA (h), 0, auth_data_len);
3944 
3946  op->key = key;
3947  op->key_len = vec_len (key);
3948  op->len = msg_len;
3949  op->digest = out;
3950  op->src = (u8 *) h;
3951  op->digest_len = 0;
3952  op->iv = 0;
3953 
3954  vnet_crypto_process_ops (lcm->vlib_main, op, 1);
3955 
3956  result = memcmp (out, auth_data, auth_data_len);
3957 
3958  vec_free (auth_data);
3959 
3960  return !result;
3961 }
3962 
3963 static void
3965 {
3967  uword *pmr_index;
3968 
3969  pmr_index = hash_get (lcm->map_register_messages_by_nonce, a->nonce);
3970  if (!pmr_index)
3971  {
3972  clib_warning ("No pending map-register entry with nonce %lu!",
3973  a->nonce);
3974  return;
3975  }
3976 
3977  a->is_free = 1;
3978  pool_put_index (lcm->pending_map_registers_pool, pmr_index[0]);
3980 
3981  /* reset map-notify counter */
3982  lcm->expired_map_registers = 0;
3983 }
3984 
3985 static mapping_t *
3987 {
3988  u32 mi;
3989 
3991  if (~0 == mi)
3992  {
3993  clib_warning ("eid %U not found in map-cache!", unformat_gid_address,
3994  e);
3995  return 0;
3996  }
3997  return pool_elt_at_index (lcm->mapping_pool, mi);
3998 }
3999 
4000 /**
4001  * When map-notify is received it is necessary that all EIDs in the record
4002  * list share common key. The key is then used to verify authentication
4003  * data in map-notify message.
4004  */
4005 static int
4007  u32 key_id, u8 ** key_out)
4008 {
4009  u32 i, len = vec_len (maps);
4010  mapping_t *m;
4011 
4012  /* get key of the first mapping */
4013  m = get_mapping (lcm, &maps[0].eid);
4014  if (!m || !m->key)
4015  return -1;
4016 
4017  key_out[0] = m->key;
4018 
4019  for (i = 1; i < len; i++)
4020  {
4021  m = get_mapping (lcm, &maps[i].eid);
4022  if (!m || !m->key)
4023  return -1;
4024 
4025  if (key_id != m->key_id || vec_cmp (m->key, key_out[0]))
4026  {
4027  clib_warning ("keys does not match! %v, %v", key_out[0], m->key);
4028  return -1;
4029  }
4030  }
4031  return 0;
4032 }
4033 
4034 static int
4036 {
4037  locator_t *locators = 0;
4038  u32 i, len;
4039  gid_address_t deid;
4040  mapping_t m;
4041  locator_t *loc;
4042 
4043  clib_memset (&m, 0, sizeof (m));
4044 
4045  /* parse record eid */
4046  for (i = 0; i < count; i++)
4047  {
4048  locators = 0;
4049  len = lisp_msg_parse_mapping_record (b, &deid, &locators, NULL);
4050  if (len == ~0)
4051  {
4052  clib_warning ("Failed to parse mapping record!");
4053  vec_foreach (loc, locators) locator_free (loc);
4054  vec_free (locators);
4055  return -1;
4056  }
4057 
4058  m.locators = locators;
4059  gid_address_copy (&m.eid, &deid);
4060  vec_add1 (a->mappings, m);
4061  }
4062 
4063  return 0;
4064 }
4065 
4066 static map_records_arg_t *
4068 {
4070  map_records_arg_t *rec;
4071 
4072  /* Cleanup first */
4073  /* *INDENT-OFF* */
4075  if (rec->is_free)
4076  map_records_arg_free (rec);
4077  }));
4078  /* *INDENT-ON* */
4079 
4081  return rec;
4082 }
4083 
4084 static map_records_arg_t *
4086 {
4087  int rc = 0;
4088  map_notify_hdr_t *mnotif_hdr;
4089  lisp_key_type_t key_id;
4091  u8 *key = 0;
4092  gid_address_t deid;
4093  u16 auth_data_len = 0;
4094  u8 record_count;
4096 
4097  a = map_record_args_get ();
4098  clib_memset (a, 0, sizeof (*a));
4099  mnotif_hdr = vlib_buffer_get_current (b);
4100  vlib_buffer_pull (b, sizeof (*mnotif_hdr));
4101  clib_memset (&deid, 0, sizeof (deid));
4102 
4103  a->nonce = MNOTIFY_NONCE (mnotif_hdr);
4104  key_id = clib_net_to_host_u16 (MNOTIFY_KEY_ID (mnotif_hdr));
4105  auth_data_len = auth_data_len_by_key_id (key_id);
4106 
4107  /* advance buffer by authentication data */
4108  vlib_buffer_pull (b, auth_data_len);
4109 
4110  record_count = MNOTIFY_REC_COUNT (mnotif_hdr);
4111  rc = parse_map_records (b, a, record_count);
4112  if (rc != 0)
4113  {
4115  return 0;
4116  }
4117 
4118  rc = map_record_integrity_check (lcm, a->mappings, key_id, &key);
4119  if (rc != 0)
4120  {
4122  return 0;
4123  }
4124 
4125  /* verify authentication data */
4126  if (!is_auth_data_valid (mnotif_hdr, vlib_buffer_get_tail (b)
4127  - (u8 *) mnotif_hdr, key_id, key))
4128  {
4129  clib_warning ("Map-notify auth data verification failed for nonce "
4130  "0x%lx!", a->nonce);
4132  return 0;
4133  }
4134  return a;
4135 }
4136 
4137 static vlib_buffer_t *
4139  ip_address_t * dst, u64 nonce, u8 probe_bit,
4140  mapping_t * records, u16 dst_port, u32 * bi_res)
4141 {
4142  vlib_buffer_t *b;
4143  u32 bi;
4144  vlib_main_t *vm = lcm->vlib_main;
4145 
4146  if (vlib_buffer_alloc (vm, &bi, 1) != 1)
4147  {
4148  clib_warning ("Can't allocate buffer for Map-Register!");
4149  return 0;
4150  }
4151 
4152  b = vlib_get_buffer (vm, bi);
4153 
4154  /* leave some space for the encap headers */
4156 
4157  lisp_msg_put_map_reply (b, records, nonce, probe_bit);
4158 
4159  /* push outer ip header */
4160  pkt_push_udp_and_ip (vm, b, LISP_CONTROL_PORT, dst_port, sloc, dst, 1);
4161 
4162  bi_res[0] = bi;
4163  return b;
4164 }
4165 
4166 static int
4168  u8 probe_bit, u64 nonce, u16 dst_port,
4169  ip_address_t * probed_loc)
4170 {
4171  ip_address_t src;
4172  u32 bi;
4173  vlib_buffer_t *b;
4174  vlib_frame_t *f;
4175  u32 next_index, *to_next;
4176  mapping_t *records = 0, *m;
4177 
4178  m = pool_elt_at_index (lcm->mapping_pool, mi);
4179  if (!m)
4180  return -1;
4181 
4182  vec_add1 (records, m[0]);
4183  add_locators (lcm, &records[0], m->locator_set_index, probed_loc);
4184  clib_memset (&src, 0, sizeof (src));
4185 
4186  if (!ip_fib_get_first_egress_ip_for_dst (lcm, dst, &src))
4187  {
4188  clib_warning ("can't find interface address for %U", format_ip_address,
4189  dst);
4190  return -1;
4191  }
4192 
4193  b = build_map_reply (lcm, &src, dst, nonce, probe_bit, records, dst_port,
4194  &bi);
4195  if (!b)
4196  return -1;
4197  free_map_register_records (records);
4198 
4199  vnet_buffer (b)->sw_if_index[VLIB_TX] = 0;
4200  next_index = (ip_addr_version (&lcm->active_map_resolver) == IP4) ?
4201  ip4_lookup_node.index : ip6_lookup_node.index;
4202 
4203  f = vlib_get_frame_to_node (lcm->vlib_main, next_index);
4204 
4205  /* Enqueue the packet */
4206  to_next = vlib_frame_vector_args (f);
4207  to_next[0] = bi;
4208  f->n_vectors = 1;
4209  vlib_put_frame_to_node (lcm->vlib_main, next_index, f);
4210  return 0;
4211 }
4212 
4213 static void
4215 {
4216  const i32 start = vnet_buffer (b)->l3_hdr_offset;
4217  if (start < 0 && start < -sizeof (b->pre_data))
4218  {
4219  *ip_hdr = 0;
4220  return;
4221  }
4222 
4223  *ip_hdr = b->data + start;
4224  if ((u8 *) * ip_hdr > (u8 *) vlib_buffer_get_current (b))
4225  *ip_hdr = 0;
4226 }
4227 
4228 void
4230  lisp_cp_main_t * lcm, vlib_buffer_t * b)
4231 {
4232  u8 *ip_hdr = 0;
4233  ip_address_t *dst_loc = 0, probed_loc, src_loc;
4234  mapping_t m;
4235  map_request_hdr_t *mreq_hdr;
4237  u64 nonce;
4238  u32 i, len = 0, rloc_probe_recv = 0;
4239  gid_address_t *itr_rlocs = 0;
4240 
4241  mreq_hdr = vlib_buffer_get_current (b);
4242  if (!MREQ_SMR (mreq_hdr) && !MREQ_RLOC_PROBE (mreq_hdr))
4243  {
4244  clib_warning
4245  ("Only SMR Map-Requests and RLOC probe supported for now!");
4246  return;
4247  }
4248 
4249  vlib_buffer_pull (b, sizeof (*mreq_hdr));
4250  nonce = MREQ_NONCE (mreq_hdr);
4251 
4252  /* parse src eid */
4253  len = lisp_msg_parse_addr (b, &src);
4254  if (len == ~0)
4255  return;
4256 
4257  len = lisp_msg_parse_itr_rlocs (b, &itr_rlocs,
4258  MREQ_ITR_RLOC_COUNT (mreq_hdr) + 1);
4259  if (len == ~0)
4260  goto done;
4261 
4262  /* parse eid records and send SMR-invoked map-requests */
4263  for (i = 0; i < MREQ_REC_COUNT (mreq_hdr); i++)
4264  {
4265  clib_memset (&dst, 0, sizeof (dst));
4266  len = lisp_msg_parse_eid_rec (b, &dst);
4267  if (len == ~0)
4268  {
4269  clib_warning ("Can't parse map-request EID-record");
4270  goto done;
4271  }
4272 
4273  if (MREQ_SMR (mreq_hdr))
4274  {
4275  /* send SMR-invoked map-requests */
4276  queue_map_request (&dst, &src, 1 /* invoked */ , 0 /* resend */ );
4277  }
4278  else if (MREQ_RLOC_PROBE (mreq_hdr))
4279  {
4280  find_ip_header (b, &ip_hdr);
4281  if (!ip_hdr)
4282  {
4283  clib_warning ("Cannot find the IP header!");
4284  goto done;
4285  }
4286  rloc_probe_recv++;
4287  clib_memset (&m, 0, sizeof (m));
4288  u32 mi = gid_dictionary_lookup (&lcm->mapping_index_by_gid, &dst);
4289 
4290  // TODO: select best locator; for now use the first one
4291  dst_loc = &gid_address_ip (&itr_rlocs[0]);
4292 
4293  /* get src/dst IP addresses */
4294  get_src_and_dst_ip (ip_hdr, &src_loc, &probed_loc);
4295 
4296  // TODO get source port from buffer
4298 
4299  send_map_reply (lcm, mi, dst_loc, 1 /* probe-bit */ , nonce,
4300  src_port, &probed_loc);
4301  }
4302  }
4303 
4304 done:
4306  LISP_CP_INPUT_ERROR_RLOC_PROBE_REQ_RECEIVED,
4307  rloc_probe_recv);
4308  vec_free (itr_rlocs);
4309 }
4310 
4313 {
4314  locator_t probed;
4315  gid_address_t deid;
4316  void *h;
4317  u32 i, len = 0;
4318  mapping_t m;
4319  map_reply_hdr_t *mrep_hdr;
4321 
4322  a = map_record_args_get ();
4323  clib_memset (a, 0, sizeof (*a));
4324 
4325  locator_t *locators;
4326 
4327  mrep_hdr = vlib_buffer_get_current (b);
4328  a->nonce = MREP_NONCE (mrep_hdr);
4329  a->is_rloc_probe = MREP_RLOC_PROBE (mrep_hdr);
4330  if (!vlib_buffer_has_space (b, sizeof (*mrep_hdr)))
4331  {
4332  clib_mem_free (a);
4333  return 0;
4334  }
4335  vlib_buffer_pull (b, sizeof (*mrep_hdr));
4336 
4337  for (i = 0; i < MREP_REC_COUNT (mrep_hdr); i++)
4338  {
4339  clib_memset (&m, 0, sizeof (m));
4340  locators = 0;
4341  h = vlib_buffer_get_current (b);
4342 
4343  m.ttl = clib_net_to_host_u32 (MAP_REC_TTL (h));
4344  m.action = MAP_REC_ACTION (h);
4345  m.authoritative = MAP_REC_AUTH (h);
4346 
4347  len = lisp_msg_parse_mapping_record (b, &deid, &locators, &probed);
4348  if (len == ~0)
4349  {
4350  clib_warning ("Failed to parse mapping record!");
4352  return 0;
4353  }
4354 
4355  m.locators = locators;
4356  gid_address_copy (&m.eid, &deid);
4357  vec_add1 (a->mappings, m);
4358  }
4359  return a;
4360 }
4361 
4362 static void
4364 {
4365  vl_api_rpc_call_main_thread (process_map_reply, (u8 *) a, sizeof (*a));
4366 }
4367 
4368 static void
4370 {
4371  vl_api_rpc_call_main_thread (process_map_notify, (u8 *) a, sizeof (a[0]));
4372 }
4373 
4374 static uword
4376  vlib_frame_t * from_frame)
4377 {
4378  u32 n_left_from, *from, *to_next_drop, rloc_probe_rep_recv = 0,
4379  map_notifies_recv = 0;
4380  lisp_msg_type_e type;
4383 
4384  from = vlib_frame_vector_args (from_frame);
4385  n_left_from = from_frame->n_vectors;
4386 
4387 
4388  while (n_left_from > 0)
4389  {
4390  u32 n_left_to_next_drop;
4391 
4393  to_next_drop, n_left_to_next_drop);
4394  while (n_left_from > 0 && n_left_to_next_drop > 0)
4395  {
4396  u32 bi0;
4397  vlib_buffer_t *b0;
4398 
4399  bi0 = from[0];
4400  from += 1;
4401  n_left_from -= 1;
4402  to_next_drop[0] = bi0;
4403  to_next_drop += 1;
4404  n_left_to_next_drop -= 1;
4405 
4406  b0 = vlib_get_buffer (vm, bi0);
4407 
4408  type = lisp_msg_type (vlib_buffer_get_current (b0));
4409  switch (type)
4410  {
4411  case LISP_MAP_REPLY:
4412  a = parse_map_reply (b0);
4413  if (a)
4414  {
4415  if (a->is_rloc_probe)
4416  rloc_probe_rep_recv++;
4418  }
4419  break;
4420  case LISP_MAP_REQUEST:
4421  process_map_request (vm, node, lcm, b0);
4422  break;
4423  case LISP_MAP_NOTIFY:
4424  a = parse_map_notify (b0);
4425  if (a)
4426  {
4427  map_notifies_recv++;
4429  }
4430  break;
4431  default:
4432  clib_warning ("Unsupported LISP message type %d", type);
4433  break;
4434  }
4435 
4436  b0->error = node->errors[LISP_CP_INPUT_ERROR_DROP];
4437 
4438  if (PREDICT_FALSE (b0->flags & VLIB_BUFFER_IS_TRACED))
4439  {
4440 
4441  }
4442  }
4443 
4445  n_left_to_next_drop);
4446  }
4448  LISP_CP_INPUT_ERROR_RLOC_PROBE_REP_RECEIVED,
4449  rloc_probe_rep_recv);
4451  LISP_CP_INPUT_ERROR_MAP_NOTIFIES_RECEIVED,
4452  map_notifies_recv);
4453  return from_frame->n_vectors;
4454 }
4455 
4456 /* *INDENT-OFF* */
4458  .function = lisp_cp_input,
4459  .name = "lisp-cp-input",
4460  .vector_size = sizeof (u32),
4461  .format_trace = format_lisp_cp_input_trace,
4462  .type = VLIB_NODE_TYPE_INTERNAL,
4463 
4464  .n_errors = LISP_CP_INPUT_N_ERROR,
4465  .error_strings = lisp_cp_input_error_strings,
4466 
4467  .n_next_nodes = LISP_CP_INPUT_N_NEXT,
4468 
4469  .next_nodes = {
4470  [LISP_CP_INPUT_NEXT_DROP] = "error-drop",
4471  },
4472 };
4473 /* *INDENT-ON* */
4474 
4475 clib_error_t *
4477 {
4479  clib_error_t *error = 0;
4481  u32 num_threads;
4482 
4483  if ((error = vlib_call_init_function (vm, lisp_gpe_init)))
4484  return error;
4485 
4486  lcm->im4 = &ip4_main;
4487  lcm->im6 = &ip6_main;
4488  lcm->vlib_main = vm;
4489  lcm->vnet_main = vnet_get_main ();
4490  lcm->mreq_itr_rlocs = ~0;
4491  lcm->flags = 0;
4492  lcm->pitr_map_index = ~0;
4493  lcm->petr_map_index = ~0;
4494  clib_memset (&lcm->active_map_resolver, 0,
4495  sizeof (lcm->active_map_resolver));
4496  clib_memset (&lcm->active_map_server, 0, sizeof (lcm->active_map_server));
4497 
4499  lcm->do_map_resolver_election = 1;
4500  lcm->do_map_server_election = 1;
4502 
4503  num_threads = 1 /* main thread */ + vtm->n_threads;
4504  vec_validate (lcm->map_records_args_pool, num_threads - 1);
4505 
4506  /* default vrf mapped to vni 0 */
4507  hash_set (lcm->table_id_by_vni, 0, 0);
4508  hash_set (lcm->vni_by_table_id, 0, 0);
4509 
4510  u64 now = clib_cpu_time_now ();
4512  lcm->nsh_map_index = ~0;
4515  lcm->expired_map_registers = 0;
4517  lcm->flags |= LISP_FLAG_XTR_MODE;
4518  return 0;
4519 }
4520 
4521 static int
4524  u32 stats_index)
4525 {
4526  vlib_counter_t v;
4528  lisp_gpe_fwd_entry_key_t fwd_key;
4529  const lisp_gpe_tunnel_t *lgt;
4530  fwd_entry_t *fe;
4531 
4532  clib_memset (stat, 0, sizeof (*stat));
4533  clib_memset (&fwd_key, 0, sizeof (fwd_key));
4534 
4536  ASSERT (fe != 0);
4537 
4538  gid_to_dp_address (&fe->reid, &stat->deid);
4539  gid_to_dp_address (&fe->leid, &stat->seid);
4540  stat->vni = gid_address_vni (&fe->reid);
4541 
4542  lgt = lisp_gpe_tunnel_get (key->tunnel_index);
4543  stat->loc_rloc = lgt->key->lcl;
4544  stat->rmt_rloc = lgt->key->rmt;
4545 
4546  vlib_get_combined_counter (cm, stats_index, &v);
4547  stat->counters = v;
4548  return 1;
4549 }
4550 
4553 {
4556  lisp_api_stats_t *stats = 0, stat;
4558  u32 index;
4559 
4560  /* *INDENT-OFF* */
4561  hash_foreach_mem (key, index, lgm->lisp_stats_index_by_key,
4562  {
4563  if (lisp_stats_api_fill (lcm, lgm, &stat, key, index))
4564  vec_add1 (stats, stat);
4565  });
4566  /* *INDENT-ON* */
4567 
4568  return stats;
4569 }
4570 
4571 static void *
4573 {
4574  map_request_args_t *a = arg;
4576 
4577  if (a->is_resend)
4579  else
4580  send_encapsulated_map_request (lcm, &a->seid, &a->deid, a->smr_invoked);
4581 
4582  return 0;
4583 }
4584 
4585 static int
4587  u8 smr_invoked, u8 is_resend)
4588 {
4590 
4591  a.is_resend = is_resend;
4592  gid_address_copy (&a.seid, seid);
4593  gid_address_copy (&a.deid, deid);
4594  a.smr_invoked = smr_invoked;
4595 
4597  (u8 *) & a, sizeof (a));
4598  return 0;
4599 }
4600 
4601 /**
4602  * Take an action with a pending map request depending on expiration time
4603  * and re-try counters.
4604  */
4605 static void
4607 {
4609  lisp_msmr_t *mr;
4610 
4611  if (r->time_to_expire - dt < 0)
4612  /* it's time to decide what to do with this pending request */
4613  {
4614  if (r->retries_num >= NUMBER_OF_RETRIES)
4615  /* too many retries -> assume current map resolver is not available */
4616  {
4618  if (!mr)
4619  {
4620  clib_warning ("Map resolver %U not found - probably deleted "
4621  "by the user recently.", format_ip_address,
4622  &lcm->active_map_resolver);
4623  }
4624  else
4625  {
4626  clib_warning ("map resolver %U is unreachable, ignoring",
4628 
4629  /* mark current map resolver unavailable so it won't be
4630  * selected next time */
4631  mr->is_down = 1;
4632  mr->last_update = vlib_time_now (lcm->vlib_main);
4633  }
4634 
4636  elect_map_resolver (lcm);
4637 
4638  /* try to find a next eligible map resolver and re-send */
4639  queue_map_request (&r->src, &r->dst, r->is_smr_invoked,
4640  1 /* resend */ );
4641  }
4642  else
4643  {
4644  /* try again */
4645  queue_map_request (&r->src, &r->dst, r->is_smr_invoked,
4646  1 /* resend */ );
4647  r->retries_num++;
4649  }
4650  }
4651  else
4652  r->time_to_expire -= dt;
4653 }
4654 
4655 static void
4657 {
4658  u64 *nonce;
4659  pending_map_request_t *pmr;
4660  u32 *to_be_removed = 0, *pmr_index;
4661 
4662  /* *INDENT-OFF* */
4664  ({
4665  if (pmr->to_be_removed)
4666  {
4667  clib_fifo_foreach (nonce, pmr->nonces, ({
4668  hash_unset (lcm->pending_map_requests_by_nonce, nonce[0]);
4669  }));
4670 
4671  vec_add1 (to_be_removed, pmr - lcm->pending_map_requests_pool);
4672  }
4673  }));
4674  /* *INDENT-ON* */
4675 
4676  vec_foreach (pmr_index, to_be_removed)
4677  pool_put_index (lcm->pending_map_requests_pool, pmr_index[0]);
4678 
4679  vec_free (to_be_removed);
4680 }
4681 
4682 static void
4684 {
4685  static f64 time_left = RLOC_PROBING_INTERVAL;
4686 
4687  if (!lcm->is_enabled || !lcm->rloc_probing)
4688  return;
4689 
4690  time_left -= dt;
4691  if (time_left <= 0)
4692  {
4693  time_left = RLOC_PROBING_INTERVAL;
4694  send_rloc_probes (lcm);
4695  }
4696 }
4697 
4698 static int
4700 {
4702  lisp_msmr_t *ms;
4703  del_all[0] = 0;
4704 
4705  r->time_to_expire -= dt;
4706 
4707  if (r->time_to_expire < 0)
4708  {
4709  lcm->expired_map_registers++;
4710 
4712  {
4713  ms = get_map_server (&lcm->active_map_server);
4714  if (!ms)
4715  {
4716  clib_warning ("Map server %U not found - probably deleted "
4717  "by the user recently.", format_ip_address,
4718  &lcm->active_map_server);
4719  }
4720  else
4721  {
4722  clib_warning ("map server %U is unreachable, ignoring",
4724 
4725  /* mark current map server unavailable so it won't be
4726  * elected next time */
4727  ms->is_down = 1;
4728  ms->last_update = vlib_time_now (lcm->vlib_main);
4729  }
4730 
4731  elect_map_server (lcm);
4732 
4733  /* indication for deleting all pending map registers */
4734  del_all[0] = 1;
4735  lcm->expired_map_registers = 0;
4736  return 0;
4737  }
4738  else
4739  {
4740  /* delete pending map register */
4741  return 0;
4742  }
4743  }
4744  return 1;
4745 }
4746 
4747 static void
4749 {
4750  u32 *to_be_removed = 0, *pmr_index;
4751  static f64 time_left = QUICK_MAP_REGISTER_INTERVAL;
4752  static u64 mreg_sent_counter = 0;
4753 
4755  u8 del_all = 0;
4756 
4757  if (!lcm->is_enabled || !lcm->map_registering)
4758  return;
4759 
4760  /* *INDENT-OFF* */
4762  ({
4763  if (!update_pending_map_register (pmr, dt, &del_all))
4764  {
4765  if (del_all)
4766  break;
4767  vec_add1 (to_be_removed, pmr - lcm->pending_map_registers_pool);
4768  }
4769  }));
4770  /* *INDENT-ON* */
4771 
4772  if (del_all)
4773  {
4774  /* delete all pending map register messages so they won't
4775  * trigger another map server election.. */
4776  pool_free (lcm->pending_map_registers_pool);
4777  hash_free (lcm->map_register_messages_by_nonce);
4778 
4779  /* ..and trigger registration against next map server (if any) */
4780  time_left = 0;
4781  }
4782  else
4783  {
4784  vec_foreach (pmr_index, to_be_removed)
4785  pool_put_index (lcm->pending_map_registers_pool, pmr_index[0]);
4786  }
4787 
4788  vec_free (to_be_removed);
4789 
4790  time_left -= dt;
4791  if (time_left <= 0)
4792  {
4793  if (mreg_sent_counter >= QUICK_MAP_REGISTER_MSG_COUNT)
4794  time_left = MAP_REGISTER_INTERVAL;
4795  else
4796  {
4797  mreg_sent_counter++;
4798  time_left = QUICK_MAP_REGISTER_INTERVAL;
4799  }
4800  send_map_register (lcm, 1 /* want map notify */ );
4801  }
4802 }
4803 
4804 static uword
4807 {
4808  u32 *expired = 0;
4809  f64 period = 2.0;
4810  pending_map_request_t *pmr;
4812 
4813  while (1)
4814  {
4816 
4817  /* currently no signals are expected - just wait for clock */
4818  (void) vlib_process_get_events (vm, 0);
4819 
4820  /* *INDENT-OFF* */
4822  ({
4823  if (!pmr->to_be_removed)
4824  update_pending_request (pmr, period);
4825  }));
4826  /* *INDENT-ON* */
4827 
4829 
4830  update_map_register (lcm, period);
4831  update_rloc_probing (lcm, period);
4832 
4833  u64 now = clib_cpu_time_now ();
4834 
4835  expired = timing_wheel_advance (&lcm->wheel, now, expired, 0);
4836  if (vec_len (expired) > 0)
4837  {
4838  u32 *mi = 0;
4839  vec_foreach (mi, expired)
4840  {
4841  process_expired_mapping (lcm, mi[0]);
4842  }
4843  _vec_len (expired) = 0;
4844  }
4845  }
4846 
4847  /* unreachable */
4848  return 0;
4849 }
4850 
4853 {
4855 
4856  if (vnet_lisp_enable_disable_status () == 0)
4857  return VNET_API_ERROR_LISP_DISABLED;
4858 
4859  if (enable)
4860  lcm->flags |= LISP_FLAG_STATS_ENABLED;
4861  else
4862  lcm->flags &= ~LISP_FLAG_STATS_ENABLED;
4863 
4864  return 0;
4865 }
4866 
4867 u8
4869 {
4871 
4872  if (vnet_lisp_enable_disable_status () == 0)
4873  return VNET_API_ERROR_LISP_DISABLED;
4874 
4875  return lcm->flags & LISP_FLAG_STATS_ENABLED;
4876 }
4877 
4878 /* *INDENT-OFF* */
4880  .function = send_map_resolver_service,
4881  .type = VLIB_NODE_TYPE_PROCESS,
4882  .name = "lisp-retry-service",
4883  .process_log2_n_stack_bytes = 16,
4884 };
4885 /* *INDENT-ON* */
4886 
4887 u32
4889 {
4891 
4892  if (protocol < LISP_TRANSPORT_PROTOCOL_UDP ||
4893  protocol > LISP_TRANSPORT_PROTOCOL_API)
4894  return VNET_API_ERROR_INVALID_ARGUMENT;
4895 
4897  return 0;
4898 }
4899 
4902 {
4904  return lcm->transport_protocol;
4905 }
4906 
4907 int
4909 {
4911  u8 pitr_mode = lcm->flags & LISP_FLAG_PITR_MODE;
4912  u8 xtr_mode = lcm->flags & LISP_FLAG_XTR_MODE;
4913  u8 petr_mode = lcm->flags & LISP_FLAG_PETR_MODE;
4914 
4915  if (pitr_mode && is_enabled)
4916  return VNET_API_ERROR_INVALID_ARGUMENT;
4917 
4918  if (is_enabled && xtr_mode)
4919  return 0;
4920  if (!is_enabled && !xtr_mode)
4921  return 0;
4922 
4923  if (is_enabled)
4924  {
4925  if (!petr_mode)
4926  {
4928  }
4929  lisp_cp_enable_l2_l3_ifaces (lcm, 1 /* with_default_route */ );
4930  lcm->flags |= LISP_FLAG_XTR_MODE;
4931  }
4932  else
4933  {
4934  if (!petr_mode)
4935  {
4937  }
4939  lcm->flags &= ~LISP_FLAG_XTR_MODE;
4940  }
4941  return 0;
4942 }
4943 
4944 int
4946 {
4948  u8 xtr_mode = lcm->flags & LISP_FLAG_XTR_MODE;
4949  u8 pitr_mode = lcm->flags & LISP_FLAG_PITR_MODE;
4950 
4951  if (xtr_mode && is_enabled)
4952  return VNET_API_ERROR_INVALID_VALUE;
4953 
4954  if (is_enabled && pitr_mode)
4955  return 0;
4956  if (!is_enabled && !pitr_mode)
4957  return 0;
4958 
4959  if (is_enabled)
4960  {
4961  /* create iface, no default route */
4962  lisp_cp_enable_l2_l3_ifaces (lcm, 0 /* with_default_route */ );
4963  lcm->flags |= LISP_FLAG_PITR_MODE;
4964  }
4965  else
4966  {
4968  lcm->flags &= ~LISP_FLAG_PITR_MODE;
4969  }
4970  return 0;
4971 }
4972 
4973 int
4975 {
4977  u8 xtr_mode = lcm->flags & LISP_FLAG_XTR_MODE;
4978  u8 petr_mode = lcm->flags & LISP_FLAG_PETR_MODE;
4979 
4980  if (is_enabled && petr_mode)
4981  return 0;
4982  if (!is_enabled && !petr_mode)
4983  return 0;
4984 
4985  if (is_enabled)
4986  {
4987  if (!xtr_mode)
4988  {
4990  }
4991  lcm->flags |= LISP_FLAG_PETR_MODE;
4992  }
4993  else
4994  {
4995  if (!xtr_mode)
4996  {
4998  }
4999  lcm->flags &= ~LISP_FLAG_PETR_MODE;
5000  }
5001  return 0;
5002 }
5003 
5004 u8
5006 {
5008  return (lcm->flags & LISP_FLAG_XTR_MODE);
5009 }
5010 
5011 u8
5013 {
5015  return (lcm->flags & LISP_FLAG_PITR_MODE);
5016 }
5017 
5018 u8
5020 {
5022  return (lcm->flags & LISP_FLAG_PETR_MODE);
5023 }
5024 
5026 
5027 /*
5028  * fd.io coding-style-patch-verification: ON
5029  *
5030  * Local Variables:
5031  * eval: (c-set-style "gnu")
5032  * End:
5033  */
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
u32 sw_if_index
Definition: ipsec_gre.api:37
#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:4375
#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:30
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:2959
vnet_api_error_t
Definition: api_errno.h:153
#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:115
boost::asio::ip::address ip_address_t
Definition: api_types.hpp:25
#define clib_fifo_head(v)
Definition: fifo.h:254
u8 vnet_lisp_get_pitr_mode(void)
Definition: control.c:5012
#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:3614
map_records_arg_t * parse_map_reply(vlib_buffer_t *b)
Definition: control.c:4312
static void mapping_start_expiration_timer(lisp_cp_main_t *lcm, u32 mi, f64 expiration_time)
Definition: control.c:3752
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
#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:4229
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:2429
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:47
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:3717
u32 vnet_lisp_set_transport_protocol(u8 protocol)
Definition: control.c:4888
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_)
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:2569
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:4369
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.
clib_error_t * vnet_lisp_gpe_enable_disable(vnet_lisp_gpe_enable_disable_args_t *a)
Enable/disable LISP-GPE.
Definition: lisp_gpe.c:193
#define NULL
Definition: clib.h:58
clib_memset(h->entries, 0, sizeof(h->entries[0]) *entries)
#define MAPPING_TIMEOUT
Definition: control.c:35
#define foreach_lisp_cp_input_error
Definition: control.c:3694
static uword lisp_cp_lookup_nsh(vlib_main_t *vm, vlib_node_runtime_t *node, vlib_frame_t *from_frame)
Definition: control.c:3606
u32 * local_mappings_indexes
Definition: control.h:192
static f64 vlib_time_now(vlib_main_t *vm)
Definition: main.h:255
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:3674
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:2848
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
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:3701
ip_lookup_main_t lookup_main
Definition: ip4.h:98
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
vl_api_ip4_address_t dst
Definition: ipsec_gre.api:39
static void remove_dead_pending_map_requests(lisp_cp_main_t *lcm)
Definition: control.c:4656
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:4852
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:4699
uword * vni_by_table_id
Definition: control.h:240
static void * send_map_request_thread_fn(void *arg)
Definition: control.c:4572
#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:121
ip6_address_t src_address
Definition: ip6_packet.h:385
u8 vnet_lisp_stats_enable_disable_state(void)
Definition: control.c:4868
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:4167
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:5019
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:2833
#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:104
#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:2745
lisp_msmr_t * map_servers
Definition: control.h:223
lisp_transport_protocol_t vnet_lisp_get_transport_protocol(void)
Definition: control.c:4901
#define MREQ_NONCE(h_)
int vnet_lisp_enable_disable_petr_mode(u8 is_enabled)
Definition: control.c:4974
static lisp_gpe_main_t * vnet_lisp_gpe_get_main()
Definition: lisp_gpe.h:183
static void add_ndp_entry(BVT(clib_bihash_kv) *kvp, void *arg)
Definition: control.c:990
static void reset_pending_mr_counters(pending_map_request_t *r)
Definition: control.c:2625
u32 ** locator_to_locator_sets
Definition: control.h:183
vlib_main_t * vlib_main
Definition: control.h:287
u32 gid_dictionary_add_del(gid_dictionary_t *db, gid_address_t *key, u64 value, u8 is_add)
void gid_dict_foreach_l2_arp_ndp_entry(gid_dictionary_t *db, void(*cb)(BVT(clib_bihash_kv) *kvp, void *arg), void *ht)
int vnet_lisp_enable_disable_pitr_mode(u8 is_enabled)
Definition: control.c:4945
#define pool_foreach(VAR, POOL, BODY)
Iterate through pool.
Definition: pool.h:493
ethernet_arp_ip4_over_ethernet_address_t ip4_over_ethernet[2]
Definition: arp_packet.h:141
#define VLIB_INIT_FUNCTION(x)
Definition: init.h:163
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:190
#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:623
static mapping_t * get_mapping(lisp_cp_main_t *lcm, gid_address_t *e)
Definition: control.c:3986
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:301
u16 fp_len
The mask length.
Definition: fib_types.h:207
#define vlib_call_init_function(vm, x)
Definition: init.h:260
u8 do_map_server_election
Definition: control.h:233
uword * vni_by_bd_id
Definition: control.h:244
u8 delete_after_expiration
Definition: lisp_types.h:368
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:286
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:4606
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:3634
static void add_locators(lisp_cp_main_t *lcm, mapping_t *m, u32 locator_set_index, ip_address_t *probed_loc)
Definition: control.c:2663
Definition: fib_entry.h:280
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
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:4363
#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:2421
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
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:2456
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)
static vlib_node_registration_t lisp_retry_service_node
(constructor) VLIB_REGISTER_NODE (lisp_retry_service_node)
Definition: control.c:4879
vlib_node_registration_t lisp_cp_input_node
(constructor) VLIB_REGISTER_NODE (lisp_cp_input_node)
Definition: control.c:4457
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:3654
#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:130
u8 authoritative
Definition: lisp_types.h:361
lisp_api_stats_t * vnet_lisp_get_stats(void)
Definition: control.c:4552
static void remove_expired_mapping(lisp_cp_main_t *lcm, u32 mi)
Definition: control.c:3734
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:4006
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:684
#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:3585
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:2408
u8 vnet_lisp_get_xtr_mode(void)
Definition: control.c:5005
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:2856
vl_api_ip4_address_t src
Definition: ipsec_gre.api:38
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
#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:2439
#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:3964
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:4586
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:49
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:1461
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:4476
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:3722
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:4138
#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:3599
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:2377
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:212
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
static void add_l2_arp_bd(BVT(clib_bihash_kv) *kvp, void *arg)
Definition: control.c:903
int gid_address_cmp(gid_address_t *a1, gid_address_t *a2)
Definition: lisp_types.c: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:522
static map_records_arg_t * parse_map_notify(vlib_buffer_t *b)
Definition: control.c:4085
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
#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:1702
static void update_map_register(lisp_cp_main_t *lcm, f64 dt)
Definition: control.c:4748
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:3718
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:2875
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:412
#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:2307
#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:4908
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:947
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:4805
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:1040
u16 cached_next_index
Next frame index that vector arguments were last enqueued to last time this node ran.
Definition: node.h:513
#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:270
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:2912
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:2631
int vnet_lisp_clear_all_remote_adjacencies(void)
Definition: control.c:1422
ip6_main_t ip6_main
Definition: ip6_forward.c:2688
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
u8 is_add
Definition: ipsec_gre.api:36
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:3204
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:3223
locator_set_t * locator_set_pool
Definition: control.h:180
static void clib_mem_free(void *p)
Definition: mem.h:205
option version
Definition: memclnt.api:17
u8 is_static
Definition: lisp_types.h:364
static void add_ndp_bd(BVT(clib_bihash_kv) *kvp, void *arg)
Definition: control.c:926
u8 is_src_dst
Definition: lisp_gpe.h:232
static void gid_address_sd_to_flat(gid_address_t *dst, gid_address_t *src, fid_address_t *fid)
Definition: control.c:384
#define gid_address_ndp_bd
Definition: lisp_types.h: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:2729
#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)
#define foreach_lisp_cp_output_error
Definition: control.c:2829
#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:57
#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
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:3246
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:3262
#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:2769
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:1720
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:2415
#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:244
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:430
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:4067
static gid_address_t * build_itr_rloc_list(lisp_cp_main_t *lcm, locator_set_t *loc_set)
Definition: control.c:2487
static void add_l2_arp_entry(BVT(clib_bihash_kv) *kvp, void *arg)
Definition: control.c:955
l2_bridge_domain_t * bd_configs
Definition: l2_input.h: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:2536
gid_address_t eid
Definition: lisp_types.h:349
typedef prefix
Definition: ip_types.api:35
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
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:369
vnet_crypto_op_id_t
Definition: crypto.h:87
gid_address_t dst
Definition: control.h:50
static void map_records_arg_free(map_records_arg_t *a)
Definition: control.c:3834
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:3278
int vnet_lisp_add_del_map_resolver(vnet_lisp_add_del_map_resolver_args_t *a)
Definition: control.c:2314
ip4_main_t ip4_main
Global ip4 main structure.
Definition: ip4_forward.c:905
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:4214
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:3767
#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:363
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:4683
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:484
#define gid_address_arp_ip4(_a)
Definition: lisp_types.h:283
void * process_map_reply(map_records_arg_t *a)
Definition: control.c:3847
u16 dst_port
Definition: udp.api:42
gid_address_t dst_eid
Definition: control.c:2438
static int parse_map_records(vlib_buffer_t *b, map_records_arg_t *a, u8 count)
Definition: control.c:4035
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
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:2362
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:2370
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:1727
static uword lisp_cp_lookup_ip6(vlib_main_t *vm, vlib_node_runtime_t *node, vlib_frame_t *from_frame)
Definition: control.c:3592
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
vl_api_mac_address_t mac
Definition: gbp.api:120
u32 mreq_itr_rlocs
Definition: control.h:236
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:2654
u32 * locator_indices
Definition: lisp_types.h:343
#define send_encapsulated_map_request(lcm, seid, deid, smr)
Definition: control.c:3036
vnet_main_t * vnet_main
Definition: control.h:288
#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:3921
A LISP GPE Tunnel.
static mapping_t * build_map_register_record_list(lisp_cp_main_t *lcm)
Definition: control.c:2708
u8 * format_lisp_cp_lookup_trace(u8 *s, va_list *args)
Definition: control.c:2443
#define MAP_REGISTER_DEFAULT_TTL
Definition: control.h:45
ip4_main_t * im4
Definition: control.h:285
gid_address_t leid
Definition: control.h:65
Definition: defs.h:46
lisp_msg_type_e
u8 protocol
Definition: ipsec.api:96
#define ip_prefix_addr(_a)
Definition: lisp_types.h:71
ip6_address_t dst_address
Definition: ip6_packet.h:385
#define resend_encapsulated_map_request(lcm, seid, deid, smr)
Definition: control.c:3039
lisp_cp_output_error_t
Definition: control.c:2839
#define PENDING_MREQ_EXPIRATION_TIME
Definition: control.h:25
static int lisp_stats_api_fill(lisp_cp_main_t *lcm, lisp_gpe_main_t *lgm, lisp_api_stats_t *stat, lisp_stats_key_t *key, u32 stats_index)
Definition: control.c:4522
locator_t * locators
Definition: lisp_types.h:355
lisp_cp_input_error_t
Definition: control.c:3707
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:3408
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:301