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
41 extern "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  */
50 typedef 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  */
63 typedef 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  */
78 typedef 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  */
89 typedef 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  */
99 typedef 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  */
109 typedef 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  */
119 typedef 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  */
130 typedef 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  */
149 typedef 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  */
180 typedef 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 
216 typedef struct vrrp_cmd_create_s {
217 	uint32_t	vcc_cmd;
218 	vrrp_vr_conf_t	vcc_conf;
219 } vrrp_cmd_create_t;
220 
221 typedef struct vrrp_ret_create_s {
222 	vrrp_err_t	vrc_err;
223 } vrrp_ret_create_t;
224 
225 typedef struct vrrp_cmd_delete_s {
226 	uint32_t	vcd_cmd;
227 	char		vcd_name[VRRP_NAME_MAX];
228 } vrrp_cmd_delete_t;
229 
230 typedef struct vrrp_ret_delete_s {
231 	vrrp_err_t	vrd_err;
232 } vrrp_ret_delete_t;
233 
234 typedef struct vrrp_cmd_enable_s {
235 	uint32_t	vcs_cmd;
236 	char		vcs_name[VRRP_NAME_MAX];
237 } vrrp_cmd_enable_t;
238 
239 typedef struct vrrp_ret_enable_s {
240 	vrrp_err_t	vrs_err;
241 } vrrp_ret_enable_t;
242 
243 typedef struct vrrp_cmd_disable_s {
244 	uint32_t	vcx_cmd;
245 	char		vcx_name[VRRP_NAME_MAX];
246 } vrrp_cmd_disable_t;
247 
248 typedef struct vrrp_ret_disable_s {
249 	vrrp_err_t	vrx_err;
250 } vrrp_ret_disable_t;
251 
252 typedef 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 
258 typedef struct vrrp_ret_modify_s {
259 	vrrp_err_t	vrm_err;
260 } vrrp_ret_modify_t;
261 
262 typedef 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 
269 typedef 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 
279 typedef struct vrrp_cmd_query_s {
280 	uint32_t	vcq_cmd;
281 	char		vcq_name[VRRP_NAME_MAX];
282 } vrrp_cmd_query_t;
283 
284 typedef 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  */
292 typedef 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  */
305 typedef 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  */
319 struct vrrp_handle {
320 	dladm_handle_t	vh_dh;
321 };
322 typedef struct vrrp_handle *vrrp_handle_t;
323 
324 const char	*vrrp_err2str(vrrp_err_t);
325 const char	*vrrp_state2str(vrrp_state_t);
326 
327 vrrp_err_t	vrrp_open(vrrp_handle_t *);
328 void		vrrp_close(vrrp_handle_t);
329 
330 boolean_t	vrrp_valid_name(const char *);
331 
332 vrrp_err_t	vrrp_create(vrrp_handle_t, vrrp_vr_conf_t *);
333 vrrp_err_t	vrrp_delete(vrrp_handle_t, const char *);
334 
335 vrrp_err_t	vrrp_enable(vrrp_handle_t, const char *);
336 vrrp_err_t	vrrp_disable(vrrp_handle_t, const char *);
337 
338 vrrp_err_t	vrrp_modify(vrrp_handle_t, vrrp_vr_conf_t *, uint32_t);
339 
340 vrrp_err_t	vrrp_query(vrrp_handle_t, const char *, vrrp_queryinfo_t **);
341 
342 vrrp_err_t	vrrp_list(vrrp_handle_t, vrid_t, const char *, int,
343 		    uint32_t *, char *);
344 
345 boolean_t	vrrp_is_vrrp_vnic(vrrp_handle_t, datalink_id_t,
346 		    datalink_id_t *, uint16_t *, vrid_t *, int *);
347 
348 vrrp_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