FD.io VPP  v17.07.01-10-g3be13f0
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 :
94  &src_lkup_dpo);
95 
96  /*
97  * add the entry to the destination FIB that uses the lookup DPO
98  */
99  dst_fei = fib_table_entry_special_dpo_add (dst_fib_index,
100  &dst_fib_prefix,
103  &src_lkup_dpo);
104 
105  /*
106  * the DPO is locked by the FIB entry, and we have no further
107  * need for it.
108  */
109  dpo_unlock (&src_lkup_dpo);
110 
111  /*
112  * save the SRC FIB index on the entry so we can retrieve it for
113  * subsequent routes.
114  */
115  fib_entry_set_source_data (dst_fei, FIB_SOURCE_LISP, &src_fib_index);
116  }
117  else
118  {
119  /*
120  * destination FIB entry already present
121  */
122  src_fib_index = *(u32 *) fib_entry_get_source_data (dst_fei,
124  }
125 
126  return (src_fib_index);
127 }
128 
129 /**
130  * @brief Del route to IP4 or IP6 SD FIB.
131  *
132  * Remove routes from both destination and source FIBs.
133  *
134  * @param[in] src_fib_index The index/ID of the SRC FIB
135  * @param[in] src_prefix Source IP prefix.
136  * @param[in] dst_fib_index The index/ID of the DST FIB
137  * @param[in] dst_prefix Destination IP prefix.
138  */
139 static void
141  const ip_prefix_t * src_prefix,
142  u32 dst_fib_index, const ip_prefix_t * dst_prefix)
143 {
144  fib_prefix_t dst_fib_prefix, src_fib_prefix;
145  u8 have_default = 0;
146  u32 n_entries;
147 
148  ASSERT (NULL != dst_prefix);
149  ASSERT (NULL != src_prefix);
150 
151  ip_prefix_to_fib_prefix (dst_prefix, &dst_fib_prefix);
152  ip_prefix_to_fib_prefix (src_prefix, &src_fib_prefix);
153 
154  fib_table_entry_delete (src_fib_index, &src_fib_prefix, FIB_SOURCE_LISP);
155 
156  /* check if only default left or empty */
157  fib_prefix_t default_pref = {
158  .fp_proto = dst_fib_prefix.fp_proto
159  };
160 
161  if (fib_table_lookup_exact_match (src_fib_index,
162  &default_pref) != FIB_NODE_INDEX_INVALID)
163  have_default = 1;
164 
165  n_entries = fib_table_get_num_entries (src_fib_index,
166  src_fib_prefix.fp_proto,
168  if (n_entries == 0 || (have_default && n_entries == 1))
169  {
170  /*
171  * remove src FIB default route
172  */
173  if (have_default)
174  fib_table_entry_special_remove (src_fib_index, &default_pref,
176 
177  /*
178  * there's nothing left now, unlock the source FIB and the
179  * destination route
180  */
181  fib_table_entry_special_remove (dst_fib_index,
182  &dst_fib_prefix, FIB_SOURCE_LISP);
183  fib_table_unlock (src_fib_index, src_fib_prefix.fp_proto);
184  }
185 }
186 
187 /**
188  * @brief Add route to IP4 or IP6 SRC FIB.
189  *
190  * Adds a route to in the LISP SRC FIB with the result of the route
191  * being the DPO passed.
192  *
193  * @param[in] src_fib_index The index/ID of the SRC FIB
194  * @param[in] src_prefix Source IP prefix.
195  * @param[in] src_dpo The DPO the route will link to.
196  */
197 static void
199  const ip_prefix_t * src_prefix,
200  const dpo_id_t * src_dpo)
201 {
202  fib_prefix_t src_fib_prefix;
203 
204  ip_prefix_to_fib_prefix (src_prefix, &src_fib_prefix);
205 
206  /*
207  * add the entry into the source fib.
208  */
209  fib_node_index_t src_fei;
210 
211  src_fei = fib_table_lookup_exact_match (src_fib_index, &src_fib_prefix);
212 
213  if (FIB_NODE_INDEX_INVALID == src_fei ||
215  {
216  fib_table_entry_special_dpo_add (src_fib_index,
217  &src_fib_prefix,
219  FIB_ENTRY_FLAG_EXCLUSIVE, src_dpo);
220  }
221 }
222 
223 static fib_route_path_t *
225 {
226  const lisp_gpe_adjacency_t *ladj;
227  fib_route_path_t *rpaths = NULL;
228  u8 best_priority;
229  u32 ii;
230 
231  vec_validate (rpaths, vec_len (paths) - 1);
232 
233  best_priority = paths[0].priority;
234 
235  vec_foreach_index (ii, paths)
236  {
237  if (paths[0].priority != best_priority)
238  break;
239 
240  ladj = lisp_gpe_adjacency_get (paths[ii].lisp_adj);
241 
243  &rpaths[ii].frp_addr, &rpaths[ii].frp_proto);
244 
245  rpaths[ii].frp_sw_if_index = ladj->sw_if_index;
246  rpaths[ii].frp_weight = (paths[ii].weight ? paths[ii].weight : 1);
247  }
248 
249  ASSERT (0 != vec_len (rpaths));
250 
251  return (rpaths);
252 }
253 
254 /**
255  * @brief Add route to IP4 or IP6 SRC FIB.
256  *
257  * Adds a route to in the LISP SRC FIB for the tunnel.
258  *
259  * @param[in] src_fib_index The index/ID of the SRC FIB
260  * @param[in] src_prefix Source IP prefix.
261  * @param[in] paths The paths from which to construct the
262  * load balance
263  */
264 static void
265 ip_src_fib_add_route (u32 src_fib_index,
266  const ip_prefix_t * src_prefix,
267  const lisp_fwd_path_t * paths)
268 {
269  fib_prefix_t src_fib_prefix;
270  fib_route_path_t *rpaths;
271 
272  ip_prefix_to_fib_prefix (src_prefix, &src_fib_prefix);
273 
274  rpaths = lisp_gpe_mk_fib_paths (paths);
275 
276  fib_table_entry_update (src_fib_index,
277  &src_fib_prefix,
279  vec_free (rpaths);
280 }
281 
282 static void
284 {
286  u8 found = 0, ip_version;
287  u32 *lfei, new_lfei;
288  ip_version = ip_prefix_version (&lfe->key->rmt.ippref);
289 
290  new_lfei = lfe - lgm->lisp_fwd_entry_pool;
291  vec_foreach (lfei, lgm->native_fwd_lfes[ip_version])
292  {
293  lfe = pool_elt_at_index (lgm->lisp_fwd_entry_pool, lfei[0]);
294  if (lfei[0] == new_lfei)
295  {
296  found = 1;
297  break;
298  }
299  }
300 
301  if (is_add)
302  {
303  if (!found)
304  vec_add1 (lgm->native_fwd_lfes[ip_version], new_lfei);
305  }
306  else
307  {
308  if (found)
309  vec_del1 (lgm->native_fwd_lfes[ip_version], lfei[0]);
310  }
311 }
312 
313 static void
315 {
317  dpo_proto_t dproto;
318  ip_prefix_t ippref;
319  fib_prefix_t fib_prefix;
320  u8 ip_version = ip_prefix_version (&lfe->key->rmt.ippref);
321  dproto = (ip_version == IP4 ? DPO_PROTO_IP4 : DPO_PROTO_IP6);
322 
323  if (lfe->is_src_dst)
324  {
326  &lfe->key->rmt.ippref);
327  memcpy (&ippref, &lfe->key->lcl.ippref, sizeof (ippref));
328  }
329  else
330  {
331  lfe->src_fib_index = lfe->eid_fib_index;
332  memcpy (&ippref, &lfe->key->rmt.ippref, sizeof (ippref));
333  }
334 
336  {
337  dpo_id_t dpo = DPO_INVALID;
338 
339  switch (lfe->action)
340  {
341  case LISP_FORWARD_NATIVE:
342  /* TODO handle route overlaps with fib and default route */
343  if (vec_len (lgm->native_fwd_rpath[ip_version]))
344  {
345  ip_prefix_to_fib_prefix (&lfe->key->rmt.ippref, &fib_prefix);
346  fib_table_entry_update (lfe->eid_fib_index, &fib_prefix,
348  lgm->native_fwd_rpath[ip_version]);
350  break;
351  }
352  case LISP_NO_ACTION:
353  /* TODO update timers? */
355  /* insert tunnel that always sends map-request */
356  dpo_copy (&dpo, lisp_cp_dpo_get (dproto));
357  break;
358  case LISP_DROP:
359  /* for drop fwd entries, just add route, no need to add encap tunnel */
360  dpo_copy (&dpo, drop_dpo_get (dproto));
361  break;
362  }
363  ip_src_fib_add_route_w_dpo (lfe->src_fib_index, &ippref, &dpo);
364  dpo_reset (&dpo);
365  }
366  else
367  {
368  ip_src_fib_add_route (lfe->src_fib_index, &ippref, lfe->paths);
369  }
370 }
371 
372 static void
374 {
375  fib_prefix_t dst_fib_prefix;
376 
377  if (lfe->is_src_dst)
379  &lfe->key->lcl.ippref,
380  lfe->eid_fib_index, &lfe->key->rmt.ippref);
381  else
382  {
383  ip_prefix_to_fib_prefix (&lfe->key->rmt.ippref, &dst_fib_prefix);
384  fib_table_entry_delete (lfe->src_fib_index, &dst_fib_prefix,
387  }
388 }
389 
390 static lisp_gpe_fwd_entry_t *
394 {
395  uword *p;
396 
397  memset (key, 0, sizeof (*key));
398 
400  {
401  /*
402  * the ip version of the source is not set to ip6 when the
403  * source is all zeros. force it.
404  */
407  }
408 
409  gid_to_dp_address (&a->rmt_eid, &key->rmt);
410  gid_to_dp_address (&a->lcl_eid, &key->lcl);
411  key->vni = a->vni;
412 
413  p = hash_get_mem (lgm->lisp_gpe_fwd_entries, key);
414 
415  if (NULL != p)
416  {
417  return (pool_elt_at_index (lgm->lisp_fwd_entry_pool, p[0]));
418  }
419  return (NULL);
420 }
421 
422 static int
423 lisp_gpe_fwd_entry_path_sort (void *a1, void *a2)
424 {
425  lisp_fwd_path_t *p1 = a1, *p2 = a2;
426 
427  return (p1->priority - p2->priority);
428 }
429 
430 static void
433 {
434  lisp_fwd_path_t *path;
435  u32 index;
436 
437  vec_validate (lfe->paths, vec_len (a->locator_pairs) - 1);
438 
439  vec_foreach_index (index, a->locator_pairs)
440  {
441  path = &lfe->paths[index];
442 
443  path->priority = a->locator_pairs[index].priority;
444  path->weight = a->locator_pairs[index].weight;
445 
446  path->lisp_adj =
448  [index],
449  a->dp_table, lfe->key->vni);
450  }
452 }
453 
454 void
456  u32 fwd_entry_index)
457 {
458  const lisp_gpe_adjacency_t *ladj;
459  lisp_fwd_path_t *path;
461  u8 *dummy_elt;
464  lisp_stats_key_t key;
465 
466  lfe = find_fwd_entry (lgm, a, &fe_key);
467 
468  if (!lfe)
469  return;
470 
472  return;
473 
474  memset (&key, 0, sizeof (key));
475  key.fwd_entry_index = fwd_entry_index;
476 
477  vec_foreach (path, lfe->paths)
478  {
479  ladj = lisp_gpe_adjacency_get (path->lisp_adj);
480  key.tunnel_index = ladj->tunnel_index;
481  lisp_stats_key_t *key_copy = clib_mem_alloc (sizeof (*key_copy));
482  memcpy (key_copy, &key, sizeof (*key_copy));
483  pool_get (lgm->dummy_stats_pool, dummy_elt);
484  hash_set_mem (lgm->lisp_stats_index_by_key, key_copy,
485  dummy_elt - lgm->dummy_stats_pool);
486 
488  dummy_elt - lgm->dummy_stats_pool);
490  dummy_elt - lgm->dummy_stats_pool);
491  }
492 }
493 
494 /**
495  * @brief Add/Delete LISP IP forwarding entry.
496  *
497  * creation of forwarding entries for IP LISP overlay:
498  *
499  * @param[in] lgm Reference to @ref lisp_gpe_main_t.
500  * @param[in] a Parameters for building the forwarding entry.
501  *
502  * @return 0 on success.
503  */
504 static int
507 {
510  fib_protocol_t fproto;
511 
512  lfe = find_fwd_entry (lgm, a, &key);
513 
514  if (NULL != lfe)
515  /* don't support updates */
516  return VNET_API_ERROR_INVALID_VALUE;
517 
518  pool_get (lgm->lisp_fwd_entry_pool, lfe);
519  memset (lfe, 0, sizeof (*lfe));
520  lfe->key = clib_mem_alloc (sizeof (key));
521  memcpy (lfe->key, &key, sizeof (key));
522 
524  lfe - lgm->lisp_fwd_entry_pool);
525  a->fwd_entry_index = lfe - lgm->lisp_fwd_entry_pool;
526 
527  fproto = (IP4 == ip_prefix_version (&fid_addr_ippref (&lfe->key->rmt)) ?
529 
530  lfe->type = (a->is_negative ?
534  lfe->eid_table_id = a->table_id;
536  lfe->eid_table_id);
537  lfe->is_src_dst = a->is_src_dst;
538 
540  {
542  }
543  else
544  {
545  lfe->action = a->action;
546  }
547 
548  create_fib_entries (lfe);
549  return (0);
550 }
551 
552 static void
554 {
555  lisp_fwd_path_t *path;
556  fib_protocol_t fproto;
557 
559  {
560  vec_foreach (path, lfe->paths)
561  {
563  }
564  }
565 
566  delete_fib_entries (lfe);
567 
568  fproto = (IP4 == ip_prefix_version (&fid_addr_ippref (&lfe->key->rmt)) ?
570  fib_table_unlock (lfe->eid_fib_index, fproto);
571 
573  clib_mem_free (lfe->key);
574  pool_put (lgm->lisp_fwd_entry_pool, lfe);
575 }
576 
577 /**
578  * @brief Add/Delete LISP IP forwarding entry.
579  *
580  * removal of forwarding entries for IP LISP overlay:
581  *
582  * @param[in] lgm Reference to @ref lisp_gpe_main_t.
583  * @param[in] a Parameters for building the forwarding entry.
584  *
585  * @return 0 on success.
586  */
587 static int
590 {
593 
594  lfe = find_fwd_entry (lgm, a, &key);
595 
596  if (NULL == lfe)
597  /* no such entry */
598  return VNET_API_ERROR_INVALID_VALUE;
599 
600  del_ip_fwd_entry_i (lgm, lfe);
601 
602  return (0);
603 }
604 
605 static void
606 make_mac_fib_key (BVT (clib_bihash_kv) * kv, u16 bd_index, u8 src_mac[6],
607  u8 dst_mac[6])
608 {
609  kv->key[0] = (((u64) bd_index) << 48) | mac_to_u64 (dst_mac);
610  kv->key[1] = mac_to_u64 (src_mac);
611  kv->key[2] = 0;
612 }
613 
614 /**
615  * @brief Lookup L2 SD FIB entry
616  *
617  * Does a vni + dest + source lookup in the L2 LISP FIB. If the lookup fails
618  * it tries a second time with source set to 0 (i.e., a simple dest lookup).
619  *
620  * @param[in] lgm Reference to @ref lisp_gpe_main_t.
621  * @param[in] bd_index Bridge domain index.
622  * @param[in] src_mac Source mac address.
623  * @param[in] dst_mac Destination mac address.
624  *
625  * @return index of mapping matching the lookup key.
626  */
627 index_t
628 lisp_l2_fib_lookup (lisp_gpe_main_t * lgm, u16 bd_index, u8 src_mac[6],
629  u8 dst_mac[6])
630 {
631  int rv;
632  BVT (clib_bihash_kv) kv, value;
633 
634  make_mac_fib_key (&kv, bd_index, src_mac, dst_mac);
635  rv = BV (clib_bihash_search_inline_2) (&lgm->l2_fib, &kv, &value);
636 
637  /* no match, try with src 0, catch all for dst */
638  if (rv != 0)
639  {
640  kv.key[1] = 0;
641  rv = BV (clib_bihash_search_inline_2) (&lgm->l2_fib, &kv, &value);
642  if (rv == 0)
643  return value.value;
644  }
645  else
646  return value.value;
647 
649 }
650 
651 /**
652  * @brief Add/del L2 SD FIB entry
653  *
654  * Inserts value in L2 FIB keyed by vni + dest + source. If entry is
655  * overwritten the associated value is returned.
656  *
657  * @param[in] lgm Reference to @ref lisp_gpe_main_t.
658  * @param[in] bd_index Bridge domain index.
659  * @param[in] src_mac Source mac address.
660  * @param[in] dst_mac Destination mac address.
661  * @param[in] val Value to add.
662  * @param[in] is_add Add/del flag.
663  *
664  * @return ~0 or value of overwritten entry.
665  */
666 static u32
667 lisp_l2_fib_add_del_entry (u16 bd_index, u8 src_mac[6],
668  u8 dst_mac[6], const dpo_id_t * dpo, u8 is_add)
669 {
671  BVT (clib_bihash_kv) kv, value;
672  u32 old_val = ~0;
673 
674  make_mac_fib_key (&kv, bd_index, src_mac, dst_mac);
675 
676  if (BV (clib_bihash_search) (&lgm->l2_fib, &kv, &value) == 0)
677  old_val = value.value;
678 
679  if (!is_add)
680  BV (clib_bihash_add_del) (&lgm->l2_fib, &kv, 0 /* is_add */ );
681  else
682  {
683  kv.value = dpo->dpoi_index;
684  BV (clib_bihash_add_del) (&lgm->l2_fib, &kv, 1 /* is_add */ );
685  }
686  return old_val;
687 }
688 
689 #define L2_FIB_DEFAULT_HASH_NUM_BUCKETS (64 * 1024)
690 #define L2_FIB_DEFAULT_HASH_MEMORY_SIZE (32<<20)
691 
692 static void
694 {
695  index_t lbi;
696 
697  BV (clib_bihash_init) (&lgm->l2_fib, "l2 fib",
700 
701  /*
702  * the result from a 'miss' in a L2 Table
703  */
706 
708 }
709 
710 static void
712 {
713  lisp_fwd_path_t *path;
714 
716  {
717  vec_foreach (path, lfe->paths)
718  {
720  }
721  fib_path_list_child_remove (lfe->l2.path_list_index,
722  lfe->l2.child_index);
723  }
724 
725  lisp_l2_fib_add_del_entry (lfe->l2.eid_bd_index,
726  fid_addr_mac (&lfe->key->lcl),
727  fid_addr_mac (&lfe->key->rmt), NULL, 0);
728 
730  clib_mem_free (lfe->key);
731  pool_put (lgm->lisp_fwd_entry_pool, lfe);
732 }
733 
734 /**
735  * @brief Delete LISP L2 forwarding entry.
736  *
737  * Coordinates the removal of forwarding entries for L2 LISP overlay:
738  *
739  * @param[in] lgm Reference to @ref lisp_gpe_main_t.
740  * @param[in] a Parameters for building the forwarding entry.
741  *
742  * @return 0 on success.
743  */
744 static int
747 {
750 
751  lfe = find_fwd_entry (lgm, a, &key);
752 
753  if (NULL == lfe)
754  return VNET_API_ERROR_INVALID_VALUE;
755 
756  del_l2_fwd_entry_i (lgm, lfe);
757 
758  return (0);
759 }
760 
761 /**
762  * @brief Construct and insert the forwarding information used by an L2 entry
763  */
764 static void
766 {
768  dpo_id_t dpo = DPO_INVALID;
769 
771  {
772  fib_path_list_contribute_forwarding (lfe->l2.path_list_index,
774  &lfe->l2.dpo);
775  dpo_copy (&dpo, &lfe->l2.dpo);
776  }
777  else
778  {
779  switch (lfe->action)
780  {
781  case SEND_MAP_REQUEST:
782  dpo_copy (&dpo, &lgm->l2_lb_cp_lkup);
783  break;
784  case NO_ACTION:
785  case FORWARD_NATIVE:
786  case DROP:
788  }
789  }
790 
791  /* add entry to l2 lisp fib */
792  lisp_l2_fib_add_del_entry (lfe->l2.eid_bd_index,
793  fid_addr_mac (&lfe->key->lcl),
794  fid_addr_mac (&lfe->key->rmt), &dpo, 1);
795 
796  dpo_reset (&dpo);
797 }
798 
799 /**
800  * @brief Add LISP L2 forwarding entry.
801  *
802  * Coordinates the creation of forwarding entries for L2 LISP overlay:
803  * creates lisp-gpe tunnel and injects new entry in Source/Dest L2 FIB.
804  *
805  * @param[in] lgm Reference to @ref lisp_gpe_main_t.
806  * @param[in] a Parameters for building the forwarding entry.
807  *
808  * @return 0 on success.
809  */
810 static int
813 {
815  bd_main_t *bdm = &bd_main;
817  uword *bd_indexp;
818 
819  bd_indexp = hash_get (bdm->bd_index_by_bd_id, a->bd_id);
820  if (!bd_indexp)
821  {
822  clib_warning ("bridge domain %d doesn't exist", a->bd_id);
823  return -1;
824  }
825 
826  lfe = find_fwd_entry (lgm, a, &key);
827 
828  if (NULL != lfe)
829  /* don't support updates */
830  return VNET_API_ERROR_INVALID_VALUE;
831 
832  pool_get (lgm->lisp_fwd_entry_pool, lfe);
833  memset (lfe, 0, sizeof (*lfe));
834  lfe->key = clib_mem_alloc (sizeof (key));
835  memcpy (lfe->key, &key, sizeof (key));
836 
838  lfe - lgm->lisp_fwd_entry_pool);
839  a->fwd_entry_index = lfe - lgm->lisp_fwd_entry_pool;
840 
841  lfe->type = (a->is_negative ?
844  lfe->l2.eid_bd_id = a->bd_id;
845  lfe->l2.eid_bd_index = bd_indexp[0];
847 
849  {
850  fib_route_path_t *rpaths;
851 
852  /*
853  * Make the sorted array of LISP paths with their resp. adjacency
854  */
856 
857  /*
858  * From the LISP paths, construct a FIB path list that will
859  * contribute a load-balance.
860  */
861  rpaths = lisp_gpe_mk_fib_paths (lfe->paths);
862 
863  lfe->l2.path_list_index =
865 
866  /*
867  * become a child of the path-list so we receive updates when
868  * its forwarding state changes. this includes an implicit lock.
869  */
870  lfe->l2.child_index =
871  fib_path_list_child_add (lfe->l2.path_list_index,
873  lfe - lgm->lisp_fwd_entry_pool);
874  }
875  else
876  {
877  lfe->action = a->action;
878  }
879 
881 
882  return 0;
883 }
884 
885 /**
886  * @brief Lookup NSH SD FIB entry
887  *
888  * Does an SPI+SI lookup in the NSH LISP FIB.
889  *
890  * @param[in] lgm Reference to @ref lisp_gpe_main_t.
891  * @param[in] spi_si SPI + SI.
892  *
893  * @return next node index.
894  */
895 const dpo_id_t *
896 lisp_nsh_fib_lookup (lisp_gpe_main_t * lgm, u32 spi_si_net_order)
897 {
898  int rv;
899  BVT (clib_bihash_kv) kv, value;
900 
901  memset (&kv, 0, sizeof (kv));
902  kv.key[0] = spi_si_net_order;
903  rv = BV (clib_bihash_search_inline_2) (&lgm->nsh_fib, &kv, &value);
904 
905  if (rv != 0)
906  {
907  return lgm->nsh_cp_lkup;
908  }
909  else
910  {
912  lfe = pool_elt_at_index (lgm->lisp_fwd_entry_pool, value.value);
913  return &lfe->nsh.choice;
914  }
915 }
916 
917 /**
918  * @brief Add/del NSH FIB entry
919  *
920  * Inserts value in NSH FIB keyed by SPI+SI. If entry is
921  * overwritten the associated value is returned.
922  *
923  * @param[in] lgm Reference to @ref lisp_gpe_main_t.
924  * @param[in] spi_si SPI + SI.
925  * @param[in] dpo Load balanced mapped to SPI + SI
926  *
927  * @return ~0 or value of overwritten entry.
928  */
929 static u32
930 lisp_nsh_fib_add_del_entry (u32 spi_si_host_order, u32 lfei, u8 is_add)
931 {
933  BVT (clib_bihash_kv) kv, value;
934  u32 old_val = ~0;
935 
936  memset (&kv, 0, sizeof (kv));
937  kv.key[0] = clib_host_to_net_u32 (spi_si_host_order);
938  kv.value = 0ULL;
939 
940  if (BV (clib_bihash_search) (&lgm->nsh_fib, &kv, &value) == 0)
941  old_val = value.value;
942 
943  if (!is_add)
944  BV (clib_bihash_add_del) (&lgm->nsh_fib, &kv, 0 /* is_add */ );
945  else
946  {
947  kv.value = lfei;
948  BV (clib_bihash_add_del) (&lgm->nsh_fib, &kv, 1 /* is_add */ );
949  }
950  return old_val;
951 }
952 
953 #define NSH_FIB_DEFAULT_HASH_NUM_BUCKETS (64 * 1024)
954 #define NSH_FIB_DEFAULT_HASH_MEMORY_SIZE (32<<20)
955 
956 static void
958 {
959  BV (clib_bihash_init) (&lgm->nsh_fib, "nsh fib",
962 
963  /*
964  * the result from a 'miss' in a NSH Table
965  */
967 }
968 
969 static void
971 {
972  lisp_fwd_path_t *path;
973 
975  {
976  vec_foreach (path, lfe->paths)
977  {
979  }
980  fib_path_list_child_remove (lfe->nsh.path_list_index,
981  lfe->nsh.child_index);
982  dpo_reset (&lfe->nsh.choice);
983  }
984 
985  lisp_nsh_fib_add_del_entry (fid_addr_nsh (&lfe->key->rmt), (u32) ~ 0, 0);
986 
988  clib_mem_free (lfe->key);
989  pool_put (lgm->lisp_fwd_entry_pool, lfe);
990 }
991 
992 /**
993  * @brief Delete LISP NSH forwarding entry.
994  *
995  * Coordinates the removal of forwarding entries for NSH LISP overlay:
996  *
997  * @param[in] lgm Reference to @ref lisp_gpe_main_t.
998  * @param[in] a Parameters for building the forwarding entry.
999  *
1000  * @return 0 on success.
1001  */
1002 static int
1005 {
1007  lisp_gpe_fwd_entry_t *lfe;
1008 
1009  lfe = find_fwd_entry (lgm, a, &key);
1010 
1011  if (NULL == lfe)
1012  return VNET_API_ERROR_INVALID_VALUE;
1013 
1014  del_nsh_fwd_entry_i (lgm, lfe);
1015 
1016  return (0);
1017 }
1018 
1019 /**
1020  * @brief Construct and insert the forwarding information used by an NSH entry
1021  */
1022 static void
1024 {
1026  dpo_id_t dpo = DPO_INVALID;
1028  uword *hip;
1029 
1031  {
1032  fib_path_list_contribute_forwarding (lfe->nsh.path_list_index,
1034  &lfe->nsh.dpo);
1035 
1036  /*
1037  * LISP encap is always the same for this SPI+SI so we do that hash now
1038  * and stack on the choice.
1039  */
1040  if (DPO_LOAD_BALANCE == lfe->nsh.dpo.dpoi_type)
1041  {
1042  const dpo_id_t *tmp;
1043  const load_balance_t *lb;
1044  int hash;
1045 
1046  lb = load_balance_get (lfe->nsh.dpo.dpoi_index);
1047  hash = fid_addr_nsh (&lfe->key->rmt) % lb->lb_n_buckets;
1048  tmp =
1050 
1051  dpo_copy (&dpo, tmp);
1052  }
1053  }
1054  else
1055  {
1056  switch (lfe->action)
1057  {
1058  case SEND_MAP_REQUEST:
1059  dpo_copy (&dpo, lgm->nsh_cp_lkup);
1060  break;
1061  case NO_ACTION:
1062  case FORWARD_NATIVE:
1063  case DROP:
1065  }
1066  }
1067 
1068  /* We have only one nsh-lisp interface (no NSH virtualization) */
1070  if (hip)
1071  {
1072  hi = vnet_get_hw_interface (lgm->vnet_main, hip[0]);
1073  dpo_stack_from_node (hi->tx_node_index, &lfe->nsh.choice, &dpo);
1074  }
1075  /* add entry to nsh lisp fib */
1077  lfe - lgm->lisp_fwd_entry_pool, 1);
1078  dpo_reset (&dpo);
1079 
1080 }
1081 
1082 /**
1083  * @brief Add LISP NSH forwarding entry.
1084  *
1085  * Coordinates the creation of forwarding entries for L2 LISP overlay:
1086  * creates lisp-gpe tunnel and injects new entry in Source/Dest L2 FIB.
1087  *
1088  * @param[in] lgm Reference to @ref lisp_gpe_main_t.
1089  * @param[in] a Parameters for building the forwarding entry.
1090  *
1091  * @return 0 on success.
1092  */
1093 static int
1096 {
1098  lisp_gpe_fwd_entry_t *lfe;
1099 
1100  lfe = find_fwd_entry (lgm, a, &key);
1101 
1102  if (NULL != lfe)
1103  /* don't support updates */
1104  return VNET_API_ERROR_INVALID_VALUE;
1105 
1106  pool_get (lgm->lisp_fwd_entry_pool, lfe);
1107  memset (lfe, 0, sizeof (*lfe));
1108  lfe->key = clib_mem_alloc (sizeof (key));
1109  memcpy (lfe->key, &key, sizeof (key));
1110 
1112  lfe - lgm->lisp_fwd_entry_pool);
1113  a->fwd_entry_index = lfe - lgm->lisp_fwd_entry_pool;
1114 
1115  lfe->type = (a->is_negative ?
1118  lfe->tenant = 0;
1119 
1121  {
1122  fib_route_path_t *rpaths;
1123 
1124  /*
1125  * Make the sorted array of LISP paths with their resp. adjacency
1126  */
1127  lisp_gpe_fwd_entry_mk_paths (lfe, a);
1128 
1129  /*
1130  * From the LISP paths, construct a FIB path list that will
1131  * contribute a load-balance.
1132  */
1133  rpaths = lisp_gpe_mk_fib_paths (lfe->paths);
1134 
1135  lfe->nsh.path_list_index =
1137 
1138  /*
1139  * become a child of the path-list so we receive updates when
1140  * its forwarding state changes. this includes an implicit lock.
1141  */
1142  lfe->nsh.child_index =
1143  fib_path_list_child_add (lfe->nsh.path_list_index,
1145  lfe - lgm->lisp_fwd_entry_pool);
1146  }
1147  else
1148  {
1149  lfe->action = a->action;
1150  }
1151 
1153 
1154  return 0;
1155 }
1156 
1157 /**
1158  * @brief conver from the embedded fib_node_t struct to the LSIP entry
1159  */
1160 static lisp_gpe_fwd_entry_t *
1162 {
1163  return ((lisp_gpe_fwd_entry_t *) (((char *) node) -
1165  node)));
1166 }
1167 
1168 /**
1169  * @brief Function invoked during a backwalk of the FIB graph
1170  */
1174 {
1176 
1177  if (fid_addr_type (&lfe->key->rmt) == FID_ADDR_MAC)
1179  else if (fid_addr_type (&lfe->key->rmt) == FID_ADDR_NSH)
1181 
1182  return (FIB_NODE_BACK_WALK_CONTINUE);
1183 }
1184 
1185 /**
1186  * @brief Get a fib_node_t struct from the index of a LISP fwd entry
1187  */
1188 static fib_node_t *
1190 {
1192  lisp_gpe_fwd_entry_t *lfe;
1193 
1194  lfe = pool_elt_at_index (lgm->lisp_fwd_entry_pool, index);
1195 
1196  return (&(lfe->node));
1197 }
1198 
1199 /**
1200  * @brief An indication from the graph that the last lock has gone
1201  */
1202 static void
1204 {
1205  /* We don't manage the locks of the LISP objects via the graph, since
1206  * this object has no children. so this is a no-op. */
1207 }
1208 
1209 /**
1210  * @brief Virtual function table to register with FIB for the LISP type
1211  */
1215  .fnv_back_walk = lisp_gpe_fib_node_back_walk,
1216 };
1217 
1218 /**
1219  * @brief Forwarding entry create/remove dispatcher.
1220  *
1221  * Calls l2 or l3 forwarding entry add/del function based on input data.
1222  *
1223  * @param[in] a Forwarding entry parameters.
1224  * @param[out] hw_if_indexp NOT USED
1225  *
1226  * @return 0 on success.
1227  */
1228 int
1230  u32 * hw_if_indexp)
1231 {
1233  u8 type;
1234 
1236  {
1237  clib_warning ("LISP is disabled!");
1238  return VNET_API_ERROR_LISP_DISABLED;
1239  }
1240 
1241  type = gid_address_type (&a->rmt_eid);
1242  switch (type)
1243  {
1244  case GID_ADDR_IP_PREFIX:
1245  if (a->is_add)
1246  return add_ip_fwd_entry (lgm, a);
1247  else
1248  return del_ip_fwd_entry (lgm, a);
1249  break;
1250  case GID_ADDR_MAC:
1251  if (a->is_add)
1252  return add_l2_fwd_entry (lgm, a);
1253  else
1254  return del_l2_fwd_entry (lgm, a);
1255  case GID_ADDR_NSH:
1256  if (a->is_add)
1257  return add_nsh_fwd_entry (lgm, a);
1258  else
1259  return del_nsh_fwd_entry (lgm, a);
1260  default:
1261  clib_warning ("Forwarding entries for type %d not supported!", type);
1262  return -1;
1263  }
1264 }
1265 
1266 int
1268 {
1271  u32 i;
1272 
1273  for (i = 0; i < vlib_combined_counter_n_counters (cm); i++)
1275 
1276  return 0;
1277 }
1278 
1279 static void
1280 lisp_del_adj_stats (lisp_gpe_main_t * lgm, u32 fwd_entry_index, u32 ti)
1281 {
1282  hash_pair_t *hp;
1283  lisp_stats_key_t key;
1284  void *key_copy;
1285  uword *p;
1286  u8 *s;
1287 
1288  memset (&key, 0, sizeof (key));
1289  key.fwd_entry_index = fwd_entry_index;
1290  key.tunnel_index = ti;
1291 
1292  p = hash_get_mem (lgm->lisp_stats_index_by_key, &key);
1293  if (p)
1294  {
1295  s = pool_elt_at_index (lgm->dummy_stats_pool, p[0]);
1296  hp = hash_get_pair (lgm->lisp_stats_index_by_key, &key);
1297  key_copy = (void *) (hp->key);
1299  clib_mem_free (key_copy);
1300  pool_put (lgm->dummy_stats_pool, s);
1301  }
1302 }
1303 
1304 void
1306  u32 fwd_entry_index)
1307 {
1309  lisp_gpe_fwd_entry_key_t fe_key;
1310  lisp_gpe_fwd_entry_t *lfe;
1311  lisp_fwd_path_t *path;
1312  const lisp_gpe_adjacency_t *ladj;
1313 
1314  lfe = find_fwd_entry (lgm, a, &fe_key);
1315  if (!lfe)
1316  return;
1317 
1319  return;
1320 
1321  vec_foreach (path, lfe->paths)
1322  {
1323  ladj = lisp_gpe_adjacency_get (path->lisp_adj);
1324  lisp_del_adj_stats (lgm, fwd_entry_index, ladj->tunnel_index);
1325  }
1326 }
1327 
1328 /**
1329  * @brief Flush all the forwrding entries
1330  */
1331 void
1333 {
1335  lisp_gpe_fwd_entry_t *lfe;
1336 
1337  /* *INDENT-OFF* */
1338  pool_foreach (lfe, lgm->lisp_fwd_entry_pool,
1339  ({
1340  switch (fid_addr_type(&lfe->key->rmt))
1341  {
1342  case FID_ADDR_MAC:
1343  del_l2_fwd_entry_i (lgm, lfe);
1344  break;
1345  case FID_ADDR_IP_PREF:
1346  del_ip_fwd_entry_i (lgm, lfe);
1347  break;
1348  case FID_ADDR_NSH:
1349  del_nsh_fwd_entry_i (lgm, lfe);
1350  break;
1351  }
1352  }));
1353  /* *INDENT-ON* */
1354 }
1355 
1356 static u8 *
1357 format_lisp_fwd_path (u8 * s, va_list ap)
1358 {
1359  lisp_fwd_path_t *lfp = va_arg (ap, lisp_fwd_path_t *);
1360 
1361  s = format (s, "weight:%d ", lfp->weight);
1362  s = format (s, "adj:[%U]\n",
1366 
1367  return (s);
1368 }
1369 
1371 {
1375 
1376 
1377 static u8 *
1379 {
1381  lisp_gpe_fwd_entry_t *lfe = va_arg (ap, lisp_gpe_fwd_entry_t *);
1383  va_arg (ap, lisp_gpe_fwd_entry_format_flag_t);
1384 
1385  s = format (s, "VNI:%d VRF:%d EID: %U -> %U [index:%d]",
1386  lfe->key->vni, lfe->eid_table_id,
1387  format_fid_address, &lfe->key->lcl,
1388  format_fid_address, &lfe->key->rmt,
1389  lfe - lgm->lisp_fwd_entry_pool);
1390 
1392  {
1393  s = format (s, "\n Negative - action:%U",
1395  }
1396  else
1397  {
1398  lisp_fwd_path_t *path;
1399 
1400  s = format (s, "\n via:");
1401  vec_foreach (path, lfe->paths)
1402  {
1403  s = format (s, "\n %U", format_lisp_fwd_path, path);
1404  }
1405  }
1406 
1408  {
1409  switch (fid_addr_type (&lfe->key->rmt))
1410  {
1411  case FID_ADDR_MAC:
1412  s = format (s, " fib-path-list:%d\n", lfe->l2.path_list_index);
1413  s = format (s, " dpo:%U\n", format_dpo_id, &lfe->l2.dpo, 0);
1414  break;
1415  case FID_ADDR_NSH:
1416  s = format (s, " fib-path-list:%d\n", lfe->nsh.path_list_index);
1417  s = format (s, " dpo:%U\n", format_dpo_id, &lfe->nsh.dpo, 0);
1418  break;
1419  case FID_ADDR_IP_PREF:
1420  break;
1421  }
1422  }
1423 
1424  return (s);
1425 }
1426 
1427 static clib_error_t *
1429  unformat_input_t * input, vlib_cli_command_t * cmd)
1430 {
1432  lisp_gpe_fwd_entry_t *lfe;
1433  index_t index;
1434  u32 vni = ~0;
1435 
1436  if (unformat (input, "vni %d", &vni))
1437  ;
1438  else if (unformat (input, "%d", &index))
1439  {
1440  if (!pool_is_free_index (lgm->lisp_fwd_entry_pool, index))
1441  {
1442  lfe = pool_elt_at_index (lgm->lisp_fwd_entry_pool, index);
1443 
1444  vlib_cli_output (vm, "[%d@] %U",
1445  index,
1448  }
1449  else
1450  {
1451  vlib_cli_output (vm, "entry %d invalid", index);
1452  }
1453 
1454  return (NULL);
1455  }
1456 
1457  /* *INDENT-OFF* */
1458  pool_foreach (lfe, lgm->lisp_fwd_entry_pool,
1459  ({
1460  if ((vni == ~0) ||
1461  (lfe->key->vni == vni))
1462  vlib_cli_output (vm, "%U", format_lisp_gpe_fwd_entry, lfe,
1463  LISP_GPE_FWD_ENTRY_FORMAT_NONE);
1464  }));
1465  /* *INDENT-ON* */
1466 
1467  return (NULL);
1468 }
1469 
1470 /* *INDENT-OFF* */
1472  .path = "show gpe entry",
1473  .short_help = "show gpe entry vni <vni> vrf <vrf> [leid <leid>] reid <reid>",
1474  .function = lisp_gpe_fwd_entry_show,
1475 };
1476 /* *INDENT-ON* */
1477 
1478 clib_error_t *
1480 {
1482  clib_error_t *error = NULL;
1483 
1485  return (error);
1486 
1487  l2_fib_init (lgm);
1488  nsh_fib_init (lgm);
1489 
1491 
1492  return (error);
1493 }
1494 
1495 u32 *
1497 {
1499  lisp_gpe_fwd_entry_t *lfe;
1500  u32 *vnis = 0;
1501 
1502  /* *INDENT-OFF* */
1503  pool_foreach (lfe, lgm->lisp_fwd_entry_pool,
1504  ({
1505  hash_set (vnis, lfe->key->vni, 0);
1506  }));
1507  /* *INDENT-ON* */
1508 
1509  return vnis;
1510 }
1511 
1514 {
1516  lisp_gpe_fwd_entry_t *lfe;
1517  lisp_api_gpe_fwd_entry_t *entries = 0, e;
1518 
1519  /* *INDENT-OFF* */
1520  pool_foreach (lfe, lgm->lisp_fwd_entry_pool,
1521  ({
1522  if (lfe->key->vni == vni)
1523  {
1524  memset (&e, 0, sizeof (e));
1525  e.dp_table = lfe->eid_table_id;
1526  e.vni = lfe->key->vni;
1527  if (lfe->type == LISP_GPE_FWD_ENTRY_TYPE_NEGATIVE)
1528  e.action = lfe->action;
1529  e.fwd_entry_index = lfe - lgm->lisp_fwd_entry_pool;
1530  memcpy (&e.reid, &lfe->key->rmt, sizeof (e.reid));
1531  memcpy (&e.leid, &lfe->key->lcl, sizeof (e.leid));
1532  vec_add1 (entries, e);
1533  }
1534  }));
1535  /* *INDENT-ON* */
1536 
1537  return entries;
1538 }
1539 
1541 
1542 /*
1543  * fd.io coding-style-patch-verification: ON
1544  *
1545  * Local Variables:
1546  * eval: (c-set-style "gnu")
1547  * End:
1548  */
void dpo_unlock(dpo_id_t *dpo)
Release a reference counting lock on the DPO.
Definition: dpo.c:292
#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.
struct lisp_gpe_fwd_entry_t_::@221::@228 nsh
Fields relevant to an NSH entry.
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:1072
struct lisp_gpe_fwd_entry_t_::@221::@227 l2
Fields relevant to an L2 entry.
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:431
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:341
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:350
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:337
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:257
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:184
A representation of a path as described by a route producer.
Definition: fib_types.h:336
u32 * vnet_lisp_gpe_get_fwd_entry_vnis(void)
u32 bd_id
bridge domain id
Definition: lisp_gpe.h:269
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:162
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:705
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:134
void dpo_copy(dpo_id_t *dst, const dpo_id_t *src)
atomic copy a data-plane object.
Definition: dpo.c:235
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:522
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:419
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:133
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:121
index_t load_balance_create(u32 n_buckets, dpo_proto_t lb_proto, flow_hash_config_t fhc)
Definition: load_balance.c:193
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
#define pool_foreach(VAR, POOL, BODY)
Iterate through pool.
Definition: pool.h:376
u32 frp_sw_if_index
The interface.
Definition: fib_types.h:369
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:390
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:233
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:151
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
#define hash_get_pair(h, key)
Definition: hash.h:251
Contribute an object that is to be used to forward Ethernet packets.
Definition: fib_types.h:109
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:226
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:233
void gid_to_dp_address(gid_address_t *g, dp_address_t *d)
Definition: lisp_types.c:598
The identity of a DPO is a combination of its type and its instance number/index of objects of that t...
Definition: dpo.h:152
void fib_table_unlock(u32 fib_index, fib_protocol_t proto)
Take a reference counting lock on the table.
Definition: fib_table.c:1145
#define hash_get(h, key)
Definition: hash.h:248
Definition: fib_entry.h:237
#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:266
u8 * format_negative_mapping_action(u8 *s, va_list *args)
Definition: lisp_types.c:430
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:1169
#define vec_del1(v, i)
Delete the element at index I.
Definition: vec.h:805
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)
u8 * dummy_stats_pool
Definition: lisp_gpe.h:162
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:127
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:279
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:907
Definition: lisp_gpe.h:282
#define gid_address_ippref(_a)
Definition: lisp_types.h:258
#define L2_FIB_DEFAULT_HASH_MEMORY_SIZE
u8 is_negative
type of mapping
Definition: lisp_gpe.h:236
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:260
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:229
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:835
u32 frp_weight
[un]equal cost path weight
Definition: fib_types.h:383
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:267
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:159
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.
#define fid_addr_ippref(_a)
Definition: lisp_types.h:130
Context passed between object during a back walk.
Definition: fib_node.h:192
#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:290
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:135
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:231
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:1041
static u64 mac_to_u64(u8 *m)
Definition: load_balance.c:901
dpo_proto_t fib_proto_to_dpo(fib_protocol_t fib_proto)
Definition: fib_types.c:211
gid_address_t rmt_eid
remote eid
Definition: lisp_gpe.h:245
void load_balance_set_bucket(index_t lbi, u32 bucket, const dpo_id_t *next)
Definition: load_balance.c:210
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:123
u64 uword
Definition: types.h:112
static void gpe_native_fwd_add_del_lfe(lisp_gpe_fwd_entry_t *lfe, u8 is_add)
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:239
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:168
#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:272
#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:248
#define DPO_INVALID
An initialiser for DPOs declared on the stack.
Definition: dpo.h:179
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:266
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
fib_route_path_t * native_fwd_rpath[2]
Native fwd data structures.
Definition: lisp_gpe.h:167
LISP.
Definition: fib_entry.h:70
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:205
#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:76
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:237
gid_address_t lcl_eid
local eid
Definition: lisp_gpe.h:242
tunnel_lookup_t nsh_ifaces
Definition: lisp_gpe.h:156
u32 * native_fwd_lfes[2]
Definition: lisp_gpe.h:168
void vlib_cli_output(vlib_main_t *vm, char *fmt,...)
Definition: cli.c:680
#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:161
uword unformat(unformat_input_t *i, const char *fmt,...)
Definition: unformat.c:972
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.