FD.io VPP  v20.09-rc2-28-g3c5414029
Vector Packet Processing
lisp_gpe_fwd_entry.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 
20 #include <vnet/fib/fib_table.h>
21 #include <vnet/fib/fib_entry.h>
22 #include <vnet/fib/fib_path_list.h>
23 #include <vnet/fib/ip6_fib.h>
24 #include <vnet/fib/ip4_fib.h>
25 #include <vnet/dpo/drop_dpo.h>
26 #include <vnet/dpo/lookup_dpo.h>
27 #include <vnet/dpo/load_balance.h>
28 #include <vnet/adj/adj_midchain.h>
29 
30 /**
31  * @brief Add route to IP4 or IP6 Destination FIB.
32  *
33  * Add a route to the destination FIB that results in the lookup
34  * in the SRC FIB. The SRC FIB is created is it does not yet exist.
35  *
36  * @param[in] dst_table_id Destination FIB Table-ID
37  * @param[in] dst_prefix Destination IP prefix.
38  *
39  * @return src_fib_index The index/ID of the SRC FIB created.
40  */
41 static u32
43 {
44  fib_node_index_t src_fib_index;
45  fib_prefix_t dst_fib_prefix;
46  fib_node_index_t dst_fei;
47 
48  ASSERT (NULL != dst_prefix);
49 
50  ip_prefix_to_fib_prefix (dst_prefix, &dst_fib_prefix);
51 
52  /*
53  * lookup the destination prefix in the VRF table and retrieve the
54  * LISP associated data
55  */
56  dst_fei = fib_table_lookup_exact_match (dst_fib_index, &dst_fib_prefix);
57 
58  /*
59  * If the FIB entry is not present, or not LISP sourced, add it
60  */
61  if (dst_fei == FIB_NODE_INDEX_INVALID ||
62  NULL == fib_entry_get_source_data (dst_fei, FIB_SOURCE_LISP))
63  {
64  dpo_id_t src_lkup_dpo = DPO_INVALID;
65 
66  /* create a new src FIB. */
67  src_fib_index =
68  fib_table_create_and_lock (dst_fib_prefix.fp_proto,
70  "LISP-src for [%d,%U]",
71  dst_fib_index,
72  format_fib_prefix, &dst_fib_prefix);
73  /*
74  * add src fib default route
75  */
77  .fp_proto = dst_fib_prefix.fp_proto,
78  };
79  fib_table_entry_special_dpo_add (src_fib_index, &prefix,
83  (dst_fib_prefix.fp_proto)));
84  /*
85  * create a data-path object to perform the source address lookup
86  * in the SRC FIB
87  */
89  (ip_prefix_version (dst_prefix) ==
95  &src_lkup_dpo);
96 
97  /*
98  * add the entry to the destination FIB that uses the lookup DPO
99  */
100  dst_fei = fib_table_entry_special_dpo_add (dst_fib_index,
101  &dst_fib_prefix,
104  &src_lkup_dpo);
105 
106  /*
107  * the DPO is locked by the FIB entry, and we have no further
108  * need for it.
109  */
110  dpo_unlock (&src_lkup_dpo);
111 
112  /*
113  * save the SRC FIB index on the entry so we can retrieve it for
114  * subsequent routes.
115  */
116  fib_entry_set_source_data (dst_fei, FIB_SOURCE_LISP, &src_fib_index);
117  }
118  else
119  {
120  /*
121  * destination FIB entry already present
122  */
123  src_fib_index = *(u32 *) fib_entry_get_source_data (dst_fei,
125  }
126 
127  return (src_fib_index);
128 }
129 
130 /**
131  * @brief Del route to IP4 or IP6 SD FIB.
132  *
133  * Remove routes from both destination and source FIBs.
134  *
135  * @param[in] src_fib_index The index/ID of the SRC FIB
136  * @param[in] src_prefix Source IP prefix.
137  * @param[in] dst_fib_index The index/ID of the DST FIB
138  * @param[in] dst_prefix Destination IP prefix.
139  */
140 static void
142  const ip_prefix_t * src_prefix,
143  u32 dst_fib_index, const ip_prefix_t * dst_prefix)
144 {
145  fib_prefix_t dst_fib_prefix, src_fib_prefix;
146  u8 have_default = 0;
147  u32 n_entries;
148 
149  ASSERT (NULL != dst_prefix);
150  ASSERT (NULL != src_prefix);
151 
152  ip_prefix_to_fib_prefix (dst_prefix, &dst_fib_prefix);
153  ip_prefix_to_fib_prefix (src_prefix, &src_fib_prefix);
154 
155  fib_table_entry_delete (src_fib_index, &src_fib_prefix, FIB_SOURCE_LISP);
156 
157  /* check if only default left or empty */
158  fib_prefix_t default_pref = {
159  .fp_proto = dst_fib_prefix.fp_proto
160  };
161 
162  if (fib_table_lookup_exact_match (src_fib_index,
163  &default_pref) != FIB_NODE_INDEX_INVALID)
164  have_default = 1;
165 
166  n_entries = fib_table_get_num_entries (src_fib_index,
167  src_fib_prefix.fp_proto,
169  if (n_entries == 0 || (have_default && n_entries == 1))
170  {
171  /*
172  * remove src FIB default route
173  */
174  if (have_default)
175  fib_table_entry_special_remove (src_fib_index, &default_pref,
177 
178  /*
179  * there's nothing left now, unlock the source FIB and the
180  * destination route
181  */
182  fib_table_entry_special_remove (dst_fib_index,
183  &dst_fib_prefix, FIB_SOURCE_LISP);
184  fib_table_unlock (src_fib_index, src_fib_prefix.fp_proto,
186  }
187 }
188 
189 /**
190  * @brief Add route to IP4 or IP6 SRC FIB.
191  *
192  * Adds a route to in the LISP SRC FIB with the result of the route
193  * being the DPO passed.
194  *
195  * @param[in] src_fib_index The index/ID of the SRC FIB
196  * @param[in] src_prefix Source IP prefix.
197  * @param[in] src_dpo The DPO the route will link to.
198  *
199  * @return fib index of the inserted prefix
200  */
201 static fib_node_index_t
203  const ip_prefix_t * src_prefix,
204  const dpo_id_t * src_dpo)
205 {
206  fib_node_index_t fei = ~0;
207  fib_prefix_t src_fib_prefix;
208 
209  ip_prefix_to_fib_prefix (src_prefix, &src_fib_prefix);
210 
211  /*
212  * add the entry into the source fib.
213  */
214  fib_node_index_t src_fei;
215 
216  src_fei = fib_table_lookup_exact_match (src_fib_index, &src_fib_prefix);
217 
218  if (FIB_NODE_INDEX_INVALID == src_fei ||
220  {
221  fei = fib_table_entry_special_dpo_add (src_fib_index,
222  &src_fib_prefix,
225  src_dpo);
226  }
227  return fei;
228 }
229 
230 static fib_route_path_t *
232 {
233  const lisp_gpe_adjacency_t *ladj;
234  fib_route_path_t *rpaths = NULL;
235  fib_protocol_t fp;
236  u8 best_priority;
237  u32 ii;
238 
239  vec_validate (rpaths, vec_len (paths) - 1);
240 
241  best_priority = paths[0].priority;
242 
243  vec_foreach_index (ii, paths)
244  {
245  if (paths[0].priority != best_priority)
246  break;
247 
248  ladj = lisp_gpe_adjacency_get (paths[ii].lisp_adj);
249 
250  fp = ip_address_to_46 (&ladj->remote_rloc, &rpaths[ii].frp_addr);
251 
252  rpaths[ii].frp_proto = fib_proto_to_dpo (fp);
253  rpaths[ii].frp_sw_if_index = ladj->sw_if_index;
254  rpaths[ii].frp_weight = (paths[ii].weight ? paths[ii].weight : 1);
255  }
256 
257  ASSERT (0 != vec_len (rpaths));
258 
259  return (rpaths);
260 }
261 
262 /**
263  * @brief Add route to IP4 or IP6 SRC FIB.
264  *
265  * Adds a route to in the LISP SRC FIB for the tunnel.
266  *
267  * @param[in] src_fib_index The index/ID of the SRC FIB
268  * @param[in] src_prefix Source IP prefix.
269  * @param[in] paths The paths from which to construct the
270  * load balance
271  */
272 static fib_node_index_t
273 ip_src_fib_add_route (u32 src_fib_index,
274  const ip_prefix_t * src_prefix,
275  const lisp_fwd_path_t * paths)
276 {
277  fib_prefix_t src_fib_prefix;
278  fib_route_path_t *rpaths;
279 
280  ip_prefix_to_fib_prefix (src_prefix, &src_fib_prefix);
281 
282  rpaths = lisp_gpe_mk_fib_paths (paths);
283 
284  fib_node_index_t fib_entry_index =
285  fib_table_entry_update (src_fib_index, &src_fib_prefix, FIB_SOURCE_LISP,
286  FIB_ENTRY_FLAG_NONE, rpaths);
287  vec_free (rpaths);
288  return fib_entry_index;
289 }
290 
291 static void
293 {
295  u8 found = 0, ip_version;
296  u32 *lfei, new_lfei;
297  ip_version = ip_prefix_version (&lfe->key->rmt.ippref);
298 
299  new_lfei = lfe - lgm->lisp_fwd_entry_pool;
300  vec_foreach (lfei, lgm->native_fwd_lfes[ip_version])
301  {
302  lfe = pool_elt_at_index (lgm->lisp_fwd_entry_pool, lfei[0]);
303  if (lfei[0] == new_lfei)
304  {
305  found = 1;
306  break;
307  }
308  }
309 
310  if (is_add)
311  {
312  if (!found)
313  vec_add1 (lgm->native_fwd_lfes[ip_version], new_lfei);
314  }
315  else
316  {
317  if (found)
318  vec_del1 (lgm->native_fwd_lfes[ip_version], lfei[0]);
319  }
320 }
321 
322 static index_t
324 {
325  fib_node_index_t fi;
326  fib_entry_t *fe;
328  dpo_proto_t dproto;
329  ip_prefix_t ippref;
330  fib_prefix_t fib_prefix;
331  u8 ip_version = ip_prefix_version (&lfe->key->rmt.ippref);
332  dproto = (ip_version == AF_IP4 ? DPO_PROTO_IP4 : DPO_PROTO_IP6);
333 
334  if (lfe->is_src_dst)
335  {
337  &lfe->key->rmt.ippref);
338  memcpy (&ippref, &lfe->key->lcl.ippref, sizeof (ippref));
339  }
340  else
341  {
342  lfe->src_fib_index = lfe->eid_fib_index;
343  memcpy (&ippref, &lfe->key->rmt.ippref, sizeof (ippref));
344  }
345 
347  {
348  dpo_id_t dpo = DPO_INVALID;
349 
350  switch (lfe->action)
351  {
352  case LISP_FORWARD_NATIVE:
353  /* TODO handle route overlaps with fib and default route */
354  if (vec_len (lgm->native_fwd_rpath[ip_version]))
355  {
356  ip_prefix_to_fib_prefix (&lfe->key->rmt.ippref, &fib_prefix);
357  fi = fib_table_entry_update (lfe->eid_fib_index, &fib_prefix,
360  lgm->native_fwd_rpath[ip_version]);
362  goto done;
363  }
364  case LISP_NO_ACTION:
365  /* TODO update timers? */
367  /* insert tunnel that always sends map-request */
368  dpo_copy (&dpo, lisp_cp_dpo_get (dproto));
369  break;
370  case LISP_DROP:
371  /* for drop fwd entries, just add route, no need to add encap tunnel */
372  dpo_copy (&dpo, drop_dpo_get (dproto));
373  break;
374  }
375  fi = ip_src_fib_add_route_w_dpo (lfe->src_fib_index, &ippref, &dpo);
376  dpo_reset (&dpo);
377  }
378  else
379  {
380  fi = ip_src_fib_add_route (lfe->src_fib_index, &ippref, lfe->paths);
381  }
382 done:
383  fe = fib_entry_get (fi);
384  return fe->fe_lb.dpoi_index;
385 }
386 
387 static void
389 {
390  fib_prefix_t dst_fib_prefix;
391 
392  if (lfe->is_src_dst)
394  &lfe->key->lcl.ippref,
395  lfe->eid_fib_index, &lfe->key->rmt.ippref);
396  else
397  {
398  ip_prefix_to_fib_prefix (&lfe->key->rmt.ippref, &dst_fib_prefix);
399  fib_table_entry_delete (lfe->src_fib_index, &dst_fib_prefix,
402  }
403 }
404 
405 static lisp_gpe_fwd_entry_t *
409 {
410  uword *p;
411 
412  clib_memset (key, 0, sizeof (*key));
413 
415  {
416  /*
417  * the ip version of the source is not set to ip6 when the
418  * source is all zeros. force it.
419  */
422  }
423 
424  gid_to_dp_address (&a->rmt_eid, &key->rmt);
425  gid_to_dp_address (&a->lcl_eid, &key->lcl);
426  key->vni = a->vni;
427 
428  p = hash_get_mem (lgm->lisp_gpe_fwd_entries, key);
429 
430  if (NULL != p)
431  {
432  return (pool_elt_at_index (lgm->lisp_fwd_entry_pool, p[0]));
433  }
434  return (NULL);
435 }
436 
437 static int
438 lisp_gpe_fwd_entry_path_sort (void *a1, void *a2)
439 {
440  lisp_fwd_path_t *p1 = a1, *p2 = a2;
441 
442  return (p1->priority - p2->priority);
443 }
444 
445 static void
448 {
450  u32 index;
451 
452  vec_validate (lfe->paths, vec_len (a->locator_pairs) - 1);
453 
454  vec_foreach_index (index, a->locator_pairs)
455  {
456  path = &lfe->paths[index];
457 
458  path->priority = a->locator_pairs[index].priority;
459  path->weight = a->locator_pairs[index].weight;
460 
461  path->lisp_adj =
463  [index],
464  a->dp_table, lfe->key->vni);
465  }
467 }
468 
469 void
471  u32 fwd_entry_index)
472 {
473  const lisp_gpe_adjacency_t *ladj;
476  u8 *placeholder_elt;
480 
481  lfe = find_fwd_entry (lgm, a, &fe_key);
482 
483  if (!lfe)
484  return;
485 
487  return;
488 
489  clib_memset (&key, 0, sizeof (key));
490  key.fwd_entry_index = fwd_entry_index;
491 
492  vec_foreach (path, lfe->paths)
493  {
494  ladj = lisp_gpe_adjacency_get (path->lisp_adj);
495  key.tunnel_index = ladj->tunnel_index;
496  lisp_stats_key_t *key_copy = clib_mem_alloc (sizeof (*key_copy));
497  memcpy (key_copy, &key, sizeof (*key_copy));
498  pool_get (lgm->placeholder_stats_pool, placeholder_elt);
499  hash_set_mem (lgm->lisp_stats_index_by_key, key_copy,
500  placeholder_elt - lgm->placeholder_stats_pool);
501 
503  placeholder_elt -
506  placeholder_elt -
508  }
509 }
510 
511 /**
512  * @brief Add/Delete LISP IP forwarding entry.
513  *
514  * creation of forwarding entries for IP LISP overlay:
515  *
516  * @param[in] lgm Reference to @ref lisp_gpe_main_t.
517  * @param[in] a Parameters for building the forwarding entry.
518  *
519  * @return 0 on success.
520  */
521 static int
524 {
527  fib_protocol_t fproto;
528 
529  lfe = find_fwd_entry (lgm, a, &key);
530 
531  if (NULL != lfe)
532  /* don't support updates */
533  return VNET_API_ERROR_INVALID_VALUE;
534 
535  pool_get (lgm->lisp_fwd_entry_pool, lfe);
536  clib_memset (lfe, 0, sizeof (*lfe));
537  lfe->key = clib_mem_alloc (sizeof (key));
538  memcpy (lfe->key, &key, sizeof (key));
539 
541  lfe - lgm->lisp_fwd_entry_pool);
542  a->fwd_entry_index = lfe - lgm->lisp_fwd_entry_pool;
543 
544  fproto = (AF_IP4 == ip_prefix_version (&fid_addr_ippref (&lfe->key->rmt)) ?
546 
547  lfe->type = (a->is_negative ?
551  lfe->eid_table_id = a->table_id;
553  lfe->eid_table_id,
555  lfe->is_src_dst = a->is_src_dst;
556 
558  {
560  }
561  else
562  {
563  lfe->action = a->action;
564  }
565 
566  lfe->dpoi_index = create_fib_entries (lfe);
567  return (0);
568 }
569 
570 static void
572 {
574  fib_protocol_t fproto;
575 
577  {
578  vec_foreach (path, lfe->paths)
579  {
581  }
582  }
583 
584  delete_fib_entries (lfe);
585 
586  fproto = (AF_IP4 == ip_prefix_version (&fid_addr_ippref (&lfe->key->rmt)) ?
589 
591  clib_mem_free (lfe->key);
592  pool_put (lgm->lisp_fwd_entry_pool, lfe);
593 }
594 
595 /**
596  * @brief Add/Delete LISP IP forwarding entry.
597  *
598  * removal of forwarding entries for IP LISP overlay:
599  *
600  * @param[in] lgm Reference to @ref lisp_gpe_main_t.
601  * @param[in] a Parameters for building the forwarding entry.
602  *
603  * @return 0 on success.
604  */
605 static int
608 {
611 
612  lfe = find_fwd_entry (lgm, a, &key);
613 
614  if (NULL == lfe)
615  /* no such entry */
616  return VNET_API_ERROR_INVALID_VALUE;
617 
618  del_ip_fwd_entry_i (lgm, lfe);
619 
620  return (0);
621 }
622 
623 static void
624 make_mac_fib_key (BVT (clib_bihash_kv) * kv, u16 bd_index, u8 src_mac[6],
625  u8 dst_mac[6])
626 {
627  kv->key[0] = (((u64) bd_index) << 48) | mac_to_u64 (dst_mac);
628  kv->key[1] = mac_to_u64 (src_mac);
629  kv->key[2] = 0;
630 }
631 
632 /**
633  * @brief Lookup L2 SD FIB entry
634  *
635  * Does a vni + dest + source lookup in the L2 LISP FIB. If the lookup fails
636  * it tries a second time with source set to 0 (i.e., a simple dest lookup).
637  *
638  * @param[in] lgm Reference to @ref lisp_gpe_main_t.
639  * @param[in] bd_index Bridge domain index.
640  * @param[in] src_mac Source mac address.
641  * @param[in] dst_mac Destination mac address.
642  *
643  * @return index of mapping matching the lookup key.
644  */
645 index_t
647  u8 dst_mac[6])
648 {
649  int rv;
650  BVT (clib_bihash_kv) kv, value;
651 
652  make_mac_fib_key (&kv, bd_index, src_mac, dst_mac);
653  rv = BV (clib_bihash_search_inline_2) (&lgm->l2_fib, &kv, &value);
654 
655  /* no match, try with src 0, catch all for dst */
656  if (rv != 0)
657  {
658  kv.key[1] = 0;
659  rv = BV (clib_bihash_search_inline_2) (&lgm->l2_fib, &kv, &value);
660  if (rv == 0)
661  return value.value;
662  }
663  else
664  return value.value;
665 
667 }
668 
669 /**
670  * @brief Add/del L2 SD FIB entry
671  *
672  * Inserts value in L2 FIB keyed by vni + dest + source. If entry is
673  * overwritten the associated value is returned.
674  *
675  * @param[in] lgm Reference to @ref lisp_gpe_main_t.
676  * @param[in] bd_index Bridge domain index.
677  * @param[in] src_mac Source mac address.
678  * @param[in] dst_mac Destination mac address.
679  * @param[in] val Value to add.
680  * @param[in] is_add Add/del flag.
681  *
682  * @return ~0 or value of overwritten entry.
683  */
684 static u32
686  u8 dst_mac[6], const dpo_id_t * dpo, u8 is_add)
687 {
689  BVT (clib_bihash_kv) kv, value;
690  u32 old_val = ~0;
691 
692  make_mac_fib_key (&kv, bd_index, src_mac, dst_mac);
693 
694  if (BV (clib_bihash_search) (&lgm->l2_fib, &kv, &value) == 0)
695  old_val = value.value;
696 
697  if (!is_add)
698  BV (clib_bihash_add_del) (&lgm->l2_fib, &kv, 0 /* is_add */ );
699  else
700  {
701  kv.value = dpo->dpoi_index;
702  BV (clib_bihash_add_del) (&lgm->l2_fib, &kv, 1 /* is_add */ );
703  }
704  return old_val;
705 }
706 
707 #define L2_FIB_DEFAULT_HASH_NUM_BUCKETS (64 * 1024)
708 #define L2_FIB_DEFAULT_HASH_MEMORY_SIZE (32<<20)
709 
710 static void
712 {
713  index_t lbi;
714 
715  BV (clib_bihash_init) (&lgm->l2_fib, "l2 fib",
718 
719  /*
720  * the result from a 'miss' in a L2 Table
721  */
724 
726 }
727 
728 static void
730 {
732 
734  {
735  vec_foreach (path, lfe->paths)
736  {
738  }
739  fib_path_list_child_remove (lfe->l2.path_list_index,
740  lfe->l2.child_index);
741  }
742 
743  lisp_l2_fib_add_del_entry (lfe->l2.eid_bd_index,
744  fid_addr_mac (&lfe->key->lcl),
745  fid_addr_mac (&lfe->key->rmt), NULL, 0);
746 
748  clib_mem_free (lfe->key);
749  pool_put (lgm->lisp_fwd_entry_pool, lfe);
750 }
751 
752 /**
753  * @brief Delete LISP L2 forwarding entry.
754  *
755  * Coordinates the removal of forwarding entries for L2 LISP overlay:
756  *
757  * @param[in] lgm Reference to @ref lisp_gpe_main_t.
758  * @param[in] a Parameters for building the forwarding entry.
759  *
760  * @return 0 on success.
761  */
762 static int
765 {
768 
769  lfe = find_fwd_entry (lgm, a, &key);
770 
771  if (NULL == lfe)
772  return VNET_API_ERROR_INVALID_VALUE;
773 
774  del_l2_fwd_entry_i (lgm, lfe);
775 
776  return (0);
777 }
778 
779 /**
780  * @brief Construct and insert the forwarding information used by an L2 entry
781  */
782 static void
784 {
786  dpo_id_t dpo = DPO_INVALID;
787 
789  {
790  fib_path_list_contribute_forwarding (lfe->l2.path_list_index,
793  &lfe->l2.dpo);
794  dpo_copy (&dpo, &lfe->l2.dpo);
795  }
796  else
797  {
798  switch (lfe->action)
799  {
800  case SEND_MAP_REQUEST:
801  dpo_copy (&dpo, &lgm->l2_lb_cp_lkup);
802  break;
803  case NO_ACTION:
804  case FORWARD_NATIVE:
805  case DROP:
807  }
808  }
809 
810  /* add entry to l2 lisp fib */
811  lisp_l2_fib_add_del_entry (lfe->l2.eid_bd_index,
812  fid_addr_mac (&lfe->key->lcl),
813  fid_addr_mac (&lfe->key->rmt), &dpo, 1);
814  lfe->dpoi_index = dpo.dpoi_index;
815 
816  dpo_reset (&dpo);
817 }
818 
819 /**
820  * @brief Add LISP L2 forwarding entry.
821  *
822  * Coordinates the creation of forwarding entries for L2 LISP overlay:
823  * creates lisp-gpe tunnel and injects new entry in Source/Dest L2 FIB.
824  *
825  * @param[in] lgm Reference to @ref lisp_gpe_main_t.
826  * @param[in] a Parameters for building the forwarding entry.
827  *
828  * @return 0 on success.
829  */
830 static int
833 {
835  bd_main_t *bdm = &bd_main;
837  uword *bd_indexp;
838 
839  bd_indexp = hash_get (bdm->bd_index_by_bd_id, a->bd_id);
840  if (!bd_indexp)
841  {
842  clib_warning ("bridge domain %d doesn't exist", a->bd_id);
843  return -1;
844  }
845 
846  lfe = find_fwd_entry (lgm, a, &key);
847 
848  if (NULL != lfe)
849  /* don't support updates */
850  return VNET_API_ERROR_INVALID_VALUE;
851 
852  pool_get (lgm->lisp_fwd_entry_pool, lfe);
853  clib_memset (lfe, 0, sizeof (*lfe));
854  lfe->key = clib_mem_alloc (sizeof (key));
855  memcpy (lfe->key, &key, sizeof (key));
856 
858  lfe - lgm->lisp_fwd_entry_pool);
859  a->fwd_entry_index = lfe - lgm->lisp_fwd_entry_pool;
860 
861  lfe->type = (a->is_negative ?
864  lfe->l2.eid_bd_id = a->bd_id;
865  lfe->l2.eid_bd_index = bd_indexp[0];
867 
869  {
870  fib_route_path_t *rpaths;
871 
872  /*
873  * Make the sorted array of LISP paths with their resp. adjacency
874  */
876 
877  /*
878  * From the LISP paths, construct a FIB path list that will
879  * contribute a load-balance.
880  */
881  rpaths = lisp_gpe_mk_fib_paths (lfe->paths);
882 
883  lfe->l2.path_list_index =
885 
886  /*
887  * become a child of the path-list so we receive updates when
888  * its forwarding state changes. this includes an implicit lock.
889  */
890  lfe->l2.child_index =
891  fib_path_list_child_add (lfe->l2.path_list_index,
893  lfe - lgm->lisp_fwd_entry_pool);
894  }
895  else
896  {
897  lfe->action = a->action;
898  }
899 
901 
902  return 0;
903 }
904 
905 /**
906  * @brief Lookup NSH SD FIB entry
907  *
908  * Does an SPI+SI lookup in the NSH LISP FIB.
909  *
910  * @param[in] lgm Reference to @ref lisp_gpe_main_t.
911  * @param[in] spi_si SPI + SI.
912  *
913  * @return next node index.
914  */
915 const dpo_id_t *
916 lisp_nsh_fib_lookup (lisp_gpe_main_t * lgm, u32 spi_si_net_order)
917 {
918  int rv;
919  BVT (clib_bihash_kv) kv, value;
920 
921  clib_memset (&kv, 0, sizeof (kv));
922  kv.key[0] = spi_si_net_order;
923  rv = BV (clib_bihash_search_inline_2) (&lgm->nsh_fib, &kv, &value);
924 
925  if (rv != 0)
926  {
927  return lgm->nsh_cp_lkup;
928  }
929  else
930  {
932  lfe = pool_elt_at_index (lgm->lisp_fwd_entry_pool, value.value);
933  return &lfe->nsh.choice;
934  }
935 }
936 
937 /**
938  * @brief Add/del NSH FIB entry
939  *
940  * Inserts value in NSH FIB keyed by SPI+SI. If entry is
941  * overwritten the associated value is returned.
942  *
943  * @param[in] lgm Reference to @ref lisp_gpe_main_t.
944  * @param[in] spi_si SPI + SI.
945  * @param[in] dpo Load balanced mapped to SPI + SI
946  *
947  * @return ~0 or value of overwritten entry.
948  */
949 static u32
950 lisp_nsh_fib_add_del_entry (u32 spi_si_host_order, u32 lfei, u8 is_add)
951 {
953  BVT (clib_bihash_kv) kv, value;
954  u32 old_val = ~0;
955 
956  clib_memset (&kv, 0, sizeof (kv));
957  kv.key[0] = clib_host_to_net_u32 (spi_si_host_order);
958  kv.value = 0ULL;
959 
960  if (BV (clib_bihash_search) (&lgm->nsh_fib, &kv, &value) == 0)
961  old_val = value.value;
962 
963  if (!is_add)
964  BV (clib_bihash_add_del) (&lgm->nsh_fib, &kv, 0 /* is_add */ );
965  else
966  {
967  kv.value = lfei;
968  BV (clib_bihash_add_del) (&lgm->nsh_fib, &kv, 1 /* is_add */ );
969  }
970  return old_val;
971 }
972 
973 #define NSH_FIB_DEFAULT_HASH_NUM_BUCKETS (64 * 1024)
974 #define NSH_FIB_DEFAULT_HASH_MEMORY_SIZE (32<<20)
975 
976 static void
978 {
979  BV (clib_bihash_init) (&lgm->nsh_fib, "nsh fib",
982 
983  /*
984  * the result from a 'miss' in a NSH Table
985  */
987 }
988 
989 static void
991 {
993 
995  {
996  vec_foreach (path, lfe->paths)
997  {
999  }
1000  fib_path_list_child_remove (lfe->nsh.path_list_index,
1001  lfe->nsh.child_index);
1002  dpo_reset (&lfe->nsh.choice);
1003  }
1004 
1005  lisp_nsh_fib_add_del_entry (fid_addr_nsh (&lfe->key->rmt), (u32) ~ 0, 0);
1006 
1008  clib_mem_free (lfe->key);
1009  pool_put (lgm->lisp_fwd_entry_pool, lfe);
1010 }
1011 
1012 /**
1013  * @brief Delete LISP NSH forwarding entry.
1014  *
1015  * Coordinates the removal of forwarding entries for NSH LISP overlay:
1016  *
1017  * @param[in] lgm Reference to @ref lisp_gpe_main_t.
1018  * @param[in] a Parameters for building the forwarding entry.
1019  *
1020  * @return 0 on success.
1021  */
1022 static int
1025 {
1027  lisp_gpe_fwd_entry_t *lfe;
1028 
1029  lfe = find_fwd_entry (lgm, a, &key);
1030 
1031  if (NULL == lfe)
1032  return VNET_API_ERROR_INVALID_VALUE;
1033 
1034  del_nsh_fwd_entry_i (lgm, lfe);
1035 
1036  return (0);
1037 }
1038 
1039 /**
1040  * @brief Construct and insert the forwarding information used by an NSH entry
1041  */
1042 static void
1044 {
1046  dpo_id_t dpo = DPO_INVALID;
1048  uword *hip;
1049 
1051  {
1052  fib_path_list_contribute_forwarding (lfe->nsh.path_list_index,
1055  &lfe->nsh.dpo);
1056 
1057  /*
1058  * LISP encap is always the same for this SPI+SI so we do that hash now
1059  * and stack on the choice.
1060  */
1061  if (DPO_LOAD_BALANCE == lfe->nsh.dpo.dpoi_type)
1062  {
1063  const dpo_id_t *tmp;
1064  const load_balance_t *lb;
1065  int hash;
1066 
1067  lb = load_balance_get (lfe->nsh.dpo.dpoi_index);
1068  hash = fid_addr_nsh (&lfe->key->rmt) % lb->lb_n_buckets;
1069  tmp =
1071 
1072  dpo_copy (&dpo, tmp);
1073  }
1074  }
1075  else
1076  {
1077  switch (lfe->action)
1078  {
1079  case SEND_MAP_REQUEST:
1080  dpo_copy (&dpo, lgm->nsh_cp_lkup);
1081  break;
1082  case NO_ACTION:
1083  case FORWARD_NATIVE:
1084  case DROP:
1086  }
1087  }
1088 
1089  /* We have only one nsh-lisp interface (no NSH virtualization) */
1091  if (hip)
1092  {
1093  hi = vnet_get_hw_interface (lgm->vnet_main, hip[0]);
1094  dpo_stack_from_node (hi->tx_node_index, &lfe->nsh.choice, &dpo);
1095  }
1096  /* add entry to nsh lisp fib */
1098  lfe - lgm->lisp_fwd_entry_pool, 1);
1099  dpo_reset (&dpo);
1100 
1101 }
1102 
1103 /**
1104  * @brief Add LISP NSH forwarding entry.
1105  *
1106  * Coordinates the creation of forwarding entries for L2 LISP overlay:
1107  * creates lisp-gpe tunnel and injects new entry in Source/Dest L2 FIB.
1108  *
1109  * @param[in] lgm Reference to @ref lisp_gpe_main_t.
1110  * @param[in] a Parameters for building the forwarding entry.
1111  *
1112  * @return 0 on success.
1113  */
1114 static int
1117 {
1119  lisp_gpe_fwd_entry_t *lfe;
1120 
1121  lfe = find_fwd_entry (lgm, a, &key);
1122 
1123  if (NULL != lfe)
1124  /* don't support updates */
1125  return VNET_API_ERROR_INVALID_VALUE;
1126 
1127  pool_get (lgm->lisp_fwd_entry_pool, lfe);
1128  clib_memset (lfe, 0, sizeof (*lfe));
1129  lfe->key = clib_mem_alloc (sizeof (key));
1130  memcpy (lfe->key, &key, sizeof (key));
1131 
1133  lfe - lgm->lisp_fwd_entry_pool);
1134  a->fwd_entry_index = lfe - lgm->lisp_fwd_entry_pool;
1135 
1136  lfe->type = (a->is_negative ?
1139  lfe->tenant = 0;
1140 
1142  {
1143  fib_route_path_t *rpaths;
1144 
1145  /*
1146  * Make the sorted array of LISP paths with their resp. adjacency
1147  */
1148  lisp_gpe_fwd_entry_mk_paths (lfe, a);
1149 
1150  /*
1151  * From the LISP paths, construct a FIB path list that will
1152  * contribute a load-balance.
1153  */
1154  rpaths = lisp_gpe_mk_fib_paths (lfe->paths);
1155 
1156  lfe->nsh.path_list_index =
1158 
1159  /*
1160  * become a child of the path-list so we receive updates when
1161  * its forwarding state changes. this includes an implicit lock.
1162  */
1163  lfe->nsh.child_index =
1164  fib_path_list_child_add (lfe->nsh.path_list_index,
1166  lfe - lgm->lisp_fwd_entry_pool);
1167  }
1168  else
1169  {
1170  lfe->action = a->action;
1171  }
1172 
1174 
1175  return 0;
1176 }
1177 
1178 /**
1179  * @brief conver from the embedded fib_node_t struct to the LSIP entry
1180  */
1181 static lisp_gpe_fwd_entry_t *
1183 {
1184  return ((lisp_gpe_fwd_entry_t *) (((char *) node) -
1186  node)));
1187 }
1188 
1189 /**
1190  * @brief Function invoked during a backwalk of the FIB graph
1191  */
1195 {
1197 
1198  if (fid_addr_type (&lfe->key->rmt) == FID_ADDR_MAC)
1200  else if (fid_addr_type (&lfe->key->rmt) == FID_ADDR_NSH)
1202 
1203  return (FIB_NODE_BACK_WALK_CONTINUE);
1204 }
1205 
1206 /**
1207  * @brief Get a fib_node_t struct from the index of a LISP fwd entry
1208  */
1209 static fib_node_t *
1211 {
1213  lisp_gpe_fwd_entry_t *lfe;
1214 
1215  lfe = pool_elt_at_index (lgm->lisp_fwd_entry_pool, index);
1216 
1217  return (&(lfe->node));
1218 }
1219 
1220 /**
1221  * @brief An indication from the graph that the last lock has gone
1222  */
1223 static void
1225 {
1226  /* We don't manage the locks of the LISP objects via the graph, since
1227  * this object has no children. so this is a no-op. */
1228 }
1229 
1230 /**
1231  * @brief Virtual function table to register with FIB for the LISP type
1232  */
1236  .fnv_back_walk = lisp_gpe_fib_node_back_walk,
1237 };
1238 
1239 /**
1240  * @brief Forwarding entry create/remove dispatcher.
1241  *
1242  * Calls l2 or l3 forwarding entry add/del function based on input data.
1243  *
1244  * @param[in] a Forwarding entry parameters.
1245  * @param[out] hw_if_indexp NOT USED
1246  *
1247  * @return 0 on success.
1248  */
1249 int
1251  u32 * hw_if_indexp)
1252 {
1254  u8 type;
1255 
1257  {
1258  clib_warning ("LISP is disabled!");
1259  return VNET_API_ERROR_LISP_DISABLED;
1260  }
1261 
1262  type = gid_address_type (&a->rmt_eid);
1263  switch (type)
1264  {
1265  case GID_ADDR_IP_PREFIX:
1266  if (a->is_add)
1267  return add_ip_fwd_entry (lgm, a);
1268  else
1269  return del_ip_fwd_entry (lgm, a);
1270  break;
1271  case GID_ADDR_MAC:
1272  if (a->is_add)
1273  return add_l2_fwd_entry (lgm, a);
1274  else
1275  return del_l2_fwd_entry (lgm, a);
1276  case GID_ADDR_NSH:
1277  if (a->is_add)
1278  return add_nsh_fwd_entry (lgm, a);
1279  else
1280  return del_nsh_fwd_entry (lgm, a);
1281  default:
1282  clib_warning ("Forwarding entries for type %d not supported!", type);
1283  return -1;
1284  }
1285 }
1286 
1287 int
1289 {
1292  u32 i;
1293 
1294  if (cm->counters == NULL)
1295  return 0;
1296 
1297  for (i = 0; i < vlib_combined_counter_n_counters (cm); i++)
1299 
1300  return 0;
1301 }
1302 
1303 static void
1304 lisp_del_adj_stats (lisp_gpe_main_t * lgm, u32 fwd_entry_index, u32 ti)
1305 {
1306  hash_pair_t *hp;
1308  void *key_copy;
1309  uword *p;
1310  u8 *s;
1311 
1312  clib_memset (&key, 0, sizeof (key));
1313  key.fwd_entry_index = fwd_entry_index;
1314  key.tunnel_index = ti;
1315 
1316  p = hash_get_mem (lgm->lisp_stats_index_by_key, &key);
1317  if (p)
1318  {
1319  s = pool_elt_at_index (lgm->placeholder_stats_pool, p[0]);
1320  hp = hash_get_pair (lgm->lisp_stats_index_by_key, &key);
1321  key_copy = (void *) (hp->key);
1323  clib_mem_free (key_copy);
1324  pool_put (lgm->placeholder_stats_pool, s);
1325  }
1326 }
1327 
1328 void
1330  u32 fwd_entry_index)
1331 {
1333  lisp_gpe_fwd_entry_key_t fe_key;
1334  lisp_gpe_fwd_entry_t *lfe;
1336  const lisp_gpe_adjacency_t *ladj;
1337 
1338  lfe = find_fwd_entry (lgm, a, &fe_key);
1339  if (!lfe)
1340  return;
1341 
1343  return;
1344 
1345  vec_foreach (path, lfe->paths)
1346  {
1347  ladj = lisp_gpe_adjacency_get (path->lisp_adj);
1348  lisp_del_adj_stats (lgm, fwd_entry_index, ladj->tunnel_index);
1349  }
1350 }
1351 
1352 /**
1353  * @brief Flush all the forwrding entries
1354  */
1355 void
1357 {
1359  lisp_gpe_fwd_entry_t *lfe;
1360 
1361  /* *INDENT-OFF* */
1362  pool_foreach (lfe, lgm->lisp_fwd_entry_pool,
1363  ({
1364  switch (fid_addr_type(&lfe->key->rmt))
1365  {
1366  case FID_ADDR_MAC:
1367  del_l2_fwd_entry_i (lgm, lfe);
1368  break;
1369  case FID_ADDR_IP_PREF:
1370  del_ip_fwd_entry_i (lgm, lfe);
1371  break;
1372  case FID_ADDR_NSH:
1373  del_nsh_fwd_entry_i (lgm, lfe);
1374  break;
1375  }
1376  }));
1377  /* *INDENT-ON* */
1378 }
1379 
1380 static u8 *
1381 format_lisp_fwd_path (u8 * s, va_list * ap)
1382 {
1383  lisp_fwd_path_t *lfp = va_arg (*ap, lisp_fwd_path_t *);
1384 
1385  s = format (s, "weight:%d ", lfp->weight);
1386  s = format (s, "adj:[%U]\n",
1390 
1391  return (s);
1392 }
1393 
1395 {
1399 
1400 
1401 static u8 *
1402 format_lisp_gpe_fwd_entry (u8 * s, va_list * ap)
1403 {
1405  lisp_gpe_fwd_entry_t *lfe = va_arg (*ap, lisp_gpe_fwd_entry_t *);
1407  va_arg (*ap, lisp_gpe_fwd_entry_format_flag_t);
1408 
1409  s = format (s, "VNI:%d VRF:%d EID: %U -> %U [index:%d]",
1410  lfe->key->vni, lfe->eid_table_id,
1411  format_fid_address, &lfe->key->lcl,
1412  format_fid_address, &lfe->key->rmt,
1413  lfe - lgm->lisp_fwd_entry_pool);
1414 
1416  {
1417  s = format (s, "\n Negative - action:%U",
1419  }
1420  else
1421  {
1423 
1424  s = format (s, "\n via:");
1425  vec_foreach (path, lfe->paths)
1426  {
1427  s = format (s, "\n %U", format_lisp_fwd_path, path);
1428  }
1429  }
1430 
1432  {
1433  switch (fid_addr_type (&lfe->key->rmt))
1434  {
1435  case FID_ADDR_MAC:
1436  s = format (s, " fib-path-list:%d\n", lfe->l2.path_list_index);
1437  s = format (s, " dpo:%U\n", format_dpo_id, &lfe->l2.dpo, 0);
1438  break;
1439  case FID_ADDR_NSH:
1440  s = format (s, " fib-path-list:%d\n", lfe->nsh.path_list_index);
1441  s = format (s, " dpo:%U\n", format_dpo_id, &lfe->nsh.dpo, 0);
1442  break;
1443  case FID_ADDR_IP_PREF:
1444  break;
1445  }
1446  }
1447 
1448  return (s);
1449 }
1450 
1451 static clib_error_t *
1453  unformat_input_t * input, vlib_cli_command_t * cmd)
1454 {
1456  lisp_gpe_fwd_entry_t *lfe;
1457  index_t index;
1458  u32 vni = ~0;
1459 
1460  if (unformat (input, "vni %d", &vni))
1461  ;
1462  else if (unformat (input, "%d", &index))
1463  {
1464  if (!pool_is_free_index (lgm->lisp_fwd_entry_pool, index))
1465  {
1466  lfe = pool_elt_at_index (lgm->lisp_fwd_entry_pool, index);
1467 
1468  vlib_cli_output (vm, "[%d@] %U",
1469  index,
1472  }
1473  else
1474  {
1475  vlib_cli_output (vm, "entry %d invalid", index);
1476  }
1477 
1478  return (NULL);
1479  }
1480 
1481  /* *INDENT-OFF* */
1482  pool_foreach (lfe, lgm->lisp_fwd_entry_pool,
1483  ({
1484  if ((vni == ~0) ||
1485  (lfe->key->vni == vni))
1486  vlib_cli_output (vm, "%U", format_lisp_gpe_fwd_entry, lfe,
1487  LISP_GPE_FWD_ENTRY_FORMAT_NONE);
1488  }));
1489  /* *INDENT-ON* */
1490 
1491  return (NULL);
1492 }
1493 
1494 /* *INDENT-OFF* */
1496  .path = "show gpe entry",
1497  .short_help = "show gpe entry vni <vni> vrf <vrf> [leid <leid>] reid <reid>",
1498  .function = lisp_gpe_fwd_entry_show,
1499 };
1500 /* *INDENT-ON* */
1501 
1502 clib_error_t *
1504 {
1506  clib_error_t *error = NULL;
1507 
1509  return (error);
1510 
1511  l2_fib_init (lgm);
1512  nsh_fib_init (lgm);
1513 
1515 
1516  return (error);
1517 }
1518 
1519 u32 *
1521 {
1523  lisp_gpe_fwd_entry_t *lfe;
1524  u32 *vnis = 0;
1525 
1526  /* *INDENT-OFF* */
1527  pool_foreach (lfe, lgm->lisp_fwd_entry_pool,
1528  ({
1529  hash_set (vnis, lfe->key->vni, 0);
1530  }));
1531  /* *INDENT-ON* */
1532 
1533  return vnis;
1534 }
1535 
1538 {
1540  lisp_gpe_fwd_entry_t *lfe;
1542 
1543  /* *INDENT-OFF* */
1544  pool_foreach (lfe, lgm->lisp_fwd_entry_pool,
1545  ({
1546  if (lfe->key->vni == vni)
1547  {
1548  clib_memset (&e, 0, sizeof (e));
1549  e.dp_table = lfe->eid_table_id;
1550  e.vni = lfe->key->vni;
1551  if (lfe->type == LISP_GPE_FWD_ENTRY_TYPE_NEGATIVE)
1552  e.action = lfe->action;
1553  e.fwd_entry_index = lfe - lgm->lisp_fwd_entry_pool;
1554  memcpy (&e.reid, &lfe->key->rmt, sizeof (e.reid));
1555  memcpy (&e.leid, &lfe->key->lcl, sizeof (e.leid));
1556  vec_add1 (entries, e);
1557  }
1558  }));
1559  /* *INDENT-ON* */
1560 
1561  return entries;
1562 }
1563 
1564 int
1566  vlib_counter_t * c)
1567 {
1569  lisp_gpe_fwd_entry_t *lfe;
1570  lisp_gpe_fwd_entry_key_t unused;
1571 
1572  lfe = find_fwd_entry (lgm, a, &unused);
1573  if (NULL == lfe)
1574  return -1;
1575 
1577  return -1;
1578 
1579  if (~0 == lfe->dpoi_index)
1580  return -1;
1581 
1583  lfe->dpoi_index, c);
1584  return 0;
1585 }
1586 
1588 
1589 /*
1590  * fd.io coding-style-patch-verification: ON
1591  *
1592  * Local Variables:
1593  * eval: (c-set-style "gnu")
1594  * End:
1595  */
void dpo_unlock(dpo_id_t *dpo)
Release a reference counting lock on the DPO.
Definition: dpo.c:373
#define vec_validate(V, I)
Make sure vector is long enough for given index (no header, unspecified alignment) ...
Definition: vec.h:509
static void ip_src_dst_fib_del_route(u32 src_fib_index, const ip_prefix_t *src_prefix, u32 dst_fib_index, const ip_prefix_t *dst_prefix)
Del route to IP4 or IP6 SD FIB.
u16 lb_n_buckets
number of buckets in the load-balance.
Definition: load_balance.h:116
void dpo_stack_from_node(u32 child_node_index, dpo_id_t *dpo, const dpo_id_t *parent)
Stack one DPO object on another, and thus establish a child parent relationship.
Definition: dpo.c:531
fib_protocol_t fp_proto
protocol type
Definition: fib_types.h:212
static void lisp_del_adj_stats(lisp_gpe_main_t *lgm, u32 fwd_entry_index, u32 ti)
#define vec_foreach_index(var, v)
Iterate over vector indices.
ip46_address_t frp_addr
The next-hop address.
Definition: fib_types.h:506
vlib_combined_counter_main_t lbm_to_counters
Definition: load_balance.h:46
u16 vni
Definition: flow_types.api:160
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: ip_types.c:395
vl_api_prefix_t dst_prefix
Definition: acl_types.api:45
static const fib_node_vft_t lisp_fwd_vft
Virtual function table to register with FIB for the LISP type.
static int add_l2_fwd_entry(lisp_gpe_main_t *lgm, vnet_lisp_gpe_add_del_fwd_entry_args_t *a)
Add LISP L2 forwarding entry.
An entry in a FIB table.
Definition: fib_entry.h:305
#define gid_address_type(_a)
Definition: lisp_types.h:203
static void l2_fib_init(lisp_gpe_main_t *lgm)
negative_fwd_actions_e action
When the type is negative.
void vlib_validate_combined_counter(vlib_combined_counter_main_t *cm, u32 index)
validate a combined counter
Definition: counter.c:108
void fib_path_list_child_remove(fib_node_index_t path_list_index, u32 si)
fib_node_index_t fib_table_lookup_exact_match(u32 fib_index, const fib_prefix_t *prefix)
Perfom an exact match in the non-forwarding table.
Definition: fib_table.c:97
vl_api_wireguard_peer_flags_t flags
Definition: wireguard.api:103
a
Definition: bitmap.h:538
const dpo_id_t * lisp_cp_dpo_get(dpo_proto_t proto)
Definition: lisp_cp_dpo.c:26
u8 vnet_lisp_gpe_enable_disable_status(void)
Check if LISP-GPE is enabled.
Definition: lisp_gpe.c:184
A representation of a path as described by a route producer.
Definition: fib_types.h:490
u32 * vnet_lisp_gpe_get_fwd_entry_vnis(void)
u32 bd_id
bridge domain id
Definition: lisp_gpe.h:270
static fib_node_t * lisp_gpe_fwd_entry_get_fib_node(fib_node_index_t index)
Get a fib_node_t struct from the index of a LISP fwd entry.
dp_address_t lcl
void vnet_lisp_gpe_fwd_entry_flush(void)
Flush all the forwrding entries.
unsigned long u64
Definition: types.h:89
fib_node_index_t fib_table_entry_update(u32 fib_index, const fib_prefix_t *prefix, fib_source_t source, fib_entry_flag_t flags, fib_route_path_t *paths)
Update an entry to have a new set of paths.
Definition: fib_table.c:756
u8 priority
Priority.
static u32 lisp_l2_fib_add_del_entry(u16 bd_index, u8 src_mac[6], u8 dst_mac[6], const dpo_id_t *dpo, u8 is_add)
Add/del L2 SD FIB entry.
clib_memset(h->entries, 0, sizeof(h->entries[0]) *entries)
enum fib_node_back_walk_rc_t_ fib_node_back_walk_rc_t
Return code from a back walk function.
LISP-GPE global state.
Definition: lisp_gpe.h:118
static vnet_hw_interface_t * vnet_get_hw_interface(vnet_main_t *vnm, u32 hw_if_index)
#define fid_addr_nsh(_a)
Definition: lisp_types.h:86
void dpo_copy(dpo_id_t *dst, const dpo_id_t *src)
atomic copy a data-plane object.
Definition: dpo.c:262
u32 index_t
A Data-Path Object is an object that represents actions that are applied to packets are they are swit...
Definition: dpo.h:41
#define vec_add1(V, E)
Add 1 element to end of vector (unspecified alignment).
Definition: vec.h:592
Combined counter to hold both packets and byte differences.
Definition: counter_types.h:26
u32 src_fib_index
The SRC-FIB index for created for anding source-route entries.
u32 eid_table_id
The VRF ID.
LISP-GPE definitions.
lisp_gpe_fwd_entry_key_t * key
The Entry&#39;s key: {lEID,rEID,vni}.
#define hash_set_mem(h, key, value)
Definition: hash.h:275
#define STRUCT_OFFSET_OF(t, f)
Definition: clib.h:70
vlib_main_t * vm
Definition: in2out_ed.c:1582
static u8 * format_lisp_fwd_path(u8 *s, va_list *ap)
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)
dpo_proto_t frp_proto
The protocol of the address below.
Definition: fib_types.h:495
vl_api_fib_path_t path
Definition: mfib_types.api:34
vl_api_prefix_t prefix
Definition: ip.api:144
u32 lisp_gpe_tenant_find_or_create(u32 vni)
Find or create a tenant for the given VNI.
#define NSH_FIB_DEFAULT_HASH_MEMORY_SIZE
#define pool_get(P, E)
Allocate an object E from a pool P (unspecified alignment).
Definition: pool.h:252
u32 fib_path_list_child_add(fib_node_index_t path_list_index, fib_node_type_t child_type, fib_node_index_t child_index)
unsigned char u8
Definition: types.h:56
#define fid_addr_mac(_a)
Definition: lisp_types.h:85
vlib_counter_t ** counters
Per-thread u64 non-atomic counter pairs.
Definition: counter.h:190
enum fib_protocol_t_ fib_protocol_t
Protocol Type.
u32 tenant
The tenant the entry belongs to.
void fib_node_register_type(fib_node_type_t type, const fib_node_vft_t *vft)
fib_node_register_type
Definition: fib_node.c:60
static void delete_fib_entries(lisp_gpe_fwd_entry_t *lfe)
ip_prefix_t ippref
Definition: lisp_types.h:73
index_t load_balance_create(u32 n_buckets, dpo_proto_t lb_proto, flow_hash_config_t fhc)
Definition: load_balance.c:263
const dpo_id_t * drop_dpo_get(dpo_proto_t proto)
Definition: drop_dpo.c:25
static clib_error_t * lisp_gpe_fwd_entry_show(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
static lisp_gpe_main_t * vnet_lisp_gpe_get_main()
Definition: lisp_gpe.h:183
const dpo_id_t * nsh_cp_lkup
Definition: lisp_gpe.h:158
static int add_ip_fwd_entry(lisp_gpe_main_t *lgm, vnet_lisp_gpe_add_del_fwd_entry_args_t *a)
Add/Delete LISP IP forwarding entry.
enum lisp_gpe_fwd_entry_format_flag_t_ lisp_gpe_fwd_entry_format_flag_t
static fib_node_index_t ip_src_fib_add_route(u32 src_fib_index, const ip_prefix_t *src_prefix, const lisp_fwd_path_t *paths)
Add route to IP4 or IP6 SRC FIB.
#define pool_foreach(VAR, POOL, BODY)
Iterate through pool.
Definition: pool.h:513
u32 frp_sw_if_index
The interface.
Definition: fib_types.h:530
int clib_bihash_add_del(clib_bihash *h, clib_bihash_kv *add_v, int is_add)
Add or delete a (key,value) pair from a bi-hash table.
#define VLIB_INIT_FUNCTION(x)
Definition: init.h:173
u32 fwd_entry_index
Definition: lisp_gpe.h:95
struct lisp_gpe_fwd_entry_t_::@494::@501 nsh
Fields relevant to an NSH entry.
clib_error_t * lisp_gpe_fwd_entry_init(vlib_main_t *vm)
void fib_table_entry_special_remove(u32 fib_index, const fib_prefix_t *prefix, fib_source_t source)
Remove a &#39;special&#39; entry from the FIB.
Definition: fib_table.c:424
u16 lb_n_buckets_minus_1
number of buckets in the load-balance - 1.
Definition: load_balance.h:121
vlib_combined_counter_main_t counters
Definition: lisp_gpe.h:164
LISP-GPE fwd entry key.
u8 is_add
Definition: lisp_gpe.h:234
u8 * format_fib_prefix(u8 *s, va_list *args)
Definition: fib_types.c:264
static void lisp_gpe_fwd_entry_mk_paths(lisp_gpe_fwd_entry_t *lfe, vnet_lisp_gpe_add_del_fwd_entry_args_t *a)
void lisp_gpe_adjacency_unlock(index_t lai)
lisp_gpe_fwd_entry_type_t type
The forwarding entry type.
void vnet_lisp_gpe_del_fwd_counters(vnet_lisp_gpe_add_del_fwd_entry_args_t *a, u32 fwd_entry_index)
Aggregate type for a prefix.
Definition: fib_types.h:203
uword * lisp_gpe_fwd_entries
DB of all forwarding entries.
Definition: lisp_gpe.h:124
#define hash_get_pair(h, key)
Definition: hash.h:252
unsigned int u32
Definition: types.h:88
Contribute an object that is to be used to forward Ethernet packets.
Definition: fib_types.h:141
enum dpo_proto_t_ dpo_proto_t
Data path protocol.
#define vlib_call_init_function(vm, x)
Definition: init.h:270
dp_address_t rmt
uword * bd_index_by_bd_id
Definition: l2_bd.h:36
Definition: lisp_gpe.h:227
i32 priority
Definition: ipsec.api:95
Common utility functions for IPv4, IPv6 and L2 LISP-GPE adjacencys.
static void make_mac_fib_key(BVT(clib_bihash_kv) *kv, u16 bd_index, u8 src_mac[6], u8 dst_mac[6])
Definition: fib_entry.h:112
void gid_to_dp_address(gid_address_t *g, dp_address_t *d)
Definition: lisp_types.c:489
vl_api_fib_path_type_t type
Definition: fib_types.api:123
The identity of a DPO is a combination of its type and its instance number/index of objects of that t...
Definition: dpo.h:170
vnet_crypto_main_t * cm
Definition: quic_crypto.c:53
#define hash_get(h, key)
Definition: hash.h:249
Definition: fib_entry.h:116
#define pool_elt_at_index(p, i)
Returns pointer to element at given index.
Definition: pool.h:534
static void vlib_zero_combined_counter(vlib_combined_counter_main_t *cm, u32 index)
Clear a combined counter Clears the set of per-thread counters.
Definition: counter.h:285
fib_node_index_t fib_path_list_create(fib_path_list_flags_t flags, const fib_route_path_t *rpaths)
#define hash_unset_mem(h, key)
Definition: hash.h:291
static int lisp_gpe_fwd_entry_path_sort(void *a1, void *a2)
u32 table_id
table (vrf) id
Definition: lisp_gpe.h:267
u8 * format_negative_mapping_action(u8 *s, va_list *args)
Definition: lisp_types.c:360
static u32 lisp_nsh_fib_add_del_entry(u32 spi_si_host_order, u32 lfei, u8 is_add)
Add/del NSH FIB entry.
index_t dpoi_index
used for getting load balance statistics
static int del_ip_fwd_entry(lisp_gpe_main_t *lgm, vnet_lisp_gpe_add_del_fwd_entry_args_t *a)
Add/Delete LISP IP forwarding entry.
static const dpo_id_t * load_balance_get_bucket_i(const load_balance_t *lb, u32 bucket)
Definition: load_balance.h:229
long ctx[MAX_CONNS]
Definition: main.c:144
u32 vlib_combined_counter_n_counters(const vlib_combined_counter_main_t *cm)
The number of counters (not the number of per-thread counters)
Definition: counter.c:175
struct _unformat_input_t unformat_input_t
unsigned short u16
Definition: types.h:57
static void del_l2_fwd_entry_i(lisp_gpe_main_t *lgm, lisp_gpe_fwd_entry_t *lfe)
load-balancing over a choice of [un]equal cost paths
Definition: dpo.h:102
#define pool_put(P, E)
Free an object E in pool P.
Definition: pool.h:302
int vnet_lisp_flush_stats(void)
The FIB DPO provieds;.
Definition: load_balance.h:106
u32 fib_table_get_num_entries(u32 fib_index, fib_protocol_t proto, fib_source_t source)
Return the number of entries in the FIB added by a given source.
Definition: fib_table.c:1322
#define vec_del1(v, i)
Delete the element at index I.
Definition: vec.h:875
u32 sw_if_index
The SW IF index of the sub-interface this adjacency uses.
const lisp_gpe_adjacency_t * lisp_gpe_adjacency_get(index_t lai)
fib_protocol_t ip_address_to_46(const ip_address_t *addr, ip46_address_t *a)
Definition: ip_types.c:250
void lookup_dpo_add_or_lock_w_fib_index(fib_node_index_t fib_index, dpo_proto_t proto, lookup_cast_t cast, lookup_input_t input, lookup_table_t table_config, dpo_id_t *dpo)
Definition: lookup_dpo.c:137
load_balance_main_t load_balance_main
The one instance of load-balance main.
Definition: load_balance.c:56
static u32 ip_dst_fib_add_route(u32 dst_fib_index, const ip_prefix_t *dst_prefix)
Add route to IP4 or IP6 Destination FIB.
An node in the FIB graph.
Definition: fib_node.h:295
void clib_bihash_init(clib_bihash *h, char *name, u32 nbuckets, uword memory_size)
initialize a bounded index extensible hash table
void fib_table_unlock(u32 fib_index, fib_protocol_t proto, fib_source_t source)
Take a reference counting lock on the table.
Definition: fib_table.c:1291
Definition: lisp_gpe.h:283
#define gid_address_ippref(_a)
Definition: lisp_types.h:204
#define L2_FIB_DEFAULT_HASH_MEMORY_SIZE
u8 is_negative
type of mapping
Definition: lisp_gpe.h:237
BVT(clib_bihash)
Definition: l2_fib.c:972
vl_api_prefix_t src_prefix
Definition: acl_types.api:44
index_t lisp_gpe_adjacency_find_or_create_and_lock(const locator_pair_t *pair, u32 overlay_table_id, u32 vni)
u32 vni
VNI/tenant id in HOST byte order.
Definition: lisp_gpe.h:261
int fib_entry_is_sourced(fib_node_index_t fib_entry_index, fib_source_t source)
u32 fwd_entry_index
forwarding entry index of
Definition: lisp_gpe.h:230
svmdb_client_t * c
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
sll srl srl sll sra u16x4 i
Definition: vector_sse42.h:317
Contribute an object that is to be used to forward NSH packets.
Definition: fib_types.h:147
#define vec_free(V)
Free vector&#39;s memory (no header).
Definition: vec.h:380
void fib_table_entry_delete(u32 fib_index, const fib_prefix_t *prefix, fib_source_t source)
Delete a FIB entry.
Definition: fib_table.c:886
vnet_main_t * vnet_main
Definition: lisp_gpe.h:172
static void lisp_gpe_fwd_entry_fib_node_last_lock_gone(fib_node_t *node)
An indication from the graph that the last lock has gone.
#define clib_warning(format, args...)
Definition: error.h:59
fib_node_get_t fnv_get
Definition: fib_node.h:283
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:299
void dpo_set(dpo_id_t *dpo, dpo_type_t type, dpo_proto_t proto, index_t index)
Set/create a DPO ID The DPO will be locked.
Definition: dpo.c:186
lisp_gpe_main_t lisp_gpe_main
LISP-GPE global state.
Definition: lisp_gpe.c:30
static int del_l2_fwd_entry(lisp_gpe_main_t *lgm, vnet_lisp_gpe_add_del_fwd_entry_args_t *a)
Delete LISP L2 forwarding entry.
fib_entry_t * fib_entry_get(fib_node_index_t index)
Definition: fib_entry.c:51
vlib_main_t vlib_node_runtime_t * node
Definition: in2out_ed.c:1582
vl_api_mac_address_t src_mac
Definition: acl_types.api:93
#define fid_addr_ippref(_a)
Definition: lisp_types.h:82
Context passed between object during a back walk.
Definition: fib_node.h:208
vl_api_fib_path_t paths[n_paths]
Definition: ip.api:146
#define VLIB_CLI_COMMAND(x,...)
Definition: cli.h:158
static int add_nsh_fwd_entry(lisp_gpe_main_t *lgm, vnet_lisp_gpe_add_del_fwd_entry_args_t *a)
Add LISP NSH forwarding entry.
static lisp_gpe_fwd_entry_t * lisp_gpe_fwd_entry_from_fib_node(fib_node_t *node)
conver from the embedded fib_node_t struct to the LSIP entry
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.
fib_node_index_t fib_table_entry_special_dpo_add(u32 fib_index, const fib_prefix_t *prefix, fib_source_t source, fib_entry_flag_t flags, const dpo_id_t *dpo)
Add a &#39;special&#39; entry to the FIB that links to the DPO passed A special entry is an entry that the FI...
Definition: fib_table.c:324
static u8 * format_lisp_gpe_fwd_entry(u8 *s, va_list *ap)
u8 value
Definition: qos.api:54
#define ASSERT(truth)
#define fid_addr_type(_a)
Definition: lisp_types.h:87
const void * fib_entry_get_source_data(fib_node_index_t fib_entry_index, fib_source_t source)
u8 * placeholder_stats_pool
Definition: lisp_gpe.h:162
void vlib_cli_output(vlib_main_t *vm, char *fmt,...)
Definition: cli.c:696
int clib_bihash_search_inline_2(clib_bihash *h, clib_bihash_kv *search_key, clib_bihash_kv *valuep)
Search a bi-hash table.
static void del_nsh_fwd_entry_i(lisp_gpe_main_t *lgm, lisp_gpe_fwd_entry_t *lfe)
static load_balance_t * load_balance_get(index_t lbi)
Definition: load_balance.h:220
DROP
Definition: error.def:41
A path on which to forward lisp traffic.
u8 weight
[UE]CMP weigt for the path
static void clib_mem_free(void *p)
Definition: mem.h:215
uword * hw_if_index_by_dp_table
Lookup lisp-gpe interfaces by dp table (eg.
Definition: lisp_gpe.h:84
u32 fib_table_find_or_create_and_lock(fib_protocol_t proto, u32 table_id, fib_source_t src)
Get the index of the FIB for a Table-ID.
Definition: fib_table.c:1156
static fib_node_index_t ip_src_fib_add_route_w_dpo(u32 src_fib_index, const ip_prefix_t *src_prefix, const dpo_id_t *src_dpo)
Add route to IP4 or IP6 SRC FIB.
static lisp_gpe_fwd_entry_t * find_fwd_entry(lisp_gpe_main_t *lgm, vnet_lisp_gpe_add_del_fwd_entry_args_t *a, lisp_gpe_fwd_entry_key_t *key)
u8 is_src_dst
Definition: lisp_gpe.h:232
static u64 mac_to_u64(u8 *m)
dpo_proto_t fib_proto_to_dpo(fib_protocol_t fib_proto)
Definition: fib_types.c:324
static index_t create_fib_entries(lisp_gpe_fwd_entry_t *lfe)
gid_address_t rmt_eid
remote eid
Definition: lisp_gpe.h:246
void load_balance_set_bucket(index_t lbi, u32 bucket, const dpo_id_t *next)
Definition: load_balance.c:280
static void * clib_mem_alloc(uword size)
Definition: mem.h:157
u8 * format_dpo_id(u8 *s, va_list *args)
Format a DPO_id_t oject.
Definition: dpo.c:148
vl_api_ip4_address_t hi
Definition: arp.api:37
u32 entries
dpo_id_t fe_lb
The load-balance used for forwarding.
Definition: fib_entry.h:331
static void gpe_native_fwd_add_del_lfe(lisp_gpe_fwd_entry_t *lfe, u8 is_add)
typedef key
Definition: ipsec_types.api:85
static void lisp_gpe_nsh_update_fwding(lisp_gpe_fwd_entry_t *lfe)
Construct and insert the forwarding information used by an NSH entry.
negative_fwd_actions_e action
action for negative mappings
Definition: lisp_gpe.h:240
A LISP GPE Adjacency.
static vlib_cli_command_t lisp_gpe_fwd_entry_show_command
(constructor) VLIB_CLI_COMMAND (lisp_gpe_fwd_entry_show_command)
u32 eid_fib_index
The FIB index for the overlay, i.e.
index_t dpoi_index
the index of objects of that type
Definition: dpo.h:186
#define FIB_NODE_INDEX_INVALID
Definition: fib_types.h:31
struct lisp_gpe_fwd_entry_t_ * lisp_fwd_entry_pool
A Pool of all LISP forwarding entries.
Definition: lisp_gpe.h:129
#define vec_len(v)
Number of elements in vector (rvalue-only, NULL tolerant)
dpo_id_t l2_lb_cp_lkup
Load-balance for a miss in the table.
Definition: lisp_gpe.h:149
struct lisp_gpe_fwd_entry_t_::@494::@500 l2
Fields relevant to an L2 entry.
u32 tunnel_index
The index of the LISP GPE tunnel that provides the transport in the underlay.
static uword max_log2(uword x)
Definition: clib.h:208
u32 dp_table
generic access
Definition: lisp_gpe.h:273
u64 uword
Definition: types.h:112
#define vec_sort_with_function(vec, f)
Sort a vector using the supplied element comparison function.
Definition: vec.h:1055
static void del_ip_fwd_entry_i(lisp_gpe_main_t *lgm, lisp_gpe_fwd_entry_t *lfe)
static fib_route_path_t * lisp_gpe_mk_fib_paths(const lisp_fwd_path_t *paths)
locator_pair_t * locator_pairs
vector of locator pairs
Definition: lisp_gpe.h:249
#define DPO_INVALID
An initialiser for DPOs declared on the stack.
Definition: dpo.h:197
u32 index
Definition: flow_types.api:221
#define ip_prefix_version(_a)
Definition: ip_types.h:88
A collection of combined counters.
Definition: counter.h:188
void fib_path_list_contribute_forwarding(fib_node_index_t path_list_index, fib_forward_chain_type_t fct, fib_path_list_fwd_flags_t flags, dpo_id_t *dpo)
lisp_fwd_path_t * paths
When the type is &#39;normal&#39; The RLOC pair that form the route&#39;s paths.
#define hash_get_mem(h, key)
Definition: hash.h:269
static void nsh_fib_init(lisp_gpe_main_t *lgm)
A FIB graph nodes virtual function table.
Definition: fib_node.h:282
u8 * format_lisp_gpe_adjacency(u8 *s, va_list *args)
index_t lisp_l2_fib_lookup(lisp_gpe_main_t *lgm, u16 bd_index, u8 src_mac[6], u8 dst_mac[6])
Lookup L2 SD FIB entry.
clib_error_t * lisp_cp_dpo_module_init(vlib_main_t *vm)
Definition: lisp_cp_dpo.c:96
fib_route_path_t * native_fwd_rpath[2]
Native fwd data structures.
Definition: lisp_gpe.h:167
int vnet_lisp_gpe_get_fwd_stats(vnet_lisp_gpe_add_del_fwd_entry_args_t *a, vlib_counter_t *c)
static fib_node_back_walk_rc_t lisp_gpe_fib_node_back_walk(fib_node_t *node, fib_node_back_walk_ctx_t *ctx)
Function invoked during a backwalk of the FIB graph.
void dpo_reset(dpo_id_t *dpo)
reset a DPO ID The DPO will be unlocked.
Definition: dpo.c:232
#define vec_foreach(var, vec)
Vector iterator.
#define NSH_FIB_DEFAULT_HASH_NUM_BUCKETS
uword * lisp_stats_index_by_key
Definition: lisp_gpe.h:163
static void lisp_gpe_l2_update_fwding(lisp_gpe_fwd_entry_t *lfe)
Construct and insert the forwarding information used by an L2 entry.
static int del_nsh_fwd_entry(lisp_gpe_main_t *lgm, vnet_lisp_gpe_add_del_fwd_entry_args_t *a)
Delete LISP NSH forwarding entry.
bd_main_t bd_main
Definition: l2_bd.c:44
u32 vni
u8 frp_weight
[un]equal cost path weight
Definition: fib_types.h:590
fib_node_t node
This object joins the FIB control plane graph to receive updates to for changes to the graph...
u8 * format_fid_address(u8 *s, va_list *args)
Definition: lisp_types.c:166
gid_address_t lcl_eid
local eid
Definition: lisp_gpe.h:243
u32 fib_table_create_and_lock(fib_protocol_t proto, fib_source_t src, const char *const fmt,...)
Create a new table with no table ID.
Definition: fib_table.c:1175
tunnel_lookup_t nsh_ifaces
Definition: lisp_gpe.h:156
u32 * native_fwd_lfes[2]
Definition: lisp_gpe.h:168
#define L2_FIB_DEFAULT_HASH_NUM_BUCKETS
void fib_entry_set_source_data(fib_node_index_t fib_entry_index, fib_source_t source, const void *data)
const dpo_id_t * lisp_nsh_fib_lookup(lisp_gpe_main_t *lgm, u32 spi_si_net_order)
Lookup NSH SD FIB entry.
lisp_gpe_fwd_entry_format_flag_t_
ip_address_t remote_rloc
remote RLOC.
uword key
Definition: hash.h:162
uword unformat(unformat_input_t *i, const char *fmt,...)
Definition: unformat.c:978
lisp_api_gpe_fwd_entry_t * vnet_lisp_gpe_fwd_entries_get_by_vni(u32 vni)
u8 is_src_dst
Follows src/dst or dst only forwarding policy.
index_t lisp_adj
The adjacency constructed for the locator pair.
A LISP Forwarding Entry.