1/*
2 * CDDL HEADER START
3 *
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
7 *
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
12 *
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 *
19 * CDDL HEADER END
20 */
21
22/*
23 * Copyright 2010 Sun Microsystems, Inc.  All rights reserved.
24 * Use is subject to license terms.
25 */
26
27#ifndef	_LIBVRRPADM_H
28#define	_LIBVRRPADM_H
29
30#include <sys/types.h>
31#include <sys/socket.h>
32#include <netinet/in.h>		/* in(6)_addr_t */
33#include <arpa/inet.h>
34#include <net/if.h>		/* LIFNAMSIZ */
35#include <limits.h>
36#include <netinet/vrrp.h>
37#include <syslog.h>
38#include <libdladm.h>
39
40#ifdef __cplusplus
41extern "C" {
42#endif
43
44#define	VRRP_NAME_MAX	32
45#define	VRRPD_SOCKET	"/var/run/vrrpd.socket"
46
47/*
48 * to store the IP addresses
49 */
50typedef struct vrrp_addr {
51	union {
52		struct sockaddr_in	a4;
53		struct sockaddr_in6	a6;
54	} in;
55#define	in4	in.a4
56#define	in6	in.a6
57} vrrp_addr_t;
58
59/*
60 * VRRP instance (configuration information).
61 * Passed to vrrp_create(), returned by vrrp_query().
62 */
63typedef struct vrrp_vr_conf_s {
64	char		vvc_name[VRRP_NAME_MAX];	/* VRRP router name */
65	char		vvc_link[MAXLINKNAMELEN];	/* data-link name */
66	vrid_t		vvc_vrid;			/* VRID */
67	int		vvc_af;				/* IPv4/IPv6 */
68	int		vvc_pri;
69	uint32_t	vvc_adver_int;			/* in ms */
70	boolean_t	vvc_preempt;
71	boolean_t	vvc_accept;
72	boolean_t	vvc_enabled;
73} vrrp_vr_conf_t;
74
75/*
76 * VRRP state machine
77 */
78typedef enum {
79	VRRP_STATE_NONE = -1,
80	VRRP_STATE_INIT,
81	VRRP_STATE_MASTER,
82	VRRP_STATE_BACKUP
83} vrrp_state_t;
84
85/*
86 * VRRP status structure
87 * Returned by vrrp_query() as part of vrrp_queryinfo_t.
88 */
89typedef struct vrrp_statusinfo_s {
90	vrrp_state_t	vs_state;
91	vrrp_state_t	vs_prev_state;
92	struct timeval	vs_st_time;	/* timestamp of last state trans */
93} vrrp_stateinfo_t;
94
95/*
96 * The information obtained from peer's advertisements
97 * Returned by vrrp_query() as part of vrrp_queryinfo_t.
98 */
99typedef struct vrrp_peer_s {
100	vrrp_addr_t	vp_addr;	/* source IP addr of the message */
101	int		vp_prio;	/* priority in adv message */
102	struct timeval	vp_time;	/* timestamp of the adv message */
103	int		vp_adver_int;	/* adv interval in adv message */
104} vrrp_peer_t;
105
106/*
107 * Useful timer information, in ms
108 */
109typedef struct vrrp_timeinfo_s {
110	int	vt_since_last_tran;	/* time since last state transition */
111	int	vt_since_last_adv;	/* time since last advertisement */
112	int	vt_master_down_intv;	/* timer interval for backup to */
113					/* declare master down */
114} vrrp_timerinfo_t;
115
116/*
117 * Address information
118 */
119typedef struct vrrp_addrinfo_s {
120	char		va_vnic[MAXLINKNAMELEN];
121	vrrp_addr_t	va_primary;
122	uint32_t	va_vipcnt;
123	vrrp_addr_t	va_vips[1];
124} vrrp_addrinfo_t;
125
126/*
127 * VRRP instance configuration and run-time states information
128 * Returned by vrrp_query().
129 */
130typedef struct vrrp_queryinfo {
131	vrrp_vr_conf_t		show_vi;
132	vrrp_stateinfo_t	show_vs;
133	vrrp_peer_t		show_vp;
134	vrrp_timerinfo_t	show_vt;
135	vrrp_addrinfo_t		show_va;
136} vrrp_queryinfo_t;
137
138/*
139 * flags sent with the VRRP_CMD_MODIFY command. Used in vrrp_setprop().
140 */
141#define	VRRP_CONF_PRIORITY	0x01
142#define	VRRP_CONF_INTERVAL	0x02
143#define	VRRP_CONF_PREEMPT	0x04
144#define	VRRP_CONF_ACCEPT	0x08
145
146/*
147 * Errors
148 */
149typedef enum {
150	VRRP_SUCCESS = 0,
151	VRRP_EINVAL,		/* invalid parameter */
152	VRRP_EINVALVRNAME,	/* invalid router name */
153	VRRP_ENOMEM,		/* no memory */
154	VRRP_ENOVIRT,		/* no virtual IP addresses */
155	VRRP_ENOPRIM,		/* no primary IP address */
156	VRRP_ENOVNIC,		/* no vnic created */
157	VRRP_ENOLINK,		/* the link does not exist */
158	VRRP_EINVALLINK,	/* invalid link */
159	VRRP_EINVALADDR,	/* invalid IP address */
160	VRRP_EINVALAF,		/* invalid IP address familty */
161	VRRP_EDB,		/* configuration error */
162	VRRP_EPERM,		/* permission denied */
163	VRRP_EBADSTATE,		/* VRRP router in bad state */
164	VRRP_EVREXIST,		/* <vrid, intf, af> three-tuple exists */
165	VRRP_EINSTEXIST,	/* router name already exists */
166	VRRP_EEXIST,		/* already exists */
167	VRRP_ENOTFOUND,		/* vrrp router not found */
168	VRRP_ETOOSMALL,		/* too small space */
169	VRRP_EAGAIN,		/* Try again */
170	VRRP_EALREADY,		/* already */
171	VRRP_EDLADM,		/* dladm failure */
172	VRRP_EIPADM,		/* ipadm failure */
173	VRRP_ESYS,		/* system error */
174	VRRP_ENOSVC		/* VRRP service not enabled */
175} vrrp_err_t;
176
177/*
178 * Internal commands used between vrrpadm and vrrpd.
179 */
180typedef enum {
181	VRRP_CMD_RETURN = 0,
182	VRRP_CMD_CREATE,
183	VRRP_CMD_DELETE,
184	VRRP_CMD_ENABLE,
185	VRRP_CMD_DISABLE,
186	VRRP_CMD_MODIFY,
187	VRRP_CMD_LIST,
188	VRRP_CMD_QUERY
189} vrrp_cmd_type_t;
190
191#define	addr_len(af) ((af) == AF_INET ? sizeof (in_addr_t): sizeof (in6_addr_t))
192
193#define	VRRPADDR_UNSPECIFIED(af, addr) 					\
194	(((af) == AF_INET6 && IN6_IS_ADDR_UNSPECIFIED(			\
195	    &(addr)->in6.sin6_addr)) || ((af) == AF_INET &&		\
196	    ((addr)->in4.sin_addr.s_addr == INADDR_ANY)))
197
198#define	VRRPADDR2STR(af, addr, abuf, size, append) {			\
199	char ap[INET6_ADDRSTRLEN];					\
200									\
201	if (VRRPADDR_UNSPECIFIED(af, addr)) {				\
202		(void) strlcpy(ap, "--", INET6_ADDRSTRLEN);		\
203	} else if ((af) == AF_INET) {					\
204		(void) inet_ntop((af), &(addr)->in4.sin_addr, ap,	\
205		    INET6_ADDRSTRLEN);					\
206	} else {							\
207		(void) inet_ntop((af), &(addr)->in6.sin6_addr, ap,	\
208		    INET6_ADDRSTRLEN);					\
209	}								\
210	if (append)							\
211		(void) strlcat(abuf, ap, size);				\
212	else								\
213		(void) strlcpy(abuf, ap, size);				\
214}
215
216typedef struct vrrp_cmd_create_s {
217	uint32_t	vcc_cmd;
218	vrrp_vr_conf_t	vcc_conf;
219} vrrp_cmd_create_t;
220
221typedef struct vrrp_ret_create_s {
222	vrrp_err_t	vrc_err;
223} vrrp_ret_create_t;
224
225typedef struct vrrp_cmd_delete_s {
226	uint32_t	vcd_cmd;
227	char		vcd_name[VRRP_NAME_MAX];
228} vrrp_cmd_delete_t;
229
230typedef struct vrrp_ret_delete_s {
231	vrrp_err_t	vrd_err;
232} vrrp_ret_delete_t;
233
234typedef struct vrrp_cmd_enable_s {
235	uint32_t	vcs_cmd;
236	char		vcs_name[VRRP_NAME_MAX];
237} vrrp_cmd_enable_t;
238
239typedef struct vrrp_ret_enable_s {
240	vrrp_err_t	vrs_err;
241} vrrp_ret_enable_t;
242
243typedef struct vrrp_cmd_disable_s {
244	uint32_t	vcx_cmd;
245	char		vcx_name[VRRP_NAME_MAX];
246} vrrp_cmd_disable_t;
247
248typedef struct vrrp_ret_disable_s {
249	vrrp_err_t	vrx_err;
250} vrrp_ret_disable_t;
251
252typedef struct vrrp_cmd_modify_s {
253	uint32_t	vcm_cmd;
254	uint32_t	vcm_mask;
255	vrrp_vr_conf_t	vcm_conf;
256} vrrp_cmd_modify_t;
257
258typedef struct vrrp_ret_modify_s {
259	vrrp_err_t	vrm_err;
260} vrrp_ret_modify_t;
261
262typedef struct vrrp_cmd_list_s {
263	uint32_t	vcl_cmd;
264	vrid_t		vcl_vrid;
265	char		vcl_ifname[LIFNAMSIZ];
266	int		vcl_af;
267} vrrp_cmd_list_t;
268
269typedef struct vrrp_ret_list_s {
270	vrrp_err_t	vrl_err;
271	uint32_t	vrl_cnt;
272	/*
273	 * When vrl_cnt is non-zero, the return structure will be followed
274	 * by the list of router names, separated by '\0'. Its size will
275	 * be vrl_cnt * VRRP_NAME_MAX.
276	 */
277} vrrp_ret_list_t;
278
279typedef struct vrrp_cmd_query_s {
280	uint32_t	vcq_cmd;
281	char		vcq_name[VRRP_NAME_MAX];
282} vrrp_cmd_query_t;
283
284typedef struct vrrp_ret_query_s {
285	vrrp_err_t		vrq_err;
286	vrrp_queryinfo_t	vrq_qinfo;
287} vrrp_ret_query_t;
288
289/*
290 * Union of all VRRP commands
291 */
292typedef union vrrp_cmd_s {
293	uint32_t		vc_cmd;
294	vrrp_cmd_create_t	vc_cmd_create;
295	vrrp_cmd_delete_t	vc_cmd_delete;
296	vrrp_cmd_enable_t	vc_cmd_enable;
297	vrrp_cmd_disable_t	vc_cmd_disable;
298	vrrp_cmd_modify_t	vc_cmd_modify;
299	vrrp_cmd_list_t		vc_cmd_list;
300} vrrp_cmd_t;
301
302/*
303 * Union of all VRRP replies of the VRRP commands
304 */
305typedef union vrrp_ret_s {
306	vrrp_err_t		vr_err;
307	vrrp_ret_create_t	vr_ret_create;
308	vrrp_ret_delete_t	vr_ret_delete;
309	vrrp_ret_enable_t	vr_ret_enable;
310	vrrp_ret_disable_t	vr_ret_disable;
311	vrrp_ret_modify_t	vr_ret_modify;
312	vrrp_ret_list_t		vr_ret_list;
313	vrrp_ret_query_t	vr_ret_query;
314} vrrp_ret_t;
315
316/*
317 * Public APIs
318 */
319struct vrrp_handle {
320	dladm_handle_t	vh_dh;
321};
322typedef struct vrrp_handle *vrrp_handle_t;
323
324const char	*vrrp_err2str(vrrp_err_t);
325const char	*vrrp_state2str(vrrp_state_t);
326
327vrrp_err_t	vrrp_open(vrrp_handle_t *);
328void		vrrp_close(vrrp_handle_t);
329
330boolean_t	vrrp_valid_name(const char *);
331
332vrrp_err_t	vrrp_create(vrrp_handle_t, vrrp_vr_conf_t *);
333vrrp_err_t	vrrp_delete(vrrp_handle_t, const char *);
334
335vrrp_err_t	vrrp_enable(vrrp_handle_t, const char *);
336vrrp_err_t	vrrp_disable(vrrp_handle_t, const char *);
337
338vrrp_err_t	vrrp_modify(vrrp_handle_t, vrrp_vr_conf_t *, uint32_t);
339
340vrrp_err_t	vrrp_query(vrrp_handle_t, const char *, vrrp_queryinfo_t **);
341
342vrrp_err_t	vrrp_list(vrrp_handle_t, vrid_t, const char *, int,
343		    uint32_t *, char *);
344
345boolean_t	vrrp_is_vrrp_vnic(vrrp_handle_t, datalink_id_t,
346		    datalink_id_t *, uint16_t *, vrid_t *, int *);
347
348vrrp_err_t	vrrp_get_vnicname(vrrp_handle_t, vrid_t, int, char *,
349		    datalink_id_t *, uint16_t *, char *, size_t);
350
351#ifdef __cplusplus
352}
353#endif
354
355#endif	/* _LIBVRRPADM_H */
356