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