summaryrefslogtreecommitdiff
path: root/usr/src/lib/libvrrpadm/common/libvrrpadm.h
blob: 703c256d1006de84bdc7bf05b6a4264ff98eda30 (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
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
/*
 * CDDL HEADER START
 *
 * The contents of this file are subject to the terms of the
 * Common Development and Distribution License (the "License").
 * You may not use this file except in compliance with the License.
 *
 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
 * or http://www.opensolaris.org/os/licensing.
 * See the License for the specific language governing permissions
 * and limitations under the License.
 *
 * When distributing Covered Code, include this CDDL HEADER in each
 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
 * If applicable, add the following below this CDDL HEADER, with the
 * fields enclosed by brackets "[]" replaced with your own identifying
 * information: Portions Copyright [yyyy] [name of copyright owner]
 *
 * CDDL HEADER END
 */

/*
 * Copyright 2010 Sun Microsystems, Inc.  All rights reserved.
 * Use is subject to license terms.
 */

#ifndef	_LIBVRRPADM_H
#define	_LIBVRRPADM_H

#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>		/* in(6)_addr_t */
#include <arpa/inet.h>
#include <net/if.h>		/* LIFNAMSIZ */
#include <limits.h>
#include <netinet/vrrp.h>
#include <syslog.h>
#include <libdladm.h>

#ifdef __cplusplus
extern "C" {
#endif

#define	VRRP_NAME_MAX	32
#define	VRRPD_SOCKET	"/var/run/vrrpd.socket"

/*
 * to store the IP addresses
 */
typedef struct vrrp_addr {
	union {
		struct sockaddr_in	a4;
		struct sockaddr_in6	a6;
	} in;
#define	in4	in.a4
#define	in6	in.a6
} vrrp_addr_t;

/*
 * VRRP instance (configuration information).
 * Passed to vrrp_create(), returned by vrrp_query().
 */
typedef struct vrrp_vr_conf_s {
	char		vvc_name[VRRP_NAME_MAX];	/* VRRP router name */
	char		vvc_link[MAXLINKNAMELEN];	/* data-link name */
	vrid_t		vvc_vrid;			/* VRID */
	int		vvc_af;				/* IPv4/IPv6 */
	int		vvc_pri;
	uint32_t	vvc_adver_int;			/* in ms */
	boolean_t	vvc_preempt;
	boolean_t	vvc_accept;
	boolean_t	vvc_enabled;
} vrrp_vr_conf_t;

/*
 * VRRP state machine
 */
typedef enum {
	VRRP_STATE_NONE = -1,
	VRRP_STATE_INIT,
	VRRP_STATE_MASTER,
	VRRP_STATE_BACKUP
} vrrp_state_t;

/*
 * VRRP status structure
 * Returned by vrrp_query() as part of vrrp_queryinfo_t.
 */
typedef struct vrrp_statusinfo_s {
	vrrp_state_t	vs_state;
	vrrp_state_t	vs_prev_state;
	struct timeval	vs_st_time;	/* timestamp of last state trans */
} vrrp_stateinfo_t;

/*
 * The information obtained from peer's advertisements
 * Returned by vrrp_query() as part of vrrp_queryinfo_t.
 */
typedef struct vrrp_peer_s {
	vrrp_addr_t	vp_addr;	/* source IP addr of the message */
	int		vp_prio;	/* priority in adv message */
	struct timeval	vp_time;	/* timestamp of the adv message */
	int		vp_adver_int;	/* adv interval in adv message */
} vrrp_peer_t;

/*
 * Useful timer information, in ms
 */
typedef struct vrrp_timeinfo_s {
	int	vt_since_last_tran;	/* time since last state transition */
	int	vt_since_last_adv;	/* time since last advertisement */
	int	vt_master_down_intv;	/* timer interval for backup to */
					/* declare master down */
} vrrp_timerinfo_t;

/*
 * Address information
 */
typedef struct vrrp_addrinfo_s {
	char		va_vnic[MAXLINKNAMELEN];
	vrrp_addr_t	va_primary;
	uint32_t	va_vipcnt;
	vrrp_addr_t	va_vips[1];
} vrrp_addrinfo_t;

/*
 * VRRP instance configuration and run-time states information
 * Returned by vrrp_query().
 */
typedef struct vrrp_queryinfo {
	vrrp_vr_conf_t		show_vi;
	vrrp_stateinfo_t	show_vs;
	vrrp_peer_t		show_vp;
	vrrp_timerinfo_t	show_vt;
	vrrp_addrinfo_t		show_va;
} vrrp_queryinfo_t;

/*
 * flags sent with the VRRP_CMD_MODIFY command. Used in vrrp_setprop().
 */
#define	VRRP_CONF_PRIORITY	0x01
#define	VRRP_CONF_INTERVAL	0x02
#define	VRRP_CONF_PREEMPT	0x04
#define	VRRP_CONF_ACCEPT	0x08

/*
 * Errors
 */
typedef enum {
	VRRP_SUCCESS = 0,
	VRRP_EINVAL,		/* invalid parameter */
	VRRP_EINVALVRNAME,	/* invalid router name */
	VRRP_ENOMEM,		/* no memory */
	VRRP_ENOVIRT,		/* no virtual IP addresses */
	VRRP_ENOPRIM,		/* no primary IP address */
	VRRP_ENOVNIC,		/* no vnic created */
	VRRP_ENOLINK,		/* the link does not exist */
	VRRP_EINVALLINK,	/* invalid link */
	VRRP_EINVALADDR,	/* invalid IP address */
	VRRP_EINVALAF,		/* invalid IP address familty */
	VRRP_EDB,		/* configuration error */
	VRRP_EPERM,		/* permission denied */
	VRRP_EBADSTATE,		/* VRRP router in bad state */
	VRRP_EVREXIST,		/* <vrid, intf, af> three-tuple exists */
	VRRP_EINSTEXIST,	/* router name already exists */
	VRRP_EEXIST,		/* already exists */
	VRRP_ENOTFOUND,		/* vrrp router not found */
	VRRP_ETOOSMALL,		/* too small space */
	VRRP_EAGAIN,		/* Try again */
	VRRP_EALREADY,		/* already */
	VRRP_EDLADM,		/* dladm failure */
	VRRP_EIPADM,		/* ipadm failure */
	VRRP_ESYS,		/* system error */
	VRRP_ENOSVC		/* VRRP service not enabled */
} vrrp_err_t;

/*
 * Internal commands used between vrrpadm and vrrpd.
 */
typedef enum {
	VRRP_CMD_RETURN = 0,
	VRRP_CMD_CREATE,
	VRRP_CMD_DELETE,
	VRRP_CMD_ENABLE,
	VRRP_CMD_DISABLE,
	VRRP_CMD_MODIFY,
	VRRP_CMD_LIST,
	VRRP_CMD_QUERY
} vrrp_cmd_type_t;

#define	addr_len(af) ((af) == AF_INET ? sizeof (in_addr_t): sizeof (in6_addr_t))

#define	VRRPADDR_UNSPECIFIED(af, addr) 					\
	(((af) == AF_INET6 && IN6_IS_ADDR_UNSPECIFIED(			\
	    &(addr)->in6.sin6_addr)) || ((af) == AF_INET &&		\
	    ((addr)->in4.sin_addr.s_addr == INADDR_ANY)))

#define	VRRPADDR2STR(af, addr, abuf, size, append) {			\
	char ap[INET6_ADDRSTRLEN];					\
									\
	if (VRRPADDR_UNSPECIFIED(af, addr)) {				\
		(void) strlcpy(ap, "--", INET6_ADDRSTRLEN);		\
	} else if ((af) == AF_INET) {					\
		(void) inet_ntop((af), &(addr)->in4.sin_addr, ap,	\
		    INET6_ADDRSTRLEN);					\
	} else {							\
		(void) inet_ntop((af), &(addr)->in6.sin6_addr, ap,	\
		    INET6_ADDRSTRLEN);					\
	}								\
	if (append)							\
		(void) strlcat(abuf, ap, size);				\
	else								\
		(void) strlcpy(abuf, ap, size);				\
}

typedef struct vrrp_cmd_create_s {
	uint32_t	vcc_cmd;
	vrrp_vr_conf_t	vcc_conf;
} vrrp_cmd_create_t;

typedef struct vrrp_ret_create_s {
	vrrp_err_t	vrc_err;
} vrrp_ret_create_t;

typedef struct vrrp_cmd_delete_s {
	uint32_t	vcd_cmd;
	char		vcd_name[VRRP_NAME_MAX];
} vrrp_cmd_delete_t;

typedef struct vrrp_ret_delete_s {
	vrrp_err_t	vrd_err;
} vrrp_ret_delete_t;

typedef struct vrrp_cmd_enable_s {
	uint32_t	vcs_cmd;
	char		vcs_name[VRRP_NAME_MAX];
} vrrp_cmd_enable_t;

typedef struct vrrp_ret_enable_s {
	vrrp_err_t	vrs_err;
} vrrp_ret_enable_t;

typedef struct vrrp_cmd_disable_s {
	uint32_t	vcx_cmd;
	char		vcx_name[VRRP_NAME_MAX];
} vrrp_cmd_disable_t;

typedef struct vrrp_ret_disable_s {
	vrrp_err_t	vrx_err;
} vrrp_ret_disable_t;

typedef struct vrrp_cmd_modify_s {
	uint32_t	vcm_cmd;
	uint32_t	vcm_mask;
	vrrp_vr_conf_t	vcm_conf;
} vrrp_cmd_modify_t;

typedef struct vrrp_ret_modify_s {
	vrrp_err_t	vrm_err;
} vrrp_ret_modify_t;

typedef struct vrrp_cmd_list_s {
	uint32_t	vcl_cmd;
	vrid_t		vcl_vrid;
	char		vcl_ifname[LIFNAMSIZ];
	int		vcl_af;
} vrrp_cmd_list_t;

typedef struct vrrp_ret_list_s {
	vrrp_err_t	vrl_err;
	uint32_t	vrl_cnt;
	/*
	 * When vrl_cnt is non-zero, the return structure will be followed
	 * by the list of router names, separated by '\0'. Its size will
	 * be vrl_cnt * VRRP_NAME_MAX.
	 */
} vrrp_ret_list_t;

typedef struct vrrp_cmd_query_s {
	uint32_t	vcq_cmd;
	char		vcq_name[VRRP_NAME_MAX];
} vrrp_cmd_query_t;

typedef struct vrrp_ret_query_s {
	vrrp_err_t		vrq_err;
	vrrp_queryinfo_t	vrq_qinfo;
} vrrp_ret_query_t;

/*
 * Union of all VRRP commands
 */
typedef union vrrp_cmd_s {
	uint32_t		vc_cmd;
	vrrp_cmd_create_t	vc_cmd_create;
	vrrp_cmd_delete_t	vc_cmd_delete;
	vrrp_cmd_enable_t	vc_cmd_enable;
	vrrp_cmd_disable_t	vc_cmd_disable;
	vrrp_cmd_modify_t	vc_cmd_modify;
	vrrp_cmd_list_t		vc_cmd_list;
} vrrp_cmd_t;

/*
 * Union of all VRRP replies of the VRRP commands
 */
typedef union vrrp_ret_s {
	vrrp_err_t		vr_err;
	vrrp_ret_create_t	vr_ret_create;
	vrrp_ret_delete_t	vr_ret_delete;
	vrrp_ret_enable_t	vr_ret_enable;
	vrrp_ret_disable_t	vr_ret_disable;
	vrrp_ret_modify_t	vr_ret_modify;
	vrrp_ret_list_t		vr_ret_list;
	vrrp_ret_query_t	vr_ret_query;
} vrrp_ret_t;

/*
 * Public APIs
 */
struct vrrp_handle {
	dladm_handle_t	vh_dh;
};
typedef struct vrrp_handle *vrrp_handle_t;

const char	*vrrp_err2str(vrrp_err_t);
const char	*vrrp_state2str(vrrp_state_t);

vrrp_err_t	vrrp_open(vrrp_handle_t *);
void		vrrp_close(vrrp_handle_t);

boolean_t	vrrp_valid_name(const char *);

vrrp_err_t	vrrp_create(vrrp_handle_t, vrrp_vr_conf_t *);
vrrp_err_t	vrrp_delete(vrrp_handle_t, const char *);

vrrp_err_t	vrrp_enable(vrrp_handle_t, const char *);
vrrp_err_t	vrrp_disable(vrrp_handle_t, const char *);

vrrp_err_t	vrrp_modify(vrrp_handle_t, vrrp_vr_conf_t *, uint32_t);

vrrp_err_t	vrrp_query(vrrp_handle_t, const char *, vrrp_queryinfo_t **);

vrrp_err_t	vrrp_list(vrrp_handle_t, vrid_t, const char *, int,
		    uint32_t *, char *);

boolean_t	vrrp_is_vrrp_vnic(vrrp_handle_t, datalink_id_t,
		    datalink_id_t *, uint16_t *, vrid_t *, int *);

vrrp_err_t	vrrp_get_vnicname(vrrp_handle_t, vrid_t, int, char *,
		    datalink_id_t *, uint16_t *, char *, size_t);

#ifdef __cplusplus
}
#endif

#endif	/* _LIBVRRPADM_H */