]>
Commit | Line | Data |
---|---|---|
ad28e79a SW |
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 | ||
5463ce26 | 26 | #include "lib/nexthop.h" |
69171da2 | 27 | #include "lib/nexthop_group.h" |
ad28e79a | 28 | |
17e38209 RW |
29 | #ifdef __cplusplus |
30 | extern "C" { | |
31 | #endif | |
32 | ||
0c8215cb SW |
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 | */ | |
e22e8001 | 39 | struct nh_grp { |
0c8215cb SW |
40 | uint32_t id; |
41 | uint8_t weight; | |
42 | }; | |
43 | ||
37c6708b | 44 | PREDECL_RBTREE_UNIQ(nhg_connected_tree); |
0c8215cb | 45 | |
53ac1fbb | 46 | /* |
c415d895 | 47 | * Hashtables containing nhg entries is in `zebra_router`. |
53ac1fbb | 48 | */ |
69171da2 | 49 | struct nhg_hash_entry { |
a95b8020 | 50 | uint32_t id; |
77b76fc9 | 51 | afi_t afi; |
69171da2 | 52 | vrf_id_t vrf_id; |
38e40db1 | 53 | int type; |
69171da2 | 54 | |
c415d895 | 55 | struct nexthop_group nhg; |
69171da2 | 56 | |
1d48702e MS |
57 | /* If supported, a mapping of backup nexthops. */ |
58 | struct nhg_backup_info *backup_info; | |
59 | ||
2614bf87 SW |
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 | ||
69171da2 DS |
68 | uint32_t refcnt; |
69 | uint32_t dplane_ref; | |
c8ee3cdb DS |
70 | |
71 | uint32_t flags; | |
3119f6a1 | 72 | |
0c8215cb | 73 | /* Dependency tree for other entries. |
3119f6a1 SW |
74 | * For instance a group with two |
75 | * nexthops will have two dependencies | |
76 | * pointing to those nhg_hash_entries. | |
0c8215cb SW |
77 | * |
78 | * Using a rb tree here to make lookups | |
79 | * faster with ID's. | |
3119f6a1 | 80 | */ |
37c6708b | 81 | struct nhg_connected_tree_head nhg_depends, nhg_dependents; |
1d48702e | 82 | |
c8ee3cdb DS |
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 | */ | |
38e40db1 | 89 | #define NEXTHOP_GROUP_VALID (1 << 0) |
c8ee3cdb DS |
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 | */ | |
38e40db1 | 95 | #define NEXTHOP_GROUP_INSTALLED (1 << 1) |
7f6077d0 SW |
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 | */ | |
38e40db1 | 100 | #define NEXTHOP_GROUP_QUEUED (1 << 2) |
98cda54a SW |
101 | /* |
102 | * Is this a nexthop that is recursively resolved? | |
103 | */ | |
38e40db1 | 104 | #define NEXTHOP_GROUP_RECURSIVE (1 << 3) |
1d48702e MS |
105 | |
106 | /* | |
107 | * Backup nexthop support - identify groups that are backups for | |
108 | * another group. | |
109 | */ | |
0885b1e3 | 110 | #define NEXTHOP_GROUP_BACKUP (1 << 4) |
1d48702e | 111 | |
981ca597 RZ |
112 | /* |
113 | * Track FPM installation status.. | |
114 | */ | |
0885b1e3 | 115 | #define NEXTHOP_GROUP_FPM (1 << 5) |
69171da2 DS |
116 | }; |
117 | ||
38e40db1 | 118 | /* Was this one we created, either this session or previously? */ |
0885b1e3 SW |
119 | #define ZEBRA_NHG_CREATED(NHE) \ |
120 | (((NHE->type) <= ZEBRA_ROUTE_MAX) && (NHE->type != ZEBRA_ROUTE_KERNEL)) | |
121 | ||
122 | /* Is this an NHE owned by zebra and not an upper level protocol? */ | |
123 | #define ZEBRA_OWNED(NHE) (NHE->type == ZEBRA_ROUTE_NHG) | |
38e40db1 | 124 | |
1d48702e MS |
125 | /* |
126 | * Backup nexthops: this is a group object itself, so | |
127 | * that the backup nexthops can use the same code as a normal object. | |
128 | */ | |
129 | struct nhg_backup_info { | |
130 | struct nhg_hash_entry *nhe; | |
131 | }; | |
e22e8001 SW |
132 | |
133 | enum nhg_ctx_op_e { | |
134 | NHG_CTX_OP_NONE = 0, | |
135 | NHG_CTX_OP_NEW, | |
136 | NHG_CTX_OP_DEL, | |
137 | }; | |
138 | ||
1b366e63 | 139 | enum nhg_ctx_status { |
e22e8001 SW |
140 | NHG_CTX_NONE = 0, |
141 | NHG_CTX_QUEUED, | |
1b366e63 | 142 | NHG_CTX_REQUEUED, |
e22e8001 SW |
143 | NHG_CTX_SUCCESS, |
144 | NHG_CTX_FAILURE, | |
145 | }; | |
146 | ||
147 | /* | |
148 | * Context needed to queue nhg updates on the | |
149 | * work queue. | |
150 | */ | |
151 | struct nhg_ctx { | |
152 | ||
153 | /* Unique ID */ | |
154 | uint32_t id; | |
155 | ||
156 | vrf_id_t vrf_id; | |
157 | afi_t afi; | |
38e40db1 SW |
158 | /* |
159 | * This should only every be ZEBRA_ROUTE_NHG unless we get a a kernel | |
160 | * created nexthop not made by us. | |
161 | */ | |
162 | int type; | |
e22e8001 SW |
163 | |
164 | /* If its a group array, how many? */ | |
165 | uint8_t count; | |
166 | ||
167 | /* Its either a single nexthop or an array of ID's */ | |
168 | union { | |
169 | struct nexthop nh; | |
170 | struct nh_grp grp[MULTIPATH_NUM]; | |
171 | } u; | |
172 | ||
173 | enum nhg_ctx_op_e op; | |
1b366e63 | 174 | enum nhg_ctx_status status; |
e22e8001 SW |
175 | }; |
176 | ||
7c99d51b MS |
177 | /* Global control to disable use of kernel nexthops, if available. We can't |
178 | * force the kernel to support nexthop ids, of course, but we can disable | |
179 | * zebra's use of them, for testing e.g. By default, if the kernel supports | |
180 | * nexthop ids, zebra uses them. | |
181 | */ | |
182 | void zebra_nhg_enable_kernel_nexthops(bool set); | |
183 | bool zebra_nhg_kernel_nexthops_enabled(void); | |
e22e8001 | 184 | |
fe593b78 SW |
185 | /** |
186 | * NHE abstracted tree functions. | |
1d48702e | 187 | * Use these where possible instead of direct access. |
fe593b78 | 188 | */ |
0eb97b86 MS |
189 | struct nhg_hash_entry *zebra_nhg_alloc(void); |
190 | void zebra_nhg_free(struct nhg_hash_entry *nhe); | |
191 | /* In order to clear a generic hash, we need a generic api, sigh. */ | |
192 | void zebra_nhg_hash_free(void *p); | |
193 | ||
377e29f7 MS |
194 | /* Init an nhe, for use in a hash lookup for example. There's some fuzziness |
195 | * if the nhe represents only a single nexthop, so we try to capture that | |
196 | * variant also. | |
197 | */ | |
198 | void zebra_nhe_init(struct nhg_hash_entry *nhe, afi_t afi, | |
199 | const struct nexthop *nh); | |
200 | ||
f727646a MS |
201 | /* |
202 | * Shallow copy of 'orig', into new/allocated nhe. | |
203 | */ | |
204 | struct nhg_hash_entry *zebra_nhe_copy(const struct nhg_hash_entry *orig, | |
205 | uint32_t id); | |
206 | ||
1d48702e MS |
207 | /* Allocate, free backup nexthop info objects */ |
208 | struct nhg_backup_info *zebra_nhg_backup_alloc(void); | |
209 | void zebra_nhg_backup_free(struct nhg_backup_info **p); | |
210 | ||
1d48702e MS |
211 | struct nexthop_group *zebra_nhg_get_backup_nhg(struct nhg_hash_entry *nhe); |
212 | ||
98cda54a | 213 | extern struct nhg_hash_entry *zebra_nhg_resolve(struct nhg_hash_entry *nhe); |
98cda54a | 214 | |
fe593b78 | 215 | extern unsigned int zebra_nhg_depends_count(const struct nhg_hash_entry *nhe); |
0c8215cb | 216 | extern bool zebra_nhg_depends_is_empty(const struct nhg_hash_entry *nhe); |
5948f013 | 217 | |
fe593b78 SW |
218 | extern unsigned int |
219 | zebra_nhg_dependents_count(const struct nhg_hash_entry *nhe); | |
220 | extern bool zebra_nhg_dependents_is_empty(const struct nhg_hash_entry *nhe); | |
3119f6a1 | 221 | |
5948f013 | 222 | /* Lookup ID, doesn't create */ |
d9f5b2f5 | 223 | extern struct nhg_hash_entry *zebra_nhg_lookup_id(uint32_t id); |
d9f5b2f5 | 224 | |
5948f013 | 225 | /* Hash functions */ |
69171da2 | 226 | extern uint32_t zebra_nhg_hash_key(const void *arg); |
a95b8020 | 227 | extern uint32_t zebra_nhg_id_key(const void *arg); |
69171da2 DS |
228 | |
229 | extern bool zebra_nhg_hash_equal(const void *arg1, const void *arg2); | |
d9f5b2f5 | 230 | extern bool zebra_nhg_hash_id_equal(const void *arg1, const void *arg2); |
69171da2 | 231 | |
e22e8001 SW |
232 | /* |
233 | * Process a context off of a queue. | |
234 | * Specifically this should be from | |
235 | * the rib meta queue. | |
236 | */ | |
237 | extern int nhg_ctx_process(struct nhg_ctx *ctx); | |
85f5e761 | 238 | |
e22e8001 SW |
239 | /* Find via kernel nh creation */ |
240 | extern int zebra_nhg_kernel_find(uint32_t id, struct nexthop *nh, | |
241 | struct nh_grp *grp, uint8_t count, | |
38e40db1 SW |
242 | vrf_id_t vrf_id, afi_t afi, int type, |
243 | int startup); | |
9a1588c4 | 244 | /* Del via kernel */ |
88cafda7 | 245 | extern int zebra_nhg_kernel_del(uint32_t id, vrf_id_t vrf_id); |
e22e8001 | 246 | |
377e29f7 | 247 | /* Find an nhe based on a nexthop_group */ |
0885b1e3 SW |
248 | extern struct nhg_hash_entry *zebra_nhg_rib_find(uint32_t id, |
249 | struct nexthop_group *nhg, | |
250 | afi_t rt_afi, int type); | |
3057df51 | 251 | |
377e29f7 MS |
252 | /* Find an nhe based on a route's nhe, used during route creation */ |
253 | struct nhg_hash_entry * | |
254 | zebra_nhg_rib_find_nhe(struct nhg_hash_entry *rt_nhe, afi_t rt_afi); | |
255 | ||
0885b1e3 SW |
256 | |
257 | /** | |
258 | * Functions for Add/Del/Replace via protocol NHG creation. | |
259 | * | |
260 | * The NHEs will not be hashed. They will only be present in the | |
261 | * ID table and therefore not sharable. | |
262 | * | |
263 | * It is the owning protocols job to manage these. | |
264 | */ | |
265 | ||
266 | /* | |
267 | * Add NHE. | |
268 | * | |
269 | * Returns allocated NHE on success, otherwise NULL. | |
270 | */ | |
271 | struct nhg_hash_entry *zebra_nhg_proto_add(uint32_t id, int type, | |
272 | struct nexthop_group *nhg, | |
273 | afi_t afi); | |
274 | ||
275 | ||
276 | /* | |
277 | * Del NHE. | |
278 | * | |
279 | * Returns deleted NHE on success, otherwise NULL. | |
280 | * | |
281 | * Caller must free the NHE. | |
282 | */ | |
283 | struct nhg_hash_entry *zebra_nhg_proto_del(uint32_t id); | |
284 | ||
285 | /* | |
286 | * Replace NHE. | |
287 | * | |
288 | * Returns new NHE on success, otherwise NULL. | |
289 | */ | |
290 | struct nhg_hash_entry * | |
291 | zebra_nhg_proto_replace(uint32_t id, struct nexthop_group *nhg, afi_t afi); | |
292 | ||
5948f013 SW |
293 | /* Reference counter functions */ |
294 | extern void zebra_nhg_decrement_ref(struct nhg_hash_entry *nhe); | |
295 | extern void zebra_nhg_increment_ref(struct nhg_hash_entry *nhe); | |
144a1b34 | 296 | |
5948f013 SW |
297 | /* Check validity of nhe, if invalid will update dependents as well */ |
298 | extern void zebra_nhg_check_valid(struct nhg_hash_entry *nhe); | |
299 | ||
300 | /* Convert nhe depends to a grp context that can be passed around safely */ | |
8dbc800f SW |
301 | extern uint8_t zebra_nhg_nhe2grp(struct nh_grp *grp, struct nhg_hash_entry *nhe, |
302 | int size); | |
98cda54a | 303 | |
5948f013 SW |
304 | /* Dataplane install/uninstall */ |
305 | extern void zebra_nhg_install_kernel(struct nhg_hash_entry *nhe); | |
306 | extern void zebra_nhg_uninstall_kernel(struct nhg_hash_entry *nhe); | |
147bad16 | 307 | |
0c8215cb SW |
308 | /* Forward ref of dplane update context type */ |
309 | struct zebra_dplane_ctx; | |
5948f013 SW |
310 | extern void zebra_nhg_dplane_result(struct zebra_dplane_ctx *ctx); |
311 | ||
38e40db1 | 312 | |
5948f013 SW |
313 | /* Sweet the nhg hash tables for old entries on restart */ |
314 | extern void zebra_nhg_sweep_table(struct hash *hash); | |
315 | ||
316 | /* Nexthop resolution processing */ | |
5463ce26 | 317 | struct route_entry; /* Forward ref to avoid circular includes */ |
5948f013 | 318 | extern int nexthop_active_update(struct route_node *rn, struct route_entry *re); |
7c99d51b | 319 | |
17e38209 RW |
320 | #ifdef __cplusplus |
321 | } | |
322 | #endif | |
323 | ||
7c99d51b | 324 | #endif /* __ZEBRA_NHG_H__ */ |