]>
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 | ||
26 | #include "zebra/rib.h" | |
69171da2 | 27 | #include "lib/nexthop_group.h" |
ad28e79a | 28 | |
5f3c9e52 SW |
29 | #include "zebra/zebra_dplane.h" |
30 | ||
0c8215cb SW |
31 | /* This struct is used exclusively for dataplane |
32 | * interaction via a dataplane context. | |
33 | * | |
34 | * It is designed to mimic the netlink nexthop_grp | |
35 | * struct in include/linux/nexthop.h | |
36 | */ | |
e22e8001 | 37 | struct nh_grp { |
0c8215cb SW |
38 | uint32_t id; |
39 | uint8_t weight; | |
40 | }; | |
41 | ||
37c6708b | 42 | PREDECL_RBTREE_UNIQ(nhg_connected_tree); |
0c8215cb | 43 | |
69171da2 | 44 | struct nhg_hash_entry { |
a95b8020 | 45 | uint32_t id; |
77b76fc9 | 46 | afi_t afi; |
69171da2 | 47 | vrf_id_t vrf_id; |
d9f5b2f5 | 48 | bool is_kernel_nh; |
69171da2 | 49 | |
8e401b25 | 50 | struct nexthop_group *nhg; |
69171da2 | 51 | |
2614bf87 SW |
52 | /* If this is not a group, it |
53 | * will be a single nexthop | |
54 | * and must have an interface | |
55 | * associated with it. | |
56 | * Otherwise, this will be null. | |
57 | */ | |
58 | struct interface *ifp; | |
59 | ||
69171da2 DS |
60 | uint32_t refcnt; |
61 | uint32_t dplane_ref; | |
c8ee3cdb DS |
62 | |
63 | uint32_t flags; | |
3119f6a1 | 64 | |
0c8215cb | 65 | /* Dependency tree for other entries. |
3119f6a1 SW |
66 | * For instance a group with two |
67 | * nexthops will have two dependencies | |
68 | * pointing to those nhg_hash_entries. | |
0c8215cb SW |
69 | * |
70 | * Using a rb tree here to make lookups | |
71 | * faster with ID's. | |
3119f6a1 | 72 | */ |
37c6708b | 73 | struct nhg_connected_tree_head nhg_depends, nhg_dependents; |
c8ee3cdb DS |
74 | /* |
75 | * Is this nexthop group valid, ie all nexthops are fully resolved. | |
76 | * What is fully resolved? It's a nexthop that is either self contained | |
77 | * and correct( ie no recursive pointer ) or a nexthop that is recursively | |
78 | * resolved and correct. | |
79 | */ | |
80 | #define NEXTHOP_GROUP_VALID 0x1 | |
81 | /* | |
82 | * Has this nexthop group been installed? At this point in time, this | |
83 | * means that the data-plane has been told about this nexthop group | |
84 | * and it's possible usage by a route entry. | |
85 | */ | |
86 | #define NEXTHOP_GROUP_INSTALLED 0x2 | |
7f6077d0 SW |
87 | /* |
88 | * Has the nexthop group been queued to be send to the FIB? | |
89 | * The NEXTHOP_GROUP_VALID flag should also be set by this point. | |
90 | */ | |
91 | #define NEXTHOP_GROUP_QUEUED 0x4 | |
98cda54a SW |
92 | /* |
93 | * Is this a nexthop that is recursively resolved? | |
94 | */ | |
95 | #define NEXTHOP_GROUP_RECURSIVE 0x8 | |
69171da2 DS |
96 | }; |
97 | ||
a15d4c00 SW |
98 | /* Abstraction for connected trees */ |
99 | struct nhg_connected { | |
37c6708b | 100 | struct nhg_connected_tree_item tree_item; |
3119f6a1 SW |
101 | struct nhg_hash_entry *nhe; |
102 | }; | |
103 | ||
37c6708b SW |
104 | static int nhg_connected_cmp(const struct nhg_connected *con1, |
105 | const struct nhg_connected *con2) | |
106 | { | |
107 | return (con1->nhe->id - con2->nhe->id); | |
108 | } | |
109 | ||
110 | DECLARE_RBTREE_UNIQ(nhg_connected_tree, struct nhg_connected, tree_item, | |
111 | nhg_connected_cmp); | |
3119f6a1 | 112 | |
e22e8001 SW |
113 | |
114 | enum nhg_ctx_op_e { | |
115 | NHG_CTX_OP_NONE = 0, | |
116 | NHG_CTX_OP_NEW, | |
117 | NHG_CTX_OP_DEL, | |
118 | }; | |
119 | ||
120 | enum nhg_ctx_result { | |
121 | NHG_CTX_NONE = 0, | |
122 | NHG_CTX_QUEUED, | |
123 | NHG_CTX_SUCCESS, | |
124 | NHG_CTX_FAILURE, | |
125 | }; | |
126 | ||
127 | /* | |
128 | * Context needed to queue nhg updates on the | |
129 | * work queue. | |
130 | */ | |
131 | struct nhg_ctx { | |
132 | ||
133 | /* Unique ID */ | |
134 | uint32_t id; | |
135 | ||
136 | vrf_id_t vrf_id; | |
137 | afi_t afi; | |
138 | bool is_kernel_nh; | |
139 | ||
140 | /* If its a group array, how many? */ | |
141 | uint8_t count; | |
142 | ||
143 | /* Its either a single nexthop or an array of ID's */ | |
144 | union { | |
145 | struct nexthop nh; | |
146 | struct nh_grp grp[MULTIPATH_NUM]; | |
147 | } u; | |
148 | ||
149 | enum nhg_ctx_op_e op; | |
150 | enum nhg_ctx_result status; | |
151 | }; | |
152 | ||
153 | ||
69171da2 DS |
154 | void zebra_nhg_init(void); |
155 | void zebra_nhg_terminate(void); | |
156 | ||
fe593b78 SW |
157 | extern void nhg_connected_free(struct nhg_connected *dep); |
158 | extern struct nhg_connected *nhg_connected_new(struct nhg_hash_entry *nhe); | |
159 | ||
160 | /* nhg connected tree direct access functions */ | |
37c6708b SW |
161 | extern void nhg_connected_tree_init(struct nhg_connected_tree_head *head); |
162 | extern void nhg_connected_tree_free(struct nhg_connected_tree_head *head); | |
163 | extern bool | |
164 | nhg_connected_tree_is_empty(const struct nhg_connected_tree_head *head); | |
98cda54a | 165 | extern struct nhg_connected * |
37c6708b SW |
166 | nhg_connected_tree_root(struct nhg_connected_tree_head *head); |
167 | extern void nhg_connected_tree_del_nhe(struct nhg_connected_tree_head *head, | |
168 | struct nhg_hash_entry *nhe); | |
169 | extern void nhg_connected_tree_add_nhe(struct nhg_connected_tree_head *head, | |
170 | struct nhg_hash_entry *nhe); | |
fe593b78 SW |
171 | |
172 | /** | |
173 | * NHE abstracted tree functions. | |
174 | * Use these where possible instead of the direct ones access ones. | |
175 | */ | |
98cda54a SW |
176 | |
177 | ||
178 | extern struct nhg_hash_entry *zebra_nhg_resolve(struct nhg_hash_entry *nhe); | |
179 | extern uint32_t zebra_nhg_get_resolved_id(uint32_t id); | |
180 | ||
fe593b78 SW |
181 | /* Depends */ |
182 | extern unsigned int zebra_nhg_depends_count(const struct nhg_hash_entry *nhe); | |
0c8215cb | 183 | extern bool zebra_nhg_depends_is_empty(const struct nhg_hash_entry *nhe); |
0c8215cb SW |
184 | extern void zebra_nhg_depends_del(struct nhg_hash_entry *from, |
185 | struct nhg_hash_entry *depend); | |
186 | extern void zebra_nhg_depends_add(struct nhg_hash_entry *to, | |
187 | struct nhg_hash_entry *depend); | |
0c8215cb | 188 | extern void zebra_nhg_depends_init(struct nhg_hash_entry *nhe); |
fe593b78 SW |
189 | /* Dependents */ |
190 | extern unsigned int | |
191 | zebra_nhg_dependents_count(const struct nhg_hash_entry *nhe); | |
192 | extern bool zebra_nhg_dependents_is_empty(const struct nhg_hash_entry *nhe); | |
193 | extern void zebra_nhg_dependents_del(struct nhg_hash_entry *from, | |
194 | struct nhg_hash_entry *dependent); | |
195 | extern void zebra_nhg_dependents_add(struct nhg_hash_entry *to, | |
196 | struct nhg_hash_entry *dependent); | |
197 | extern void zebra_nhg_dependents_init(struct nhg_hash_entry *nhe); | |
3119f6a1 | 198 | |
3119f6a1 | 199 | |
d9f5b2f5 SW |
200 | extern struct nhg_hash_entry *zebra_nhg_lookup_id(uint32_t id); |
201 | extern int zebra_nhg_insert_id(struct nhg_hash_entry *nhe); | |
202 | ||
69171da2 | 203 | extern uint32_t zebra_nhg_hash_key(const void *arg); |
a95b8020 | 204 | extern uint32_t zebra_nhg_id_key(const void *arg); |
69171da2 DS |
205 | |
206 | extern bool zebra_nhg_hash_equal(const void *arg1, const void *arg2); | |
d9f5b2f5 | 207 | extern bool zebra_nhg_hash_id_equal(const void *arg1, const void *arg2); |
69171da2 | 208 | |
e22e8001 SW |
209 | /* |
210 | * Process a context off of a queue. | |
211 | * Specifically this should be from | |
212 | * the rib meta queue. | |
213 | */ | |
214 | extern int nhg_ctx_process(struct nhg_ctx *ctx); | |
85f5e761 | 215 | |
e22e8001 SW |
216 | /* Find via kernel nh creation */ |
217 | extern int zebra_nhg_kernel_find(uint32_t id, struct nexthop *nh, | |
218 | struct nh_grp *grp, uint8_t count, | |
219 | vrf_id_t vrf_id, afi_t afi); | |
220 | ||
221 | /* Find via route creation */ | |
7f997721 SW |
222 | extern struct nhg_hash_entry * |
223 | zebra_nhg_rib_find(uint32_t id, struct nexthop_group *nhg, afi_t rt_afi); | |
3057df51 | 224 | |
0c8215cb | 225 | |
b599cd2a | 226 | void zebra_nhg_free_members(struct nhg_hash_entry *nhe); |
d9f5b2f5 | 227 | void zebra_nhg_free(void *arg); |
d9f5b2f5 | 228 | void zebra_nhg_decrement_ref(struct nhg_hash_entry *nhe); |
7fd392cc | 229 | void zebra_nhg_increment_ref(struct nhg_hash_entry *nhe); |
e22e8001 | 230 | |
fe593b78 SW |
231 | void zebra_nhg_set_invalid(struct nhg_hash_entry *nhe); |
232 | void zebra_nhg_set_if(struct nhg_hash_entry *nhe, struct interface *ifp); | |
8b5bdc8b SW |
233 | |
234 | extern int nexthop_active_update(struct route_node *rn, struct route_entry *re); | |
5be96a2d | 235 | |
144a1b34 SW |
236 | extern int zebra_nhg_re_update_ref(struct route_entry *re, |
237 | struct nhg_hash_entry *nhe); | |
238 | ||
98cda54a SW |
239 | extern uint8_t zebra_nhg_nhe2grp(struct nh_grp *grp, |
240 | struct nhg_hash_entry *nhe); | |
241 | ||
5be96a2d | 242 | void zebra_nhg_install_kernel(struct nhg_hash_entry *nhe); |
147bad16 SW |
243 | void zebra_nhg_uninstall_kernel(struct nhg_hash_entry *nhe); |
244 | ||
245 | void zebra_nhg_cleanup_tables(void); | |
5f3c9e52 | 246 | |
0c8215cb SW |
247 | /* Forward ref of dplane update context type */ |
248 | struct zebra_dplane_ctx; | |
5f3c9e52 | 249 | void zebra_nhg_dplane_result(struct zebra_dplane_ctx *ctx); |
ad28e79a | 250 | #endif |