]>
Commit | Line | Data |
---|---|---|
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 "lib/nexthop.h" | |
27 | #include "lib/nexthop_group.h" | |
28 | ||
29 | /* This struct is used exclusively for dataplane | |
30 | * interaction via a dataplane context. | |
31 | * | |
32 | * It is designed to mimic the netlink nexthop_grp | |
33 | * struct in include/linux/nexthop.h | |
34 | */ | |
35 | struct nh_grp { | |
36 | uint32_t id; | |
37 | uint8_t weight; | |
38 | }; | |
39 | ||
40 | PREDECL_RBTREE_UNIQ(nhg_connected_tree); | |
41 | ||
42 | /* | |
43 | * Hashtables contiaining entries found in `zebra_router`. | |
44 | */ | |
45 | ||
46 | struct nhg_hash_entry { | |
47 | uint32_t id; | |
48 | afi_t afi; | |
49 | vrf_id_t vrf_id; | |
50 | int type; | |
51 | ||
52 | struct nexthop_group *nhg; | |
53 | ||
54 | /* If this is not a group, it | |
55 | * will be a single nexthop | |
56 | * and must have an interface | |
57 | * associated with it. | |
58 | * Otherwise, this will be null. | |
59 | */ | |
60 | struct interface *ifp; | |
61 | ||
62 | uint32_t refcnt; | |
63 | uint32_t dplane_ref; | |
64 | ||
65 | uint32_t flags; | |
66 | ||
67 | /* Dependency tree for other entries. | |
68 | * For instance a group with two | |
69 | * nexthops will have two dependencies | |
70 | * pointing to those nhg_hash_entries. | |
71 | * | |
72 | * Using a rb tree here to make lookups | |
73 | * faster with ID's. | |
74 | */ | |
75 | struct nhg_connected_tree_head nhg_depends, nhg_dependents; | |
76 | /* | |
77 | * Is this nexthop group valid, ie all nexthops are fully resolved. | |
78 | * What is fully resolved? It's a nexthop that is either self contained | |
79 | * and correct( ie no recursive pointer ) or a nexthop that is recursively | |
80 | * resolved and correct. | |
81 | */ | |
82 | #define NEXTHOP_GROUP_VALID (1 << 0) | |
83 | /* | |
84 | * Has this nexthop group been installed? At this point in time, this | |
85 | * means that the data-plane has been told about this nexthop group | |
86 | * and it's possible usage by a route entry. | |
87 | */ | |
88 | #define NEXTHOP_GROUP_INSTALLED (1 << 1) | |
89 | /* | |
90 | * Has the nexthop group been queued to be send to the FIB? | |
91 | * The NEXTHOP_GROUP_VALID flag should also be set by this point. | |
92 | */ | |
93 | #define NEXTHOP_GROUP_QUEUED (1 << 2) | |
94 | /* | |
95 | * Is this a nexthop that is recursively resolved? | |
96 | */ | |
97 | #define NEXTHOP_GROUP_RECURSIVE (1 << 3) | |
98 | /* | |
99 | * This is a nexthop group we got from the kernel, it is identical to | |
100 | * one we already have. (The kernel allows duplicate nexthops, we don't | |
101 | * since we hash on them). We are only tracking it in our ID table, | |
102 | * it is unusable by our created routes but may be used by routes we get | |
103 | * from the kernel. Therefore, it is unhashable. | |
104 | */ | |
105 | #define NEXTHOP_GROUP_UNHASHABLE (1 << 4) | |
106 | }; | |
107 | ||
108 | /* Was this one we created, either this session or previously? */ | |
109 | #define ZEBRA_NHG_CREATED(NHE) ((NHE->type) == ZEBRA_ROUTE_NHG) | |
110 | ||
111 | ||
112 | enum nhg_ctx_op_e { | |
113 | NHG_CTX_OP_NONE = 0, | |
114 | NHG_CTX_OP_NEW, | |
115 | NHG_CTX_OP_DEL, | |
116 | }; | |
117 | ||
118 | enum nhg_ctx_status { | |
119 | NHG_CTX_NONE = 0, | |
120 | NHG_CTX_QUEUED, | |
121 | NHG_CTX_REQUEUED, | |
122 | NHG_CTX_SUCCESS, | |
123 | NHG_CTX_FAILURE, | |
124 | }; | |
125 | ||
126 | /* | |
127 | * Context needed to queue nhg updates on the | |
128 | * work queue. | |
129 | */ | |
130 | struct nhg_ctx { | |
131 | ||
132 | /* Unique ID */ | |
133 | uint32_t id; | |
134 | ||
135 | vrf_id_t vrf_id; | |
136 | afi_t afi; | |
137 | /* | |
138 | * This should only every be ZEBRA_ROUTE_NHG unless we get a a kernel | |
139 | * created nexthop not made by us. | |
140 | */ | |
141 | int type; | |
142 | ||
143 | /* If its a group array, how many? */ | |
144 | uint8_t count; | |
145 | ||
146 | /* Its either a single nexthop or an array of ID's */ | |
147 | union { | |
148 | struct nexthop nh; | |
149 | struct nh_grp grp[MULTIPATH_NUM]; | |
150 | } u; | |
151 | ||
152 | enum nhg_ctx_op_e op; | |
153 | enum nhg_ctx_status status; | |
154 | }; | |
155 | ||
156 | ||
157 | /** | |
158 | * NHE abstracted tree functions. | |
159 | * Use these where possible instead of the direct ones access ones. | |
160 | */ | |
161 | struct nhg_hash_entry *zebra_nhg_alloc(void); | |
162 | void zebra_nhg_free(struct nhg_hash_entry *nhe); | |
163 | /* In order to clear a generic hash, we need a generic api, sigh. */ | |
164 | void zebra_nhg_hash_free(void *p); | |
165 | ||
166 | extern struct nhg_hash_entry *zebra_nhg_resolve(struct nhg_hash_entry *nhe); | |
167 | ||
168 | extern unsigned int zebra_nhg_depends_count(const struct nhg_hash_entry *nhe); | |
169 | extern bool zebra_nhg_depends_is_empty(const struct nhg_hash_entry *nhe); | |
170 | ||
171 | extern unsigned int | |
172 | zebra_nhg_dependents_count(const struct nhg_hash_entry *nhe); | |
173 | extern bool zebra_nhg_dependents_is_empty(const struct nhg_hash_entry *nhe); | |
174 | ||
175 | /* Lookup ID, doesn't create */ | |
176 | extern struct nhg_hash_entry *zebra_nhg_lookup_id(uint32_t id); | |
177 | ||
178 | /* Hash functions */ | |
179 | extern uint32_t zebra_nhg_hash_key(const void *arg); | |
180 | extern uint32_t zebra_nhg_id_key(const void *arg); | |
181 | ||
182 | extern bool zebra_nhg_hash_equal(const void *arg1, const void *arg2); | |
183 | extern bool zebra_nhg_hash_id_equal(const void *arg1, const void *arg2); | |
184 | ||
185 | /* | |
186 | * Process a context off of a queue. | |
187 | * Specifically this should be from | |
188 | * the rib meta queue. | |
189 | */ | |
190 | extern int nhg_ctx_process(struct nhg_ctx *ctx); | |
191 | ||
192 | /* Find via kernel nh creation */ | |
193 | extern int zebra_nhg_kernel_find(uint32_t id, struct nexthop *nh, | |
194 | struct nh_grp *grp, uint8_t count, | |
195 | vrf_id_t vrf_id, afi_t afi, int type, | |
196 | int startup); | |
197 | /* Del via kernel */ | |
198 | extern int zebra_nhg_kernel_del(uint32_t id); | |
199 | ||
200 | /* Find via route creation */ | |
201 | extern struct nhg_hash_entry * | |
202 | zebra_nhg_rib_find(uint32_t id, struct nexthop_group *nhg, afi_t rt_afi); | |
203 | ||
204 | /* Reference counter functions */ | |
205 | extern void zebra_nhg_decrement_ref(struct nhg_hash_entry *nhe); | |
206 | extern void zebra_nhg_increment_ref(struct nhg_hash_entry *nhe); | |
207 | ||
208 | /* Check validity of nhe, if invalid will update dependents as well */ | |
209 | extern void zebra_nhg_check_valid(struct nhg_hash_entry *nhe); | |
210 | ||
211 | /* Convert nhe depends to a grp context that can be passed around safely */ | |
212 | extern uint8_t zebra_nhg_nhe2grp(struct nh_grp *grp, struct nhg_hash_entry *nhe, | |
213 | int size); | |
214 | ||
215 | /* Dataplane install/uninstall */ | |
216 | extern void zebra_nhg_install_kernel(struct nhg_hash_entry *nhe); | |
217 | extern void zebra_nhg_uninstall_kernel(struct nhg_hash_entry *nhe); | |
218 | ||
219 | /* Forward ref of dplane update context type */ | |
220 | struct zebra_dplane_ctx; | |
221 | extern void zebra_nhg_dplane_result(struct zebra_dplane_ctx *ctx); | |
222 | ||
223 | ||
224 | /* Sweet the nhg hash tables for old entries on restart */ | |
225 | extern void zebra_nhg_sweep_table(struct hash *hash); | |
226 | ||
227 | /* Nexthop resolution processing */ | |
228 | struct route_entry; /* Forward ref to avoid circular includes */ | |
229 | extern int nexthop_active_update(struct route_node *rn, struct route_entry *re); | |
230 | #endif |