FD.io VPP  v17.01.1-3-gc6833f8
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 
287  dproto = (ip_prefix_version (&lfe->key->rmt.ippref) == IP4 ?
289 
291  &lfe->key->rmt.ippref);
292 
294  {
295  dpo_id_t dpo = DPO_INVALID;
296 
297  switch (lfe->action)
298  {
299  case LISP_NO_ACTION:
300  /* TODO update timers? */
301  case LISP_FORWARD_NATIVE:
302  /* TODO check if route/next-hop for eid exists in fib and add
303  * more specific for the eid with the next-hop found */
305  /* insert tunnel that always sends map-request */
306  dpo_copy (&dpo, lisp_cp_dpo_get (dproto));
307  break;
308  case LISP_DROP:
309  /* for drop fwd entries, just add route, no need to add encap tunnel */
310  dpo_copy (&dpo, drop_dpo_get (dproto));
311  break;
312  }
314  &lfe->key->lcl.ippref, &dpo);
315  dpo_reset (&dpo);
316  }
317  else
318  {
320  &lfe->key->lcl.ippref, lfe->paths);
321  }
322 }
323 
324 static void
326 {
328  &lfe->key->lcl.ippref,
329  lfe->eid_fib_index, &lfe->key->rmt.ippref);
330 }
331 
332 static void
334 {
335  switch (gid_address_type (g))
336  {
337  case GID_ADDR_IP_PREFIX:
338  case GID_ADDR_SRC_DST:
340  d->type = FID_ADDR_IP_PREF;
341  break;
342  case GID_ADDR_MAC:
343  default:
344  mac_copy (&d->mac, &gid_address_mac (g));
345  d->type = FID_ADDR_MAC;
346  break;
347  }
348 }
349 
350 static lisp_gpe_fwd_entry_t *
354 {
355  uword *p;
356 
357  memset (key, 0, sizeof (*key));
358 
360  {
361  /*
362  * the ip version of the source is not set to ip6 when the
363  * source is all zeros. force it.
364  */
367  }
368 
369  gid_to_dp_address (&a->rmt_eid, &key->rmt);
370  gid_to_dp_address (&a->lcl_eid, &key->lcl);
371  key->vni = a->vni;
372 
373  p = hash_get_mem (lgm->lisp_gpe_fwd_entries, key);
374 
375  if (NULL != p)
376  {
377  return (pool_elt_at_index (lgm->lisp_fwd_entry_pool, p[0]));
378  }
379  return (NULL);
380 }
381 
382 static int
383 lisp_gpe_fwd_entry_path_sort (void *a1, void *a2)
384 {
385  lisp_fwd_path_t *p1 = a1, *p2 = a2;
386 
387  return (p1->priority - p2->priority);
388 }
389 
390 static void
393 {
394  lisp_fwd_path_t *path;
395  u32 index;
396 
397  vec_validate (lfe->paths, vec_len (a->locator_pairs) - 1);
398 
399  vec_foreach_index (index, a->locator_pairs)
400  {
401  path = &lfe->paths[index];
402 
403  path->priority = a->locator_pairs[index].priority;
404  path->weight = a->locator_pairs[index].weight;
405 
406  path->lisp_adj =
408  [index],
409  a->dp_table, lfe->key->vni);
410  }
412 }
413 
414 /**
415  * @brief Add/Delete LISP IP forwarding entry.
416  *
417  * creation of forwarding entries for IP LISP overlay:
418  *
419  * @param[in] lgm Reference to @ref lisp_gpe_main_t.
420  * @param[in] a Parameters for building the forwarding entry.
421  *
422  * @return 0 on success.
423  */
424 static int
427 {
430  fib_protocol_t fproto;
431 
432  lfe = find_fwd_entry (lgm, a, &key);
433 
434  if (NULL != lfe)
435  /* don't support updates */
436  return VNET_API_ERROR_INVALID_VALUE;
437 
438  pool_get (lgm->lisp_fwd_entry_pool, lfe);
439  memset (lfe, 0, sizeof (*lfe));
440  lfe->key = clib_mem_alloc (sizeof (key));
441  memcpy (lfe->key, &key, sizeof (key));
442 
444  lfe - lgm->lisp_fwd_entry_pool);
445 
446  fproto = (IP4 == ip_prefix_version (&fid_addr_ippref (&lfe->key->rmt)) ?
448 
449  lfe->type = (a->is_negative ?
453  lfe->eid_table_id = a->table_id;
455  lfe->eid_table_id);
456 
458  {
460  }
461 
462  create_fib_entries (lfe);
463 
464  return (0);
465 }
466 
467 static void
469 {
470  lisp_fwd_path_t *path;
471  fib_protocol_t fproto;
472 
473  vec_foreach (path, lfe->paths)
474  {
476  }
477 
478  delete_fib_entries (lfe);
479 
480  fproto = (IP4 == ip_prefix_version (&fid_addr_ippref (&lfe->key->rmt)) ?
482  fib_table_unlock (lfe->eid_fib_index, fproto);
483 
485  clib_mem_free (lfe->key);
486  pool_put (lgm->lisp_fwd_entry_pool, lfe);
487 }
488 
489 /**
490  * @brief Add/Delete LISP IP forwarding entry.
491  *
492  * removal of forwarding entries for IP LISP overlay:
493  *
494  * @param[in] lgm Reference to @ref lisp_gpe_main_t.
495  * @param[in] a Parameters for building the forwarding entry.
496  *
497  * @return 0 on success.
498  */
499 static int
502 {
505 
506  lfe = find_fwd_entry (lgm, a, &key);
507 
508  if (NULL == lfe)
509  /* no such entry */
510  return VNET_API_ERROR_INVALID_VALUE;
511 
512  del_ip_fwd_entry_i (lgm, lfe);
513 
514  return (0);
515 }
516 
517 static void
518 make_mac_fib_key (BVT (clib_bihash_kv) * kv, u16 bd_index, u8 src_mac[6],
519  u8 dst_mac[6])
520 {
521  kv->key[0] = (((u64) bd_index) << 48) | mac_to_u64 (dst_mac);
522  kv->key[1] = mac_to_u64 (src_mac);
523  kv->key[2] = 0;
524 }
525 
526 /**
527  * @brief Lookup L2 SD FIB entry
528  *
529  * Does a vni + dest + source lookup in the L2 LISP FIB. If the lookup fails
530  * it tries a second time with source set to 0 (i.e., a simple dest lookup).
531  *
532  * @param[in] lgm Reference to @ref lisp_gpe_main_t.
533  * @param[in] bd_index Bridge domain index.
534  * @param[in] src_mac Source mac address.
535  * @param[in] dst_mac Destination mac address.
536  *
537  * @return index of mapping matching the lookup key.
538  */
539 index_t
540 lisp_l2_fib_lookup (lisp_gpe_main_t * lgm, u16 bd_index, u8 src_mac[6],
541  u8 dst_mac[6])
542 {
543  int rv;
544  BVT (clib_bihash_kv) kv, value;
545 
546  make_mac_fib_key (&kv, bd_index, src_mac, dst_mac);
547  rv = BV (clib_bihash_search_inline_2) (&lgm->l2_fib, &kv, &value);
548 
549  /* no match, try with src 0, catch all for dst */
550  if (rv != 0)
551  {
552  kv.key[1] = 0;
553  rv = BV (clib_bihash_search_inline_2) (&lgm->l2_fib, &kv, &value);
554  if (rv == 0)
555  return value.value;
556  }
557  else
558  return value.value;
559 
561 }
562 
563 /**
564  * @brief Add/del L2 SD FIB entry
565  *
566  * Inserts value in L2 FIB keyed by vni + dest + source. If entry is
567  * overwritten the associated value is returned.
568  *
569  * @param[in] lgm Reference to @ref lisp_gpe_main_t.
570  * @param[in] bd_index Bridge domain index.
571  * @param[in] src_mac Source mac address.
572  * @param[in] dst_mac Destination mac address.
573  * @param[in] val Value to add.
574  * @param[in] is_add Add/del flag.
575  *
576  * @return ~0 or value of overwritten entry.
577  */
578 static u32
579 lisp_l2_fib_add_del_entry (u16 bd_index, u8 src_mac[6],
580  u8 dst_mac[6], const dpo_id_t * dpo, u8 is_add)
581 {
583  BVT (clib_bihash_kv) kv, value;
584  u32 old_val = ~0;
585 
586  make_mac_fib_key (&kv, bd_index, src_mac, dst_mac);
587 
588  if (BV (clib_bihash_search) (&lgm->l2_fib, &kv, &value) == 0)
589  old_val = value.value;
590 
591  if (!is_add)
592  BV (clib_bihash_add_del) (&lgm->l2_fib, &kv, 0 /* is_add */ );
593  else
594  {
595  kv.value = dpo->dpoi_index;
596  BV (clib_bihash_add_del) (&lgm->l2_fib, &kv, 1 /* is_add */ );
597  }
598  return old_val;
599 }
600 
601 #define L2_FIB_DEFAULT_HASH_NUM_BUCKETS (64 * 1024)
602 #define L2_FIB_DEFAULT_HASH_MEMORY_SIZE (32<<20)
603 
604 static void
606 {
607  index_t lbi;
608 
609  BV (clib_bihash_init) (&lgm->l2_fib, "l2 fib",
612 
613  /*
614  * the result from a 'miss' in a L2 Table
615  */
618 
620 }
621 
622 static void
624 {
625  lisp_fwd_path_t *path;
626 
628  {
629  vec_foreach (path, lfe->paths)
630  {
632  }
633  fib_path_list_child_remove (lfe->l2.path_list_index,
634  lfe->l2.child_index);
635  }
636 
637  lisp_l2_fib_add_del_entry (lfe->l2.eid_bd_index,
638  fid_addr_mac (&lfe->key->lcl),
639  fid_addr_mac (&lfe->key->rmt), NULL, 0);
640 
642  clib_mem_free (lfe->key);
643  pool_put (lgm->lisp_fwd_entry_pool, lfe);
644 }
645 
646 /**
647  * @brief Delete LISP L2 forwarding entry.
648  *
649  * Coordinates the removal of forwarding entries for L2 LISP overlay:
650  *
651  * @param[in] lgm Reference to @ref lisp_gpe_main_t.
652  * @param[in] a Parameters for building the forwarding entry.
653  *
654  * @return 0 on success.
655  */
656 static int
659 {
662 
663  lfe = find_fwd_entry (lgm, a, &key);
664 
665  if (NULL == lfe)
666  return VNET_API_ERROR_INVALID_VALUE;
667 
668  del_l2_fwd_entry_i (lgm, lfe);
669 
670  return (0);
671 }
672 
673 /**
674  * @brief Construct and insert the forwarding information used by a L2 entry
675  */
676 static void
678 {
680  dpo_id_t dpo = DPO_INVALID;
681 
683  {
684  fib_path_list_contribute_forwarding (lfe->l2.path_list_index,
686  &lfe->l2.dpo);
687  dpo_copy (&dpo, &lfe->l2.dpo);
688  }
689  else
690  {
691  dpo_copy (&dpo, &lgm->l2_lb_cp_lkup);
692  }
693 
694  /* add entry to l2 lisp fib */
695  lisp_l2_fib_add_del_entry (lfe->l2.eid_bd_index,
696  fid_addr_mac (&lfe->key->lcl),
697  fid_addr_mac (&lfe->key->rmt), &dpo, 1);
698 
699  dpo_reset (&dpo);
700 }
701 
702 /**
703  * @brief Add LISP L2 forwarding entry.
704  *
705  * Coordinates the creation of forwarding entries for L2 LISP overlay:
706  * creates lisp-gpe tunnel and injects new entry in Source/Dest L2 FIB.
707  *
708  * @param[in] lgm Reference to @ref lisp_gpe_main_t.
709  * @param[in] a Parameters for building the forwarding entry.
710  *
711  * @return 0 on success.
712  */
713 static int
716 {
718  bd_main_t *bdm = &bd_main;
720  uword *bd_indexp;
721 
722  bd_indexp = hash_get (bdm->bd_index_by_bd_id, a->bd_id);
723  if (!bd_indexp)
724  {
725  clib_warning ("bridge domain %d doesn't exist", a->bd_id);
726  return -1;
727  }
728 
729  lfe = find_fwd_entry (lgm, a, &key);
730 
731  if (NULL != lfe)
732  /* don't support updates */
733  return VNET_API_ERROR_INVALID_VALUE;
734 
735  pool_get (lgm->lisp_fwd_entry_pool, lfe);
736  memset (lfe, 0, sizeof (*lfe));
737  lfe->key = clib_mem_alloc (sizeof (key));
738  memcpy (lfe->key, &key, sizeof (key));
739 
741  lfe - lgm->lisp_fwd_entry_pool);
742 
743  lfe->type = (a->is_negative ?
746  lfe->l2.eid_bd_id = a->bd_id;
747  lfe->l2.eid_bd_index = bd_indexp[0];
749 
751  {
752  fib_route_path_t *rpaths;
753 
754  /*
755  * Make the sorted array of LISP paths with their resp. adjacency
756  */
758 
759  /*
760  * From the LISP paths, construct a FIB path list that will
761  * contribute a load-balance.
762  */
763  rpaths = lisp_gpe_mk_fib_paths (lfe->paths);
764 
765  lfe->l2.path_list_index =
767 
768  /*
769  * become a child of the path-list so we receive updates when
770  * its forwarding state changes. this includes an implicit lock.
771  */
772  lfe->l2.child_index =
773  fib_path_list_child_add (lfe->l2.path_list_index,
775  lfe - lgm->lisp_fwd_entry_pool);
776  }
777  else
778  {
779  lfe->action = a->action;
780  }
781 
783 
784  return 0;
785 }
786 
787 /**
788  * @brief conver from the embedded fib_node_t struct to the LSIP entry
789  */
790 static lisp_gpe_fwd_entry_t *
792 {
793  return ((lisp_gpe_fwd_entry_t *) (((char *) node) -
795  node)));
796 }
797 
798 /**
799  * @brief Function invoked during a backwalk of the FIB graph
800  */
804 {
806 
808 }
809 
810 /**
811  * @brief Get a fib_node_t struct from the index of a LISP fwd entry
812  */
813 static fib_node_t *
815 {
818 
819  lfe = pool_elt_at_index (lgm->lisp_fwd_entry_pool, index);
820 
821  return (&(lfe->node));
822 }
823 
824 /**
825  * @brief An indication from the graph that the last lock has gone
826  */
827 static void
829 {
830  /* We don't manage the locks of the LISP objects via the graph, since
831  * this object has no children. so this is a no-op. */
832 }
833 
834 /**
835  * @brief Virtual function table to register with FIB for the LISP type
836  */
837 const static fib_node_vft_t lisp_fwd_vft = {
840  .fnv_back_walk = lisp_gpe_fib_node_back_walk,
841 };
842 
843 /**
844  * @brief Forwarding entry create/remove dispatcher.
845  *
846  * Calls l2 or l3 forwarding entry add/del function based on input data.
847  *
848  * @param[in] a Forwarding entry parameters.
849  * @param[out] hw_if_indexp NOT USED
850  *
851  * @return 0 on success.
852  */
853 int
855  u32 * hw_if_indexp)
856 {
858  u8 type;
859 
861  {
862  clib_warning ("LISP is disabled!");
863  return VNET_API_ERROR_LISP_DISABLED;
864  }
865 
866  type = gid_address_type (&a->rmt_eid);
867  switch (type)
868  {
869  case GID_ADDR_IP_PREFIX:
870  if (a->is_add)
871  return add_ip_fwd_entry (lgm, a);
872  else
873  return del_ip_fwd_entry (lgm, a);
874  break;
875  case GID_ADDR_MAC:
876  if (a->is_add)
877  return add_l2_fwd_entry (lgm, a);
878  else
879  return del_l2_fwd_entry (lgm, a);
880  default:
881  clib_warning ("Forwarding entries for type %d not supported!", type);
882  return -1;
883  }
884 }
885 
886 /**
887  * @brief Flush all the forwrding entries
888  */
889 void
891 {
894 
895  /* *INDENT-OFF* */
897  ({
898  switch (fid_addr_type(&lfe->key->rmt))
899  {
900  case FID_ADDR_MAC:
901  del_l2_fwd_entry_i (lgm, lfe);
902  break;
903  case FID_ADDR_IP_PREF:
904  del_ip_fwd_entry_i (lgm, lfe);
905  break;
906  }
907  }));
908  /* *INDENT-ON* */
909 }
910 
911 static u8 *
912 format_lisp_fwd_path (u8 * s, va_list ap)
913 {
914  lisp_fwd_path_t *lfp = va_arg (ap, lisp_fwd_path_t *);
915 
916  s = format (s, "priority:%d weight:%d ", lfp->priority, lfp->weight);
917  s = format (s, "adj:[%U]\n",
921 
922  return (s);
923 }
924 
926 {
930 
931 
932 static u8 *
933 format_lisp_gpe_fwd_entry (u8 * s, va_list ap)
934 {
936  lisp_gpe_fwd_entry_t *lfe = va_arg (ap, lisp_gpe_fwd_entry_t *);
939 
940  s = format (s, "VNI:%d VRF:%d EID: %U -> %U [index:%d]",
941  lfe->key->vni, lfe->eid_table_id,
942  format_fid_address, &lfe->key->lcl,
943  format_fid_address, &lfe->key->rmt,
944  lfe - lgm->lisp_fwd_entry_pool);
945 
947  {
948  s = format (s, "\n Negative - action:%U",
950  }
951  else
952  {
953  lisp_fwd_path_t *path;
954 
955  s = format (s, "\n via:");
956  vec_foreach (path, lfe->paths)
957  {
958  s = format (s, "\n %U", format_lisp_fwd_path, path);
959  }
960  }
961 
963  {
964  switch (fid_addr_type (&lfe->key->rmt))
965  {
966  case FID_ADDR_MAC:
967  s = format (s, " fib-path-list:%d\n", lfe->l2.path_list_index);
968  s = format (s, " dpo:%U\n", format_dpo_id, &lfe->l2.dpo, 0);
969  break;
970  case FID_ADDR_IP_PREF:
971  break;
972  }
973  }
974 
975  return (s);
976 }
977 
978 static clib_error_t *
980  unformat_input_t * input, vlib_cli_command_t * cmd)
981 {
984  index_t index;
985  u32 vni = ~0;
986 
987  if (unformat (input, "vni %d", &vni))
988  ;
989  else if (unformat (input, "%d", &index))
990  {
991  if (!pool_is_free_index (lgm->lisp_fwd_entry_pool, index))
992  {
993  lfe = pool_elt_at_index (lgm->lisp_fwd_entry_pool, index);
994 
995  vlib_cli_output (vm, "[%d@] %U",
996  index,
999  }
1000  else
1001  {
1002  vlib_cli_output (vm, "entry %d invalid", index);
1003  }
1004 
1005  return (NULL);
1006  }
1007 
1008  /* *INDENT-OFF* */
1009  pool_foreach (lfe, lgm->lisp_fwd_entry_pool,
1010  ({
1011  if ((vni == ~0) ||
1012  (lfe->key->vni == vni))
1013  vlib_cli_output (vm, "%U", format_lisp_gpe_fwd_entry, lfe,
1014  LISP_GPE_FWD_ENTRY_FORMAT_NONE);
1015  }));
1016  /* *INDENT-ON* */
1017 
1018  return (NULL);
1019 }
1020 
1021 /* *INDENT-OFF* */
1023  .path = "show lisp gpe entry",
1024  .short_help = "show lisp gpe entry vni <vni> vrf <vrf> [leid <leid>] reid <reid>",
1025  .function = lisp_gpe_fwd_entry_show,
1026 };
1027 /* *INDENT-ON* */
1028 
1029 clib_error_t *
1031 {
1033  clib_error_t *error = NULL;
1034 
1036  return (error);
1037 
1038  l2_fib_init (lgm);
1039 
1041 
1042  return (error);
1043 }
1044 
1046 
1047 /*
1048  * fd.io coding-style-patch-verification: ON
1049  *
1050  * Local Variables:
1051  * eval: (c-set-style "gnu")
1052  * End:
1053  */
void dpo_unlock(dpo_id_t *dpo)
Release a reference counting lock on the DPO.
Definition: dpo.c:278
#define vec_validate(V, I)
Make sure vector is long enough for given index (no header, unspecified alignment) ...
Definition: vec.h:396
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:995
fib_protocol_t fp_proto
protocol type
Definition: fib_types.h:154
fib_protocol_t frp_proto
The protocol of the address below.
Definition: fib_types.h:290
#define vec_foreach_index(var, v)
Iterate over vector indices.
ip46_address_t frp_addr
The next-hop address.
Definition: fib_types.h:299
static void gid_to_dp_address(gid_address_t *g, dp_address_t *d)
static const fib_node_vft_t lisp_fwd_vft
Virtual function table to register with FIB for the LISP type.
static int add_l2_fwd_entry(lisp_gpe_main_t *lgm, vnet_lisp_gpe_add_del_fwd_entry_args_t *a)
Add LISP L2 forwarding entry.
#define gid_address_type(_a)
Definition: lisp_types.h:228
uword unformat(unformat_input_t *i, char *fmt,...)
Definition: unformat.c:966
static void l2_fib_init(lisp_gpe_main_t *lgm)
negative_fwd_actions_e action
When the type is negative.
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:174
A representation of a path as described by a route producer.
Definition: fib_types.h:285
bad routing header type(not 4)") sr_error (NO_MORE_SEGMENTS
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:159
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:677
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:89
void dpo_copy(dpo_id_t *dst, const dpo_id_t *src)
atomic copy a data-plane object.
Definition: dpo.c:221
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,r-EID,vni}.
#define hash_set_mem(h, key, value)
Definition: hash.h:274
#define STRUCT_OFFSET_OF(t, f)
Definition: clib.h:62
u32 lisp_gpe_tenant_find_or_create(u32 vni)
Find or create a tenant for the given VNI.
#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:126
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:117
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 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:348
u32 frp_sw_if_index
The interface.
Definition: fib_types.h:311
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
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:399
u16 bd_id
bridge domain id
Definition: lisp_gpe.h:216
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])
LISP-GPE fwd entry key.
u8 is_add
Definition: lisp_gpe.h:180
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.
Aggregrate type for a prefix.
Definition: fib_types.h:145
uword * lisp_gpe_fwd_entries
DB of all forwarding entries.
Definition: lisp_gpe.h:95
#define clib_warning(format, args...)
Definition: error.h:59
unsigned long u64
Definition: types.h:89
Contribute an object that is to be used to forward Ethernet packets.
Definition: fib_types.h:103
enum dpo_proto_t_ dpo_proto_t
Data path protocol.
#define vlib_call_init_function(vm, x)
Definition: init.h:161
dp_address_t rmt
uword * bd_index_by_bd_id
Definition: l2_bd.h:27
Definition: lisp_gpe.h:178
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:216
The identity of a DPO is a combination of its type and its instance number/index of objects of that t...
Definition: dpo.h:138
void fib_table_unlock(u32 fib_index, fib_protocol_t proto)
Take a reference counting lock on the table.
Definition: fib_table.c:1048
#define hash_get(h, key)
Definition: hash.h:248
Definition: fib_entry.h:220
#define pool_elt_at_index(p, i)
Returns pointer to element at given index.
Definition: pool.h:369
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:213
u8 * format_negative_mapping_action(u8 *s, va_list *args)
Definition: lisp_types.c:380
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.
#define gid_address_mac(_a)
Definition: lisp_types.h:234
static void del_l2_fwd_entry_i(lisp_gpe_main_t *lgm, lisp_gpe_fwd_entry_t *lfe)
load-balancing over a choice of [un]equal cost paths
Definition: dpo.h:102
#define pool_put(P, E)
Free an object E in pool P.
Definition: pool.h:214
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:1072
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:273
void clib_bihash_init(clib_bihash *h, char *name, u32 nbuckets, uword memory_size)
initialize a bounded index extensible hash table
void vlib_cli_output(vlib_main_t *vm, char *fmt,...)
Definition: cli.c:576
void ip_address_to_46(const ip_address_t *addr, ip46_address_t *a, fib_protocol_t *proto)
Definition: lisp_types.c:779
#define gid_address_ippref(_a)
Definition: lisp_types.h:229
#define L2_FIB_DEFAULT_HASH_MEMORY_SIZE
u8 is_negative
type of mapping
Definition: lisp_gpe.h:183
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:207
int fib_entry_is_sourced(fib_node_index_t fib_entry_index, fib_source_t source)
#define vec_free(V)
Free vector&#39;s memory (no header).
Definition: vec.h:300
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:808
u32 frp_weight
[un]equal cost path weight
Definition: fib_types.h:320
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.
fib_node_get_t fnv_get
Definition: fib_node.h:261
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:211
fid_addr_type_t type
Definition: lisp_types.h:120
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:154
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:125
Context passed between object during a back walk.
Definition: fib_node.h:186
#define VLIB_CLI_COMMAND(x,...)
Definition: cli.h:154
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
struct _gid_address_t gid_address_t
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:127
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
int clib_bihash_search(clib_bihash *h, clib_bihash_kv *search_v, clib_bihash_kv *return_v)
Search a bi-hash table.
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
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)
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:964
static u64 mac_to_u64(u8 *m)
Definition: load_balance.c:872
void fib_path_list_contribute_forwarding(fib_node_index_t path_list_index, fib_forward_chain_type_t type, dpo_id_t *dpo)
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:192
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:118
u64 uword
Definition: types.h:112
negative_fwd_actions_e action
action for negative mappings
Definition: lisp_gpe.h:186
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:154
#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:100
#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:120
static u8 * format_lisp_gpe_fwd_entry(u8 *s, va_list ap)
static uword max_log2(uword x)
Definition: clib.h:222
u32 dp_table
generic access
Definition: lisp_gpe.h:219
#define vec_sort_with_function(vec, f)
Sort a vector using the supplied element comparison function.
Definition: vec.h:920
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:195
#define DPO_INVALID
An initialiser for DPOs declared on the stack.
Definition: dpo.h:165
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
void mac_copy(void *dst, void *src)
Definition: lisp_types.c:915
A FIB graph nodes virtual function table.
Definition: fib_node.h:260
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:91
u8 * format(u8 *s, const char *fmt,...)
Definition: format.c:418
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:191
#define vec_foreach(var, vec)
Vector iterator.
struct _unformat_input_t unformat_input_t
static void lisp_gpe_l2_update_fwding(lisp_gpe_fwd_entry_t *lfe)
Construct and insert the forwarding information used by a L2 entry.
u32 flags
Definition: vhost-user.h:75
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:206
gid_address_t lcl_eid
local eid
Definition: lisp_gpe.h:189
#define L2_FIB_DEFAULT_HASH_NUM_BUCKETS
void ip_prefix_copy(void *dst, void *src)
Definition: lisp_types.c:909
void fib_entry_set_source_data(fib_node_index_t fib_entry_index, fib_source_t source, const void *data)
struct lisp_gpe_fwd_entry_t_::@230::@236 l2
Fields relevant to an L2 entry.
lisp_gpe_fwd_entry_format_flag_t_
ip_address_t remote_rloc
remote RLOC.
index_t lisp_adj
The adjacency constructed for the locator pair.
A LISP Forwarding Entry.