summaryrefslogtreecommitdiffstats
path: root/lib/mgmt_be_client.h
blob: db427457a4e219d53ff188f30024ca31c68962f1 (plain)
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
// SPDX-License-Identifier: GPL-2.0-or-later
/*
 * MGMTD Backend Client Library api interfaces
 * Copyright (C) 2021  Vmware, Inc.
 *		       Pushpasis Sarkar <spushpasis@vmware.com>
 */

#ifndef _FRR_MGMTD_BE_CLIENT_H_
#define _FRR_MGMTD_BE_CLIENT_H_

#ifdef __cplusplus
extern "C" {
#endif

#include "northbound.h"
#include "mgmt_pb.h"
#include "mgmtd/mgmt_defines.h"

/***************************************************************
 * Client IDs
 ***************************************************************/

/*
 * Add enum value for each supported component, wrap with
 * #ifdef HAVE_COMPONENT
 */
enum mgmt_be_client_id {
	MGMTD_BE_CLIENT_ID_MIN = 0,
	MGMTD_BE_CLIENT_ID_INIT = -1,
#ifdef HAVE_STATICD
	MGMTD_BE_CLIENT_ID_STATICD,
#endif
	MGMTD_BE_CLIENT_ID_MAX
};

#define FOREACH_MGMTD_BE_CLIENT_ID(id)			\
	for ((id) = MGMTD_BE_CLIENT_ID_MIN;		\
	     (id) < MGMTD_BE_CLIENT_ID_MAX; (id)++)

/***************************************************************
 * Constants
 ***************************************************************/

#define MGMTD_BE_CLIENT_ERROR_STRING_MAX_LEN 32

#define MGMTD_BE_DEFAULT_CONN_RETRY_INTVL_SEC 5

#define MGMTD_BE_MSG_PROC_DELAY_USEC 10
#define MGMTD_BE_MAX_NUM_MSG_PROC 500

#define MGMTD_BE_MSG_WRITE_DELAY_MSEC 1
#define MGMTD_BE_MAX_NUM_MSG_WRITE 1000

#define GMGD_BE_MAX_NUM_REQ_ITEMS 64

#define MGMTD_BE_MSG_MAX_LEN 16384

#define MGMTD_SOCKET_BE_SEND_BUF_SIZE 65535
#define MGMTD_SOCKET_BE_RECV_BUF_SIZE MGMTD_SOCKET_BE_SEND_BUF_SIZE

#define MGMTD_MAX_CFG_CHANGES_IN_BATCH				\
	((10 * MGMTD_BE_MSG_MAX_LEN) /				\
	 (MGMTD_MAX_XPATH_LEN + MGMTD_MAX_YANG_VALUE_LEN))

/*
 * MGMTD_BE_MSG_MAX_LEN must be used 80%
 * since there is overhead of google protobuf
 * that gets added to sent message
 */
#define MGMTD_BE_CFGDATA_PACKING_EFFICIENCY 0.8
#define MGMTD_BE_CFGDATA_MAX_MSG_LEN                                        \
	(MGMTD_BE_MSG_MAX_LEN * MGMTD_BE_CFGDATA_PACKING_EFFICIENCY)

#define MGMTD_BE_MAX_BATCH_IDS_IN_REQ                                       \
	(MGMTD_BE_MSG_MAX_LEN - 128) / sizeof(uint64_t)

#define MGMTD_BE_CONTAINER_NODE_VAL "<<container>>"

/***************************************************************
 * Data-structures
 ***************************************************************/

#define MGMTD_BE_MAX_CLIENTS_PER_XPATH_REG 32

struct mgmt_be_client_txn_ctx {
	uintptr_t *user_ctx;
};

/*
 * All the client-specific information this library needs to
 * initialize itself, setup connection with MGMTD BackEnd interface
 * and carry on all required procedures appropriately.
 *
 * BackEnd clients need to initialise a instance of this structure
 * with appropriate data and pass it while calling the API
 * to initialize the library (See mgmt_be_client_lib_init for
 * more details).
 */
struct mgmt_be_client_params {
	char name[MGMTD_CLIENT_NAME_MAX_LEN];
	uintptr_t user_data;
	unsigned long conn_retry_intvl_sec;

	void (*client_connect_notify)(uintptr_t lib_hndl,
				      uintptr_t usr_data,
				      bool connected);

	void (*client_subscribe_notify)(
		uintptr_t lib_hndl, uintptr_t usr_data,
		struct nb_yang_xpath **xpath,
		enum mgmt_result subscribe_result[], int num_paths);

	void (*txn_notify)(
		uintptr_t lib_hndl, uintptr_t usr_data,
		struct mgmt_be_client_txn_ctx *txn_ctx, bool destroyed);

	enum mgmt_result (*data_validate)(
		uintptr_t lib_hndl, uintptr_t usr_data,
		struct mgmt_be_client_txn_ctx *txn_ctx,
		struct nb_yang_xpath *xpath, struct nb_yang_value *data,
		bool delete, char *error_if_any);

	enum mgmt_result (*data_apply)(
		uintptr_t lib_hndl, uintptr_t usr_data,
		struct mgmt_be_client_txn_ctx *txn_ctx,
		struct nb_yang_xpath *xpath, struct nb_yang_value *data,
		bool delete);

	enum mgmt_result (*get_data_elem)(
		uintptr_t lib_hndl, uintptr_t usr_data,
		struct mgmt_be_client_txn_ctx *txn_ctx,
		struct nb_yang_xpath *xpath, struct nb_yang_xpath_elem *elem);

	enum mgmt_result (*get_data)(
		uintptr_t lib_hndl, uintptr_t usr_data,
		struct mgmt_be_client_txn_ctx *txn_ctx,
		struct nb_yang_xpath *xpath, bool keys_only,
		struct nb_yang_xpath_elem **elems, int *num_elems,
		int *next_key);

	enum mgmt_result (*get_next_data)(
		uintptr_t lib_hndl, uintptr_t usr_data,
		struct mgmt_be_client_txn_ctx *txn_ctx,
		struct nb_yang_xpath *xpath, bool keys_only,
		struct nb_yang_xpath_elem **elems, int *num_elems);
};

/***************************************************************
 * Global data exported
 ***************************************************************/

extern const char *mgmt_be_client_names[MGMTD_BE_CLIENT_ID_MAX + 1];

static inline const char *mgmt_be_client_id2name(enum mgmt_be_client_id id)
{
	if (id > MGMTD_BE_CLIENT_ID_MAX)
		id = MGMTD_BE_CLIENT_ID_MAX;
	return mgmt_be_client_names[id];
}

static inline enum mgmt_be_client_id
mgmt_be_client_name2id(const char *name)
{
	enum mgmt_be_client_id id;

	FOREACH_MGMTD_BE_CLIENT_ID (id) {
		if (!strncmp(mgmt_be_client_names[id], name,
			     MGMTD_CLIENT_NAME_MAX_LEN))
			return id;
	}

	return MGMTD_BE_CLIENT_ID_MAX;
}

/***************************************************************
 * API prototypes
 ***************************************************************/

/*
 * Initialize library and try connecting with MGMTD.
 *
 * params
 *    Backend client parameters.
 *
 * master_thread
 *    Thread master.
 *
 * Returns:
 *    Backend client lib handler (nothing but address of mgmt_be_client_ctx)
 */
extern uintptr_t mgmt_be_client_lib_init(struct mgmt_be_client_params *params,
					 struct event_loop *master_thread);

/*
 * Subscribe with MGMTD for one or more YANG subtree(s).
 *
 * lib_hndl
 *    Client library handler.
 *
 * reg_yang_xpaths
 *    Yang xpath(s) that needs to be subscribed to.
 *
 * num_xpaths
 *    Number of xpaths
 *
 * Returns:
 *    MGMTD_SUCCESS on success, MGMTD_* otherwise.
 */
extern enum mgmt_result mgmt_be_subscribe_yang_data(uintptr_t lib_hndl,
						       char **reg_yang_xpaths,
						       int num_xpaths);

/*
 * Send one or more YANG notifications to MGMTD daemon.
 *
 * lib_hndl
 *    Client library handler.
 *
 * data_elems
 *    Yang data elements from data tree.
 *
 * num_elems
 *    Number of data elements.
 *
 * Returns:
 *    MGMTD_SUCCESS on success, MGMTD_* otherwise.
 */
extern enum mgmt_result
mgmt_be_send_yang_notify(uintptr_t lib_hndl, Mgmtd__YangData **data_elems,
			    int num_elems);

/*
 * Un-subscribe with MGMTD for one or more YANG subtree(s).
 *
 * lib_hndl
 *    Client library handler.
 *
 * reg_yang_xpaths
 *    Yang xpath(s) that needs to be un-subscribed from.
 *
 * num_reg_xpaths
 *    Number of subscribed xpaths
 *
 * Returns:
 *    MGMTD_SUCCESS on success, MGMTD_* otherwise.
 */
enum mgmt_result mgmt_be_unsubscribe_yang_data(uintptr_t lib_hndl,
						  char **reg_yang_xpaths,
						  int num_reg_xpaths);

/*
 * Destroy library and cleanup everything.
 */
extern void mgmt_be_client_lib_destroy(uintptr_t lib_hndl);

#ifdef __cplusplus
}
#endif

#endif /* _FRR_MGMTD_BE_CLIENT_H_ */