]> git.proxmox.com Git - mirror_frr.git/blame - zebra/zebra_nhg.h
zebra: implement protocol NHG Add/Del
[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;
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 */
129struct nhg_backup_info {
130 struct nhg_hash_entry *nhe;
131};
e22e8001
SW
132
133enum nhg_ctx_op_e {
134 NHG_CTX_OP_NONE = 0,
135 NHG_CTX_OP_NEW,
136 NHG_CTX_OP_DEL,
137};
138
1b366e63 139enum 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 */
151struct 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 */
182void zebra_nhg_enable_kernel_nexthops(bool set);
183bool 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
189struct nhg_hash_entry *zebra_nhg_alloc(void);
190void zebra_nhg_free(struct nhg_hash_entry *nhe);
191/* In order to clear a generic hash, we need a generic api, sigh. */
192void 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 */
198void 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 */
204struct 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 */
208struct nhg_backup_info *zebra_nhg_backup_alloc(void);
209void zebra_nhg_backup_free(struct nhg_backup_info **p);
210
1d48702e
MS
211struct nexthop_group *zebra_nhg_get_backup_nhg(struct nhg_hash_entry *nhe);
212
98cda54a 213extern struct nhg_hash_entry *zebra_nhg_resolve(struct nhg_hash_entry *nhe);
98cda54a 214
fe593b78 215extern unsigned int zebra_nhg_depends_count(const struct nhg_hash_entry *nhe);
0c8215cb 216extern bool zebra_nhg_depends_is_empty(const struct nhg_hash_entry *nhe);
5948f013 217
fe593b78
SW
218extern unsigned int
219zebra_nhg_dependents_count(const struct nhg_hash_entry *nhe);
220extern bool zebra_nhg_dependents_is_empty(const struct nhg_hash_entry *nhe);
3119f6a1 221
5948f013 222/* Lookup ID, doesn't create */
d9f5b2f5 223extern struct nhg_hash_entry *zebra_nhg_lookup_id(uint32_t id);
d9f5b2f5 224
5948f013 225/* Hash functions */
69171da2 226extern uint32_t zebra_nhg_hash_key(const void *arg);
a95b8020 227extern uint32_t zebra_nhg_id_key(const void *arg);
69171da2
DS
228
229extern bool zebra_nhg_hash_equal(const void *arg1, const void *arg2);
d9f5b2f5 230extern 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 */
237extern int nhg_ctx_process(struct nhg_ctx *ctx);
85f5e761 238
e22e8001
SW
239/* Find via kernel nh creation */
240extern 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 245extern 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
248extern 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 */
253struct nhg_hash_entry *
254zebra_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 */
271struct 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 */
283struct 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 */
290struct nhg_hash_entry *
291zebra_nhg_proto_replace(uint32_t id, struct nexthop_group *nhg, afi_t afi);
292
5948f013
SW
293/* Reference counter functions */
294extern void zebra_nhg_decrement_ref(struct nhg_hash_entry *nhe);
295extern 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 */
298extern 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
301extern 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 */
305extern void zebra_nhg_install_kernel(struct nhg_hash_entry *nhe);
306extern void zebra_nhg_uninstall_kernel(struct nhg_hash_entry *nhe);
147bad16 307
0c8215cb
SW
308/* Forward ref of dplane update context type */
309struct zebra_dplane_ctx;
5948f013
SW
310extern 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 */
314extern void zebra_nhg_sweep_table(struct hash *hash);
315
316/* Nexthop resolution processing */
5463ce26 317struct route_entry; /* Forward ref to avoid circular includes */
5948f013 318extern 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__ */