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