]> git.proxmox.com Git - mirror_frr.git/blob - zebra/zebra_nhg.h
Merge pull request #7220 from idryzhov/fix-clear-isis
[mirror_frr.git] / zebra / zebra_nhg.h
1 /* Zebra Nexthop Group header.
2 * Copyright (C) 2019 Cumulus Networks, Inc.
3 * Donald Sharp
4 * Stephen Worley
5 *
6 * This file is part of FRR.
7 *
8 * FRR is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License as published by the
10 * Free Software Foundation; either version 2, or (at your option) any
11 * later version.
12 *
13 * FRR is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with FRR; see the file COPYING. If not, write to the Free
20 * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
21 * 02111-1307, USA.
22 */
23 #ifndef __ZEBRA_NHG_H__
24 #define __ZEBRA_NHG_H__
25
26 #include "lib/nexthop.h"
27 #include "lib/nexthop_group.h"
28
29 #ifdef __cplusplus
30 extern "C" {
31 #endif
32
33 /* This struct is used exclusively for dataplane
34 * interaction via a dataplane context.
35 *
36 * It is designed to mimic the netlink nexthop_grp
37 * struct in include/linux/nexthop.h
38 */
39 struct nh_grp {
40 uint32_t id;
41 uint8_t weight;
42 };
43
44 PREDECL_RBTREE_UNIQ(nhg_connected_tree);
45
46 /*
47 * Hashtables containing nhg entries is in `zebra_router`.
48 */
49 struct nhg_hash_entry {
50 uint32_t id;
51 afi_t afi;
52 vrf_id_t vrf_id;
53 int type;
54
55 struct nexthop_group nhg;
56
57 /* If supported, a mapping of backup nexthops. */
58 struct nhg_backup_info *backup_info;
59
60 /* If this is not a group, it
61 * will be a single nexthop
62 * and must have an interface
63 * associated with it.
64 * Otherwise, this will be null.
65 */
66 struct interface *ifp;
67
68 uint32_t refcnt;
69 uint32_t dplane_ref;
70
71 uint32_t flags;
72
73 /* Dependency tree for other entries.
74 * For instance a group with two
75 * nexthops will have two dependencies
76 * pointing to those nhg_hash_entries.
77 *
78 * Using a rb tree here to make lookups
79 * faster with ID's.
80 */
81 struct nhg_connected_tree_head nhg_depends, nhg_dependents;
82
83 /*
84 * Is this nexthop group valid, ie all nexthops are fully resolved.
85 * What is fully resolved? It's a nexthop that is either self contained
86 * and correct( ie no recursive pointer ) or a nexthop that is recursively
87 * resolved and correct.
88 */
89 #define NEXTHOP_GROUP_VALID (1 << 0)
90 /*
91 * Has this nexthop group been installed? At this point in time, this
92 * means that the data-plane has been told about this nexthop group
93 * and it's possible usage by a route entry.
94 */
95 #define NEXTHOP_GROUP_INSTALLED (1 << 1)
96 /*
97 * Has the nexthop group been queued to be send to the FIB?
98 * The NEXTHOP_GROUP_VALID flag should also be set by this point.
99 */
100 #define NEXTHOP_GROUP_QUEUED (1 << 2)
101 /*
102 * Is this a nexthop that is recursively resolved?
103 */
104 #define NEXTHOP_GROUP_RECURSIVE (1 << 3)
105
106 /*
107 * Backup nexthop support - identify groups that are backups for
108 * another group.
109 */
110 #define NEXTHOP_GROUP_BACKUP (1 << 4)
111
112 /*
113 * The NHG has been release by an upper level protocol via the
114 * `zebra_nhg_proto_del()` API.
115 *
116 * We use this flag to track this state in case the NHG is still being used
117 * by routes therefore holding their refcnts as well. Otherwise, the NHG will
118 * be removed and uninstalled.
119 *
120 */
121 #define NEXTHOP_GROUP_PROTO_RELEASED (1 << 5)
122
123 /*
124 * Track FPM installation status..
125 */
126 #define NEXTHOP_GROUP_FPM (1 << 6)
127 };
128
129 /* Was this one we created, either this session or previously? */
130 #define ZEBRA_NHG_CREATED(NHE) \
131 (((NHE->type) <= ZEBRA_ROUTE_MAX) && (NHE->type != ZEBRA_ROUTE_KERNEL))
132
133 /* Is this an NHE owned by zebra and not an upper level protocol? */
134 #define ZEBRA_OWNED(NHE) (NHE->type == ZEBRA_ROUTE_NHG)
135
136 /*
137 * Backup nexthops: this is a group object itself, so
138 * that the backup nexthops can use the same code as a normal object.
139 */
140 struct nhg_backup_info {
141 struct nhg_hash_entry *nhe;
142 };
143
144 enum nhg_ctx_op_e {
145 NHG_CTX_OP_NONE = 0,
146 NHG_CTX_OP_NEW,
147 NHG_CTX_OP_DEL,
148 };
149
150 enum nhg_ctx_status {
151 NHG_CTX_NONE = 0,
152 NHG_CTX_QUEUED,
153 NHG_CTX_REQUEUED,
154 NHG_CTX_SUCCESS,
155 NHG_CTX_FAILURE,
156 };
157
158 /*
159 * Context needed to queue nhg updates on the
160 * work queue.
161 */
162 struct nhg_ctx {
163
164 /* Unique ID */
165 uint32_t id;
166
167 vrf_id_t vrf_id;
168 afi_t afi;
169 /*
170 * This should only every be ZEBRA_ROUTE_NHG unless we get a a kernel
171 * created nexthop not made by us.
172 */
173 int type;
174
175 /* If its a group array, how many? */
176 uint8_t count;
177
178 /* Its either a single nexthop or an array of ID's */
179 union {
180 struct nexthop nh;
181 struct nh_grp grp[MULTIPATH_NUM];
182 } u;
183
184 enum nhg_ctx_op_e op;
185 enum nhg_ctx_status status;
186 };
187
188 /* Global control to disable use of kernel nexthops, if available. We can't
189 * force the kernel to support nexthop ids, of course, but we can disable
190 * zebra's use of them, for testing e.g. By default, if the kernel supports
191 * nexthop ids, zebra uses them.
192 */
193 void zebra_nhg_enable_kernel_nexthops(bool set);
194 bool zebra_nhg_kernel_nexthops_enabled(void);
195
196 /* Global control for zebra to only use proto-owned nexthops */
197 void zebra_nhg_set_proto_nexthops_only(bool set);
198 bool zebra_nhg_proto_nexthops_only(void);
199
200 /**
201 * NHE abstracted tree functions.
202 * Use these where possible instead of direct access.
203 */
204 struct nhg_hash_entry *zebra_nhg_alloc(void);
205 void zebra_nhg_free(struct nhg_hash_entry *nhe);
206 /* In order to clear a generic hash, we need a generic api, sigh. */
207 void zebra_nhg_hash_free(void *p);
208
209 /* Init an nhe, for use in a hash lookup for example. There's some fuzziness
210 * if the nhe represents only a single nexthop, so we try to capture that
211 * variant also.
212 */
213 void zebra_nhe_init(struct nhg_hash_entry *nhe, afi_t afi,
214 const struct nexthop *nh);
215
216 /*
217 * Shallow copy of 'orig', into new/allocated nhe.
218 */
219 struct nhg_hash_entry *zebra_nhe_copy(const struct nhg_hash_entry *orig,
220 uint32_t id);
221
222 /* Allocate, free backup nexthop info objects */
223 struct nhg_backup_info *zebra_nhg_backup_alloc(void);
224 void zebra_nhg_backup_free(struct nhg_backup_info **p);
225
226 struct nexthop_group *zebra_nhg_get_backup_nhg(struct nhg_hash_entry *nhe);
227
228 extern struct nhg_hash_entry *zebra_nhg_resolve(struct nhg_hash_entry *nhe);
229
230 extern unsigned int zebra_nhg_depends_count(const struct nhg_hash_entry *nhe);
231 extern bool zebra_nhg_depends_is_empty(const struct nhg_hash_entry *nhe);
232
233 extern unsigned int
234 zebra_nhg_dependents_count(const struct nhg_hash_entry *nhe);
235 extern bool zebra_nhg_dependents_is_empty(const struct nhg_hash_entry *nhe);
236
237 /* Lookup ID, doesn't create */
238 extern struct nhg_hash_entry *zebra_nhg_lookup_id(uint32_t id);
239
240 /* Hash functions */
241 extern uint32_t zebra_nhg_hash_key(const void *arg);
242 extern uint32_t zebra_nhg_id_key(const void *arg);
243
244 extern bool zebra_nhg_hash_equal(const void *arg1, const void *arg2);
245 extern bool zebra_nhg_hash_id_equal(const void *arg1, const void *arg2);
246
247 /*
248 * Process a context off of a queue.
249 * Specifically this should be from
250 * the rib meta queue.
251 */
252 extern int nhg_ctx_process(struct nhg_ctx *ctx);
253
254 /* Find via kernel nh creation */
255 extern int zebra_nhg_kernel_find(uint32_t id, struct nexthop *nh,
256 struct nh_grp *grp, uint8_t count,
257 vrf_id_t vrf_id, afi_t afi, int type,
258 int startup);
259 /* Del via kernel */
260 extern int zebra_nhg_kernel_del(uint32_t id, vrf_id_t vrf_id);
261
262 /* Find an nhe based on a nexthop_group */
263 extern struct nhg_hash_entry *zebra_nhg_rib_find(uint32_t id,
264 struct nexthop_group *nhg,
265 afi_t rt_afi, int type);
266
267 /* Find an nhe based on a route's nhe, used during route creation */
268 struct nhg_hash_entry *
269 zebra_nhg_rib_find_nhe(struct nhg_hash_entry *rt_nhe, afi_t rt_afi);
270
271
272 /**
273 * Functions for Add/Del/Replace via protocol NHG creation.
274 *
275 * The NHEs will not be hashed. They will only be present in the
276 * ID table and therefore not sharable.
277 *
278 * It is the owning protocols job to manage these.
279 */
280
281 /*
282 * Add NHE. If already exists, Replace.
283 *
284 * Returns allocated NHE on success, otherwise NULL.
285 */
286 struct nhg_hash_entry *zebra_nhg_proto_add(uint32_t id, int type,
287 struct nexthop_group *nhg,
288 afi_t afi);
289
290 /*
291 * Del NHE.
292 *
293 * Returns deleted NHE on success, otherwise NULL.
294 *
295 * Caller must decrement ref with zebra_nhg_decrement_ref() when done.
296 */
297 struct nhg_hash_entry *zebra_nhg_proto_del(uint32_t id, int type);
298
299 /*
300 * Remove specific by proto NHGs.
301 *
302 * Called after client disconnect.
303 *
304 */
305 unsigned long zebra_nhg_score_proto(int type);
306
307 /* Reference counter functions */
308 extern void zebra_nhg_decrement_ref(struct nhg_hash_entry *nhe);
309 extern void zebra_nhg_increment_ref(struct nhg_hash_entry *nhe);
310
311 /* Check validity of nhe, if invalid will update dependents as well */
312 extern void zebra_nhg_check_valid(struct nhg_hash_entry *nhe);
313
314 /* Convert nhe depends to a grp context that can be passed around safely */
315 extern uint8_t zebra_nhg_nhe2grp(struct nh_grp *grp, struct nhg_hash_entry *nhe,
316 int size);
317
318 /* Dataplane install/uninstall */
319 extern void zebra_nhg_install_kernel(struct nhg_hash_entry *nhe);
320 extern void zebra_nhg_uninstall_kernel(struct nhg_hash_entry *nhe);
321
322 /* Forward ref of dplane update context type */
323 struct zebra_dplane_ctx;
324 extern void zebra_nhg_dplane_result(struct zebra_dplane_ctx *ctx);
325
326
327 /* Sweet the nhg hash tables for old entries on restart */
328 extern void zebra_nhg_sweep_table(struct hash *hash);
329
330 /* Nexthop resolution processing */
331 struct route_entry; /* Forward ref to avoid circular includes */
332 extern int nexthop_active_update(struct route_node *rn, struct route_entry *re);
333
334 #ifdef __cplusplus
335 }
336 #endif
337
338 #endif /* __ZEBRA_NHG_H__ */