]>
Commit | Line | Data |
---|---|---|
ea1c14f6 MS |
1 | /* |
2 | * Zebra dataplane layer api interfaces. | |
3 | * Copyright (c) 2018 Volta Networks, Inc. | |
4 | * | |
5 | * This program is free software; you can redistribute it and/or modify | |
6 | * it under the terms of the GNU General Public License as published by | |
7 | * the Free Software Foundation; either version 2 of the License, or | |
8 | * (at your option) any later version. | |
9 | * | |
10 | * This program is distributed in the hope that it will be useful, but | |
11 | * WITHOUT ANY WARRANTY; without even the implied warranty of | |
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
13 | * General Public License for more details. | |
14 | * | |
15 | * You should have received a copy of the GNU General Public License along | |
16 | * with this program; see the file COPYING; if not, write to the Free Software | |
17 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | |
18 | */ | |
19 | ||
20 | #ifndef _ZEBRA_DPLANE_H | |
21 | #define _ZEBRA_DPLANE_H 1 | |
22 | ||
7cdb1a84 MS |
23 | #include "lib/zebra.h" |
24 | #include "lib/prefix.h" | |
25 | #include "lib/nexthop.h" | |
26 | #include "lib/nexthop_group.h" | |
27 | #include "lib/openbsd-queue.h" | |
28 | #include "zebra/zebra_ns.h" | |
29 | #include "zebra/rib.h" | |
30 | #include "zebra/zserv.h" | |
ea1c14f6 MS |
31 | |
32 | ||
85a75f1e MS |
33 | /* Key netlink info from zebra ns */ |
34 | struct zebra_dplane_info { | |
35 | ns_id_t ns_id; | |
36 | ||
37 | #if defined(HAVE_NETLINK) | |
7cdb1a84 | 38 | struct nlsock nls; |
85a75f1e MS |
39 | bool is_cmd; |
40 | #endif | |
41 | }; | |
42 | ||
43 | /* Utility to fill in zns info from main zns struct */ | |
44 | static inline void | |
45 | zebra_dplane_info_from_zns(struct zebra_dplane_info *zns_info, | |
46 | const struct zebra_ns *zns, bool is_cmd) | |
47 | { | |
48 | zns_info->ns_id = zns->ns_id; | |
49 | ||
50 | #if defined(HAVE_NETLINK) | |
51 | zns_info->is_cmd = is_cmd; | |
52 | if (is_cmd) { | |
7cdb1a84 | 53 | zns_info->nls = zns->netlink_cmd; |
85a75f1e | 54 | } else { |
7cdb1a84 | 55 | zns_info->nls = zns->netlink; |
85a75f1e MS |
56 | } |
57 | #endif /* NETLINK */ | |
58 | } | |
59 | ||
ea1c14f6 MS |
60 | /* |
61 | * Result codes used when returning status back to the main zebra context. | |
62 | */ | |
63 | ||
64 | /* | |
65 | * Philosophy Note: | |
66 | * | |
67 | * Flags being SET/UNSET do not belong in the South Bound | |
68 | * Interface. This Setting belongs at the calling level | |
69 | * because we can and will have multiple different interfaces | |
70 | * and we will have potentially multiple different | |
71 | * modules/filters to call. As such Setting/Unsetting | |
72 | * success failure should be handled by the caller. | |
73 | */ | |
74 | enum zebra_dplane_status { | |
75 | ZEBRA_DPLANE_STATUS_NONE = 0, | |
76 | ZEBRA_DPLANE_INSTALL_SUCCESS, | |
77 | ZEBRA_DPLANE_INSTALL_FAILURE, | |
78 | ZEBRA_DPLANE_DELETE_SUCCESS, | |
79 | ZEBRA_DPLANE_DELETE_FAILURE, | |
80 | ||
81 | }; | |
82 | ||
83 | enum zebra_dplane_result { | |
84 | ZEBRA_DPLANE_REQUEST_QUEUED, | |
85 | ZEBRA_DPLANE_REQUEST_SUCCESS, | |
86 | ZEBRA_DPLANE_REQUEST_FAILURE, | |
87 | }; | |
88 | ||
7cdb1a84 MS |
89 | /* |
90 | * API between the zebra dataplane system and the main zebra processing | |
91 | * context. | |
92 | */ | |
93 | ||
94 | /* | |
95 | * Enqueue a route install or update for the dataplane. | |
96 | */ | |
5709131c | 97 | enum dplane_op_e { |
7cdb1a84 MS |
98 | DPLANE_OP_NONE = 0, |
99 | ||
100 | /* Route update */ | |
101 | DPLANE_OP_ROUTE_INSTALL, | |
102 | DPLANE_OP_ROUTE_UPDATE, | |
103 | DPLANE_OP_ROUTE_DELETE, | |
104 | ||
5709131c | 105 | }; |
7cdb1a84 | 106 | |
7cdb1a84 | 107 | /* |
25779064 | 108 | * The dataplane context struct is used to exchange info between the main zebra |
7cdb1a84 MS |
109 | * context and the dataplane module(s). If these are two independent pthreads, |
110 | * they cannot share existing global data structures safely. | |
111 | */ | |
7cdb1a84 MS |
112 | |
113 | /* Define a tailq list type for context blocks. The list is exposed/public, | |
114 | * but the internal linkage in the context struct is private, so there | |
115 | * are accessor apis that support enqueue and dequeue. | |
116 | */ | |
25779064 | 117 | TAILQ_HEAD(dplane_ctx_q, zebra_dplane_ctx); |
7cdb1a84 | 118 | |
7cdb1a84 MS |
119 | /* Return a dataplane results context block after use; the caller's pointer will |
120 | * be cleared. | |
121 | */ | |
25779064 | 122 | void dplane_ctx_fini(struct zebra_dplane_ctx **pctx); |
7cdb1a84 MS |
123 | |
124 | /* Enqueue a context block to caller's tailq. This just exists so that the | |
125 | * context struct can remain opaque. | |
126 | */ | |
25779064 MS |
127 | void dplane_ctx_enqueue_tail(struct dplane_ctx_q *q, |
128 | const struct zebra_dplane_ctx *ctx); | |
7cdb1a84 MS |
129 | |
130 | /* Dequeue a context block from the head of caller's tailq */ | |
25779064 | 131 | void dplane_ctx_dequeue(struct dplane_ctx_q *q, struct zebra_dplane_ctx **ctxp); |
7cdb1a84 MS |
132 | |
133 | /* | |
134 | * Accessors for information from the context object | |
135 | */ | |
25779064 MS |
136 | enum zebra_dplane_result dplane_ctx_get_status( |
137 | const struct zebra_dplane_ctx *ctx); | |
f183e380 | 138 | const char *dplane_res2str(enum zebra_dplane_result res); |
7cdb1a84 | 139 | |
25779064 | 140 | enum dplane_op_e dplane_ctx_get_op(const struct zebra_dplane_ctx *ctx); |
5709131c | 141 | const char *dplane_op2str(enum dplane_op_e op); |
7cdb1a84 | 142 | |
25779064 | 143 | const struct prefix *dplane_ctx_get_dest(const struct zebra_dplane_ctx *ctx); |
7cdb1a84 | 144 | |
5709131c MS |
145 | /* Source prefix is a little special - use convention to return NULL |
146 | * to mean "no src prefix" | |
7cdb1a84 | 147 | */ |
25779064 MS |
148 | const struct prefix *dplane_ctx_get_src(const struct zebra_dplane_ctx *ctx); |
149 | ||
150 | bool dplane_ctx_is_update(const struct zebra_dplane_ctx *ctx); | |
151 | uint32_t dplane_ctx_get_seq(const struct zebra_dplane_ctx *ctx); | |
152 | uint32_t dplane_ctx_get_old_seq(const struct zebra_dplane_ctx *ctx); | |
153 | vrf_id_t dplane_ctx_get_vrf(const struct zebra_dplane_ctx *ctx); | |
154 | int dplane_ctx_get_type(const struct zebra_dplane_ctx *ctx); | |
155 | int dplane_ctx_get_old_type(const struct zebra_dplane_ctx *ctx); | |
156 | afi_t dplane_ctx_get_afi(const struct zebra_dplane_ctx *ctx); | |
157 | safi_t dplane_ctx_get_safi(const struct zebra_dplane_ctx *ctx); | |
158 | uint32_t dplane_ctx_get_table(const struct zebra_dplane_ctx *ctx); | |
159 | route_tag_t dplane_ctx_get_tag(const struct zebra_dplane_ctx *ctx); | |
160 | route_tag_t dplane_ctx_get_old_tag(const struct zebra_dplane_ctx *ctx); | |
161 | uint16_t dplane_ctx_get_instance(const struct zebra_dplane_ctx *ctx); | |
162 | uint16_t dplane_ctx_get_old_instance(const struct zebra_dplane_ctx *ctx); | |
163 | uint32_t dplane_ctx_get_metric(const struct zebra_dplane_ctx *ctx); | |
164 | uint32_t dplane_ctx_get_old_metric(const struct zebra_dplane_ctx *ctx); | |
165 | uint32_t dplane_ctx_get_mtu(const struct zebra_dplane_ctx *ctx); | |
166 | uint32_t dplane_ctx_get_nh_mtu(const struct zebra_dplane_ctx *ctx); | |
167 | uint8_t dplane_ctx_get_distance(const struct zebra_dplane_ctx *ctx); | |
168 | uint8_t dplane_ctx_get_old_distance(const struct zebra_dplane_ctx *ctx); | |
169 | ||
170 | const struct nexthop_group *dplane_ctx_get_ng( | |
171 | const struct zebra_dplane_ctx *ctx); | |
172 | const struct nexthop_group *dplane_ctx_get_old_ng( | |
173 | const struct zebra_dplane_ctx *ctx); | |
174 | ||
175 | const struct zebra_dplane_info *dplane_ctx_get_ns( | |
176 | const struct zebra_dplane_ctx *ctx); | |
7cdb1a84 | 177 | |
4dfd7a02 MS |
178 | /* Indicates zebra shutdown/exit is in progress. Some operations may be |
179 | * simplified or skipped during shutdown processing. | |
180 | */ | |
181 | bool dplane_is_in_shutdown(void); | |
182 | ||
7cdb1a84 MS |
183 | /* |
184 | * Enqueue route change operations for the dataplane. | |
185 | */ | |
655d681a MS |
186 | enum zebra_dplane_result dplane_route_add(struct route_node *rn, |
187 | struct route_entry *re); | |
7cdb1a84 | 188 | |
655d681a MS |
189 | enum zebra_dplane_result dplane_route_update(struct route_node *rn, |
190 | struct route_entry *re, | |
191 | struct route_entry *old_re); | |
7cdb1a84 | 192 | |
655d681a MS |
193 | enum zebra_dplane_result dplane_route_delete(struct route_node *rn, |
194 | struct route_entry *re); | |
7cdb1a84 | 195 | |
91f16812 MS |
196 | /* Retrieve the limit on the number of pending, unprocessed updates. */ |
197 | uint32_t dplane_get_in_queue_limit(void); | |
198 | ||
199 | /* Configure limit on the number of pending, queued updates. If 'unset', reset | |
200 | * to default value. | |
201 | */ | |
202 | void dplane_set_in_queue_limit(uint32_t limit, bool set); | |
203 | ||
204 | /* Retrieve the current queue depth of incoming, unprocessed updates */ | |
205 | uint32_t dplane_get_in_queue_len(void); | |
206 | ||
1d11b21f MS |
207 | /* |
208 | * Vty/cli apis | |
209 | */ | |
210 | int dplane_show_helper(struct vty *vty, bool detailed); | |
211 | int dplane_show_provs_helper(struct vty *vty, bool detailed); | |
212 | ||
213 | ||
214 | /* | |
215 | * Dataplane providers: modules that consume dataplane events. | |
216 | */ | |
217 | ||
fe2c53d4 | 218 | /* Support string name for a dataplane provider */ |
7cdb1a84 MS |
219 | #define DPLANE_PROVIDER_NAMELEN 64 |
220 | ||
221 | /* Priority or ordering values for providers. The idea is that there may be | |
222 | * some pre-processing, followed by an external or remote dataplane, | |
223 | * followed by the kernel, followed by some post-processing step (such as | |
224 | * the fpm output stream.) | |
225 | */ | |
5709131c | 226 | enum dplane_provider_prio_e { |
7cdb1a84 MS |
227 | DPLANE_PRIO_NONE = 0, |
228 | DPLANE_PRIO_PREPROCESS, | |
229 | DPLANE_PRIO_PRE_KERNEL, | |
230 | DPLANE_PRIO_KERNEL, | |
231 | DPLANE_PRIO_POSTPROCESS, | |
b8e0423d | 232 | DPLANE_PRIO_LAST |
5709131c | 233 | }; |
7cdb1a84 MS |
234 | |
235 | /* Provider's entry-point to process a context block */ | |
25779064 | 236 | typedef int (*dplane_provider_process_fp)(struct zebra_dplane_ctx *ctx); |
7cdb1a84 | 237 | |
18c37974 MS |
238 | /* Provider's entry-point for shutdown and cleanup */ |
239 | typedef int (*dplane_provider_fini_fp)(void); | |
240 | ||
7cdb1a84 MS |
241 | /* Provider registration */ |
242 | int dplane_provider_register(const char *name, | |
5709131c | 243 | enum dplane_provider_prio_e prio, |
18c37974 MS |
244 | dplane_provider_process_fp fp, |
245 | dplane_provider_fini_fp fini_fp); | |
7cdb1a84 MS |
246 | |
247 | /* | |
248 | * Results are returned to zebra core via a callback | |
249 | */ | |
25779064 | 250 | typedef int (*dplane_results_fp)(const struct zebra_dplane_ctx *ctx); |
7cdb1a84 MS |
251 | |
252 | /* | |
253 | * Zebra registers a results callback with the dataplane. The callback is | |
254 | * called in the dataplane thread context, so the expectation is that the | |
255 | * context is queued (or that processing is very limited). | |
256 | */ | |
257 | int dplane_results_register(dplane_results_fp fp); | |
258 | ||
259 | /* | |
1d11b21f MS |
260 | * Initialize the dataplane modules at zebra startup. This is currently called |
261 | * by the rib module. | |
7cdb1a84 MS |
262 | */ |
263 | void zebra_dplane_init(void); | |
264 | ||
4dfd7a02 MS |
265 | /* Finalize/cleanup apis, one called early as shutdown is starting, |
266 | * one called late at the end of zebra shutdown, and then one called | |
267 | * from the zebra main thread to stop the dplane thread free all resources. | |
268 | * | |
1d11b21f MS |
269 | * Zebra expects to try to clean up all vrfs and all routes during |
270 | * shutdown, so the dplane must be available until very late. | |
271 | */ | |
4dfd7a02 | 272 | void zebra_dplane_pre_finish(void); |
1d11b21f | 273 | void zebra_dplane_finish(void); |
4dfd7a02 | 274 | void zebra_dplane_shutdown(void); |
1d11b21f | 275 | |
ea1c14f6 | 276 | #endif /* _ZEBRA_DPLANE_H */ |