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 */
|