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