FD.io VPP  v17.04.2-2-ga8f93f8
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
42 ip_dst_fib_add_route (u32 dst_fib_index, const ip_prefix_t * dst_prefix)
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 ||
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,
69  "LISP-src for [%d,%U]",
70  dst_fib_index,
71  format_fib_prefix, &dst_fib_prefix);
72  /*
73  * add src fib default route
74  */
75  fib_prefix_t prefix = {
76  .fp_proto = dst_fib_prefix.fp_proto,
77  };
78  fib_table_entry_special_dpo_add (src_fib_index, &prefix,
82  (dst_fib_prefix.fp_proto)));
83  /*
84  * create a data-path object to perform the source address lookup
85  * in the SRC FIB
86  */
88  (ip_prefix_version (dst_prefix) ==
89  IP6 ? DPO_PROTO_IP6 :
93  &src_lkup_dpo);
94 
95  /*
96  * add the entry to the destination FIB that uses the lookup DPO
97  */
98  dst_fei = fib_table_entry_special_dpo_add (dst_fib_index,
99  &dst_fib_prefix,
102  &src_lkup_dpo);
103 
104  /*
105  * the DPO is locked by the FIB entry, and we have no further
106  * need for it.
107  */
108  dpo_unlock (&src_lkup_dpo);
109 
110  /*
111  * save the SRC FIB index on the entry so we can retrieve it for
112  * subsequent routes.
113  */
114  fib_entry_set_source_data (dst_fei, FIB_SOURCE_LISP, &src_fib_index);
115  }
116  else
117  {
118  /*
119  * destination FIB entry already present
120  */
121  src_fib_index = *(u32 *) fib_entry_get_source_data (dst_fei,
123  }
124 
125  return (src_fib_index);
126 }
127 
128 /**
129  * @brief Del route to IP4 or IP6 SD FIB.
130  *
131  * Remove routes from both destination and source FIBs.
132  *
133  * @param[in] src_fib_index The index/ID of the SRC FIB
134  * @param[in] src_prefix Source IP prefix.
135  * @param[in] dst_fib_index The index/ID of the DST FIB
136  * @param[in] dst_prefix Destination IP prefix.
137  */
138 static void
140  const ip_prefix_t * src_prefix,
141  u32 dst_fib_index, const ip_prefix_t * dst_prefix)
142 {
143  fib_prefix_t dst_fib_prefix, src_fib_prefix;
144  u8 have_default = 0;
145  u32 n_entries;
146 
147  ASSERT (NULL != dst_prefix);
148  ASSERT (NULL != src_prefix);
149 
150  ip_prefix_to_fib_prefix (dst_prefix, &dst_fib_prefix);
151  ip_prefix_to_fib_prefix (src_prefix, &src_fib_prefix);
152 
153  fib_table_entry_delete (src_fib_index, &src_fib_prefix, FIB_SOURCE_LISP);
154 
155  /* check if only default left or empty */
156  fib_prefix_t default_pref = {
157  .fp_proto = dst_fib_prefix.fp_proto
158  };
159 
160  if (fib_table_lookup_exact_match (src_fib_index,
161  &default_pref) != FIB_NODE_INDEX_INVALID)
162  have_default = 1;
163 
164  n_entries = fib_table_get_num_entries (src_fib_index,
165  src_fib_prefix.fp_proto,
167  if (n_entries == 0 || (have_default && n_entries == 1))
168  {
169  /*
170  * remove src FIB default route
171  */
172  if (have_default)
173  fib_table_entry_special_remove (src_fib_index, &default_pref,
175 
176  /*
177  * there's nothing left now, unlock the source FIB and the
178  * destination route
179  */
180  fib_table_entry_special_remove (dst_fib_index,
181  &dst_fib_prefix, FIB_SOURCE_LISP);
182  fib_table_unlock (src_fib_index, src_fib_prefix.fp_proto);
183  }
184 }
185 
186 /**
187  * @brief Add route to IP4 or IP6 SRC FIB.
188  *
189  * Adds a route to in the LISP SRC FIB with the result of the route
190  * being the DPO passed.
191  *
192  * @param[in] src_fib_index The index/ID of the SRC FIB
193  * @param[in] src_prefix Source IP prefix.
194  * @param[in] src_dpo The DPO the route will link to.
195  */
196 static void
198  const ip_prefix_t * src_prefix,
199  const dpo_id_t * src_dpo)
200 {
201  fib_prefix_t src_fib_prefix;
202 
203  ip_prefix_to_fib_prefix (src_prefix, &src_fib_prefix);
204 
205  /*
206  * add the entry into the source fib.
207  */
208  fib_node_index_t src_fei;
209 
210  src_fei = fib_table_lookup_exact_match (src_fib_index, &src_fib_prefix);
211 
212  if (FIB_NODE_INDEX_INVALID == src_fei ||
214  {
215  fib_table_entry_special_dpo_add (src_fib_index,
216  &src_fib_prefix,
218  FIB_ENTRY_FLAG_EXCLUSIVE, src_dpo);
219  }
220 }
221 
222 static fib_route_path_t *
224 {
225  const lisp_gpe_adjacency_t *ladj;
226  fib_route_path_t *rpaths = NULL;
227  u8 best_priority;
228  u32 ii;
229 
230  vec_validate (rpaths, vec_len (paths) - 1);
231 
232  best_priority = paths[0].priority;
233 
234  vec_foreach_index (ii, paths)
235  {
236  if (paths[0].priority != best_priority)
237  break;
238 
239  ladj = lisp_gpe_adjacency_get (paths[ii].lisp_adj);
240 
242  &rpaths[ii].frp_addr, &rpaths[ii].frp_proto);
243 
244  rpaths[ii].frp_sw_if_index = ladj->sw_if_index;
245  rpaths[ii].frp_weight = (paths[ii].weight ? paths[ii].weight : 1);
246  }
247 
248  ASSERT (0 != vec_len (rpaths));
249 
250  return (rpaths);
251 }
252 
253 /**
254  * @brief Add route to IP4 or IP6 SRC FIB.
255  *
256  * Adds a route to in the LISP SRC FIB for the tunnel.
257  *
258  * @param[in] src_fib_index The index/ID of the SRC FIB
259  * @param[in] src_prefix Source IP prefix.
260  * @param[in] paths The paths from which to construct the
261  * load balance
262  */
263 static void
264 ip_src_fib_add_route (u32 src_fib_index,
265  const ip_prefix_t * src_prefix,
266  const lisp_fwd_path_t * paths)
267 {
268  fib_prefix_t src_fib_prefix;
269  fib_route_path_t *rpaths;
270 
271  ip_prefix_to_fib_prefix (src_prefix, &src_fib_prefix);
272 
273  rpaths = lisp_gpe_mk_fib_paths (paths);
274 
275  fib_table_entry_update (src_fib_index,
276  &src_fib_prefix,
278  vec_free (rpaths);
279 }
280 
281 
282 static void
284 {
285  dpo_proto_t dproto;
286  ip_prefix_t ippref;
287  dproto = (ip_prefix_version (&lfe->key->rmt.ippref) == IP4 ?
289 
290  if (lfe->is_src_dst)
291  {
293  &lfe->key->rmt.ippref);
294  memcpy (&ippref, &lfe->key->lcl.ippref, sizeof (ippref));
295  }
296  else
297  {
298  lfe->src_fib_index = lfe->eid_fib_index;
299  memcpy (&ippref, &lfe->key->rmt.ippref, sizeof (ippref));
300  }
301 
303  {
304  dpo_id_t dpo = DPO_INVALID;
305 
306  switch (lfe->action)
307  {
308  case LISP_NO_ACTION:
309  /* TODO update timers? */
310  case LISP_FORWARD_NATIVE:
311  /* TODO check if route/next-hop for eid exists in fib and add
312  * more specific for the eid with the next-hop found */
314  /* insert tunnel that always sends map-request */
315  dpo_copy (&dpo, lisp_cp_dpo_get (dproto));
316  break;
317  case LISP_DROP:
318  /* for drop fwd entries, just add route, no need to add encap tunnel */
319  dpo_copy (&dpo, drop_dpo_get (dproto));
320  break;
321  }
322  ip_src_fib_add_route_w_dpo (lfe->src_fib_index, &ippref, &dpo);
323  dpo_reset (&dpo);
324  }
325  else
326  {
327  ip_src_fib_add_route (lfe->src_fib_index, &ippref, lfe->paths);
328  }
329 }
330 
331 static void
333 {
334  fib_prefix_t dst_fib_prefix;
335 
336  if (lfe->is_src_dst)
338  &lfe->key->lcl.ippref,
339  lfe->eid_fib_index, &lfe->key->rmt.ippref);
340  else
341  {
342  ip_prefix_to_fib_prefix (&lfe->key->rmt.ippref, &dst_fib_prefix);
343  fib_table_entry_delete (lfe->src_fib_index, &dst_fib_prefix,
345  }
346 }
347 
348 static lisp_gpe_fwd_entry_t *
352 {
353  uword *p;
354 
355  memset (key, 0, sizeof (*key));
356 
358  {
359  /*
360  * the ip version of the source is not set to ip6 when the
361  * source is all zeros. force it.
362  */
365  }
366 
367  gid_to_dp_address (&a->rmt_eid, &key->rmt);
368  gid_to_dp_address (&a->lcl_eid, &key->lcl);
369  key->vni = a->vni;
370 
371  p = hash_get_mem (lgm->lisp_gpe_fwd_entries, key);
372 
373  if (NULL != p)
374  {
375  return (pool_elt_at_index (lgm->lisp_fwd_entry_pool, p[0]));
376  }
377  return (NULL);
378 }
379 
380 static int
381 lisp_gpe_fwd_entry_path_sort (void *a1, void *a2)
382 {
383  lisp_fwd_path_t *p1 = a1, *p2 = a2;
384 
385  return (p1->priority - p2->priority);
386 }
387 
388 static void
391 {
392  lisp_fwd_path_t *path;
393  u32 index;
394 
395  vec_validate (lfe->paths, vec_len (a->locator_pairs) - 1);
396 
397  vec_foreach_index (index, a->locator_pairs)
398  {
399  path = &lfe->paths[index];
400 
401  path->priority = a->locator_pairs[index].priority;
402  path->weight = a->locator_pairs[index].weight;
403 
404  path->lisp_adj =
406  [index],
407  a->dp_table, lfe->key->vni);
408  }
410 }
411 
412 void
414  u32 fwd_entry_index)
415 {
416  const lisp_gpe_adjacency_t *ladj;
417  lisp_fwd_path_t *path;
421  lisp_stats_key_t key, *stats_key;
422 
423  lfe = find_fwd_entry (lgm, a, &fe_key);
424 
426  return;
427 
428  memset (&key, 0, sizeof (key));
429  key.fwd_entry_index = fwd_entry_index;
430 
431  vec_foreach (path, lfe->paths)
432  {
433  ladj = lisp_gpe_adjacency_get (path->lisp_adj);
434  key.tunnel_index = ladj->tunnel_index;
435 
436  pool_get (lgm->stats_key_pool, stats_key);
437  memcpy (stats_key, &key, sizeof (key));
438  hash_set_mem (lgm->lisp_stats_index_by_key, stats_key,
439  stats_key - lgm->stats_key_pool);
440 
442  stats_key - lgm->stats_key_pool);
444  stats_key - lgm->stats_key_pool);
445  }
446 }
447 
448 /**
449  * @brief Add/Delete LISP IP forwarding entry.
450  *
451  * creation of forwarding entries for IP LISP overlay:
452  *
453  * @param[in] lgm Reference to @ref lisp_gpe_main_t.
454  * @param[in] a Parameters for building the forwarding entry.
455  *
456  * @return 0 on success.
457  */
458 static int
461 {
464  fib_protocol_t fproto;
465 
466  lfe = find_fwd_entry (lgm, a, &key);
467 
468  if (NULL != lfe)
469  /* don't support updates */
470  return VNET_API_ERROR_INVALID_VALUE;
471 
472  pool_get (lgm->lisp_fwd_entry_pool, lfe);
473  memset (lfe, 0, sizeof (*lfe));
474  lfe->key = clib_mem_alloc (sizeof (key));
475  memcpy (lfe->key, &key, sizeof (key));
476 
478  lfe - lgm->lisp_fwd_entry_pool);
479 
480  fproto = (IP4 == ip_prefix_version (&fid_addr_ippref (&lfe->key->rmt)) ?
482 
483  lfe->type = (a->is_negative ?
487  lfe->eid_table_id = a->table_id;
489  lfe->eid_table_id);
490  lfe->is_src_dst = a->is_src_dst;
491 
493  {
495  }
496 
497  create_fib_entries (lfe);
498  return (0);
499 }
500 
501 static void
503 {
504  lisp_fwd_path_t *path;
505  fib_protocol_t fproto;
506 
507  vec_foreach (path, lfe->paths)
508  {
510  }
511 
512  delete_fib_entries (lfe);
513 
514  fproto = (IP4 == ip_prefix_version (&fid_addr_ippref (&lfe->key->rmt)) ?
516  fib_table_unlock (lfe->eid_fib_index, fproto);
517 
519  clib_mem_free (lfe->key);
520  pool_put (lgm->lisp_fwd_entry_pool, lfe);
521 }
522 
523 /**
524  * @brief Add/Delete LISP IP forwarding entry.
525  *
526  * removal of forwarding entries for IP LISP overlay:
527  *
528  * @param[in] lgm Reference to @ref lisp_gpe_main_t.
529  * @param[in] a Parameters for building the forwarding entry.
530  *
531  * @return 0 on success.
532  */
533 static int
536 {
539 
540  lfe = find_fwd_entry (lgm, a, &key);
541 
542  if (NULL == lfe)
543  /* no such entry */
544  return VNET_API_ERROR_INVALID_VALUE;
545 
546  del_ip_fwd_entry_i (lgm, lfe);
547 
548  return (0);
549 }
550 
551 static void
552 make_mac_fib_key (BVT (clib_bihash_kv) * kv, u16 bd_index, u8 src_mac[6],
553  u8 dst_mac[6])
554 {
555  kv->key[0] = (((u64) bd_index) << 48) | mac_to_u64 (dst_mac);
556  kv->key[1] = mac_to_u64 (src_mac);
557  kv->key[2] = 0;
558 }
559 
560 /**
561  * @brief Lookup L2 SD FIB entry
562  *
563  * Does a vni + dest + source lookup in the L2 LISP FIB. If the lookup fails
564  * it tries a second time with source set to 0 (i.e., a simple dest lookup).
565  *
566  * @param[in] lgm Reference to @ref lisp_gpe_main_t.
567  * @param[in] bd_index Bridge domain index.
568  * @param[in] src_mac Source mac address.
569  * @param[in] dst_mac Destination mac address.
570  *
571  * @return index of mapping matching the lookup key.
572  */
573 index_t
574 lisp_l2_fib_lookup (lisp_gpe_main_t * lgm, u16 bd_index, u8 src_mac[6],
575  u8 dst_mac[6])
576 {
577  int rv;
578  BVT (clib_bihash_kv) kv, value;
579 
580  make_mac_fib_key (&kv, bd_index, src_mac, dst_mac);
581  rv = BV (clib_bihash_search_inline_2) (&lgm->l2_fib, &kv, &value);
582 
583  /* no match, try with src 0, catch all for dst */
584  if (rv != 0)
585  {
586  kv.key[1] = 0;
587  rv = BV (clib_bihash_search_inline_2) (&lgm->l2_fib, &kv, &value);
588  if (rv == 0)
589  return value.value;
590  }
591  else
592  return value.value;
593 
595 }
596 
597 /**
598  * @brief Add/del L2 SD FIB entry
599  *
600  * Inserts value in L2 FIB keyed by vni + dest + source. If entry is
601  * overwritten the associated value is returned.
602  *
603  * @param[in] lgm Reference to @ref lisp_gpe_main_t.
604  * @param[in] bd_index Bridge domain index.
605  * @param[in] src_mac Source mac address.
606  * @param[in] dst_mac Destination mac address.
607  * @param[in] val Value to add.
608  * @param[in] is_add Add/del flag.
609  *
610  * @return ~0 or value of overwritten entry.
611  */
612 static u32
613 lisp_l2_fib_add_del_entry (u16 bd_index, u8 src_mac[6],
614  u8 dst_mac[6], const dpo_id_t * dpo, u8 is_add)
615 {
617  BVT (clib_bihash_kv) kv, value;
618  u32 old_val = ~0;
619 
620  make_mac_fib_key (&kv, bd_index, src_mac, dst_mac);
621 
622  if (BV (clib_bihash_search) (&lgm->l2_fib, &kv, &value) == 0)
623  old_val = value.value;
624 
625  if (!is_add)
626  BV (clib_bihash_add_del) (&lgm->l2_fib, &kv, 0 /* is_add */ );
627  else
628  {
629  kv.value = dpo->dpoi_index;
630  BV (clib_bihash_add_del) (&lgm->l2_fib, &kv, 1 /* is_add */ );
631  }
632  return old_val;
633 }
634 
635 #define L2_FIB_DEFAULT_HASH_NUM_BUCKETS (64 * 1024)
636 #define L2_FIB_DEFAULT_HASH_MEMORY_SIZE (32<<20)
637 
638 static void
640 {
641  index_t lbi;
642 
643  BV (clib_bihash_init) (&lgm->l2_fib, "l2 fib",
646 
647  /*
648  * the result from a 'miss' in a L2 Table
649  */
652 
654 }
655 
656 static void
658 {
659  lisp_fwd_path_t *path;
660 
662  {
663  vec_foreach (path, lfe->paths)
664  {
666  }
667  fib_path_list_child_remove (lfe->l2.path_list_index,
668  lfe->l2.child_index);
669  }
670 
671  lisp_l2_fib_add_del_entry (lfe->l2.eid_bd_index,
672  fid_addr_mac (&lfe->key->lcl),
673  fid_addr_mac (&lfe->key->rmt), NULL, 0);
674 
676  clib_mem_free (lfe->key);
677  pool_put (lgm->lisp_fwd_entry_pool, lfe);
678 }
679 
680 /**
681  * @brief Delete LISP L2 forwarding entry.
682  *
683  * Coordinates the removal of forwarding entries for L2 LISP overlay:
684  *
685  * @param[in] lgm Reference to @ref lisp_gpe_main_t.
686  * @param[in] a Parameters for building the forwarding entry.
687  *
688  * @return 0 on success.
689  */
690 static int
693 {
696 
697  lfe = find_fwd_entry (lgm, a, &key);
698 
699  if (NULL == lfe)
700  return VNET_API_ERROR_INVALID_VALUE;
701 
702  del_l2_fwd_entry_i (lgm, lfe);
703 
704  return (0);
705 }
706 
707 /**
708  * @brief Construct and insert the forwarding information used by an L2 entry
709  */
710 static void
712 {
714  dpo_id_t dpo = DPO_INVALID;
715 
717  {
718  fib_path_list_contribute_forwarding (lfe->l2.path_list_index,
720  &lfe->l2.dpo);
721  dpo_copy (&dpo, &lfe->l2.dpo);
722  }
723  else
724  {
725  switch (lfe->action)
726  {
727  case SEND_MAP_REQUEST:
728  dpo_copy (&dpo, &lgm->l2_lb_cp_lkup);
729  break;
730  case NO_ACTION:
731  case FORWARD_NATIVE:
732  case DROP:
734  }
735  }
736 
737  /* add entry to l2 lisp fib */
738  lisp_l2_fib_add_del_entry (lfe->l2.eid_bd_index,
739  fid_addr_mac (&lfe->key->lcl),
740  fid_addr_mac (&lfe->key->rmt), &dpo, 1);
741 
742  dpo_reset (&dpo);
743 }
744 
745 /**
746  * @brief Add LISP L2 forwarding entry.
747  *
748  * Coordinates the creation of forwarding entries for L2 LISP overlay:
749  * creates lisp-gpe tunnel and injects new entry in Source/Dest L2 FIB.
750  *
751  * @param[in] lgm Reference to @ref lisp_gpe_main_t.
752  * @param[in] a Parameters for building the forwarding entry.
753  *
754  * @return 0 on success.
755  */
756 static int
759 {
761  bd_main_t *bdm = &bd_main;
763  uword *bd_indexp;
764 
765  bd_indexp = hash_get (bdm->bd_index_by_bd_id, a->bd_id);
766  if (!bd_indexp)
767  {
768  clib_warning ("bridge domain %d doesn't exist", a->bd_id);
769  return -1;
770  }
771 
772  lfe = find_fwd_entry (lgm, a, &key);
773 
774  if (NULL != lfe)
775  /* don't support updates */
776  return VNET_API_ERROR_INVALID_VALUE;
777 
778  pool_get (lgm->lisp_fwd_entry_pool, lfe);
779  memset (lfe, 0, sizeof (*lfe));
780  lfe->key = clib_mem_alloc (sizeof (key));
781  memcpy (lfe->key, &key, sizeof (key));
782 
784  lfe - lgm->lisp_fwd_entry_pool);
785 
786  lfe->type = (a->is_negative ?
789  lfe->l2.eid_bd_id = a->bd_id;
790  lfe->l2.eid_bd_index = bd_indexp[0];
792 
794  {
795  fib_route_path_t *rpaths;
796 
797  /*
798  * Make the sorted array of LISP paths with their resp. adjacency
799  */
801 
802  /*
803  * From the LISP paths, construct a FIB path list that will
804  * contribute a load-balance.
805  */
806  rpaths = lisp_gpe_mk_fib_paths (lfe->paths);
807 
808  lfe->l2.path_list_index =
810 
811  /*
812  * become a child of the path-list so we receive updates when
813  * its forwarding state changes. this includes an implicit lock.
814  */
815  lfe->l2.child_index =
816  fib_path_list_child_add (lfe->l2.path_list_index,
818  lfe - lgm->lisp_fwd_entry_pool);
819  }
820  else
821  {
822  lfe->action = a->action;
823  }
824 
826 
827  return 0;
828 }
829 
830 /**
831  * @brief Lookup NSH SD FIB entry
832  *
833  * Does an SPI+SI lookup in the NSH LISP FIB.
834  *
835  * @param[in] lgm Reference to @ref lisp_gpe_main_t.
836  * @param[in] spi_si SPI + SI.
837  *
838  * @return next node index.
839  */
840 const dpo_id_t *
841 lisp_nsh_fib_lookup (lisp_gpe_main_t * lgm, u32 spi_si_net_order)
842 {
843  int rv;
844  BVT (clib_bihash_kv) kv, value;
845 
846  memset (&kv, 0, sizeof (kv));
847  kv.key[0] = spi_si_net_order;
848  rv = BV (clib_bihash_search_inline_2) (&lgm->nsh_fib, &kv, &value);
849 
850  if (rv != 0)
851  {
852  return lgm->nsh_cp_lkup;
853  }
854  else
855  {
857  lfe = pool_elt_at_index (lgm->lisp_fwd_entry_pool, value.value);
858  return &lfe->nsh.choice;
859  }
860 }
861 
862 /**
863  * @brief Add/del NSH FIB entry
864  *
865  * Inserts value in NSH FIB keyed by SPI+SI. If entry is
866  * overwritten the associated value is returned.
867  *
868  * @param[in] lgm Reference to @ref lisp_gpe_main_t.
869  * @param[in] spi_si SPI + SI.
870  * @param[in] dpo Load balanced mapped to SPI + SI
871  *
872  * @return ~0 or value of overwritten entry.
873  */
874 static u32
875 lisp_nsh_fib_add_del_entry (u32 spi_si_host_order, u32 lfei, u8 is_add)
876 {
878  BVT (clib_bihash_kv) kv, value;
879  u32 old_val = ~0;
880 
881  memset (&kv, 0, sizeof (kv));
882  kv.key[0] = clib_host_to_net_u32 (spi_si_host_order);
883  kv.value = 0ULL;
884 
885  if (BV (clib_bihash_search) (&lgm->nsh_fib, &kv, &value) == 0)
886  old_val = value.value;
887 
888  if (!is_add)
889  BV (clib_bihash_add_del) (&lgm->nsh_fib, &kv, 0 /* is_add */ );
890  else
891  {
892  kv.value = lfei;
893  BV (clib_bihash_add_del) (&lgm->nsh_fib, &kv, 1 /* is_add */ );
894  }
895  return old_val;
896 }
897 
898 #define NSH_FIB_DEFAULT_HASH_NUM_BUCKETS (64 * 1024)
899 #define NSH_FIB_DEFAULT_HASH_MEMORY_SIZE (32<<20)
900 
901 static void
903 {
904  BV (clib_bihash_init) (&lgm->nsh_fib, "nsh fib",
907 
908  /*
909  * the result from a 'miss' in a NSH Table
910  */
912 }
913 
914 static void
916 {
917  lisp_fwd_path_t *path;
918 
920  {
921  vec_foreach (path, lfe->paths)
922  {
924  }
925  fib_path_list_child_remove (lfe->nsh.path_list_index,
926  lfe->nsh.child_index);
927  dpo_reset (&lfe->nsh.choice);
928  }
929 
930  lisp_nsh_fib_add_del_entry (fid_addr_nsh (&lfe->key->rmt), (u32) ~ 0, 0);
931 
933  clib_mem_free (lfe->key);
934  pool_put (lgm->lisp_fwd_entry_pool, lfe);
935 }
936 
937 /**
938  * @brief Delete LISP NSH forwarding entry.
939  *
940  * Coordinates the removal of forwarding entries for NSH LISP overlay:
941  *
942  * @param[in] lgm Reference to @ref lisp_gpe_main_t.
943  * @param[in] a Parameters for building the forwarding entry.
944  *
945  * @return 0 on success.
946  */
947 static int
950 {
953 
954  lfe = find_fwd_entry (lgm, a, &key);
955 
956  if (NULL == lfe)
957  return VNET_API_ERROR_INVALID_VALUE;
958 
959  del_nsh_fwd_entry_i (lgm, lfe);
960 
961  return (0);
962 }
963 
964 /**
965  * @brief Construct and insert the forwarding information used by an NSH entry
966  */
967 static void
969 {
971  dpo_id_t dpo = DPO_INVALID;
973  uword *hip;
974 
976  {
977  fib_path_list_contribute_forwarding (lfe->nsh.path_list_index,
979  &lfe->nsh.dpo);
980 
981  /*
982  * LISP encap is always the same for this SPI+SI so we do that hash now
983  * and stack on the choice.
984  */
985  if (DPO_LOAD_BALANCE == lfe->nsh.dpo.dpoi_type)
986  {
987  const dpo_id_t *tmp;
988  const load_balance_t *lb;
989  int hash;
990 
991  lb = load_balance_get (lfe->nsh.dpo.dpoi_index);
992  hash = fid_addr_nsh (&lfe->key->rmt) % lb->lb_n_buckets;
993  tmp =
995 
996  dpo_copy (&dpo, tmp);
997  }
998  }
999  else
1000  {
1001  switch (lfe->action)
1002  {
1003  case SEND_MAP_REQUEST:
1004  dpo_copy (&dpo, lgm->nsh_cp_lkup);
1005  break;
1006  case NO_ACTION:
1007  case FORWARD_NATIVE:
1008  case DROP:
1010  }
1011  }
1012 
1013  /* We have only one nsh-lisp interface (no NSH virtualization) */
1015  if (hip)
1016  {
1017  hi = vnet_get_hw_interface (lgm->vnet_main, hip[0]);
1018  dpo_stack_from_node (hi->tx_node_index, &lfe->nsh.choice, &dpo);
1019  }
1020  /* add entry to nsh lisp fib */
1022  lfe - lgm->lisp_fwd_entry_pool, 1);
1023  dpo_reset (&dpo);
1024 
1025 }
1026 
1027 /**
1028  * @brief Add LISP NSH forwarding entry.
1029  *
1030  * Coordinates the creation of forwarding entries for L2 LISP overlay:
1031  * creates lisp-gpe tunnel and injects new entry in Source/Dest L2 FIB.
1032  *
1033  * @param[in] lgm Reference to @ref lisp_gpe_main_t.
1034  * @param[in] a Parameters for building the forwarding entry.
1035  *
1036  * @return 0 on success.
1037  */
1038 static int
1041 {
1043  lisp_gpe_fwd_entry_t *lfe;
1044 
1045  lfe = find_fwd_entry (lgm, a, &key);
1046 
1047  if (NULL != lfe)
1048  /* don't support updates */
1049  return VNET_API_ERROR_INVALID_VALUE;
1050 
1051  pool_get (lgm->lisp_fwd_entry_pool, lfe);
1052  memset (lfe, 0, sizeof (*lfe));
1053  lfe->key = clib_mem_alloc (sizeof (key));
1054  memcpy (lfe->key, &key, sizeof (key));
1055 
1057  lfe - lgm->lisp_fwd_entry_pool);
1058 
1059  lfe->type = (a->is_negative ?
1062  lfe->tenant = 0;
1063 
1065  {
1066  fib_route_path_t *rpaths;
1067 
1068  /*
1069  * Make the sorted array of LISP paths with their resp. adjacency
1070  */
1071  lisp_gpe_fwd_entry_mk_paths (lfe, a);
1072 
1073  /*
1074  * From the LISP paths, construct a FIB path list that will
1075  * contribute a load-balance.
1076  */
1077  rpaths = lisp_gpe_mk_fib_paths (lfe->paths);
1078 
1079  lfe->nsh.path_list_index =
1081 
1082  /*
1083  * become a child of the path-list so we receive updates when
1084  * its forwarding state changes. this includes an implicit lock.
1085  */
1086  lfe->nsh.child_index =
1087  fib_path_list_child_add (lfe->nsh.path_list_index,
1089  lfe - lgm->lisp_fwd_entry_pool);
1090  }
1091  else
1092  {
1093  lfe->action = a->action;
1094  }
1095 
1097 
1098  return 0;
1099 }
1100 
1101 /**
1102  * @brief conver from the embedded fib_node_t struct to the LSIP entry
1103  */
1104 static lisp_gpe_fwd_entry_t *
1106 {
1107  return ((lisp_gpe_fwd_entry_t *) (((char *) node) -
1109  node)));
1110 }
1111 
1112 /**
1113  * @brief Function invoked during a backwalk of the FIB graph
1114  */
1118 {
1120 
1121  if (fid_addr_type (&lfe->key->rmt) == FID_ADDR_MAC)
1123  else if (fid_addr_type (&lfe->key->rmt) == FID_ADDR_NSH)
1125 
1126  return (FIB_NODE_BACK_WALK_CONTINUE);
1127 }
1128 
1129 /**
1130  * @brief Get a fib_node_t struct from the index of a LISP fwd entry
1131  */
1132 static fib_node_t *
1134 {
1136  lisp_gpe_fwd_entry_t *lfe;
1137 
1138  lfe = pool_elt_at_index (lgm->lisp_fwd_entry_pool, index);
1139 
1140  return (&(lfe->node));
1141 }
1142 
1143 /**
1144  * @brief An indication from the graph that the last lock has gone
1145  */
1146 static void
1148 {
1149  /* We don't manage the locks of the LISP objects via the graph, since
1150  * this object has no children. so this is a no-op. */
1151 }
1152 
1153 /**
1154  * @brief Virtual function table to register with FIB for the LISP type
1155  */
1159  .fnv_back_walk = lisp_gpe_fib_node_back_walk,
1160 };
1161 
1162 /**
1163  * @brief Forwarding entry create/remove dispatcher.
1164  *
1165  * Calls l2 or l3 forwarding entry add/del function based on input data.
1166  *
1167  * @param[in] a Forwarding entry parameters.
1168  * @param[out] hw_if_indexp NOT USED
1169  *
1170  * @return 0 on success.
1171  */
1172 int
1174  u32 * hw_if_indexp)
1175 {
1177  u8 type;
1178 
1180  {
1181  clib_warning ("LISP is disabled!");
1182  return VNET_API_ERROR_LISP_DISABLED;
1183  }
1184 
1185  type = gid_address_type (&a->rmt_eid);
1186  switch (type)
1187  {
1188  case GID_ADDR_IP_PREFIX:
1189  if (a->is_add)
1190  return add_ip_fwd_entry (lgm, a);
1191  else
1192  return del_ip_fwd_entry (lgm, a);
1193  break;
1194  case GID_ADDR_MAC:
1195  if (a->is_add)
1196  return add_l2_fwd_entry (lgm, a);
1197  else
1198  return del_l2_fwd_entry (lgm, a);
1199  case GID_ADDR_NSH:
1200  if (a->is_add)
1201  return add_nsh_fwd_entry (lgm, a);
1202  else
1203  return del_nsh_fwd_entry (lgm, a);
1204  default:
1205  clib_warning ("Forwarding entries for type %d not supported!", type);
1206  return -1;
1207  }
1208 }
1209 
1210 int
1212 {
1215  u32 i;
1216 
1217  for (i = 0; i < vlib_combined_counter_n_counters (cm); i++)
1219 
1220  return 0;
1221 }
1222 
1223 static void
1224 lisp_del_adj_stats (lisp_gpe_main_t * lgm, u32 fwd_entry_index, u32 ti)
1225 {
1226  lisp_stats_key_t key;
1227  uword *p;
1228 
1229  memset (&key, 0, sizeof (key));
1230  key.fwd_entry_index = fwd_entry_index;
1231  key.tunnel_index = ti;
1232 
1233  p = hash_get_mem (lgm->lisp_stats_index_by_key, &key);
1234  ASSERT (p);
1235 
1236  pool_put_index (lgm->stats_key_pool, p[0]);
1238 }
1239 
1240 void
1242  u32 fwd_entry_index)
1243 {
1245  lisp_gpe_fwd_entry_key_t fe_key;
1246  lisp_gpe_fwd_entry_t *lfe;
1247  lisp_fwd_path_t *path;
1248  const lisp_gpe_adjacency_t *ladj;
1249 
1250  lfe = find_fwd_entry (lgm, a, &fe_key);
1251  if (!lfe)
1252  return;
1253 
1255  return;
1256 
1257  vec_foreach (path, lfe->paths)
1258  {
1259  ladj = lisp_gpe_adjacency_get (path->lisp_adj);
1260  lisp_del_adj_stats (lgm, fwd_entry_index, ladj->tunnel_index);
1261  }
1262 }
1263 
1264 /**
1265  * @brief Flush all the forwrding entries
1266  */
1267 void
1269 {
1271  lisp_gpe_fwd_entry_t *lfe;
1272 
1273  /* *INDENT-OFF* */
1274  pool_foreach (lfe, lgm->lisp_fwd_entry_pool,
1275  ({
1276  switch (fid_addr_type(&lfe->key->rmt))
1277  {
1278  case FID_ADDR_MAC:
1279  del_l2_fwd_entry_i (lgm, lfe);
1280  break;
1281  case FID_ADDR_IP_PREF:
1282  del_ip_fwd_entry_i (lgm, lfe);
1283  break;
1284  case FID_ADDR_NSH:
1285  del_nsh_fwd_entry_i (lgm, lfe);
1286  break;
1287  }
1288  }));
1289  /* *INDENT-ON* */
1290 }
1291 
1292 static u8 *
1293 format_lisp_fwd_path (u8 * s, va_list ap)
1294 {
1295  lisp_fwd_path_t *lfp = va_arg (ap, lisp_fwd_path_t *);
1296 
1297  s = format (s, "weight:%d ", lfp->weight);
1298  s = format (s, "adj:[%U]\n",
1302 
1303  return (s);
1304 }
1305 
1307 {
1311 
1312 
1313 static u8 *
1315 {
1317  lisp_gpe_fwd_entry_t *lfe = va_arg (ap, lisp_gpe_fwd_entry_t *);
1319  va_arg (ap, lisp_gpe_fwd_entry_format_flag_t);
1320 
1321  s = format (s, "VNI:%d VRF:%d EID: %U -> %U [index:%d]",
1322  lfe->key->vni, lfe->eid_table_id,
1323  format_fid_address, &lfe->key->lcl,
1324  format_fid_address, &lfe->key->rmt,
1325  lfe - lgm->lisp_fwd_entry_pool);
1326 
1328  {
1329  s = format (s, "\n Negative - action:%U",
1331  }
1332  else
1333  {
1334  lisp_fwd_path_t *path;
1335 
1336  s = format (s, "\n via:");
1337  vec_foreach (path, lfe->paths)
1338  {
1339  s = format (s, "\n %U", format_lisp_fwd_path, path);
1340  }
1341  }
1342 
1344  {
1345  switch (fid_addr_type (&lfe->key->rmt))
1346  {
1347  case FID_ADDR_MAC:
1348  s = format (s, " fib-path-list:%d\n", lfe->l2.path_list_index);
1349  s = format (s, " dpo:%U\n", format_dpo_id, &lfe->l2.dpo, 0);
1350  break;
1351  case FID_ADDR_NSH:
1352  s = format (s, " fib-path-list:%d\n", lfe->nsh.path_list_index);
1353  s = format (s, " dpo:%U\n", format_dpo_id, &lfe->nsh.dpo, 0);
1354  break;
1355  case FID_ADDR_IP_PREF:
1356  break;
1357  }
1358  }
1359 
1360  return (s);
1361 }
1362 
1363 static clib_error_t *
1365  unformat_input_t * input, vlib_cli_command_t * cmd)
1366 {
1368  lisp_gpe_fwd_entry_t *lfe;
1369  index_t index;
1370  u32 vni = ~0;
1371 
1372  if (unformat (input, "vni %d", &vni))
1373  ;
1374  else if (unformat (input, "%d", &index))
1375  {
1376  if (!pool_is_free_index (lgm->lisp_fwd_entry_pool, index))
1377  {
1378  lfe = pool_elt_at_index (lgm->lisp_fwd_entry_pool, index);
1379 
1380  vlib_cli_output (vm, "[%d@] %U",
1381  index,
1384  }
1385  else
1386  {
1387  vlib_cli_output (vm, "entry %d invalid", index);
1388  }
1389 
1390  return (NULL);
1391  }
1392 
1393  /* *INDENT-OFF* */
1394  pool_foreach (lfe, lgm->lisp_fwd_entry_pool,
1395  ({
1396  if ((vni == ~0) ||
1397  (lfe->key->vni == vni))
1398  vlib_cli_output (vm, "%U", format_lisp_gpe_fwd_entry, lfe,
1399  LISP_GPE_FWD_ENTRY_FORMAT_NONE);
1400  }));
1401  /* *INDENT-ON* */
1402 
1403  return (NULL);
1404 }
1405 
1406 /* *INDENT-OFF* */
1408  .path = "show gpe entry",
1409  .short_help = "show gpe entry vni <vni> vrf <vrf> [leid <leid>] reid <reid>",
1410  .function = lisp_gpe_fwd_entry_show,
1411 };
1412 /* *INDENT-ON* */
1413 
1414 clib_error_t *
1416 {
1418  clib_error_t *error = NULL;
1419 
1421  return (error);
1422 
1423  l2_fib_init (lgm);
1424  nsh_fib_init (lgm);
1425 
1427 
1428  return (error);
1429 }
1430 
1433 {
1435  lisp_gpe_fwd_entry_t *lfe;
1436  lisp_api_gpe_fwd_entry_t *entries = 0, e;
1437 
1438  /* *INDENT-OFF* */
1439  pool_foreach (lfe, lgm->lisp_fwd_entry_pool,
1440  ({
1441  if (lfe->key->vni == vni)
1442  {
1443  memset (&e, 0, sizeof (e));
1444  e.dp_table = lfe->eid_table_id;
1445  e.vni = lfe->key->vni;
1446  e.fwd_entry_index = lfe - lgm->lisp_fwd_entry_pool;
1447  memcpy (&e.reid, &lfe->key->rmt, sizeof (e.reid));
1448  memcpy (&e.leid, &lfe->key->lcl, sizeof (e.leid));
1449  vec_add1 (entries, e);
1450  }
1451  }));
1452  /* *INDENT-ON* */
1453 
1454  return entries;
1455 }
1456 
1458 
1459 /*
1460  * fd.io coding-style-patch-verification: ON
1461  *
1462  * Local Variables:
1463  * eval: (c-set-style "gnu")
1464  * End:
1465  */
void dpo_unlock(dpo_id_t *dpo)
Release a reference counting lock on the DPO.
Definition: dpo.c:281
#define vec_validate(V, I)
Make sure vector is long enough for given index (no header, unspecified alignment) ...
Definition: vec.h:436
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.
u32 fib_table_create_and_lock(fib_protocol_t proto, const char *const fmt,...)
Create a new table with no table ID.
Definition: fib_table.c:985
u16 lb_n_buckets
number of buckets in the load-balance.
Definition: load_balance.h:88
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:420
fib_protocol_t fp_proto
protocol type
Definition: fib_types.h:169
vmrglw vmrglh hi
fib_protocol_t frp_proto
The protocol of the address below.
Definition: fib_types.h:313
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:322
lisp_stats_key_t * stats_key_pool
Definition: lisp_gpe.h:162
static const fib_node_vft_t lisp_fwd_vft
Virtual function table to register with FIB for the LISP type.
sll srl srl sll sra u16x4 i
Definition: vector_sse2.h:343
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.
#define gid_address_type(_a)
Definition: lisp_types.h:241
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:89
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:95
a
Definition: bitmap.h:516
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:181
struct lisp_gpe_fwd_entry_t_::@187::@193 l2
Fields relevant to an L2 entry.
A representation of a path as described by a route producer.
Definition: fib_types.h:308
u32 bd_id
bridge domain id
Definition: lisp_gpe.h:262
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 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:165
void vnet_lisp_gpe_fwd_entry_flush(void)
Flush all the forwrding entries.
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:667
u8 priority
Priority.
#define NULL
Definition: clib.h:55
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.
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:132
void dpo_copy(dpo_id_t *dst, const dpo_id_t *src)
atomic copy a data-plane object.
Definition: dpo.c:224
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
void lookup_dpo_add_or_lock_w_fib_index(fib_node_index_t fib_index, dpo_proto_t proto, lookup_input_t input, lookup_table_t table_config, dpo_id_t *dpo)
Definition: lookup_dpo.c:116
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:274
#define STRUCT_OFFSET_OF(t, f)
Definition: clib.h:62
u8 * format(u8 *s, const char *fmt,...)
Definition: format.c:418
void vnet_lisp_gpe_add_fwd_counters(vnet_lisp_gpe_add_del_fwd_entry_args_t *a, u32 fwd_entry_index)
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:200
#define ip_prefix_version(_a)
Definition: lisp_types.h:72
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)
#define fid_addr_mac(_a)
Definition: lisp_types.h:131
enum fib_protocol_t_ fib_protocol_t
Protocol Type.
u32 tenant
The tenant the entry belongs to.
static void create_fib_entries(lisp_gpe_fwd_entry_t *lfe)
void fib_node_register_type(fib_node_type_t type, const fib_node_vft_t *vft)
fib_node_register_type
Definition: fib_node.c:58
static void delete_fib_entries(lisp_gpe_fwd_entry_t *lfe)
ip_prefix_t ippref
Definition: lisp_types.h:119
index_t load_balance_create(u32 n_buckets, dpo_proto_t lb_proto, flow_hash_config_t fhc)
Definition: load_balance.c:192
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:179
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
#define pool_foreach(VAR, POOL, BODY)
Iterate through pool.
Definition: pool.h:376
u32 frp_sw_if_index
The interface.
Definition: fib_types.h:334
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:111
u32 fwd_entry_index
Definition: lisp_gpe.h:95
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:388
u16 lb_n_buckets_minus_1
number of buckets in the load-balance - 1.
Definition: load_balance.h:93
static BVT(clib_bihash)
Definition: adj_nbr.c:26
static void make_mac_fib_key(BVT(clib_bihash_kv)*kv, u16 bd_index, u8 src_mac[6], u8 dst_mac[6])
vlib_combined_counter_main_t counters
Definition: lisp_gpe.h:164
LISP-GPE fwd entry key.
u8 is_add
Definition: lisp_gpe.h:226
void fib_path_list_contribute_forwarding(fib_node_index_t path_list_index, fib_forward_chain_type_t fct, dpo_id_t *dpo)
u8 * format_fib_prefix(u8 *s, va_list *args)
Definition: fib_types.c:150
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)
Aggregrate type for a prefix.
Definition: fib_types.h:160
uword * lisp_gpe_fwd_entries
DB of all forwarding entries.
Definition: lisp_gpe.h:124
unsigned long u64
Definition: types.h:89
Contribute an object that is to be used to forward Ethernet packets.
Definition: fib_types.h:109
struct lisp_gpe_fwd_entry_t_::@187::@194 nsh
Fields relevant to an NSH entry.
enum dpo_proto_t_ dpo_proto_t
Data path protocol.
#define vlib_call_init_function(vm, x)
Definition: init.h:162
dp_address_t rmt
uword * bd_index_by_bd_id
Definition: l2_bd.h:27
Definition: lisp_gpe.h:222
static void 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.
Common utility functions for IPv4, IPv6 and L2 LISP-GPE adjacencys.
Definition: fib_entry.h:227
void gid_to_dp_address(gid_address_t *g, dp_address_t *d)
Definition: lisp_types.c:577
The identity of a DPO is a combination of its type and its instance number/index of objects of that t...
Definition: dpo.h:146
void fib_table_unlock(u32 fib_index, fib_protocol_t proto)
Take a reference counting lock on the table.
Definition: fib_table.c:1058
#define hash_get(h, key)
Definition: hash.h:248
Definition: fib_entry.h:231
#define pool_elt_at_index(p, i)
Returns pointer to element at given index.
Definition: pool.h:397
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:276
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:280
static int lisp_gpe_fwd_entry_path_sort(void *a1, void *a2)
u32 table_id
table (vrf) id
Definition: lisp_gpe.h:259
u8 * format_negative_mapping_action(u8 *s, va_list *args)
Definition: lisp_types.c:409
static u32 lisp_nsh_fib_add_del_entry(u32 spi_si_host_order, u32 lfei, u8 is_add)
Add/del NSH FIB entry.
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:202
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:100
struct _unformat_input_t unformat_input_t
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:104
#define pool_put(P, E)
Free an object E in pool P.
Definition: pool.h:241
int vnet_lisp_flush_stats(void)
The FIB DPO provieds;.
Definition: load_balance.h:84
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:1082
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)
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:277
void clib_bihash_init(clib_bihash *h, char *name, u32 nbuckets, uword memory_size)
initialize a bounded index extensible hash table
void ip_address_to_46(const ip_address_t *addr, ip46_address_t *a, fib_protocol_t *proto)
Definition: lisp_types.c:850
Definition: lisp_gpe.h:269
#define gid_address_ippref(_a)
Definition: lisp_types.h:242
#define L2_FIB_DEFAULT_HASH_MEMORY_SIZE
u8 is_negative
type of mapping
Definition: lisp_gpe.h:229
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:253
int fib_entry_is_sourced(fib_node_index_t fib_entry_index, fib_source_t source)
vlib_main_t * vm
Definition: buffer.c:276
Contribute an object that is to be used to forward NSH packets.
Definition: fib_types.h:115
#define vec_free(V)
Free vector&#39;s memory (no header).
Definition: vec.h:340
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:798
u32 frp_weight
[un]equal cost path weight
Definition: fib_types.h:343
vnet_main_t * vnet_main
Definition: lisp_gpe.h:168
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:265
u32 fib_node_index_t
A typedef of a node index.
Definition: fib_types.h:28
#define pool_is_free_index(P, I)
Use free bitmap to query whether given index is free.
Definition: pool.h:238
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:157
lisp_gpe_main_t lisp_gpe_main
LISP-GPE global state.
Definition: lisp_gpe.c:27
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.
#define fid_addr_ippref(_a)
Definition: lisp_types.h:128
Context passed between object during a back walk.
Definition: fib_node.h:190
#define VLIB_CLI_COMMAND(x,...)
Definition: cli.h:154
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:288
#define pool_put_index(p, i)
Free pool element with given index.
Definition: pool.h:255
static void 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.
#define ASSERT(truth)
#define fid_addr_type(_a)
Definition: lisp_types.h:133
const void * fib_entry_get_source_data(fib_node_index_t fib_entry_index, fib_source_t source)
unsigned int u32
Definition: types.h:88
static void del_nsh_fwd_entry_i(lisp_gpe_main_t *lgm, lisp_gpe_fwd_entry_t *lfe)
int clib_bihash_search(clib_bihash *h, clib_bihash_kv *search_v, clib_bihash_kv *return_v)
Search a bi-hash table.
static load_balance_t * load_balance_get(index_t lbi)
Definition: load_balance.h:193
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:176
uword * hw_if_index_by_dp_table
Lookup lisp-gpe interfaces by dp table (eg.
Definition: lisp_gpe.h:84
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:224
u32 fib_table_find_or_create_and_lock(fib_protocol_t proto, u32 table_id)
Get the index of the FIB for a Table-ID.
Definition: fib_table.c:954
static u64 mac_to_u64(u8 *m)
Definition: load_balance.c:889
dpo_proto_t fib_proto_to_dpo(fib_protocol_t fib_proto)
Definition: fib_types.c:220
gid_address_t rmt_eid
remote eid
Definition: lisp_gpe.h:238
void load_balance_set_bucket(index_t lbi, u32 bucket, const dpo_id_t *next)
Definition: load_balance.c:209
static void * clib_mem_alloc(uword size)
Definition: mem.h:109
u8 * format_dpo_id(u8 *s, va_list *args)
Format a DPO_id_t oject
Definition: dpo.c:121
u64 uword
Definition: types.h:112
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:232
A LISP GPE Adjacency.
unsigned short u16
Definition: types.h:57
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:162
#define FIB_NODE_INDEX_INVALID
Definition: fib_types.h:29
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)
unsigned char u8
Definition: types.h:56
dpo_id_t l2_lb_cp_lkup
Load-balance for a miss in the table.
Definition: lisp_gpe.h:149
static u8 * format_lisp_gpe_fwd_entry(u8 *s, va_list ap)
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:228
u32 dp_table
generic access
Definition: lisp_gpe.h:265
#define vec_sort_with_function(vec, f)
Sort a vector using the supplied element comparison function.
Definition: vec.h:960
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:241
#define DPO_INVALID
An initialiser for DPOs declared on the stack.
Definition: dpo.h:173
A collection of combined counters.
Definition: counter.h:180
Definition: lisp_types.h:37
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:268
static void nsh_fib_init(lisp_gpe_main_t *lgm)
A FIB graph nodes virtual function table.
Definition: fib_node.h:264
u8 * format_lisp_gpe_adjacency(u8 *s, va_list *args)
static u8 * format_lisp_fwd_path(u8 *s, va_list ap)
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
LISP.
Definition: fib_entry.h:66
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:194
#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.
u32 flags
Definition: vhost-user.h:78
Definition: lisp_types.h:38
bd_main_t bd_main
Definition: l2_bd.c:44
u32 vni
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:220
gid_address_t lcl_eid
local eid
Definition: lisp_gpe.h:235
tunnel_lookup_t nsh_ifaces
Definition: lisp_gpe.h:156
void vlib_cli_output(vlib_main_t *vm, char *fmt,...)
Definition: cli.c:577
#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 unformat(unformat_input_t *i, const char *fmt,...)
Definition: unformat.c:971
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.