1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
|
// SPDX-License-Identifier: GPL-2.0-or-later
/*
* Zebra API server.
* Portions:
* Copyright (C) 1997-1999 Kunihiro Ishiguro
* Copyright (C) 2015-2018 Cumulus Networks, Inc.
* et al.
*/
#ifndef _ZEBRA_ZSERV_H
#define _ZEBRA_ZSERV_H
/* clang-format off */
#include <stdint.h> /* for uint32_t, uint8_t */
#include <time.h> /* for time_t */
#include "lib/route_types.h" /* for ZEBRA_ROUTE_MAX */
#include "lib/zebra.h" /* for AFI_MAX */
#include "lib/vrf.h" /* for vrf_bitmap_t */
#include "lib/zclient.h" /* for redist_proto */
#include "lib/stream.h" /* for stream, stream_fifo */
#include "frrevent.h" /* for thread, thread_master */
#include "lib/linklist.h" /* for list */
#include "lib/workqueue.h" /* for work_queue */
#include "lib/hook.h" /* for DECLARE_HOOK, DECLARE_KOOH */
/* clang-format on */
#ifdef __cplusplus
extern "C" {
#endif
struct zebra_vrf;
/* Default configuration filename. */
#define DEFAULT_CONFIG_FILE "zebra.conf"
#define ZEBRA_RMAP_DEFAULT_UPDATE_TIMER 5 /* disabled by default */
/* Stale route marker timer */
#define ZEBRA_DEFAULT_STALE_UPDATE_DELAY 1
/* Count of stale routes processed in timer context */
#define ZEBRA_MAX_STALE_ROUTE_COUNT 50000
/* Graceful Restart information */
struct client_gr_info {
/* VRF for which GR enabled */
vrf_id_t vrf_id;
/* Stale time and GR cap */
uint32_t stale_removal_time;
enum zserv_client_capabilities capabilities;
/* GR commands */
bool do_delete;
bool gr_enable;
bool stale_client;
/* Route sync and enable flags for AFI/SAFI */
bool af_enabled[AFI_MAX];
bool route_sync[AFI_MAX];
/* Book keeping */
void *stale_client_ptr;
struct event *t_stale_removal;
TAILQ_ENTRY(client_gr_info) gr_info;
};
/* Client structure. */
struct zserv {
/* Client pthread */
struct frr_pthread *pthread;
/* Client file descriptor. */
int sock;
/* Attributes used to permit access to zapi clients from
* other pthreads: the client has a busy counter, and a
* 'closed' flag. These attributes are managed using a
* lock, via the acquire_client() and release_client() apis.
*/
int busy_count;
bool is_closed;
/* Input/output buffer to the client. */
pthread_mutex_t ibuf_mtx;
struct stream_fifo *ibuf_fifo;
pthread_mutex_t obuf_mtx;
struct stream_fifo *obuf_fifo;
/* Private I/O buffers */
struct stream *ibuf_work;
struct stream *obuf_work;
/* Buffer of data waiting to be written to client. */
struct buffer *wb;
/* Threads for read/write. */
struct event *t_read;
struct event *t_write;
/* Event for message processing, for the main pthread */
struct event *t_process;
/* Event for the main pthread */
struct event *t_cleanup;
/* This client's redistribute flag. */
struct redist_proto mi_redist[AFI_MAX][ZEBRA_ROUTE_MAX];
vrf_bitmap_t redist[AFI_MAX][ZEBRA_ROUTE_MAX];
/* Redistribute default route flag. */
vrf_bitmap_t redist_default[AFI_MAX];
/* Router-id information. */
vrf_bitmap_t ridinfo[AFI_MAX];
/* Router-id information. */
vrf_bitmap_t neighinfo[AFI_MAX];
bool notify_owner;
/* Indicates if client is synchronous. */
bool synchronous;
/* client's protocol and session info */
uint8_t proto;
uint16_t instance;
uint32_t session_id;
/*
* Interested for MLAG Updates, and also stores the client
* interested message mask
*/
bool mlag_updates_interested;
uint32_t mlag_reg_mask1;
/* Statistics */
uint32_t redist_v4_add_cnt;
uint32_t redist_v4_del_cnt;
uint32_t redist_v6_add_cnt;
uint32_t redist_v6_del_cnt;
uint32_t v4_route_add_cnt;
uint32_t v4_route_upd8_cnt;
uint32_t v4_route_del_cnt;
uint32_t v6_route_add_cnt;
uint32_t v6_route_del_cnt;
uint32_t v6_route_upd8_cnt;
uint32_t connected_rt_add_cnt;
uint32_t connected_rt_del_cnt;
uint32_t ifup_cnt;
uint32_t ifdown_cnt;
uint32_t ifadd_cnt;
uint32_t ifdel_cnt;
uint32_t if_bfd_cnt;
uint32_t bfd_peer_add_cnt;
uint32_t bfd_peer_upd8_cnt;
uint32_t bfd_peer_del_cnt;
uint32_t bfd_peer_replay_cnt;
uint32_t vrfadd_cnt;
uint32_t vrfdel_cnt;
uint32_t if_vrfchg_cnt;
uint32_t bfd_client_reg_cnt;
uint32_t vniadd_cnt;
uint32_t vnidel_cnt;
uint32_t l3vniadd_cnt;
uint32_t l3vnidel_cnt;
uint32_t macipadd_cnt;
uint32_t macipdel_cnt;
uint32_t prefixadd_cnt;
uint32_t prefixdel_cnt;
uint32_t v4_nh_watch_add_cnt;
uint32_t v4_nh_watch_rem_cnt;
uint32_t v6_nh_watch_add_cnt;
uint32_t v6_nh_watch_rem_cnt;
uint32_t vxlan_sg_add_cnt;
uint32_t vxlan_sg_del_cnt;
uint32_t local_es_add_cnt;
uint32_t local_es_del_cnt;
uint32_t local_es_evi_add_cnt;
uint32_t local_es_evi_del_cnt;
uint32_t error_cnt;
uint32_t nhg_add_cnt;
uint32_t nhg_upd8_cnt;
uint32_t nhg_del_cnt;
time_t nh_reg_time;
time_t nh_dereg_time;
time_t nh_last_upd_time;
/*
* Session information.
*
* These are not synchronous with respect to each other. For instance,
* last_read_cmd may contain a value that has been read in the future
* relative to last_read_time.
*/
pthread_mutex_t stats_mtx;
/* BEGIN covered by stats_mtx */
/* monotime of client creation */
uint64_t connect_time;
/* monotime of last message received */
uint64_t last_read_time;
/* monotime of last message sent */
uint64_t last_write_time;
/* command code of last message read */
uint64_t last_read_cmd;
/* command code of last message written */
uint64_t last_write_cmd;
/* END covered by stats_mtx */
/*
* Number of instances configured with
* graceful restart
*/
uint32_t gr_instance_count;
time_t restart_time;
/*
* Graceful restart information for
* each instance
*/
TAILQ_HEAD(info_list, client_gr_info) gr_info_queue;
};
#define ZAPI_HANDLER_ARGS \
struct zserv *client, struct zmsghdr *hdr, struct stream *msg, \
struct zebra_vrf *zvrf
/* Hooks for client connect / disconnect */
DECLARE_HOOK(zserv_client_connect, (struct zserv *client), (client));
DECLARE_KOOH(zserv_client_close, (struct zserv *client), (client));
#define DYNAMIC_CLIENT_GR_DISABLED(_client) \
((_client->proto <= ZEBRA_ROUTE_LOCAL) || !(_client->gr_instance_count))
/*
* Initialize Zebra API server.
*
* Installs CLI commands and creates the client list.
*/
extern void zserv_init(void);
/*
* Stop the Zebra API server.
*
* closes the socket
*/
extern void zserv_close(void);
/*
* Start Zebra API server.
*
* Allocates resources, creates the server socket and begins listening on the
* socket.
*
* path
* where to place the Unix domain socket
*/
extern void zserv_start(char *path);
/*
* Send a message to a connected Zebra API client.
*
* client
* the client to send to
*
* msg
* the message to send
*/
extern int zserv_send_message(struct zserv *client, struct stream *msg);
/*
* Send a batch of messages to a connected Zebra API client.
*
* client
* the client to send to
*
* fifo
* the list of messages to send
*/
extern int zserv_send_batch(struct zserv *client, struct stream_fifo *fifo);
/*
* Retrieve a client by its protocol and instance number.
*
* proto
* protocol number
*
* instance
* instance number
*
* Returns:
* The Zebra API client.
*/
extern struct zserv *zserv_find_client(uint8_t proto, unsigned short instance);
/*
* Retrieve a client by its protocol, instance number, and session id.
*
* proto
* protocol number
*
* instance
* instance number
*
* session_id
* session id
*
* Returns:
* The Zebra API client.
*/
struct zserv *zserv_find_client_session(uint8_t proto, unsigned short instance,
uint32_t session_id);
/*
* Retrieve a client object by the complete tuple of
* {protocol, instance, session}. This version supports use
* from a different pthread: the object will be returned marked
* in-use. The caller *must* release the client object with the
* release_client() api, to ensure that the in-use marker is cleared properly.
*
* Returns:
* The Zebra API client.
*/
extern struct zserv *zserv_acquire_client(uint8_t proto,
unsigned short instance,
uint32_t session_id);
/*
* Release a client object that was acquired with the acquire_client() api.
* After this has been called, the pointer must not be used - it may be freed
* in another pthread if the client has closed.
*/
extern void zserv_release_client(struct zserv *client);
/*
* Close a client.
*
* Kills a client's thread, removes the client from the client list and cleans
* up its resources.
*
* client
* the client to close
*/
extern void zserv_close_client(struct zserv *client);
/*
* Free memory for a zserv client object - note that this does not
* clean up the internal allocations associated with the zserv client,
* this just free the struct's memory.
*/
void zserv_client_delete(struct zserv *client);
/*
* Log a ZAPI message hexdump.
*
* errmsg
* Error message to include with packet hexdump
*
* msg
* Message to log
*
* hdr
* Message header
*/
void zserv_log_message(const char *errmsg, struct stream *msg,
struct zmsghdr *hdr);
/* TODO */
__attribute__((__noreturn__)) void zebra_finalize(struct event *event);
/*
* Graceful restart functions.
*/
extern void zebra_gr_client_final_shutdown(struct zserv *client);
extern int zebra_gr_client_disconnect(struct zserv *client);
extern void zebra_gr_client_reconnect(struct zserv *client);
extern void zebra_gr_stale_client_cleanup(struct list *client_list);
extern void zread_client_capabilities(struct zserv *client, struct zmsghdr *hdr,
struct stream *msg,
struct zebra_vrf *zvrf);
#ifdef __cplusplus
}
#endif
#endif /* _ZEBRA_ZEBRA_H */
|