FD.io VPP  v20.09-64-g4f7b92f0a
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 
130 /*
131  * Add a path-extension indicating whether this path is resolved,
132  * because it passed the refinement check
133  */
134 static void
136  fib_node_index_t path_index,
138 {
139  fib_path_ext_t *path_ext;
140 
142  path_index);
143 
144  if (NULL != path_ext)
145  {
146  path_ext->fpe_adj_flags = flags;
147  }
148  else
149  {
150  ASSERT(!"no path extension");
151  }
152 }
153 
155 {
160 
163  fib_node_index_t path_index,
164  void *arg)
165 {
167  u32 adj_itf;
168 
169  ctx = arg;
170  adj_itf = fib_path_get_resolving_interface(path_index);
171 
172  if (ctx->cover_itf == adj_itf)
173  {
174  fib_enty_src_adj_update_path_ext(ctx->src, path_index,
177  }
178  else
179  {
180  /*
181  * if the interface the adj is on is unnumbered to the
182  * cover's, then allow that too.
183  */
184  vnet_sw_interface_t *swif;
185 
186  swif = vnet_get_sw_interface (vnet_get_main(), adj_itf);
187 
189  ctx->cover_itf == swif->unnumbered_sw_if_index)
190  {
191  fib_enty_src_adj_update_path_ext(ctx->src, path_index,
194  }
195  else
196  {
197  fib_enty_src_adj_update_path_ext(ctx->src, path_index,
199  }
200  }
202 }
203 
204 static int
206  const fib_entry_t *fib_entry)
207 {
208  fib_entry_t *cover;
209 
210  /*
211  * find the covering prefix. become a dependent thereof.
212  * there should always be a cover, though it may be the default route.
213  */
214  src->u.adj.fesa_cover = fib_table_get_less_specific(fib_entry->fe_fib_index,
215  &fib_entry->fe_prefix);
216 
217  ASSERT(FIB_NODE_INDEX_INVALID != src->u.adj.fesa_cover);
218  ASSERT(fib_entry_get_index(fib_entry) != src->u.adj.fesa_cover);
219 
220  cover = fib_entry_get(src->u.adj.fesa_cover);
221 
222  ASSERT(cover != fib_entry);
223 
224  src->u.adj.fesa_sibling =
225  fib_entry_cover_track(cover,
226  fib_entry_get_index(fib_entry));
227 
228  /*
229  * if the cover is attached on the same interface as this adj source then
230  * install the FIB entry via the adj. otherwise install a drop.
231  * This prevents ARP/ND entries that on interface X that do not belong
232  * on X's subnet from being added to the FIB. To do so would allow
233  * nefarious gratuitous ARP requests from attracting traffic to the sender.
234  *
235  * and yes, I really do mean attached and not connected.
236  * this abomination;
237  * ip route add 10.0.0.0/24 Eth0
238  * is attached. and we want adj-fibs to install on Eth0.
239  */
243  {
245  .cover_itf = fib_entry_get_resolving_interface(src->u.adj.fesa_cover),
247  .src = src,
248  };
249 
252  &ctx);
253 
254  /*
255  * active the entry is one of the paths refines the cover.
256  */
258  }
259  return (0);
260 }
261 
262 /*
263  * Source re-activate.
264  * Called when the source path lit has changed and the source is still
265  * the best source
266  */
267 static int
269  const fib_entry_t *fib_entry)
270 {
272  .cover_itf = fib_entry_get_resolving_interface(src->u.adj.fesa_cover),
274  .src = src,
275  };
276 
279  &ctx);
280 
282 }
283 
284 /*
285  * Source Deactivate.
286  * Called when the source is no longer best source on the entry
287  */
288 static void
290  const fib_entry_t *fib_entry)
291 {
292  fib_entry_t *cover;
293 
294  /*
295  * remove the dependency on the covering entry
296  */
297  if (FIB_NODE_INDEX_INVALID == src->u.adj.fesa_cover)
298  {
299  /*
300  * this is the case if the entry is in the non-forwarding trie
301  */
302  return;
303  }
304 
305  cover = fib_entry_get(src->u.adj.fesa_cover);
306  fib_entry_cover_untrack(cover, src->u.adj.fesa_sibling);
307 
308  /*
309  * tell the cover this entry no longer needs exporting
310  */
312 
313  src->u.adj.fesa_cover = FIB_NODE_INDEX_INVALID;
314 }
315 
316 static u8*
318  u8* s)
319 {
320  return (format(s, " cover:%d", src->u.adj.fesa_cover));
321 }
322 
323 static void
325  const fib_entry_t *fib_entry)
326 {
327  /*
328  * The adj source now rules! poke our cover to get exported
329  */
330  fib_entry_t *cover;
331 
332  ASSERT(FIB_NODE_INDEX_INVALID != src->u.adj.fesa_cover);
333  cover = fib_entry_get(src->u.adj.fesa_cover);
334 
336  fib_entry_get_index(fib_entry));
337 }
338 
341  const fib_entry_t *fib_entry)
342 {
344  .install = !0,
345  .bw_reason = FIB_NODE_BW_REASON_FLAG_NONE,
346  };
347 
348  fib_entry_src_adj_deactivate(src, fib_entry);
349 
350  res.install = fib_entry_src_adj_activate(src, fib_entry);
351 
352  if (res.install) {
353  /*
354  * ADJ fib can install
355  */
357  }
358 
359  FIB_ENTRY_DBG(fib_entry, "adj-src-cover-changed");
360  return (res);
361 }
362 
363 /*
364  * fib_entry_src_adj_cover_update
365  */
368  const fib_entry_t *fib_entry)
369 {
370  /*
371  * the cover has updated, i.e. its forwarding or flags
372  * have changed. don't deactivate/activate here, since this
373  * prefix is updated during the covers walk.
374  */
376  .install = 0,
377  .bw_reason = FIB_NODE_BW_REASON_FLAG_NONE,
378  };
379  fib_entry_t *cover;
380 
381  /*
382  * If there is no cover, then the source is not active and we can ignore
383  * this update
384  */
385  if (FIB_NODE_INDEX_INVALID != src->u.adj.fesa_cover)
386  {
387  cover = fib_entry_get(src->u.adj.fesa_cover);
388 
390 
391  FIB_ENTRY_DBG(fib_entry, "adj-src-cover-updated");
392  }
393  return (res);
394 }
395 
396 const static fib_entry_src_vft_t adj_src_vft = {
398  .fesv_path_swap = fib_entry_src_adj_path_swap,
399  .fesv_path_add = fib_entry_src_adj_path_add,
400  .fesv_path_remove = fib_entry_src_adj_path_remove,
401  .fesv_remove = fib_entry_src_adj_remove,
402  .fesv_activate = fib_entry_src_adj_activate,
403  .fesv_deactivate = fib_entry_src_adj_deactivate,
404  .fesv_reactivate = fib_entry_src_adj_reactivate,
405  .fesv_format = fib_entry_src_adj_format,
406  .fesv_installed = fib_entry_src_adj_installed,
407  .fesv_cover_change = fib_entry_src_adj_cover_change,
408  .fesv_cover_update = fib_entry_src_adj_cover_update,
409 };
410 
411 void
413 {
415 }
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:103
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:490
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
u8 * format(u8 *s, const char *fmt,...)
Definition: format.c:424
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)
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)
struct fib_entry_src_t_::@275::@278 adj
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:738
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:30
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)
vl_api_fib_path_t paths[n_paths]
Definition: ip.api:146
#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
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:2162
#define FIB_NODE_INDEX_INVALID
Definition: fib_types.h:31
union fib_entry_src_t_::@275 u
Source specific info.
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
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