FD.io VPP  v16.12-rc0-308-g931be3a
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 
145  ASSERT (NULL != dst_prefix);
146  ASSERT (NULL != src_prefix);
147 
148  ip_prefix_to_fib_prefix (dst_prefix, &dst_fib_prefix);
149  ip_prefix_to_fib_prefix (src_prefix, &src_fib_prefix);
150 
151  fib_table_entry_delete (src_fib_index, &src_fib_prefix, FIB_SOURCE_LISP);
152 
153  if (0 == fib_table_get_num_entries (src_fib_index,
154  src_fib_prefix.fp_proto,
156  {
157  /*
158  * there's nothing left, unlock the source FIB and the
159  * destination route
160  */
161  fib_table_entry_special_remove (dst_fib_index,
162  &dst_fib_prefix, FIB_SOURCE_LISP);
163  fib_table_unlock (src_fib_index, src_fib_prefix.fp_proto);
164  }
165 }
166 
167 /**
168  * @brief Add route to IP4 or IP6 SRC FIB.
169  *
170  * Adds a route to in the LISP SRC FIB with the result of the route
171  * being the DPO passed.
172  *
173  * @param[in] src_fib_index The index/ID of the SRC FIB
174  * @param[in] src_prefix Source IP prefix.
175  * @param[in] src_dpo The DPO the route will link to.
176  */
177 static void
179  const ip_prefix_t * src_prefix,
180  const dpo_id_t * src_dpo)
181 {
182  fib_prefix_t src_fib_prefix;
183 
184  ip_prefix_to_fib_prefix (src_prefix, &src_fib_prefix);
185 
186  /*
187  * add the entry into the source fib.
188  */
189  fib_node_index_t src_fei;
190 
191  src_fei = fib_table_lookup_exact_match (src_fib_index, &src_fib_prefix);
192 
193  if (FIB_NODE_INDEX_INVALID == src_fei ||
195  {
196  fib_table_entry_special_dpo_add (src_fib_index,
197  &src_fib_prefix,
199  FIB_ENTRY_FLAG_EXCLUSIVE, src_dpo);
200  }
201 }
202 
203 static fib_route_path_t *
205 {
206  const lisp_gpe_adjacency_t *ladj;
207  fib_route_path_t *rpaths = NULL;
208  u8 best_priority;
209  u32 ii;
210 
211  vec_validate (rpaths, vec_len (paths) - 1);
212 
213  best_priority = paths[0].priority;
214 
215  vec_foreach_index (ii, paths)
216  {
217  if (paths[0].priority != best_priority)
218  break;
219 
220  ladj = lisp_gpe_adjacency_get (paths[ii].lisp_adj);
221 
223  &rpaths[ii].frp_addr, &rpaths[ii].frp_proto);
224 
225  rpaths[ii].frp_sw_if_index = ladj->sw_if_index;
226  rpaths[ii].frp_weight = (paths[ii].weight ? paths[ii].weight : 1);
227  rpaths[ii].frp_label = MPLS_LABEL_INVALID;
228  }
229 
230  ASSERT (0 != vec_len (rpaths));
231 
232  return (rpaths);
233 }
234 
235 /**
236  * @brief Add route to IP4 or IP6 SRC FIB.
237  *
238  * Adds a route to in the LISP SRC FIB for the tunnel.
239  *
240  * @param[in] src_fib_index The index/ID of the SRC FIB
241  * @param[in] src_prefix Source IP prefix.
242  * @param[in] paths The paths from which to construct the
243  * load balance
244  */
245 static void
246 ip_src_fib_add_route (u32 src_fib_index,
247  const ip_prefix_t * src_prefix,
248  const lisp_fwd_path_t * paths)
249 {
250  fib_prefix_t src_fib_prefix;
251  fib_route_path_t *rpaths;
252 
253  ip_prefix_to_fib_prefix (src_prefix, &src_fib_prefix);
254 
255  rpaths = lisp_gpe_mk_fib_paths (paths);
256 
257  fib_table_entry_update (src_fib_index,
258  &src_fib_prefix,
260  vec_free (rpaths);
261 }
262 
263 
264 static void
266 {
267  dpo_proto_t dproto;
268 
269  dproto = (ip_prefix_version (&lfe->key->rmt.ippref) == IP4 ?
271 
273  &lfe->key->rmt.ippref);
274 
276  {
277  dpo_id_t dpo = DPO_INVALID;
278 
279  switch (lfe->action)
280  {
281  case LISP_NO_ACTION:
282  /* TODO update timers? */
283  case LISP_FORWARD_NATIVE:
284  /* TODO check if route/next-hop for eid exists in fib and add
285  * more specific for the eid with the next-hop found */
287  /* insert tunnel that always sends map-request */
288  dpo_copy (&dpo, lisp_cp_dpo_get (dproto));
289  break;
290  case LISP_DROP:
291  /* for drop fwd entries, just add route, no need to add encap tunnel */
292  dpo_copy (&dpo, drop_dpo_get (dproto));
293  break;
294  }
296  &lfe->key->lcl.ippref, &dpo);
297  dpo_reset (&dpo);
298  }
299  else
300  {
302  &lfe->key->lcl.ippref, lfe->paths);
303  }
304 }
305 
306 static void
308 {
310  &lfe->key->lcl.ippref,
311  lfe->eid_fib_index, &lfe->key->rmt.ippref);
312 }
313 
314 static void
316 {
317  switch (gid_address_type (g))
318  {
319  case GID_ADDR_IP_PREFIX:
320  case GID_ADDR_SRC_DST:
322  d->type = FID_ADDR_IP_PREF;
323  break;
324  case GID_ADDR_MAC:
325  default:
326  mac_copy (&d->mac, &gid_address_mac (g));
327  d->type = FID_ADDR_MAC;
328  break;
329  }
330 }
331 
332 static lisp_gpe_fwd_entry_t *
336 {
337  uword *p;
338 
339  memset (key, 0, sizeof (*key));
340 
342  {
343  /*
344  * the ip version of the source is not set to ip6 when the
345  * source is all zeros. force it.
346  */
349  }
350 
351  gid_to_dp_address (&a->rmt_eid, &key->rmt);
352  gid_to_dp_address (&a->lcl_eid, &key->lcl);
353  key->vni = a->vni;
354 
355  p = hash_get_mem (lgm->lisp_gpe_fwd_entries, key);
356 
357  if (NULL != p)
358  {
359  return (pool_elt_at_index (lgm->lisp_fwd_entry_pool, p[0]));
360  }
361  return (NULL);
362 }
363 
364 static int
365 lisp_gpe_fwd_entry_path_sort (void *a1, void *a2)
366 {
367  lisp_fwd_path_t *p1 = a1, *p2 = a2;
368 
369  return (p1->priority - p2->priority);
370 }
371 
372 static void
375 {
376  lisp_fwd_path_t *path;
377  u32 index;
378 
379  vec_validate (lfe->paths, vec_len (a->locator_pairs) - 1);
380 
381  vec_foreach_index (index, a->locator_pairs)
382  {
383  path = &lfe->paths[index];
384 
385  path->priority = a->locator_pairs[index].priority;
386  path->weight = a->locator_pairs[index].weight;
387 
388  path->lisp_adj =
390  [index],
391  a->dp_table, lfe->key->vni);
392  }
394 }
395 
396 /**
397  * @brief Add/Delete LISP IP forwarding entry.
398  *
399  * creation of forwarding entries for IP LISP overlay:
400  *
401  * @param[in] lgm Reference to @ref lisp_gpe_main_t.
402  * @param[in] a Parameters for building the forwarding entry.
403  *
404  * @return 0 on success.
405  */
406 static int
409 {
412  fib_protocol_t fproto;
413 
414  lfe = find_fwd_entry (lgm, a, &key);
415 
416  if (NULL != lfe)
417  /* don't support updates */
418  return VNET_API_ERROR_INVALID_VALUE;
419 
420  pool_get (lgm->lisp_fwd_entry_pool, lfe);
421  memset (lfe, 0, sizeof (*lfe));
422  lfe->key = clib_mem_alloc (sizeof (key));
423  memcpy (lfe->key, &key, sizeof (key));
424 
426  lfe - lgm->lisp_fwd_entry_pool);
427 
428  fproto = (IP4 == ip_prefix_version (&fid_addr_ippref (&lfe->key->rmt)) ?
430 
431  lfe->type = (a->is_negative ?
435  lfe->eid_table_id = a->table_id;
437  lfe->eid_table_id);
438 
440  {
442  }
443 
444  create_fib_entries (lfe);
445 
446  return (0);
447 }
448 
449 static void
451 {
452  lisp_fwd_path_t *path;
453  fib_protocol_t fproto;
454 
455  vec_foreach (path, lfe->paths)
456  {
458  }
459 
460  delete_fib_entries (lfe);
461 
462  fproto = (IP4 == ip_prefix_version (&fid_addr_ippref (&lfe->key->rmt)) ?
464  fib_table_unlock (lfe->eid_fib_index, fproto);
465 
467  clib_mem_free (lfe->key);
468  pool_put (lgm->lisp_fwd_entry_pool, lfe);
469 }
470 
471 /**
472  * @brief Add/Delete LISP IP forwarding entry.
473  *
474  * removal of forwarding entries for IP LISP overlay:
475  *
476  * @param[in] lgm Reference to @ref lisp_gpe_main_t.
477  * @param[in] a Parameters for building the forwarding entry.
478  *
479  * @return 0 on success.
480  */
481 static int
484 {
487 
488  lfe = find_fwd_entry (lgm, a, &key);
489 
490  if (NULL == lfe)
491  /* no such entry */
492  return VNET_API_ERROR_INVALID_VALUE;
493 
494  del_ip_fwd_entry_i (lgm, lfe);
495 
496  return (0);
497 }
498 
499 static void
500 make_mac_fib_key (BVT (clib_bihash_kv) * kv, u16 bd_index, u8 src_mac[6],
501  u8 dst_mac[6])
502 {
503  kv->key[0] = (((u64) bd_index) << 48) | mac_to_u64 (dst_mac);
504  kv->key[1] = mac_to_u64 (src_mac);
505  kv->key[2] = 0;
506 }
507 
508 /**
509  * @brief Lookup L2 SD FIB entry
510  *
511  * Does a vni + dest + source lookup in the L2 LISP FIB. If the lookup fails
512  * it tries a second time with source set to 0 (i.e., a simple dest lookup).
513  *
514  * @param[in] lgm Reference to @ref lisp_gpe_main_t.
515  * @param[in] bd_index Bridge domain index.
516  * @param[in] src_mac Source mac address.
517  * @param[in] dst_mac Destination mac address.
518  *
519  * @return index of mapping matching the lookup key.
520  */
521 index_t
522 lisp_l2_fib_lookup (lisp_gpe_main_t * lgm, u16 bd_index, u8 src_mac[6],
523  u8 dst_mac[6])
524 {
525  int rv;
526  BVT (clib_bihash_kv) kv, value;
527 
528  make_mac_fib_key (&kv, bd_index, src_mac, dst_mac);
529  rv = BV (clib_bihash_search_inline_2) (&lgm->l2_fib, &kv, &value);
530 
531  /* no match, try with src 0, catch all for dst */
532  if (rv != 0)
533  {
534  kv.key[1] = 0;
535  rv = BV (clib_bihash_search_inline_2) (&lgm->l2_fib, &kv, &value);
536  if (rv == 0)
537  return value.value;
538  }
539  else
540  return value.value;
541 
543 }
544 
545 /**
546  * @brief Add/del L2 SD FIB entry
547  *
548  * Inserts value in L2 FIB keyed by vni + dest + source. If entry is
549  * overwritten the associated value is returned.
550  *
551  * @param[in] lgm Reference to @ref lisp_gpe_main_t.
552  * @param[in] bd_index Bridge domain index.
553  * @param[in] src_mac Source mac address.
554  * @param[in] dst_mac Destination mac address.
555  * @param[in] val Value to add.
556  * @param[in] is_add Add/del flag.
557  *
558  * @return ~0 or value of overwritten entry.
559  */
560 static u32
561 lisp_l2_fib_add_del_entry (u16 bd_index, u8 src_mac[6],
562  u8 dst_mac[6], const dpo_id_t * dpo, u8 is_add)
563 {
565  BVT (clib_bihash_kv) kv, value;
566  u32 old_val = ~0;
567 
568  make_mac_fib_key (&kv, bd_index, src_mac, dst_mac);
569 
570  if (BV (clib_bihash_search) (&lgm->l2_fib, &kv, &value) == 0)
571  old_val = value.value;
572 
573  if (!is_add)
574  BV (clib_bihash_add_del) (&lgm->l2_fib, &kv, 0 /* is_add */ );
575  else
576  {
577  kv.value = dpo->dpoi_index;
578  BV (clib_bihash_add_del) (&lgm->l2_fib, &kv, 1 /* is_add */ );
579  }
580  return old_val;
581 }
582 
583 #define L2_FIB_DEFAULT_HASH_NUM_BUCKETS (64 * 1024)
584 #define L2_FIB_DEFAULT_HASH_MEMORY_SIZE (32<<20)
585 
586 static void
588 {
589  index_t lbi;
590 
591  BV (clib_bihash_init) (&lgm->l2_fib, "l2 fib",
594 
595  /*
596  * the result from a 'miss' in a L2 Table
597  */
600 
602 }
603 
604 static void
606 {
607  lisp_fwd_path_t *path;
608 
610  {
611  vec_foreach (path, lfe->paths)
612  {
614  }
615  fib_path_list_child_remove (lfe->l2.path_list_index,
616  lfe->l2.child_index);
617  }
618 
619  lisp_l2_fib_add_del_entry (lfe->l2.eid_bd_index,
620  fid_addr_mac (&lfe->key->lcl),
621  fid_addr_mac (&lfe->key->rmt), NULL, 0);
622 
624  clib_mem_free (lfe->key);
625  pool_put (lgm->lisp_fwd_entry_pool, lfe);
626 }
627 
628 /**
629  * @brief Delete LISP L2 forwarding entry.
630  *
631  * Coordinates the removal of forwarding entries for L2 LISP overlay:
632  *
633  * @param[in] lgm Reference to @ref lisp_gpe_main_t.
634  * @param[in] a Parameters for building the forwarding entry.
635  *
636  * @return 0 on success.
637  */
638 static int
641 {
644 
645  lfe = find_fwd_entry (lgm, a, &key);
646 
647  if (NULL == lfe)
648  return VNET_API_ERROR_INVALID_VALUE;
649 
650  del_l2_fwd_entry_i (lgm, lfe);
651 
652  return (0);
653 }
654 
655 /**
656  * @brief Construct and insert the forwarding information used by a L2 entry
657  */
658 static void
660 {
662  dpo_id_t dpo = DPO_INVALID;
663 
665  {
666  fib_path_list_contribute_forwarding (lfe->l2.path_list_index,
668  &lfe->l2.dpo);
669  dpo_copy (&dpo, &lfe->l2.dpo);
670  }
671  else
672  {
673  dpo_copy (&dpo, &lgm->l2_lb_cp_lkup);
674  }
675 
676  /* add entry to l2 lisp fib */
677  lisp_l2_fib_add_del_entry (lfe->l2.eid_bd_index,
678  fid_addr_mac (&lfe->key->lcl),
679  fid_addr_mac (&lfe->key->rmt), &dpo, 1);
680 
681  dpo_reset (&dpo);
682 }
683 
684 /**
685  * @brief Add LISP L2 forwarding entry.
686  *
687  * Coordinates the creation of forwarding entries for L2 LISP overlay:
688  * creates lisp-gpe tunnel and injects new entry in Source/Dest L2 FIB.
689  *
690  * @param[in] lgm Reference to @ref lisp_gpe_main_t.
691  * @param[in] a Parameters for building the forwarding entry.
692  *
693  * @return 0 on success.
694  */
695 static int
698 {
700  bd_main_t *bdm = &bd_main;
702  uword *bd_indexp;
703 
704  bd_indexp = hash_get (bdm->bd_index_by_bd_id, a->bd_id);
705  if (!bd_indexp)
706  {
707  clib_warning ("bridge domain %d doesn't exist", a->bd_id);
708  return -1;
709  }
710 
711  lfe = find_fwd_entry (lgm, a, &key);
712 
713  if (NULL != lfe)
714  /* don't support updates */
715  return VNET_API_ERROR_INVALID_VALUE;
716 
717  pool_get (lgm->lisp_fwd_entry_pool, lfe);
718  memset (lfe, 0, sizeof (*lfe));
719  lfe->key = clib_mem_alloc (sizeof (key));
720  memcpy (lfe->key, &key, sizeof (key));
721 
723  lfe - lgm->lisp_fwd_entry_pool);
724 
725  lfe->type = (a->is_negative ?
728  lfe->l2.eid_bd_id = a->bd_id;
729  lfe->l2.eid_bd_index = bd_indexp[0];
731 
733  {
734  fib_route_path_t *rpaths;
735 
736  /*
737  * Make the sorted array of LISP paths with their resp. adjacency
738  */
740 
741  /*
742  * From the LISP paths, construct a FIB path list that will
743  * contribute a load-balance.
744  */
745  rpaths = lisp_gpe_mk_fib_paths (lfe->paths);
746 
747  lfe->l2.path_list_index =
749 
750  /*
751  * become a child of the path-list so we receive updates when
752  * its forwarding state changes. this includes an implicit lock.
753  */
754  lfe->l2.child_index =
755  fib_path_list_child_add (lfe->l2.path_list_index,
757  lfe - lgm->lisp_fwd_entry_pool);
758  }
759  else
760  {
761  lfe->action = a->action;
762  }
763 
765 
766  return 0;
767 }
768 
769 /**
770  * @brief conver from the embedded fib_node_t struct to the LSIP entry
771  */
772 static lisp_gpe_fwd_entry_t *
774 {
775  return ((lisp_gpe_fwd_entry_t *) (((char *) node) -
777  node)));
778 }
779 
780 /**
781  * @brief Function invoked during a backwalk of the FIB graph
782  */
786 {
788 
790 }
791 
792 /**
793  * @brief Get a fib_node_t struct from the index of a LISP fwd entry
794  */
795 static fib_node_t *
797 {
800 
801  lfe = pool_elt_at_index (lgm->lisp_fwd_entry_pool, index);
802 
803  return (&(lfe->node));
804 }
805 
806 /**
807  * @brief An indication from the graph that the last lock has gone
808  */
809 static void
811 {
812  /* We don't manage the locks of the LISP objects via the graph, since
813  * this object has no children. so this is a no-op. */
814 }
815 
816 /**
817  * @brief Virtual function table to register with FIB for the LISP type
818  */
819 const static fib_node_vft_t lisp_fwd_vft = {
822  .fnv_back_walk = lisp_gpe_fib_node_back_walk,
823 };
824 
825 /**
826  * @brief Forwarding entry create/remove dispatcher.
827  *
828  * Calls l2 or l3 forwarding entry add/del function based on input data.
829  *
830  * @param[in] a Forwarding entry parameters.
831  * @param[out] hw_if_indexp NOT USED
832  *
833  * @return 0 on success.
834  */
835 int
837  u32 * hw_if_indexp)
838 {
840  u8 type;
841 
843  {
844  clib_warning ("LISP is disabled!");
845  return VNET_API_ERROR_LISP_DISABLED;
846  }
847 
848  type = gid_address_type (&a->rmt_eid);
849  switch (type)
850  {
851  case GID_ADDR_IP_PREFIX:
852  if (a->is_add)
853  return add_ip_fwd_entry (lgm, a);
854  else
855  return del_ip_fwd_entry (lgm, a);
856  break;
857  case GID_ADDR_MAC:
858  if (a->is_add)
859  return add_l2_fwd_entry (lgm, a);
860  else
861  return del_l2_fwd_entry (lgm, a);
862  default:
863  clib_warning ("Forwarding entries for type %d not supported!", type);
864  return -1;
865  }
866 }
867 
868 /**
869  * @brief Flush all the forwrding entries
870  */
871 void
873 {
876 
877  /* *INDENT-OFF* */
879  ({
880  switch (fid_addr_type(&lfe->key->rmt))
881  {
882  case FID_ADDR_MAC:
883  del_l2_fwd_entry_i (lgm, lfe);
884  break;
885  case FID_ADDR_IP_PREF:
886  del_ip_fwd_entry_i (lgm, lfe);
887  break;
888  }
889  }));
890  /* *INDENT-ON* */
891 }
892 
893 static u8 *
894 format_lisp_fwd_path (u8 * s, va_list ap)
895 {
896  lisp_fwd_path_t *lfp = va_arg (ap, lisp_fwd_path_t *);
897 
898  s = format (s, "priority:%d weight:%d ", lfp->priority, lfp->weight);
899  s = format (s, "adj:[%U]\n",
903 
904  return (s);
905 }
906 
908 {
912 
913 
914 static u8 *
915 format_lisp_gpe_fwd_entry (u8 * s, va_list ap)
916 {
918  lisp_gpe_fwd_entry_t *lfe = va_arg (ap, lisp_gpe_fwd_entry_t *);
921 
922  s = format (s, "VNI:%d VRF:%d EID: %U -> %U [index:%d]",
923  lfe->key->vni, lfe->eid_table_id,
924  format_fid_address, &lfe->key->lcl,
925  format_fid_address, &lfe->key->rmt,
926  lfe - lgm->lisp_fwd_entry_pool);
927 
929  {
930  s = format (s, "\n Negative - action:%U",
932  }
933  else
934  {
935  lisp_fwd_path_t *path;
936 
937  s = format (s, "\n via:");
938  vec_foreach (path, lfe->paths)
939  {
940  s = format (s, "\n %U", format_lisp_fwd_path, path);
941  }
942  }
943 
945  {
946  switch (fid_addr_type (&lfe->key->rmt))
947  {
948  case FID_ADDR_MAC:
949  s = format (s, " fib-path-list:%d\n", lfe->l2.path_list_index);
950  s = format (s, " dpo:%U\n", format_dpo_id, &lfe->l2.dpo, 0);
951  break;
952  case FID_ADDR_IP_PREF:
953  break;
954  }
955  }
956 
957  return (s);
958 }
959 
960 static clib_error_t *
962  unformat_input_t * input, vlib_cli_command_t * cmd)
963 {
966  index_t index;
967  u32 vni = ~0;
968 
969  if (unformat (input, "vni %d", &vni))
970  ;
971  else if (unformat (input, "%d", &index))
972  {
973  if (!pool_is_free_index (lgm->lisp_fwd_entry_pool, index))
974  {
975  lfe = pool_elt_at_index (lgm->lisp_fwd_entry_pool, index);
976 
977  vlib_cli_output (vm, "[%d@] %U",
978  index,
981  }
982  else
983  {
984  vlib_cli_output (vm, "entry %d invalid", index);
985  }
986 
987  return (NULL);
988  }
989 
990  /* *INDENT-OFF* */
992  ({
993  if ((vni == ~0) ||
994  (lfe->key->vni == vni))
995  vlib_cli_output (vm, "%U", format_lisp_gpe_fwd_entry, lfe,
996  LISP_GPE_FWD_ENTRY_FORMAT_NONE);
997  }));
998  /* *INDENT-ON* */
999 
1000  return (NULL);
1001 }
1002 
1003 /* *INDENT-OFF* */
1005  .path = "show lisp gpe entry",
1006  .short_help = "show lisp gpe entry vni <vni> vrf <vrf> [leid <leid>] reid <reid>",
1007  .function = lisp_gpe_fwd_entry_show,
1008 };
1009 /* *INDENT-ON* */
1010 
1011 clib_error_t *
1013 {
1015  clib_error_t *error = NULL;
1016 
1018  return (error);
1019 
1020  l2_fib_init (lgm);
1021 
1023 
1024  return (error);
1025 }
1026 
1028 
1029 /*
1030  * fd.io coding-style-patch-verification: ON
1031  *
1032  * Local Variables:
1033  * eval: (c-set-style "gnu")
1034  * End:
1035  */
void dpo_unlock(dpo_id_t *dpo)
Release a reference counting lock on the DPO.
Definition: dpo.c:253
#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:980
fib_protocol_t fp_proto
protocol type
Definition: fib_types.h:158
fib_protocol_t frp_proto
The protocol of the address below.
Definition: fib_types.h:288
#define vec_foreach_index(var, v)
Iterate over vector indices.
ip46_address_t frp_addr
The next-hop address.
Definition: fib_types.h:295
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:215
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:283
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:113
void vnet_lisp_gpe_fwd_entry_flush(void)
Flush all the forwrding entries.
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:196
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
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, const fib_route_path_t *paths)
Update an entry to have a new set of paths.
Definition: fib_table.c:666
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:59
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:113
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:104
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:300
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:140
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:149
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:107
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:215
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:1033
#define hash_get(h, key)
Definition: hash.h:248
Definition: fib_entry.h:219
#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:337
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:221
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:1057
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:242
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:575
void ip_address_to_46(const ip_address_t *addr, ip46_address_t *a, fib_protocol_t *proto)
Definition: lisp_types.c:728
#define gid_address_ippref(_a)
Definition: lisp_types.h:216
#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 MPLS_LABEL_INVALID
Definition: mpls_types.h:33
#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:793
u32 frp_weight
[un]equal cost path weight
Definition: fib_types.h:309
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.
struct lisp_gpe_fwd_entry_t_::@216::@222 l2
Fields relevant to an L2 entry.
fib_node_get_t fnv_get
Definition: fib_node.h:230
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:107
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:134
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:112
Context passed between object during a back walk.
Definition: fib_node.h:160
#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:114
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
mpls_label_t frp_label
The outgoing MPLS label.
Definition: fib_types.h:317
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:949
static u64 mac_to_u64(u8 *m)
Definition: load_balance.c:826
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:202
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:98
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:164
Definition: lisp_types.h:24
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:864
A FIB graph nodes virtual function table.
Definition: fib_node.h:229
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:65
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:171
#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:25
bd_main_t bd_main
Definition: l2_bd.c:43
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:858
void fib_entry_set_source_data(fib_node_index_t fib_entry_index, fib_source_t source, const void *data)
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.