FD.io VPP  v21.06-3-gbb25fbf28
Vector Packet Processing
fib_entry_src_adj.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 
16 #include "fib_entry.h"
17 #include "fib_entry_src.h"
18 #include "fib_path_list.h"
19 #include "fib_table.h"
20 #include "fib_entry_cover.h"
21 #include "fib_attached_export.h"
22 #include "fib_path_ext.h"
23 
24 /**
25  * Source initialisation Function
26  */
27 static void
29 {
30  src->u.adj.fesa_cover = FIB_NODE_INDEX_INVALID;
31  src->u.adj.fesa_sibling = FIB_NODE_INDEX_INVALID;
32 }
33 
34 static void
36  const fib_entry_t *entry,
37  fib_path_list_flags_t pl_flags,
38  const fib_route_path_t *paths)
39 {
40  const fib_route_path_t *rpath;
41 
42  if (FIB_NODE_INDEX_INVALID == src->fes_pl)
43  {
44  src->fes_pl = fib_path_list_create(pl_flags, paths);
45  }
46  else
47  {
48  src->fes_pl = fib_path_list_copy_and_path_add(src->fes_pl,
49  pl_flags,
50  paths);
51  }
52 
53  /*
54  * resolve the existing extensions
55  */
56  fib_path_ext_list_resolve(&src->fes_path_exts, src->fes_pl);
57 
58  /*
59  * and new extensions
60  */
61  vec_foreach(rpath, paths)
62  {
63  fib_path_ext_list_insert(&src->fes_path_exts,
64  src->fes_pl,
66  rpath);
67  }
68 }
69 
70 static void
72  fib_path_list_flags_t pl_flags,
73  const fib_route_path_t *rpaths)
74 {
75  const fib_route_path_t *rpath;
76 
77  if (FIB_NODE_INDEX_INVALID != src->fes_pl)
78  {
79  src->fes_pl = fib_path_list_copy_and_path_remove(src->fes_pl,
80  pl_flags,
81  rpaths);
82  }
83 
84  /*
85  * remove the path-extension for the path
86  */
87  vec_foreach(rpath, rpaths)
88  {
89  fib_path_ext_list_remove(&src->fes_path_exts, FIB_PATH_EXT_ADJ, rpath);
90  };
91  /*
92  * resolve the remaining extensions
93  */
94  fib_path_ext_list_resolve(&src->fes_path_exts, src->fes_pl);
95 }
96 
97 static void
99  const fib_entry_t *entry,
100  fib_path_list_flags_t pl_flags,
101  const fib_route_path_t *paths)
102 {
103  const fib_route_path_t *rpath;
104 
105  /*
106  * flush all the old extensions before we create a brand new path-list
107  */
108  fib_path_ext_list_flush(&src->fes_path_exts);
109 
110  src->fes_pl = fib_path_list_create(pl_flags, paths);
111 
112  /*
113  * and new extensions
114  */
115  vec_foreach(rpath, paths)
116  {
117  fib_path_ext_list_push_back(&src->fes_path_exts,
118  src->fes_pl,
120  rpath);
121  }
122 }
123 
124 static void
126 {
127  src->fes_pl = FIB_NODE_INDEX_INVALID;
128 
129  if (FIB_NODE_INDEX_INVALID != src->u.adj.fesa_cover)
130  {
131  fib_entry_cover_untrack(fib_entry_get(src->u.adj.fesa_cover),
132  src->u.adj.fesa_sibling);
133  }
134 }
135 
136 /*
137  * Add a path-extension indicating whether this path is resolved,
138  * because it passed the refinement check
139  */
140 static void
142  fib_node_index_t path_index,
144 {
145  fib_path_ext_t *path_ext;
146 
147  path_ext = fib_path_ext_list_find_by_path_index(&src->fes_path_exts,
148  path_index);
149 
150  if (NULL != path_ext)
151  {
152  path_ext->fpe_adj_flags = flags;
153  }
154  else
155  {
156  ASSERT(!"no path extension");
157  }
158 }
159 
161 {
166 
169  fib_node_index_t path_index,
170  void *arg)
171 {
173  u32 adj_itf;
174 
175  ctx = arg;
176  adj_itf = fib_path_get_resolving_interface(path_index);
177 
178  if (ctx->cover_itf == adj_itf)
179  {
180  fib_enty_src_adj_update_path_ext(ctx->src, path_index,
183  }
184  else
185  {
186  /*
187  * if the interface the adj is on is unnumbered to the
188  * cover's, then allow that too.
189  */
191 
193 
195  ctx->cover_itf == swif->unnumbered_sw_if_index)
196  {
197  fib_enty_src_adj_update_path_ext(ctx->src, path_index,
200  }
201  else
202  {
203  fib_enty_src_adj_update_path_ext(ctx->src, path_index,
205  }
206  }
208 }
209 
210 static int
212  const fib_entry_t *fib_entry)
213 {
214  fib_entry_t *cover;
215 
216  /*
217  * find the covering prefix. become a dependent thereof.
218  * there should always be a cover, though it may be the default route.
219  */
220  src->u.adj.fesa_cover = fib_table_get_less_specific(fib_entry->fe_fib_index,
221  &fib_entry->fe_prefix);
222 
223  ASSERT(FIB_NODE_INDEX_INVALID != src->u.adj.fesa_cover);
224  ASSERT(fib_entry_get_index(fib_entry) != src->u.adj.fesa_cover);
225 
226  cover = fib_entry_get(src->u.adj.fesa_cover);
227 
228  ASSERT(cover != fib_entry);
229 
230  src->u.adj.fesa_sibling =
231  fib_entry_cover_track(cover,
232  fib_entry_get_index(fib_entry));
233 
234  /*
235  * if the cover is attached on the same interface as this adj source then
236  * install the FIB entry via the adj. otherwise install a drop.
237  * This prevents ARP/ND entries that on interface X that do not belong
238  * on X's subnet from being added to the FIB. To do so would allow
239  * nefarious gratuitous ARP requests from attracting traffic to the sender.
240  *
241  * and yes, I really do mean attached and not connected.
242  * this abomination;
243  * ip route add 10.0.0.0/24 Eth0
244  * is attached. and we want adj-fibs to install on Eth0.
245  */
249  {
251  .cover_itf = fib_entry_get_resolving_interface(src->u.adj.fesa_cover),
253  .src = src,
254  };
255 
256  fib_path_list_walk(src->fes_pl,
258  &ctx);
259 
260  /*
261  * active the entry is one of the paths refines the cover.
262  */
263  return (FIB_PATH_EXT_ADJ_FLAG_REFINES_COVER & ctx.flags);
264  }
265  return (0);
266 }
267 
268 /*
269  * Source re-activate.
270  * Called when the source path lit has changed and the source is still
271  * the best source
272  */
273 static int
275  const fib_entry_t *fib_entry)
276 {
278  .cover_itf = fib_entry_get_resolving_interface(src->u.adj.fesa_cover),
280  .src = src,
281  };
282 
283  fib_path_list_walk(src->fes_pl,
285  &ctx);
286 
287  return (FIB_PATH_EXT_ADJ_FLAG_REFINES_COVER & ctx.flags);
288 }
289 
290 /*
291  * Source Deactivate.
292  * Called when the source is no longer best source on the entry
293  */
294 static void
296  const fib_entry_t *fib_entry)
297 {
298  fib_entry_t *cover;
299 
300  /*
301  * remove the dependency on the covering entry
302  */
303  if (FIB_NODE_INDEX_INVALID == src->u.adj.fesa_cover)
304  {
305  /*
306  * this is the case if the entry is in the non-forwarding trie
307  */
308  return;
309  }
310 
311  cover = fib_entry_get(src->u.adj.fesa_cover);
312  fib_entry_cover_untrack(cover, src->u.adj.fesa_sibling);
313 
314  /*
315  * tell the cover this entry no longer needs exporting
316  */
318 
319  src->u.adj.fesa_cover = FIB_NODE_INDEX_INVALID;
320  src->u.adj.fesa_sibling = FIB_NODE_INDEX_INVALID;
321 }
322 
323 static u8*
325  u8* s)
326 {
327  return (format(s, " cover:%d", src->u.adj.fesa_cover));
328 }
329 
330 static void
332  const fib_entry_t *fib_entry)
333 {
334  /*
335  * The adj source now rules! poke our cover to get exported
336  */
337  fib_entry_t *cover;
338 
339  ASSERT(FIB_NODE_INDEX_INVALID != src->u.adj.fesa_cover);
340  cover = fib_entry_get(src->u.adj.fesa_cover);
341 
343  fib_entry_get_index(fib_entry));
344 }
345 
348  const fib_entry_t *fib_entry)
349 {
351  .install = 0,
352  .bw_reason = FIB_NODE_BW_REASON_FLAG_NONE,
353  };
354 
355  /*
356  * not interested in a change to the cover if the cover
357  * is not being tracked, i.e. the source is not active
358  */
359  if (FIB_NODE_INDEX_INVALID == src->u.adj.fesa_cover)
360  return res;
361 
362  fib_entry_src_adj_deactivate(src, fib_entry);
363 
364  res.install = fib_entry_src_adj_activate(src, fib_entry);
365 
366  if (res.install) {
367  /*
368  * ADJ fib can install
369  */
371  }
372 
373  FIB_ENTRY_DBG(fib_entry, "adj-src-cover-changed");
374  return (res);
375 }
376 
377 /*
378  * fib_entry_src_adj_cover_update
379  */
382  const fib_entry_t *fib_entry)
383 {
384  /*
385  * the cover has updated, i.e. its forwarding or flags
386  * have changed. don't deactivate/activate here, since this
387  * prefix is updated during the covers walk.
388  */
390  .install = 0,
391  .bw_reason = FIB_NODE_BW_REASON_FLAG_NONE,
392  };
393  fib_entry_t *cover;
394 
395  /*
396  * If there is no cover, then the source is not active and we can ignore
397  * this update
398  */
399  if (FIB_NODE_INDEX_INVALID != src->u.adj.fesa_cover)
400  {
401  cover = fib_entry_get(src->u.adj.fesa_cover);
402 
404 
405  FIB_ENTRY_DBG(fib_entry, "adj-src-cover-updated");
406  }
407  return (res);
408 }
409 
412  .fesv_path_swap = fib_entry_src_adj_path_swap,
413  .fesv_path_add = fib_entry_src_adj_path_add,
414  .fesv_path_remove = fib_entry_src_adj_path_remove,
415  .fesv_remove = fib_entry_src_adj_remove,
416  .fesv_activate = fib_entry_src_adj_activate,
417  .fesv_deactivate = fib_entry_src_adj_deactivate,
418  .fesv_reactivate = fib_entry_src_adj_reactivate,
419  .fesv_format = fib_entry_src_adj_format,
420  .fesv_installed = fib_entry_src_adj_installed,
421  .fesv_cover_change = fib_entry_src_adj_cover_change,
422  .fesv_cover_update = fib_entry_src_adj_cover_update,
423 };
424 
425 void
427 {
429 }
fib_entry_get_flags_i
fib_entry_flag_t fib_entry_get_flags_i(const fib_entry_t *fib_entry)
Definition: fib_entry_src.c:1905
fib_entry.h
fib_entry_src_cover_res_t_
Result from a cover update/change.
Definition: fib_entry_src.h:91
fib_enty_src_adj_update_path_ext
static void fib_enty_src_adj_update_path_ext(fib_entry_src_t *src, fib_node_index_t path_index, fib_path_ext_adj_flags_t flags)
Definition: fib_entry_src_adj.c:141
fib_entry_src_path_list_walk_cxt_t
struct fib_entry_src_path_list_walk_cxt_t_ fib_entry_src_path_list_walk_cxt_t
fib_entry_src_adj_cover_change
static fib_entry_src_cover_res_t fib_entry_src_adj_cover_change(fib_entry_src_t *src, const fib_entry_t *fib_entry)
Definition: fib_entry_src_adj.c:347
vnet_sw_interface_t
Definition: interface.h:868
FIB_NODE_BW_REASON_FLAG_NONE
@ FIB_NODE_BW_REASON_FLAG_NONE
Definition: fib_node.h:155
fib_entry_t_
An entry in a FIB table.
Definition: fib_entry.h:305
fib_entry_src_path_list_walk_cxt_t_::flags
fib_path_ext_adj_flags_t flags
Definition: fib_entry_src_adj.c:164
fib_entry_src_adj_installed
static void fib_entry_src_adj_installed(fib_entry_src_t *src, const fib_entry_t *fib_entry)
Definition: fib_entry_src_adj.c:331
fib_entry_src_path_list_walk_cxt_t_::cover_itf
u32 cover_itf
Definition: fib_entry_src_adj.c:163
FIB_ENTRY_FLAG_ATTACHED
@ FIB_ENTRY_FLAG_ATTACHED
Definition: fib_entry.h:114
fib_entry_src_t_
Information related to the source of a FIB entry.
Definition: fib_entry.h:197
fib_entry_src_adj_remove
static void fib_entry_src_adj_remove(fib_entry_src_t *src)
Definition: fib_entry_src_adj.c:125
paths
paths
Definition: map.api:460
FIB_NODE_INDEX_INVALID
#define FIB_NODE_INDEX_INVALID
Definition: fib_types.h:30
fib_table.h
fib_path_list_walk_rc_t
enum fib_path_list_walk_rc_t_ fib_path_list_walk_rc_t
return code to control pat-hlist walk
vnet_get_sw_interface
static vnet_sw_interface_t * vnet_get_sw_interface(vnet_main_t *vnm, u32 sw_if_index)
Definition: interface_funcs.h:58
fib_path_ext_list_flush
void fib_path_ext_list_flush(fib_path_ext_list_t *list)
Definition: fib_path_ext.c:448
fib_attached_export_covered_removed
void fib_attached_export_covered_removed(fib_entry_t *cover, fib_node_index_t covered)
Definition: fib_attached_export.c:430
fib_entry_src_adj_cover_update
static fib_entry_src_cover_res_t fib_entry_src_adj_cover_update(fib_entry_src_t *src, const fib_entry_t *fib_entry)
Definition: fib_entry_src_adj.c:381
fib_path_list_flags_t
enum fib_path_list_flags_t_ fib_path_list_flags_t
FIB_NODE_BW_REASON_FLAG_EVALUATE
@ FIB_NODE_BW_REASON_FLAG_EVALUATE
Definition: fib_node.h:157
fib_entry_src.h
fib_entry_src_vft_t_
Virtual function table each FIB entry source will register.
Definition: fib_entry_src.h:195
fib_entry_t_::fe_fib_index
u32 fe_fib_index
The index of the FIB table this entry is in.
Definition: fib_entry.h:318
fib_entry_src_adj_deactivate
static void fib_entry_src_adj_deactivate(fib_entry_src_t *src, const fib_entry_t *fib_entry)
Definition: fib_entry_src_adj.c:295
fib_entry_src_adj_activate
static int fib_entry_src_adj_activate(fib_entry_src_t *src, const fib_entry_t *fib_entry)
Definition: fib_entry_src_adj.c:211
FIB_SOURCE_INTERFACE
@ FIB_SOURCE_INTERFACE
Route added as a result of interface configuration.
Definition: fib_source.h:59
fib_path_ext_list_remove
void fib_path_ext_list_remove(fib_path_ext_list_t *list, fib_path_ext_type_t ext_type, const fib_route_path_t *rpath)
Definition: fib_path_ext.c:428
vnet_get_main
vnet_main_t * vnet_get_main(void)
Definition: pnat_test_stubs.h:56
fib_entry_cover.h
fib_path_ext_adj_flags_t
enum fib_path_ext_adj_flags_t_ fib_path_ext_adj_flags_t
FIB_SOURCE_BH_ADJ
@ FIB_SOURCE_BH_ADJ
adj w/ cover tracking + refinement
Definition: fib_source.h:233
fib_node_index_t
u32 fib_node_index_t
A typedef of a node index.
Definition: fib_types.h:29
fib_entry_get_index
fib_node_index_t fib_entry_get_index(const fib_entry_t *fib_entry)
Definition: fib_entry.c:63
fib_entry_src_adj_path_add
static void fib_entry_src_adj_path_add(fib_entry_src_t *src, const fib_entry_t *entry, fib_path_list_flags_t pl_flags, const fib_route_path_t *paths)
Definition: fib_entry_src_adj.c:35
fib_entry_src_path_list_walk_cxt_t_::src
fib_entry_src_t * src
Definition: fib_entry_src_adj.c:162
fib_entry_get_flags_for_source
fib_entry_flag_t fib_entry_get_flags_for_source(fib_node_index_t fib_entry_index, fib_source_t source)
Definition: fib_entry_src.c:1877
VNET_SW_INTERFACE_FLAG_UNNUMBERED
@ VNET_SW_INTERFACE_FLAG_UNNUMBERED
Definition: interface.h:850
src
vl_api_address_t src
Definition: gre.api:54
fib_path_ext_list_find_by_path_index
fib_path_ext_t * fib_path_ext_list_find_by_path_index(const fib_path_ext_list_t *list, fib_node_index_t path_index)
Definition: fib_path_ext.c:326
FIB_ENTRY_DBG
#define FIB_ENTRY_DBG(_e, _fmt, _args...)
Definition: fib_entry_src.h:28
fib_path_get_resolving_interface
u32 fib_path_get_resolving_interface(fib_node_index_t path_index)
Definition: fib_path.c:2158
fib_entry_get_resolving_interface
u32 fib_entry_get_resolving_interface(fib_node_index_t entry_index)
Definition: fib_entry.c:1474
fib_entry_src_path_list_walk_cxt_t_
Definition: fib_entry_src_adj.c:160
fib_attached_export_covered_added
void fib_attached_export_covered_added(fib_entry_t *cover, fib_node_index_t covered)
Definition: fib_attached_export.c:398
FIB_PATH_LIST_WALK_CONTINUE
@ FIB_PATH_LIST_WALK_CONTINUE
Definition: fib_types.h:633
fib_path_ext_list_resolve
void fib_path_ext_list_resolve(fib_path_ext_list_t *list, fib_node_index_t path_list_index)
Definition: fib_path_ext.c:416
fib_entry_src_adj_path_remove
static void fib_entry_src_adj_path_remove(fib_entry_src_t *src, fib_path_list_flags_t pl_flags, const fib_route_path_t *rpaths)
Definition: fib_entry_src_adj.c:71
fib_entry_src_adj_path_list_walk
static fib_path_list_walk_rc_t fib_entry_src_adj_path_list_walk(fib_node_index_t pl_index, fib_node_index_t path_index, void *arg)
Definition: fib_entry_src_adj.c:168
fib_entry_src_adj_register
void fib_entry_src_adj_register(void)
Definition: fib_entry_src_adj.c:426
fib_path_list.h
fib_path_list_copy_and_path_remove
fib_node_index_t fib_path_list_copy_and_path_remove(fib_node_index_t orig_path_list_index, fib_path_list_flags_t flags, const fib_route_path_t *rpaths)
Definition: fib_path_list.c:1086
fib_entry_get
fib_entry_t * fib_entry_get(fib_node_index_t index)
Definition: fib_entry.c:51
format
description fragment has unexpected format
Definition: map.api:433
ASSERT
#define ASSERT(truth)
Definition: error_bootstrap.h:69
fib_path_list_walk
void fib_path_list_walk(fib_node_index_t path_list_index, fib_path_list_walk_fn_t func, void *ctx)
Definition: fib_path_list.c:1382
u32
unsigned int u32
Definition: types.h:88
fib_route_path_t_
A representation of a path as described by a route producer.
Definition: fib_types.h:500
ctx
long ctx[MAX_CONNS]
Definition: main.c:144
vec_foreach
#define vec_foreach(var, vec)
Vector iterator.
Definition: vec_bootstrap.h:213
adj_src_vft
const static fib_entry_src_vft_t adj_src_vft
Definition: fib_entry_src_adj.c:410
fib_entry_src_adj_format
static u8 * fib_entry_src_adj_format(fib_entry_src_t *src, u8 *s)
Definition: fib_entry_src_adj.c:324
fib_entry_cover_untrack
void fib_entry_cover_untrack(fib_entry_t *cover, u32 tracked_index)
Definition: fib_entry_cover.c:45
fib_entry_src_cover_res_t_::bw_reason
fib_node_bw_reason_flag_t bw_reason
Definition: fib_entry_src.h:93
fib_entry_cover_track
u32 fib_entry_cover_track(fib_entry_t *cover, fib_node_index_t covered)
Definition: fib_entry_cover.c:22
fib_entry_src_adj_init
static void fib_entry_src_adj_init(fib_entry_src_t *src)
Source initialisation Function.
Definition: fib_entry_src_adj.c:28
fib_entry_src_vft_t_::fesv_init
fib_entry_src_init_t fesv_init
Definition: fib_entry_src.h:196
fib_entry_t_::fe_prefix
const fib_prefix_t fe_prefix
The prefix of the route.
Definition: fib_entry.h:314
u8
unsigned char u8
Definition: types.h:56
fib_entry_src_adj_path_swap
static void fib_entry_src_adj_path_swap(fib_entry_src_t *src, const fib_entry_t *entry, fib_path_list_flags_t pl_flags, const fib_route_path_t *paths)
Definition: fib_entry_src_adj.c:98
fib_path_ext_list_push_back
fib_path_ext_t * fib_path_ext_list_push_back(fib_path_ext_list_t *list, fib_node_index_t path_list_index, fib_path_ext_type_t ext_type, const fib_route_path_t *rpath)
Definition: fib_path_ext.c:346
FIB_PATH_EXT_ADJ_FLAG_REFINES_COVER
@ FIB_PATH_EXT_ADJ_FLAG_REFINES_COVER
Definition: fib_path_ext.h:50
fib_path_ext_t_::fpe_adj_flags
fib_path_ext_adj_flags_t fpe_adj_flags
For an ADJ type extension.
Definition: fib_path_ext.h:114
fib_path_ext_t_
A path extension is a per-entry addition to the forwarding information when packets are sent for that...
Definition: fib_path_ext.h:98
fib_path_ext_list_insert
fib_path_ext_t * fib_path_ext_list_insert(fib_path_ext_list_t *list, fib_node_index_t path_list_index, fib_path_ext_type_t ext_type, const fib_route_path_t *rpath)
Definition: fib_path_ext.c:372
fib_table_get_less_specific
fib_node_index_t fib_table_get_less_specific(u32 fib_index, const fib_prefix_t *prefix)
Get the less specific (covering) prefix.
Definition: fib_table.c:133
fib_entry_src_behaviour_register
void fib_entry_src_behaviour_register(fib_source_behaviour_t bh, const fib_entry_src_vft_t *vft)
Definition: fib_entry_src.c:61
fib_path_ext.h
fib_entry_src_cover_res_t_::install
u16 install
Definition: fib_entry_src.h:92
FIB_PATH_EXT_ADJ
@ FIB_PATH_EXT_ADJ
A adj-source extension indicating the path's refinement criteria result.
Definition: fib_path_ext.h:36
FIB_PATH_EXT_ADJ_FLAG_NONE
@ FIB_PATH_EXT_ADJ_FLAG_NONE
Definition: fib_path_ext.h:49
fib_entry_src_adj_reactivate
static int fib_entry_src_adj_reactivate(fib_entry_src_t *src, const fib_entry_t *fib_entry)
Definition: fib_entry_src_adj.c:274
fib_path_list_copy_and_path_add
fib_node_index_t fib_path_list_copy_and_path_add(fib_node_index_t orig_path_list_index, fib_path_list_flags_t flags, const fib_route_path_t *rpaths)
Definition: fib_path_list.c:907
fib_path_list_create
fib_node_index_t fib_path_list_create(fib_path_list_flags_t flags, const fib_route_path_t *rpaths)
Definition: fib_path_list.c:682
fib_attached_export.h
swif
u32 swif
Definition: interface_output.c:1078
flags
vl_api_wireguard_peer_flags_t flags
Definition: wireguard.api:105