fib: Decouple source from priority and behaviour
[vpp.git] / src / vnet / fib / fib_entry.h
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 #ifndef __FIB_ENTRY_H__
17 #define __FIB_ENTRY_H__
18
19 #include <vnet/fib/fib_node.h>
20 #include <vnet/fib/fib_source.h>
21 #include <vnet/adj/adj.h>
22 #include <vnet/ip/ip.h>
23 #include <vnet/dpo/dpo.h>
24
25 /**
26  * The different sources that can create a route.
27  * The sources are defined here with their relative priority order.
28  * The lower the value the higher the priority
29  */
30 typedef enum fib_entry_attribute_t_ {
31     /**
32      * Marker. Add new values after this one.
33      */
34     FIB_ENTRY_ATTRIBUTE_FIRST,
35     /**
36      * Connected. The prefix is configured on an interface.
37      */
38     FIB_ENTRY_ATTRIBUTE_CONNECTED = FIB_ENTRY_ATTRIBUTE_FIRST,
39     /**
40      * Attached. The prefix is attached to an interface.
41      */
42     FIB_ENTRY_ATTRIBUTE_ATTACHED,
43     /**
44      * The route is an explicit drop.
45      */
46     FIB_ENTRY_ATTRIBUTE_DROP,
47     /**
48      * The route is exclusive. The client creating the route is
49      * providing an exclusive adjacency.
50      */
51     FIB_ENTRY_ATTRIBUTE_EXCLUSIVE,
52     /**
53      * The route is attached cross tables and thus imports covered
54      * prefixes from the other table.
55      */
56     FIB_ENTRY_ATTRIBUTE_IMPORT,
57     /**
58      * The prefix/address is local to this device
59      */
60     FIB_ENTRY_ATTRIBUTE_LOCAL,
61     /**
62      * The prefix/address is a multicast prefix.
63      *  this aplies only to MPLS. IP multicast is handled by mfib
64      */
65     FIB_ENTRY_ATTRIBUTE_MULTICAST,
66     /**
67      * The prefix/address exempted from loose uRPF check
68      * To be used with caution
69      */
70     FIB_ENTRY_ATTRIBUTE_URPF_EXEMPT,
71     /**
72      * The prefix/address exempted from attached export
73      */
74     FIB_ENTRY_ATTRIBUTE_NO_ATTACHED_EXPORT,
75     /**
76      * This FIB entry imposes its source information on all prefixes
77      * that is covers
78      */
79     FIB_ENTRY_ATTRIBUTE_COVERED_INHERIT,
80     /**
81      * The interpose attribute.
82      * place the forwarding provided by the source infront of the forwarding
83      * provided by the best source, or failing that, by the cover.
84      */
85     FIB_ENTRY_ATTRIBUTE_INTERPOSE,
86     /**
87      * Marker. add new entries before this one.
88      */
89     FIB_ENTRY_ATTRIBUTE_LAST = FIB_ENTRY_ATTRIBUTE_INTERPOSE,
90 } fib_entry_attribute_t;
91
92 #define FIB_ENTRY_ATTRIBUTES {                          \
93     [FIB_ENTRY_ATTRIBUTE_CONNECTED] = "connected",      \
94     [FIB_ENTRY_ATTRIBUTE_ATTACHED]  = "attached",       \
95     [FIB_ENTRY_ATTRIBUTE_IMPORT]    = "import",         \
96     [FIB_ENTRY_ATTRIBUTE_DROP]      = "drop",           \
97     [FIB_ENTRY_ATTRIBUTE_EXCLUSIVE] = "exclusive",      \
98     [FIB_ENTRY_ATTRIBUTE_LOCAL]     = "local",          \
99     [FIB_ENTRY_ATTRIBUTE_URPF_EXEMPT] = "uRPF-exempt",  \
100     [FIB_ENTRY_ATTRIBUTE_MULTICAST] = "multicast",      \
101     [FIB_ENTRY_ATTRIBUTE_NO_ATTACHED_EXPORT] = "no-attached-export",    \
102     [FIB_ENTRY_ATTRIBUTE_COVERED_INHERIT] = "covered-inherit",  \
103     [FIB_ENTRY_ATTRIBUTE_INTERPOSE] = "interpose",  \
104 }
105
106 #define FOR_EACH_FIB_ATTRIBUTE(_item)                   \
107     for (_item = FIB_ENTRY_ATTRIBUTE_FIRST;             \
108          _item <= FIB_ENTRY_ATTRIBUTE_LAST;             \
109          _item++)
110
111 typedef enum fib_entry_flag_t_ {
112     FIB_ENTRY_FLAG_NONE      = 0,
113     FIB_ENTRY_FLAG_CONNECTED = (1 << FIB_ENTRY_ATTRIBUTE_CONNECTED),
114     FIB_ENTRY_FLAG_ATTACHED  = (1 << FIB_ENTRY_ATTRIBUTE_ATTACHED),
115     FIB_ENTRY_FLAG_DROP      = (1 << FIB_ENTRY_ATTRIBUTE_DROP),
116     FIB_ENTRY_FLAG_EXCLUSIVE = (1 << FIB_ENTRY_ATTRIBUTE_EXCLUSIVE),
117     FIB_ENTRY_FLAG_LOCAL     = (1 << FIB_ENTRY_ATTRIBUTE_LOCAL),
118     FIB_ENTRY_FLAG_IMPORT    = (1 << FIB_ENTRY_ATTRIBUTE_IMPORT),
119     FIB_ENTRY_FLAG_NO_ATTACHED_EXPORT = (1 << FIB_ENTRY_ATTRIBUTE_NO_ATTACHED_EXPORT),
120     FIB_ENTRY_FLAG_LOOSE_URPF_EXEMPT = (1 << FIB_ENTRY_ATTRIBUTE_URPF_EXEMPT),
121     FIB_ENTRY_FLAG_MULTICAST = (1 << FIB_ENTRY_ATTRIBUTE_MULTICAST),
122     FIB_ENTRY_FLAG_COVERED_INHERIT = (1 << FIB_ENTRY_ATTRIBUTE_COVERED_INHERIT),
123     FIB_ENTRY_FLAG_INTERPOSE = (1 << FIB_ENTRY_ATTRIBUTE_INTERPOSE),
124 } __attribute__((packed)) fib_entry_flag_t;
125
126 extern u8 * format_fib_entry_flags(u8 *s, va_list *args);
127
128 /**
129  * Flags for the source data
130  */
131 typedef enum fib_entry_src_attribute_t_ {
132     /**
133      * Marker. Add new values after this one.
134      */
135     FIB_ENTRY_SRC_ATTRIBUTE_FIRST,
136     /**
137      * the source has been added to the entry
138      */
139     FIB_ENTRY_SRC_ATTRIBUTE_ADDED = FIB_ENTRY_SRC_ATTRIBUTE_FIRST,
140     /**
141      * the source is contributing forwarding
142      */
143     FIB_ENTRY_SRC_ATTRIBUTE_CONTRIBUTING,
144     /**
145      * the source is active/best
146      */
147     FIB_ENTRY_SRC_ATTRIBUTE_ACTIVE,
148     /**
149      * the source is stale
150      */
151     FIB_ENTRY_SRC_ATTRIBUTE_STALE,
152     /**
153      * the source is inherited from its cover
154      */
155     FIB_ENTRY_SRC_ATTRIBUTE_INHERITED,
156     /**
157      * Marker. add new entries before this one.
158      */
159     FIB_ENTRY_SRC_ATTRIBUTE_LAST = FIB_ENTRY_SRC_ATTRIBUTE_INHERITED,
160 } fib_entry_src_attribute_t;
161
162
163 #define FIB_ENTRY_SRC_ATTRIBUTES {               \
164     [FIB_ENTRY_SRC_ATTRIBUTE_ADDED]  = "added",  \
165     [FIB_ENTRY_SRC_ATTRIBUTE_CONTRIBUTING] = "contributing", \
166     [FIB_ENTRY_SRC_ATTRIBUTE_ACTIVE] = "active", \
167     [FIB_ENTRY_SRC_ATTRIBUTE_STALE] = "stale",      \
168     [FIB_ENTRY_SRC_ATTRIBUTE_INHERITED] = "inherited", \
169 }
170
171 #define FOR_EACH_FIB_SRC_ATTRIBUTE(_item)               \
172     for (_item = FIB_ENTRY_SRC_ATTRIBUTE_FIRST;         \
173          _item <= FIB_ENTRY_SRC_ATTRIBUTE_LAST;         \
174          _item++)
175
176 typedef enum fib_entry_src_flag_t_ {
177     FIB_ENTRY_SRC_FLAG_NONE   = 0,
178     FIB_ENTRY_SRC_FLAG_ADDED  = (1 << FIB_ENTRY_SRC_ATTRIBUTE_ADDED),
179     FIB_ENTRY_SRC_FLAG_CONTRIBUTING = (1 << FIB_ENTRY_SRC_ATTRIBUTE_CONTRIBUTING),
180     FIB_ENTRY_SRC_FLAG_ACTIVE = (1 << FIB_ENTRY_SRC_ATTRIBUTE_ACTIVE),
181     FIB_ENTRY_SRC_FLAG_STALE = (1 << FIB_ENTRY_SRC_ATTRIBUTE_STALE),
182     FIB_ENTRY_SRC_FLAG_INHERITED = (1 << FIB_ENTRY_SRC_ATTRIBUTE_INHERITED),
183 } __attribute__ ((packed)) fib_entry_src_flag_t;
184
185 extern u8 * format_fib_entry_src_flags(u8 *s, va_list *args);
186
187 /*
188  * Keep the size of the flags field to 2 bytes, so it
189  * can be placed next to the 2 bytes reference count
190  */
191 STATIC_ASSERT (sizeof(fib_entry_src_flag_t) <= 2,
192                "FIB entry flags field size too big");
193
194 /**
195  * Information related to the source of a FIB entry
196  */
197 typedef struct fib_entry_src_t_ {
198     /**
199      * A vector of path extensions
200      */
201     fib_path_ext_list_t fes_path_exts;
202
203     /**
204      * The path-list created by the source
205      */
206     fib_node_index_t fes_pl;
207
208     /**
209      * Flags the source contributes to the entry
210      */
211     fib_entry_flag_t fes_entry_flags;
212
213     /**
214      * Which source this info block is for
215      */
216     fib_source_t fes_src;
217
218     /**
219      * Flags on the source
220      */
221     fib_entry_src_flag_t fes_flags;
222
223     /**
224      * 1 bytes ref count. This is not the number of users of the Entry
225      * (which is itself not large, due to path-list sharing), but the number
226      * of times a given source has been added. Which is even fewer
227      */
228     u8 fes_ref_count;
229     
230     /**
231      * Source specific info
232      */
233     union {
234         struct {
235             /**
236              * the index of the FIB entry that is the covering entry
237              */
238             fib_node_index_t fesr_cover;
239             /**
240              * This source's index in the cover's list
241              */
242             u32 fesr_sibling;
243         } rr;
244         struct {
245             /**
246              * the index of the FIB entry that is the covering entry
247              */
248             fib_node_index_t fesi_cover;
249             /**
250              * This source's index in the cover's list
251              */
252             u32 fesi_sibling;
253             /**
254              * DPO type to interpose. The dpo type needs to have registered
255              * it's 'contribute interpose' callback function.
256              */
257             dpo_id_t fesi_dpo;
258         } interpose;
259         struct {
260             /**
261              * the index of the FIB entry that is the covering entry
262              */
263             fib_node_index_t fesa_cover;
264             /**
265              * This source's index in the cover's list
266              */
267             u32 fesa_sibling;
268         } adj;
269         struct {
270             /**
271              * the index of the FIB entry that is the covering entry
272              */
273             fib_node_index_t fesi_cover;
274             /**
275              * This source's index in the cover's list
276              */
277             u32 fesi_sibling;
278         } interface;
279         struct {
280             /**
281              * This MPLS local label associated with the prefix.
282              */
283             mpls_label_t fesm_label;
284
285             /**
286              * the indicies of the LFIB entries created
287              */
288             fib_node_index_t fesm_lfes[2];
289         } mpls;
290         struct {
291             /**
292              * The source FIB index.
293              */
294             fib_node_index_t fesl_fib_index;
295         } lisp;
296     } u;
297 } fib_entry_src_t;
298
299 /**
300  * An entry in a FIB table.
301  *
302  * This entry represents a route added to the FIB that is stored
303  * in one of the FIB tables.
304  */
305 typedef struct fib_entry_t_ {
306     /**
307      * Base class. The entry's node representation in the graph.
308      */
309     fib_node_t fe_node;
310     /**
311      * The prefix of the route. this is const just to be sure.
312      * It is the entry's key/identity and so should never change.
313      */
314     const fib_prefix_t fe_prefix;
315     /**
316      * The index of the FIB table this entry is in
317      */
318     u32 fe_fib_index;
319     /**
320      * The load-balance used for forwarding.
321      *
322      * We don't share the EOS and non-EOS even in case when they could be
323      * because:
324      *   - complexity & reliability v. memory
325      *       determining the conditions where sharing is possible is non-trivial.
326      *   - separate LBs means we can get the EOS bit right in the MPLS label DPO
327      *     and so save a few clock cycles in the DP imposition node since we can
328      *     paint the header straight on without the need to check the packet
329      *     type to derive the EOS bit value.
330      */
331     dpo_id_t fe_lb;
332     /**
333      * Vector of source infos.
334      * Most entries will only have 1 source. So we optimise for memory usage,
335      * which is preferable since we have many entries.
336      */
337     fib_entry_src_t *fe_srcs;
338     /**
339      * the path-list for which this entry is a child. This is also the path-list
340      * that is contributing forwarding for this entry.
341      */
342     fib_node_index_t fe_parent;
343     /**
344      * index of this entry in the parent's child list.
345      * This is set when this entry is added as a child, but can also
346      * be changed by the parent as it manages its list.
347      */
348     u32 fe_sibling;
349
350     /**
351      * A vector of delegate indices.
352      */
353     index_t *fe_delegates;
354 } fib_entry_t;
355
356 #define FOR_EACH_FIB_ENTRY_FLAG(_item) \
357     for (_item = FIB_ENTRY_FLAG_FIRST; _item < FIB_ENTRY_FLAG_MAX; _item++)
358
359 #define FIB_ENTRY_FORMAT_BRIEF   (0x0)
360 #define FIB_ENTRY_FORMAT_DETAIL  (0x1)
361 #define FIB_ENTRY_FORMAT_DETAIL2 (0x2)
362
363 extern u8 *format_fib_entry (u8 * s, va_list * args);
364 extern u8 *format_fib_source (u8 * s, va_list * args);
365
366 extern fib_node_index_t fib_entry_create_special(u32 fib_index,
367                                                  const fib_prefix_t *prefix,
368                                                  fib_source_t source,
369                                                  fib_entry_flag_t flags,
370                                                  const dpo_id_t *dpo);
371
372 extern fib_node_index_t fib_entry_create (u32 fib_index,
373                                           const fib_prefix_t *prefix,
374                                           fib_source_t source,
375                                           fib_entry_flag_t flags,
376                                           const fib_route_path_t *paths);
377 extern void fib_entry_update (fib_node_index_t fib_entry_index,
378                               fib_source_t source,
379                               fib_entry_flag_t flags,
380                               const fib_route_path_t *paths);
381
382 extern void fib_entry_path_add(fib_node_index_t fib_entry_index,
383                                fib_source_t source,
384                                fib_entry_flag_t flags,
385                                const fib_route_path_t *rpaths);
386 extern void fib_entry_special_add(fib_node_index_t fib_entry_index,
387                                   fib_source_t source,
388                                   fib_entry_flag_t flags,
389                                   const dpo_id_t *dpo);
390 extern void fib_entry_special_update(fib_node_index_t fib_entry_index,
391                                      fib_source_t source,
392                                      fib_entry_flag_t flags,
393                                      const dpo_id_t *dpo);
394 extern fib_entry_src_flag_t fib_entry_special_remove(fib_node_index_t fib_entry_index,
395                                                      fib_source_t source);
396
397 extern fib_entry_src_flag_t fib_entry_path_remove(fib_node_index_t fib_entry_index,
398                                                   fib_source_t source,
399                                                   const fib_route_path_t *rpaths);
400
401 extern void fib_entry_inherit(fib_node_index_t cover,
402                               fib_node_index_t covered);
403
404 extern fib_entry_src_flag_t fib_entry_delete(fib_node_index_t fib_entry_index,
405                                              fib_source_t source);
406
407 extern void fib_entry_recalculate_forwarding(
408     fib_node_index_t fib_entry_index);
409 extern void fib_entry_contribute_urpf(fib_node_index_t path_index,
410                                       index_t urpf);
411 extern void fib_entry_contribute_forwarding(
412     fib_node_index_t fib_entry_index,
413     fib_forward_chain_type_t type,
414     dpo_id_t *dpo);
415 extern const dpo_id_t * fib_entry_contribute_ip_forwarding(
416     fib_node_index_t fib_entry_index);
417 extern adj_index_t fib_entry_get_adj_for_source(
418     fib_node_index_t fib_entry_index,
419     fib_source_t source);
420 extern const int fib_entry_get_dpo_for_source (
421     fib_node_index_t fib_entry_index,
422     fib_source_t source,
423     dpo_id_t *dpo);
424
425 extern adj_index_t fib_entry_get_adj(fib_node_index_t fib_entry_index);
426
427 extern int fib_entry_cmp_for_sort(void *i1, void *i2);
428
429 extern void fib_entry_cover_changed(fib_node_index_t fib_entry);
430 extern void fib_entry_cover_updated(fib_node_index_t fib_entry);
431 extern int fib_entry_recursive_loop_detect(fib_node_index_t entry_index,
432                                            fib_node_index_t **entry_indicies);
433
434 extern void fib_entry_lock(fib_node_index_t fib_entry_index);
435 extern void fib_entry_unlock(fib_node_index_t fib_entry_index);
436
437 extern u32 fib_entry_child_add(fib_node_index_t fib_entry_index,
438                                fib_node_type_t type,
439                                fib_node_index_t child_index);
440 extern void fib_entry_child_remove(fib_node_index_t fib_entry_index,
441                                    u32 sibling_index);
442 extern u32 fib_entry_get_resolving_interface(fib_node_index_t fib_entry_index);
443 extern u32 fib_entry_get_resolving_interface_for_source(
444     fib_node_index_t fib_entry_index,
445     fib_source_t source);
446
447 extern fib_route_path_t* fib_entry_encode(fib_node_index_t fib_entry_index);
448 extern const fib_prefix_t* fib_entry_get_prefix(fib_node_index_t fib_entry_index);
449 extern u32 fib_entry_get_fib_index(fib_node_index_t fib_entry_index);
450 extern void fib_entry_set_source_data(fib_node_index_t fib_entry_index,
451                                       fib_source_t source,
452                                       const void *data);
453 extern const void* fib_entry_get_source_data(fib_node_index_t fib_entry_index,
454                                              fib_source_t source);
455
456 extern fib_entry_flag_t fib_entry_get_flags(fib_node_index_t fib_entry_index);
457 extern fib_entry_flag_t fib_entry_get_flags_for_source(
458     fib_node_index_t fib_entry_index,
459     fib_source_t source);
460 extern fib_source_t fib_entry_get_best_source(fib_node_index_t fib_entry_index);
461 extern int fib_entry_is_sourced(fib_node_index_t fib_entry_index,
462                                 fib_source_t source);
463
464 extern fib_node_index_t fib_entry_get_path_list(fib_node_index_t fib_entry_index);
465 extern int fib_entry_is_resolved(fib_node_index_t fib_entry_index);
466 extern int fib_entry_is_host(fib_node_index_t fib_entry_index);
467 extern int fib_entry_is_marked(fib_node_index_t fib_entry_index, fib_source_t source);
468 extern void fib_entry_mark(fib_node_index_t fib_entry_index, fib_source_t source);
469 extern void fib_entry_set_flow_hash_config(fib_node_index_t fib_entry_index,
470                                            flow_hash_config_t hash_config);
471
472 extern void fib_entry_module_init(void);
473
474 extern u32 fib_entry_get_stats_index(fib_node_index_t fib_entry_index);
475
476 /*
477  * unsafe... beware the raw pointer.
478  */
479 extern fib_node_index_t fib_entry_get_index(const fib_entry_t * fib_entry);
480 extern fib_entry_t * fib_entry_get(fib_node_index_t fib_entry_index);
481
482 /*
483  * for testing purposes.
484  */
485 extern u32 fib_entry_pool_size(void);
486
487 #endif