FD.io VPP  v17.04-9-g99c0734
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 
23 /**
24  * Source initialisation Function
25  */
26 static void
28 {
29  src->adj.fesa_cover = FIB_NODE_INDEX_INVALID;
30  src->adj.fesa_sibling = FIB_NODE_INDEX_INVALID;
31 }
32 
33 static void
35  const fib_entry_t *entry,
36  fib_path_list_flags_t pl_flags,
37  const fib_route_path_t *paths)
38 {
39  src->fes_pl = fib_path_list_create(pl_flags, paths);
40 }
41 
42 static void
44 {
46 }
47 
48 
49 /*
50  * Source activate.
51  * Called when the source is the new longer best source on the entry
52  */
53 static int
55  const fib_entry_t *fib_entry)
56 {
57  fib_entry_t *cover;
58 
59  /*
60  * find the covering prefix. become a dependent thereof.
61  * there should always be a cover, though it may be the default route.
62  */
63  src->adj.fesa_cover = fib_table_get_less_specific(fib_entry->fe_fib_index,
64  &fib_entry->fe_prefix);
65 
66  ASSERT(FIB_NODE_INDEX_INVALID != src->adj.fesa_cover);
67  ASSERT(fib_entry_get_index(fib_entry) != src->adj.fesa_cover);
68 
69  cover = fib_entry_get(src->adj.fesa_cover);
70 
71  ASSERT(cover != fib_entry);
72 
73  src->adj.fesa_sibling =
75  fib_entry_get_index(fib_entry));
76 
77  /*
78  * if the cover is attached on the same interface as this adj source then
79  * install the FIB entry via the adj. otherwise install a drop.
80  * This prevents ARP/ND entries that on interface X that do not belong
81  * on X's subnet from being added to the FIB. To do so would allow
82  * nefarious gratuitous ARP requests from attracting traffic to the sender.
83  *
84  * and yes, I really do mean attached and not connected.
85  * this abomination;
86  * ip route add 10.0.0.0/24 Eth0
87  * is attached. and we want adj-fibs to install on Eth0.
88  */
90  {
91  u32 cover_itf = fib_entry_get_resolving_interface(src->adj.fesa_cover);
93 
94  if (cover_itf == adj_itf)
95  {
96  return (1);
97  }
98  else
99  {
100  /*
101  * if the interface the adj is on is unnumbered to the
102  * cover's, then allow that too.
103  */
104  vnet_sw_interface_t *swif;
105 
106  swif = vnet_get_sw_interface (vnet_get_main(), adj_itf);
107 
109  cover_itf == swif->unnumbered_sw_if_index)
110  {
111  return (1);
112  }
113  }
114  }
115  return (0);
116 }
117 
118 /*
119  * Source Deactivate.
120  * Called when the source is no longer best source on the entry
121  */
122 static void
124  const fib_entry_t *fib_entry)
125 {
126  fib_entry_t *cover;
127 
128  /*
129  * remove the depednecy on the covering entry
130  */
131  ASSERT(FIB_NODE_INDEX_INVALID != src->adj.fesa_cover);
132  cover = fib_entry_get(src->adj.fesa_cover);
133 
134  fib_entry_cover_untrack(cover, src->adj.fesa_sibling);
135 
136  /*
137  * tell the cover this entry no longer needs exporting
138  */
140 
141  src->adj.fesa_cover = FIB_NODE_INDEX_INVALID;
142 }
143 
144 static u8*
146  u8* s)
147 {
148  return (format(s, "cover:%d", src->adj.fesa_cover));
149 }
150 
151 static void
153  const fib_entry_t *fib_entry)
154 {
155  /*
156  * The adj source now rules! poke our cover to get exported
157  */
158  fib_entry_t *cover;
159 
160  ASSERT(FIB_NODE_INDEX_INVALID != src->adj.fesa_cover);
161  cover = fib_entry_get(src->adj.fesa_cover);
162 
164  fib_entry_get_index(fib_entry));
165 }
166 
169  const fib_entry_t *fib_entry)
170 {
172  .install = !0,
173  .bw_reason = FIB_NODE_BW_REASON_FLAG_NONE,
174  };
175 
176  fib_entry_src_adj_deactivate(src, fib_entry);
177 
178  res.install = fib_entry_src_adj_activate(src, fib_entry);
179 
180  if (res.install) {
181  /*
182  * ADJ fib can install
183  */
185  }
186 
187  return (res);
188 }
189 
190 /*
191  * fib_entry_src_adj_cover_update
192  */
195  const fib_entry_t *fib_entry)
196 {
197  /*
198  * the cover has updated, i.e. its forwarding or flags
199  * have changed. do'nt decativate/activate here, since this
200  * prefix is updated during the covers walk.
201  */
203  .install = !0,
204  .bw_reason = FIB_NODE_BW_REASON_FLAG_NONE,
205  };
206  fib_entry_t *cover;
207 
208  ASSERT(FIB_NODE_INDEX_INVALID != src->adj.fesa_cover);
209 
210  cover = fib_entry_get(src->adj.fesa_cover);
211 
213 
214  return (res);
215 }
216 
217 const static fib_entry_src_vft_t adj_src_vft = {
219  .fesv_path_swap = fib_entry_src_adj_path_swap,
220  .fesv_remove = fib_entry_src_adj_remove,
221  .fesv_activate = fib_entry_src_adj_activate,
222  .fesv_deactivate = fib_entry_src_adj_deactivate,
223  .fesv_format = fib_entry_src_adj_format,
224  .fesv_installed = fib_entry_src_adj_installed,
225  .fesv_cover_change = fib_entry_src_adj_cover_change,
226  .fesv_cover_update = fib_entry_src_adj_cover_update,
227 };
228 
229 void
231 {
232  fib_entry_src_register(FIB_SOURCE_ADJ, &adj_src_vft);
233 }
#define VNET_SW_INTERFACE_FLAG_UNNUMBERED
Definition: interface.h:543
fib_entry_src_init_t fesv_init
An entry in a FIB table.
Definition: fib_entry.h:373
fib_node_bw_reason_flag_t bw_reason
Definition: fib_entry_src.h:89
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:308
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 fib_path_list_get_resolving_interface(fib_node_index_t path_list_index)
Information related to the source of a FIB entry.
Definition: fib_entry.h:282
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:87
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:418
u32 fe_fib_index
The index of the FIB table this entry is in.
Definition: fib_entry.h:386
Definition: fib_entry.h:229
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:56
u16 install
Definition: fib_entry_src.h:88
static void fib_entry_src_adj_remove(fib_entry_src_t *src)
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:92
static void fib_entry_src_adj_installed(fib_entry_src_t *src, const fib_entry_t *fib_entry)
void fib_entry_src_adj_register(void)
u32 fib_entry_get_resolving_interface(fib_node_index_t entry_index)
Definition: fib_entry.c:1321
static void fib_entry_src_adj_deactivate(fib_entry_src_t *src, const fib_entry_t *fib_entry)
struct fib_entry_src_t_::@88::@91 adj
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)
fib_entry_t * fib_entry_get(fib_node_index_t index)
Definition: fib_entry.c:44
static u8 * fib_entry_src_adj_format(fib_entry_src_t *src, u8 *s)
#define ASSERT(truth)
unsigned int u32
Definition: types.h:88
void fib_entry_src_register(fib_source_t source, const fib_entry_src_vft_t *vft)
Definition: fib_entry_src.c:38
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:291
#define FIB_NODE_INDEX_INVALID
Definition: fib_types.h:29
unsigned char u8
Definition: types.h:56
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:382
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