]> git.proxmox.com Git - mirror_frr.git/blame - zebra/zebra_nhg.h
zebra: add PROTO_OWNED macro for NHE id bounds checking
[mirror_frr.git] / zebra / zebra_nhg.h
CommitLineData
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
30extern "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 39struct nh_grp {
0c8215cb
SW
40 uint32_t id;
41 uint8_t weight;
42};
43
37c6708b 44PREDECL_RBTREE_UNIQ(nhg_connected_tree);
0c8215cb 45
53ac1fbb 46/*
c415d895 47 * Hashtables containing nhg entries is in `zebra_router`.
53ac1fbb 48 */
69171da2 49struct nhg_hash_entry {
a95b8020 50 uint32_t id;
77b76fc9 51 afi_t afi;
69171da2 52 vrf_id_t vrf_id;
ee94437e
MS
53
54 /* Source protocol - zebra or another daemon */
38e40db1 55 int type;
69171da2 56
ee94437e
MS
57 /* zapi instance and session id, for groups from other daemons */
58 uint16_t zapi_instance;
59 uint32_t zapi_session;
60
c415d895 61 struct nexthop_group nhg;
69171da2 62
1d48702e
MS
63 /* If supported, a mapping of backup nexthops. */
64 struct nhg_backup_info *backup_info;
65
2614bf87
SW
66 /* If this is not a group, it
67 * will be a single nexthop
68 * and must have an interface
69 * associated with it.
70 * Otherwise, this will be null.
71 */
72 struct interface *ifp;
73
69171da2
DS
74 uint32_t refcnt;
75 uint32_t dplane_ref;
c8ee3cdb
DS
76
77 uint32_t flags;
3119f6a1 78
0c8215cb 79 /* Dependency tree for other entries.
3119f6a1
SW
80 * For instance a group with two
81 * nexthops will have two dependencies
82 * pointing to those nhg_hash_entries.
0c8215cb
SW
83 *
84 * Using a rb tree here to make lookups
85 * faster with ID's.
3119f6a1 86 */
37c6708b 87 struct nhg_connected_tree_head nhg_depends, nhg_dependents;
1d48702e 88
c8ee3cdb
DS
89/*
90 * Is this nexthop group valid, ie all nexthops are fully resolved.
91 * What is fully resolved? It's a nexthop that is either self contained
92 * and correct( ie no recursive pointer ) or a nexthop that is recursively
93 * resolved and correct.
94 */
38e40db1 95#define NEXTHOP_GROUP_VALID (1 << 0)
c8ee3cdb
DS
96/*
97 * Has this nexthop group been installed? At this point in time, this
98 * means that the data-plane has been told about this nexthop group
99 * and it's possible usage by a route entry.
100 */
38e40db1 101#define NEXTHOP_GROUP_INSTALLED (1 << 1)
7f6077d0
SW
102/*
103 * Has the nexthop group been queued to be send to the FIB?
104 * The NEXTHOP_GROUP_VALID flag should also be set by this point.
105 */
38e40db1 106#define NEXTHOP_GROUP_QUEUED (1 << 2)
98cda54a
SW
107/*
108 * Is this a nexthop that is recursively resolved?
109 */
38e40db1 110#define NEXTHOP_GROUP_RECURSIVE (1 << 3)
1d48702e
MS
111
112/*
113 * Backup nexthop support - identify groups that are backups for
114 * another group.
115 */
0885b1e3 116#define NEXTHOP_GROUP_BACKUP (1 << 4)
1d48702e 117
8155e8c5
SW
118/*
119 * The NHG has been release by an upper level protocol via the
120 * `zebra_nhg_proto_del()` API.
121 *
122 * We use this flag to track this state in case the NHG is still being used
123 * by routes therefore holding their refcnts as well. Otherwise, the NHG will
124 * be removed and uninstalled.
125 *
126 */
127#define NEXTHOP_GROUP_PROTO_RELEASED (1 << 5)
128
981ca597
RZ
129/*
130 * Track FPM installation status..
131 */
8155e8c5 132#define NEXTHOP_GROUP_FPM (1 << 6)
69171da2
DS
133};
134
4f9bb78e
AK
135/* Upper 4 bits of the NHG are reserved for indicating the NHG type */
136#define NHG_ID_TYPE_POS 28
137enum nhg_type {
138 NHG_TYPE_L3 = 0,
139 NHG_TYPE_L2_NH, /* NHs in a L2 NHG used as a MAC/FDB dest */
140 NHG_TYPE_L2, /* L2 NHG used as a MAC/FDB dest */
141};
142
38e40db1 143/* Was this one we created, either this session or previously? */
0885b1e3
SW
144#define ZEBRA_NHG_CREATED(NHE) \
145 (((NHE->type) <= ZEBRA_ROUTE_MAX) && (NHE->type != ZEBRA_ROUTE_KERNEL))
146
147/* Is this an NHE owned by zebra and not an upper level protocol? */
148#define ZEBRA_OWNED(NHE) (NHE->type == ZEBRA_ROUTE_NHG)
38e40db1 149
65f137fe
SW
150#define PROTO_OWNED(NHE) (NHE->id >= ZEBRA_NHG_PROTO_LOWER)
151
1d48702e
MS
152/*
153 * Backup nexthops: this is a group object itself, so
154 * that the backup nexthops can use the same code as a normal object.
155 */
156struct nhg_backup_info {
157 struct nhg_hash_entry *nhe;
158};
e22e8001
SW
159
160enum nhg_ctx_op_e {
161 NHG_CTX_OP_NONE = 0,
162 NHG_CTX_OP_NEW,
163 NHG_CTX_OP_DEL,
164};
165
1b366e63 166enum nhg_ctx_status {
e22e8001
SW
167 NHG_CTX_NONE = 0,
168 NHG_CTX_QUEUED,
1b366e63 169 NHG_CTX_REQUEUED,
e22e8001
SW
170 NHG_CTX_SUCCESS,
171 NHG_CTX_FAILURE,
172};
173
174/*
175 * Context needed to queue nhg updates on the
176 * work queue.
177 */
178struct nhg_ctx {
179
180 /* Unique ID */
181 uint32_t id;
182
183 vrf_id_t vrf_id;
184 afi_t afi;
9b4ab909 185
38e40db1 186 /*
9b4ab909 187 * This should only ever be ZEBRA_ROUTE_NHG unless we get a a kernel
38e40db1
SW
188 * created nexthop not made by us.
189 */
190 int type;
e22e8001
SW
191
192 /* If its a group array, how many? */
193 uint8_t count;
194
195 /* Its either a single nexthop or an array of ID's */
196 union {
197 struct nexthop nh;
198 struct nh_grp grp[MULTIPATH_NUM];
199 } u;
200
201 enum nhg_ctx_op_e op;
1b366e63 202 enum nhg_ctx_status status;
e22e8001
SW
203};
204
7c99d51b
MS
205/* Global control to disable use of kernel nexthops, if available. We can't
206 * force the kernel to support nexthop ids, of course, but we can disable
207 * zebra's use of them, for testing e.g. By default, if the kernel supports
208 * nexthop ids, zebra uses them.
209 */
210void zebra_nhg_enable_kernel_nexthops(bool set);
211bool zebra_nhg_kernel_nexthops_enabled(void);
e22e8001 212
6c67f41f
SW
213/* Global control for zebra to only use proto-owned nexthops */
214void zebra_nhg_set_proto_nexthops_only(bool set);
215bool zebra_nhg_proto_nexthops_only(void);
216
aa458838
MS
217/* Global control for use of activated backups for recursive resolution. */
218void zebra_nhg_set_recursive_use_backups(bool set);
219bool zebra_nhg_recursive_use_backups(void);
220
fe593b78
SW
221/**
222 * NHE abstracted tree functions.
1d48702e 223 * Use these where possible instead of direct access.
fe593b78 224 */
0eb97b86
MS
225struct nhg_hash_entry *zebra_nhg_alloc(void);
226void zebra_nhg_free(struct nhg_hash_entry *nhe);
227/* In order to clear a generic hash, we need a generic api, sigh. */
228void zebra_nhg_hash_free(void *p);
229
377e29f7
MS
230/* Init an nhe, for use in a hash lookup for example. There's some fuzziness
231 * if the nhe represents only a single nexthop, so we try to capture that
232 * variant also.
233 */
234void zebra_nhe_init(struct nhg_hash_entry *nhe, afi_t afi,
235 const struct nexthop *nh);
236
f727646a
MS
237/*
238 * Shallow copy of 'orig', into new/allocated nhe.
239 */
240struct nhg_hash_entry *zebra_nhe_copy(const struct nhg_hash_entry *orig,
241 uint32_t id);
242
1d48702e
MS
243/* Allocate, free backup nexthop info objects */
244struct nhg_backup_info *zebra_nhg_backup_alloc(void);
245void zebra_nhg_backup_free(struct nhg_backup_info **p);
246
1d48702e
MS
247struct nexthop_group *zebra_nhg_get_backup_nhg(struct nhg_hash_entry *nhe);
248
98cda54a 249extern struct nhg_hash_entry *zebra_nhg_resolve(struct nhg_hash_entry *nhe);
98cda54a 250
fe593b78 251extern unsigned int zebra_nhg_depends_count(const struct nhg_hash_entry *nhe);
0c8215cb 252extern bool zebra_nhg_depends_is_empty(const struct nhg_hash_entry *nhe);
5948f013 253
fe593b78
SW
254extern unsigned int
255zebra_nhg_dependents_count(const struct nhg_hash_entry *nhe);
256extern bool zebra_nhg_dependents_is_empty(const struct nhg_hash_entry *nhe);
3119f6a1 257
5948f013 258/* Lookup ID, doesn't create */
d9f5b2f5 259extern struct nhg_hash_entry *zebra_nhg_lookup_id(uint32_t id);
d9f5b2f5 260
5948f013 261/* Hash functions */
69171da2 262extern uint32_t zebra_nhg_hash_key(const void *arg);
a95b8020 263extern uint32_t zebra_nhg_id_key(const void *arg);
69171da2
DS
264
265extern bool zebra_nhg_hash_equal(const void *arg1, const void *arg2);
d9f5b2f5 266extern bool zebra_nhg_hash_id_equal(const void *arg1, const void *arg2);
69171da2 267
e22e8001
SW
268/*
269 * Process a context off of a queue.
270 * Specifically this should be from
271 * the rib meta queue.
272 */
273extern int nhg_ctx_process(struct nhg_ctx *ctx);
85f5e761 274
e22e8001
SW
275/* Find via kernel nh creation */
276extern int zebra_nhg_kernel_find(uint32_t id, struct nexthop *nh,
277 struct nh_grp *grp, uint8_t count,
38e40db1
SW
278 vrf_id_t vrf_id, afi_t afi, int type,
279 int startup);
9a1588c4 280/* Del via kernel */
88cafda7 281extern int zebra_nhg_kernel_del(uint32_t id, vrf_id_t vrf_id);
e22e8001 282
377e29f7 283/* Find an nhe based on a nexthop_group */
0885b1e3
SW
284extern struct nhg_hash_entry *zebra_nhg_rib_find(uint32_t id,
285 struct nexthop_group *nhg,
286 afi_t rt_afi, int type);
3057df51 287
377e29f7
MS
288/* Find an nhe based on a route's nhe, used during route creation */
289struct nhg_hash_entry *
290zebra_nhg_rib_find_nhe(struct nhg_hash_entry *rt_nhe, afi_t rt_afi);
291
0885b1e3
SW
292
293/**
294 * Functions for Add/Del/Replace via protocol NHG creation.
295 *
296 * The NHEs will not be hashed. They will only be present in the
297 * ID table and therefore not sharable.
298 *
299 * It is the owning protocols job to manage these.
300 */
301
302/*
2d8a9c54 303 * Add NHE. If already exists, Replace.
0885b1e3
SW
304 *
305 * Returns allocated NHE on success, otherwise NULL.
306 */
307struct nhg_hash_entry *zebra_nhg_proto_add(uint32_t id, int type,
ee94437e 308 uint16_t instance, uint32_t session,
0885b1e3
SW
309 struct nexthop_group *nhg,
310 afi_t afi);
311
0885b1e3
SW
312/*
313 * Del NHE.
314 *
315 * Returns deleted NHE on success, otherwise NULL.
316 *
1f655680 317 * Caller must decrement ref with zebra_nhg_decrement_ref() when done.
0885b1e3 318 */
aaa42e05 319struct nhg_hash_entry *zebra_nhg_proto_del(uint32_t id, int type);
0885b1e3 320
24db1a7b
SW
321/*
322 * Remove specific by proto NHGs.
323 *
324 * Called after client disconnect.
325 *
326 */
327unsigned long zebra_nhg_score_proto(int type);
328
5948f013
SW
329/* Reference counter functions */
330extern void zebra_nhg_decrement_ref(struct nhg_hash_entry *nhe);
331extern void zebra_nhg_increment_ref(struct nhg_hash_entry *nhe);
144a1b34 332
5948f013
SW
333/* Check validity of nhe, if invalid will update dependents as well */
334extern void zebra_nhg_check_valid(struct nhg_hash_entry *nhe);
335
336/* Convert nhe depends to a grp context that can be passed around safely */
8dbc800f
SW
337extern uint8_t zebra_nhg_nhe2grp(struct nh_grp *grp, struct nhg_hash_entry *nhe,
338 int size);
98cda54a 339
5948f013
SW
340/* Dataplane install/uninstall */
341extern void zebra_nhg_install_kernel(struct nhg_hash_entry *nhe);
342extern void zebra_nhg_uninstall_kernel(struct nhg_hash_entry *nhe);
147bad16 343
0c8215cb
SW
344/* Forward ref of dplane update context type */
345struct zebra_dplane_ctx;
5948f013
SW
346extern void zebra_nhg_dplane_result(struct zebra_dplane_ctx *ctx);
347
38e40db1 348
b1b07ef5 349/* Sweep the nhg hash tables for old entries on restart */
5948f013
SW
350extern void zebra_nhg_sweep_table(struct hash *hash);
351
b1b07ef5
DS
352/*
353 * We are shutting down but the nexthops should be kept
354 * as that -r has been specified and we don't want to delete
355 * the routes unintentionally
356 */
357extern void zebra_nhg_mark_keep(void);
358
5948f013 359/* Nexthop resolution processing */
5463ce26 360struct route_entry; /* Forward ref to avoid circular includes */
5948f013 361extern int nexthop_active_update(struct route_node *rn, struct route_entry *re);
7c99d51b 362
17e38209
RW
363#ifdef __cplusplus
364}
365#endif
366
7c99d51b 367#endif /* __ZEBRA_NHG_H__ */