FD.io VPP  v21.01.1
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  {
49  pl_flags,
50  paths);
51  }
52 
53  /*
54  * resolve the existing extensions
55  */
57 
58  /*
59  * and new extensions
60  */
61  vec_foreach(rpath, paths)
62  {
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  {
80  pl_flags,
81  rpaths);
82  }
83 
84  /*
85  * remove the path-extension for the path
86  */
87  vec_foreach(rpath, rpaths)
88  {
90  };
91  /*
92  * resolve the remaining extensions
93  */
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  */
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  {
118  src->fes_pl,
120  rpath);
121  }
122 }
123 
124 static void
126 {
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 
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  */
190  vnet_sw_interface_t *swif;
191 
192  swif = vnet_get_sw_interface (vnet_get_main(), adj_itf);
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 
258  &ctx);
259 
260  /*
261  * active the entry is one of the paths refines the cover.
262  */
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 
285  &ctx);
286 
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 
410 const static fib_entry_src_vft_t adj_src_vft = {
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_src_init_t fesv_init
#define FIB_ENTRY_DBG(_e, _fmt, _args...)
Definition: fib_entry_src.h:28
An entry in a FIB table.
Definition: fib_entry.h:305
fib_node_bw_reason_flag_t bw_reason
Definition: fib_entry_src.h:93
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)
vl_api_wireguard_peer_flags_t flags
Definition: wireguard.api:105
fib_entry_flag_t fib_entry_get_flags_i(const fib_entry_t *fib_entry)
A representation of a path as described by a route producer.
Definition: fib_types.h:500
Route added as a result of interface configuration.
Definition: fib_source.h:56
void fib_entry_cover_untrack(fib_entry_t *cover, u32 tracked_index)
vnet_main_t * vnet_get_main(void)
Definition: misc.c:46
Virtual function table each FIB entry source will register.
u32 cover_itf
Information related to the source of a FIB entry.
Definition: fib_entry.h:197
static fib_entry_src_cover_res_t fib_entry_src_adj_cover_change(fib_entry_src_t *src, const fib_entry_t *fib_entry)
vl_api_address_t src
Definition: gre.api:54
Result from a cover update/change.
Definition: fib_entry_src.h:91
void fib_path_list_walk(fib_node_index_t path_list_index, fib_path_list_walk_fn_t func, void *ctx)
static vnet_sw_interface_t * vnet_get_sw_interface(vnet_main_t *vnm, u32 sw_if_index)
adj w/ cover tracking + refinement
Definition: fib_source.h:222
u32 fe_fib_index
The index of the FIB table this entry is in.
Definition: fib_entry.h:318
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.h:114
unsigned char u8
Definition: types.h:56
struct fib_entry_src_path_list_walk_cxt_t_ fib_entry_src_path_list_walk_cxt_t
static int fib_entry_src_adj_activate(fib_entry_src_t *src, const fib_entry_t *fib_entry)
void fib_attached_export_covered_added(fib_entry_t *cover, fib_node_index_t covered)
u32 fib_entry_cover_track(fib_entry_t *cover, fib_node_index_t covered)
description fragment has unexpected format
Definition: map.api:433
fib_node_index_t fib_entry_get_index(const fib_entry_t *fib_entry)
Definition: fib_entry.c:63
unsigned int u32
Definition: types.h:88
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
u16 install
Definition: fib_entry_src.h:92
A adj-source extension indicating the path's refinement criteria result.
Definition: fib_path_ext.h:36
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)
static void fib_entry_src_adj_remove(fib_entry_src_t *src)
void fib_path_ext_list_flush(fib_path_ext_list_t *list)
Definition: fib_path_ext.c:448
static fib_entry_src_cover_res_t fib_entry_src_adj_cover_update(fib_entry_src_t *src, const fib_entry_t *fib_entry)
fib_node_index_t fib_path_list_create(fib_path_list_flags_t flags, const fib_route_path_t *rpaths)
static void fib_entry_src_adj_installed(fib_entry_src_t *src, const fib_entry_t *fib_entry)
long ctx[MAX_CONNS]
Definition: main.c:144
void fib_entry_src_adj_register(void)
vnet_sw_interface_flags_t flags
Definition: interface.h:739
union fib_entry_src_t_::@301 u
Source specific info.
fib_entry_src_t * src
u32 fib_entry_get_resolving_interface(fib_node_index_t entry_index)
Definition: fib_entry.c:1458
static void fib_entry_src_adj_deactivate(fib_entry_src_t *src, const fib_entry_t *fib_entry)
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)
static void fib_entry_src_adj_init(fib_entry_src_t *src)
Source initialisation Function.
void fib_attached_export_covered_removed(fib_entry_t *cover, fib_node_index_t covered)
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
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
u32 fib_node_index_t
A typedef of a node index.
Definition: fib_types.h:29
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)
fib_entry_t * fib_entry_get(fib_node_index_t index)
Definition: fib_entry.c:51
static u8 * fib_entry_src_adj_format(fib_entry_src_t *src, u8 *s)
#define ASSERT(truth)
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)
fib_node_index_t fes_pl
The path-list created by the source.
Definition: fib_entry.h:206
paths
Definition: map.api:460
fib_path_ext_adj_flags_t fpe_adj_flags
For an ADJ type extension.
Definition: fib_path_ext.h:114
fib_entry_flag_t fib_entry_get_flags_for_source(fib_node_index_t fib_entry_index, fib_source_t source)
fib_path_ext_adj_flags_t flags
enum fib_path_list_walk_rc_t_ fib_path_list_walk_rc_t
return code to control pat-hlist walk
u32 fib_path_get_resolving_interface(fib_node_index_t path_index)
Definition: fib_path.c:2149
#define FIB_NODE_INDEX_INVALID
Definition: fib_types.h:30
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
enum fib_path_ext_adj_flags_t_ fib_path_ext_adj_flags_t
static int fib_entry_src_adj_reactivate(fib_entry_src_t *src, const fib_entry_t *fib_entry)
#define vec_foreach(var, vec)
Vector iterator.
A path extension is a per-entry addition to the forwarding information when packets are sent for that...
Definition: fib_path_ext.h:98
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)
fib_path_ext_list_t fes_path_exts
A vector of path extensions.
Definition: fib_entry.h:201
struct fib_entry_src_t_::@301::@304 adj
enum fib_path_list_flags_t_ fib_path_list_flags_t
void fib_entry_src_behaviour_register(fib_source_behaviour_t bh, const fib_entry_src_vft_t *vft)
Definition: fib_entry_src.c:61
const fib_prefix_t fe_prefix
The prefix of the route.
Definition: fib_entry.h:314
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_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