FD.io VPP  v19.04.4-rc0-5-ge88582fac
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  */
241  {
243  .cover_itf = fib_entry_get_resolving_interface(src->u.adj.fesa_cover),
245  .src = src,
246  };
247 
250  &ctx);
251 
252  /*
253  * active the entry is one of the paths refines the cover.
254  */
256  }
257  return (0);
258 }
259 
260 /*
261  * Source re-activate.
262  * Called when the source path lit has changed and the source is still
263  * the best source
264  */
265 static int
267  const fib_entry_t *fib_entry)
268 {
270  .cover_itf = fib_entry_get_resolving_interface(src->u.adj.fesa_cover),
272  .src = src,
273  };
274 
277  &ctx);
278 
280 }
281 
282 /*
283  * Source Deactivate.
284  * Called when the source is no longer best source on the entry
285  */
286 static void
288  const fib_entry_t *fib_entry)
289 {
290  fib_entry_t *cover;
291 
292  /*
293  * remove the dependency on the covering entry
294  */
295  if (FIB_NODE_INDEX_INVALID == src->u.adj.fesa_cover)
296  {
297  /*
298  * this is the case if the entry is in the non-forwarding trie
299  */
300  return;
301  }
302 
303  cover = fib_entry_get(src->u.adj.fesa_cover);
304  fib_entry_cover_untrack(cover, src->u.adj.fesa_sibling);
305 
306  /*
307  * tell the cover this entry no longer needs exporting
308  */
310 
311  src->u.adj.fesa_cover = FIB_NODE_INDEX_INVALID;
312 }
313 
314 static u8*
316  u8* s)
317 {
318  return (format(s, " cover:%d", src->u.adj.fesa_cover));
319 }
320 
321 static void
323  const fib_entry_t *fib_entry)
324 {
325  /*
326  * The adj source now rules! poke our cover to get exported
327  */
328  fib_entry_t *cover;
329 
330  ASSERT(FIB_NODE_INDEX_INVALID != src->u.adj.fesa_cover);
331  cover = fib_entry_get(src->u.adj.fesa_cover);
332 
334  fib_entry_get_index(fib_entry));
335 }
336 
339  const fib_entry_t *fib_entry)
340 {
342  .install = !0,
343  .bw_reason = FIB_NODE_BW_REASON_FLAG_NONE,
344  };
345 
346  fib_entry_src_adj_deactivate(src, fib_entry);
347 
348  res.install = fib_entry_src_adj_activate(src, fib_entry);
349 
350  if (res.install) {
351  /*
352  * ADJ fib can install
353  */
355  }
356 
357  FIB_ENTRY_DBG(fib_entry, "adj-src-cover-changed");
358  return (res);
359 }
360 
361 /*
362  * fib_entry_src_adj_cover_update
363  */
366  const fib_entry_t *fib_entry)
367 {
368  /*
369  * the cover has updated, i.e. its forwarding or flags
370  * have changed. don't deactivate/activate here, since this
371  * prefix is updated during the covers walk.
372  */
374  .install = !0,
375  .bw_reason = FIB_NODE_BW_REASON_FLAG_NONE,
376  };
377  fib_entry_t *cover;
378 
379  ASSERT(FIB_NODE_INDEX_INVALID != src->u.adj.fesa_cover);
380 
381  cover = fib_entry_get(src->u.adj.fesa_cover);
382 
384 
385  FIB_ENTRY_DBG(fib_entry, "adj-src-cover-updated");
386 
387  return (res);
388 }
389 
390 const static fib_entry_src_vft_t adj_src_vft = {
392  .fesv_path_swap = fib_entry_src_adj_path_swap,
393  .fesv_path_add = fib_entry_src_adj_path_add,
394  .fesv_path_remove = fib_entry_src_adj_path_remove,
395  .fesv_remove = fib_entry_src_adj_remove,
396  .fesv_activate = fib_entry_src_adj_activate,
397  .fesv_deactivate = fib_entry_src_adj_deactivate,
398  .fesv_reactivate = fib_entry_src_adj_reactivate,
399  .fesv_format = fib_entry_src_adj_format,
400  .fesv_installed = fib_entry_src_adj_installed,
401  .fesv_cover_change = fib_entry_src_adj_cover_change,
402  .fesv_cover_update = fib_entry_src_adj_cover_update,
403 };
404 
405 void
407 {
408  fib_entry_src_register(FIB_SOURCE_ADJ, &adj_src_vft);
409 }
fib_entry_src_init_t fesv_init
#define FIB_ENTRY_DBG(_e, _fmt, _args...)
Definition: fib_entry_src.h:28
u32 flags
Definition: vhost_user.h:115
An entry in a FIB table.
Definition: fib_entry.h:462
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 *rpath)
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)
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:476
void fib_entry_cover_untrack(fib_entry_t *cover, u32 tracked_index)
vnet_main_t * vnet_get_main(void)
Definition: misc.c:47
union fib_entry_src_t_::@134 u
Source specific info.
Virtual function table each FIB entry source will register.
u32 cover_itf
#define NULL
Definition: clib.h:58
Information related to the source of a FIB entry.
Definition: fib_entry.h:354
static fib_entry_src_cover_res_t fib_entry_src_adj_cover_change(fib_entry_src_t *src, const fib_entry_t *fib_entry)
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)
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:475
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:277
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:62
struct fib_entry_src_t_::@134::@137 adj
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)
Adjacency source.
Definition: fib_entry.h:108
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:684
vl_api_ip4_address_t src
Definition: ipsec_gre.api:38
fib_entry_src_t * src
u32 fib_entry_get_resolving_interface(fib_node_index_t entry_index)
Definition: fib_entry.c:1461
static void fib_entry_src_adj_deactivate(fib_entry_src_t *src, const fib_entry_t *fib_entry)
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:50
static u8 * fib_entry_src_adj_format(fib_entry_src_t *src, u8 *s)
#define ASSERT(truth)
void fib_entry_src_register(fib_source_t source, const fib_entry_src_vft_t *vft)
Definition: fib_entry_src.c:56
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:363
fib_path_ext_adj_flags_t fpe_adj_flags
For an ADJ type extension.
Definition: fib_path_ext.h:114
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:2087
#define FIB_NODE_INDEX_INVALID
Definition: fib_types.h:31
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:358
enum fib_path_list_flags_t_ fib_path_list_flags_t
const fib_prefix_t fe_prefix
The prefix of the route.
Definition: fib_entry.h:471
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:131
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